Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Update sqlite to 3.39.2
Baptiste Daroussin committed 3 years ago
commit 5ac1b918dd3b52e0222ddebbc4def030b89cb55f
parent 6ebdabb
3 files changed +9855 -7371
modified external/sqlite/shell.c
@@ -247,6 +247,16 @@ static void setTextMode(FILE *file, int isOutput){
# define setTextMode(X,Y)
#endif

+
/*
+
** When compiling with emcc (a.k.a. emscripten), we're building a
+
** WebAssembly (WASM) bundle and need to disable and rewire a few
+
** things.
+
*/
+
#ifdef __EMSCRIPTEN__
+
#define SQLITE_SHELL_WASM_MODE
+
#else
+
#undef SQLITE_SHELL_WASM_MODE
+
#endif

/* True if the timer is enabled */
static int enableTimer = 0;
@@ -709,6 +719,7 @@ static char *local_getline(char *zLine, FILE *in){
** be freed by the caller or else passed back into this routine via the
** zPrior argument for reuse.
*/
+
#ifndef SQLITE_SHELL_WASM_MODE
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
  char *zPrompt;
  char *zResult;
@@ -728,7 +739,7 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
  }
  return zResult;
}
-

+
#endif /* !SQLITE_SHELL_WASM_MODE */

/*
** Return the value of a hexadecimal digit.  Return -1 if the input
@@ -816,7 +827,7 @@ static void freeText(ShellText *p){
** If the third argument, quote, is not '\0', then it is used as a
** quote character for zAppend.
*/
-
static void appendText(ShellText *p, char const *zAppend, char quote){
+
static void appendText(ShellText *p, const char *zAppend, char quote){
  int len;
  int i;
  int nAppend = strlen30(zAppend);
@@ -1381,6 +1392,117 @@ INT closedir(
/************************* End test_windirent.c ********************/
#define dirent DIRENT
#endif
+
/************************* Begin ../ext/misc/memtrace.c ******************/
+
/*
+
** 2019-01-21
+
**
+
** The author disclaims copyright to this source code.  In place of
+
** a legal notice, here is a blessing:
+
**
+
**    May you do good and not evil.
+
**    May you find forgiveness for yourself and forgive others.
+
**    May you share freely, never taking more than you give.
+
**
+
*************************************************************************
+
**
+
** This file implements an extension that uses the SQLITE_CONFIG_MALLOC
+
** mechanism to add a tracing layer on top of SQLite.  If this extension
+
** is registered prior to sqlite3_initialize(), it will cause all memory
+
** allocation activities to be logged on standard output, or to some other
+
** FILE specified by the initializer.
+
**
+
** This file needs to be compiled into the application that uses it.
+
**
+
** This extension is used to implement the --memtrace option of the
+
** command-line shell.
+
*/
+
#include <assert.h>
+
#include <string.h>
+
#include <stdio.h>
+

+
/* The original memory allocation routines */
+
static sqlite3_mem_methods memtraceBase;
+
static FILE *memtraceOut;
+

+
/* Methods that trace memory allocations */
+
static void *memtraceMalloc(int n){
+
  if( memtraceOut ){
+
    fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n", 
+
            memtraceBase.xRoundup(n));
+
  }
+
  return memtraceBase.xMalloc(n);
+
}
+
static void memtraceFree(void *p){
+
  if( p==0 ) return;
+
  if( memtraceOut ){
+
    fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
+
  }
+
  memtraceBase.xFree(p);
+
}
+
static void *memtraceRealloc(void *p, int n){
+
  if( p==0 ) return memtraceMalloc(n);
+
  if( n==0 ){
+
    memtraceFree(p);
+
    return 0;
+
  }
+
  if( memtraceOut ){
+
    fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
+
            memtraceBase.xSize(p), memtraceBase.xRoundup(n));
+
  }
+
  return memtraceBase.xRealloc(p, n);
+
}
+
static int memtraceSize(void *p){
+
  return memtraceBase.xSize(p);
+
}
+
static int memtraceRoundup(int n){
+
  return memtraceBase.xRoundup(n);
+
}
+
static int memtraceInit(void *p){
+
  return memtraceBase.xInit(p);
+
}
+
static void memtraceShutdown(void *p){
+
  memtraceBase.xShutdown(p);
+
}
+

+
/* The substitute memory allocator */
+
static sqlite3_mem_methods ersaztMethods = {
+
  memtraceMalloc,
+
  memtraceFree,
+
  memtraceRealloc,
+
  memtraceSize,
+
  memtraceRoundup,
+
  memtraceInit,
+
  memtraceShutdown,
+
  0
+
};
+

+
/* Begin tracing memory allocations to out. */
+
int sqlite3MemTraceActivate(FILE *out){
+
  int rc = SQLITE_OK;
+
  if( memtraceBase.xMalloc==0 ){
+
    rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
+
    if( rc==SQLITE_OK ){
+
      rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
+
    }
+
  }
+
  memtraceOut = out;
+
  return rc;
+
}
+

+
/* Deactivate memory tracing */
+
int sqlite3MemTraceDeactivate(void){
+
  int rc = SQLITE_OK;
+
  if( memtraceBase.xMalloc!=0 ){
+
    rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
+
    if( rc==SQLITE_OK ){
+
      memset(&memtraceBase, 0, sizeof(memtraceBase));
+
    }
+
  }
+
  memtraceOut = 0;
+
  return rc;
+
}
+

+
/************************* End ../ext/misc/memtrace.c ********************/
/************************* Begin ../ext/misc/shathree.c ******************/
/*
** 2017-03-08
@@ -1403,7 +1525,7 @@ INT closedir(
** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
** X is NULL.
**
-
** The sha3_query(Y) function evalutes all queries in the SQL statements of Y
+
** The sha3_query(Y) function evaluates all queries in the SQL statements of Y
** and returns a hash of their results.
**
** The SIZE argument is optional.  If omitted, the SHA3-256 hash algorithm
@@ -2108,9 +2230,9 @@ int sqlite3_shathree_init(
}

/************************* End ../ext/misc/shathree.c ********************/
-
/************************* Begin ../ext/misc/fileio.c ******************/
+
/************************* Begin ../ext/misc/uint.c ******************/
/*
-
** 2014-06-13
+
** 2020-04-14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
@@ -2121,1029 +2243,729 @@ int sqlite3_shathree_init(
**
******************************************************************************
**
-
** This SQLite extension implements SQL functions readfile() and
-
** writefile(), and eponymous virtual type "fsdir".
-
**
-
** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
-
**
-
**   If neither of the optional arguments is present, then this UDF
-
**   function writes blob DATA to file FILE. If successful, the number
-
**   of bytes written is returned. If an error occurs, NULL is returned.
-
**
-
**   If the first option argument - MODE - is present, then it must
-
**   be passed an integer value that corresponds to a POSIX mode
-
**   value (file type + permissions, as returned in the stat.st_mode
-
**   field by the stat() system call). Three types of files may
-
**   be written/created:
-
**
-
**     regular files:  (mode & 0170000)==0100000
-
**     symbolic links: (mode & 0170000)==0120000
-
**     directories:    (mode & 0170000)==0040000
-
**
-
**   For a directory, the DATA is ignored. For a symbolic link, it is
-
**   interpreted as text and used as the target of the link. For a
-
**   regular file, it is interpreted as a blob and written into the
-
**   named file. Regardless of the type of file, its permissions are
-
**   set to (mode & 0777) before returning.
-
**
-
**   If the optional MTIME argument is present, then it is interpreted
-
**   as an integer - the number of seconds since the unix epoch. The
-
**   modification-time of the target file is set to this value before
-
**   returning.
-
**
-
**   If three or more arguments are passed to this function and an
-
**   error is encountered, an exception is raised.
-
**
-
** READFILE(FILE):
-
**
-
**   Read and return the contents of file FILE (type blob) from disk.
-
**
-
** FSDIR:
-
**
-
**   Used as follows:
-
**
-
**     SELECT * FROM fsdir($path [, $dir]);
-
**
-
**   Parameter $path is an absolute or relative pathname. If the file that it
-
**   refers to does not exist, it is an error. If the path refers to a regular
-
**   file or symbolic link, it returns a single row. Or, if the path refers
-
**   to a directory, it returns one row for the directory, and one row for each
-
**   file within the hierarchy rooted at $path.
+
** This SQLite extension implements the UINT collating sequence.
**
-
**   Each row has the following columns:
+
** UINT works like BINARY for text, except that embedded strings
+
** of digits compare in numeric order.
**
-
**     name:  Path to file or directory (text value).
-
**     mode:  Value of stat.st_mode for directory entry (an integer).
-
**     mtime: Value of stat.st_mtime for directory entry (an integer).
-
**     data:  For a regular file, a blob containing the file data. For a
-
**            symlink, a text value containing the text of the link. For a
-
**            directory, NULL.
+
**     *   Leading zeros are handled properly, in the sense that
+
**         they do not mess of the maginitude comparison of embedded
+
**         strings of digits.  "x00123y" is equal to "x123y".
**
-
**   If a non-NULL value is specified for the optional $dir parameter and
-
**   $path is a relative path, then $path is interpreted relative to $dir. 
-
**   And the paths returned in the "name" column of the table are also 
-
**   relative to directory $dir.
+
**     *   Only unsigned integers are recognized.  Plus and minus
+
**         signs are ignored.  Decimal points and exponential notation
+
**         are ignored.
**
-
** Notes on building this extension for Windows:
-
**   Unless linked statically with the SQLite library, a preprocessor
-
**   symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone
-
**   DLL form of this extension for WIN32. See its use below for details.
+
**     *   Embedded integers can be of arbitrary length.  Comparison
+
**         is *not* limited integers that can be expressed as a
+
**         64-bit machine integer.
*/
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
-
#include <stdio.h>
-
#include <string.h>
#include <assert.h>
-

-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
#if !defined(_WIN32) && !defined(WIN32)
-
#  include <unistd.h>
-
#  include <dirent.h>
-
#  include <utime.h>
-
#  include <sys/time.h>
-
#else
-
#  include "windows.h"
-
#  include <io.h>
-
#  include <direct.h>
-
/* #  include "test_windirent.h" */
-
#  define dirent DIRENT
-
#  ifndef chmod
-
#    define chmod _chmod
-
#  endif
-
#  ifndef stat
-
#    define stat _stat
-
#  endif
-
#  define mkdir(path,mode) _mkdir(path)
-
#  define lstat(path,buf) stat(path,buf)
-
#endif
-
#include <time.h>
-
#include <errno.h>
-

-

-
/*
-
** Structure of the fsdir() table-valued function
-
*/
-
                 /*    0    1    2     3    4           5             */
-
#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
-
#define FSDIR_COLUMN_NAME     0     /* Name of the file */
-
#define FSDIR_COLUMN_MODE     1     /* Access mode */
-
#define FSDIR_COLUMN_MTIME    2     /* Last modification time */
-
#define FSDIR_COLUMN_DATA     3     /* File content */
-
#define FSDIR_COLUMN_PATH     4     /* Path to top of search */
-
#define FSDIR_COLUMN_DIR      5     /* Path is relative to this directory */
-

+
#include <string.h>
+
#include <ctype.h>

/*
-
** Set the result stored by context ctx to a blob containing the 
-
** contents of file zName.  Or, leave the result unchanged (NULL)
-
** if the file does not exist or is unreadable.
-
**
-
** If the file exceeds the SQLite blob size limit, through an
-
** SQLITE_TOOBIG error.
-
**
-
** Throw an SQLITE_IOERR if there are difficulties pulling the file
-
** off of disk.
+
** Compare text in lexicographic order, except strings of digits
+
** compare in numeric order.
*/
-
static void readFileContents(sqlite3_context *ctx, const char *zName){
-
  FILE *in;
-
  sqlite3_int64 nIn;
-
  void *pBuf;
-
  sqlite3 *db;
-
  int mxBlob;
-

-
  in = fopen(zName, "rb");
-
  if( in==0 ){
-
    /* File does not exist or is unreadable. Leave the result set to NULL. */
-
    return;
-
  }
-
  fseek(in, 0, SEEK_END);
-
  nIn = ftell(in);
-
  rewind(in);
-
  db = sqlite3_context_db_handle(ctx);
-
  mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
-
  if( nIn>mxBlob ){
-
    sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
-
    fclose(in);
-
    return;
-
  }
-
  pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
-
  if( pBuf==0 ){
-
    sqlite3_result_error_nomem(ctx);
-
    fclose(in);
-
    return;
-
  }
-
  if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
-
    sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
-
  }else{
-
    sqlite3_result_error_code(ctx, SQLITE_IOERR);
-
    sqlite3_free(pBuf);
+
static int uintCollFunc(
+
  void *notUsed,
+
  int nKey1, const void *pKey1,
+
  int nKey2, const void *pKey2
+
){
+
  const unsigned char *zA = (const unsigned char*)pKey1;
+
  const unsigned char *zB = (const unsigned char*)pKey2;
+
  int i=0, j=0, x;
+
  (void)notUsed;
+
  while( i<nKey1 && j<nKey2 ){
+
    x = zA[i] - zB[j];
+
    if( isdigit(zA[i]) ){
+
      int k;
+
      if( !isdigit(zB[j]) ) return x;
+
      while( i<nKey1 && zA[i]=='0' ){ i++; }
+
      while( j<nKey2 && zB[j]=='0' ){ j++; }
+
      k = 0;
+
      while( i+k<nKey1 && isdigit(zA[i+k])
+
             && j+k<nKey2 && isdigit(zB[j+k]) ){
+
        k++;
+
      }
+
      if( i+k<nKey1 && isdigit(zA[i+k]) ){
+
        return +1;
+
      }else if( j+k<nKey2 && isdigit(zB[j+k]) ){
+
        return -1;
+
      }else{
+
        x = memcmp(zA+i, zB+j, k);
+
        if( x ) return x;
+
        i += k;
+
        j += k;
+
      }
+
    }else if( x ){
+
      return x;
+
    }else{
+
      i++;
+
      j++;
+
    }
  }
-
  fclose(in);
+
  return (nKey1 - i) - (nKey2 - j);
}

-
/*
-
** Implementation of the "readfile(X)" SQL function.  The entire content
-
** of the file named X is read and returned as a BLOB.  NULL is returned
-
** if the file does not exist or is unreadable.
-
*/
-
static void readfileFunc(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
-
){
-
  const char *zName;
-
  (void)(argc);  /* Unused parameter */
-
  zName = (const char*)sqlite3_value_text(argv[0]);
-
  if( zName==0 ) return;
-
  readFileContents(context, zName);
-
}
+
#ifdef _WIN32

-
/*
-
** Set the error message contained in context ctx to the results of
-
** vprintf(zFmt, ...).
-
*/
-
static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
-
  char *zMsg = 0;
-
  va_list ap;
-
  va_start(ap, zFmt);
-
  zMsg = sqlite3_vmprintf(zFmt, ap);
-
  sqlite3_result_error(ctx, zMsg, -1);
-
  sqlite3_free(zMsg);
-
  va_end(ap);
+
#endif
+
int sqlite3_uint_init(
+
  sqlite3 *db, 
+
  char **pzErrMsg, 
+
  const sqlite3_api_routines *pApi
+
){
+
  SQLITE_EXTENSION_INIT2(pApi);
+
  (void)pzErrMsg;  /* Unused parameter */
+
  return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
}

-
#if defined(_WIN32)
+
/************************* End ../ext/misc/uint.c ********************/
+
/************************* Begin ../ext/misc/decimal.c ******************/
/*
-
** This function is designed to convert a Win32 FILETIME structure into the
-
** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
+
** 2020-06-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.
+
**
+
******************************************************************************
+
**
+
** Routines to implement arbitrary-precision decimal math.
+
**
+
** The focus here is on simplicity and correctness, not performance.
*/
-
static sqlite3_uint64 fileTimeToUnixTime(
-
  LPFILETIME pFileTime
-
){
-
  SYSTEMTIME epochSystemTime;
-
  ULARGE_INTEGER epochIntervals;
-
  FILETIME epochFileTime;
-
  ULARGE_INTEGER fileIntervals;
-

-
  memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
-
  epochSystemTime.wYear = 1970;
-
  epochSystemTime.wMonth = 1;
-
  epochSystemTime.wDay = 1;
-
  SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
-
  epochIntervals.LowPart = epochFileTime.dwLowDateTime;
-
  epochIntervals.HighPart = epochFileTime.dwHighDateTime;
-

-
  fileIntervals.LowPart = pFileTime->dwLowDateTime;
-
  fileIntervals.HighPart = pFileTime->dwHighDateTime;
+
/* #include "sqlite3ext.h" */
+
SQLITE_EXTENSION_INIT1
+
#include <assert.h>
+
#include <string.h>
+
#include <ctype.h>
+
#include <stdlib.h>

-
  return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
-
}
+
/* Mark a function parameter as unused, to suppress nuisance compiler
+
** warnings. */
+
#ifndef UNUSED_PARAMETER
+
# define UNUSED_PARAMETER(X)  (void)(X)
+
#endif


-
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
-
#  /* To allow a standalone DLL, use this next replacement function: */
-
#  undef sqlite3_win32_utf8_to_unicode
-
#  define sqlite3_win32_utf8_to_unicode utf8_to_utf16
-
#
-
LPWSTR utf8_to_utf16(const char *z){
-
  int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0);
-
  LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR));
-
  if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) )
-
    return rv;
-
  sqlite3_free(rv);
-
  return 0;
-
}
-
#endif
+
/* A decimal object */
+
typedef struct Decimal Decimal;
+
struct Decimal {
+
  char sign;        /* 0 for positive, 1 for negative */
+
  char oom;         /* True if an OOM is encountered */
+
  char isNull;      /* True if holds a NULL rather than a number */
+
  char isInit;      /* True upon initialization */
+
  int nDigit;       /* Total number of digits */
+
  int nFrac;        /* Number of digits to the right of the decimal point */
+
  signed char *a;   /* Array of digits.  Most significant first. */
+
};

/*
-
** This function attempts to normalize the time values found in the stat()
-
** buffer to UTC.  This is necessary on Win32, where the runtime library
-
** appears to return these values as local times.
+
** Release memory held by a Decimal, but do not free the object itself.
*/
-
static void statTimesToUtc(
-
  const char *zPath,
-
  struct stat *pStatBuf
-
){
-
  HANDLE hFindFile;
-
  WIN32_FIND_DATAW fd;
-
  LPWSTR zUnicodeName;
-
  extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
-
  zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
-
  if( zUnicodeName ){
-
    memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
-
    hFindFile = FindFirstFileW(zUnicodeName, &fd);
-
    if( hFindFile!=NULL ){
-
      pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
-
      pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
-
      pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
-
      FindClose(hFindFile);
-
    }
-
    sqlite3_free(zUnicodeName);
-
  }
+
static void decimal_clear(Decimal *p){
+
  sqlite3_free(p->a);
}
-
#endif

/*
-
** This function is used in place of stat().  On Windows, special handling
-
** is required in order for the included time to be returned as UTC.  On all
-
** other systems, this function simply calls stat().
+
** Destroy a Decimal object
*/
-
static int fileStat(
-
  const char *zPath,
-
  struct stat *pStatBuf
-
){
-
#if defined(_WIN32)
-
  int rc = stat(zPath, pStatBuf);
-
  if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
-
  return rc;
-
#else
-
  return stat(zPath, pStatBuf);
-
#endif
+
static void decimal_free(Decimal *p){
+
  if( p ){
+
    decimal_clear(p);
+
    sqlite3_free(p);
+
  }
}

/*
-
** This function is used in place of lstat().  On Windows, special handling
-
** is required in order for the included time to be returned as UTC.  On all
-
** other systems, this function simply calls lstat().
+
** Allocate a new Decimal object.  Initialize it to the number given
+
** by the input string.
*/
-
static int fileLinkStat(
-
  const char *zPath,
-
  struct stat *pStatBuf
+
static Decimal *decimal_new(
+
  sqlite3_context *pCtx,
+
  sqlite3_value *pIn,
+
  int nAlt,
+
  const unsigned char *zAlt
){
-
#if defined(_WIN32)
-
  int rc = lstat(zPath, pStatBuf);
-
  if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
-
  return rc;
-
#else
-
  return lstat(zPath, pStatBuf);
-
#endif
-
}
-

-
/*
-
** Argument zFile is the name of a file that will be created and/or written
-
** by SQL function writefile(). This function ensures that the directory
-
** zFile will be written to exists, creating it if required. The permissions
-
** for any path components created by this function are set in accordance
-
** with the current umask.
-
**
-
** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
-
** SQLITE_OK is returned if the directory is successfully created, or
-
** SQLITE_ERROR otherwise.
-
*/
-
static int makeDirectory(
-
  const char *zFile
-
){
-
  char *zCopy = sqlite3_mprintf("%s", zFile);
-
  int rc = SQLITE_OK;
-

-
  if( zCopy==0 ){
-
    rc = SQLITE_NOMEM;
+
  Decimal *p;
+
  int n, i;
+
  const unsigned char *zIn;
+
  int iExp = 0;
+
  p = sqlite3_malloc( sizeof(*p) );
+
  if( p==0 ) goto new_no_mem;
+
  p->sign = 0;
+
  p->oom = 0;
+
  p->isInit = 1;
+
  p->isNull = 0;
+
  p->nDigit = 0;
+
  p->nFrac = 0;
+
  if( zAlt ){
+
    n = nAlt,
+
    zIn = zAlt;
  }else{
-
    int nCopy = (int)strlen(zCopy);
-
    int i = 1;
-

-
    while( rc==SQLITE_OK ){
-
      struct stat sStat;
-
      int rc2;
-

-
      for(; zCopy[i]!='/' && i<nCopy; i++);
-
      if( i==nCopy ) break;
-
      zCopy[i] = '\0';
-

-
      rc2 = fileStat(zCopy, &sStat);
-
      if( rc2!=0 ){
-
        if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR;
-
      }else{
-
        if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
-
      }
-
      zCopy[i] = '/';
-
      i++;
+
    if( sqlite3_value_type(pIn)==SQLITE_NULL ){
+
      p->a = 0;
+
      p->isNull = 1;
+
      return p;
    }
-

-
    sqlite3_free(zCopy);
+
    n = sqlite3_value_bytes(pIn);
+
    zIn = sqlite3_value_text(pIn);
  }
-

-
  return rc;
-
}
-

-
/*
-
** This function does the work for the writefile() UDF. Refer to 
-
** header comments at the top of this file for details.
-
*/
-
static int writeFile(
-
  sqlite3_context *pCtx,          /* Context to return bytes written in */
-
  const char *zFile,              /* File to write */
-
  sqlite3_value *pData,           /* Data to write */
-
  mode_t mode,                    /* MODE parameter passed to writefile() */
-
  sqlite3_int64 mtime             /* MTIME parameter (or -1 to not set time) */
-
){
-
  if( zFile==0 ) return 1;
-
#if !defined(_WIN32) && !defined(WIN32)
-
  if( S_ISLNK(mode) ){
-
    const char *zTo = (const char*)sqlite3_value_text(pData);
-
    if( zTo==0 || symlink(zTo, zFile)<0 ) return 1;
-
  }else
-
#endif
-
  {
-
    if( S_ISDIR(mode) ){
-
      if( mkdir(zFile, mode) ){
-
        /* The mkdir() call to create the directory failed. This might not
-
        ** be an error though - if there is already a directory at the same
-
        ** path and either the permissions already match or can be changed
-
        ** to do so using chmod(), it is not an error.  */
-
        struct stat sStat;
-
        if( errno!=EEXIST
-
         || 0!=fileStat(zFile, &sStat)
-
         || !S_ISDIR(sStat.st_mode)
-
         || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
-
        ){
-
          return 1;
-
        }
+
  p->a = sqlite3_malloc64( n+1 );
+
  if( p->a==0 ) goto new_no_mem;
+
  for(i=0; isspace(zIn[i]); i++){}
+
  if( zIn[i]=='-' ){
+
    p->sign = 1;
+
    i++;
+
  }else if( zIn[i]=='+' ){
+
    i++;
+
  }
+
  while( i<n && zIn[i]=='0' ) i++;
+
  while( i<n ){
+
    char c = zIn[i];
+
    if( c>='0' && c<='9' ){
+
      p->a[p->nDigit++] = c - '0';
+
    }else if( c=='.' ){
+
      p->nFrac = p->nDigit + 1;
+
    }else if( c=='e' || c=='E' ){
+
      int j = i+1;
+
      int neg = 0;
+
      if( j>=n ) break;
+
      if( zIn[j]=='-' ){
+
        neg = 1;
+
        j++;
+
      }else if( zIn[j]=='+' ){
+
        j++;
      }
-
    }else{
-
      sqlite3_int64 nWrite = 0;
-
      const char *z;
-
      int rc = 0;
-
      FILE *out = fopen(zFile, "wb");
-
      if( out==0 ) return 1;
-
      z = (const char*)sqlite3_value_blob(pData);
-
      if( z ){
-
        sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
-
        nWrite = sqlite3_value_bytes(pData);
-
        if( nWrite!=n ){
-
          rc = 1;
+
      while( j<n && iExp<1000000 ){
+
        if( zIn[j]>='0' && zIn[j]<='9' ){
+
          iExp = iExp*10 + zIn[j] - '0';
        }
+
        j++;
      }
-
      fclose(out);
-
      if( rc==0 && mode && chmod(zFile, mode & 0777) ){
-
        rc = 1;
-
      }
-
      if( rc ) return 2;
-
      sqlite3_result_int64(pCtx, nWrite);
+
      if( neg ) iExp = -iExp;
+
      break;
    }
+
    i++;
  }
-

-
  if( mtime>=0 ){
-
#if defined(_WIN32)
-
#if !SQLITE_OS_WINRT
-
    /* Windows */
-
    FILETIME lastAccess;
-
    FILETIME lastWrite;
-
    SYSTEMTIME currentTime;
-
    LONGLONG intervals;
-
    HANDLE hFile;
-
    LPWSTR zUnicodeName;
-
    extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
-

-
    GetSystemTime(&currentTime);
-
    SystemTimeToFileTime(&currentTime, &lastAccess);
-
    intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
-
    lastWrite.dwLowDateTime = (DWORD)intervals;
-
    lastWrite.dwHighDateTime = intervals >> 32;
-
    zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
-
    if( zUnicodeName==0 ){
-
      return 1;
+
  if( p->nFrac ){
+
    p->nFrac = p->nDigit - (p->nFrac - 1);
+
  }
+
  if( iExp>0 ){
+
    if( p->nFrac>0 ){
+
      if( iExp<=p->nFrac ){
+
        p->nFrac -= iExp;
+
        iExp = 0;
+
      }else{
+
        iExp -= p->nFrac;
+
        p->nFrac = 0;
+
      }
    }
-
    hFile = CreateFileW(
-
      zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
-
      FILE_FLAG_BACKUP_SEMANTICS, NULL
-
    );
-
    sqlite3_free(zUnicodeName);
-
    if( hFile!=INVALID_HANDLE_VALUE ){
-
      BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
-
      CloseHandle(hFile);
-
      return !bResult;
-
    }else{
-
      return 1;
+
    if( iExp>0 ){   
+
      p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
+
      if( p->a==0 ) goto new_no_mem;
+
      memset(p->a+p->nDigit, 0, iExp);
+
      p->nDigit += iExp;
    }
-
#endif
-
#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
-
    /* Recent unix */
-
    struct timespec times[2];
-
    times[0].tv_nsec = times[1].tv_nsec = 0;
-
    times[0].tv_sec = time(0);
-
    times[1].tv_sec = mtime;
-
    if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
-
      return 1;
+
  }else if( iExp<0 ){
+
    int nExtra;
+
    iExp = -iExp;
+
    nExtra = p->nDigit - p->nFrac - 1;
+
    if( nExtra ){
+
      if( nExtra>=iExp ){
+
        p->nFrac += iExp;
+
        iExp  = 0;
+
      }else{
+
        iExp -= nExtra;
+
        p->nFrac = p->nDigit - 1;
+
      }
    }
-
#else
-
    /* Legacy unix */
-
    struct timeval times[2];
-
    times[0].tv_usec = times[1].tv_usec = 0;
-
    times[0].tv_sec = time(0);
-
    times[1].tv_sec = mtime;
-
    if( utimes(zFile, times) ){
-
      return 1;
+
    if( iExp>0 ){
+
      p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
+
      if( p->a==0 ) goto new_no_mem;
+
      memmove(p->a+iExp, p->a, p->nDigit);
+
      memset(p->a, 0, iExp);
+
      p->nDigit += iExp;
+
      p->nFrac += iExp;
    }
-
#endif
  }
+
  return p;

+
new_no_mem:
+
  if( pCtx ) sqlite3_result_error_nomem(pCtx);
+
  sqlite3_free(p);
  return 0;
}

/*
-
** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.  
-
** Refer to header comments at the top of this file for details.
+
** Make the given Decimal the result.
*/
-
static void writefileFunc(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
-
){
-
  const char *zFile;
-
  mode_t mode = 0;
-
  int res;
-
  sqlite3_int64 mtime = -1;
-

-
  if( argc<2 || argc>4 ){
-
    sqlite3_result_error(context, 
-
        "wrong number of arguments to function writefile()", -1
-
    );
+
static void decimal_result(sqlite3_context *pCtx, Decimal *p){
+
  char *z;
+
  int i, j;
+
  int n;
+
  if( p==0 || p->oom ){
+
    sqlite3_result_error_nomem(pCtx);
    return;
  }
-

-
  zFile = (const char*)sqlite3_value_text(argv[0]);
-
  if( zFile==0 ) return;
-
  if( argc>=3 ){
-
    mode = (mode_t)sqlite3_value_int(argv[2]);
+
  if( p->isNull ){
+
    sqlite3_result_null(pCtx);
+
    return;
  }
-
  if( argc==4 ){
-
    mtime = sqlite3_value_int64(argv[3]);
+
  z = sqlite3_malloc( p->nDigit+4 );
+
  if( z==0 ){
+
    sqlite3_result_error_nomem(pCtx);
+
    return;
  }
-

-
  res = writeFile(context, zFile, argv[1], mode, mtime);
-
  if( res==1 && errno==ENOENT ){
-
    if( makeDirectory(zFile)==SQLITE_OK ){
-
      res = writeFile(context, zFile, argv[1], mode, mtime);
-
    }
+
  i = 0;
+
  if( p->nDigit==0 || (p->nDigit==1 && p->a[0]==0) ){
+
    p->sign = 0;
  }
-

-
  if( argc>2 && res!=0 ){
-
    if( S_ISLNK(mode) ){
-
      ctxErrorMsg(context, "failed to create symlink: %s", zFile);
-
    }else if( S_ISDIR(mode) ){
-
      ctxErrorMsg(context, "failed to create directory: %s", zFile);
-
    }else{
-
      ctxErrorMsg(context, "failed to write file: %s", zFile);
-
    }
+
  if( p->sign ){
+
    z[0] = '-';
+
    i = 1;
  }
+
  n = p->nDigit - p->nFrac;
+
  if( n<=0 ){
+
    z[i++] = '0';
+
  }
+
  j = 0;
+
  while( n>1 && p->a[j]==0 ){
+
    j++;
+
    n--;
+
  }
+
  while( n>0  ){
+
    z[i++] = p->a[j] + '0';
+
    j++;
+
    n--;
+
  }
+
  if( p->nFrac ){
+
    z[i++] = '.';
+
    do{
+
      z[i++] = p->a[j] + '0';
+
      j++;
+
    }while( j<p->nDigit );
+
  }
+
  z[i] = 0;
+
  sqlite3_result_text(pCtx, z, i, sqlite3_free);
}

/*
-
** SQL function:   lsmode(MODE)
+
** SQL Function:   decimal(X)
**
-
** Given a numberic st_mode from stat(), convert it into a human-readable
-
** text string in the style of "ls -l".
+
** Convert input X into decimal and then back into text
*/
-
static void lsModeFunc(
+
static void decimalFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
-
  int i;
-
  int iMode = sqlite3_value_int(argv[0]);
-
  char z[16];
-
  (void)argc;
-
  if( S_ISLNK(iMode) ){
-
    z[0] = 'l';
-
  }else if( S_ISREG(iMode) ){
-
    z[0] = '-';
-
  }else if( S_ISDIR(iMode) ){
-
    z[0] = 'd';
-
  }else{
-
    z[0] = '?';
-
  }
-
  for(i=0; i<3; i++){
-
    int m = (iMode >> ((2-i)*3));
-
    char *a = &z[1 + i*3];
-
    a[0] = (m & 0x4) ? 'r' : '-';
-
    a[1] = (m & 0x2) ? 'w' : '-';
-
    a[2] = (m & 0x1) ? 'x' : '-';
-
  }
-
  z[10] = '\0';
-
  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
+
  Decimal *p = decimal_new(context, argv[0], 0, 0);
+
  UNUSED_PARAMETER(argc);
+
  decimal_result(context, p);
+
  decimal_free(p);
}

-
#ifndef SQLITE_OMIT_VIRTUALTABLE
-

-
/* 
-
** Cursor type for recursively iterating through a directory structure.
-
*/
-
typedef struct fsdir_cursor fsdir_cursor;
-
typedef struct FsdirLevel FsdirLevel;
-

-
struct FsdirLevel {
-
  DIR *pDir;                 /* From opendir() */
-
  char *zDir;                /* Name of directory (nul-terminated) */
-
};
-

-
struct fsdir_cursor {
-
  sqlite3_vtab_cursor base;  /* Base class - must be first */
-

-
  int nLvl;                  /* Number of entries in aLvl[] array */
-
  int iLvl;                  /* Index of current entry */
-
  FsdirLevel *aLvl;          /* Hierarchy of directories being traversed */
-

-
  const char *zBase;
-
  int nBase;
-

-
  struct stat sStat;         /* Current lstat() results */
-
  char *zPath;               /* Path to current entry */
-
  sqlite3_int64 iRowid;      /* Current rowid */
-
};
-

-
typedef struct fsdir_tab fsdir_tab;
-
struct fsdir_tab {
-
  sqlite3_vtab base;         /* Base class - must be first */
-
};
-

/*
-
** Construct a new fsdir virtual table object.
+
** Compare to Decimal objects.  Return negative, 0, or positive if the
+
** first object is less than, equal to, or greater than the second.
+
**
+
** Preconditions for this routine:
+
**
+
**    pA!=0
+
**    pA->isNull==0
+
**    pB!=0
+
**    pB->isNull==0
*/
-
static int fsdirConnect(
-
  sqlite3 *db,
-
  void *pAux,
-
  int argc, const char *const*argv,
-
  sqlite3_vtab **ppVtab,
-
  char **pzErr
-
){
-
  fsdir_tab *pNew = 0;
-
  int rc;
-
  (void)pAux;
-
  (void)argc;
-
  (void)argv;
-
  (void)pzErr;
-
  rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
-
  if( rc==SQLITE_OK ){
-
    pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
-
    if( pNew==0 ) return SQLITE_NOMEM;
-
    memset(pNew, 0, sizeof(*pNew));
-
    sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
+
static int decimal_cmp(const Decimal *pA, const Decimal *pB){
+
  int nASig, nBSig, rc, n;
+
  if( pA->sign!=pB->sign ){
+
    return pA->sign ? -1 : +1;
+
  }
+
  if( pA->sign ){
+
    const Decimal *pTemp = pA;
+
    pA = pB;
+
    pB = pTemp;
+
  }
+
  nASig = pA->nDigit - pA->nFrac;
+
  nBSig = pB->nDigit - pB->nFrac;
+
  if( nASig!=nBSig ){
+
    return nASig - nBSig;
+
  }
+
  n = pA->nDigit;
+
  if( n>pB->nDigit ) n = pB->nDigit;
+
  rc = memcmp(pA->a, pB->a, n);
+
  if( rc==0 ){
+
    rc = pA->nDigit - pB->nDigit;
  }
-
  *ppVtab = (sqlite3_vtab*)pNew;
  return rc;
}

/*
-
** This method is the destructor for fsdir vtab objects.
+
** SQL Function:   decimal_cmp(X, Y)
+
**
+
** Return negative, zero, or positive if X is less then, equal to, or
+
** greater than Y.
*/
-
static int fsdirDisconnect(sqlite3_vtab *pVtab){
-
  sqlite3_free(pVtab);
-
  return SQLITE_OK;
-
}
+
static void decimalCmpFunc(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
+
){
+
  Decimal *pA = 0, *pB = 0;
+
  int rc;

-
/*
-
** Constructor for a new fsdir_cursor object.
-
*/
-
static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
-
  fsdir_cursor *pCur;
-
  (void)p;
-
  pCur = sqlite3_malloc( sizeof(*pCur) );
-
  if( pCur==0 ) return SQLITE_NOMEM;
-
  memset(pCur, 0, sizeof(*pCur));
-
  pCur->iLvl = -1;
-
  *ppCursor = &pCur->base;
-
  return SQLITE_OK;
+
  UNUSED_PARAMETER(argc);
+
  pA = decimal_new(context, argv[0], 0, 0);
+
  if( pA==0 || pA->isNull ) goto cmp_done;
+
  pB = decimal_new(context, argv[1], 0, 0);
+
  if( pB==0 || pB->isNull ) goto cmp_done;
+
  rc = decimal_cmp(pA, pB);
+
  if( rc<0 ) rc = -1;
+
  else if( rc>0 ) rc = +1;
+
  sqlite3_result_int(context, rc);
+
cmp_done:
+
  decimal_free(pA);
+
  decimal_free(pB);
}

/*
-
** Reset a cursor back to the state it was in when first returned
-
** by fsdirOpen().
+
** Expand the Decimal so that it has a least nDigit digits and nFrac
+
** digits to the right of the decimal point.
*/
-
static void fsdirResetCursor(fsdir_cursor *pCur){
-
  int i;
-
  for(i=0; i<=pCur->iLvl; i++){
-
    FsdirLevel *pLvl = &pCur->aLvl[i];
-
    if( pLvl->pDir ) closedir(pLvl->pDir);
-
    sqlite3_free(pLvl->zDir);
+
static void decimal_expand(Decimal *p, int nDigit, int nFrac){
+
  int nAddSig;
+
  int nAddFrac;
+
  if( p==0 ) return;
+
  nAddFrac = nFrac - p->nFrac;
+
  nAddSig = (nDigit - p->nDigit) - nAddFrac;
+
  if( nAddFrac==0 && nAddSig==0 ) return;
+
  p->a = sqlite3_realloc64(p->a, nDigit+1);
+
  if( p->a==0 ){
+
    p->oom = 1;
+
    return;
+
  }
+
  if( nAddSig ){
+
    memmove(p->a+nAddSig, p->a, p->nDigit);
+
    memset(p->a, 0, nAddSig);
+
    p->nDigit += nAddSig;
+
  }
+
  if( nAddFrac ){
+
    memset(p->a+p->nDigit, 0, nAddFrac);
+
    p->nDigit += nAddFrac;
+
    p->nFrac += nAddFrac;
  }
-
  sqlite3_free(pCur->zPath);
-
  sqlite3_free(pCur->aLvl);
-
  pCur->aLvl = 0;
-
  pCur->zPath = 0;
-
  pCur->zBase = 0;
-
  pCur->nBase = 0;
-
  pCur->nLvl = 0;
-
  pCur->iLvl = -1;
-
  pCur->iRowid = 1;
}

/*
-
** Destructor for an fsdir_cursor.
+
** Add the value pB into pA.
+
**
+
** Both pA and pB might become denormalized by this routine.
*/
-
static int fsdirClose(sqlite3_vtab_cursor *cur){
-
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-

-
  fsdirResetCursor(pCur);
-
  sqlite3_free(pCur);
-
  return SQLITE_OK;
-
}
-

-
/*
-
** Set the error message for the virtual table associated with cursor
-
** pCur to the results of vprintf(zFmt, ...).
-
*/
-
static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
-
  va_list ap;
-
  va_start(ap, zFmt);
-
  pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
-
  va_end(ap);
-
}
-

-

-
/*
-
** Advance an fsdir_cursor to its next row of output.
-
*/
-
static int fsdirNext(sqlite3_vtab_cursor *cur){
-
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-
  mode_t m = pCur->sStat.st_mode;
-

-
  pCur->iRowid++;
-
  if( S_ISDIR(m) ){
-
    /* Descend into this directory */
-
    int iNew = pCur->iLvl + 1;
-
    FsdirLevel *pLvl;
-
    if( iNew>=pCur->nLvl ){
-
      int nNew = iNew+1;
-
      sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
-
      FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
-
      if( aNew==0 ) return SQLITE_NOMEM;
-
      memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
-
      pCur->aLvl = aNew;
-
      pCur->nLvl = nNew;
-
    }
-
    pCur->iLvl = iNew;
-
    pLvl = &pCur->aLvl[iNew];
-
    
-
    pLvl->zDir = pCur->zPath;
-
    pCur->zPath = 0;
-
    pLvl->pDir = opendir(pLvl->zDir);
-
    if( pLvl->pDir==0 ){
-
      fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
-
      return SQLITE_ERROR;
-
    }
+
static void decimal_add(Decimal *pA, Decimal *pB){
+
  int nSig, nFrac, nDigit;
+
  int i, rc;
+
  if( pA==0 ){
+
    return;
  }
-

-
  while( pCur->iLvl>=0 ){
-
    FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
-
    struct dirent *pEntry = readdir(pLvl->pDir);
-
    if( pEntry ){
-
      if( pEntry->d_name[0]=='.' ){
-
       if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
-
       if( pEntry->d_name[1]=='\0' ) continue;
-
      }
-
      sqlite3_free(pCur->zPath);
-
      pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
-
      if( pCur->zPath==0 ) return SQLITE_NOMEM;
-
      if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
-
        fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
-
        return SQLITE_ERROR;
-
      }
-
      return SQLITE_OK;
-
    }
-
    closedir(pLvl->pDir);
-
    sqlite3_free(pLvl->zDir);
-
    pLvl->pDir = 0;
-
    pLvl->zDir = 0;
-
    pCur->iLvl--;
+
  if( pA->oom || pB==0 || pB->oom ){
+
    pA->oom = 1;
+
    return;
  }
-

-
  /* EOF */
-
  sqlite3_free(pCur->zPath);
-
  pCur->zPath = 0;
-
  return SQLITE_OK;
-
}
-

-
/*
-
** Return values of columns for the row at which the series_cursor
-
** is currently pointing.
-
*/
-
static int fsdirColumn(
-
  sqlite3_vtab_cursor *cur,   /* The cursor */
-
  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
-
  int i                       /* Which column to return */
-
){
-
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-
  switch( i ){
-
    case FSDIR_COLUMN_NAME: {
-
      sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
-
      break;
-
    }
-

-
    case FSDIR_COLUMN_MODE:
-
      sqlite3_result_int64(ctx, pCur->sStat.st_mode);
-
      break;
-

-
    case FSDIR_COLUMN_MTIME:
-
      sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
-
      break;
-

-
    case FSDIR_COLUMN_DATA: {
-
      mode_t m = pCur->sStat.st_mode;
-
      if( S_ISDIR(m) ){
-
        sqlite3_result_null(ctx);
-
#if !defined(_WIN32) && !defined(WIN32)
-
      }else if( S_ISLNK(m) ){
-
        char aStatic[64];
-
        char *aBuf = aStatic;
-
        sqlite3_int64 nBuf = 64;
-
        int n;
-

-
        while( 1 ){
-
          n = readlink(pCur->zPath, aBuf, nBuf);
-
          if( n<nBuf ) break;
-
          if( aBuf!=aStatic ) sqlite3_free(aBuf);
-
          nBuf = nBuf*2;
-
          aBuf = sqlite3_malloc64(nBuf);
-
          if( aBuf==0 ){
-
            sqlite3_result_error_nomem(ctx);
-
            return SQLITE_NOMEM;
-
          }
+
  if( pA->isNull || pB->isNull ){
+
    pA->isNull = 1;
+
    return;
+
  }
+
  nSig = pA->nDigit - pA->nFrac;
+
  if( nSig && pA->a[0]==0 ) nSig--;
+
  if( nSig<pB->nDigit-pB->nFrac ){
+
    nSig = pB->nDigit - pB->nFrac;
+
  }
+
  nFrac = pA->nFrac;
+
  if( nFrac<pB->nFrac ) nFrac = pB->nFrac;
+
  nDigit = nSig + nFrac + 1;
+
  decimal_expand(pA, nDigit, nFrac);
+
  decimal_expand(pB, nDigit, nFrac);
+
  if( pA->oom || pB->oom ){
+
    pA->oom = 1;
+
  }else{
+
    if( pA->sign==pB->sign ){
+
      int carry = 0;
+
      for(i=nDigit-1; i>=0; i--){
+
        int x = pA->a[i] + pB->a[i] + carry;
+
        if( x>=10 ){
+
          carry = 1;
+
          pA->a[i] = x - 10;
+
        }else{
+
          carry = 0;
+
          pA->a[i] = x;
        }
-

-
        sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
-
        if( aBuf!=aStatic ) sqlite3_free(aBuf);
-
#endif
+
      }
+
    }else{
+
      signed char *aA, *aB;
+
      int borrow = 0;
+
      rc = memcmp(pA->a, pB->a, nDigit);
+
      if( rc<0 ){
+
        aA = pB->a;
+
        aB = pA->a;
+
        pA->sign = !pA->sign;
      }else{
-
        readFileContents(ctx, pCur->zPath);
+
        aA = pA->a;
+
        aB = pB->a;
+
      }
+
      for(i=nDigit-1; i>=0; i--){
+
        int x = aA[i] - aB[i] - borrow;
+
        if( x<0 ){
+
          pA->a[i] = x+10;
+
          borrow = 1;
+
        }else{
+
          pA->a[i] = x;
+
          borrow = 0;
+
        }
      }
-
    }
-
    case FSDIR_COLUMN_PATH:
-
    default: {
-
      /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
-
      ** always return their values as NULL */
-
      break;
    }
  }
-
  return SQLITE_OK;
}

/*
-
** Return the rowid for the current row. In this implementation, the
-
** first row returned is assigned rowid value 1, and each subsequent
-
** row a value 1 more than that of the previous.
+
** Compare text in decimal order.
*/
-
static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
-
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-
  *pRowid = pCur->iRowid;
-
  return SQLITE_OK;
+
static int decimalCollFunc(
+
  void *notUsed,
+
  int nKey1, const void *pKey1,
+
  int nKey2, const void *pKey2
+
){
+
  const unsigned char *zA = (const unsigned char*)pKey1;
+
  const unsigned char *zB = (const unsigned char*)pKey2;
+
  Decimal *pA = decimal_new(0, 0, nKey1, zA);
+
  Decimal *pB = decimal_new(0, 0, nKey2, zB);
+
  int rc;
+
  UNUSED_PARAMETER(notUsed);
+
  if( pA==0 || pB==0 ){
+
    rc = 0;
+
  }else{
+
    rc = decimal_cmp(pA, pB);
+
  }
+
  decimal_free(pA);
+
  decimal_free(pB);
+
  return rc;
}

-
/*
-
** Return TRUE if the cursor has been moved off of the last
-
** row of output.
-
*/
-
static int fsdirEof(sqlite3_vtab_cursor *cur){
-
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-
  return (pCur->zPath==0);
-
}

/*
-
** xFilter callback.
+
** SQL Function:   decimal_add(X, Y)
+
**                 decimal_sub(X, Y)
**
-
** idxNum==1   PATH parameter only
-
** idxNum==2   Both PATH and DIR supplied
+
** Return the sum or difference of X and Y.
*/
-
static int fsdirFilter(
-
  sqlite3_vtab_cursor *cur, 
-
  int idxNum, const char *idxStr,
-
  int argc, sqlite3_value **argv
+
static void decimalAddFunc(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
){
-
  const char *zDir = 0;
-
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-
  (void)idxStr;
-
  fsdirResetCursor(pCur);
-

-
  if( idxNum==0 ){
-
    fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
-
    return SQLITE_ERROR;
-
  }
-

-
  assert( argc==idxNum && (argc==1 || argc==2) );
-
  zDir = (const char*)sqlite3_value_text(argv[0]);
-
  if( zDir==0 ){
-
    fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
-
    return SQLITE_ERROR;
-
  }
-
  if( argc==2 ){
-
    pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
-
  }
-
  if( pCur->zBase ){
-
    pCur->nBase = (int)strlen(pCur->zBase)+1;
-
    pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
-
  }else{
-
    pCur->zPath = sqlite3_mprintf("%s", zDir);
+
  Decimal *pA = decimal_new(context, argv[0], 0, 0);
+
  Decimal *pB = decimal_new(context, argv[1], 0, 0);
+
  UNUSED_PARAMETER(argc);
+
  decimal_add(pA, pB);
+
  decimal_result(context, pA);
+
  decimal_free(pA);
+
  decimal_free(pB);
+
}
+
static void decimalSubFunc(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
+
){
+
  Decimal *pA = decimal_new(context, argv[0], 0, 0);
+
  Decimal *pB = decimal_new(context, argv[1], 0, 0);
+
  UNUSED_PARAMETER(argc);
+
  if( pB ){
+
    pB->sign = !pB->sign;
+
    decimal_add(pA, pB);
+
    decimal_result(context, pA);
  }
+
  decimal_free(pA);
+
  decimal_free(pB);
+
}

-
  if( pCur->zPath==0 ){
-
    return SQLITE_NOMEM;
-
  }
-
  if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
-
    fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
-
    return SQLITE_ERROR;
+
/* Aggregate funcion:   decimal_sum(X)
+
**
+
** Works like sum() except that it uses decimal arithmetic for unlimited
+
** precision.
+
*/
+
static void decimalSumStep(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
+
){
+
  Decimal *p;
+
  Decimal *pArg;
+
  UNUSED_PARAMETER(argc);
+
  p = sqlite3_aggregate_context(context, sizeof(*p));
+
  if( p==0 ) return;
+
  if( !p->isInit ){
+
    p->isInit = 1;
+
    p->a = sqlite3_malloc(2);
+
    if( p->a==0 ){
+
      p->oom = 1;
+
    }else{
+
      p->a[0] = 0;
+
    }
+
    p->nDigit = 1;
+
    p->nFrac = 0;
  }
-

-
  return SQLITE_OK;
+
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+
  pArg = decimal_new(context, argv[0], 0, 0);
+
  decimal_add(p, pArg);
+
  decimal_free(pArg);
+
}
+
static void decimalSumInverse(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
+
){
+
  Decimal *p;
+
  Decimal *pArg;
+
  UNUSED_PARAMETER(argc);
+
  p = sqlite3_aggregate_context(context, sizeof(*p));
+
  if( p==0 ) return;
+
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+
  pArg = decimal_new(context, argv[0], 0, 0);
+
  if( pArg ) pArg->sign = !pArg->sign;
+
  decimal_add(p, pArg);
+
  decimal_free(pArg);
+
}
+
static void decimalSumValue(sqlite3_context *context){
+
  Decimal *p = sqlite3_aggregate_context(context, 0);
+
  if( p==0 ) return;
+
  decimal_result(context, p);
+
}
+
static void decimalSumFinalize(sqlite3_context *context){
+
  Decimal *p = sqlite3_aggregate_context(context, 0);
+
  if( p==0 ) return;
+
  decimal_result(context, p);
+
  decimal_clear(p);
}

/*
-
** SQLite will invoke this method one or more times while planning a query
-
** that uses the generate_series virtual table.  This routine needs to create
-
** a query plan for each invocation and compute an estimated cost for that
-
** plan.
-
**
-
** In this implementation idxNum is used to represent the
-
** query plan.  idxStr is unused.
+
** SQL Function:   decimal_mul(X, Y)
**
-
** The query plan is represented by values of idxNum:
+
** Return the product of X and Y.
**
-
**  (1)  The path value is supplied by argv[0]
-
**  (2)  Path is in argv[0] and dir is in argv[1]
+
** All significant digits after the decimal point are retained.
+
** Trailing zeros after the decimal point are omitted as long as
+
** the number of digits after the decimal point is no less than
+
** either the number of digits in either input.
*/
-
static int fsdirBestIndex(
-
  sqlite3_vtab *tab,
-
  sqlite3_index_info *pIdxInfo
+
static void decimalMulFunc(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
){
-
  int i;                 /* Loop over constraints */
-
  int idxPath = -1;      /* Index in pIdxInfo->aConstraint of PATH= */
-
  int idxDir = -1;       /* Index in pIdxInfo->aConstraint of DIR= */
-
  int seenPath = 0;      /* True if an unusable PATH= constraint is seen */
-
  int seenDir = 0;       /* True if an unusable DIR= constraint is seen */
-
  const struct sqlite3_index_constraint *pConstraint;
-

-
  (void)tab;
-
  pConstraint = pIdxInfo->aConstraint;
-
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
-
    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
-
    switch( pConstraint->iColumn ){
-
      case FSDIR_COLUMN_PATH: {
-
        if( pConstraint->usable ){
-
          idxPath = i;
-
          seenPath = 0;
-
        }else if( idxPath<0 ){
-
          seenPath = 1;
-
        }
-
        break;
-
      }
-
      case FSDIR_COLUMN_DIR: {
-
        if( pConstraint->usable ){
-
          idxDir = i;
-
          seenDir = 0;
-
        }else if( idxDir<0 ){
-
          seenDir = 1;
-
        }
-
        break;
-
      }
-
    } 
+
  Decimal *pA = decimal_new(context, argv[0], 0, 0);
+
  Decimal *pB = decimal_new(context, argv[1], 0, 0);
+
  signed char *acc = 0;
+
  int i, j, k;
+
  int minFrac;
+
  UNUSED_PARAMETER(argc);
+
  if( pA==0 || pA->oom || pA->isNull
+
   || pB==0 || pB->oom || pB->isNull 
+
  ){
+
    goto mul_end;
  }
-
  if( seenPath || seenDir ){
-
    /* If input parameters are unusable, disallow this plan */
-
    return SQLITE_CONSTRAINT;
+
  acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 );
+
  if( acc==0 ){
+
    sqlite3_result_error_nomem(context);
+
    goto mul_end;
  }
-

-
  if( idxPath<0 ){
-
    pIdxInfo->idxNum = 0;
-
    /* The pIdxInfo->estimatedCost should have been initialized to a huge
-
    ** number.  Leave it unchanged. */
-
    pIdxInfo->estimatedRows = 0x7fffffff;
-
  }else{
-
    pIdxInfo->aConstraintUsage[idxPath].omit = 1;
-
    pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
-
    if( idxDir>=0 ){
-
      pIdxInfo->aConstraintUsage[idxDir].omit = 1;
-
      pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
-
      pIdxInfo->idxNum = 2;
-
      pIdxInfo->estimatedCost = 10.0;
-
    }else{
-
      pIdxInfo->idxNum = 1;
-
      pIdxInfo->estimatedCost = 100.0;
+
  memset(acc, 0, pA->nDigit + pB->nDigit + 2);
+
  minFrac = pA->nFrac;
+
  if( pB->nFrac<minFrac ) minFrac = pB->nFrac;
+
  for(i=pA->nDigit-1; i>=0; i--){
+
    signed char f = pA->a[i];
+
    int carry = 0, x;
+
    for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){
+
      x = acc[k] + f*pB->a[j] + carry;
+
      acc[k] = x%10;
+
      carry = x/10;
    }
+
    x = acc[k] + carry;
+
    acc[k] = x%10;
+
    acc[k-1] += x/10;
  }
+
  sqlite3_free(pA->a);
+
  pA->a = acc;
+
  acc = 0;
+
  pA->nDigit += pB->nDigit + 2;
+
  pA->nFrac += pB->nFrac;
+
  pA->sign ^= pB->sign;
+
  while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){
+
    pA->nFrac--;
+
    pA->nDigit--;
+
  }
+
  decimal_result(context, pA);

-
  return SQLITE_OK;
-
}
-

-
/*
-
** Register the "fsdir" virtual table.
-
*/
-
static int fsdirRegister(sqlite3 *db){
-
  static sqlite3_module fsdirModule = {
-
    0,                         /* iVersion */
-
    0,                         /* xCreate */
-
    fsdirConnect,              /* xConnect */
-
    fsdirBestIndex,            /* xBestIndex */
-
    fsdirDisconnect,           /* xDisconnect */
-
    0,                         /* xDestroy */
-
    fsdirOpen,                 /* xOpen - open a cursor */
-
    fsdirClose,                /* xClose - close a cursor */
-
    fsdirFilter,               /* xFilter - configure scan constraints */
-
    fsdirNext,                 /* xNext - advance a cursor */
-
    fsdirEof,                  /* xEof - check for end of scan */
-
    fsdirColumn,               /* xColumn - read data */
-
    fsdirRowid,                /* xRowid - read data */
-
    0,                         /* xUpdate */
-
    0,                         /* xBegin */
-
    0,                         /* xSync */
-
    0,                         /* xCommit */
-
    0,                         /* xRollback */
-
    0,                         /* xFindMethod */
-
    0,                         /* xRename */
-
    0,                         /* xSavepoint */
-
    0,                         /* xRelease */
-
    0,                         /* xRollbackTo */
-
    0,                         /* xShadowName */
-
  };
-

-
  int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
-
  return rc;
+
mul_end:
+
  sqlite3_free(acc);
+
  decimal_free(pA);
+
  decimal_free(pB);
}
-
#else         /* SQLITE_OMIT_VIRTUALTABLE */
-
# define fsdirRegister(x) SQLITE_OK
-
#endif

#ifdef _WIN32

#endif
-
int sqlite3_fileio_init(
+
int sqlite3_decimal_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
-
  SQLITE_EXTENSION_INIT2(pApi);
-
  (void)pzErrMsg;  /* Unused parameter */
-
  rc = sqlite3_create_function(db, "readfile", 1, 
-
                               SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
-
                               readfileFunc, 0, 0);
-
  if( rc==SQLITE_OK ){
-
    rc = sqlite3_create_function(db, "writefile", -1,
-
                                 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
-
                                 writefileFunc, 0, 0);
+
  static const struct {
+
    const char *zFuncName;
+
    int nArg;
+
    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+
  } aFunc[] = {
+
    { "decimal",       1,   decimalFunc        },
+
    { "decimal_cmp",   2,   decimalCmpFunc     },
+
    { "decimal_add",   2,   decimalAddFunc     },
+
    { "decimal_sub",   2,   decimalSubFunc     },
+
    { "decimal_mul",   2,   decimalMulFunc     },
+
  };
+
  unsigned int i;
+
  (void)pzErrMsg;  /* Unused parameter */
+

+
  SQLITE_EXTENSION_INIT2(pApi);
+

+
  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
+
    rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg,
+
                   SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
+
                   0, aFunc[i].xFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
-
    rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
-
                                 lsModeFunc, 0, 0);
+
    rc = sqlite3_create_window_function(db, "decimal_sum", 1,
+
                   SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0,
+
                   decimalSumStep, decimalSumFinalize,
+
                   decimalSumValue, decimalSumInverse, 0);
  }
  if( rc==SQLITE_OK ){
-
    rc = fsdirRegister(db);
+
    rc = sqlite3_create_collation(db, "decimal", SQLITE_UTF8,
+
                                  0, decimalCollFunc);
  }
  return rc;
}

-
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
-
/* To allow a standalone DLL, make test_windirent.c use the same
-
 * redefined SQLite API calls as the above extension code does.
-
 * Just pull in this .c to accomplish this. As a beneficial side
-
 * effect, this extension becomes a single translation unit. */
-
#  include "test_windirent.c"
-
#endif
-

-
/************************* End ../ext/misc/fileio.c ********************/
-
/************************* Begin ../ext/misc/completion.c ******************/
+
/************************* End ../ext/misc/decimal.c ********************/
+
/************************* Begin ../ext/misc/ieee754.c ******************/
/*
-
** 2017-07-10
+
** 2013-04-17
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
@@ -3152,502 +2974,294 @@ int sqlite3_fileio_init(
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
-
*************************************************************************
+
******************************************************************************
**
-
** This file implements an eponymous virtual table that returns suggested
-
** completions for a partial SQL input.
+
** This SQLite extension implements functions for the exact display
+
** and input of IEEE754 Binary64 floating-point numbers.
**
-
** Suggested usage:
+
**   ieee754(X)
+
**   ieee754(Y,Z)
**
-
**     SELECT DISTINCT candidate COLLATE nocase
-
**       FROM completion($prefix,$wholeline)
-
**      ORDER BY 1;
+
** In the first form, the value X should be a floating-point number.
+
** The function will return a string of the form 'ieee754(Y,Z)' where
+
** Y and Z are integers such that X==Y*pow(2,Z).
**
-
** The two query parameters are optional.  $prefix is the text of the
-
** current word being typed and that is to be completed.  $wholeline is
-
** the complete input line, used for context.
+
** In the second form, Y and Z are integers which are the mantissa and
+
** base-2 exponent of a new floating point number.  The function returns
+
** a floating-point value equal to Y*pow(2,Z).
**
-
** The raw completion() table might return the same candidate multiple
-
** times, for example if the same column name is used to two or more
-
** tables.  And the candidates are returned in an arbitrary order.  Hence,
-
** the DISTINCT and ORDER BY are recommended.
+
** Examples:
**
-
** This virtual table operates at the speed of human typing, and so there
-
** is no attempt to make it fast.  Even a slow implementation will be much
-
** faster than any human can type.
+
**     ieee754(2.0)             ->     'ieee754(2,0)'
+
**     ieee754(45.25)           ->     'ieee754(181,-2)'
+
**     ieee754(2, 0)            ->     2.0
+
**     ieee754(181, -2)         ->     45.25
+
**
+
** Two additional functions break apart the one-argument ieee754()
+
** result into separate integer values:
+
**
+
**     ieee754_mantissa(45.25)  ->     181
+
**     ieee754_exponent(45.25)  ->     -2
+
**
+
** These functions convert binary64 numbers into blobs and back again.
+
**
+
**     ieee754_from_blob(x'3ff0000000000000')  ->  1.0
+
**     ieee754_to_blob(1.0)                    ->  x'3ff0000000000000'
+
**
+
** In all single-argument functions, if the argument is an 8-byte blob
+
** then that blob is interpreted as a big-endian binary64 value.
+
**
+
**
+
** EXACT DECIMAL REPRESENTATION OF BINARY64 VALUES
+
** -----------------------------------------------
+
**
+
** This extension in combination with the separate 'decimal' extension
+
** can be used to compute the exact decimal representation of binary64
+
** values.  To begin, first compute a table of exponent values:
+
**
+
**    CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT);
+
**    WITH RECURSIVE c(x,v) AS (
+
**      VALUES(0,'1')
+
**      UNION ALL
+
**      SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1<=971
+
**    ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
+
**    WITH RECURSIVE c(x,v) AS (
+
**      VALUES(-1,'0.5')
+
**      UNION ALL
+
**      SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1>=-1075
+
**    ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
+
**
+
** Then, to compute the exact decimal representation of a floating
+
** point value (the value 47.49 is used in the example) do:
+
**
+
**    WITH c(n) AS (VALUES(47.49))
+
**          ---------------^^^^^---- Replace with whatever you want
+
**    SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v)
+
**      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
+
**
+
** Here is a query to show various boundry values for the binary64
+
** number format:
+
**
+
**    WITH c(name,bin) AS (VALUES
+
**       ('minimum positive value',        x'0000000000000001'),
+
**       ('maximum subnormal value',       x'000fffffffffffff'),
+
**       ('mininum positive nornal value', x'0010000000000000'),
+
**       ('maximum value',                 x'7fefffffffffffff'))
+
**    SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v)
+
**      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin);
**
*/
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
-
#include <ctype.h>
-

-
#ifndef SQLITE_OMIT_VIRTUALTABLE
-

-
/* completion_vtab is a subclass of sqlite3_vtab which will
-
** serve as the underlying representation of a completion virtual table
-
*/
-
typedef struct completion_vtab completion_vtab;
-
struct completion_vtab {
-
  sqlite3_vtab base;  /* Base class - must be first */
-
  sqlite3 *db;        /* Database connection for this completion vtab */
-
};
-

-
/* completion_cursor is a subclass of sqlite3_vtab_cursor which will
-
** serve as the underlying representation of a cursor that scans
-
** over rows of the result
-
*/
-
typedef struct completion_cursor completion_cursor;
-
struct completion_cursor {
-
  sqlite3_vtab_cursor base;  /* Base class - must be first */
-
  sqlite3 *db;               /* Database connection for this cursor */
-
  int nPrefix, nLine;        /* Number of bytes in zPrefix and zLine */
-
  char *zPrefix;             /* The prefix for the word we want to complete */
-
  char *zLine;               /* The whole that we want to complete */
-
  const char *zCurrentRow;   /* Current output row */
-
  int szRow;                 /* Length of the zCurrentRow string */
-
  sqlite3_stmt *pStmt;       /* Current statement */
-
  sqlite3_int64 iRowid;      /* The rowid */
-
  int ePhase;                /* Current phase */
-
  int j;                     /* inter-phase counter */
-
};

-
/* Values for ePhase:
-
*/
-
#define COMPLETION_FIRST_PHASE   1
-
#define COMPLETION_KEYWORDS      1
-
#define COMPLETION_PRAGMAS       2
-
#define COMPLETION_FUNCTIONS     3
-
#define COMPLETION_COLLATIONS    4
-
#define COMPLETION_INDEXES       5
-
#define COMPLETION_TRIGGERS      6
-
#define COMPLETION_DATABASES     7
-
#define COMPLETION_TABLES        8    /* Also VIEWs and TRIGGERs */
-
#define COMPLETION_COLUMNS       9
-
#define COMPLETION_MODULES       10
-
#define COMPLETION_EOF           11
+
/* Mark a function parameter as unused, to suppress nuisance compiler
+
** warnings. */
+
#ifndef UNUSED_PARAMETER
+
# define UNUSED_PARAMETER(X)  (void)(X)
+
#endif

/*
-
** The completionConnect() method is invoked to create a new
-
** completion_vtab that describes the completion virtual table.
-
**
-
** Think of this routine as the constructor for completion_vtab objects.
-
**
-
** All this routine needs to do is:
-
**
-
**    (1) Allocate the completion_vtab object and initialize all fields.
-
**
-
**    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
-
**        result set of queries against completion will look like.
+
** Implementation of the ieee754() function
*/
-
static int completionConnect(
-
  sqlite3 *db,
-
  void *pAux,
-
  int argc, const char *const*argv,
-
  sqlite3_vtab **ppVtab,
-
  char **pzErr
+
static void ieee754func(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
){
-
  completion_vtab *pNew;
-
  int rc;
-

-
  (void)(pAux);    /* Unused parameter */
-
  (void)(argc);    /* Unused parameter */
-
  (void)(argv);    /* Unused parameter */
-
  (void)(pzErr);   /* Unused parameter */
-

-
/* Column numbers */
-
#define COMPLETION_COLUMN_CANDIDATE 0  /* Suggested completion of the input */
-
#define COMPLETION_COLUMN_PREFIX    1  /* Prefix of the word to be completed */
-
#define COMPLETION_COLUMN_WHOLELINE 2  /* Entire line seen so far */
-
#define COMPLETION_COLUMN_PHASE     3  /* ePhase - used for debugging only */
-

-
  sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
-
  rc = sqlite3_declare_vtab(db,
-
      "CREATE TABLE x("
-
      "  candidate TEXT,"
-
      "  prefix TEXT HIDDEN,"
-
      "  wholeline TEXT HIDDEN,"
-
      "  phase INT HIDDEN"        /* Used for debugging only */
-
      ")");
-
  if( rc==SQLITE_OK ){
-
    pNew = sqlite3_malloc( sizeof(*pNew) );
-
    *ppVtab = (sqlite3_vtab*)pNew;
-
    if( pNew==0 ) return SQLITE_NOMEM;
-
    memset(pNew, 0, sizeof(*pNew));
-
    pNew->db = db;
-
  }
-
  return rc;
-
}
-

-
/*
-
** This method is the destructor for completion_cursor objects.
-
*/
-
static int completionDisconnect(sqlite3_vtab *pVtab){
-
  sqlite3_free(pVtab);
-
  return SQLITE_OK;
-
}
-

-
/*
-
** Constructor for a new completion_cursor object.
-
*/
-
static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
-
  completion_cursor *pCur;
-
  pCur = sqlite3_malloc( sizeof(*pCur) );
-
  if( pCur==0 ) return SQLITE_NOMEM;
-
  memset(pCur, 0, sizeof(*pCur));
-
  pCur->db = ((completion_vtab*)p)->db;
-
  *ppCursor = &pCur->base;
-
  return SQLITE_OK;
-
}
-

-
/*
-
** Reset the completion_cursor.
-
*/
-
static void completionCursorReset(completion_cursor *pCur){
-
  sqlite3_free(pCur->zPrefix);   pCur->zPrefix = 0;  pCur->nPrefix = 0;
-
  sqlite3_free(pCur->zLine);     pCur->zLine = 0;    pCur->nLine = 0;
-
  sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
-
  pCur->j = 0;
-
}
-

-
/*
-
** Destructor for a completion_cursor.
-
*/
-
static int completionClose(sqlite3_vtab_cursor *cur){
-
  completionCursorReset((completion_cursor*)cur);
-
  sqlite3_free(cur);
-
  return SQLITE_OK;
-
}
-

-
/*
-
** Advance a completion_cursor to its next row of output.
-
**
-
** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
-
** record the current state of the scan.  This routine sets ->zCurrentRow
-
** to the current row of output and then returns.  If no more rows remain,
-
** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
-
** table that has reached the end of its scan.
-
**
-
** The current implementation just lists potential identifiers and
-
** keywords and filters them by zPrefix.  Future enhancements should
-
** take zLine into account to try to restrict the set of identifiers and
-
** keywords based on what would be legal at the current point of input.
-
*/
-
static int completionNext(sqlite3_vtab_cursor *cur){
-
  completion_cursor *pCur = (completion_cursor*)cur;
-
  int eNextPhase = 0;  /* Next phase to try if current phase reaches end */
-
  int iCol = -1;       /* If >=0, step pCur->pStmt and use the i-th column */
-
  pCur->iRowid++;
-
  while( pCur->ePhase!=COMPLETION_EOF ){
-
    switch( pCur->ePhase ){
-
      case COMPLETION_KEYWORDS: {
-
        if( pCur->j >= sqlite3_keyword_count() ){
-
          pCur->zCurrentRow = 0;
-
          pCur->ePhase = COMPLETION_DATABASES;
-
        }else{
-
          sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
-
        }
-
        iCol = -1;
-
        break;
-
      }
-
      case COMPLETION_DATABASES: {
-
        if( pCur->pStmt==0 ){
-
          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
-
                             &pCur->pStmt, 0);
-
        }
-
        iCol = 1;
-
        eNextPhase = COMPLETION_TABLES;
-
        break;
-
      }
-
      case COMPLETION_TABLES: {
-
        if( pCur->pStmt==0 ){
-
          sqlite3_stmt *pS2;
-
          char *zSql = 0;
-
          const char *zSep = "";
-
          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
-
          while( sqlite3_step(pS2)==SQLITE_ROW ){
-
            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
-
            zSql = sqlite3_mprintf(
-
               "%z%s"
-
               "SELECT name FROM \"%w\".sqlite_schema",
-
               zSql, zSep, zDb
-
            );
-
            if( zSql==0 ) return SQLITE_NOMEM;
-
            zSep = " UNION ";
-
          }
-
          sqlite3_finalize(pS2);
-
          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
-
          sqlite3_free(zSql);
-
        }
-
        iCol = 0;
-
        eNextPhase = COMPLETION_COLUMNS;
-
        break;
-
      }
-
      case COMPLETION_COLUMNS: {
-
        if( pCur->pStmt==0 ){
-
          sqlite3_stmt *pS2;
-
          char *zSql = 0;
-
          const char *zSep = "";
-
          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
-
          while( sqlite3_step(pS2)==SQLITE_ROW ){
-
            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
-
            zSql = sqlite3_mprintf(
-
               "%z%s"
-
               "SELECT pti.name FROM \"%w\".sqlite_schema AS sm"
-
                       " JOIN pragma_table_info(sm.name,%Q) AS pti"
-
               " WHERE sm.type='table'",
-
               zSql, zSep, zDb, zDb
-
            );
-
            if( zSql==0 ) return SQLITE_NOMEM;
-
            zSep = " UNION ";
-
          }
-
          sqlite3_finalize(pS2);
-
          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
-
          sqlite3_free(zSql);
-
        }
-
        iCol = 0;
-
        eNextPhase = COMPLETION_EOF;
-
        break;
+
  if( argc==1 ){
+
    sqlite3_int64 m, a;
+
    double r;
+
    int e;
+
    int isNeg;
+
    char zResult[100];
+
    assert( sizeof(m)==sizeof(r) );
+
    if( sqlite3_value_type(argv[0])==SQLITE_BLOB
+
     && sqlite3_value_bytes(argv[0])==sizeof(r)
+
    ){
+
      const unsigned char *x = sqlite3_value_blob(argv[0]);
+
      unsigned int i;
+
      sqlite3_uint64 v = 0;
+
      for(i=0; i<sizeof(r); i++){
+
        v = (v<<8) | x[i];
      }
+
      memcpy(&r, &v, sizeof(r));
+
    }else{
+
      r = sqlite3_value_double(argv[0]);
    }
-
    if( iCol<0 ){
-
      /* This case is when the phase presets zCurrentRow */
-
      if( pCur->zCurrentRow==0 ) continue;
+
    if( r<0.0 ){
+
      isNeg = 1;
+
      r = -r;
    }else{
-
      if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
-
        /* Extract the next row of content */
-
        pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
-
        pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
+
      isNeg = 0;
+
    }
+
    memcpy(&a,&r,sizeof(a));
+
    if( a==0 ){
+
      e = 0;
+
      m = 0;
+
    }else{
+
      e = a>>52;
+
      m = a & ((((sqlite3_int64)1)<<52)-1);
+
      if( e==0 ){
+
        m <<= 1;
      }else{
-
        /* When all rows are finished, advance to the next phase */
-
        sqlite3_finalize(pCur->pStmt);
-
        pCur->pStmt = 0;
-
        pCur->ePhase = eNextPhase;
-
        continue;
+
        m |= ((sqlite3_int64)1)<<52;
+
      }
+
      while( e<1075 && m>0 && (m&1)==0 ){
+
        m >>= 1;
+
        e++;
      }
+
      if( isNeg ) m = -m;
    }
-
    if( pCur->nPrefix==0 ) break;
-
    if( pCur->nPrefix<=pCur->szRow
-
     && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
-
    ){
-
      break;
+
    switch( *(int*)sqlite3_user_data(context) ){
+
      case 0:
+
        sqlite3_snprintf(sizeof(zResult), zResult, "ieee754(%lld,%d)",
+
                         m, e-1075);
+
        sqlite3_result_text(context, zResult, -1, SQLITE_TRANSIENT);
+
        break;
+
      case 1:
+
        sqlite3_result_int64(context, m);
+
        break;
+
      case 2:
+
        sqlite3_result_int(context, e-1075);
+
        break;
    }
-
  }
+
  }else{
+
    sqlite3_int64 m, e, a;
+
    double r;
+
    int isNeg = 0;
+
    m = sqlite3_value_int64(argv[0]);
+
    e = sqlite3_value_int64(argv[1]);

-
  return SQLITE_OK;
-
}
+
    /* Limit the range of e.  Ticket 22dea1cfdb9151e4 2021-03-02 */
+
    if( e>10000 ){
+
      e = 10000;
+
    }else if( e<-10000 ){
+
      e = -10000;
+
    }

-
/*
-
** Return values of columns for the row at which the completion_cursor
-
** is currently pointing.
-
*/
-
static int completionColumn(
-
  sqlite3_vtab_cursor *cur,   /* The cursor */
-
  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
-
  int i                       /* Which column to return */
-
){
-
  completion_cursor *pCur = (completion_cursor*)cur;
-
  switch( i ){
-
    case COMPLETION_COLUMN_CANDIDATE: {
-
      sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
-
      break;
+
    if( m<0 ){
+
      isNeg = 1;
+
      m = -m;
+
      if( m<0 ) return;
+
    }else if( m==0 && e>-1000 && e<1000 ){
+
      sqlite3_result_double(context, 0.0);
+
      return;
    }
-
    case COMPLETION_COLUMN_PREFIX: {
-
      sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
-
      break;
+
    while( (m>>32)&0xffe00000 ){
+
      m >>= 1;
+
      e++;
    }
-
    case COMPLETION_COLUMN_WHOLELINE: {
-
      sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
-
      break;
+
    while( m!=0 && ((m>>32)&0xfff00000)==0 ){
+
      m <<= 1;
+
      e--;
    }
-
    case COMPLETION_COLUMN_PHASE: {
-
      sqlite3_result_int(ctx, pCur->ePhase);
-
      break;
+
    e += 1075;
+
    if( e<=0 ){
+
      /* Subnormal */
+
      if( 1-e >= 64 ){
+
        m = 0;
+
      }else{
+
        m >>= 1-e;
+
      }
+
      e = 0;
+
    }else if( e>0x7ff ){
+
      e = 0x7ff;
    }
+
    a = m & ((((sqlite3_int64)1)<<52)-1);
+
    a |= e<<52;
+
    if( isNeg ) a |= ((sqlite3_uint64)1)<<63;
+
    memcpy(&r, &a, sizeof(r));
+
    sqlite3_result_double(context, r);
  }
-
  return SQLITE_OK;
}

/*
-
** Return the rowid for the current row.  In this implementation, the
-
** rowid is the same as the output value.
+
** Functions to convert between blobs and floats.
*/
-
static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
-
  completion_cursor *pCur = (completion_cursor*)cur;
-
  *pRowid = pCur->iRowid;
-
  return SQLITE_OK;
-
}
-

-
/*
-
** Return TRUE if the cursor has been moved off of the last
-
** row of output.
-
*/
-
static int completionEof(sqlite3_vtab_cursor *cur){
-
  completion_cursor *pCur = (completion_cursor*)cur;
-
  return pCur->ePhase >= COMPLETION_EOF;
-
}
-

-
/*
-
** This method is called to "rewind" the completion_cursor object back
-
** to the first row of output.  This method is always called at least
-
** once prior to any call to completionColumn() or completionRowid() or 
-
** completionEof().
-
*/
-
static int completionFilter(
-
  sqlite3_vtab_cursor *pVtabCursor, 
-
  int idxNum, const char *idxStr,
-
  int argc, sqlite3_value **argv
+
static void ieee754func_from_blob(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
){
-
  completion_cursor *pCur = (completion_cursor *)pVtabCursor;
-
  int iArg = 0;
-
  (void)(idxStr);   /* Unused parameter */
-
  (void)(argc);     /* Unused parameter */
-
  completionCursorReset(pCur);
-
  if( idxNum & 1 ){
-
    pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
-
    if( pCur->nPrefix>0 ){
-
      pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
-
      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
-
    }
-
    iArg = 1;
-
  }
-
  if( idxNum & 2 ){
-
    pCur->nLine = sqlite3_value_bytes(argv[iArg]);
-
    if( pCur->nLine>0 ){
-
      pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
-
      if( pCur->zLine==0 ) return SQLITE_NOMEM;
-
    }
-
  }
-
  if( pCur->zLine!=0 && pCur->zPrefix==0 ){
-
    int i = pCur->nLine;
-
    while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
-
      i--;
-
    }
-
    pCur->nPrefix = pCur->nLine - i;
-
    if( pCur->nPrefix>0 ){
-
      pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
-
      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
+
  UNUSED_PARAMETER(argc);
+
  if( sqlite3_value_type(argv[0])==SQLITE_BLOB
+
   && sqlite3_value_bytes(argv[0])==sizeof(double)
+
  ){
+
    double r;
+
    const unsigned char *x = sqlite3_value_blob(argv[0]);
+
    unsigned int i;
+
    sqlite3_uint64 v = 0;
+
    for(i=0; i<sizeof(r); i++){
+
      v = (v<<8) | x[i];
    }
+
    memcpy(&r, &v, sizeof(r));
+
    sqlite3_result_double(context, r);
  }
-
  pCur->iRowid = 0;
-
  pCur->ePhase = COMPLETION_FIRST_PHASE;
-
  return completionNext(pVtabCursor);
}
-

-
/*
-
** SQLite will invoke this method one or more times while planning a query
-
** that uses the completion virtual table.  This routine needs to create
-
** a query plan for each invocation and compute an estimated cost for that
-
** plan.
-
**
-
** There are two hidden parameters that act as arguments to the table-valued
-
** function:  "prefix" and "wholeline".  Bit 0 of idxNum is set if "prefix"
-
** is available and bit 1 is set if "wholeline" is available.
-
*/
-
static int completionBestIndex(
-
  sqlite3_vtab *tab,
-
  sqlite3_index_info *pIdxInfo
+
static void ieee754func_to_blob(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
){
-
  int i;                 /* Loop over constraints */
-
  int idxNum = 0;        /* The query plan bitmask */
-
  int prefixIdx = -1;    /* Index of the start= constraint, or -1 if none */
-
  int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
-
  int nArg = 0;          /* Number of arguments that completeFilter() expects */
-
  const struct sqlite3_index_constraint *pConstraint;
-

-
  (void)(tab);    /* Unused parameter */
-
  pConstraint = pIdxInfo->aConstraint;
-
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
-
    if( pConstraint->usable==0 ) continue;
-
    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
-
    switch( pConstraint->iColumn ){
-
      case COMPLETION_COLUMN_PREFIX:
-
        prefixIdx = i;
-
        idxNum |= 1;
-
        break;
-
      case COMPLETION_COLUMN_WHOLELINE:
-
        wholelineIdx = i;
-
        idxNum |= 2;
-
        break;
+
  UNUSED_PARAMETER(argc);
+
  if( sqlite3_value_type(argv[0])==SQLITE_FLOAT
+
   || sqlite3_value_type(argv[0])==SQLITE_INTEGER
+
  ){
+
    double r = sqlite3_value_double(argv[0]);
+
    sqlite3_uint64 v;
+
    unsigned char a[sizeof(r)];
+
    unsigned int i;
+
    memcpy(&v, &r, sizeof(r));
+
    for(i=1; i<=sizeof(r); i++){
+
      a[sizeof(r)-i] = v&0xff;
+
      v >>= 8;
    }
+
    sqlite3_result_blob(context, a, sizeof(r), SQLITE_TRANSIENT);
  }
-
  if( prefixIdx>=0 ){
-
    pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
-
    pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
-
  }
-
  if( wholelineIdx>=0 ){
-
    pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
-
    pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
-
  }
-
  pIdxInfo->idxNum = idxNum;
-
  pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
-
  pIdxInfo->estimatedRows = 500 - 100*nArg;
-
  return SQLITE_OK;
}

-
/*
-
** This following structure defines all the methods for the 
-
** completion virtual table.
-
*/
-
static sqlite3_module completionModule = {
-
  0,                         /* iVersion */
-
  0,                         /* xCreate */
-
  completionConnect,         /* xConnect */
-
  completionBestIndex,       /* xBestIndex */
-
  completionDisconnect,      /* xDisconnect */
-
  0,                         /* xDestroy */
-
  completionOpen,            /* xOpen - open a cursor */
-
  completionClose,           /* xClose - close a cursor */
-
  completionFilter,          /* xFilter - configure scan constraints */
-
  completionNext,            /* xNext - advance a cursor */
-
  completionEof,             /* xEof - check for end of scan */
-
  completionColumn,          /* xColumn - read data */
-
  completionRowid,           /* xRowid - read data */
-
  0,                         /* xUpdate */
-
  0,                         /* xBegin */
-
  0,                         /* xSync */
-
  0,                         /* xCommit */
-
  0,                         /* xRollback */
-
  0,                         /* xFindMethod */
-
  0,                         /* xRename */
-
  0,                         /* xSavepoint */
-
  0,                         /* xRelease */
-
  0,                         /* xRollbackTo */
-
  0                          /* xShadowName */
-
};
-

-
#endif /* SQLITE_OMIT_VIRTUALTABLE */
-

-
int sqlite3CompletionVtabInit(sqlite3 *db){
-
  int rc = SQLITE_OK;
-
#ifndef SQLITE_OMIT_VIRTUALTABLE
-
  rc = sqlite3_create_module(db, "completion", &completionModule, 0);
-
#endif
-
  return rc;
-
}

#ifdef _WIN32

#endif
-
int sqlite3_completion_init(
+
int sqlite3_ieee_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
+
  static const struct {
+
    char *zFName;
+
    int nArg;
+
    int iAux;
+
    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
+
  } aFunc[] = {
+
    { "ieee754",           1,   0, ieee754func },
+
    { "ieee754",           2,   0, ieee754func },
+
    { "ieee754_mantissa",  1,   1, ieee754func },
+
    { "ieee754_exponent",  1,   2, ieee754func },
+
    { "ieee754_to_blob",   1,   0, ieee754func_to_blob },
+
    { "ieee754_from_blob", 1,   0, ieee754func_from_blob },
+

+
  };
+
  unsigned int i;
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
-
  (void)(pzErrMsg);  /* Unused parameter */
-
#ifndef SQLITE_OMIT_VIRTUALTABLE
-
  rc = sqlite3CompletionVtabInit(db);
-
#endif
+
  (void)pzErrMsg;  /* Unused parameter */
+
  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
+
    rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
+
                               SQLITE_UTF8|SQLITE_INNOCUOUS,
+
                               (void*)&aFunc[i].iAux,
+
                               aFunc[i].xFunc, 0, 0);
+
  }
  return rc;
}

-
/************************* End ../ext/misc/completion.c ********************/
-
/************************* Begin ../ext/misc/appendvfs.c ******************/
+
/************************* End ../ext/misc/ieee754.c ********************/
+
/************************* Begin ../ext/misc/series.c ******************/
/*
-
** 2017-10-20
+
** 2015-08-18
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
@@ -3656,879 +3270,1237 @@ int sqlite3_completion_init(
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
-
******************************************************************************
-
**
-
** This file implements a VFS shim that allows an SQLite database to be
-
** appended onto the end of some other file, such as an executable.
+
*************************************************************************
**
-
** A special record must appear at the end of the file that identifies the
-
** file as an appended database and provides the offset to the first page
-
** of the exposed content. (Or, it is the length of the content prefix.)
-
** For best performance page 1 should be located at a disk page boundary,
-
** though that is not required.
+
** This file demonstrates how to create a table-valued-function using
+
** a virtual table.  This demo implements the generate_series() function
+
** which gives similar results to the eponymous function in PostgreSQL.
+
** Examples:
**
-
** When opening a database using this VFS, the connection might treat
-
** the file as an ordinary SQLite database, or it might treat it as a
-
** database appended onto some other file.  The decision is made by
-
** applying the following rules in order:
+
**      SELECT * FROM generate_series(0,100,5);
**
-
**  (1)  An empty file is an ordinary database.
+
** The query above returns integers from 0 through 100 counting by steps
+
** of 5.
**
-
**  (2)  If the file ends with the appendvfs trailer string
-
**       "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
+
**      SELECT * FROM generate_series(0,100);
**
-
**  (3)  If the file begins with the standard SQLite prefix string
-
**       "SQLite format 3", that file is an ordinary database.
+
** Integers from 0 through 100 with a step size of 1.
**
-
**  (4)  If none of the above apply and the SQLITE_OPEN_CREATE flag is
-
**       set, then a new database is appended to the already existing file.
+
**      SELECT * FROM generate_series(20) LIMIT 10;
**
-
**  (5)  Otherwise, SQLITE_CANTOPEN is returned.
+
** Integers 20 through 29.
**
-
** To avoid unnecessary complications with the PENDING_BYTE, the size of
-
** the file containing the database is limited to 1GiB. (1073741824 bytes)
-
** This VFS will not read or write past the 1GiB mark.  This restriction
-
** might be lifted in future versions.  For now, if you need a larger
-
** database, then keep it in a separate file.
+
** HOW IT WORKS
**
-
** If the file being opened is a plain database (not an appended one), then
-
** this shim is a pass-through into the default underlying VFS. (rule 3)
-
**/
-
/* #include "sqlite3ext.h" */
-
SQLITE_EXTENSION_INIT1
-
#include <string.h>
-
#include <assert.h>
-

-
/* The append mark at the end of the database is:
+
** The generate_series "function" is really a virtual table with the
+
** following schema:
**
-
**     Start-Of-SQLite3-NNNNNNNN
-
**     123456789 123456789 12345
+
**     CREATE TABLE generate_series(
+
**       value,
+
**       start HIDDEN,
+
**       stop HIDDEN,
+
**       step HIDDEN
+
**     );
**
-
** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
-
** the offset to page 1, and also the length of the prefix content.
+
** Function arguments in queries against this virtual table are translated
+
** into equality constraints against successive hidden columns.  In other
+
** words, the following pairs of queries are equivalent to each other:
+
**
+
**    SELECT * FROM generate_series(0,100,5);
+
**    SELECT * FROM generate_series WHERE start=0 AND stop=100 AND step=5;
+
**
+
**    SELECT * FROM generate_series(0,100);
+
**    SELECT * FROM generate_series WHERE start=0 AND stop=100;
+
**
+
**    SELECT * FROM generate_series(20) LIMIT 10;
+
**    SELECT * FROM generate_series WHERE start=20 LIMIT 10;
+
**
+
** The generate_series virtual table implementation leaves the xCreate method
+
** set to NULL.  This means that it is not possible to do a CREATE VIRTUAL
+
** TABLE command with "generate_series" as the USING argument.  Instead, there
+
** is a single generate_series virtual table that is always available without
+
** having to be created first.
+
**
+
** The xBestIndex method looks for equality constraints against the hidden
+
** start, stop, and step columns, and if present, it uses those constraints
+
** to bound the sequence of generated values.  If the equality constraints
+
** are missing, it uses 0 for start, 4294967295 for stop, and 1 for step.
+
** xBestIndex returns a small cost when both start and stop are available,
+
** and a very large cost if either start or stop are unavailable.  This
+
** encourages the query planner to order joins such that the bounds of the
+
** series are well-defined.
*/
-
#define APND_MARK_PREFIX     "Start-Of-SQLite3-"
-
#define APND_MARK_PREFIX_SZ  17
-
#define APND_MARK_FOS_SZ      8
-
#define APND_MARK_SIZE       (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ)
+
/* #include "sqlite3ext.h" */
+
SQLITE_EXTENSION_INIT1
+
#include <assert.h>
+
#include <string.h>
+

+
#ifndef SQLITE_OMIT_VIRTUALTABLE
+

+

+
/* series_cursor is a subclass of sqlite3_vtab_cursor which will
+
** serve as the underlying representation of a cursor that scans
+
** over rows of the result
+
*/
+
typedef struct series_cursor series_cursor;
+
struct series_cursor {
+
  sqlite3_vtab_cursor base;  /* Base class - must be first */
+
  int isDesc;                /* True to count down rather than up */
+
  sqlite3_int64 iRowid;      /* The rowid */
+
  sqlite3_int64 iValue;      /* Current value ("value") */
+
  sqlite3_int64 mnValue;     /* Mimimum value ("start") */
+
  sqlite3_int64 mxValue;     /* Maximum value ("stop") */
+
  sqlite3_int64 iStep;       /* Increment ("step") */
+
};

/*
-
** Maximum size of the combined prefix + database + append-mark.  This
-
** must be less than 0x40000000 to avoid locking issues on Windows.
+
** The seriesConnect() method is invoked to create a new
+
** series_vtab that describes the generate_series virtual table.
+
**
+
** Think of this routine as the constructor for series_vtab objects.
+
**
+
** All this routine needs to do is:
+
**
+
**    (1) Allocate the series_vtab object and initialize all fields.
+
**
+
**    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
+
**        result set of queries against generate_series will look like.
*/
-
#define APND_MAX_SIZE  (0x40000000)
+
static int seriesConnect(
+
  sqlite3 *db,
+
  void *pUnused,
+
  int argcUnused, const char *const*argvUnused,
+
  sqlite3_vtab **ppVtab,
+
  char **pzErrUnused
+
){
+
  sqlite3_vtab *pNew;
+
  int rc;
+

+
/* Column numbers */
+
#define SERIES_COLUMN_VALUE 0
+
#define SERIES_COLUMN_START 1
+
#define SERIES_COLUMN_STOP  2
+
#define SERIES_COLUMN_STEP  3
+

+
  (void)pUnused;
+
  (void)argcUnused;
+
  (void)argvUnused;
+
  (void)pzErrUnused;
+
  rc = sqlite3_declare_vtab(db,
+
     "CREATE TABLE x(value,start hidden,stop hidden,step hidden)");
+
  if( rc==SQLITE_OK ){
+
    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
+
    if( pNew==0 ) return SQLITE_NOMEM;
+
    memset(pNew, 0, sizeof(*pNew));
+
    sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
+
  }
+
  return rc;
+
}

/*
-
** Try to align the database to an even multiple of APND_ROUNDUP bytes.
+
** This method is the destructor for series_cursor objects.
*/
-
#ifndef APND_ROUNDUP
-
#define APND_ROUNDUP 4096
-
#endif
-
#define APND_ALIGN_MASK         ((sqlite3_int64)(APND_ROUNDUP-1))
-
#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK)
+
static int seriesDisconnect(sqlite3_vtab *pVtab){
+
  sqlite3_free(pVtab);
+
  return SQLITE_OK;
+
}

/*
-
** Forward declaration of objects used by this utility
+
** Constructor for a new series_cursor object.
*/
-
typedef struct sqlite3_vfs ApndVfs;
-
typedef struct ApndFile ApndFile;
+
static int seriesOpen(sqlite3_vtab *pUnused, sqlite3_vtab_cursor **ppCursor){
+
  series_cursor *pCur;
+
  (void)pUnused;
+
  pCur = sqlite3_malloc( sizeof(*pCur) );
+
  if( pCur==0 ) return SQLITE_NOMEM;
+
  memset(pCur, 0, sizeof(*pCur));
+
  *ppCursor = &pCur->base;
+
  return SQLITE_OK;
+
}

-
/* Access to a lower-level VFS that (might) implement dynamic loading,
-
** access to randomness, etc.
+
/*
+
** Destructor for a series_cursor.
*/
-
#define ORIGVFS(p)  ((sqlite3_vfs*)((p)->pAppData))
-
#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
+
static int seriesClose(sqlite3_vtab_cursor *cur){
+
  sqlite3_free(cur);
+
  return SQLITE_OK;
+
}

-
/* An open appendvfs file
-
**
-
** An instance of this structure describes the appended database file.
-
** A separate sqlite3_file object is always appended. The appended
-
** sqlite3_file object (which can be accessed using ORIGFILE()) describes
-
** the entire file, including the prefix, the database, and the
-
** append-mark.
-
**
-
** The structure of an AppendVFS database is like this:
-
**
-
**   +-------------+---------+----------+-------------+
-
**   | prefix-file | padding | database | append-mark |
-
**   +-------------+---------+----------+-------------+
-
**                           ^          ^
-
**                           |          |
-
**                         iPgOne      iMark
-
**
-
**
-
** "prefix file" -  file onto which the database has been appended.
-
** "padding"     -  zero or more bytes inserted so that "database"
-
**                  starts on an APND_ROUNDUP boundary
-
** "database"    -  The SQLite database file
-
** "append-mark" -  The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates
-
**                  the offset from the start of prefix-file to the start
-
**                  of "database".
-
**
-
** The size of the database is iMark - iPgOne.
-
**
-
** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value
-
** of iPgOne stored as a big-ending 64-bit integer.
-
**
-
** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE).
-
** Or, iMark is -1 to indicate that it has not yet been written.
+

+
/*
+
** Advance a series_cursor to its next row of output.
*/
-
struct ApndFile {
-
  sqlite3_file base;        /* Subclass.  MUST BE FIRST! */
-
  sqlite3_int64 iPgOne;     /* Offset to the start of the database */
-
  sqlite3_int64 iMark;      /* Offset of the append mark.  -1 if unwritten */
-
  /* Always followed by another sqlite3_file that describes the whole file */
-
};
+
static int seriesNext(sqlite3_vtab_cursor *cur){
+
  series_cursor *pCur = (series_cursor*)cur;
+
  if( pCur->isDesc ){
+
    pCur->iValue -= pCur->iStep;
+
  }else{
+
    pCur->iValue += pCur->iStep;
+
  }
+
  pCur->iRowid++;
+
  return SQLITE_OK;
+
}

/*
-
** Methods for ApndFile
+
** Return values of columns for the row at which the series_cursor
+
** is currently pointing.
*/
-
static int apndClose(sqlite3_file*);
-
static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
-
static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
-
static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
-
static int apndSync(sqlite3_file*, int flags);
-
static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
-
static int apndLock(sqlite3_file*, int);
-
static int apndUnlock(sqlite3_file*, int);
-
static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
-
static int apndFileControl(sqlite3_file*, int op, void *pArg);
-
static int apndSectorSize(sqlite3_file*);
-
static int apndDeviceCharacteristics(sqlite3_file*);
-
static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
-
static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
-
static void apndShmBarrier(sqlite3_file*);
-
static int apndShmUnmap(sqlite3_file*, int deleteFlag);
-
static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
-
static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
+
static int seriesColumn(
+
  sqlite3_vtab_cursor *cur,   /* The cursor */
+
  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
+
  int i                       /* Which column to return */
+
){
+
  series_cursor *pCur = (series_cursor*)cur;
+
  sqlite3_int64 x = 0;
+
  switch( i ){
+
    case SERIES_COLUMN_START:  x = pCur->mnValue; break;
+
    case SERIES_COLUMN_STOP:   x = pCur->mxValue; break;
+
    case SERIES_COLUMN_STEP:   x = pCur->iStep;   break;
+
    default:                   x = pCur->iValue;  break;
+
  }
+
  sqlite3_result_int64(ctx, x);
+
  return SQLITE_OK;
+
}

/*
-
** Methods for ApndVfs
+
** Return the rowid for the current row. In this implementation, the
+
** first row returned is assigned rowid value 1, and each subsequent
+
** row a value 1 more than that of the previous.
*/
-
static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
-
static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
-
static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
-
static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
-
static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
-
static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
-
static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
-
static void apndDlClose(sqlite3_vfs*, void*);
-
static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
-
static int apndSleep(sqlite3_vfs*, int microseconds);
-
static int apndCurrentTime(sqlite3_vfs*, double*);
-
static int apndGetLastError(sqlite3_vfs*, int, char *);
-
static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
-
static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
-
static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
-
static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);
-

-
static sqlite3_vfs apnd_vfs = {
-
  3,                            /* iVersion (set when registered) */
-
  0,                            /* szOsFile (set when registered) */
-
  1024,                         /* mxPathname */
-
  0,                            /* pNext */
-
  "apndvfs",                    /* zName */
-
  0,                            /* pAppData (set when registered) */ 
-
  apndOpen,                     /* xOpen */
-
  apndDelete,                   /* xDelete */
-
  apndAccess,                   /* xAccess */
-
  apndFullPathname,             /* xFullPathname */
-
  apndDlOpen,                   /* xDlOpen */
-
  apndDlError,                  /* xDlError */
-
  apndDlSym,                    /* xDlSym */
-
  apndDlClose,                  /* xDlClose */
-
  apndRandomness,               /* xRandomness */
-
  apndSleep,                    /* xSleep */
-
  apndCurrentTime,              /* xCurrentTime */
-
  apndGetLastError,             /* xGetLastError */
-
  apndCurrentTimeInt64,         /* xCurrentTimeInt64 */
-
  apndSetSystemCall,            /* xSetSystemCall */
-
  apndGetSystemCall,            /* xGetSystemCall */
-
  apndNextSystemCall            /* xNextSystemCall */
-
};
-

-
static const sqlite3_io_methods apnd_io_methods = {
-
  3,                              /* iVersion */
-
  apndClose,                      /* xClose */
-
  apndRead,                       /* xRead */
-
  apndWrite,                      /* xWrite */
-
  apndTruncate,                   /* xTruncate */
-
  apndSync,                       /* xSync */
-
  apndFileSize,                   /* xFileSize */
-
  apndLock,                       /* xLock */
-
  apndUnlock,                     /* xUnlock */
-
  apndCheckReservedLock,          /* xCheckReservedLock */
-
  apndFileControl,                /* xFileControl */
-
  apndSectorSize,                 /* xSectorSize */
-
  apndDeviceCharacteristics,      /* xDeviceCharacteristics */
-
  apndShmMap,                     /* xShmMap */
-
  apndShmLock,                    /* xShmLock */
-
  apndShmBarrier,                 /* xShmBarrier */
-
  apndShmUnmap,                   /* xShmUnmap */
-
  apndFetch,                      /* xFetch */
-
  apndUnfetch                     /* xUnfetch */
-
};
+
static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+
  series_cursor *pCur = (series_cursor*)cur;
+
  *pRowid = pCur->iRowid;
+
  return SQLITE_OK;
+
}

/*
-
** Close an apnd-file.
+
** Return TRUE if the cursor has been moved off of the last
+
** row of output.
*/
-
static int apndClose(sqlite3_file *pFile){
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xClose(pFile);
+
static int seriesEof(sqlite3_vtab_cursor *cur){
+
  series_cursor *pCur = (series_cursor*)cur;
+
  if( pCur->isDesc ){
+
    return pCur->iValue < pCur->mnValue;
+
  }else{
+
    return pCur->iValue > pCur->mxValue;
+
  }
}

-
/*
-
** Read data from an apnd-file.
+
/* True to cause run-time checking of the start=, stop=, and/or step= 
+
** parameters.  The only reason to do this is for testing the
+
** constraint checking logic for virtual tables in the SQLite core.
*/
-
static int apndRead(
-
  sqlite3_file *pFile, 
-
  void *zBuf, 
-
  int iAmt, 
-
  sqlite_int64 iOfst
-
){
-
  ApndFile *paf = (ApndFile *)pFile;
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
-
}
+
#ifndef SQLITE_SERIES_CONSTRAINT_VERIFY
+
# define SQLITE_SERIES_CONSTRAINT_VERIFY 0
+
#endif

/*
-
** Add the append-mark onto what should become the end of the file.
-
*  If and only if this succeeds, internal ApndFile.iMark is updated.
-
*  Parameter iWriteEnd is the appendvfs-relative offset of the new mark.
+
** This method is called to "rewind" the series_cursor object back
+
** to the first row of output.  This method is always called at least
+
** once prior to any call to seriesColumn() or seriesRowid() or 
+
** seriesEof().
+
**
+
** The query plan selected by seriesBestIndex is passed in the idxNum
+
** parameter.  (idxStr is not used in this implementation.)  idxNum
+
** is a bitmask showing which constraints are available:
+
**
+
**    1:    start=VALUE
+
**    2:    stop=VALUE
+
**    4:    step=VALUE
+
**
+
** Also, if bit 8 is set, that means that the series should be output
+
** in descending order rather than in ascending order.  If bit 16 is
+
** set, then output must appear in ascending order.
+
**
+
** This routine should initialize the cursor and position it so that it
+
** is pointing at the first row, or pointing off the end of the table
+
** (so that seriesEof() will return true) if the table is empty.
*/
-
static int apndWriteMark(
-
  ApndFile *paf,
-
  sqlite3_file *pFile,
-
  sqlite_int64 iWriteEnd
+
static int seriesFilter(
+
  sqlite3_vtab_cursor *pVtabCursor, 
+
  int idxNum, const char *idxStrUnused,
+
  int argc, sqlite3_value **argv
){
-
  sqlite_int64 iPgOne = paf->iPgOne;
-
  unsigned char a[APND_MARK_SIZE];
-
  int i = APND_MARK_FOS_SZ;
-
  int rc;
-
  assert(pFile == ORIGFILE(paf));
-
  memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
-
  while( --i >= 0 ){
-
    a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
-
    iPgOne >>= 8;
+
  series_cursor *pCur = (series_cursor *)pVtabCursor;
+
  int i = 0;
+
  (void)idxStrUnused;
+
  if( idxNum & 1 ){
+
    pCur->mnValue = sqlite3_value_int64(argv[i++]);
+
  }else{
+
    pCur->mnValue = 0;
  }
-
  iWriteEnd += paf->iPgOne;
-
  if( SQLITE_OK==(rc = pFile->pMethods->xWrite
-
                  (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
-
    paf->iMark = iWriteEnd;
+
  if( idxNum & 2 ){
+
    pCur->mxValue = sqlite3_value_int64(argv[i++]);
+
  }else{
+
    pCur->mxValue = 0xffffffff;
  }
-
  return rc;
-
}
-

-
/*
-
** Write data to an apnd-file.
-
*/
-
static int apndWrite(
-
  sqlite3_file *pFile,
-
  const void *zBuf,
-
  int iAmt,
-
  sqlite_int64 iOfst
-
){
-
  ApndFile *paf = (ApndFile *)pFile;
-
  sqlite_int64 iWriteEnd = iOfst + iAmt;
-
  if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
-
  pFile = ORIGFILE(pFile);
-
  /* If append-mark is absent or will be overwritten, write it. */
-
  if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
-
    int rc = apndWriteMark(paf, pFile, iWriteEnd);
-
    if( SQLITE_OK!=rc ) return rc;
+
  if( idxNum & 4 ){
+
    pCur->iStep = sqlite3_value_int64(argv[i++]);
+
    if( pCur->iStep==0 ){
+
      pCur->iStep = 1;
+
    }else if( pCur->iStep<0 ){
+
      pCur->iStep = -pCur->iStep;
+
      if( (idxNum & 16)==0 ) idxNum |= 8;
+
    }
+
  }else{
+
    pCur->iStep = 1;
  }
-
  return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
-
}
-

-
/*
-
** Truncate an apnd-file.
-
*/
-
static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
-
  ApndFile *paf = (ApndFile *)pFile;
-
  pFile = ORIGFILE(pFile);
-
  /* The append mark goes out first so truncate failure does not lose it. */
-
  if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR;
-
  /* Truncate underlying file just past append mark */
-
  return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
-
}
-

-
/*
-
** Sync an apnd-file.
-
*/
-
static int apndSync(sqlite3_file *pFile, int flags){
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xSync(pFile, flags);
-
}
-

-
/*
-
** Return the current file-size of an apnd-file.
-
** If the append mark is not yet there, the file-size is 0.
-
*/
-
static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
-
  ApndFile *paf = (ApndFile *)pFile;
-
  *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;
+
  for(i=0; i<argc; i++){
+
    if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
+
      /* If any of the constraints have a NULL value, then return no rows.
+
      ** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
+
      pCur->mnValue = 1;
+
      pCur->mxValue = 0;
+
      break;
+
    }
+
  }
+
  if( idxNum & 8 ){
+
    pCur->isDesc = 1;
+
    pCur->iValue = pCur->mxValue;
+
    if( pCur->iStep>0 ){
+
      pCur->iValue -= (pCur->mxValue - pCur->mnValue)%pCur->iStep;
+
    }
+
  }else{
+
    pCur->isDesc = 0;
+
    pCur->iValue = pCur->mnValue;
+
  }
+
  pCur->iRowid = 1;
  return SQLITE_OK;
}

/*
-
** Lock an apnd-file.
+
** SQLite will invoke this method one or more times while planning a query
+
** that uses the generate_series virtual table.  This routine needs to create
+
** a query plan for each invocation and compute an estimated cost for that
+
** plan.
+
**
+
** In this implementation idxNum is used to represent the
+
** query plan.  idxStr is unused.
+
**
+
** The query plan is represented by bits in idxNum:
+
**
+
**  (1)  start = $value  -- constraint exists
+
**  (2)  stop = $value   -- constraint exists
+
**  (4)  step = $value   -- constraint exists
+
**  (8)  output in descending order
*/
-
static int apndLock(sqlite3_file *pFile, int eLock){
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xLock(pFile, eLock);
-
}
+
static int seriesBestIndex(
+
  sqlite3_vtab *pVTab,
+
  sqlite3_index_info *pIdxInfo
+
){
+
  int i, j;              /* Loop over constraints */
+
  int idxNum = 0;        /* The query plan bitmask */
+
  int bStartSeen = 0;    /* EQ constraint seen on the START column */
+
  int unusableMask = 0;  /* Mask of unusable constraints */
+
  int nArg = 0;          /* Number of arguments that seriesFilter() expects */
+
  int aIdx[3];           /* Constraints on start, stop, and step */
+
  const struct sqlite3_index_constraint *pConstraint;

-
/*
-
** Unlock an apnd-file.
-
*/
-
static int apndUnlock(sqlite3_file *pFile, int eLock){
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xUnlock(pFile, eLock);
-
}
+
  /* This implementation assumes that the start, stop, and step columns
+
  ** are the last three columns in the virtual table. */
+
  assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
+
  assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );

-
/*
-
** Check if another file-handle holds a RESERVED lock on an apnd-file.
-
*/
-
static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
+
  aIdx[0] = aIdx[1] = aIdx[2] = -1;
+
  pConstraint = pIdxInfo->aConstraint;
+
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+
    int iCol;    /* 0 for start, 1 for stop, 2 for step */
+
    int iMask;   /* bitmask for those column */
+
    if( pConstraint->iColumn<SERIES_COLUMN_START ) continue;
+
    iCol = pConstraint->iColumn - SERIES_COLUMN_START;
+
    assert( iCol>=0 && iCol<=2 );
+
    iMask = 1 << iCol;
+
    if( iCol==0 ) bStartSeen = 1;
+
    if( pConstraint->usable==0 ){
+
      unusableMask |=  iMask;
+
      continue;
+
    }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+
      idxNum |= iMask;
+
      aIdx[iCol] = i;
+
    }
+
  }
+
  for(i=0; i<3; i++){
+
    if( (j = aIdx[i])>=0 ){
+
      pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
+
      pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
+
    }
+
  }
+
  /* The current generate_column() implementation requires at least one
+
  ** argument (the START value).  Legacy versions assumed START=0 if the
+
  ** first argument was omitted.  Compile with -DZERO_ARGUMENT_GENERATE_SERIES
+
  ** to obtain the legacy behavior */
+
#ifndef ZERO_ARGUMENT_GENERATE_SERIES
+
  if( !bStartSeen ){
+
    sqlite3_free(pVTab->zErrMsg);
+
    pVTab->zErrMsg = sqlite3_mprintf(
+
        "first argument to \"generate_series()\" missing or unusable");
+
    return SQLITE_ERROR;
+
  }
+
#endif
+
  if( (unusableMask & ~idxNum)!=0 ){
+
    /* The start, stop, and step columns are inputs.  Therefore if there
+
    ** are unusable constraints on any of start, stop, or step then
+
    ** this plan is unusable */
+
    return SQLITE_CONSTRAINT;
+
  }
+
  if( (idxNum & 3)==3 ){
+
    /* Both start= and stop= boundaries are available.  This is the 
+
    ** the preferred case */
+
    pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0));
+
    pIdxInfo->estimatedRows = 1000;
+
    if( pIdxInfo->nOrderBy>=1 && pIdxInfo->aOrderBy[0].iColumn==0 ){
+
      if( pIdxInfo->aOrderBy[0].desc ){
+
        idxNum |= 8;
+
      }else{
+
        idxNum |= 16;
+
      }
+
      pIdxInfo->orderByConsumed = 1;
+
    }
+
  }else{
+
    /* If either boundary is missing, we have to generate a huge span
+
    ** of numbers.  Make this case very expensive so that the query
+
    ** planner will work hard to avoid it. */
+
    pIdxInfo->estimatedRows = 2147483647;
+
  }
+
  pIdxInfo->idxNum = idxNum;
+
  return SQLITE_OK;
}

/*
-
** File control method. For custom operations on an apnd-file.
+
** This following structure defines all the methods for the 
+
** generate_series virtual table.
*/
-
static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
-
  ApndFile *paf = (ApndFile *)pFile;
-
  int rc;
-
  pFile = ORIGFILE(pFile);
-
  if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne;
-
  rc = pFile->pMethods->xFileControl(pFile, op, pArg);
-
  if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
-
    *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
+
static sqlite3_module seriesModule = {
+
  0,                         /* iVersion */
+
  0,                         /* xCreate */
+
  seriesConnect,             /* xConnect */
+
  seriesBestIndex,           /* xBestIndex */
+
  seriesDisconnect,          /* xDisconnect */
+
  0,                         /* xDestroy */
+
  seriesOpen,                /* xOpen - open a cursor */
+
  seriesClose,               /* xClose - close a cursor */
+
  seriesFilter,              /* xFilter - configure scan constraints */
+
  seriesNext,                /* xNext - advance a cursor */
+
  seriesEof,                 /* xEof - check for end of scan */
+
  seriesColumn,              /* xColumn - read data */
+
  seriesRowid,               /* xRowid - read data */
+
  0,                         /* xUpdate */
+
  0,                         /* xBegin */
+
  0,                         /* xSync */
+
  0,                         /* xCommit */
+
  0,                         /* xRollback */
+
  0,                         /* xFindMethod */
+
  0,                         /* xRename */
+
  0,                         /* xSavepoint */
+
  0,                         /* xRelease */
+
  0,                         /* xRollbackTo */
+
  0                          /* xShadowName */
+
};
+

+
#endif /* SQLITE_OMIT_VIRTUALTABLE */
+

+
#ifdef _WIN32
+

+
#endif
+
int sqlite3_series_init(
+
  sqlite3 *db, 
+
  char **pzErrMsg, 
+
  const sqlite3_api_routines *pApi
+
){
+
  int rc = SQLITE_OK;
+
  SQLITE_EXTENSION_INIT2(pApi);
+
#ifndef SQLITE_OMIT_VIRTUALTABLE
+
  if( sqlite3_libversion_number()<3008012 && pzErrMsg!=0 ){
+
    *pzErrMsg = sqlite3_mprintf(
+
        "generate_series() requires SQLite 3.8.12 or later");
+
    return SQLITE_ERROR;
  }
+
  rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0);
+
#endif
  return rc;
}

+
/************************* End ../ext/misc/series.c ********************/
+
/************************* Begin ../ext/misc/regexp.c ******************/
/*
-
** Return the sector-size in bytes for an apnd-file.
+
** 2012-11-13
+
**
+
** 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.
+
**
+
******************************************************************************
+
**
+
** The code in this file implements a compact but reasonably
+
** efficient regular-expression matcher for posix extended regular
+
** expressions against UTF8 text.
+
**
+
** This file is an SQLite extension.  It registers a single function
+
** named "regexp(A,B)" where A is the regular expression and B is the
+
** string to be matched.  By registering this function, SQLite will also
+
** then implement the "B regexp A" operator.  Note that with the function
+
** the regular expression comes first, but with the operator it comes
+
** second.
+
**
+
**  The following regular expression syntax is supported:
+
**
+
**     X*      zero or more occurrences of X
+
**     X+      one or more occurrences of X
+
**     X?      zero or one occurrences of X
+
**     X{p,q}  between p and q occurrences of X
+
**     (X)     match X
+
**     X|Y     X or Y
+
**     ^X      X occurring at the beginning of the string
+
**     X$      X occurring at the end of the string
+
**     .       Match any single character
+
**     \c      Character c where c is one of \{}()[]|*+?.
+
**     \c      C-language escapes for c in afnrtv.  ex: \t or \n
+
**     \uXXXX  Where XXXX is exactly 4 hex digits, unicode value XXXX
+
**     \xXX    Where XX is exactly 2 hex digits, unicode value XX
+
**     [abc]   Any single character from the set abc
+
**     [^abc]  Any single character not in the set abc
+
**     [a-z]   Any single character in the range a-z
+
**     [^a-z]  Any single character not in the range a-z
+
**     \b      Word boundary
+
**     \w      Word character.  [A-Za-z0-9_]
+
**     \W      Non-word character
+
**     \d      Digit
+
**     \D      Non-digit
+
**     \s      Whitespace character
+
**     \S      Non-whitespace character
+
**
+
** A nondeterministic finite automaton (NFA) is used for matching, so the
+
** performance is bounded by O(N*M) where N is the size of the regular
+
** expression and M is the size of the input string.  The matcher never
+
** exhibits exponential behavior.  Note that the X{p,q} operator expands
+
** to p copies of X following by q-p copies of X? and that the size of the
+
** regular expression in the O(N*M) performance bound is computed after
+
** this expansion.
*/
-
static int apndSectorSize(sqlite3_file *pFile){
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xSectorSize(pFile);
-
}
+
#include <string.h>
+
#include <stdlib.h>
+
/* #include "sqlite3ext.h" */
+
SQLITE_EXTENSION_INIT1

/*
-
** Return the device characteristic flags supported by an apnd-file.
+
** The following #defines change the names of some functions implemented in
+
** this file to prevent name collisions with C-library functions of the
+
** same name.
*/
-
static int apndDeviceCharacteristics(sqlite3_file *pFile){
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xDeviceCharacteristics(pFile);
-
}
-

-
/* Create a shared memory file mapping */
-
static int apndShmMap(
-
  sqlite3_file *pFile,
-
  int iPg,
-
  int pgsz,
-
  int bExtend,
-
  void volatile **pp
-
){
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
-
}
+
#define re_match   sqlite3re_match
+
#define re_compile sqlite3re_compile
+
#define re_free    sqlite3re_free

-
/* Perform locking on a shared-memory segment */
-
static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xShmLock(pFile,offset,n,flags);
-
}
+
/* The end-of-input character */
+
#define RE_EOF            0    /* End of input */

-
/* Memory barrier operation on shared memory */
-
static void apndShmBarrier(sqlite3_file *pFile){
-
  pFile = ORIGFILE(pFile);
-
  pFile->pMethods->xShmBarrier(pFile);
-
}
+
/* The NFA is implemented as sequence of opcodes taken from the following
+
** set.  Each opcode has a single integer argument.
+
*/
+
#define RE_OP_MATCH       1    /* Match the one character in the argument */
+
#define RE_OP_ANY         2    /* Match any one character.  (Implements ".") */
+
#define RE_OP_ANYSTAR     3    /* Special optimized version of .* */
+
#define RE_OP_FORK        4    /* Continue to both next and opcode at iArg */
+
#define RE_OP_GOTO        5    /* Jump to opcode at iArg */
+
#define RE_OP_ACCEPT      6    /* Halt and indicate a successful match */
+
#define RE_OP_CC_INC      7    /* Beginning of a [...] character class */
+
#define RE_OP_CC_EXC      8    /* Beginning of a [^...] character class */
+
#define RE_OP_CC_VALUE    9    /* Single value in a character class */
+
#define RE_OP_CC_RANGE   10    /* Range of values in a character class */
+
#define RE_OP_WORD       11    /* Perl word character [A-Za-z0-9_] */
+
#define RE_OP_NOTWORD    12    /* Not a perl word character */
+
#define RE_OP_DIGIT      13    /* digit:  [0-9] */
+
#define RE_OP_NOTDIGIT   14    /* Not a digit */
+
#define RE_OP_SPACE      15    /* space:  [ \t\n\r\v\f] */
+
#define RE_OP_NOTSPACE   16    /* Not a digit */
+
#define RE_OP_BOUNDARY   17    /* Boundary between word and non-word */

-
/* Unmap a shared memory segment */
-
static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
-
}
+
/* Each opcode is a "state" in the NFA */
+
typedef unsigned short ReStateNumber;

-
/* Fetch a page of a memory-mapped file */
-
static int apndFetch(
-
  sqlite3_file *pFile,
-
  sqlite3_int64 iOfst,
-
  int iAmt,
-
  void **pp
-
){
-
  ApndFile *p = (ApndFile *)pFile;
-
  if( p->iMark < 0 || iOfst+iAmt > p->iMark ){
-
    return SQLITE_IOERR; /* Cannot read what is not yet there. */
-
  }
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
-
}
+
/* Because this is an NFA and not a DFA, multiple states can be active at
+
** once.  An instance of the following object records all active states in
+
** the NFA.  The implementation is optimized for the common case where the
+
** number of actives states is small.
+
*/
+
typedef struct ReStateSet {
+
  unsigned nState;            /* Number of current states */
+
  ReStateNumber *aState;      /* Current states */
+
} ReStateSet;

-
/* Release a memory-mapped page */
-
static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
-
  ApndFile *p = (ApndFile *)pFile;
-
  pFile = ORIGFILE(pFile);
-
  return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
-
}
+
/* An input string read one character at a time.
+
*/
+
typedef struct ReInput ReInput;
+
struct ReInput {
+
  const unsigned char *z;  /* All text */
+
  int i;                   /* Next byte to read */
+
  int mx;                  /* EOF when i>=mx */
+
};

-
/*
-
** Try to read the append-mark off the end of a file.  Return the
-
** start of the appended database if the append-mark is present.
-
** If there is no valid append-mark, return -1;
-
**
-
** An append-mark is only valid if the NNNNNNNN start-of-database offset
-
** indicates that the appended database contains at least one page.  The
-
** start-of-database value must be a multiple of 512.
+
/* A compiled NFA (or an NFA that is in the process of being compiled) is
+
** an instance of the following object.
*/
-
static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
-
  int rc, i;
-
  sqlite3_int64 iMark;
-
  int msbs = 8 * (APND_MARK_FOS_SZ-1);
-
  unsigned char a[APND_MARK_SIZE];
+
typedef struct ReCompiled ReCompiled;
+
struct ReCompiled {
+
  ReInput sIn;                /* Regular expression text */
+
  const char *zErr;           /* Error message to return */
+
  char *aOp;                  /* Operators for the virtual machine */
+
  int *aArg;                  /* Arguments to each operator */
+
  unsigned (*xNextChar)(ReInput*);  /* Next character function */
+
  unsigned char zInit[12];    /* Initial text to match */
+
  int nInit;                  /* Number of characters in zInit */
+
  unsigned nState;            /* Number of entries in aOp[] and aArg[] */
+
  unsigned nAlloc;            /* Slots allocated for aOp[] and aArg[] */
+
};

-
  if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
-
  rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
-
  if( rc ) return -1;
-
  if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
-
  iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
-
  for(i=1; i<8; i++){
-
    msbs -= 8;
-
    iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
-
  }
-
  if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1;
-
  if( iMark & 0x1ff ) return -1;
-
  return iMark;
+
/* Add a state to the given state set if it is not already there */
+
static void re_add_state(ReStateSet *pSet, int newState){
+
  unsigned i;
+
  for(i=0; i<pSet->nState; i++) if( pSet->aState[i]==newState ) return;
+
  pSet->aState[pSet->nState++] = (ReStateNumber)newState;
}

-
static const char apvfsSqliteHdr[] = "SQLite format 3";
-
/*
-
** Check to see if the file is an appendvfs SQLite database file.
-
** Return true iff it is such. Parameter sz is the file's size.
+
/* Extract the next unicode character from *pzIn and return it.  Advance
+
** *pzIn to the first byte past the end of the character returned.  To
+
** be clear:  this routine converts utf8 to unicode.  This routine is 
+
** optimized for the common case where the next character is a single byte.
*/
-
static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
-
  int rc;
-
  char zHdr[16];
-
  sqlite3_int64 iMark = apndReadMark(sz, pFile);
-
  if( iMark>=0 ){
-
    /* If file has the correct end-marker, the expected odd size, and the
-
    ** SQLite DB type marker where the end-marker puts it, then it
-
    ** is an appendvfs database.
-
    */
-
    rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
-
    if( SQLITE_OK==rc
-
     && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
-
     && (sz & 0x1ff) == APND_MARK_SIZE
-
     && sz>=512+APND_MARK_SIZE
-
    ){
-
      return 1; /* It's an appendvfs database */
+
static unsigned re_next_char(ReInput *p){
+
  unsigned c;
+
  if( p->i>=p->mx ) return 0;
+
  c = p->z[p->i++];
+
  if( c>=0x80 ){
+
    if( (c&0xe0)==0xc0 && p->i<p->mx && (p->z[p->i]&0xc0)==0x80 ){
+
      c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f);
+
      if( c<0x80 ) c = 0xfffd;
+
    }else if( (c&0xf0)==0xe0 && p->i+1<p->mx && (p->z[p->i]&0xc0)==0x80
+
           && (p->z[p->i+1]&0xc0)==0x80 ){
+
      c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
+
      p->i += 2;
+
      if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
+
    }else if( (c&0xf8)==0xf0 && p->i+3<p->mx && (p->z[p->i]&0xc0)==0x80
+
           && (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){
+
      c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6)
+
                       | (p->z[p->i+2]&0x3f);
+
      p->i += 3;
+
      if( c<=0xffff || c>0x10ffff ) c = 0xfffd;
+
    }else{
+
      c = 0xfffd;
    }
  }
-
  return 0;
+
  return c;
+
}
+
static unsigned re_next_char_nocase(ReInput *p){
+
  unsigned c = re_next_char(p);
+
  if( c>='A' && c<='Z' ) c += 'a' - 'A';
+
  return c;
}

-
/*
-
** Check to see if the file is an ordinary SQLite database file.
-
** Return true iff so. Parameter sz is the file's size.
-
*/
-
static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
-
  char zHdr[16];
-
  if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */
-
   || (sz & 0x1ff) != 0
-
   || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0)
-
   || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0
-
  ){
-
    return 0;
-
  }else{
-
    return 1;
-
  }
+
/* Return true if c is a perl "word" character:  [A-Za-z0-9_] */
+
static int re_word_char(int c){
+
  return (c>='0' && c<='9') || (c>='a' && c<='z')
+
      || (c>='A' && c<='Z') || c=='_';
}

-
/*
-
** Open an apnd file handle.
+
/* Return true if c is a "digit" character:  [0-9] */
+
static int re_digit_char(int c){
+
  return (c>='0' && c<='9');
+
}
+

+
/* Return true if c is a perl "space" character:  [ \t\r\n\v\f] */
+
static int re_space_char(int c){
+
  return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f';
+
}
+

+
/* Run a compiled regular expression on the zero-terminated input
+
** string zIn[].  Return true on a match and false if there is no match.
*/
-
static int apndOpen(
-
  sqlite3_vfs *pApndVfs,
-
  const char *zName,
-
  sqlite3_file *pFile,
-
  int flags,
-
  int *pOutFlags
-
){
-
  ApndFile *pApndFile = (ApndFile*)pFile;
-
  sqlite3_file *pBaseFile = ORIGFILE(pFile);
-
  sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs);
-
  int rc;
-
  sqlite3_int64 sz = 0;
-
  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
-
    /* The appendvfs is not to be used for transient or temporary databases.
-
    ** Just use the base VFS open to initialize the given file object and
-
    ** open the underlying file. (Appendvfs is then unused for this file.)
-
    */
-
    return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags);
-
  }
-
  memset(pApndFile, 0, sizeof(ApndFile));
-
  pFile->pMethods = &apnd_io_methods;
-
  pApndFile->iMark = -1;    /* Append mark not yet written */
+
static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
+
  ReStateSet aStateSet[2], *pThis, *pNext;
+
  ReStateNumber aSpace[100];
+
  ReStateNumber *pToFree;
+
  unsigned int i = 0;
+
  unsigned int iSwap = 0;
+
  int c = RE_EOF+1;
+
  int cPrev = 0;
+
  int rc = 0;
+
  ReInput in;

-
  rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags);
-
  if( rc==SQLITE_OK ){
-
    rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
-
    if( rc ){
-
      pBaseFile->pMethods->xClose(pBaseFile);
+
  in.z = zIn;
+
  in.i = 0;
+
  in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn);
+

+
  /* Look for the initial prefix match, if there is one. */
+
  if( pRe->nInit ){
+
    unsigned char x = pRe->zInit[0];
+
    while( in.i+pRe->nInit<=in.mx 
+
     && (zIn[in.i]!=x ||
+
         strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
+
    ){
+
      in.i++;
    }
+
    if( in.i+pRe->nInit>in.mx ) return 0;
  }
-
  if( rc ){
-
    pFile->pMethods = 0;
-
    return rc;
-
  }
-
  if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){
-
    /* The file being opened appears to be just an ordinary DB. Copy
-
    ** the base dispatch-table so this instance mimics the base VFS. 
-
    */
-
    memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile);
-
    return SQLITE_OK;
-
  }
-
  pApndFile->iPgOne = apndReadMark(sz, pFile);
-
  if( pApndFile->iPgOne>=0 ){
-
    pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */
-
    return SQLITE_OK;
-
  }
-
  if( (flags & SQLITE_OPEN_CREATE)==0 ){
-
    pBaseFile->pMethods->xClose(pBaseFile);
-
    rc = SQLITE_CANTOPEN;
-
    pFile->pMethods = 0;
+

+
  if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
+
    pToFree = 0;
+
    aStateSet[0].aState = aSpace;
  }else{
-
    /* Round newly added appendvfs location to #define'd page boundary. 
-
    ** Note that nothing has yet been written to the underlying file.
-
    ** The append mark will be written along with first content write.
-
    ** Until then, paf->iMark value indicates it is not yet written.
-
    */
-
    pApndFile->iPgOne = APND_START_ROUNDUP(sz);
+
    pToFree = sqlite3_malloc64( sizeof(ReStateNumber)*2*pRe->nState );
+
    if( pToFree==0 ) return -1;
+
    aStateSet[0].aState = pToFree;
  }
-
  return rc;
-
}
-

-
/*
-
** Delete an apnd file.
-
** For an appendvfs, this could mean delete the appendvfs portion,
-
** leaving the appendee as it was before it gained an appendvfs.
-
** For now, this code deletes the underlying file too.
-
*/
-
static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
-
  return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
+
  aStateSet[1].aState = &aStateSet[0].aState[pRe->nState];
+
  pNext = &aStateSet[1];
+
  pNext->nState = 0;
+
  re_add_state(pNext, 0);
+
  while( c!=RE_EOF && pNext->nState>0 ){
+
    cPrev = c;
+
    c = pRe->xNextChar(&in);
+
    pThis = pNext;
+
    pNext = &aStateSet[iSwap];
+
    iSwap = 1 - iSwap;
+
    pNext->nState = 0;
+
    for(i=0; i<pThis->nState; i++){
+
      int x = pThis->aState[i];
+
      switch( pRe->aOp[x] ){
+
        case RE_OP_MATCH: {
+
          if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
+
          break;
+
        }
+
        case RE_OP_ANY: {
+
          if( c!=0 ) re_add_state(pNext, x+1);
+
          break;
+
        }
+
        case RE_OP_WORD: {
+
          if( re_word_char(c) ) re_add_state(pNext, x+1);
+
          break;
+
        }
+
        case RE_OP_NOTWORD: {
+
          if( !re_word_char(c) && c!=0 ) re_add_state(pNext, x+1);
+
          break;
+
        }
+
        case RE_OP_DIGIT: {
+
          if( re_digit_char(c) ) re_add_state(pNext, x+1);
+
          break;
+
        }
+
        case RE_OP_NOTDIGIT: {
+
          if( !re_digit_char(c) && c!=0 ) re_add_state(pNext, x+1);
+
          break;
+
        }
+
        case RE_OP_SPACE: {
+
          if( re_space_char(c) ) re_add_state(pNext, x+1);
+
          break;
+
        }
+
        case RE_OP_NOTSPACE: {
+
          if( !re_space_char(c) && c!=0 ) re_add_state(pNext, x+1);
+
          break;
+
        }
+
        case RE_OP_BOUNDARY: {
+
          if( re_word_char(c)!=re_word_char(cPrev) ) re_add_state(pThis, x+1);
+
          break;
+
        }
+
        case RE_OP_ANYSTAR: {
+
          re_add_state(pNext, x);
+
          re_add_state(pThis, x+1);
+
          break;
+
        }
+
        case RE_OP_FORK: {
+
          re_add_state(pThis, x+pRe->aArg[x]);
+
          re_add_state(pThis, x+1);
+
          break;
+
        }
+
        case RE_OP_GOTO: {
+
          re_add_state(pThis, x+pRe->aArg[x]);
+
          break;
+
        }
+
        case RE_OP_ACCEPT: {
+
          rc = 1;
+
          goto re_match_end;
+
        }
+
        case RE_OP_CC_EXC: {
+
          if( c==0 ) break;
+
          /* fall-through */ goto re_op_cc_inc;
+
        }
+
        case RE_OP_CC_INC: re_op_cc_inc: {
+
          int j = 1;
+
          int n = pRe->aArg[x];
+
          int hit = 0;
+
          for(j=1; j>0 && j<n; j++){
+
            if( pRe->aOp[x+j]==RE_OP_CC_VALUE ){
+
              if( pRe->aArg[x+j]==c ){
+
                hit = 1;
+
                j = -1;
+
              }
+
            }else{
+
              if( pRe->aArg[x+j]<=c && pRe->aArg[x+j+1]>=c ){
+
                hit = 1;
+
                j = -1;
+
              }else{
+
                j++;
+
              }
+
            }
+
          }
+
          if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit;
+
          if( hit ) re_add_state(pNext, x+n);
+
          break;
+
        }
+
      }
+
    }
+
  }
+
  for(i=0; i<pNext->nState; i++){
+
    if( pRe->aOp[pNext->aState[i]]==RE_OP_ACCEPT ){ rc = 1; break; }
+
  }
+
re_match_end:
+
  sqlite3_free(pToFree);
+
  return rc;
}

-
/*
-
** All other VFS methods are pass-thrus.
+
/* Resize the opcode and argument arrays for an RE under construction.
*/
-
static int apndAccess(
-
  sqlite3_vfs *pVfs, 
-
  const char *zPath, 
-
  int flags, 
-
  int *pResOut
-
){
-
  return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
-
}
-
static int apndFullPathname(
-
  sqlite3_vfs *pVfs, 
-
  const char *zPath, 
-
  int nOut, 
-
  char *zOut
-
){
-
  return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
-
}
-
static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
-
  return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
-
}
-
static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
-
  ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
-
}
-
static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
-
  return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
-
}
-
static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
-
  ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
+
static int re_resize(ReCompiled *p, int N){
+
  char *aOp;
+
  int *aArg;
+
  aOp = sqlite3_realloc64(p->aOp, N*sizeof(p->aOp[0]));
+
  if( aOp==0 ) return 1;
+
  p->aOp = aOp;
+
  aArg = sqlite3_realloc64(p->aArg, N*sizeof(p->aArg[0]));
+
  if( aArg==0 ) return 1;
+
  p->aArg = aArg;
+
  p->nAlloc = N;
+
  return 0;
}
-
static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
-
  return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
+

+
/* Insert a new opcode and argument into an RE under construction.  The
+
** insertion point is just prior to existing opcode iBefore.
+
*/
+
static int re_insert(ReCompiled *p, int iBefore, int op, int arg){
+
  int i;
+
  if( p->nAlloc<=p->nState && re_resize(p, p->nAlloc*2) ) return 0;
+
  for(i=p->nState; i>iBefore; i--){
+
    p->aOp[i] = p->aOp[i-1];
+
    p->aArg[i] = p->aArg[i-1];
+
  }
+
  p->nState++;
+
  p->aOp[iBefore] = (char)op;
+
  p->aArg[iBefore] = arg;
+
  return iBefore;
}
-
static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
-
  return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
+

+
/* Append a new opcode and argument to the end of the RE under construction.
+
*/
+
static int re_append(ReCompiled *p, int op, int arg){
+
  return re_insert(p, p->nState, op, arg);
}
-
static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
-
  return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
+

+
/* Make a copy of N opcodes starting at iStart onto the end of the RE
+
** under construction.
+
*/
+
static void re_copy(ReCompiled *p, int iStart, int N){
+
  if( p->nState+N>=p->nAlloc && re_resize(p, p->nAlloc*2+N) ) return;
+
  memcpy(&p->aOp[p->nState], &p->aOp[iStart], N*sizeof(p->aOp[0]));
+
  memcpy(&p->aArg[p->nState], &p->aArg[iStart], N*sizeof(p->aArg[0]));
+
  p->nState += N;
}
-
static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
-
  return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
+

+
/* Return true if c is a hexadecimal digit character:  [0-9a-fA-F]
+
** If c is a hex digit, also set *pV = (*pV)*16 + valueof(c).  If
+
** c is not a hex digit *pV is unchanged.
+
*/
+
static int re_hex(int c, int *pV){
+
  if( c>='0' && c<='9' ){
+
    c -= '0';
+
  }else if( c>='a' && c<='f' ){
+
    c -= 'a' - 10;
+
  }else if( c>='A' && c<='F' ){
+
    c -= 'A' - 10;
+
  }else{
+
    return 0;
+
  }
+
  *pV = (*pV)*16 + (c & 0xff);
+
  return 1;
}
-
static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
-
  return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
+

+
/* A backslash character has been seen, read the next character and
+
** return its interpretation.
+
*/
+
static unsigned re_esc_char(ReCompiled *p){
+
  static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]";
+
  static const char zTrans[] = "\a\f\n\r\t\v";
+
  int i, v = 0;
+
  char c;
+
  if( p->sIn.i>=p->sIn.mx ) return 0;
+
  c = p->sIn.z[p->sIn.i];
+
  if( c=='u' && p->sIn.i+4<p->sIn.mx ){
+
    const unsigned char *zIn = p->sIn.z + p->sIn.i;
+
    if( re_hex(zIn[1],&v)
+
     && re_hex(zIn[2],&v)
+
     && re_hex(zIn[3],&v)
+
     && re_hex(zIn[4],&v)
+
    ){
+
      p->sIn.i += 5;
+
      return v;
+
    }
+
  }
+
  if( c=='x' && p->sIn.i+2<p->sIn.mx ){
+
    const unsigned char *zIn = p->sIn.z + p->sIn.i;
+
    if( re_hex(zIn[1],&v)
+
     && re_hex(zIn[2],&v)
+
    ){
+
      p->sIn.i += 3;
+
      return v;
+
    }
+
  }
+
  for(i=0; zEsc[i] && zEsc[i]!=c; i++){}
+
  if( zEsc[i] ){
+
    if( i<6 ) c = zTrans[i];
+
    p->sIn.i++;
+
  }else{
+
    p->zErr = "unknown \\ escape";
+
  }
+
  return c;
}
-
static int apndSetSystemCall(
-
  sqlite3_vfs *pVfs,
-
  const char *zName,
-
  sqlite3_syscall_ptr pCall
-
){
-
  return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
+

+
/* Forward declaration */
+
static const char *re_subcompile_string(ReCompiled*);
+

+
/* Peek at the next byte of input */
+
static unsigned char rePeek(ReCompiled *p){
+
  return p->sIn.i<p->sIn.mx ? p->sIn.z[p->sIn.i] : 0;
}
-
static sqlite3_syscall_ptr apndGetSystemCall(
-
  sqlite3_vfs *pVfs,
-
  const char *zName
-
){
-
  return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
+

+
/* Compile RE text into a sequence of opcodes.  Continue up to the
+
** first unmatched ")" character, then return.  If an error is found,
+
** return a pointer to the error message string.
+
*/
+
static const char *re_subcompile_re(ReCompiled *p){
+
  const char *zErr;
+
  int iStart, iEnd, iGoto;
+
  iStart = p->nState;
+
  zErr = re_subcompile_string(p);
+
  if( zErr ) return zErr;
+
  while( rePeek(p)=='|' ){
+
    iEnd = p->nState;
+
    re_insert(p, iStart, RE_OP_FORK, iEnd + 2 - iStart);
+
    iGoto = re_append(p, RE_OP_GOTO, 0);
+
    p->sIn.i++;
+
    zErr = re_subcompile_string(p);
+
    if( zErr ) return zErr;
+
    p->aArg[iGoto] = p->nState - iGoto;
+
  }
+
  return 0;
}
-
static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
-
  return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
+

+
/* Compile an element of regular expression text (anything that can be
+
** an operand to the "|" operator).  Return NULL on success or a pointer
+
** to the error message if there is a problem.
+
*/
+
static const char *re_subcompile_string(ReCompiled *p){
+
  int iPrev = -1;
+
  int iStart;
+
  unsigned c;
+
  const char *zErr;
+
  while( (c = p->xNextChar(&p->sIn))!=0 ){
+
    iStart = p->nState;
+
    switch( c ){
+
      case '|':
+
      case '$':
+
      case ')': {
+
        p->sIn.i--;
+
        return 0;
+
      }
+
      case '(': {
+
        zErr = re_subcompile_re(p);
+
        if( zErr ) return zErr;
+
        if( rePeek(p)!=')' ) return "unmatched '('";
+
        p->sIn.i++;
+
        break;
+
      }
+
      case '.': {
+
        if( rePeek(p)=='*' ){
+
          re_append(p, RE_OP_ANYSTAR, 0);
+
          p->sIn.i++;
+
        }else{
+
          re_append(p, RE_OP_ANY, 0);
+
        }
+
        break;
+
      }
+
      case '*': {
+
        if( iPrev<0 ) return "'*' without operand";
+
        re_insert(p, iPrev, RE_OP_GOTO, p->nState - iPrev + 1);
+
        re_append(p, RE_OP_FORK, iPrev - p->nState + 1);
+
        break;
+
      }
+
      case '+': {
+
        if( iPrev<0 ) return "'+' without operand";
+
        re_append(p, RE_OP_FORK, iPrev - p->nState);
+
        break;
+
      }
+
      case '?': {
+
        if( iPrev<0 ) return "'?' without operand";
+
        re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
+
        break;
+
      }
+
      case '{': {
+
        int m = 0, n = 0;
+
        int sz, j;
+
        if( iPrev<0 ) return "'{m,n}' without operand";
+
        while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }
+
        n = m;
+
        if( c==',' ){
+
          p->sIn.i++;
+
          n = 0;
+
          while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }
+
        }
+
        if( c!='}' ) return "unmatched '{'";
+
        if( n>0 && n<m ) return "n less than m in '{m,n}'";
+
        p->sIn.i++;
+
        sz = p->nState - iPrev;
+
        if( m==0 ){
+
          if( n==0 ) return "both m and n are zero in '{m,n}'";
+
          re_insert(p, iPrev, RE_OP_FORK, sz+1);
+
          n--;
+
        }else{
+
          for(j=1; j<m; j++) re_copy(p, iPrev, sz);
+
        }
+
        for(j=m; j<n; j++){
+
          re_append(p, RE_OP_FORK, sz+1);
+
          re_copy(p, iPrev, sz);
+
        }
+
        if( n==0 && m>0 ){
+
          re_append(p, RE_OP_FORK, -sz);
+
        }
+
        break;
+
      }
+
      case '[': {
+
        int iFirst = p->nState;
+
        if( rePeek(p)=='^' ){
+
          re_append(p, RE_OP_CC_EXC, 0);
+
          p->sIn.i++;
+
        }else{
+
          re_append(p, RE_OP_CC_INC, 0);
+
        }
+
        while( (c = p->xNextChar(&p->sIn))!=0 ){
+
          if( c=='[' && rePeek(p)==':' ){
+
            return "POSIX character classes not supported";
+
          }
+
          if( c=='\\' ) c = re_esc_char(p);
+
          if( rePeek(p)=='-' ){
+
            re_append(p, RE_OP_CC_RANGE, c);
+
            p->sIn.i++;
+
            c = p->xNextChar(&p->sIn);
+
            if( c=='\\' ) c = re_esc_char(p);
+
            re_append(p, RE_OP_CC_RANGE, c);
+
          }else{
+
            re_append(p, RE_OP_CC_VALUE, c);
+
          }
+
          if( rePeek(p)==']' ){ p->sIn.i++; break; }
+
        }
+
        if( c==0 ) return "unclosed '['";
+
        p->aArg[iFirst] = p->nState - iFirst;
+
        break;
+
      }
+
      case '\\': {
+
        int specialOp = 0;
+
        switch( rePeek(p) ){
+
          case 'b': specialOp = RE_OP_BOUNDARY;   break;
+
          case 'd': specialOp = RE_OP_DIGIT;      break;
+
          case 'D': specialOp = RE_OP_NOTDIGIT;   break;
+
          case 's': specialOp = RE_OP_SPACE;      break;
+
          case 'S': specialOp = RE_OP_NOTSPACE;   break;
+
          case 'w': specialOp = RE_OP_WORD;       break;
+
          case 'W': specialOp = RE_OP_NOTWORD;    break;
+
        }
+
        if( specialOp ){
+
          p->sIn.i++;
+
          re_append(p, specialOp, 0);
+
        }else{
+
          c = re_esc_char(p);
+
          re_append(p, RE_OP_MATCH, c);
+
        }
+
        break;
+
      }
+
      default: {
+
        re_append(p, RE_OP_MATCH, c);
+
        break;
+
      }
+
    }
+
    iPrev = iStart;
+
  }
+
  return 0;
}

-
  
-
#ifdef _WIN32
-

-
#endif
-
/* 
-
** This routine is called when the extension is loaded.
-
** Register the new VFS.
+
/* Free and reclaim all the memory used by a previously compiled
+
** regular expression.  Applications should invoke this routine once
+
** for every call to re_compile() to avoid memory leaks.
*/
-
int sqlite3_appendvfs_init(
-
  sqlite3 *db, 
-
  char **pzErrMsg, 
-
  const sqlite3_api_routines *pApi
-
){
-
  int rc = SQLITE_OK;
-
  sqlite3_vfs *pOrig;
-
  SQLITE_EXTENSION_INIT2(pApi);
-
  (void)pzErrMsg;
-
  (void)db;
-
  pOrig = sqlite3_vfs_find(0);
-
  if( pOrig==0 ) return SQLITE_ERROR;
-
  apnd_vfs.iVersion = pOrig->iVersion;
-
  apnd_vfs.pAppData = pOrig;
-
  apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
-
  rc = sqlite3_vfs_register(&apnd_vfs, 0);
-
#ifdef APPENDVFS_TEST
-
  if( rc==SQLITE_OK ){
-
    rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
+
static void re_free(ReCompiled *pRe){
+
  if( pRe ){
+
    sqlite3_free(pRe->aOp);
+
    sqlite3_free(pRe->aArg);
+
    sqlite3_free(pRe);
  }
-
#endif
-
  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
-
  return rc;
}

-
/************************* End ../ext/misc/appendvfs.c ********************/
-
/************************* Begin ../ext/misc/memtrace.c ******************/
/*
-
** 2019-01-21
-
**
-
** The author disclaims copyright to this source code.  In place of
-
** a legal notice, here is a blessing:
-
**
-
**    May you do good and not evil.
-
**    May you find forgiveness for yourself and forgive others.
-
**    May you share freely, never taking more than you give.
-
**
-
*************************************************************************
-
**
-
** This file implements an extension that uses the SQLITE_CONFIG_MALLOC
-
** mechanism to add a tracing layer on top of SQLite.  If this extension
-
** is registered prior to sqlite3_initialize(), it will cause all memory
-
** allocation activities to be logged on standard output, or to some other
-
** FILE specified by the initializer.
-
**
-
** This file needs to be compiled into the application that uses it.
-
**
-
** This extension is used to implement the --memtrace option of the
-
** command-line shell.
+
** Compile a textual regular expression in zIn[] into a compiled regular
+
** expression suitable for us by re_match() and return a pointer to the
+
** compiled regular expression in *ppRe.  Return NULL on success or an
+
** error message if something goes wrong.
*/
-
#include <assert.h>
-
#include <string.h>
-
#include <stdio.h>
-

-
/* The original memory allocation routines */
-
static sqlite3_mem_methods memtraceBase;
-
static FILE *memtraceOut;
+
static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
+
  ReCompiled *pRe;
+
  const char *zErr;
+
  int i, j;

-
/* Methods that trace memory allocations */
-
static void *memtraceMalloc(int n){
-
  if( memtraceOut ){
-
    fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n", 
-
            memtraceBase.xRoundup(n));
-
  }
-
  return memtraceBase.xMalloc(n);
-
}
-
static void memtraceFree(void *p){
-
  if( p==0 ) return;
-
  if( memtraceOut ){
-
    fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
+
  *ppRe = 0;
+
  pRe = sqlite3_malloc( sizeof(*pRe) );
+
  if( pRe==0 ){
+
    return "out of memory";
  }
-
  memtraceBase.xFree(p);
-
}
-
static void *memtraceRealloc(void *p, int n){
-
  if( p==0 ) return memtraceMalloc(n);
-
  if( n==0 ){
-
    memtraceFree(p);
-
    return 0;
+
  memset(pRe, 0, sizeof(*pRe));
+
  pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char;
+
  if( re_resize(pRe, 30) ){
+
    re_free(pRe);
+
    return "out of memory";
  }
-
  if( memtraceOut ){
-
    fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
-
            memtraceBase.xSize(p), memtraceBase.xRoundup(n));
+
  if( zIn[0]=='^' ){
+
    zIn++;
+
  }else{
+
    re_append(pRe, RE_OP_ANYSTAR, 0);
  }
-
  return memtraceBase.xRealloc(p, n);
-
}
-
static int memtraceSize(void *p){
-
  return memtraceBase.xSize(p);
-
}
-
static int memtraceRoundup(int n){
-
  return memtraceBase.xRoundup(n);
-
}
-
static int memtraceInit(void *p){
-
  return memtraceBase.xInit(p);
-
}
-
static void memtraceShutdown(void *p){
-
  memtraceBase.xShutdown(p);
-
}
-

-
/* The substitute memory allocator */
-
static sqlite3_mem_methods ersaztMethods = {
-
  memtraceMalloc,
-
  memtraceFree,
-
  memtraceRealloc,
-
  memtraceSize,
-
  memtraceRoundup,
-
  memtraceInit,
-
  memtraceShutdown,
-
  0
-
};
-

-
/* Begin tracing memory allocations to out. */
-
int sqlite3MemTraceActivate(FILE *out){
-
  int rc = SQLITE_OK;
-
  if( memtraceBase.xMalloc==0 ){
-
    rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
-
    if( rc==SQLITE_OK ){
-
      rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
-
    }
+
  pRe->sIn.z = (unsigned char*)zIn;
+
  pRe->sIn.i = 0;
+
  pRe->sIn.mx = (int)strlen(zIn);
+
  zErr = re_subcompile_re(pRe);
+
  if( zErr ){
+
    re_free(pRe);
+
    return zErr;
+
  }
+
  if( rePeek(pRe)=='$' && pRe->sIn.i+1>=pRe->sIn.mx ){
+
    re_append(pRe, RE_OP_MATCH, RE_EOF);
+
    re_append(pRe, RE_OP_ACCEPT, 0);
+
    *ppRe = pRe;
+
  }else if( pRe->sIn.i>=pRe->sIn.mx ){
+
    re_append(pRe, RE_OP_ACCEPT, 0);
+
    *ppRe = pRe;
+
  }else{
+
    re_free(pRe);
+
    return "unrecognized character";
  }
-
  memtraceOut = out;
-
  return rc;
-
}

-
/* Deactivate memory tracing */
-
int sqlite3MemTraceDeactivate(void){
-
  int rc = SQLITE_OK;
-
  if( memtraceBase.xMalloc!=0 ){
-
    rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
-
    if( rc==SQLITE_OK ){
-
      memset(&memtraceBase, 0, sizeof(memtraceBase));
+
  /* The following is a performance optimization.  If the regex begins with
+
  ** ".*" (if the input regex lacks an initial "^") and afterwards there are
+
  ** one or more matching characters, enter those matching characters into
+
  ** zInit[].  The re_match() routine can then search ahead in the input 
+
  ** string looking for the initial match without having to run the whole
+
  ** regex engine over the string.  Do not worry able trying to match
+
  ** unicode characters beyond plane 0 - those are very rare and this is
+
  ** just an optimization. */
+
  if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){
+
    for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
+
      unsigned x = pRe->aArg[i];
+
      if( x<=127 ){
+
        pRe->zInit[j++] = (unsigned char)x;
+
      }else if( x<=0xfff ){
+
        pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
+
        pRe->zInit[j++] = 0x80 | (x&0x3f);
+
      }else if( x<=0xffff ){
+
        pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12));
+
        pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
+
        pRe->zInit[j++] = 0x80 | (x&0x3f);
+
      }else{
+
        break;
+
      }
    }
+
    if( j>0 && pRe->zInit[j-1]==0 ) j--;
+
    pRe->nInit = j;
  }
-
  memtraceOut = 0;
-
  return rc;
+
  return pRe->zErr;
}

-
/************************* End ../ext/misc/memtrace.c ********************/
-
/************************* Begin ../ext/misc/uint.c ******************/
/*
-
** 2020-04-14
-
**
-
** 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 SQLite extension implements the UINT collating sequence.
-
**
-
** UINT works like BINARY for text, except that embedded strings
-
** of digits compare in numeric order.
-
**
-
**     *   Leading zeros are handled properly, in the sense that
-
**         they do not mess of the maginitude comparison of embedded
-
**         strings of digits.  "x00123y" is equal to "x123y".
+
** Implementation of the regexp() SQL function.  This function implements
+
** the build-in REGEXP operator.  The first argument to the function is the
+
** pattern and the second argument is the string.  So, the SQL statements:
**
-
**     *   Only unsigned integers are recognized.  Plus and minus
-
**         signs are ignored.  Decimal points and exponential notation
-
**         are ignored.
+
**       A REGEXP B
**
-
**     *   Embedded integers can be of arbitrary length.  Comparison
-
**         is *not* limited integers that can be expressed as a
-
**         64-bit machine integer.
-
*/
-
/* #include "sqlite3ext.h" */
-
SQLITE_EXTENSION_INIT1
-
#include <assert.h>
-
#include <string.h>
-
#include <ctype.h>
-

-
/*
-
** Compare text in lexicographic order, except strings of digits
-
** compare in numeric order.
+
** is implemented as regexp(B,A).
*/
-
static int uintCollFunc(
-
  void *notUsed,
-
  int nKey1, const void *pKey1,
-
  int nKey2, const void *pKey2
+
static void re_sql_func(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
){
-
  const unsigned char *zA = (const unsigned char*)pKey1;
-
  const unsigned char *zB = (const unsigned char*)pKey2;
-
  int i=0, j=0, x;
-
  (void)notUsed;
-
  while( i<nKey1 && j<nKey2 ){
-
    x = zA[i] - zB[j];
-
    if( isdigit(zA[i]) ){
-
      int k;
-
      if( !isdigit(zB[j]) ) return x;
-
      while( i<nKey1 && zA[i]=='0' ){ i++; }
-
      while( j<nKey2 && zB[j]=='0' ){ j++; }
-
      k = 0;
-
      while( i+k<nKey1 && isdigit(zA[i+k])
-
             && j+k<nKey2 && isdigit(zB[j+k]) ){
-
        k++;
-
      }
-
      if( i+k<nKey1 && isdigit(zA[i+k]) ){
-
        return +1;
-
      }else if( j+k<nKey2 && isdigit(zB[j+k]) ){
-
        return -1;
-
      }else{
-
        x = memcmp(zA+i, zB+j, k);
-
        if( x ) return x;
-
        i += k;
-
        j += k;
-
      }
-
    }else if( x ){
-
      return x;
-
    }else{
-
      i++;
-
      j++;
+
  ReCompiled *pRe;          /* Compiled regular expression */
+
  const char *zPattern;     /* The regular expression */
+
  const unsigned char *zStr;/* String being searched */
+
  const char *zErr;         /* Compile error message */
+
  int setAux = 0;           /* True to invoke sqlite3_set_auxdata() */
+

+
  (void)argc;  /* Unused */
+
  pRe = sqlite3_get_auxdata(context, 0);
+
  if( pRe==0 ){
+
    zPattern = (const char*)sqlite3_value_text(argv[0]);
+
    if( zPattern==0 ) return;
+
    zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0);
+
    if( zErr ){
+
      re_free(pRe);
+
      sqlite3_result_error(context, zErr, -1);
+
      return;
+
    }
+
    if( pRe==0 ){
+
      sqlite3_result_error_nomem(context);
+
      return;
    }
+
    setAux = 1;
+
  }
+
  zStr = (const unsigned char*)sqlite3_value_text(argv[1]);
+
  if( zStr!=0 ){
+
    sqlite3_result_int(context, re_match(pRe, zStr, -1));
+
  }
+
  if( setAux ){
+
    sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free);
  }
-
  return (nKey1 - i) - (nKey2 - j);
}

+
/*
+
** Invoke this routine to register the regexp() function with the
+
** SQLite database connection.
+
*/
#ifdef _WIN32

#endif
-
int sqlite3_uint_init(
+
int sqlite3_regexp_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
+
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
-
  (void)pzErrMsg;  /* Unused parameter */
-
  return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
+
  (void)pzErrMsg;  /* Unused */
+
  rc = sqlite3_create_function(db, "regexp", 2, 
+
                            SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
+
                            0, re_sql_func, 0, 0);
+
  if( rc==SQLITE_OK ){
+
    /* The regexpi(PATTERN,STRING) function is a case-insensitive version
+
    ** of regexp(PATTERN,STRING). */
+
    rc = sqlite3_create_function(db, "regexpi", 2,
+
                            SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
+
                            (void*)db, re_sql_func, 0, 0);
+
  }
+
  return rc;
}

-
/************************* End ../ext/misc/uint.c ********************/
-
/************************* Begin ../ext/misc/decimal.c ******************/
+
/************************* End ../ext/misc/regexp.c ********************/
+
#ifndef SQLITE_SHELL_WASM_MODE
+
/************************* Begin ../ext/misc/fileio.c ******************/
/*
-
** 2020-06-22
+
** 2014-06-13
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
@@ -4539,930 +4511,1029 @@ int sqlite3_uint_init(
**
******************************************************************************
**
-
** Routines to implement arbitrary-precision decimal math.
+
** This SQLite extension implements SQL functions readfile() and
+
** writefile(), and eponymous virtual type "fsdir".
**
-
** The focus here is on simplicity and correctness, not performance.
+
** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
+
**
+
**   If neither of the optional arguments is present, then this UDF
+
**   function writes blob DATA to file FILE. If successful, the number
+
**   of bytes written is returned. If an error occurs, NULL is returned.
+
**
+
**   If the first option argument - MODE - is present, then it must
+
**   be passed an integer value that corresponds to a POSIX mode
+
**   value (file type + permissions, as returned in the stat.st_mode
+
**   field by the stat() system call). Three types of files may
+
**   be written/created:
+
**
+
**     regular files:  (mode & 0170000)==0100000
+
**     symbolic links: (mode & 0170000)==0120000
+
**     directories:    (mode & 0170000)==0040000
+
**
+
**   For a directory, the DATA is ignored. For a symbolic link, it is
+
**   interpreted as text and used as the target of the link. For a
+
**   regular file, it is interpreted as a blob and written into the
+
**   named file. Regardless of the type of file, its permissions are
+
**   set to (mode & 0777) before returning.
+
**
+
**   If the optional MTIME argument is present, then it is interpreted
+
**   as an integer - the number of seconds since the unix epoch. The
+
**   modification-time of the target file is set to this value before
+
**   returning.
+
**
+
**   If three or more arguments are passed to this function and an
+
**   error is encountered, an exception is raised.
+
**
+
** READFILE(FILE):
+
**
+
**   Read and return the contents of file FILE (type blob) from disk.
+
**
+
** FSDIR:
+
**
+
**   Used as follows:
+
**
+
**     SELECT * FROM fsdir($path [, $dir]);
+
**
+
**   Parameter $path is an absolute or relative pathname. If the file that it
+
**   refers to does not exist, it is an error. If the path refers to a regular
+
**   file or symbolic link, it returns a single row. Or, if the path refers
+
**   to a directory, it returns one row for the directory, and one row for each
+
**   file within the hierarchy rooted at $path.
+
**
+
**   Each row has the following columns:
+
**
+
**     name:  Path to file or directory (text value).
+
**     mode:  Value of stat.st_mode for directory entry (an integer).
+
**     mtime: Value of stat.st_mtime for directory entry (an integer).
+
**     data:  For a regular file, a blob containing the file data. For a
+
**            symlink, a text value containing the text of the link. For a
+
**            directory, NULL.
+
**
+
**   If a non-NULL value is specified for the optional $dir parameter and
+
**   $path is a relative path, then $path is interpreted relative to $dir. 
+
**   And the paths returned in the "name" column of the table are also 
+
**   relative to directory $dir.
+
**
+
** Notes on building this extension for Windows:
+
**   Unless linked statically with the SQLite library, a preprocessor
+
**   symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone
+
**   DLL form of this extension for WIN32. See its use below for details.
*/
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
-
#include <assert.h>
+
#include <stdio.h>
#include <string.h>
-
#include <ctype.h>
-
#include <stdlib.h>
+
#include <assert.h>

-
/* Mark a function parameter as unused, to suppress nuisance compiler
-
** warnings. */
-
#ifndef UNUSED_PARAMETER
-
# define UNUSED_PARAMETER(X)  (void)(X)
+
#include <sys/types.h>
+
#include <sys/stat.h>
+
#include <fcntl.h>
+
#if !defined(_WIN32) && !defined(WIN32)
+
#  include <unistd.h>
+
#  include <dirent.h>
+
#  include <utime.h>
+
#  include <sys/time.h>
+
#else
+
#  include "windows.h"
+
#  include <io.h>
+
#  include <direct.h>
+
/* #  include "test_windirent.h" */
+
#  define dirent DIRENT
+
#  ifndef chmod
+
#    define chmod _chmod
+
#  endif
+
#  ifndef stat
+
#    define stat _stat
+
#  endif
+
#  define mkdir(path,mode) _mkdir(path)
+
#  define lstat(path,buf) stat(path,buf)
#endif
+
#include <time.h>
+
#include <errno.h>


-
/* A decimal object */
-
typedef struct Decimal Decimal;
-
struct Decimal {
-
  char sign;        /* 0 for positive, 1 for negative */
-
  char oom;         /* True if an OOM is encountered */
-
  char isNull;      /* True if holds a NULL rather than a number */
-
  char isInit;      /* True upon initialization */
-
  int nDigit;       /* Total number of digits */
-
  int nFrac;        /* Number of digits to the right of the decimal point */
-
  signed char *a;   /* Array of digits.  Most significant first. */
-
};
-

/*
-
** Release memory held by a Decimal, but do not free the object itself.
+
** Structure of the fsdir() table-valued function
*/
-
static void decimal_clear(Decimal *p){
-
  sqlite3_free(p->a);
-
}
+
                 /*    0    1    2     3    4           5             */
+
#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
+
#define FSDIR_COLUMN_NAME     0     /* Name of the file */
+
#define FSDIR_COLUMN_MODE     1     /* Access mode */
+
#define FSDIR_COLUMN_MTIME    2     /* Last modification time */
+
#define FSDIR_COLUMN_DATA     3     /* File content */
+
#define FSDIR_COLUMN_PATH     4     /* Path to top of search */
+
#define FSDIR_COLUMN_DIR      5     /* Path is relative to this directory */

-
/*
-
** Destroy a Decimal object
-
*/
-
static void decimal_free(Decimal *p){
-
  if( p ){
-
    decimal_clear(p);
-
    sqlite3_free(p);
-
  }
-
}

/*
-
** Allocate a new Decimal object.  Initialize it to the number given
-
** by the input string.
+
** Set the result stored by context ctx to a blob containing the 
+
** contents of file zName.  Or, leave the result unchanged (NULL)
+
** if the file does not exist or is unreadable.
+
**
+
** If the file exceeds the SQLite blob size limit, through an
+
** SQLITE_TOOBIG error.
+
**
+
** Throw an SQLITE_IOERR if there are difficulties pulling the file
+
** off of disk.
*/
-
static Decimal *decimal_new(
-
  sqlite3_context *pCtx,
-
  sqlite3_value *pIn,
-
  int nAlt,
-
  const unsigned char *zAlt
-
){
-
  Decimal *p;
-
  int n, i;
-
  const unsigned char *zIn;
-
  int iExp = 0;
-
  p = sqlite3_malloc( sizeof(*p) );
-
  if( p==0 ) goto new_no_mem;
-
  p->sign = 0;
-
  p->oom = 0;
-
  p->isInit = 1;
-
  p->isNull = 0;
-
  p->nDigit = 0;
-
  p->nFrac = 0;
-
  if( zAlt ){
-
    n = nAlt,
-
    zIn = zAlt;
-
  }else{
-
    if( sqlite3_value_type(pIn)==SQLITE_NULL ){
-
      p->a = 0;
-
      p->isNull = 1;
-
      return p;
-
    }
-
    n = sqlite3_value_bytes(pIn);
-
    zIn = sqlite3_value_text(pIn);
-
  }
-
  p->a = sqlite3_malloc64( n+1 );
-
  if( p->a==0 ) goto new_no_mem;
-
  for(i=0; isspace(zIn[i]); i++){}
-
  if( zIn[i]=='-' ){
-
    p->sign = 1;
-
    i++;
-
  }else if( zIn[i]=='+' ){
-
    i++;
-
  }
-
  while( i<n && zIn[i]=='0' ) i++;
-
  while( i<n ){
-
    char c = zIn[i];
-
    if( c>='0' && c<='9' ){
-
      p->a[p->nDigit++] = c - '0';
-
    }else if( c=='.' ){
-
      p->nFrac = p->nDigit + 1;
-
    }else if( c=='e' || c=='E' ){
-
      int j = i+1;
-
      int neg = 0;
-
      if( j>=n ) break;
-
      if( zIn[j]=='-' ){
-
        neg = 1;
-
        j++;
-
      }else if( zIn[j]=='+' ){
-
        j++;
-
      }
-
      while( j<n && iExp<1000000 ){
-
        if( zIn[j]>='0' && zIn[j]<='9' ){
-
          iExp = iExp*10 + zIn[j] - '0';
-
        }
-
        j++;
-
      }
-
      if( neg ) iExp = -iExp;
-
      break;
-
    }
-
    i++;
-
  }
-
  if( p->nFrac ){
-
    p->nFrac = p->nDigit - (p->nFrac - 1);
-
  }
-
  if( iExp>0 ){
-
    if( p->nFrac>0 ){
-
      if( iExp<=p->nFrac ){
-
        p->nFrac -= iExp;
-
        iExp = 0;
-
      }else{
-
        iExp -= p->nFrac;
-
        p->nFrac = 0;
-
      }
-
    }
-
    if( iExp>0 ){   
-
      p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
-
      if( p->a==0 ) goto new_no_mem;
-
      memset(p->a+p->nDigit, 0, iExp);
-
      p->nDigit += iExp;
-
    }
-
  }else if( iExp<0 ){
-
    int nExtra;
-
    iExp = -iExp;
-
    nExtra = p->nDigit - p->nFrac - 1;
-
    if( nExtra ){
-
      if( nExtra>=iExp ){
-
        p->nFrac += iExp;
-
        iExp  = 0;
-
      }else{
-
        iExp -= nExtra;
-
        p->nFrac = p->nDigit - 1;
-
      }
-
    }
-
    if( iExp>0 ){
-
      p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
-
      if( p->a==0 ) goto new_no_mem;
-
      memmove(p->a+iExp, p->a, p->nDigit);
-
      memset(p->a, 0, iExp);
-
      p->nDigit += iExp;
-
      p->nFrac += iExp;
-
    }
-
  }
-
  return p;
-

-
new_no_mem:
-
  if( pCtx ) sqlite3_result_error_nomem(pCtx);
-
  sqlite3_free(p);
-
  return 0;
-
}
+
static void readFileContents(sqlite3_context *ctx, const char *zName){
+
  FILE *in;
+
  sqlite3_int64 nIn;
+
  void *pBuf;
+
  sqlite3 *db;
+
  int mxBlob;

-
/*
-
** Make the given Decimal the result.
-
*/
-
static void decimal_result(sqlite3_context *pCtx, Decimal *p){
-
  char *z;
-
  int i, j;
-
  int n;
-
  if( p==0 || p->oom ){
-
    sqlite3_result_error_nomem(pCtx);
+
  in = fopen(zName, "rb");
+
  if( in==0 ){
+
    /* File does not exist or is unreadable. Leave the result set to NULL. */
    return;
  }
-
  if( p->isNull ){
-
    sqlite3_result_null(pCtx);
+
  fseek(in, 0, SEEK_END);
+
  nIn = ftell(in);
+
  rewind(in);
+
  db = sqlite3_context_db_handle(ctx);
+
  mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
+
  if( nIn>mxBlob ){
+
    sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
+
    fclose(in);
    return;
  }
-
  z = sqlite3_malloc( p->nDigit+4 );
-
  if( z==0 ){
-
    sqlite3_result_error_nomem(pCtx);
+
  pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
+
  if( pBuf==0 ){
+
    sqlite3_result_error_nomem(ctx);
+
    fclose(in);
    return;
  }
-
  i = 0;
-
  if( p->nDigit==0 || (p->nDigit==1 && p->a[0]==0) ){
-
    p->sign = 0;
-
  }
-
  if( p->sign ){
-
    z[0] = '-';
-
    i = 1;
-
  }
-
  n = p->nDigit - p->nFrac;
-
  if( n<=0 ){
-
    z[i++] = '0';
-
  }
-
  j = 0;
-
  while( n>1 && p->a[j]==0 ){
-
    j++;
-
    n--;
-
  }
-
  while( n>0  ){
-
    z[i++] = p->a[j] + '0';
-
    j++;
-
    n--;
-
  }
-
  if( p->nFrac ){
-
    z[i++] = '.';
-
    do{
-
      z[i++] = p->a[j] + '0';
-
      j++;
-
    }while( j<p->nDigit );
-
  }
-
  z[i] = 0;
-
  sqlite3_result_text(pCtx, z, i, sqlite3_free);
+
  if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
+
    sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
+
  }else{
+
    sqlite3_result_error_code(ctx, SQLITE_IOERR);
+
    sqlite3_free(pBuf);
+
  }
+
  fclose(in);
}

/*
-
** SQL Function:   decimal(X)
-
**
-
** Convert input X into decimal and then back into text
+
** Implementation of the "readfile(X)" SQL function.  The entire content
+
** of the file named X is read and returned as a BLOB.  NULL is returned
+
** if the file does not exist or is unreadable.
*/
-
static void decimalFunc(
+
static void readfileFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
-
  Decimal *p = decimal_new(context, argv[0], 0, 0);
-
  UNUSED_PARAMETER(argc);
-
  decimal_result(context, p);
-
  decimal_free(p);
+
  const char *zName;
+
  (void)(argc);  /* Unused parameter */
+
  zName = (const char*)sqlite3_value_text(argv[0]);
+
  if( zName==0 ) return;
+
  readFileContents(context, zName);
}

/*
-
** Compare to Decimal objects.  Return negative, 0, or positive if the
-
** first object is less than, equal to, or greater than the second.
-
**
-
** Preconditions for this routine:
-
**
-
**    pA!=0
-
**    pA->isNull==0
-
**    pB!=0
-
**    pB->isNull==0
+
** Set the error message contained in context ctx to the results of
+
** vprintf(zFmt, ...).
*/
-
static int decimal_cmp(const Decimal *pA, const Decimal *pB){
-
  int nASig, nBSig, rc, n;
-
  if( pA->sign!=pB->sign ){
-
    return pA->sign ? -1 : +1;
-
  }
-
  if( pA->sign ){
-
    const Decimal *pTemp = pA;
-
    pA = pB;
-
    pB = pTemp;
-
  }
-
  nASig = pA->nDigit - pA->nFrac;
-
  nBSig = pB->nDigit - pB->nFrac;
-
  if( nASig!=nBSig ){
-
    return nASig - nBSig;
-
  }
-
  n = pA->nDigit;
-
  if( n>pB->nDigit ) n = pB->nDigit;
-
  rc = memcmp(pA->a, pB->a, n);
-
  if( rc==0 ){
-
    rc = pA->nDigit - pB->nDigit;
-
  }
-
  return rc;
+
static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
+
  char *zMsg = 0;
+
  va_list ap;
+
  va_start(ap, zFmt);
+
  zMsg = sqlite3_vmprintf(zFmt, ap);
+
  sqlite3_result_error(ctx, zMsg, -1);
+
  sqlite3_free(zMsg);
+
  va_end(ap);
}

+
#if defined(_WIN32)
/*
-
** SQL Function:   decimal_cmp(X, Y)
-
**
-
** Return negative, zero, or positive if X is less then, equal to, or
-
** greater than Y.
+
** This function is designed to convert a Win32 FILETIME structure into the
+
** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
*/
-
static void decimalCmpFunc(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
+
static sqlite3_uint64 fileTimeToUnixTime(
+
  LPFILETIME pFileTime
){
-
  Decimal *pA = 0, *pB = 0;
-
  int rc;
+
  SYSTEMTIME epochSystemTime;
+
  ULARGE_INTEGER epochIntervals;
+
  FILETIME epochFileTime;
+
  ULARGE_INTEGER fileIntervals;

-
  UNUSED_PARAMETER(argc);
-
  pA = decimal_new(context, argv[0], 0, 0);
-
  if( pA==0 || pA->isNull ) goto cmp_done;
-
  pB = decimal_new(context, argv[1], 0, 0);
-
  if( pB==0 || pB->isNull ) goto cmp_done;
-
  rc = decimal_cmp(pA, pB);
-
  if( rc<0 ) rc = -1;
-
  else if( rc>0 ) rc = +1;
-
  sqlite3_result_int(context, rc);
-
cmp_done:
-
  decimal_free(pA);
-
  decimal_free(pB);
+
  memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
+
  epochSystemTime.wYear = 1970;
+
  epochSystemTime.wMonth = 1;
+
  epochSystemTime.wDay = 1;
+
  SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
+
  epochIntervals.LowPart = epochFileTime.dwLowDateTime;
+
  epochIntervals.HighPart = epochFileTime.dwHighDateTime;
+

+
  fileIntervals.LowPart = pFileTime->dwLowDateTime;
+
  fileIntervals.HighPart = pFileTime->dwHighDateTime;
+

+
  return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
+
}
+

+

+
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
+
#  /* To allow a standalone DLL, use this next replacement function: */
+
#  undef sqlite3_win32_utf8_to_unicode
+
#  define sqlite3_win32_utf8_to_unicode utf8_to_utf16
+
#
+
LPWSTR utf8_to_utf16(const char *z){
+
  int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0);
+
  LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR));
+
  if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) )
+
    return rv;
+
  sqlite3_free(rv);
+
  return 0;
}
+
#endif

/*
-
** Expand the Decimal so that it has a least nDigit digits and nFrac
-
** digits to the right of the decimal point.
+
** This function attempts to normalize the time values found in the stat()
+
** buffer to UTC.  This is necessary on Win32, where the runtime library
+
** appears to return these values as local times.
*/
-
static void decimal_expand(Decimal *p, int nDigit, int nFrac){
-
  int nAddSig;
-
  int nAddFrac;
-
  if( p==0 ) return;
-
  nAddFrac = nFrac - p->nFrac;
-
  nAddSig = (nDigit - p->nDigit) - nAddFrac;
-
  if( nAddFrac==0 && nAddSig==0 ) return;
-
  p->a = sqlite3_realloc64(p->a, nDigit+1);
-
  if( p->a==0 ){
-
    p->oom = 1;
-
    return;
-
  }
-
  if( nAddSig ){
-
    memmove(p->a+nAddSig, p->a, p->nDigit);
-
    memset(p->a, 0, nAddSig);
-
    p->nDigit += nAddSig;
-
  }
-
  if( nAddFrac ){
-
    memset(p->a+p->nDigit, 0, nAddFrac);
-
    p->nDigit += nAddFrac;
-
    p->nFrac += nAddFrac;
+
static void statTimesToUtc(
+
  const char *zPath,
+
  struct stat *pStatBuf
+
){
+
  HANDLE hFindFile;
+
  WIN32_FIND_DATAW fd;
+
  LPWSTR zUnicodeName;
+
  extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
+
  zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
+
  if( zUnicodeName ){
+
    memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
+
    hFindFile = FindFirstFileW(zUnicodeName, &fd);
+
    if( hFindFile!=NULL ){
+
      pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
+
      pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
+
      pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
+
      FindClose(hFindFile);
+
    }
+
    sqlite3_free(zUnicodeName);
  }
}
+
#endif

/*
-
** Add the value pB into pA.
-
**
-
** Both pA and pB might become denormalized by this routine.
+
** This function is used in place of stat().  On Windows, special handling
+
** is required in order for the included time to be returned as UTC.  On all
+
** other systems, this function simply calls stat().
*/
-
static void decimal_add(Decimal *pA, Decimal *pB){
-
  int nSig, nFrac, nDigit;
-
  int i, rc;
-
  if( pA==0 ){
-
    return;
-
  }
-
  if( pA->oom || pB==0 || pB->oom ){
-
    pA->oom = 1;
-
    return;
-
  }
-
  if( pA->isNull || pB->isNull ){
-
    pA->isNull = 1;
-
    return;
-
  }
-
  nSig = pA->nDigit - pA->nFrac;
-
  if( nSig && pA->a[0]==0 ) nSig--;
-
  if( nSig<pB->nDigit-pB->nFrac ){
-
    nSig = pB->nDigit - pB->nFrac;
-
  }
-
  nFrac = pA->nFrac;
-
  if( nFrac<pB->nFrac ) nFrac = pB->nFrac;
-
  nDigit = nSig + nFrac + 1;
-
  decimal_expand(pA, nDigit, nFrac);
-
  decimal_expand(pB, nDigit, nFrac);
-
  if( pA->oom || pB->oom ){
-
    pA->oom = 1;
-
  }else{
-
    if( pA->sign==pB->sign ){
-
      int carry = 0;
-
      for(i=nDigit-1; i>=0; i--){
-
        int x = pA->a[i] + pB->a[i] + carry;
-
        if( x>=10 ){
-
          carry = 1;
-
          pA->a[i] = x - 10;
-
        }else{
-
          carry = 0;
-
          pA->a[i] = x;
-
        }
-
      }
-
    }else{
-
      signed char *aA, *aB;
-
      int borrow = 0;
-
      rc = memcmp(pA->a, pB->a, nDigit);
-
      if( rc<0 ){
-
        aA = pB->a;
-
        aB = pA->a;
-
        pA->sign = !pA->sign;
-
      }else{
-
        aA = pA->a;
-
        aB = pB->a;
-
      }
-
      for(i=nDigit-1; i>=0; i--){
-
        int x = aA[i] - aB[i] - borrow;
-
        if( x<0 ){
-
          pA->a[i] = x+10;
-
          borrow = 1;
-
        }else{
-
          pA->a[i] = x;
-
          borrow = 0;
-
        }
-
      }
-
    }
-
  }
+
static int fileStat(
+
  const char *zPath,
+
  struct stat *pStatBuf
+
){
+
#if defined(_WIN32)
+
  int rc = stat(zPath, pStatBuf);
+
  if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
+
  return rc;
+
#else
+
  return stat(zPath, pStatBuf);
+
#endif
+
}
+

+
/*
+
** This function is used in place of lstat().  On Windows, special handling
+
** is required in order for the included time to be returned as UTC.  On all
+
** other systems, this function simply calls lstat().
+
*/
+
static int fileLinkStat(
+
  const char *zPath,
+
  struct stat *pStatBuf
+
){
+
#if defined(_WIN32)
+
  int rc = lstat(zPath, pStatBuf);
+
  if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
+
  return rc;
+
#else
+
  return lstat(zPath, pStatBuf);
+
#endif
}

/*
-
** Compare text in decimal order.
+
** Argument zFile is the name of a file that will be created and/or written
+
** by SQL function writefile(). This function ensures that the directory
+
** zFile will be written to exists, creating it if required. The permissions
+
** for any path components created by this function are set in accordance
+
** with the current umask.
+
**
+
** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
+
** SQLITE_OK is returned if the directory is successfully created, or
+
** SQLITE_ERROR otherwise.
*/
-
static int decimalCollFunc(
-
  void *notUsed,
-
  int nKey1, const void *pKey1,
-
  int nKey2, const void *pKey2
+
static int makeDirectory(
+
  const char *zFile
){
-
  const unsigned char *zA = (const unsigned char*)pKey1;
-
  const unsigned char *zB = (const unsigned char*)pKey2;
-
  Decimal *pA = decimal_new(0, 0, nKey1, zA);
-
  Decimal *pB = decimal_new(0, 0, nKey2, zB);
-
  int rc;
-
  UNUSED_PARAMETER(notUsed);
-
  if( pA==0 || pB==0 ){
-
    rc = 0;
+
  char *zCopy = sqlite3_mprintf("%s", zFile);
+
  int rc = SQLITE_OK;
+

+
  if( zCopy==0 ){
+
    rc = SQLITE_NOMEM;
  }else{
-
    rc = decimal_cmp(pA, pB);
+
    int nCopy = (int)strlen(zCopy);
+
    int i = 1;
+

+
    while( rc==SQLITE_OK ){
+
      struct stat sStat;
+
      int rc2;
+

+
      for(; zCopy[i]!='/' && i<nCopy; i++);
+
      if( i==nCopy ) break;
+
      zCopy[i] = '\0';
+

+
      rc2 = fileStat(zCopy, &sStat);
+
      if( rc2!=0 ){
+
        if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR;
+
      }else{
+
        if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
+
      }
+
      zCopy[i] = '/';
+
      i++;
+
    }
+

+
    sqlite3_free(zCopy);
  }
-
  decimal_free(pA);
-
  decimal_free(pB);
+

  return rc;
}

-

/*
-
** SQL Function:   decimal_add(X, Y)
-
**                 decimal_sub(X, Y)
-
**
-
** Return the sum or difference of X and Y.
+
** This function does the work for the writefile() UDF. Refer to 
+
** header comments at the top of this file for details.
*/
-
static void decimalAddFunc(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
-
){
-
  Decimal *pA = decimal_new(context, argv[0], 0, 0);
-
  Decimal *pB = decimal_new(context, argv[1], 0, 0);
-
  UNUSED_PARAMETER(argc);
-
  decimal_add(pA, pB);
-
  decimal_result(context, pA);
-
  decimal_free(pA);
-
  decimal_free(pB);
-
}
-
static void decimalSubFunc(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
+
static int writeFile(
+
  sqlite3_context *pCtx,          /* Context to return bytes written in */
+
  const char *zFile,              /* File to write */
+
  sqlite3_value *pData,           /* Data to write */
+
  mode_t mode,                    /* MODE parameter passed to writefile() */
+
  sqlite3_int64 mtime             /* MTIME parameter (or -1 to not set time) */
){
-
  Decimal *pA = decimal_new(context, argv[0], 0, 0);
-
  Decimal *pB = decimal_new(context, argv[1], 0, 0);
-
  UNUSED_PARAMETER(argc);
-
  if( pB ){
-
    pB->sign = !pB->sign;
-
    decimal_add(pA, pB);
-
    decimal_result(context, pA);
+
  if( zFile==0 ) return 1;
+
#if !defined(_WIN32) && !defined(WIN32)
+
  if( S_ISLNK(mode) ){
+
    const char *zTo = (const char*)sqlite3_value_text(pData);
+
    if( zTo==0 || symlink(zTo, zFile)<0 ) return 1;
+
  }else
+
#endif
+
  {
+
    if( S_ISDIR(mode) ){
+
      if( mkdir(zFile, mode) ){
+
        /* The mkdir() call to create the directory failed. This might not
+
        ** be an error though - if there is already a directory at the same
+
        ** path and either the permissions already match or can be changed
+
        ** to do so using chmod(), it is not an error.  */
+
        struct stat sStat;
+
        if( errno!=EEXIST
+
         || 0!=fileStat(zFile, &sStat)
+
         || !S_ISDIR(sStat.st_mode)
+
         || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
+
        ){
+
          return 1;
+
        }
+
      }
+
    }else{
+
      sqlite3_int64 nWrite = 0;
+
      const char *z;
+
      int rc = 0;
+
      FILE *out = fopen(zFile, "wb");
+
      if( out==0 ) return 1;
+
      z = (const char*)sqlite3_value_blob(pData);
+
      if( z ){
+
        sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
+
        nWrite = sqlite3_value_bytes(pData);
+
        if( nWrite!=n ){
+
          rc = 1;
+
        }
+
      }
+
      fclose(out);
+
      if( rc==0 && mode && chmod(zFile, mode & 0777) ){
+
        rc = 1;
+
      }
+
      if( rc ) return 2;
+
      sqlite3_result_int64(pCtx, nWrite);
+
    }
  }
-
  decimal_free(pA);
-
  decimal_free(pB);
+

+
  if( mtime>=0 ){
+
#if defined(_WIN32)
+
#if !SQLITE_OS_WINRT
+
    /* Windows */
+
    FILETIME lastAccess;
+
    FILETIME lastWrite;
+
    SYSTEMTIME currentTime;
+
    LONGLONG intervals;
+
    HANDLE hFile;
+
    LPWSTR zUnicodeName;
+
    extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
+

+
    GetSystemTime(&currentTime);
+
    SystemTimeToFileTime(&currentTime, &lastAccess);
+
    intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
+
    lastWrite.dwLowDateTime = (DWORD)intervals;
+
    lastWrite.dwHighDateTime = intervals >> 32;
+
    zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
+
    if( zUnicodeName==0 ){
+
      return 1;
+
    }
+
    hFile = CreateFileW(
+
      zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
+
      FILE_FLAG_BACKUP_SEMANTICS, NULL
+
    );
+
    sqlite3_free(zUnicodeName);
+
    if( hFile!=INVALID_HANDLE_VALUE ){
+
      BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
+
      CloseHandle(hFile);
+
      return !bResult;
+
    }else{
+
      return 1;
+
    }
+
#endif
+
#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
+
    /* Recent unix */
+
    struct timespec times[2];
+
    times[0].tv_nsec = times[1].tv_nsec = 0;
+
    times[0].tv_sec = time(0);
+
    times[1].tv_sec = mtime;
+
    if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
+
      return 1;
+
    }
+
#else
+
    /* Legacy unix */
+
    struct timeval times[2];
+
    times[0].tv_usec = times[1].tv_usec = 0;
+
    times[0].tv_sec = time(0);
+
    times[1].tv_sec = mtime;
+
    if( utimes(zFile, times) ){
+
      return 1;
+
    }
+
#endif
+
  }
+

+
  return 0;
}

-
/* Aggregate funcion:   decimal_sum(X)
-
**
-
** Works like sum() except that it uses decimal arithmetic for unlimited
-
** precision.
+
/*
+
** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.  
+
** Refer to header comments at the top of this file for details.
*/
-
static void decimalSumStep(
+
static void writefileFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
-
  Decimal *p;
-
  Decimal *pArg;
-
  UNUSED_PARAMETER(argc);
-
  p = sqlite3_aggregate_context(context, sizeof(*p));
-
  if( p==0 ) return;
-
  if( !p->isInit ){
-
    p->isInit = 1;
-
    p->a = sqlite3_malloc(2);
-
    if( p->a==0 ){
-
      p->oom = 1;
+
  const char *zFile;
+
  mode_t mode = 0;
+
  int res;
+
  sqlite3_int64 mtime = -1;
+

+
  if( argc<2 || argc>4 ){
+
    sqlite3_result_error(context, 
+
        "wrong number of arguments to function writefile()", -1
+
    );
+
    return;
+
  }
+

+
  zFile = (const char*)sqlite3_value_text(argv[0]);
+
  if( zFile==0 ) return;
+
  if( argc>=3 ){
+
    mode = (mode_t)sqlite3_value_int(argv[2]);
+
  }
+
  if( argc==4 ){
+
    mtime = sqlite3_value_int64(argv[3]);
+
  }
+

+
  res = writeFile(context, zFile, argv[1], mode, mtime);
+
  if( res==1 && errno==ENOENT ){
+
    if( makeDirectory(zFile)==SQLITE_OK ){
+
      res = writeFile(context, zFile, argv[1], mode, mtime);
+
    }
+
  }
+

+
  if( argc>2 && res!=0 ){
+
    if( S_ISLNK(mode) ){
+
      ctxErrorMsg(context, "failed to create symlink: %s", zFile);
+
    }else if( S_ISDIR(mode) ){
+
      ctxErrorMsg(context, "failed to create directory: %s", zFile);
    }else{
-
      p->a[0] = 0;
+
      ctxErrorMsg(context, "failed to write file: %s", zFile);
    }
-
    p->nDigit = 1;
-
    p->nFrac = 0;
  }
-
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
-
  pArg = decimal_new(context, argv[0], 0, 0);
-
  decimal_add(p, pArg);
-
  decimal_free(pArg);
-
}
-
static void decimalSumInverse(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
-
){
-
  Decimal *p;
-
  Decimal *pArg;
-
  UNUSED_PARAMETER(argc);
-
  p = sqlite3_aggregate_context(context, sizeof(*p));
-
  if( p==0 ) return;
-
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
-
  pArg = decimal_new(context, argv[0], 0, 0);
-
  if( pArg ) pArg->sign = !pArg->sign;
-
  decimal_add(p, pArg);
-
  decimal_free(pArg);
-
}
-
static void decimalSumValue(sqlite3_context *context){
-
  Decimal *p = sqlite3_aggregate_context(context, 0);
-
  if( p==0 ) return;
-
  decimal_result(context, p);
-
}
-
static void decimalSumFinalize(sqlite3_context *context){
-
  Decimal *p = sqlite3_aggregate_context(context, 0);
-
  if( p==0 ) return;
-
  decimal_result(context, p);
-
  decimal_clear(p);
}

/*
-
** SQL Function:   decimal_mul(X, Y)
-
**
-
** Return the product of X and Y.
+
** SQL function:   lsmode(MODE)
**
-
** All significant digits after the decimal point are retained.
-
** Trailing zeros after the decimal point are omitted as long as
-
** the number of digits after the decimal point is no less than
-
** either the number of digits in either input.
+
** Given a numberic st_mode from stat(), convert it into a human-readable
+
** text string in the style of "ls -l".
*/
-
static void decimalMulFunc(
+
static void lsModeFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
-
  Decimal *pA = decimal_new(context, argv[0], 0, 0);
-
  Decimal *pB = decimal_new(context, argv[1], 0, 0);
-
  signed char *acc = 0;
-
  int i, j, k;
-
  int minFrac;
-
  UNUSED_PARAMETER(argc);
-
  if( pA==0 || pA->oom || pA->isNull
-
   || pB==0 || pB->oom || pB->isNull 
-
  ){
-
    goto mul_end;
-
  }
-
  acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 );
-
  if( acc==0 ){
-
    sqlite3_result_error_nomem(context);
-
    goto mul_end;
-
  }
-
  memset(acc, 0, pA->nDigit + pB->nDigit + 2);
-
  minFrac = pA->nFrac;
-
  if( pB->nFrac<minFrac ) minFrac = pB->nFrac;
-
  for(i=pA->nDigit-1; i>=0; i--){
-
    signed char f = pA->a[i];
-
    int carry = 0, x;
-
    for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){
-
      x = acc[k] + f*pB->a[j] + carry;
-
      acc[k] = x%10;
-
      carry = x/10;
-
    }
-
    x = acc[k] + carry;
-
    acc[k] = x%10;
-
    acc[k-1] += x/10;
+
  int i;
+
  int iMode = sqlite3_value_int(argv[0]);
+
  char z[16];
+
  (void)argc;
+
  if( S_ISLNK(iMode) ){
+
    z[0] = 'l';
+
  }else if( S_ISREG(iMode) ){
+
    z[0] = '-';
+
  }else if( S_ISDIR(iMode) ){
+
    z[0] = 'd';
+
  }else{
+
    z[0] = '?';
  }
-
  sqlite3_free(pA->a);
-
  pA->a = acc;
-
  acc = 0;
-
  pA->nDigit += pB->nDigit + 2;
-
  pA->nFrac += pB->nFrac;
-
  pA->sign ^= pB->sign;
-
  while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){
-
    pA->nFrac--;
-
    pA->nDigit--;
+
  for(i=0; i<3; i++){
+
    int m = (iMode >> ((2-i)*3));
+
    char *a = &z[1 + i*3];
+
    a[0] = (m & 0x4) ? 'r' : '-';
+
    a[1] = (m & 0x2) ? 'w' : '-';
+
    a[2] = (m & 0x1) ? 'x' : '-';
  }
-
  decimal_result(context, pA);
-

-
mul_end:
-
  sqlite3_free(acc);
-
  decimal_free(pA);
-
  decimal_free(pB);
+
  z[10] = '\0';
+
  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
}

-
#ifdef _WIN32
+
#ifndef SQLITE_OMIT_VIRTUALTABLE

-
#endif
-
int sqlite3_decimal_init(
-
  sqlite3 *db, 
-
  char **pzErrMsg, 
-
  const sqlite3_api_routines *pApi
-
){
-
  int rc = SQLITE_OK;
-
  static const struct {
-
    const char *zFuncName;
-
    int nArg;
-
    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
-
  } aFunc[] = {
-
    { "decimal",       1,   decimalFunc        },
-
    { "decimal_cmp",   2,   decimalCmpFunc     },
-
    { "decimal_add",   2,   decimalAddFunc     },
-
    { "decimal_sub",   2,   decimalSubFunc     },
-
    { "decimal_mul",   2,   decimalMulFunc     },
-
  };
-
  unsigned int i;
-
  (void)pzErrMsg;  /* Unused parameter */
+
/* 
+
** Cursor type for recursively iterating through a directory structure.
+
*/
+
typedef struct fsdir_cursor fsdir_cursor;
+
typedef struct FsdirLevel FsdirLevel;

-
  SQLITE_EXTENSION_INIT2(pApi);
+
struct FsdirLevel {
+
  DIR *pDir;                 /* From opendir() */
+
  char *zDir;                /* Name of directory (nul-terminated) */
+
};

-
  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
-
    rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg,
-
                   SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
-
                   0, aFunc[i].xFunc, 0, 0);
-
  }
-
  if( rc==SQLITE_OK ){
-
    rc = sqlite3_create_window_function(db, "decimal_sum", 1,
-
                   SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0,
-
                   decimalSumStep, decimalSumFinalize,
-
                   decimalSumValue, decimalSumInverse, 0);
-
  }
+
struct fsdir_cursor {
+
  sqlite3_vtab_cursor base;  /* Base class - must be first */
+

+
  int nLvl;                  /* Number of entries in aLvl[] array */
+
  int iLvl;                  /* Index of current entry */
+
  FsdirLevel *aLvl;          /* Hierarchy of directories being traversed */
+

+
  const char *zBase;
+
  int nBase;
+

+
  struct stat sStat;         /* Current lstat() results */
+
  char *zPath;               /* Path to current entry */
+
  sqlite3_int64 iRowid;      /* Current rowid */
+
};
+

+
typedef struct fsdir_tab fsdir_tab;
+
struct fsdir_tab {
+
  sqlite3_vtab base;         /* Base class - must be first */
+
};
+

+
/*
+
** Construct a new fsdir virtual table object.
+
*/
+
static int fsdirConnect(
+
  sqlite3 *db,
+
  void *pAux,
+
  int argc, const char *const*argv,
+
  sqlite3_vtab **ppVtab,
+
  char **pzErr
+
){
+
  fsdir_tab *pNew = 0;
+
  int rc;
+
  (void)pAux;
+
  (void)argc;
+
  (void)argv;
+
  (void)pzErr;
+
  rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
  if( rc==SQLITE_OK ){
-
    rc = sqlite3_create_collation(db, "decimal", SQLITE_UTF8,
-
                                  0, decimalCollFunc);
+
    pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
+
    if( pNew==0 ) return SQLITE_NOMEM;
+
    memset(pNew, 0, sizeof(*pNew));
+
    sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
  }
+
  *ppVtab = (sqlite3_vtab*)pNew;
  return rc;
}

-
/************************* End ../ext/misc/decimal.c ********************/
-
/************************* Begin ../ext/misc/ieee754.c ******************/
/*
-
** 2013-04-17
-
**
-
** 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 SQLite extension implements functions for the exact display
-
** and input of IEEE754 Binary64 floating-point numbers.
-
**
-
**   ieee754(X)
-
**   ieee754(Y,Z)
-
**
-
** In the first form, the value X should be a floating-point number.
-
** The function will return a string of the form 'ieee754(Y,Z)' where
-
** Y and Z are integers such that X==Y*pow(2,Z).
-
**
-
** In the second form, Y and Z are integers which are the mantissa and
-
** base-2 exponent of a new floating point number.  The function returns
-
** a floating-point value equal to Y*pow(2,Z).
-
**
-
** Examples:
-
**
-
**     ieee754(2.0)             ->     'ieee754(2,0)'
-
**     ieee754(45.25)           ->     'ieee754(181,-2)'
-
**     ieee754(2, 0)            ->     2.0
-
**     ieee754(181, -2)         ->     45.25
-
**
-
** Two additional functions break apart the one-argument ieee754()
-
** result into separate integer values:
-
**
-
**     ieee754_mantissa(45.25)  ->     181
-
**     ieee754_exponent(45.25)  ->     -2
-
**
-
** These functions convert binary64 numbers into blobs and back again.
-
**
-
**     ieee754_from_blob(x'3ff0000000000000')  ->  1.0
-
**     ieee754_to_blob(1.0)                    ->  x'3ff0000000000000'
-
**
-
** In all single-argument functions, if the argument is an 8-byte blob
-
** then that blob is interpreted as a big-endian binary64 value.
-
**
-
**
-
** EXACT DECIMAL REPRESENTATION OF BINARY64 VALUES
-
** -----------------------------------------------
-
**
-
** This extension in combination with the separate 'decimal' extension
-
** can be used to compute the exact decimal representation of binary64
-
** values.  To begin, first compute a table of exponent values:
-
**
-
**    CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT);
-
**    WITH RECURSIVE c(x,v) AS (
-
**      VALUES(0,'1')
-
**      UNION ALL
-
**      SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1<=971
-
**    ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
-
**    WITH RECURSIVE c(x,v) AS (
-
**      VALUES(-1,'0.5')
-
**      UNION ALL
-
**      SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1>=-1075
-
**    ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
-
**
-
** Then, to compute the exact decimal representation of a floating
-
** point value (the value 47.49 is used in the example) do:
-
**
-
**    WITH c(n) AS (VALUES(47.49))
-
**          ---------------^^^^^---- Replace with whatever you want
-
**    SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v)
-
**      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
-
**
-
** Here is a query to show various boundry values for the binary64
-
** number format:
-
**
-
**    WITH c(name,bin) AS (VALUES
-
**       ('minimum positive value',        x'0000000000000001'),
-
**       ('maximum subnormal value',       x'000fffffffffffff'),
-
**       ('mininum positive nornal value', x'0010000000000000'),
-
**       ('maximum value',                 x'7fefffffffffffff'))
-
**    SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v)
-
**      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin);
-
**
+
** This method is the destructor for fsdir vtab objects.
+
*/
+
static int fsdirDisconnect(sqlite3_vtab *pVtab){
+
  sqlite3_free(pVtab);
+
  return SQLITE_OK;
+
}
+

+
/*
+
** Constructor for a new fsdir_cursor object.
+
*/
+
static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+
  fsdir_cursor *pCur;
+
  (void)p;
+
  pCur = sqlite3_malloc( sizeof(*pCur) );
+
  if( pCur==0 ) return SQLITE_NOMEM;
+
  memset(pCur, 0, sizeof(*pCur));
+
  pCur->iLvl = -1;
+
  *ppCursor = &pCur->base;
+
  return SQLITE_OK;
+
}
+

+
/*
+
** Reset a cursor back to the state it was in when first returned
+
** by fsdirOpen().
+
*/
+
static void fsdirResetCursor(fsdir_cursor *pCur){
+
  int i;
+
  for(i=0; i<=pCur->iLvl; i++){
+
    FsdirLevel *pLvl = &pCur->aLvl[i];
+
    if( pLvl->pDir ) closedir(pLvl->pDir);
+
    sqlite3_free(pLvl->zDir);
+
  }
+
  sqlite3_free(pCur->zPath);
+
  sqlite3_free(pCur->aLvl);
+
  pCur->aLvl = 0;
+
  pCur->zPath = 0;
+
  pCur->zBase = 0;
+
  pCur->nBase = 0;
+
  pCur->nLvl = 0;
+
  pCur->iLvl = -1;
+
  pCur->iRowid = 1;
+
}
+

+
/*
+
** Destructor for an fsdir_cursor.
+
*/
+
static int fsdirClose(sqlite3_vtab_cursor *cur){
+
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
+

+
  fsdirResetCursor(pCur);
+
  sqlite3_free(pCur);
+
  return SQLITE_OK;
+
}
+

+
/*
+
** Set the error message for the virtual table associated with cursor
+
** pCur to the results of vprintf(zFmt, ...).
*/
-
/* #include "sqlite3ext.h" */
-
SQLITE_EXTENSION_INIT1
-
#include <assert.h>
-
#include <string.h>
+
static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
+
  va_list ap;
+
  va_start(ap, zFmt);
+
  pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
+
  va_end(ap);
+
}

-
/* Mark a function parameter as unused, to suppress nuisance compiler
-
** warnings. */
-
#ifndef UNUSED_PARAMETER
-
# define UNUSED_PARAMETER(X)  (void)(X)
-
#endif

/*
-
** Implementation of the ieee754() function
+
** Advance an fsdir_cursor to its next row of output.
*/
-
static void ieee754func(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
-
){
-
  if( argc==1 ){
-
    sqlite3_int64 m, a;
-
    double r;
-
    int e;
-
    int isNeg;
-
    char zResult[100];
-
    assert( sizeof(m)==sizeof(r) );
-
    if( sqlite3_value_type(argv[0])==SQLITE_BLOB
-
     && sqlite3_value_bytes(argv[0])==sizeof(r)
-
    ){
-
      const unsigned char *x = sqlite3_value_blob(argv[0]);
-
      unsigned int i;
-
      sqlite3_uint64 v = 0;
-
      for(i=0; i<sizeof(r); i++){
-
        v = (v<<8) | x[i];
-
      }
-
      memcpy(&r, &v, sizeof(r));
-
    }else{
-
      r = sqlite3_value_double(argv[0]);
+
static int fsdirNext(sqlite3_vtab_cursor *cur){
+
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
+
  mode_t m = pCur->sStat.st_mode;
+

+
  pCur->iRowid++;
+
  if( S_ISDIR(m) ){
+
    /* Descend into this directory */
+
    int iNew = pCur->iLvl + 1;
+
    FsdirLevel *pLvl;
+
    if( iNew>=pCur->nLvl ){
+
      int nNew = iNew+1;
+
      sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
+
      FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
+
      if( aNew==0 ) return SQLITE_NOMEM;
+
      memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
+
      pCur->aLvl = aNew;
+
      pCur->nLvl = nNew;
    }
-
    if( r<0.0 ){
-
      isNeg = 1;
-
      r = -r;
-
    }else{
-
      isNeg = 0;
+
    pCur->iLvl = iNew;
+
    pLvl = &pCur->aLvl[iNew];
+
    
+
    pLvl->zDir = pCur->zPath;
+
    pCur->zPath = 0;
+
    pLvl->pDir = opendir(pLvl->zDir);
+
    if( pLvl->pDir==0 ){
+
      fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
+
      return SQLITE_ERROR;
    }
-
    memcpy(&a,&r,sizeof(a));
-
    if( a==0 ){
-
      e = 0;
-
      m = 0;
-
    }else{
-
      e = a>>52;
-
      m = a & ((((sqlite3_int64)1)<<52)-1);
-
      if( e==0 ){
-
        m <<= 1;
-
      }else{
-
        m |= ((sqlite3_int64)1)<<52;
+
  }
+

+
  while( pCur->iLvl>=0 ){
+
    FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
+
    struct dirent *pEntry = readdir(pLvl->pDir);
+
    if( pEntry ){
+
      if( pEntry->d_name[0]=='.' ){
+
       if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
+
       if( pEntry->d_name[1]=='\0' ) continue;
      }
-
      while( e<1075 && m>0 && (m&1)==0 ){
-
        m >>= 1;
-
        e++;
+
      sqlite3_free(pCur->zPath);
+
      pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
+
      if( pCur->zPath==0 ) return SQLITE_NOMEM;
+
      if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
+
        fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
+
        return SQLITE_ERROR;
      }
-
      if( isNeg ) m = -m;
+
      return SQLITE_OK;
    }
-
    switch( *(int*)sqlite3_user_data(context) ){
-
      case 0:
-
        sqlite3_snprintf(sizeof(zResult), zResult, "ieee754(%lld,%d)",
-
                         m, e-1075);
-
        sqlite3_result_text(context, zResult, -1, SQLITE_TRANSIENT);
-
        break;
-
      case 1:
-
        sqlite3_result_int64(context, m);
-
        break;
-
      case 2:
-
        sqlite3_result_int(context, e-1075);
-
        break;
+
    closedir(pLvl->pDir);
+
    sqlite3_free(pLvl->zDir);
+
    pLvl->pDir = 0;
+
    pLvl->zDir = 0;
+
    pCur->iLvl--;
+
  }
+

+
  /* EOF */
+
  sqlite3_free(pCur->zPath);
+
  pCur->zPath = 0;
+
  return SQLITE_OK;
+
}
+

+
/*
+
** Return values of columns for the row at which the series_cursor
+
** is currently pointing.
+
*/
+
static int fsdirColumn(
+
  sqlite3_vtab_cursor *cur,   /* The cursor */
+
  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
+
  int i                       /* Which column to return */
+
){
+
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
+
  switch( i ){
+
    case FSDIR_COLUMN_NAME: {
+
      sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
+
      break;
    }
-
  }else{
-
    sqlite3_int64 m, e, a;
-
    double r;
-
    int isNeg = 0;
-
    m = sqlite3_value_int64(argv[0]);
-
    e = sqlite3_value_int64(argv[1]);

-
    /* Limit the range of e.  Ticket 22dea1cfdb9151e4 2021-03-02 */
-
    if( e>10000 ){
-
      e = 10000;
-
    }else if( e<-10000 ){
-
      e = -10000;
-
    }
+
    case FSDIR_COLUMN_MODE:
+
      sqlite3_result_int64(ctx, pCur->sStat.st_mode);
+
      break;
+

+
    case FSDIR_COLUMN_MTIME:
+
      sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
+
      break;
+

+
    case FSDIR_COLUMN_DATA: {
+
      mode_t m = pCur->sStat.st_mode;
+
      if( S_ISDIR(m) ){
+
        sqlite3_result_null(ctx);
+
#if !defined(_WIN32) && !defined(WIN32)
+
      }else if( S_ISLNK(m) ){
+
        char aStatic[64];
+
        char *aBuf = aStatic;
+
        sqlite3_int64 nBuf = 64;
+
        int n;
+

+
        while( 1 ){
+
          n = readlink(pCur->zPath, aBuf, nBuf);
+
          if( n<nBuf ) break;
+
          if( aBuf!=aStatic ) sqlite3_free(aBuf);
+
          nBuf = nBuf*2;
+
          aBuf = sqlite3_malloc64(nBuf);
+
          if( aBuf==0 ){
+
            sqlite3_result_error_nomem(ctx);
+
            return SQLITE_NOMEM;
+
          }
+
        }

-
    if( m<0 ){
-
      isNeg = 1;
-
      m = -m;
-
      if( m<0 ) return;
-
    }else if( m==0 && e>-1000 && e<1000 ){
-
      sqlite3_result_double(context, 0.0);
-
      return;
-
    }
-
    while( (m>>32)&0xffe00000 ){
-
      m >>= 1;
-
      e++;
-
    }
-
    while( m!=0 && ((m>>32)&0xfff00000)==0 ){
-
      m <<= 1;
-
      e--;
-
    }
-
    e += 1075;
-
    if( e<=0 ){
-
      /* Subnormal */
-
      if( 1-e >= 64 ){
-
        m = 0;
+
        sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
+
        if( aBuf!=aStatic ) sqlite3_free(aBuf);
+
#endif
      }else{
-
        m >>= 1-e;
+
        readFileContents(ctx, pCur->zPath);
      }
-
      e = 0;
-
    }else if( e>0x7ff ){
-
      e = 0x7ff;
    }
-
    a = m & ((((sqlite3_int64)1)<<52)-1);
-
    a |= e<<52;
-
    if( isNeg ) a |= ((sqlite3_uint64)1)<<63;
-
    memcpy(&r, &a, sizeof(r));
-
    sqlite3_result_double(context, r);
+
    case FSDIR_COLUMN_PATH:
+
    default: {
+
      /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
+
      ** always return their values as NULL */
+
      break;
+
    }
  }
+
  return SQLITE_OK;
}

/*
-
** Functions to convert between blobs and floats.
+
** Return the rowid for the current row. In this implementation, the
+
** first row returned is assigned rowid value 1, and each subsequent
+
** row a value 1 more than that of the previous.
*/
-
static void ieee754func_from_blob(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
+
static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
+
  *pRowid = pCur->iRowid;
+
  return SQLITE_OK;
+
}
+

+
/*
+
** Return TRUE if the cursor has been moved off of the last
+
** row of output.
+
*/
+
static int fsdirEof(sqlite3_vtab_cursor *cur){
+
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
+
  return (pCur->zPath==0);
+
}
+

+
/*
+
** xFilter callback.
+
**
+
** idxNum==1   PATH parameter only
+
** idxNum==2   Both PATH and DIR supplied
+
*/
+
static int fsdirFilter(
+
  sqlite3_vtab_cursor *cur, 
+
  int idxNum, const char *idxStr,
+
  int argc, sqlite3_value **argv
){
-
  UNUSED_PARAMETER(argc);
-
  if( sqlite3_value_type(argv[0])==SQLITE_BLOB
-
   && sqlite3_value_bytes(argv[0])==sizeof(double)
-
  ){
-
    double r;
-
    const unsigned char *x = sqlite3_value_blob(argv[0]);
-
    unsigned int i;
-
    sqlite3_uint64 v = 0;
-
    for(i=0; i<sizeof(r); i++){
-
      v = (v<<8) | x[i];
-
    }
-
    memcpy(&r, &v, sizeof(r));
-
    sqlite3_result_double(context, r);
+
  const char *zDir = 0;
+
  fsdir_cursor *pCur = (fsdir_cursor*)cur;
+
  (void)idxStr;
+
  fsdirResetCursor(pCur);
+

+
  if( idxNum==0 ){
+
    fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
+
    return SQLITE_ERROR;
+
  }
+

+
  assert( argc==idxNum && (argc==1 || argc==2) );
+
  zDir = (const char*)sqlite3_value_text(argv[0]);
+
  if( zDir==0 ){
+
    fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
+
    return SQLITE_ERROR;
+
  }
+
  if( argc==2 ){
+
    pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
+
  }
+
  if( pCur->zBase ){
+
    pCur->nBase = (int)strlen(pCur->zBase)+1;
+
    pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
+
  }else{
+
    pCur->zPath = sqlite3_mprintf("%s", zDir);
+
  }
+

+
  if( pCur->zPath==0 ){
+
    return SQLITE_NOMEM;
+
  }
+
  if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
+
    fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
+
    return SQLITE_ERROR;
  }
+

+
  return SQLITE_OK;
}
-
static void ieee754func_to_blob(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
+

+
/*
+
** SQLite will invoke this method one or more times while planning a query
+
** that uses the generate_series virtual table.  This routine needs to create
+
** a query plan for each invocation and compute an estimated cost for that
+
** plan.
+
**
+
** In this implementation idxNum is used to represent the
+
** query plan.  idxStr is unused.
+
**
+
** The query plan is represented by values of idxNum:
+
**
+
**  (1)  The path value is supplied by argv[0]
+
**  (2)  Path is in argv[0] and dir is in argv[1]
+
*/
+
static int fsdirBestIndex(
+
  sqlite3_vtab *tab,
+
  sqlite3_index_info *pIdxInfo
){
-
  UNUSED_PARAMETER(argc);
-
  if( sqlite3_value_type(argv[0])==SQLITE_FLOAT
-
   || sqlite3_value_type(argv[0])==SQLITE_INTEGER
-
  ){
-
    double r = sqlite3_value_double(argv[0]);
-
    sqlite3_uint64 v;
-
    unsigned char a[sizeof(r)];
-
    unsigned int i;
-
    memcpy(&v, &r, sizeof(r));
-
    for(i=1; i<=sizeof(r); i++){
-
      a[sizeof(r)-i] = v&0xff;
-
      v >>= 8;
+
  int i;                 /* Loop over constraints */
+
  int idxPath = -1;      /* Index in pIdxInfo->aConstraint of PATH= */
+
  int idxDir = -1;       /* Index in pIdxInfo->aConstraint of DIR= */
+
  int seenPath = 0;      /* True if an unusable PATH= constraint is seen */
+
  int seenDir = 0;       /* True if an unusable DIR= constraint is seen */
+
  const struct sqlite3_index_constraint *pConstraint;
+

+
  (void)tab;
+
  pConstraint = pIdxInfo->aConstraint;
+
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
+
    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+
    switch( pConstraint->iColumn ){
+
      case FSDIR_COLUMN_PATH: {
+
        if( pConstraint->usable ){
+
          idxPath = i;
+
          seenPath = 0;
+
        }else if( idxPath<0 ){
+
          seenPath = 1;
+
        }
+
        break;
+
      }
+
      case FSDIR_COLUMN_DIR: {
+
        if( pConstraint->usable ){
+
          idxDir = i;
+
          seenDir = 0;
+
        }else if( idxDir<0 ){
+
          seenDir = 1;
+
        }
+
        break;
+
      }
+
    } 
+
  }
+
  if( seenPath || seenDir ){
+
    /* If input parameters are unusable, disallow this plan */
+
    return SQLITE_CONSTRAINT;
+
  }
+

+
  if( idxPath<0 ){
+
    pIdxInfo->idxNum = 0;
+
    /* The pIdxInfo->estimatedCost should have been initialized to a huge
+
    ** number.  Leave it unchanged. */
+
    pIdxInfo->estimatedRows = 0x7fffffff;
+
  }else{
+
    pIdxInfo->aConstraintUsage[idxPath].omit = 1;
+
    pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
+
    if( idxDir>=0 ){
+
      pIdxInfo->aConstraintUsage[idxDir].omit = 1;
+
      pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
+
      pIdxInfo->idxNum = 2;
+
      pIdxInfo->estimatedCost = 10.0;
+
    }else{
+
      pIdxInfo->idxNum = 1;
+
      pIdxInfo->estimatedCost = 100.0;
    }
-
    sqlite3_result_blob(context, a, sizeof(r), SQLITE_TRANSIENT);
  }
+

+
  return SQLITE_OK;
}

+
/*
+
** Register the "fsdir" virtual table.
+
*/
+
static int fsdirRegister(sqlite3 *db){
+
  static sqlite3_module fsdirModule = {
+
    0,                         /* iVersion */
+
    0,                         /* xCreate */
+
    fsdirConnect,              /* xConnect */
+
    fsdirBestIndex,            /* xBestIndex */
+
    fsdirDisconnect,           /* xDisconnect */
+
    0,                         /* xDestroy */
+
    fsdirOpen,                 /* xOpen - open a cursor */
+
    fsdirClose,                /* xClose - close a cursor */
+
    fsdirFilter,               /* xFilter - configure scan constraints */
+
    fsdirNext,                 /* xNext - advance a cursor */
+
    fsdirEof,                  /* xEof - check for end of scan */
+
    fsdirColumn,               /* xColumn - read data */
+
    fsdirRowid,                /* xRowid - read data */
+
    0,                         /* xUpdate */
+
    0,                         /* xBegin */
+
    0,                         /* xSync */
+
    0,                         /* xCommit */
+
    0,                         /* xRollback */
+
    0,                         /* xFindMethod */
+
    0,                         /* xRename */
+
    0,                         /* xSavepoint */
+
    0,                         /* xRelease */
+
    0,                         /* xRollbackTo */
+
    0,                         /* xShadowName */
+
  };
+

+
  int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
+
  return rc;
+
}
+
#else         /* SQLITE_OMIT_VIRTUALTABLE */
+
# define fsdirRegister(x) SQLITE_OK
+
#endif

#ifdef _WIN32

#endif
-
int sqlite3_ieee_init(
+
int sqlite3_fileio_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
-
  static const struct {
-
    char *zFName;
-
    int nArg;
-
    int iAux;
-
    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
-
  } aFunc[] = {
-
    { "ieee754",           1,   0, ieee754func },
-
    { "ieee754",           2,   0, ieee754func },
-
    { "ieee754_mantissa",  1,   1, ieee754func },
-
    { "ieee754_exponent",  1,   2, ieee754func },
-
    { "ieee754_to_blob",   1,   0, ieee754func_to_blob },
-
    { "ieee754_from_blob", 1,   0, ieee754func_from_blob },
-

-
  };
-
  unsigned int i;
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
  (void)pzErrMsg;  /* Unused parameter */
-
  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
-
    rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg,
-
                               SQLITE_UTF8|SQLITE_INNOCUOUS,
-
                               (void*)&aFunc[i].iAux,
-
                               aFunc[i].xFunc, 0, 0);
+
  rc = sqlite3_create_function(db, "readfile", 1, 
+
                               SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
+
                               readfileFunc, 0, 0);
+
  if( rc==SQLITE_OK ){
+
    rc = sqlite3_create_function(db, "writefile", -1,
+
                                 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
+
                                 writefileFunc, 0, 0);
+
  }
+
  if( rc==SQLITE_OK ){
+
    rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
+
                                 lsModeFunc, 0, 0);
+
  }
+
  if( rc==SQLITE_OK ){
+
    rc = fsdirRegister(db);
  }
  return rc;
}

-
/************************* End ../ext/misc/ieee754.c ********************/
-
/************************* Begin ../ext/misc/series.c ******************/
+
#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
+
/* To allow a standalone DLL, make test_windirent.c use the same
+
 * redefined SQLite API calls as the above extension code does.
+
 * Just pull in this .c to accomplish this. As a beneficial side
+
 * effect, this extension becomes a single translation unit. */
+
#  include "test_windirent.c"
+
#endif
+

+
/************************* End ../ext/misc/fileio.c ********************/
+
/************************* Begin ../ext/misc/completion.c ******************/
/*
-
** 2015-08-18
+
** 2017-07-10
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
@@ -5473,203 +5544,327 @@ int sqlite3_ieee_init(
**
*************************************************************************
**
-
** This file demonstrates how to create a table-valued-function using
-
** a virtual table.  This demo implements the generate_series() function
-
** which gives similar results to the eponymous function in PostgreSQL.
-
** Examples:
-
**
-
**      SELECT * FROM generate_series(0,100,5);
-
**
-
** The query above returns integers from 0 through 100 counting by steps
-
** of 5.
-
**
-
**      SELECT * FROM generate_series(0,100);
-
**
-
** Integers from 0 through 100 with a step size of 1.
-
**
-
**      SELECT * FROM generate_series(20) LIMIT 10;
-
**
-
** Integers 20 through 29.
-
**
-
** HOW IT WORKS
-
**
-
** The generate_series "function" is really a virtual table with the
-
** following schema:
-
**
-
**     CREATE TABLE generate_series(
-
**       value,
-
**       start HIDDEN,
-
**       stop HIDDEN,
-
**       step HIDDEN
-
**     );
+
** This file implements an eponymous virtual table that returns suggested
+
** completions for a partial SQL input.
**
-
** Function arguments in queries against this virtual table are translated
-
** into equality constraints against successive hidden columns.  In other
-
** words, the following pairs of queries are equivalent to each other:
+
** Suggested usage:
**
-
**    SELECT * FROM generate_series(0,100,5);
-
**    SELECT * FROM generate_series WHERE start=0 AND stop=100 AND step=5;
+
**     SELECT DISTINCT candidate COLLATE nocase
+
**       FROM completion($prefix,$wholeline)
+
**      ORDER BY 1;
**
-
**    SELECT * FROM generate_series(0,100);
-
**    SELECT * FROM generate_series WHERE start=0 AND stop=100;
+
** The two query parameters are optional.  $prefix is the text of the
+
** current word being typed and that is to be completed.  $wholeline is
+
** the complete input line, used for context.
**
-
**    SELECT * FROM generate_series(20) LIMIT 10;
-
**    SELECT * FROM generate_series WHERE start=20 LIMIT 10;
+
** The raw completion() table might return the same candidate multiple
+
** times, for example if the same column name is used to two or more
+
** tables.  And the candidates are returned in an arbitrary order.  Hence,
+
** the DISTINCT and ORDER BY are recommended.
**
-
** The generate_series virtual table implementation leaves the xCreate method
-
** set to NULL.  This means that it is not possible to do a CREATE VIRTUAL
-
** TABLE command with "generate_series" as the USING argument.  Instead, there
-
** is a single generate_series virtual table that is always available without
-
** having to be created first.
+
** This virtual table operates at the speed of human typing, and so there
+
** is no attempt to make it fast.  Even a slow implementation will be much
+
** faster than any human can type.
**
-
** The xBestIndex method looks for equality constraints against the hidden
-
** start, stop, and step columns, and if present, it uses those constraints
-
** to bound the sequence of generated values.  If the equality constraints
-
** are missing, it uses 0 for start, 4294967295 for stop, and 1 for step.
-
** xBestIndex returns a small cost when both start and stop are available,
-
** and a very large cost if either start or stop are unavailable.  This
-
** encourages the query planner to order joins such that the bounds of the
-
** series are well-defined.
*/
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
+
#include <ctype.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE

+
/* completion_vtab is a subclass of sqlite3_vtab which will
+
** serve as the underlying representation of a completion virtual table
+
*/
+
typedef struct completion_vtab completion_vtab;
+
struct completion_vtab {
+
  sqlite3_vtab base;  /* Base class - must be first */
+
  sqlite3 *db;        /* Database connection for this completion vtab */
+
};

-
/* series_cursor is a subclass of sqlite3_vtab_cursor which will
+
/* completion_cursor is a subclass of sqlite3_vtab_cursor which will
** serve as the underlying representation of a cursor that scans
** over rows of the result
*/
-
typedef struct series_cursor series_cursor;
-
struct series_cursor {
+
typedef struct completion_cursor completion_cursor;
+
struct completion_cursor {
  sqlite3_vtab_cursor base;  /* Base class - must be first */
-
  int isDesc;                /* True to count down rather than up */
+
  sqlite3 *db;               /* Database connection for this cursor */
+
  int nPrefix, nLine;        /* Number of bytes in zPrefix and zLine */
+
  char *zPrefix;             /* The prefix for the word we want to complete */
+
  char *zLine;               /* The whole that we want to complete */
+
  const char *zCurrentRow;   /* Current output row */
+
  int szRow;                 /* Length of the zCurrentRow string */
+
  sqlite3_stmt *pStmt;       /* Current statement */
  sqlite3_int64 iRowid;      /* The rowid */
-
  sqlite3_int64 iValue;      /* Current value ("value") */
-
  sqlite3_int64 mnValue;     /* Mimimum value ("start") */
-
  sqlite3_int64 mxValue;     /* Maximum value ("stop") */
-
  sqlite3_int64 iStep;       /* Increment ("step") */
+
  int ePhase;                /* Current phase */
+
  int j;                     /* inter-phase counter */
};

+
/* Values for ePhase:
+
*/
+
#define COMPLETION_FIRST_PHASE   1
+
#define COMPLETION_KEYWORDS      1
+
#define COMPLETION_PRAGMAS       2
+
#define COMPLETION_FUNCTIONS     3
+
#define COMPLETION_COLLATIONS    4
+
#define COMPLETION_INDEXES       5
+
#define COMPLETION_TRIGGERS      6
+
#define COMPLETION_DATABASES     7
+
#define COMPLETION_TABLES        8    /* Also VIEWs and TRIGGERs */
+
#define COMPLETION_COLUMNS       9
+
#define COMPLETION_MODULES       10
+
#define COMPLETION_EOF           11
+

/*
-
** The seriesConnect() method is invoked to create a new
-
** series_vtab that describes the generate_series virtual table.
+
** The completionConnect() method is invoked to create a new
+
** completion_vtab that describes the completion virtual table.
**
-
** Think of this routine as the constructor for series_vtab objects.
+
** Think of this routine as the constructor for completion_vtab objects.
**
** All this routine needs to do is:
**
-
**    (1) Allocate the series_vtab object and initialize all fields.
+
**    (1) Allocate the completion_vtab object and initialize all fields.
**
**    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
-
**        result set of queries against generate_series will look like.
+
**        result set of queries against completion will look like.
*/
-
static int seriesConnect(
+
static int completionConnect(
  sqlite3 *db,
-
  void *pUnused,
-
  int argcUnused, const char *const*argvUnused,
+
  void *pAux,
+
  int argc, const char *const*argv,
  sqlite3_vtab **ppVtab,
-
  char **pzErrUnused
+
  char **pzErr
){
-
  sqlite3_vtab *pNew;
+
  completion_vtab *pNew;
  int rc;

+
  (void)(pAux);    /* Unused parameter */
+
  (void)(argc);    /* Unused parameter */
+
  (void)(argv);    /* Unused parameter */
+
  (void)(pzErr);   /* Unused parameter */
+

/* Column numbers */
-
#define SERIES_COLUMN_VALUE 0
-
#define SERIES_COLUMN_START 1
-
#define SERIES_COLUMN_STOP  2
-
#define SERIES_COLUMN_STEP  3
+
#define COMPLETION_COLUMN_CANDIDATE 0  /* Suggested completion of the input */
+
#define COMPLETION_COLUMN_PREFIX    1  /* Prefix of the word to be completed */
+
#define COMPLETION_COLUMN_WHOLELINE 2  /* Entire line seen so far */
+
#define COMPLETION_COLUMN_PHASE     3  /* ePhase - used for debugging only */

-
  (void)pUnused;
-
  (void)argcUnused;
-
  (void)argvUnused;
-
  (void)pzErrUnused;
+
  sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
  rc = sqlite3_declare_vtab(db,
-
     "CREATE TABLE x(value,start hidden,stop hidden,step hidden)");
+
      "CREATE TABLE x("
+
      "  candidate TEXT,"
+
      "  prefix TEXT HIDDEN,"
+
      "  wholeline TEXT HIDDEN,"
+
      "  phase INT HIDDEN"        /* Used for debugging only */
+
      ")");
  if( rc==SQLITE_OK ){
-
    pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
+
    pNew = sqlite3_malloc( sizeof(*pNew) );
+
    *ppVtab = (sqlite3_vtab*)pNew;
    if( pNew==0 ) return SQLITE_NOMEM;
    memset(pNew, 0, sizeof(*pNew));
-
    sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
+
    pNew->db = db;
  }
  return rc;
}

/*
-
** This method is the destructor for series_cursor objects.
+
** This method is the destructor for completion_cursor objects.
*/
-
static int seriesDisconnect(sqlite3_vtab *pVtab){
+
static int completionDisconnect(sqlite3_vtab *pVtab){
  sqlite3_free(pVtab);
  return SQLITE_OK;
}

/*
-
** Constructor for a new series_cursor object.
+
** Constructor for a new completion_cursor object.
*/
-
static int seriesOpen(sqlite3_vtab *pUnused, sqlite3_vtab_cursor **ppCursor){
-
  series_cursor *pCur;
-
  (void)pUnused;
+
static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
+
  completion_cursor *pCur;
  pCur = sqlite3_malloc( sizeof(*pCur) );
  if( pCur==0 ) return SQLITE_NOMEM;
  memset(pCur, 0, sizeof(*pCur));
+
  pCur->db = ((completion_vtab*)p)->db;
  *ppCursor = &pCur->base;
  return SQLITE_OK;
}

/*
-
** Destructor for a series_cursor.
+
** Reset the completion_cursor.
*/
-
static int seriesClose(sqlite3_vtab_cursor *cur){
+
static void completionCursorReset(completion_cursor *pCur){
+
  sqlite3_free(pCur->zPrefix);   pCur->zPrefix = 0;  pCur->nPrefix = 0;
+
  sqlite3_free(pCur->zLine);     pCur->zLine = 0;    pCur->nLine = 0;
+
  sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
+
  pCur->j = 0;
+
}
+

+
/*
+
** Destructor for a completion_cursor.
+
*/
+
static int completionClose(sqlite3_vtab_cursor *cur){
+
  completionCursorReset((completion_cursor*)cur);
  sqlite3_free(cur);
  return SQLITE_OK;
}

-

/*
-
** Advance a series_cursor to its next row of output.
+
** Advance a completion_cursor to its next row of output.
+
**
+
** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
+
** record the current state of the scan.  This routine sets ->zCurrentRow
+
** to the current row of output and then returns.  If no more rows remain,
+
** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
+
** table that has reached the end of its scan.
+
**
+
** The current implementation just lists potential identifiers and
+
** keywords and filters them by zPrefix.  Future enhancements should
+
** take zLine into account to try to restrict the set of identifiers and
+
** keywords based on what would be legal at the current point of input.
*/
-
static int seriesNext(sqlite3_vtab_cursor *cur){
-
  series_cursor *pCur = (series_cursor*)cur;
-
  if( pCur->isDesc ){
-
    pCur->iValue -= pCur->iStep;
-
  }else{
-
    pCur->iValue += pCur->iStep;
-
  }
+
static int completionNext(sqlite3_vtab_cursor *cur){
+
  completion_cursor *pCur = (completion_cursor*)cur;
+
  int eNextPhase = 0;  /* Next phase to try if current phase reaches end */
+
  int iCol = -1;       /* If >=0, step pCur->pStmt and use the i-th column */
  pCur->iRowid++;
+
  while( pCur->ePhase!=COMPLETION_EOF ){
+
    switch( pCur->ePhase ){
+
      case COMPLETION_KEYWORDS: {
+
        if( pCur->j >= sqlite3_keyword_count() ){
+
          pCur->zCurrentRow = 0;
+
          pCur->ePhase = COMPLETION_DATABASES;
+
        }else{
+
          sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
+
        }
+
        iCol = -1;
+
        break;
+
      }
+
      case COMPLETION_DATABASES: {
+
        if( pCur->pStmt==0 ){
+
          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
+
                             &pCur->pStmt, 0);
+
        }
+
        iCol = 1;
+
        eNextPhase = COMPLETION_TABLES;
+
        break;
+
      }
+
      case COMPLETION_TABLES: {
+
        if( pCur->pStmt==0 ){
+
          sqlite3_stmt *pS2;
+
          char *zSql = 0;
+
          const char *zSep = "";
+
          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
+
          while( sqlite3_step(pS2)==SQLITE_ROW ){
+
            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
+
            zSql = sqlite3_mprintf(
+
               "%z%s"
+
               "SELECT name FROM \"%w\".sqlite_schema",
+
               zSql, zSep, zDb
+
            );
+
            if( zSql==0 ) return SQLITE_NOMEM;
+
            zSep = " UNION ";
+
          }
+
          sqlite3_finalize(pS2);
+
          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
+
          sqlite3_free(zSql);
+
        }
+
        iCol = 0;
+
        eNextPhase = COMPLETION_COLUMNS;
+
        break;
+
      }
+
      case COMPLETION_COLUMNS: {
+
        if( pCur->pStmt==0 ){
+
          sqlite3_stmt *pS2;
+
          char *zSql = 0;
+
          const char *zSep = "";
+
          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
+
          while( sqlite3_step(pS2)==SQLITE_ROW ){
+
            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
+
            zSql = sqlite3_mprintf(
+
               "%z%s"
+
               "SELECT pti.name FROM \"%w\".sqlite_schema AS sm"
+
                       " JOIN pragma_table_info(sm.name,%Q) AS pti"
+
               " WHERE sm.type='table'",
+
               zSql, zSep, zDb, zDb
+
            );
+
            if( zSql==0 ) return SQLITE_NOMEM;
+
            zSep = " UNION ";
+
          }
+
          sqlite3_finalize(pS2);
+
          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
+
          sqlite3_free(zSql);
+
        }
+
        iCol = 0;
+
        eNextPhase = COMPLETION_EOF;
+
        break;
+
      }
+
    }
+
    if( iCol<0 ){
+
      /* This case is when the phase presets zCurrentRow */
+
      if( pCur->zCurrentRow==0 ) continue;
+
    }else{
+
      if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
+
        /* Extract the next row of content */
+
        pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
+
        pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
+
      }else{
+
        /* When all rows are finished, advance to the next phase */
+
        sqlite3_finalize(pCur->pStmt);
+
        pCur->pStmt = 0;
+
        pCur->ePhase = eNextPhase;
+
        continue;
+
      }
+
    }
+
    if( pCur->nPrefix==0 ) break;
+
    if( pCur->nPrefix<=pCur->szRow
+
     && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
+
    ){
+
      break;
+
    }
+
  }
+

  return SQLITE_OK;
}

/*
-
** Return values of columns for the row at which the series_cursor
+
** Return values of columns for the row at which the completion_cursor
** is currently pointing.
*/
-
static int seriesColumn(
+
static int completionColumn(
  sqlite3_vtab_cursor *cur,   /* The cursor */
  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
  int i                       /* Which column to return */
){
-
  series_cursor *pCur = (series_cursor*)cur;
-
  sqlite3_int64 x = 0;
+
  completion_cursor *pCur = (completion_cursor*)cur;
  switch( i ){
-
    case SERIES_COLUMN_START:  x = pCur->mnValue; break;
-
    case SERIES_COLUMN_STOP:   x = pCur->mxValue; break;
-
    case SERIES_COLUMN_STEP:   x = pCur->iStep;   break;
-
    default:                   x = pCur->iValue;  break;
+
    case COMPLETION_COLUMN_CANDIDATE: {
+
      sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
+
      break;
+
    }
+
    case COMPLETION_COLUMN_PREFIX: {
+
      sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
+
      break;
+
    }
+
    case COMPLETION_COLUMN_WHOLELINE: {
+
      sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
+
      break;
+
    }
+
    case COMPLETION_COLUMN_PHASE: {
+
      sqlite3_result_int(ctx, pCur->ePhase);
+
      break;
+
    }
  }
-
  sqlite3_result_int64(ctx, x);
  return SQLITE_OK;
}

/*
-
** Return the rowid for the current row. In this implementation, the
-
** first row returned is assigned rowid value 1, and each subsequent
-
** row a value 1 more than that of the previous.
+
** Return the rowid for the current row.  In this implementation, the
+
** rowid is the same as the output value.
*/
-
static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
-
  series_cursor *pCur = (series_cursor*)cur;
+
static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
+
  completion_cursor *pCur = (completion_cursor*)cur;
  *pRowid = pCur->iRowid;
  return SQLITE_OK;
}
@@ -5678,213 +5873,127 @@ static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
-
static int seriesEof(sqlite3_vtab_cursor *cur){
-
  series_cursor *pCur = (series_cursor*)cur;
-
  if( pCur->isDesc ){
-
    return pCur->iValue < pCur->mnValue;
-
  }else{
-
    return pCur->iValue > pCur->mxValue;
-
  }
+
static int completionEof(sqlite3_vtab_cursor *cur){
+
  completion_cursor *pCur = (completion_cursor*)cur;
+
  return pCur->ePhase >= COMPLETION_EOF;
}

-
/* True to cause run-time checking of the start=, stop=, and/or step= 
-
** parameters.  The only reason to do this is for testing the
-
** constraint checking logic for virtual tables in the SQLite core.
-
*/
-
#ifndef SQLITE_SERIES_CONSTRAINT_VERIFY
-
# define SQLITE_SERIES_CONSTRAINT_VERIFY 0
-
#endif
-

/*
-
** This method is called to "rewind" the series_cursor object back
+
** This method is called to "rewind" the completion_cursor object back
** to the first row of output.  This method is always called at least
-
** once prior to any call to seriesColumn() or seriesRowid() or 
-
** seriesEof().
-
**
-
** The query plan selected by seriesBestIndex is passed in the idxNum
-
** parameter.  (idxStr is not used in this implementation.)  idxNum
-
** is a bitmask showing which constraints are available:
-
**
-
**    1:    start=VALUE
-
**    2:    stop=VALUE
-
**    4:    step=VALUE
-
**
-
** Also, if bit 8 is set, that means that the series should be output
-
** in descending order rather than in ascending order.  If bit 16 is
-
** set, then output must appear in ascending order.
-
**
-
** This routine should initialize the cursor and position it so that it
-
** is pointing at the first row, or pointing off the end of the table
-
** (so that seriesEof() will return true) if the table is empty.
+
** once prior to any call to completionColumn() or completionRowid() or 
+
** completionEof().
*/
-
static int seriesFilter(
+
static int completionFilter(
  sqlite3_vtab_cursor *pVtabCursor, 
-
  int idxNum, const char *idxStrUnused,
+
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
-
  series_cursor *pCur = (series_cursor *)pVtabCursor;
-
  int i = 0;
-
  (void)idxStrUnused;
+
  completion_cursor *pCur = (completion_cursor *)pVtabCursor;
+
  int iArg = 0;
+
  (void)(idxStr);   /* Unused parameter */
+
  (void)(argc);     /* Unused parameter */
+
  completionCursorReset(pCur);
  if( idxNum & 1 ){
-
    pCur->mnValue = sqlite3_value_int64(argv[i++]);
-
  }else{
-
    pCur->mnValue = 0;
+
    pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
+
    if( pCur->nPrefix>0 ){
+
      pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
+
      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
+
    }
+
    iArg = 1;
  }
  if( idxNum & 2 ){
-
    pCur->mxValue = sqlite3_value_int64(argv[i++]);
-
  }else{
-
    pCur->mxValue = 0xffffffff;
-
  }
-
  if( idxNum & 4 ){
-
    pCur->iStep = sqlite3_value_int64(argv[i++]);
-
    if( pCur->iStep==0 ){
-
      pCur->iStep = 1;
-
    }else if( pCur->iStep<0 ){
-
      pCur->iStep = -pCur->iStep;
-
      if( (idxNum & 16)==0 ) idxNum |= 8;
+
    pCur->nLine = sqlite3_value_bytes(argv[iArg]);
+
    if( pCur->nLine>0 ){
+
      pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
+
      if( pCur->zLine==0 ) return SQLITE_NOMEM;
    }
-
  }else{
-
    pCur->iStep = 1;
  }
-
  for(i=0; i<argc; i++){
-
    if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
-
      /* If any of the constraints have a NULL value, then return no rows.
-
      ** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
-
      pCur->mnValue = 1;
-
      pCur->mxValue = 0;
-
      break;
+
  if( pCur->zLine!=0 && pCur->zPrefix==0 ){
+
    int i = pCur->nLine;
+
    while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
+
      i--;
    }
-
  }
-
  if( idxNum & 8 ){
-
    pCur->isDesc = 1;
-
    pCur->iValue = pCur->mxValue;
-
    if( pCur->iStep>0 ){
-
      pCur->iValue -= (pCur->mxValue - pCur->mnValue)%pCur->iStep;
+
    pCur->nPrefix = pCur->nLine - i;
+
    if( pCur->nPrefix>0 ){
+
      pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
+
      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
    }
-
  }else{
-
    pCur->isDesc = 0;
-
    pCur->iValue = pCur->mnValue;
  }
-
  pCur->iRowid = 1;
-
  return SQLITE_OK;
+
  pCur->iRowid = 0;
+
  pCur->ePhase = COMPLETION_FIRST_PHASE;
+
  return completionNext(pVtabCursor);
}

/*
** SQLite will invoke this method one or more times while planning a query
-
** that uses the generate_series virtual table.  This routine needs to create
+
** that uses the completion virtual table.  This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
**
-
** In this implementation idxNum is used to represent the
-
** query plan.  idxStr is unused.
-
**
-
** The query plan is represented by bits in idxNum:
-
**
-
**  (1)  start = $value  -- constraint exists
-
**  (2)  stop = $value   -- constraint exists
-
**  (4)  step = $value   -- constraint exists
-
**  (8)  output in descending order
+
** There are two hidden parameters that act as arguments to the table-valued
+
** function:  "prefix" and "wholeline".  Bit 0 of idxNum is set if "prefix"
+
** is available and bit 1 is set if "wholeline" is available.
*/
-
static int seriesBestIndex(
-
  sqlite3_vtab *pVTab,
+
static int completionBestIndex(
+
  sqlite3_vtab *tab,
  sqlite3_index_info *pIdxInfo
){
-
  int i, j;              /* Loop over constraints */
+
  int i;                 /* Loop over constraints */
  int idxNum = 0;        /* The query plan bitmask */
-
  int bStartSeen = 0;    /* EQ constraint seen on the START column */
-
  int unusableMask = 0;  /* Mask of unusable constraints */
-
  int nArg = 0;          /* Number of arguments that seriesFilter() expects */
-
  int aIdx[3];           /* Constraints on start, stop, and step */
+
  int prefixIdx = -1;    /* Index of the start= constraint, or -1 if none */
+
  int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
+
  int nArg = 0;          /* Number of arguments that completeFilter() expects */
  const struct sqlite3_index_constraint *pConstraint;

-
  /* This implementation assumes that the start, stop, and step columns
-
  ** are the last three columns in the virtual table. */
-
  assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
-
  assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );
-

-
  aIdx[0] = aIdx[1] = aIdx[2] = -1;
+
  (void)(tab);    /* Unused parameter */
  pConstraint = pIdxInfo->aConstraint;
  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
-
    int iCol;    /* 0 for start, 1 for stop, 2 for step */
-
    int iMask;   /* bitmask for those column */
-
    if( pConstraint->iColumn<SERIES_COLUMN_START ) continue;
-
    iCol = pConstraint->iColumn - SERIES_COLUMN_START;
-
    assert( iCol>=0 && iCol<=2 );
-
    iMask = 1 << iCol;
-
    if( iCol==0 ) bStartSeen = 1;
-
    if( pConstraint->usable==0 ){
-
      unusableMask |=  iMask;
-
      continue;
-
    }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
-
      idxNum |= iMask;
-
      aIdx[iCol] = i;
-
    }
-
  }
-
  for(i=0; i<3; i++){
-
    if( (j = aIdx[i])>=0 ){
-
      pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
-
      pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
+
    if( pConstraint->usable==0 ) continue;
+
    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
+
    switch( pConstraint->iColumn ){
+
      case COMPLETION_COLUMN_PREFIX:
+
        prefixIdx = i;
+
        idxNum |= 1;
+
        break;
+
      case COMPLETION_COLUMN_WHOLELINE:
+
        wholelineIdx = i;
+
        idxNum |= 2;
+
        break;
    }
  }
-
  /* The current generate_column() implementation requires at least one
-
  ** argument (the START value).  Legacy versions assumed START=0 if the
-
  ** first argument was omitted.  Compile with -DZERO_ARGUMENT_GENERATE_SERIES
-
  ** to obtain the legacy behavior */
-
#ifndef ZERO_ARGUMENT_GENERATE_SERIES
-
  if( !bStartSeen ){
-
    sqlite3_free(pVTab->zErrMsg);
-
    pVTab->zErrMsg = sqlite3_mprintf(
-
        "first argument to \"generate_series()\" missing or unusable");
-
    return SQLITE_ERROR;
-
  }
-
#endif
-
  if( (unusableMask & ~idxNum)!=0 ){
-
    /* The start, stop, and step columns are inputs.  Therefore if there
-
    ** are unusable constraints on any of start, stop, or step then
-
    ** this plan is unusable */
-
    return SQLITE_CONSTRAINT;
+
  if( prefixIdx>=0 ){
+
    pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
+
    pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
  }
-
  if( (idxNum & 3)==3 ){
-
    /* Both start= and stop= boundaries are available.  This is the 
-
    ** the preferred case */
-
    pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0));
-
    pIdxInfo->estimatedRows = 1000;
-
    if( pIdxInfo->nOrderBy>=1 && pIdxInfo->aOrderBy[0].iColumn==0 ){
-
      if( pIdxInfo->aOrderBy[0].desc ){
-
        idxNum |= 8;
-
      }else{
-
        idxNum |= 16;
-
      }
-
      pIdxInfo->orderByConsumed = 1;
-
    }
-
  }else{
-
    /* If either boundary is missing, we have to generate a huge span
-
    ** of numbers.  Make this case very expensive so that the query
-
    ** planner will work hard to avoid it. */
-
    pIdxInfo->estimatedRows = 2147483647;
+
  if( wholelineIdx>=0 ){
+
    pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
+
    pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
  }
  pIdxInfo->idxNum = idxNum;
+
  pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
+
  pIdxInfo->estimatedRows = 500 - 100*nArg;
  return SQLITE_OK;
}

/*
** This following structure defines all the methods for the 
-
** generate_series virtual table.
+
** completion virtual table.
*/
-
static sqlite3_module seriesModule = {
+
static sqlite3_module completionModule = {
  0,                         /* iVersion */
  0,                         /* xCreate */
-
  seriesConnect,             /* xConnect */
-
  seriesBestIndex,           /* xBestIndex */
-
  seriesDisconnect,          /* xDisconnect */
+
  completionConnect,         /* xConnect */
+
  completionBestIndex,       /* xBestIndex */
+
  completionDisconnect,      /* xDisconnect */
  0,                         /* xDestroy */
-
  seriesOpen,                /* xOpen - open a cursor */
-
  seriesClose,               /* xClose - close a cursor */
-
  seriesFilter,              /* xFilter - configure scan constraints */
-
  seriesNext,                /* xNext - advance a cursor */
-
  seriesEof,                 /* xEof - check for end of scan */
-
  seriesColumn,              /* xColumn - read data */
-
  seriesRowid,               /* xRowid - read data */
+
  completionOpen,            /* xOpen - open a cursor */
+
  completionClose,           /* xClose - close a cursor */
+
  completionFilter,          /* xFilter - configure scan constraints */
+
  completionNext,            /* xNext - advance a cursor */
+
  completionEof,             /* xEof - check for end of scan */
+
  completionColumn,          /* xColumn - read data */
+
  completionRowid,           /* xRowid - read data */
  0,                         /* xUpdate */
  0,                         /* xBegin */
  0,                         /* xSync */
@@ -5900,31 +6009,35 @@ static sqlite3_module seriesModule = {

#endif /* SQLITE_OMIT_VIRTUALTABLE */

+
int sqlite3CompletionVtabInit(sqlite3 *db){
+
  int rc = SQLITE_OK;
+
#ifndef SQLITE_OMIT_VIRTUALTABLE
+
  rc = sqlite3_create_module(db, "completion", &completionModule, 0);
+
#endif
+
  return rc;
+
}
+

#ifdef _WIN32

#endif
-
int sqlite3_series_init(
+
int sqlite3_completion_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
+
  (void)(pzErrMsg);  /* Unused parameter */
#ifndef SQLITE_OMIT_VIRTUALTABLE
-
  if( sqlite3_libversion_number()<3008012 && pzErrMsg!=0 ){
-
    *pzErrMsg = sqlite3_mprintf(
-
        "generate_series() requires SQLite 3.8.12 or later");
-
    return SQLITE_ERROR;
-
  }
-
  rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0);
+
  rc = sqlite3CompletionVtabInit(db);
#endif
  return rc;
}

-
/************************* End ../ext/misc/series.c ********************/
-
/************************* Begin ../ext/misc/regexp.c ******************/
+
/************************* End ../ext/misc/completion.c ********************/
+
/************************* Begin ../ext/misc/appendvfs.c ******************/
/*
-
** 2012-11-13
+
** 2017-10-20
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
@@ -5935,769 +6048,669 @@ int sqlite3_series_init(
**
******************************************************************************
**
-
** The code in this file implements a compact but reasonably
-
** efficient regular-expression matcher for posix extended regular
-
** expressions against UTF8 text.
+
** This file implements a VFS shim that allows an SQLite database to be
+
** appended onto the end of some other file, such as an executable.
**
-
** This file is an SQLite extension.  It registers a single function
-
** named "regexp(A,B)" where A is the regular expression and B is the
-
** string to be matched.  By registering this function, SQLite will also
-
** then implement the "B regexp A" operator.  Note that with the function
-
** the regular expression comes first, but with the operator it comes
-
** second.
+
** A special record must appear at the end of the file that identifies the
+
** file as an appended database and provides the offset to the first page
+
** of the exposed content. (Or, it is the length of the content prefix.)
+
** For best performance page 1 should be located at a disk page boundary,
+
** though that is not required.
**
-
**  The following regular expression syntax is supported:
+
** When opening a database using this VFS, the connection might treat
+
** the file as an ordinary SQLite database, or it might treat it as a
+
** database appended onto some other file.  The decision is made by
+
** applying the following rules in order:
**
-
**     X*      zero or more occurrences of X
-
**     X+      one or more occurrences of X
-
**     X?      zero or one occurrences of X
-
**     X{p,q}  between p and q occurrences of X
-
**     (X)     match X
-
**     X|Y     X or Y
-
**     ^X      X occurring at the beginning of the string
-
**     X$      X occurring at the end of the string
-
**     .       Match any single character
-
**     \c      Character c where c is one of \{}()[]|*+?.
-
**     \c      C-language escapes for c in afnrtv.  ex: \t or \n
-
**     \uXXXX  Where XXXX is exactly 4 hex digits, unicode value XXXX
-
**     \xXX    Where XX is exactly 2 hex digits, unicode value XX
-
**     [abc]   Any single character from the set abc
-
**     [^abc]  Any single character not in the set abc
-
**     [a-z]   Any single character in the range a-z
-
**     [^a-z]  Any single character not in the range a-z
-
**     \b      Word boundary
-
**     \w      Word character.  [A-Za-z0-9_]
-
**     \W      Non-word character
-
**     \d      Digit
-
**     \D      Non-digit
-
**     \s      Whitespace character
-
**     \S      Non-whitespace character
+
**  (1)  An empty file is an ordinary database.
**
-
** A nondeterministic finite automaton (NFA) is used for matching, so the
-
** performance is bounded by O(N*M) where N is the size of the regular
-
** expression and M is the size of the input string.  The matcher never
-
** exhibits exponential behavior.  Note that the X{p,q} operator expands
-
** to p copies of X following by q-p copies of X? and that the size of the
-
** regular expression in the O(N*M) performance bound is computed after
-
** this expansion.
-
*/
-
#include <string.h>
-
#include <stdlib.h>
+
**  (2)  If the file ends with the appendvfs trailer string
+
**       "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
+
**
+
**  (3)  If the file begins with the standard SQLite prefix string
+
**       "SQLite format 3", that file is an ordinary database.
+
**
+
**  (4)  If none of the above apply and the SQLITE_OPEN_CREATE flag is
+
**       set, then a new database is appended to the already existing file.
+
**
+
**  (5)  Otherwise, SQLITE_CANTOPEN is returned.
+
**
+
** To avoid unnecessary complications with the PENDING_BYTE, the size of
+
** the file containing the database is limited to 1GiB. (1073741824 bytes)
+
** This VFS will not read or write past the 1GiB mark.  This restriction
+
** might be lifted in future versions.  For now, if you need a larger
+
** database, then keep it in a separate file.
+
**
+
** If the file being opened is a plain database (not an appended one), then
+
** this shim is a pass-through into the default underlying VFS. (rule 3)
+
**/
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
+
#include <string.h>
+
#include <assert.h>

-
/*
-
** The following #defines change the names of some functions implemented in
-
** this file to prevent name collisions with C-library functions of the
-
** same name.
+
/* The append mark at the end of the database is:
+
**
+
**     Start-Of-SQLite3-NNNNNNNN
+
**     123456789 123456789 12345
+
**
+
** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
+
** the offset to page 1, and also the length of the prefix content.
*/
-
#define re_match   sqlite3re_match
-
#define re_compile sqlite3re_compile
-
#define re_free    sqlite3re_free
-

-
/* The end-of-input character */
-
#define RE_EOF            0    /* End of input */
+
#define APND_MARK_PREFIX     "Start-Of-SQLite3-"
+
#define APND_MARK_PREFIX_SZ  17
+
#define APND_MARK_FOS_SZ      8
+
#define APND_MARK_SIZE       (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ)

-
/* The NFA is implemented as sequence of opcodes taken from the following
-
** set.  Each opcode has a single integer argument.
+
/*
+
** Maximum size of the combined prefix + database + append-mark.  This
+
** must be less than 0x40000000 to avoid locking issues on Windows.
*/
-
#define RE_OP_MATCH       1    /* Match the one character in the argument */
-
#define RE_OP_ANY         2    /* Match any one character.  (Implements ".") */
-
#define RE_OP_ANYSTAR     3    /* Special optimized version of .* */
-
#define RE_OP_FORK        4    /* Continue to both next and opcode at iArg */
-
#define RE_OP_GOTO        5    /* Jump to opcode at iArg */
-
#define RE_OP_ACCEPT      6    /* Halt and indicate a successful match */
-
#define RE_OP_CC_INC      7    /* Beginning of a [...] character class */
-
#define RE_OP_CC_EXC      8    /* Beginning of a [^...] character class */
-
#define RE_OP_CC_VALUE    9    /* Single value in a character class */
-
#define RE_OP_CC_RANGE   10    /* Range of values in a character class */
-
#define RE_OP_WORD       11    /* Perl word character [A-Za-z0-9_] */
-
#define RE_OP_NOTWORD    12    /* Not a perl word character */
-
#define RE_OP_DIGIT      13    /* digit:  [0-9] */
-
#define RE_OP_NOTDIGIT   14    /* Not a digit */
-
#define RE_OP_SPACE      15    /* space:  [ \t\n\r\v\f] */
-
#define RE_OP_NOTSPACE   16    /* Not a digit */
-
#define RE_OP_BOUNDARY   17    /* Boundary between word and non-word */
+
#define APND_MAX_SIZE  (0x40000000)

-
/* Each opcode is a "state" in the NFA */
-
typedef unsigned short ReStateNumber;
+
/*
+
** Try to align the database to an even multiple of APND_ROUNDUP bytes.
+
*/
+
#ifndef APND_ROUNDUP
+
#define APND_ROUNDUP 4096
+
#endif
+
#define APND_ALIGN_MASK         ((sqlite3_int64)(APND_ROUNDUP-1))
+
#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK)

-
/* Because this is an NFA and not a DFA, multiple states can be active at
-
** once.  An instance of the following object records all active states in
-
** the NFA.  The implementation is optimized for the common case where the
-
** number of actives states is small.
+
/*
+
** Forward declaration of objects used by this utility
*/
-
typedef struct ReStateSet {
-
  unsigned nState;            /* Number of current states */
-
  ReStateNumber *aState;      /* Current states */
-
} ReStateSet;
+
typedef struct sqlite3_vfs ApndVfs;
+
typedef struct ApndFile ApndFile;

-
/* An input string read one character at a time.
+
/* Access to a lower-level VFS that (might) implement dynamic loading,
+
** access to randomness, etc.
*/
-
typedef struct ReInput ReInput;
-
struct ReInput {
-
  const unsigned char *z;  /* All text */
-
  int i;                   /* Next byte to read */
-
  int mx;                  /* EOF when i>=mx */
-
};
+
#define ORIGVFS(p)  ((sqlite3_vfs*)((p)->pAppData))
+
#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))

-
/* A compiled NFA (or an NFA that is in the process of being compiled) is
-
** an instance of the following object.
+
/* An open appendvfs file
+
**
+
** An instance of this structure describes the appended database file.
+
** A separate sqlite3_file object is always appended. The appended
+
** sqlite3_file object (which can be accessed using ORIGFILE()) describes
+
** the entire file, including the prefix, the database, and the
+
** append-mark.
+
**
+
** The structure of an AppendVFS database is like this:
+
**
+
**   +-------------+---------+----------+-------------+
+
**   | prefix-file | padding | database | append-mark |
+
**   +-------------+---------+----------+-------------+
+
**                           ^          ^
+
**                           |          |
+
**                         iPgOne      iMark
+
**
+
**
+
** "prefix file" -  file onto which the database has been appended.
+
** "padding"     -  zero or more bytes inserted so that "database"
+
**                  starts on an APND_ROUNDUP boundary
+
** "database"    -  The SQLite database file
+
** "append-mark" -  The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates
+
**                  the offset from the start of prefix-file to the start
+
**                  of "database".
+
**
+
** The size of the database is iMark - iPgOne.
+
**
+
** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value
+
** of iPgOne stored as a big-ending 64-bit integer.
+
**
+
** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE).
+
** Or, iMark is -1 to indicate that it has not yet been written.
*/
-
typedef struct ReCompiled ReCompiled;
-
struct ReCompiled {
-
  ReInput sIn;                /* Regular expression text */
-
  const char *zErr;           /* Error message to return */
-
  char *aOp;                  /* Operators for the virtual machine */
-
  int *aArg;                  /* Arguments to each operator */
-
  unsigned (*xNextChar)(ReInput*);  /* Next character function */
-
  unsigned char zInit[12];    /* Initial text to match */
-
  int nInit;                  /* Number of characters in zInit */
-
  unsigned nState;            /* Number of entries in aOp[] and aArg[] */
-
  unsigned nAlloc;            /* Slots allocated for aOp[] and aArg[] */
+
struct ApndFile {
+
  sqlite3_file base;        /* Subclass.  MUST BE FIRST! */
+
  sqlite3_int64 iPgOne;     /* Offset to the start of the database */
+
  sqlite3_int64 iMark;      /* Offset of the append mark.  -1 if unwritten */
+
  /* Always followed by another sqlite3_file that describes the whole file */
};

-
/* Add a state to the given state set if it is not already there */
-
static void re_add_state(ReStateSet *pSet, int newState){
-
  unsigned i;
-
  for(i=0; i<pSet->nState; i++) if( pSet->aState[i]==newState ) return;
-
  pSet->aState[pSet->nState++] = (ReStateNumber)newState;
-
}
-

-
/* Extract the next unicode character from *pzIn and return it.  Advance
-
** *pzIn to the first byte past the end of the character returned.  To
-
** be clear:  this routine converts utf8 to unicode.  This routine is 
-
** optimized for the common case where the next character is a single byte.
+
/*
+
** Methods for ApndFile
*/
-
static unsigned re_next_char(ReInput *p){
-
  unsigned c;
-
  if( p->i>=p->mx ) return 0;
-
  c = p->z[p->i++];
-
  if( c>=0x80 ){
-
    if( (c&0xe0)==0xc0 && p->i<p->mx && (p->z[p->i]&0xc0)==0x80 ){
-
      c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f);
-
      if( c<0x80 ) c = 0xfffd;
-
    }else if( (c&0xf0)==0xe0 && p->i+1<p->mx && (p->z[p->i]&0xc0)==0x80
-
           && (p->z[p->i+1]&0xc0)==0x80 ){
-
      c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
-
      p->i += 2;
-
      if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
-
    }else if( (c&0xf8)==0xf0 && p->i+3<p->mx && (p->z[p->i]&0xc0)==0x80
-
           && (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){
-
      c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6)
-
                       | (p->z[p->i+2]&0x3f);
-
      p->i += 3;
-
      if( c<=0xffff || c>0x10ffff ) c = 0xfffd;
-
    }else{
-
      c = 0xfffd;
-
    }
-
  }
-
  return c;
-
}
-
static unsigned re_next_char_nocase(ReInput *p){
-
  unsigned c = re_next_char(p);
-
  if( c>='A' && c<='Z' ) c += 'a' - 'A';
-
  return c;
-
}
-

-
/* Return true if c is a perl "word" character:  [A-Za-z0-9_] */
-
static int re_word_char(int c){
-
  return (c>='0' && c<='9') || (c>='a' && c<='z')
-
      || (c>='A' && c<='Z') || c=='_';
-
}
+
static int apndClose(sqlite3_file*);
+
static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
+
static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
+
static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
+
static int apndSync(sqlite3_file*, int flags);
+
static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
+
static int apndLock(sqlite3_file*, int);
+
static int apndUnlock(sqlite3_file*, int);
+
static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
+
static int apndFileControl(sqlite3_file*, int op, void *pArg);
+
static int apndSectorSize(sqlite3_file*);
+
static int apndDeviceCharacteristics(sqlite3_file*);
+
static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
+
static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
+
static void apndShmBarrier(sqlite3_file*);
+
static int apndShmUnmap(sqlite3_file*, int deleteFlag);
+
static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
+
static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);

-
/* Return true if c is a "digit" character:  [0-9] */
-
static int re_digit_char(int c){
-
  return (c>='0' && c<='9');
-
}
+
/*
+
** Methods for ApndVfs
+
*/
+
static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
+
static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
+
static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
+
static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
+
static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
+
static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
+
static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
+
static void apndDlClose(sqlite3_vfs*, void*);
+
static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
+
static int apndSleep(sqlite3_vfs*, int microseconds);
+
static int apndCurrentTime(sqlite3_vfs*, double*);
+
static int apndGetLastError(sqlite3_vfs*, int, char *);
+
static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
+
static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
+
static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
+
static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);

-
/* Return true if c is a perl "space" character:  [ \t\r\n\v\f] */
-
static int re_space_char(int c){
-
  return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f';
-
}
+
static sqlite3_vfs apnd_vfs = {
+
  3,                            /* iVersion (set when registered) */
+
  0,                            /* szOsFile (set when registered) */
+
  1024,                         /* mxPathname */
+
  0,                            /* pNext */
+
  "apndvfs",                    /* zName */
+
  0,                            /* pAppData (set when registered) */ 
+
  apndOpen,                     /* xOpen */
+
  apndDelete,                   /* xDelete */
+
  apndAccess,                   /* xAccess */
+
  apndFullPathname,             /* xFullPathname */
+
  apndDlOpen,                   /* xDlOpen */
+
  apndDlError,                  /* xDlError */
+
  apndDlSym,                    /* xDlSym */
+
  apndDlClose,                  /* xDlClose */
+
  apndRandomness,               /* xRandomness */
+
  apndSleep,                    /* xSleep */
+
  apndCurrentTime,              /* xCurrentTime */
+
  apndGetLastError,             /* xGetLastError */
+
  apndCurrentTimeInt64,         /* xCurrentTimeInt64 */
+
  apndSetSystemCall,            /* xSetSystemCall */
+
  apndGetSystemCall,            /* xGetSystemCall */
+
  apndNextSystemCall            /* xNextSystemCall */
+
};

-
/* Run a compiled regular expression on the zero-terminated input
-
** string zIn[].  Return true on a match and false if there is no match.
-
*/
-
static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
-
  ReStateSet aStateSet[2], *pThis, *pNext;
-
  ReStateNumber aSpace[100];
-
  ReStateNumber *pToFree;
-
  unsigned int i = 0;
-
  unsigned int iSwap = 0;
-
  int c = RE_EOF+1;
-
  int cPrev = 0;
-
  int rc = 0;
-
  ReInput in;
+
static const sqlite3_io_methods apnd_io_methods = {
+
  3,                              /* iVersion */
+
  apndClose,                      /* xClose */
+
  apndRead,                       /* xRead */
+
  apndWrite,                      /* xWrite */
+
  apndTruncate,                   /* xTruncate */
+
  apndSync,                       /* xSync */
+
  apndFileSize,                   /* xFileSize */
+
  apndLock,                       /* xLock */
+
  apndUnlock,                     /* xUnlock */
+
  apndCheckReservedLock,          /* xCheckReservedLock */
+
  apndFileControl,                /* xFileControl */
+
  apndSectorSize,                 /* xSectorSize */
+
  apndDeviceCharacteristics,      /* xDeviceCharacteristics */
+
  apndShmMap,                     /* xShmMap */
+
  apndShmLock,                    /* xShmLock */
+
  apndShmBarrier,                 /* xShmBarrier */
+
  apndShmUnmap,                   /* xShmUnmap */
+
  apndFetch,                      /* xFetch */
+
  apndUnfetch                     /* xUnfetch */
+
};

-
  in.z = zIn;
-
  in.i = 0;
-
  in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn);
+
/*
+
** Close an apnd-file.
+
*/
+
static int apndClose(sqlite3_file *pFile){
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xClose(pFile);
+
}

-
  /* Look for the initial prefix match, if there is one. */
-
  if( pRe->nInit ){
-
    unsigned char x = pRe->zInit[0];
-
    while( in.i+pRe->nInit<=in.mx 
-
     && (zIn[in.i]!=x ||
-
         strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
-
    ){
-
      in.i++;
-
    }
-
    if( in.i+pRe->nInit>in.mx ) return 0;
-
  }
+
/*
+
** Read data from an apnd-file.
+
*/
+
static int apndRead(
+
  sqlite3_file *pFile, 
+
  void *zBuf, 
+
  int iAmt, 
+
  sqlite_int64 iOfst
+
){
+
  ApndFile *paf = (ApndFile *)pFile;
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
+
}

-
  if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
-
    pToFree = 0;
-
    aStateSet[0].aState = aSpace;
-
  }else{
-
    pToFree = sqlite3_malloc64( sizeof(ReStateNumber)*2*pRe->nState );
-
    if( pToFree==0 ) return -1;
-
    aStateSet[0].aState = pToFree;
-
  }
-
  aStateSet[1].aState = &aStateSet[0].aState[pRe->nState];
-
  pNext = &aStateSet[1];
-
  pNext->nState = 0;
-
  re_add_state(pNext, 0);
-
  while( c!=RE_EOF && pNext->nState>0 ){
-
    cPrev = c;
-
    c = pRe->xNextChar(&in);
-
    pThis = pNext;
-
    pNext = &aStateSet[iSwap];
-
    iSwap = 1 - iSwap;
-
    pNext->nState = 0;
-
    for(i=0; i<pThis->nState; i++){
-
      int x = pThis->aState[i];
-
      switch( pRe->aOp[x] ){
-
        case RE_OP_MATCH: {
-
          if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
-
          break;
-
        }
-
        case RE_OP_ANY: {
-
          if( c!=0 ) re_add_state(pNext, x+1);
-
          break;
-
        }
-
        case RE_OP_WORD: {
-
          if( re_word_char(c) ) re_add_state(pNext, x+1);
-
          break;
-
        }
-
        case RE_OP_NOTWORD: {
-
          if( !re_word_char(c) && c!=0 ) re_add_state(pNext, x+1);
-
          break;
-
        }
-
        case RE_OP_DIGIT: {
-
          if( re_digit_char(c) ) re_add_state(pNext, x+1);
-
          break;
-
        }
-
        case RE_OP_NOTDIGIT: {
-
          if( !re_digit_char(c) && c!=0 ) re_add_state(pNext, x+1);
-
          break;
-
        }
-
        case RE_OP_SPACE: {
-
          if( re_space_char(c) ) re_add_state(pNext, x+1);
-
          break;
-
        }
-
        case RE_OP_NOTSPACE: {
-
          if( !re_space_char(c) && c!=0 ) re_add_state(pNext, x+1);
-
          break;
-
        }
-
        case RE_OP_BOUNDARY: {
-
          if( re_word_char(c)!=re_word_char(cPrev) ) re_add_state(pThis, x+1);
-
          break;
-
        }
-
        case RE_OP_ANYSTAR: {
-
          re_add_state(pNext, x);
-
          re_add_state(pThis, x+1);
-
          break;
-
        }
-
        case RE_OP_FORK: {
-
          re_add_state(pThis, x+pRe->aArg[x]);
-
          re_add_state(pThis, x+1);
-
          break;
-
        }
-
        case RE_OP_GOTO: {
-
          re_add_state(pThis, x+pRe->aArg[x]);
-
          break;
-
        }
-
        case RE_OP_ACCEPT: {
-
          rc = 1;
-
          goto re_match_end;
-
        }
-
        case RE_OP_CC_EXC: {
-
          if( c==0 ) break;
-
          /* fall-through */ goto re_op_cc_inc;
-
        }
-
        case RE_OP_CC_INC: re_op_cc_inc: {
-
          int j = 1;
-
          int n = pRe->aArg[x];
-
          int hit = 0;
-
          for(j=1; j>0 && j<n; j++){
-
            if( pRe->aOp[x+j]==RE_OP_CC_VALUE ){
-
              if( pRe->aArg[x+j]==c ){
-
                hit = 1;
-
                j = -1;
-
              }
-
            }else{
-
              if( pRe->aArg[x+j]<=c && pRe->aArg[x+j+1]>=c ){
-
                hit = 1;
-
                j = -1;
-
              }else{
-
                j++;
-
              }
-
            }
-
          }
-
          if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit;
-
          if( hit ) re_add_state(pNext, x+n);
-
          break;
-
        }
-
      }
-
    }
+
/*
+
** Add the append-mark onto what should become the end of the file.
+
*  If and only if this succeeds, internal ApndFile.iMark is updated.
+
*  Parameter iWriteEnd is the appendvfs-relative offset of the new mark.
+
*/
+
static int apndWriteMark(
+
  ApndFile *paf,
+
  sqlite3_file *pFile,
+
  sqlite_int64 iWriteEnd
+
){
+
  sqlite_int64 iPgOne = paf->iPgOne;
+
  unsigned char a[APND_MARK_SIZE];
+
  int i = APND_MARK_FOS_SZ;
+
  int rc;
+
  assert(pFile == ORIGFILE(paf));
+
  memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
+
  while( --i >= 0 ){
+
    a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
+
    iPgOne >>= 8;
  }
-
  for(i=0; i<pNext->nState; i++){
-
    if( pRe->aOp[pNext->aState[i]]==RE_OP_ACCEPT ){ rc = 1; break; }
+
  iWriteEnd += paf->iPgOne;
+
  if( SQLITE_OK==(rc = pFile->pMethods->xWrite
+
                  (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
+
    paf->iMark = iWriteEnd;
  }
-
re_match_end:
-
  sqlite3_free(pToFree);
  return rc;
}

-
/* Resize the opcode and argument arrays for an RE under construction.
+
/*
+
** Write data to an apnd-file.
*/
-
static int re_resize(ReCompiled *p, int N){
-
  char *aOp;
-
  int *aArg;
-
  aOp = sqlite3_realloc64(p->aOp, N*sizeof(p->aOp[0]));
-
  if( aOp==0 ) return 1;
-
  p->aOp = aOp;
-
  aArg = sqlite3_realloc64(p->aArg, N*sizeof(p->aArg[0]));
-
  if( aArg==0 ) return 1;
-
  p->aArg = aArg;
-
  p->nAlloc = N;
-
  return 0;
+
static int apndWrite(
+
  sqlite3_file *pFile,
+
  const void *zBuf,
+
  int iAmt,
+
  sqlite_int64 iOfst
+
){
+
  ApndFile *paf = (ApndFile *)pFile;
+
  sqlite_int64 iWriteEnd = iOfst + iAmt;
+
  if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
+
  pFile = ORIGFILE(pFile);
+
  /* If append-mark is absent or will be overwritten, write it. */
+
  if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
+
    int rc = apndWriteMark(paf, pFile, iWriteEnd);
+
    if( SQLITE_OK!=rc ) return rc;
+
  }
+
  return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
}

-
/* Insert a new opcode and argument into an RE under construction.  The
-
** insertion point is just prior to existing opcode iBefore.
+
/*
+
** Truncate an apnd-file.
*/
-
static int re_insert(ReCompiled *p, int iBefore, int op, int arg){
-
  int i;
-
  if( p->nAlloc<=p->nState && re_resize(p, p->nAlloc*2) ) return 0;
-
  for(i=p->nState; i>iBefore; i--){
-
    p->aOp[i] = p->aOp[i-1];
-
    p->aArg[i] = p->aArg[i-1];
-
  }
-
  p->nState++;
-
  p->aOp[iBefore] = (char)op;
-
  p->aArg[iBefore] = arg;
-
  return iBefore;
+
static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
+
  ApndFile *paf = (ApndFile *)pFile;
+
  pFile = ORIGFILE(pFile);
+
  /* The append mark goes out first so truncate failure does not lose it. */
+
  if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR;
+
  /* Truncate underlying file just past append mark */
+
  return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
}

-
/* Append a new opcode and argument to the end of the RE under construction.
+
/*
+
** Sync an apnd-file.
*/
-
static int re_append(ReCompiled *p, int op, int arg){
-
  return re_insert(p, p->nState, op, arg);
+
static int apndSync(sqlite3_file *pFile, int flags){
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xSync(pFile, flags);
}

-
/* Make a copy of N opcodes starting at iStart onto the end of the RE
-
** under construction.
+
/*
+
** Return the current file-size of an apnd-file.
+
** If the append mark is not yet there, the file-size is 0.
*/
-
static void re_copy(ReCompiled *p, int iStart, int N){
-
  if( p->nState+N>=p->nAlloc && re_resize(p, p->nAlloc*2+N) ) return;
-
  memcpy(&p->aOp[p->nState], &p->aOp[iStart], N*sizeof(p->aOp[0]));
-
  memcpy(&p->aArg[p->nState], &p->aArg[iStart], N*sizeof(p->aArg[0]));
-
  p->nState += N;
+
static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
+
  ApndFile *paf = (ApndFile *)pFile;
+
  *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;
+
  return SQLITE_OK;
+
}
+

+
/*
+
** Lock an apnd-file.
+
*/
+
static int apndLock(sqlite3_file *pFile, int eLock){
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xLock(pFile, eLock);
+
}
+

+
/*
+
** Unlock an apnd-file.
+
*/
+
static int apndUnlock(sqlite3_file *pFile, int eLock){
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xUnlock(pFile, eLock);
}

-
/* Return true if c is a hexadecimal digit character:  [0-9a-fA-F]
-
** If c is a hex digit, also set *pV = (*pV)*16 + valueof(c).  If
-
** c is not a hex digit *pV is unchanged.
+
/*
+
** Check if another file-handle holds a RESERVED lock on an apnd-file.
*/
-
static int re_hex(int c, int *pV){
-
  if( c>='0' && c<='9' ){
-
    c -= '0';
-
  }else if( c>='a' && c<='f' ){
-
    c -= 'a' - 10;
-
  }else if( c>='A' && c<='F' ){
-
    c -= 'A' - 10;
-
  }else{
-
    return 0;
-
  }
-
  *pV = (*pV)*16 + (c & 0xff);
-
  return 1;
+
static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
}

-
/* A backslash character has been seen, read the next character and
-
** return its interpretation.
+
/*
+
** File control method. For custom operations on an apnd-file.
*/
-
static unsigned re_esc_char(ReCompiled *p){
-
  static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]";
-
  static const char zTrans[] = "\a\f\n\r\t\v";
-
  int i, v = 0;
-
  char c;
-
  if( p->sIn.i>=p->sIn.mx ) return 0;
-
  c = p->sIn.z[p->sIn.i];
-
  if( c=='u' && p->sIn.i+4<p->sIn.mx ){
-
    const unsigned char *zIn = p->sIn.z + p->sIn.i;
-
    if( re_hex(zIn[1],&v)
-
     && re_hex(zIn[2],&v)
-
     && re_hex(zIn[3],&v)
-
     && re_hex(zIn[4],&v)
-
    ){
-
      p->sIn.i += 5;
-
      return v;
-
    }
-
  }
-
  if( c=='x' && p->sIn.i+2<p->sIn.mx ){
-
    const unsigned char *zIn = p->sIn.z + p->sIn.i;
-
    if( re_hex(zIn[1],&v)
-
     && re_hex(zIn[2],&v)
-
    ){
-
      p->sIn.i += 3;
-
      return v;
-
    }
-
  }
-
  for(i=0; zEsc[i] && zEsc[i]!=c; i++){}
-
  if( zEsc[i] ){
-
    if( i<6 ) c = zTrans[i];
-
    p->sIn.i++;
-
  }else{
-
    p->zErr = "unknown \\ escape";
+
static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
+
  ApndFile *paf = (ApndFile *)pFile;
+
  int rc;
+
  pFile = ORIGFILE(pFile);
+
  if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne;
+
  rc = pFile->pMethods->xFileControl(pFile, op, pArg);
+
  if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
+
    *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
  }
-
  return c;
+
  return rc;
}

-
/* Forward declaration */
-
static const char *re_subcompile_string(ReCompiled*);
-

-
/* Peek at the next byte of input */
-
static unsigned char rePeek(ReCompiled *p){
-
  return p->sIn.i<p->sIn.mx ? p->sIn.z[p->sIn.i] : 0;
+
/*
+
** Return the sector-size in bytes for an apnd-file.
+
*/
+
static int apndSectorSize(sqlite3_file *pFile){
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xSectorSize(pFile);
}

-
/* Compile RE text into a sequence of opcodes.  Continue up to the
-
** first unmatched ")" character, then return.  If an error is found,
-
** return a pointer to the error message string.
+
/*
+
** Return the device characteristic flags supported by an apnd-file.
*/
-
static const char *re_subcompile_re(ReCompiled *p){
-
  const char *zErr;
-
  int iStart, iEnd, iGoto;
-
  iStart = p->nState;
-
  zErr = re_subcompile_string(p);
-
  if( zErr ) return zErr;
-
  while( rePeek(p)=='|' ){
-
    iEnd = p->nState;
-
    re_insert(p, iStart, RE_OP_FORK, iEnd + 2 - iStart);
-
    iGoto = re_append(p, RE_OP_GOTO, 0);
-
    p->sIn.i++;
-
    zErr = re_subcompile_string(p);
-
    if( zErr ) return zErr;
-
    p->aArg[iGoto] = p->nState - iGoto;
-
  }
-
  return 0;
+
static int apndDeviceCharacteristics(sqlite3_file *pFile){
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xDeviceCharacteristics(pFile);
}

-
/* Compile an element of regular expression text (anything that can be
-
** an operand to the "|" operator).  Return NULL on success or a pointer
-
** to the error message if there is a problem.
-
*/
-
static const char *re_subcompile_string(ReCompiled *p){
-
  int iPrev = -1;
-
  int iStart;
-
  unsigned c;
-
  const char *zErr;
-
  while( (c = p->xNextChar(&p->sIn))!=0 ){
-
    iStart = p->nState;
-
    switch( c ){
-
      case '|':
-
      case '$':
-
      case ')': {
-
        p->sIn.i--;
-
        return 0;
-
      }
-
      case '(': {
-
        zErr = re_subcompile_re(p);
-
        if( zErr ) return zErr;
-
        if( rePeek(p)!=')' ) return "unmatched '('";
-
        p->sIn.i++;
-
        break;
-
      }
-
      case '.': {
-
        if( rePeek(p)=='*' ){
-
          re_append(p, RE_OP_ANYSTAR, 0);
-
          p->sIn.i++;
-
        }else{
-
          re_append(p, RE_OP_ANY, 0);
-
        }
-
        break;
-
      }
-
      case '*': {
-
        if( iPrev<0 ) return "'*' without operand";
-
        re_insert(p, iPrev, RE_OP_GOTO, p->nState - iPrev + 1);
-
        re_append(p, RE_OP_FORK, iPrev - p->nState + 1);
-
        break;
-
      }
-
      case '+': {
-
        if( iPrev<0 ) return "'+' without operand";
-
        re_append(p, RE_OP_FORK, iPrev - p->nState);
-
        break;
-
      }
-
      case '?': {
-
        if( iPrev<0 ) return "'?' without operand";
-
        re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
-
        break;
-
      }
-
      case '{': {
-
        int m = 0, n = 0;
-
        int sz, j;
-
        if( iPrev<0 ) return "'{m,n}' without operand";
-
        while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }
-
        n = m;
-
        if( c==',' ){
-
          p->sIn.i++;
-
          n = 0;
-
          while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }
-
        }
-
        if( c!='}' ) return "unmatched '{'";
-
        if( n>0 && n<m ) return "n less than m in '{m,n}'";
-
        p->sIn.i++;
-
        sz = p->nState - iPrev;
-
        if( m==0 ){
-
          if( n==0 ) return "both m and n are zero in '{m,n}'";
-
          re_insert(p, iPrev, RE_OP_FORK, sz+1);
-
          n--;
-
        }else{
-
          for(j=1; j<m; j++) re_copy(p, iPrev, sz);
-
        }
-
        for(j=m; j<n; j++){
-
          re_append(p, RE_OP_FORK, sz+1);
-
          re_copy(p, iPrev, sz);
-
        }
-
        if( n==0 && m>0 ){
-
          re_append(p, RE_OP_FORK, -sz);
-
        }
-
        break;
-
      }
-
      case '[': {
-
        int iFirst = p->nState;
-
        if( rePeek(p)=='^' ){
-
          re_append(p, RE_OP_CC_EXC, 0);
-
          p->sIn.i++;
-
        }else{
-
          re_append(p, RE_OP_CC_INC, 0);
-
        }
-
        while( (c = p->xNextChar(&p->sIn))!=0 ){
-
          if( c=='[' && rePeek(p)==':' ){
-
            return "POSIX character classes not supported";
-
          }
-
          if( c=='\\' ) c = re_esc_char(p);
-
          if( rePeek(p)=='-' ){
-
            re_append(p, RE_OP_CC_RANGE, c);
-
            p->sIn.i++;
-
            c = p->xNextChar(&p->sIn);
-
            if( c=='\\' ) c = re_esc_char(p);
-
            re_append(p, RE_OP_CC_RANGE, c);
-
          }else{
-
            re_append(p, RE_OP_CC_VALUE, c);
-
          }
-
          if( rePeek(p)==']' ){ p->sIn.i++; break; }
-
        }
-
        if( c==0 ) return "unclosed '['";
-
        p->aArg[iFirst] = p->nState - iFirst;
-
        break;
-
      }
-
      case '\\': {
-
        int specialOp = 0;
-
        switch( rePeek(p) ){
-
          case 'b': specialOp = RE_OP_BOUNDARY;   break;
-
          case 'd': specialOp = RE_OP_DIGIT;      break;
-
          case 'D': specialOp = RE_OP_NOTDIGIT;   break;
-
          case 's': specialOp = RE_OP_SPACE;      break;
-
          case 'S': specialOp = RE_OP_NOTSPACE;   break;
-
          case 'w': specialOp = RE_OP_WORD;       break;
-
          case 'W': specialOp = RE_OP_NOTWORD;    break;
-
        }
-
        if( specialOp ){
-
          p->sIn.i++;
-
          re_append(p, specialOp, 0);
-
        }else{
-
          c = re_esc_char(p);
-
          re_append(p, RE_OP_MATCH, c);
-
        }
-
        break;
-
      }
-
      default: {
-
        re_append(p, RE_OP_MATCH, c);
-
        break;
-
      }
-
    }
-
    iPrev = iStart;
-
  }
-
  return 0;
+
/* Create a shared memory file mapping */
+
static int apndShmMap(
+
  sqlite3_file *pFile,
+
  int iPg,
+
  int pgsz,
+
  int bExtend,
+
  void volatile **pp
+
){
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
+
}
+

+
/* Perform locking on a shared-memory segment */
+
static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xShmLock(pFile,offset,n,flags);
}

-
/* Free and reclaim all the memory used by a previously compiled
-
** regular expression.  Applications should invoke this routine once
-
** for every call to re_compile() to avoid memory leaks.
-
*/
-
static void re_free(ReCompiled *pRe){
-
  if( pRe ){
-
    sqlite3_free(pRe->aOp);
-
    sqlite3_free(pRe->aArg);
-
    sqlite3_free(pRe);
+
/* Memory barrier operation on shared memory */
+
static void apndShmBarrier(sqlite3_file *pFile){
+
  pFile = ORIGFILE(pFile);
+
  pFile->pMethods->xShmBarrier(pFile);
+
}
+

+
/* Unmap a shared memory segment */
+
static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
+
}
+

+
/* Fetch a page of a memory-mapped file */
+
static int apndFetch(
+
  sqlite3_file *pFile,
+
  sqlite3_int64 iOfst,
+
  int iAmt,
+
  void **pp
+
){
+
  ApndFile *p = (ApndFile *)pFile;
+
  if( p->iMark < 0 || iOfst+iAmt > p->iMark ){
+
    return SQLITE_IOERR; /* Cannot read what is not yet there. */
  }
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
+
}
+

+
/* Release a memory-mapped page */
+
static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
+
  ApndFile *p = (ApndFile *)pFile;
+
  pFile = ORIGFILE(pFile);
+
  return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
}

/*
-
** Compile a textual regular expression in zIn[] into a compiled regular
-
** expression suitable for us by re_match() and return a pointer to the
-
** compiled regular expression in *ppRe.  Return NULL on success or an
-
** error message if something goes wrong.
+
** Try to read the append-mark off the end of a file.  Return the
+
** start of the appended database if the append-mark is present.
+
** If there is no valid append-mark, return -1;
+
**
+
** An append-mark is only valid if the NNNNNNNN start-of-database offset
+
** indicates that the appended database contains at least one page.  The
+
** start-of-database value must be a multiple of 512.
*/
-
static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
-
  ReCompiled *pRe;
-
  const char *zErr;
-
  int i, j;
+
static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
+
  int rc, i;
+
  sqlite3_int64 iMark;
+
  int msbs = 8 * (APND_MARK_FOS_SZ-1);
+
  unsigned char a[APND_MARK_SIZE];

-
  *ppRe = 0;
-
  pRe = sqlite3_malloc( sizeof(*pRe) );
-
  if( pRe==0 ){
-
    return "out of memory";
-
  }
-
  memset(pRe, 0, sizeof(*pRe));
-
  pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char;
-
  if( re_resize(pRe, 30) ){
-
    re_free(pRe);
-
    return "out of memory";
-
  }
-
  if( zIn[0]=='^' ){
-
    zIn++;
-
  }else{
-
    re_append(pRe, RE_OP_ANYSTAR, 0);
-
  }
-
  pRe->sIn.z = (unsigned char*)zIn;
-
  pRe->sIn.i = 0;
-
  pRe->sIn.mx = (int)strlen(zIn);
-
  zErr = re_subcompile_re(pRe);
-
  if( zErr ){
-
    re_free(pRe);
-
    return zErr;
-
  }
-
  if( rePeek(pRe)=='$' && pRe->sIn.i+1>=pRe->sIn.mx ){
-
    re_append(pRe, RE_OP_MATCH, RE_EOF);
-
    re_append(pRe, RE_OP_ACCEPT, 0);
-
    *ppRe = pRe;
-
  }else if( pRe->sIn.i>=pRe->sIn.mx ){
-
    re_append(pRe, RE_OP_ACCEPT, 0);
-
    *ppRe = pRe;
-
  }else{
-
    re_free(pRe);
-
    return "unrecognized character";
+
  if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
+
  rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
+
  if( rc ) return -1;
+
  if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
+
  iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
+
  for(i=1; i<8; i++){
+
    msbs -= 8;
+
    iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
  }
+
  if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1;
+
  if( iMark & 0x1ff ) return -1;
+
  return iMark;
+
}

-
  /* The following is a performance optimization.  If the regex begins with
-
  ** ".*" (if the input regex lacks an initial "^") and afterwards there are
-
  ** one or more matching characters, enter those matching characters into
-
  ** zInit[].  The re_match() routine can then search ahead in the input 
-
  ** string looking for the initial match without having to run the whole
-
  ** regex engine over the string.  Do not worry able trying to match
-
  ** unicode characters beyond plane 0 - those are very rare and this is
-
  ** just an optimization. */
-
  if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){
-
    for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
-
      unsigned x = pRe->aArg[i];
-
      if( x<=127 ){
-
        pRe->zInit[j++] = (unsigned char)x;
-
      }else if( x<=0xfff ){
-
        pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
-
        pRe->zInit[j++] = 0x80 | (x&0x3f);
-
      }else if( x<=0xffff ){
-
        pRe->zInit[j++] = (unsigned char)(0xd0 | (x>>12));
-
        pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
-
        pRe->zInit[j++] = 0x80 | (x&0x3f);
-
      }else{
-
        break;
-
      }
+
static const char apvfsSqliteHdr[] = "SQLite format 3";
+
/*
+
** Check to see if the file is an appendvfs SQLite database file.
+
** Return true iff it is such. Parameter sz is the file's size.
+
*/
+
static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
+
  int rc;
+
  char zHdr[16];
+
  sqlite3_int64 iMark = apndReadMark(sz, pFile);
+
  if( iMark>=0 ){
+
    /* If file has the correct end-marker, the expected odd size, and the
+
    ** SQLite DB type marker where the end-marker puts it, then it
+
    ** is an appendvfs database.
+
    */
+
    rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
+
    if( SQLITE_OK==rc
+
     && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
+
     && (sz & 0x1ff) == APND_MARK_SIZE
+
     && sz>=512+APND_MARK_SIZE
+
    ){
+
      return 1; /* It's an appendvfs database */
    }
-
    if( j>0 && pRe->zInit[j-1]==0 ) j--;
-
    pRe->nInit = j;
  }
-
  return pRe->zErr;
+
  return 0;
}

/*
-
** Implementation of the regexp() SQL function.  This function implements
-
** the build-in REGEXP operator.  The first argument to the function is the
-
** pattern and the second argument is the string.  So, the SQL statements:
-
**
-
**       A REGEXP B
-
**
-
** is implemented as regexp(B,A).
+
** Check to see if the file is an ordinary SQLite database file.
+
** Return true iff so. Parameter sz is the file's size.
*/
-
static void re_sql_func(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
+
static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
+
  char zHdr[16];
+
  if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */
+
   || (sz & 0x1ff) != 0
+
   || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0)
+
   || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0
+
  ){
+
    return 0;
+
  }else{
+
    return 1;
+
  }
+
}
+

+
/*
+
** Open an apnd file handle.
+
*/
+
static int apndOpen(
+
  sqlite3_vfs *pApndVfs,
+
  const char *zName,
+
  sqlite3_file *pFile,
+
  int flags,
+
  int *pOutFlags
){
-
  ReCompiled *pRe;          /* Compiled regular expression */
-
  const char *zPattern;     /* The regular expression */
-
  const unsigned char *zStr;/* String being searched */
-
  const char *zErr;         /* Compile error message */
-
  int setAux = 0;           /* True to invoke sqlite3_set_auxdata() */
+
  ApndFile *pApndFile = (ApndFile*)pFile;
+
  sqlite3_file *pBaseFile = ORIGFILE(pFile);
+
  sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs);
+
  int rc;
+
  sqlite3_int64 sz = 0;
+
  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
+
    /* The appendvfs is not to be used for transient or temporary databases.
+
    ** Just use the base VFS open to initialize the given file object and
+
    ** open the underlying file. (Appendvfs is then unused for this file.)
+
    */
+
    return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags);
+
  }
+
  memset(pApndFile, 0, sizeof(ApndFile));
+
  pFile->pMethods = &apnd_io_methods;
+
  pApndFile->iMark = -1;    /* Append mark not yet written */

-
  (void)argc;  /* Unused */
-
  pRe = sqlite3_get_auxdata(context, 0);
-
  if( pRe==0 ){
-
    zPattern = (const char*)sqlite3_value_text(argv[0]);
-
    if( zPattern==0 ) return;
-
    zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0);
-
    if( zErr ){
-
      re_free(pRe);
-
      sqlite3_result_error(context, zErr, -1);
-
      return;
-
    }
-
    if( pRe==0 ){
-
      sqlite3_result_error_nomem(context);
-
      return;
+
  rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags);
+
  if( rc==SQLITE_OK ){
+
    rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
+
    if( rc ){
+
      pBaseFile->pMethods->xClose(pBaseFile);
    }
-
    setAux = 1;
  }
-
  zStr = (const unsigned char*)sqlite3_value_text(argv[1]);
-
  if( zStr!=0 ){
-
    sqlite3_result_int(context, re_match(pRe, zStr, -1));
+
  if( rc ){
+
    pFile->pMethods = 0;
+
    return rc;
  }
-
  if( setAux ){
-
    sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free);
+
  if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){
+
    /* The file being opened appears to be just an ordinary DB. Copy
+
    ** the base dispatch-table so this instance mimics the base VFS. 
+
    */
+
    memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile);
+
    return SQLITE_OK;
+
  }
+
  pApndFile->iPgOne = apndReadMark(sz, pFile);
+
  if( pApndFile->iPgOne>=0 ){
+
    pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */
+
    return SQLITE_OK;
+
  }
+
  if( (flags & SQLITE_OPEN_CREATE)==0 ){
+
    pBaseFile->pMethods->xClose(pBaseFile);
+
    rc = SQLITE_CANTOPEN;
+
    pFile->pMethods = 0;
+
  }else{
+
    /* Round newly added appendvfs location to #define'd page boundary. 
+
    ** Note that nothing has yet been written to the underlying file.
+
    ** The append mark will be written along with first content write.
+
    ** Until then, paf->iMark value indicates it is not yet written.
+
    */
+
    pApndFile->iPgOne = APND_START_ROUNDUP(sz);
  }
+
  return rc;
}

/*
-
** Invoke this routine to register the regexp() function with the
-
** SQLite database connection.
+
** Delete an apnd file.
+
** For an appendvfs, this could mean delete the appendvfs portion,
+
** leaving the appendee as it was before it gained an appendvfs.
+
** For now, this code deletes the underlying file too.
+
*/
+
static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
+
  return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
+
}
+

+
/*
+
** All other VFS methods are pass-thrus.
*/
+
static int apndAccess(
+
  sqlite3_vfs *pVfs, 
+
  const char *zPath, 
+
  int flags, 
+
  int *pResOut
+
){
+
  return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
+
}
+
static int apndFullPathname(
+
  sqlite3_vfs *pVfs, 
+
  const char *zPath, 
+
  int nOut, 
+
  char *zOut
+
){
+
  return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
+
}
+
static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
+
  return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
+
}
+
static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
+
  ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
+
}
+
static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
+
  return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
+
}
+
static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
+
  ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
+
}
+
static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
+
  return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
+
}
+
static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
+
  return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
+
}
+
static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
+
  return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
+
}
+
static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
+
  return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
+
}
+
static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
+
  return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
+
}
+
static int apndSetSystemCall(
+
  sqlite3_vfs *pVfs,
+
  const char *zName,
+
  sqlite3_syscall_ptr pCall
+
){
+
  return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
+
}
+
static sqlite3_syscall_ptr apndGetSystemCall(
+
  sqlite3_vfs *pVfs,
+
  const char *zName
+
){
+
  return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
+
}
+
static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
+
  return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
+
}
+

+
  
#ifdef _WIN32

#endif
-
int sqlite3_regexp_init(
+
/* 
+
** This routine is called when the extension is loaded.
+
** Register the new VFS.
+
*/
+
int sqlite3_appendvfs_init(
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
+
  sqlite3_vfs *pOrig;
  SQLITE_EXTENSION_INIT2(pApi);
-
  (void)pzErrMsg;  /* Unused */
-
  rc = sqlite3_create_function(db, "regexp", 2, 
-
                            SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
-
                            0, re_sql_func, 0, 0);
+
  (void)pzErrMsg;
+
  (void)db;
+
  pOrig = sqlite3_vfs_find(0);
+
  if( pOrig==0 ) return SQLITE_ERROR;
+
  apnd_vfs.iVersion = pOrig->iVersion;
+
  apnd_vfs.pAppData = pOrig;
+
  apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
+
  rc = sqlite3_vfs_register(&apnd_vfs, 0);
+
#ifdef APPENDVFS_TEST
  if( rc==SQLITE_OK ){
-
    /* The regexpi(PATTERN,STRING) function is a case-insensitive version
-
    ** of regexp(PATTERN,STRING). */
-
    rc = sqlite3_create_function(db, "regexpi", 2,
-
                            SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
-
                            (void*)db, re_sql_func, 0, 0);
+
    rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
  }
+
#endif
+
  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
  return rc;
}

-
/************************* End ../ext/misc/regexp.c ********************/
+
/************************* End ../ext/misc/appendvfs.c ********************/
+
#endif
#ifdef SQLITE_HAVE_ZLIB
/************************* Begin ../ext/misc/zipfile.c ******************/
/*
@@ -8877,6 +8890,10 @@ static int zipfileRegister(sqlite3 *db){
    zipfileRollback,           /* xRollback */
    zipfileFindFunction,       /* xFindMethod */
    0,                         /* xRename */
+
    0,                         /* xSavepoint */
+
    0,                         /* xRelease */
+
    0,                         /* xRollback */
+
    0                          /* xShadowName */
  };

  int rc = sqlite3_create_module(db, "zipfile"  , &zipfileModule, 0);
@@ -12233,8 +12250,18 @@ struct ShellState {
  char *zNonce;          /* Nonce for temporary safe-mode excapes */
  EQPGraph sGraph;       /* Information for the graphical EXPLAIN QUERY PLAN */
  ExpertInfo expert;     /* Valid if previous command was ".expert OPT..." */
+
#ifdef SQLITE_SHELL_WASM_MODE
+
  struct {
+
    const char * zInput; /* Input string from wasm/JS proxy */
+
    const char * zPos;   /* Cursor pos into zInput */
+
  } wasm;
+
#endif
};

+
#ifdef SQLITE_SHELL_WASM_MODE
+
static ShellState shellState;
+
#endif
+


/* Allowed values for ShellState.autoEQP
*/
@@ -12275,7 +12302,7 @@ struct ShellState {
#define SHFLG_PreserveRowid  0x00000008 /* .dump preserves rowid values */
#define SHFLG_Newlines       0x00000010 /* .dump --newline flag */
#define SHFLG_CountChanges   0x00000020 /* .changes setting */
-
#define SHFLG_Echo           0x00000040 /* .echo or --echo setting */
+
#define SHFLG_Echo           0x00000040 /* .echo on/off, or --echo setting */
#define SHFLG_HeaderSet      0x00000080 /* showHeader has been specified */
#define SHFLG_DumpDataOnly   0x00000100 /* .dump show data only */
#define SHFLG_DumpNoSys      0x00000200 /* .dump omits system tables */
@@ -12899,7 +12926,11 @@ static int safeModeAuth(
  UNUSED_PARAMETER(zA4);
  switch( op ){
    case SQLITE_ATTACH: {
+
#ifndef SQLITE_SHELL_WASM_MODE
+
      /* In WASM builds the filesystem is a virtual sandbox, so
+
      ** there's no harm in using ATTACH. */
      failIfSafeMode(p, "cannot run ATTACH in safe mode");
+
#endif
      break;
    }
    case SQLITE_FUNCTION: {
@@ -14028,6 +14059,9 @@ static int str_in_array(const char *zStr, const char **azArray){
**       all opcodes that occur between the p2 jump destination and the opcode
**       itself by 2 spaces.
**
+
**     * Do the previous for "Return" instructions for when P2 is positive.
+
**       See tag-20220407a in wherecode.c and vdbe.c.
+
**
**     * For each "Goto", if the jump destination is earlier in the program
**       and ends on one of:
**          Yield  SeekGt  SeekLt  RowSetRead  Rewind
@@ -14042,7 +14076,8 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
  int nAlloc = 0;                 /* Allocated size of p->aiIndent[], abYield */
  int iOp;                        /* Index of operation in p->aiIndent[] */

-
  const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
+
  const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
+
                           "Return", 0 };
  const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
                            "Rewind", 0 };
  const char *azGoto[] = { "Goto", 0 };
@@ -14100,7 +14135,7 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
    p->aiIndent[iOp] = 0;
    p->nIndent = iOp+1;

-
    if( str_in_array(zOp, azNext) ){
+
    if( str_in_array(zOp, azNext) && p2op>0 ){
      for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
    }
    if( str_in_array(zOp, azGoto) && p2op<p->nIndent
@@ -14126,7 +14161,7 @@ static void explain_data_delete(ShellState *p){
}

/*
-
** Disable and restore .wheretrace and .selecttrace settings.
+
** Disable and restore .wheretrace and .treetrace/.selecttrace settings.
*/
static unsigned int savedSelectTrace;
static unsigned int savedWhereTrace;
@@ -14900,11 +14935,6 @@ static int shell_exec(
        pArg->cnt = 0;
      }

-
      /* echo the sql statement if echo on */
-
      if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){
-
        utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
-
      }
-

      /* Show the EXPLAIN QUERY PLAN if .eqp is on */
      if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
        sqlite3_stmt *pExplain;
@@ -15303,13 +15333,14 @@ static int run_schema_dump_query(
** Text of help messages.
**
** The help text for each individual command begins with a line that starts
-
** with ".".  Subsequent lines are supplimental information.
+
** with ".".  Subsequent lines are supplemental information.
**
** There must be two or more spaces between the end of the command and the
** start of the description of what that command does.
*/
static const char *(azHelp[]) = {
-
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
+
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) \
+
  && !defined(SQLITE_SHELL_WASM_MODE)
  ".archive ...             Manage SQL archives",
  "   Each command must have exactly one of the following options:",
  "     -c, --create               Create a new archive",
@@ -15335,20 +15366,28 @@ static const char *(azHelp[]) = {
#ifndef SQLITE_OMIT_AUTHORIZATION
  ".auth ON|OFF             Show authorizer callbacks",
#endif
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".backup ?DB? FILE        Backup DB (default \"main\") to FILE",
  "   Options:",
  "       --append            Use the appendvfs",
  "       --async             Write to FILE without journal and fsync()",
+
#endif
  ".bail on|off             Stop after hitting an error.  Default OFF",
  ".binary on|off           Turn binary output on or off.  Default OFF",
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".cd DIRECTORY            Change the working directory to DIRECTORY",
+
#endif
  ".changes on|off          Show number of rows changed by SQL",
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".check GLOB              Fail if output since .testcase does not match",
  ".clone NEWDB             Clone data into NEWDB from the existing database",
+
#endif
  ".connection [close] [#]  Open or close an auxiliary database connection",
  ".databases               List names and files of attached databases",
  ".dbconfig ?op? ?val?     List or change sqlite3_db_config() options",
+
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
  ".dbinfo ?DB?             Show status information about the database",
+
#endif
  ".dump ?OBJECTS?          Render database content as SQL",
  "   Options:",
  "     --data-only            Output only INSERT statements",
@@ -15365,9 +15404,13 @@ static const char *(azHelp[]) = {
  "      trace                 Like \"full\" but enable \"PRAGMA vdbe_trace\"",
#endif
  "      trigger               Like \"full\" but also show trigger bytecode",
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".excel                   Display the output of next command in spreadsheet",
  "   --bom                   Put a UTF8 byte-order mark on intermediate file",
+
#endif
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".exit ?CODE?             Exit this program with return-code CODE",
+
#endif
  ".expert                  EXPERIMENTAL. Suggest indexes for queries",
  ".explain ?on|off|auto?   Change the EXPLAIN formatting mode.  Default: auto",
  ".filectrl CMD ...        Run various sqlite3_file_control() operations",
@@ -15376,6 +15419,7 @@ static const char *(azHelp[]) = {
  ".fullschema ?--indent?   Show schema and the content of sqlite_stat tables",
  ".headers on|off          Turn display of headers on or off",
  ".help ?-all? ?PATTERN?   Show help text for PATTERN",
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".import FILE TABLE       Import data from FILE into TABLE",
  "   Options:",
  "     --ascii               Use \\037 and \\036 as column and row separators",
@@ -15390,6 +15434,7 @@ static const char *(azHelp[]) = {
  "        from the \".mode\" output mode",
  "     *  If FILE begins with \"|\" then it is a command that generates the",
  "        input text.",
+
#endif
#ifndef SQLITE_OMIT_TEST_CONTROL
  ".imposter INDEX TABLE    Create imposter table TABLE on index INDEX",
#endif
@@ -15403,10 +15448,12 @@ static const char *(azHelp[]) = {
  ".lint OPTIONS            Report potential schema issues.",
  "     Options:",
  "        fkey-indexes     Find missing foreign key indexes",
-
#ifndef SQLITE_OMIT_LOAD_EXTENSION
+
#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_WASM_MODE)
  ".load FILE ?ENTRY?       Load an extension library",
#endif
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".log FILE|off            Turn logging on or off.  FILE can be stderr/stdout",
+
#endif
  ".mode MODE ?OPTIONS?     Set output mode",
  "   MODE is one of:",
  "     ascii       Columns/rows delimited by 0x1F and 0x1E",
@@ -15431,16 +15478,23 @@ static const char *(azHelp[]) = {
  "     --quote        Quote output text as SQL literals",
  "     --noquote      Do not quote output text",
  "     TABLE          The name of SQL table used for \"insert\" mode",
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".nonce STRING            Suspend safe mode for one command if nonce matches",
+
#endif
  ".nullvalue STRING        Use STRING in place of NULL values",
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".once ?OPTIONS? ?FILE?   Output for the next SQL command only to FILE",
  "     If FILE begins with '|' then open as a pipe",
  "       --bom  Put a UTF8 byte-order mark at the beginning",
  "       -e     Send output to the system text editor",
  "       -x     Send output as CSV to a spreadsheet (same as \".excel\")",
+
  /* Note that .open is (partially) available in WASM builds but is
+
  ** currently only intended to be used by the fiddle tool, not
+
  ** end users, so is "undocumented." */
  ".open ?OPTIONS? ?FILE?   Close existing database and reopen FILE",
  "     Options:",
  "        --append        Use appendvfs to append database to the end of FILE",
+
#endif
#ifndef SQLITE_OMIT_DESERIALIZE
  "        --deserialize   Load into memory using sqlite3_deserialize()",
  "        --hexdb         Load the output of \"dbtotxt\" as an in-memory db",
@@ -15450,12 +15504,14 @@ static const char *(azHelp[]) = {
  "        --nofollow      Do not follow symbolic links",
  "        --readonly      Open FILE readonly",
  "        --zip           FILE is a ZIP archive",
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".output ?FILE?           Send output to FILE or stdout if FILE is omitted",
  "   If FILE begins with '|' then open it as a pipe.",
  "   Options:",
  "     --bom                 Prefix output with a UTF8 byte-order mark",
  "     -e                    Send output to the system text editor",
  "     -x                    Send output as CSV to a spreadsheet",
+
#endif
  ".parameter CMD ...       Manage SQL parameter bindings",
  "   clear                   Erase all bindings",
  "   init                    Initialize the TEMP table that holds bindings",
@@ -15472,9 +15528,11 @@ static const char *(azHelp[]) = {
  "   --reset                   Reset the count for each input and interrupt",
#endif
  ".prompt MAIN CONTINUE    Replace the standard prompts",
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".quit                    Exit this program",
  ".read FILE               Read input from FILE or command output",
  "    If FILE begins with \"|\", it is a command that generates the input.",
+
#endif
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
  ".recover                 Recover as much data as possible from corrupt db.",
  "   --freelist-corrupt       Assume the freelist is corrupt",
@@ -15483,8 +15541,10 @@ static const char *(azHelp[]) = {
  "   --no-rowids              Do not attempt to recover rowid values",
  "                            that are not also INTEGER PRIMARY KEYs",
#endif
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".restore ?DB? FILE       Restore content of DB (default \"main\") from FILE",
  ".save ?OPTIONS? FILE     Write database to FILE (an alias for .backup ...)",
+
#endif
  ".scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off",
  ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",
  "   Options:",
@@ -15518,7 +15578,7 @@ static const char *(azHelp[]) = {
  "      --sha3-384            Use the sha3-384 algorithm",
  "      --sha3-512            Use the sha3-512 algorithm",
  "    Any other argument is a LIKE pattern for tables to hash",
-
#ifndef SQLITE_NOHAVE_SYSTEM
+
#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
  ".shell CMD ARGS...       Run CMD ARGS... in a system shell",
#endif
  ".show                    Show the current values for various settings",
@@ -15527,11 +15587,13 @@ static const char *(azHelp[]) = {
  "   on                       Turn on automatic stat display",
  "   stmt                     Show statement stats",
  "   vmstep                   Show the virtual machine step count only",
-
#ifndef SQLITE_NOHAVE_SYSTEM
+
#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
  ".system CMD ARGS...      Run CMD ARGS... in a system shell",
#endif
  ".tables ?TABLE?          List names of tables matching LIKE pattern TABLE",
+
#ifndef SQLITE_SHELL_WASM_MODE
  ".testcase NAME           Begin redirecting output to 'testcase-out.txt'",
+
#endif
  ".testctrl CMD ...        Run various sqlite3_test_control() operations",
  "                           Run \".testctrl\" with no arguments for details",
  ".timeout MS              Try opening locked tables for MS milliseconds",
@@ -16076,20 +16138,24 @@ static void open_db(ShellState *p, int openFlags){
#ifndef SQLITE_OMIT_LOAD_EXTENSION
    sqlite3_enable_load_extension(p->db, 1);
#endif
-
    sqlite3_fileio_init(p->db, 0, 0);
    sqlite3_shathree_init(p->db, 0, 0);
-
    sqlite3_completion_init(p->db, 0, 0);
    sqlite3_uint_init(p->db, 0, 0);
    sqlite3_decimal_init(p->db, 0, 0);
    sqlite3_regexp_init(p->db, 0, 0);
    sqlite3_ieee_init(p->db, 0, 0);
    sqlite3_series_init(p->db, 0, 0);
+
#ifndef SQLITE_SHELL_WASM_MODE
+
    sqlite3_fileio_init(p->db, 0, 0);
+
    sqlite3_completion_init(p->db, 0, 0);
+
#endif
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
    sqlite3_dbdata_init(p->db, 0, 0);
#endif
#ifdef SQLITE_HAVE_ZLIB
-
    sqlite3_zipfile_init(p->db, 0, 0);
-
    sqlite3_sqlar_init(p->db, 0, 0);
+
    if( !p->bSafeModePersist ){
+
      sqlite3_zipfile_init(p->db, 0, 0);
+
      sqlite3_sqlar_init(p->db, 0, 0);
+
    }
#endif
    sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
                            shellAddSchemaName, 0, 0);
@@ -16859,6 +16925,7 @@ static int db_int(sqlite3 *db, const char *zSql){
  return res;
}

+
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
/*
** Convert a 2-byte or 4-byte big-endian integer into a native integer
*/
@@ -16965,6 +17032,8 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
  utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
  return 0;
}
+
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE)
+
          && defined(SQLITE_ENABLE_DBPAGE_VTAB) */

/*
** Print the current sqlite3_errmsg() value to stderr and return 1.
@@ -18918,7 +18987,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */


-
/* 
+
/*
 * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it.
 * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE,
 *   close db and set it to 0, and return the columns spec, to later
@@ -19001,6 +19070,13 @@ UPDATE ColNames AS t SET reps=\
  static const char * const zColDigits = "\
SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \
";
+
#else
+
  /* Counting on SQLITE_MAX_COLUMN < 100,000 here. (32767 is the hard limit.) */
+
  static const char * const zColDigits = "\
+
SELECT CASE WHEN (nc < 10) THEN 1 WHEN (nc < 100) THEN 2 \
+
 WHEN (nc < 1000) THEN 3 WHEN (nc < 10000) THEN 4 \
+
 ELSE 5 FROM (SELECT count(*) AS nc FROM ColNames) \
+
";
#endif
  static const char * const zRenameRank =
#ifdef SHELL_COLUMN_RENAME_CLEAN
@@ -19086,11 +19162,7 @@ FROM (\
    /* Formulate the columns spec, close the DB, zero *pDb. */
    char *zColsSpec = 0;
    int hasDupes = db_int(*pDb, zHasDupes);
-
#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
    int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0;
-
#else
-
# define nDigits 2
-
#endif
    if( hasDupes ){
#ifdef SHELL_COLUMN_RENAME_CLEAN
      rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0);
@@ -19201,7 +19273,8 @@ static int do_meta_command(char *zLine, ShellState *p){
  }else
#endif

-
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
+
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) \
+
  && !defined(SQLITE_SHELL_WASM_MODE)
  if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
    open_db(p, 0);
    failIfSafeMode(p, "cannot run .archive in safe mode");
@@ -19209,6 +19282,7 @@ static int do_meta_command(char *zLine, ShellState *p){
  }else
#endif

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
   || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
  ){
@@ -19277,6 +19351,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
    close_db(pDest);
  }else
+
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */

  if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
    if( nArg==2 ){
@@ -19307,6 +19382,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    test_breakpoint();
  }else

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( c=='c' && strcmp(azArg[0],"cd")==0 ){
    failIfSafeMode(p, "cannot run .cd in safe mode");
    if( nArg==2 ){
@@ -19326,6 +19402,7 @@ static int do_meta_command(char *zLine, ShellState *p){
      rc = 1;
    }
  }else
+
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */

  if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
    if( nArg==2 ){
@@ -19336,6 +19413,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
  }else

+
#ifndef SQLITE_SHELL_WASM_MODE
  /* Cancel output redirection, if it is currently set (by .testcase)
  ** Then read the content of the testcase-out.txt file and compare against
  ** azArg[1].  If there are differences, report an error and exit.
@@ -19360,7 +19438,9 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
    sqlite3_free(zRes);
  }else
+
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
    failIfSafeMode(p, "cannot run .clone in safe mode");
    if( nArg==2 ){
@@ -19370,6 +19450,7 @@ static int do_meta_command(char *zLine, ShellState *p){
      rc = 1;
    }
  }else
+
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */

  if( c=='c' && strncmp(azArg[0], "connection", n)==0 ){
    if( nArg==1 ){
@@ -19495,11 +19576,11 @@ static int do_meta_command(char *zLine, ShellState *p){
    }   
  }else

+
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
  if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
    rc = shell_dbinfo_command(p, nArg, azArg);
  }else

-
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
  if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
    open_db(p, 0);
    rc = recoverDatabaseCmd(p, nArg, azArg);
@@ -19512,7 +19593,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    int i;
    int savedShowHeader = p->showHeader;
    int savedShellFlags = p->shellFlgs;
-
    ShellClearFlag(p, 
+
    ShellClearFlag(p,
       SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
       |SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
    for(i=1; i<nArg; i++){
@@ -19658,10 +19739,12 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
  }else

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
    if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
    rc = 2;
  }else
+
#endif

  /* The ".explain" command is automatic now.  It is largely pointless.  It
  ** retained purely for backwards compatibility */
@@ -19916,6 +19999,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
  }else

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
    char *zTable = 0;           /* Insert data into this table */
    char *zSchema = 0;          /* within this schema (may default to "main") */
@@ -19937,16 +20021,12 @@ static int do_meta_command(char *zLine, ShellState *p){

    failIfSafeMode(p, "cannot run .import in safe mode");
    memset(&sCtx, 0, sizeof(sCtx));
-
    sCtx.z = sqlite3_malloc64(120);
-
    if( sCtx.z==0 ){
-
      import_cleanup(&sCtx);
-
      shell_out_of_memory();
-
    }
    if( p->mode==MODE_Ascii ){
      xRead = ascii_read_one_field;
    }else{
      xRead = csv_read_one_field;
    }
+
    rc = 1;
    for(i=1; i<nArg; i++){
      char *z = azArg[i];
      if( z[0]=='-' && z[1]=='-' ) z++;
@@ -19958,7 +20038,6 @@ static int do_meta_command(char *zLine, ShellState *p){
        }else{
          utf8_printf(p->out, "ERROR: extra argument: \"%s\".  Usage:\n", z);
          showHelp(p->out, "import");
-
          rc = 1;
          goto meta_command_exit;
        }
      }else if( strcmp(z,"-v")==0 ){
@@ -19980,7 +20059,6 @@ static int do_meta_command(char *zLine, ShellState *p){
      }else{
        utf8_printf(p->out, "ERROR: unknown option: \"%s\".  Usage:\n", z);
        showHelp(p->out, "import");
-
        rc = 1;
        goto meta_command_exit;
      }
    }
@@ -19988,7 +20066,6 @@ static int do_meta_command(char *zLine, ShellState *p){
      utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
                  zFile==0 ? "FILE" : "TABLE");
      showHelp(p->out, "import");
-
      rc = 1;
      goto meta_command_exit;
    }
    seenInterrupt = 0;
@@ -20000,21 +20077,18 @@ static int do_meta_command(char *zLine, ShellState *p){
      if( nSep==0 ){
        raw_printf(stderr,
                   "Error: non-null column separator required for import\n");
-
        rc = 1;
        goto meta_command_exit;
      }
      if( nSep>1 ){
-
        raw_printf(stderr, 
+
        raw_printf(stderr,
              "Error: multi-character column separators not allowed"
              " for import\n");
-
        rc = 1;
        goto meta_command_exit;
      }
      nSep = strlen30(p->rowSeparator);
      if( nSep==0 ){
        raw_printf(stderr,
            "Error: non-null row separator required for import\n");
-
        rc = 1;
        goto meta_command_exit;
      }
      if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
@@ -20028,7 +20102,6 @@ static int do_meta_command(char *zLine, ShellState *p){
      if( nSep>1 ){
        raw_printf(stderr, "Error: multi-character row separators not allowed"
                           " for import\n");
-
        rc = 1;
        goto meta_command_exit;
      }
      sCtx.cColSep = p->colSeparator[0];
@@ -20039,7 +20112,6 @@ static int do_meta_command(char *zLine, ShellState *p){
    if( sCtx.zFile[0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
-
      rc = 1;
      goto meta_command_exit;
#else
      sCtx.in = popen(sCtx.zFile+1, "r");
@@ -20052,8 +20124,6 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
    if( sCtx.in==0 ){
      utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
-
      rc = 1;
-
      import_cleanup(&sCtx);
      goto meta_command_exit;
    }
    if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
@@ -20067,6 +20137,11 @@ static int do_meta_command(char *zLine, ShellState *p){
      output_c_string(p->out, zSep);
      utf8_printf(p->out, "\n");
    }
+
    sCtx.z = sqlite3_malloc64(120);
+
    if( sCtx.z==0 ){
+
      import_cleanup(&sCtx);
+
      shell_out_of_memory();
+
    }
    /* Below, resources must be freed before exit. */
    while( (nSkip--)>0 ){
      while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
@@ -20215,6 +20290,7 @@ static int do_meta_command(char *zLine, ShellState *p){
          sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
    }
  }else
+
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */

#ifndef SQLITE_UNTESTABLE
  if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
@@ -20404,7 +20480,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    lintDotCommand(p, azArg, nArg);
  }else

-
#ifndef SQLITE_OMIT_LOAD_EXTENSION
+
#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_WASM_MODE)
  if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
    const char *zFile, *zProc;
    char *zErrMsg = 0;
@@ -20426,6 +20502,7 @@ static int do_meta_command(char *zLine, ShellState *p){
  }else
#endif

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
    failIfSafeMode(p, "cannot run .log in safe mode");
    if( nArg!=2 ){
@@ -20437,6 +20514,7 @@ static int do_meta_command(char *zLine, ShellState *p){
      p->pLog = output_file_open(zFile, 0);
    }
  }else
+
#endif

  if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
    const char *zMode = 0;
@@ -20561,6 +20639,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    p->cMode = p->mode;
  }else

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( c=='n' && strcmp(azArg[0], "nonce")==0 ){
    if( nArg!=2 ){
      raw_printf(stderr, "Usage: .nonce NONCE\n");
@@ -20575,6 +20654,7 @@ static int do_meta_command(char *zLine, ShellState *p){
                 ** at the end of this procedure */
    }
  }else
+
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */

  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
    if( nArg==2 ){
@@ -20596,6 +20676,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    /* Check for command-line arguments */
    for(iName=1; iName<nArg; iName++){
      const char *z = azArg[iName];
+
#ifndef SQLITE_SHELL_WASM_MODE
      if( optionMatch(z,"new") ){
        newFlag = 1;
#ifdef SQLITE_HAVE_ZLIB
@@ -20616,7 +20697,9 @@ static int do_meta_command(char *zLine, ShellState *p){
      }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
        p->szMax = integerValue(azArg[++iName]);
#endif /* SQLITE_OMIT_DESERIALIZE */
-
      }else if( z[0]=='-' ){
+
      }else
+
#endif /* !SQLITE_SHELL_WASM_MODE */
+
      if( z[0]=='-' ){
        utf8_printf(stderr, "unknown option: %s\n", z);
        rc = 1;
        goto meta_command_exit;
@@ -20643,6 +20726,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    /* If a filename is specified, try to open it first */
    if( zFN || p->openMode==SHELL_OPEN_HEXDB ){
      if( newFlag && zFN && !p->bSafeMode ) shellDeleteFile(zFN);
+
#ifndef SQLITE_SHELL_WASM_MODE
      if( p->bSafeMode
       && p->openMode!=SHELL_OPEN_HEXDB
       && zFN
@@ -20650,6 +20734,9 @@ static int do_meta_command(char *zLine, ShellState *p){
      ){
        failIfSafeMode(p, "cannot open disk-based database files in safe mode");
      }
+
#else
+
      /* WASM mode has its own sandboxed pseudo-filesystem. */
+
#endif
      if( zFN ){
        zNewFilename = sqlite3_mprintf("%s", zFN);
        shell_check_oom(zNewFilename);
@@ -20672,6 +20759,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
  }else

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( (c=='o'
        && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
   || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
@@ -20680,9 +20768,10 @@ static int do_meta_command(char *zLine, ShellState *p){
    int bTxtMode = 0;
    int i;
    int eMode = 0;
-
    int bBOM = 0;
-
    int bOnce = 0;  /* 0: .output, 1: .once, 2: .excel */
+
    int bOnce = 0;            /* 0: .output, 1: .once, 2: .excel */
+
    unsigned char zBOM[4];    /* Byte-order mark to using if --bom is present */

+
    zBOM[0] = 0;
    failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
    if( c=='e' ){
      eMode = 'x';
@@ -20695,7 +20784,10 @@ static int do_meta_command(char *zLine, ShellState *p){
      if( z[0]=='-' ){
        if( z[1]=='-' ) z++;
        if( strcmp(z,"-bom")==0 ){
-
          bBOM = 1;
+
          zBOM[0] = 0xef;
+
          zBOM[1] = 0xbb;
+
          zBOM[2] = 0xbf;
+
          zBOM[3] = 0;
        }else if( c!='e' && strcmp(z,"-x")==0 ){
          eMode = 'x';  /* spreadsheet */
        }else if( c!='e' && strcmp(z,"-e")==0 ){
@@ -20764,7 +20856,7 @@ static int do_meta_command(char *zLine, ShellState *p){
        p->out = stdout;
        rc = 1;
      }else{
-
        if( bBOM ) fprintf(p->out,"\357\273\277");
+
        if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out);
        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
      }
#endif
@@ -20777,12 +20869,13 @@ static int do_meta_command(char *zLine, ShellState *p){
        p->out = stdout;
        rc = 1;
      } else {
-
        if( bBOM ) fprintf(p->out,"\357\273\277");
+
        if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out);
        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
      }
    }
    sqlite3_free(zFile);
  }else
+
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */

  if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
    open_db(p,0);
@@ -20952,10 +21045,13 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
  }else

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
    rc = 2;
  }else
+
#endif

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
    FILE *inSaved = p->in;
    int savedLineno = p->lineno;
@@ -20990,7 +21086,9 @@ static int do_meta_command(char *zLine, ShellState *p){
    p->in = inSaved;
    p->lineno = savedLineno;
  }else
+
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */

+
#ifndef SQLITE_SHELL_WASM_MODE
  if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
    const char *zSrcFile;
    const char *zDb;
@@ -21042,6 +21140,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
    close_db(pSrc);
  }else
+
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */

  if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
    if( nArg==2 ){
@@ -21198,7 +21297,9 @@ static int do_meta_command(char *zLine, ShellState *p){
    }
  }else

-
  if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
+
  if( (c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0)
+
   || (c=='t' && n==9  && strncmp(azArg[0], "treetrace", n)==0)
+
  ){
    unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
    sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
  }else
@@ -21665,7 +21766,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    sqlite3_free(zSql);
  }else

-
#ifndef SQLITE_NOHAVE_SYSTEM
+
#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
  if( c=='s'
   && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
  ){
@@ -21686,7 +21787,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    sqlite3_free(zCmd);
    if( x ) raw_printf(stderr, "System command returns %d\n", x);
  }else
-
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
+
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE) */

  if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
    static const char *azBool[] = { "off", "on", "trigger", "full"};
@@ -21698,7 +21799,7 @@ static int do_meta_command(char *zLine, ShellState *p){
      goto meta_command_exit;
    }
    utf8_printf(p->out, "%12.12s: %s\n","echo",
-
                                  azBool[ShellHasFlag(p, SHFLG_Echo)]);
+
                azBool[ShellHasFlag(p, SHFLG_Echo)]);
    utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
    utf8_printf(p->out, "%12.12s: %s\n","explain",
         p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
@@ -21866,6 +21967,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    sqlite3_free(azResult);
  }else

+
#ifndef SQLITE_SHELL_WASM_MODE
  /* Begin redirecting output to the file "testcase-out.txt" */
  if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
    output_reset(p);
@@ -21879,6 +21981,7 @@ static int do_meta_command(char *zLine, ShellState *p){
      sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
    }
  }else
+
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */

#ifndef SQLITE_UNTESTABLE
  if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
@@ -22448,7 +22551,7 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss){
          cWait = 0;
          qss = QSS_SETV(qss, 0);
          goto PlainScan;
-
        default: assert(0); 
+
        default: assert(0);
        }
      }
    }
@@ -22469,7 +22572,7 @@ static int line_is_command_terminator(char *zLine){
    zLine += 2; /* SQL Server */
  else
    return 0;
-
  return quickscan(zLine,QSS_Start)==QSS_Start;
+
  return quickscan(zLine, QSS_Start)==QSS_Start;
}

/*
@@ -22546,6 +22649,42 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
  return 0;
}

+
static void echo_group_input(ShellState *p, const char *zDo){
+
  if( ShellHasFlag(p, SHFLG_Echo) ) utf8_printf(p->out, "%s\n", zDo);
+
}
+

+
#ifdef SQLITE_SHELL_WASM_MODE
+
/*
+
** Alternate one_input_line() impl for wasm mode. This is not in the primary impl
+
** because we need the global shellState and cannot access it from that function
+
** without moving lots of code around (creating a larger/messier diff).
+
*/
+
static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
+
  /* Parse the next line from shellState.wasm.zInput. */
+
  const char *zBegin = shellState.wasm.zPos;
+
  const char *z = zBegin;
+
  char *zLine = 0;
+
  int nZ = 0;
+

+
  UNUSED_PARAMETER(in);
+
  UNUSED_PARAMETER(isContinuation);
+
  if(!z || !*z){
+
    return 0;
+
  }
+
  while(*z && isspace(*z)) ++z;
+
  zBegin = z;
+
  for(; *z && '\n'!=*z; ++nZ, ++z){}
+
  if(nZ>0 && '\r'==zBegin[nZ-1]){
+
    --nZ;
+
  }
+
  shellState.wasm.zPos = z;
+
  zLine = realloc(zPrior, nZ+1);
+
  shell_check_oom(zLine);
+
  memcpy(zLine, zBegin, (size_t)nZ);
+
  zLine[nZ] = 0;
+
  return zLine;
+
}
+
#endif /* SQLITE_SHELL_WASM_MODE */

/*
** Read input from *in and process it.  If *in==0 then input
@@ -22595,14 +22734,13 @@ static int process_input(ShellState *p){
    }
    qss = quickscan(zLine, qss);
    if( QSS_PLAINWHITE(qss) && nSql==0 ){
-
      if( ShellHasFlag(p, SHFLG_Echo) )
-
        printf("%s\n", zLine);
      /* Just swallow single-line whitespace */
+
      echo_group_input(p, zLine);
      qss = QSS_Start;
      continue;
    }
    if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
-
      if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
+
      echo_group_input(p, zLine);
      if( zLine[0]=='.' ){
        rc = do_meta_command(zLine, p);
        if( rc==2 ){ /* exit requested */
@@ -22635,6 +22773,7 @@ static int process_input(ShellState *p){
      nSql += nLine;
    }
    if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
+
      echo_group_input(p, zSql);
      errCnt += runOneSqlLine(p, zSql, p->in, startline);
      nSql = 0;
      if( p->outCount ){
@@ -22646,13 +22785,14 @@ static int process_input(ShellState *p){
      p->bSafeMode = p->bSafeModePersist;
      qss = QSS_Start;
    }else if( nSql && QSS_PLAINWHITE(qss) ){
-
      if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
+
      echo_group_input(p, zSql);
      nSql = 0;
      qss = QSS_Start;
    }
  }
  if( nSql ){
    /* This may be incomplete. Let the SQL parser deal with that. */
+
    echo_group_input(p, zSql);
    errCnt += runOneSqlLine(p, zSql, p->in, startline);
  }
  free(zSql);
@@ -22791,7 +22931,7 @@ static const char zOptions[] =
#if !defined(SQLITE_OMIT_DESERIALIZE)
  "   -deserialize         open the database using sqlite3_deserialize()\n"
#endif
-
  "   -echo                print commands before execution\n"
+
  "   -echo                print inputs before execution\n"
  "   -init FILENAME       read/process named file\n"
  "   -[no]header          turn headers on or off\n"
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
@@ -22927,14 +23067,25 @@ static char *cmdline_option_value(int argc, char **argv, int i){
#  endif
#endif

+
#ifdef SQLITE_SHELL_WASM_MODE
+
#  define main fiddle_main
+
#endif
+

#if SQLITE_SHELL_IS_UTF8
int SQLITE_CDECL main(int argc, char **argv){
#else
int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
  char **argv;
#endif
+
#ifdef SQLITE_DEBUG
+
  sqlite3_int64 mem_main_enter = sqlite3_memory_used();
+
#endif
  char *zErrMsg = 0;
+
#ifdef SQLITE_SHELL_WASM_MODE
+
#  define data shellState
+
#else
  ShellState data;
+
#endif
  const char *zInitFile = 0;
  int i;
  int rc = 0;
@@ -22950,8 +23101,13 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){

  setBinaryMode(stdin, 0);
  setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
+
#ifdef SQLITE_SHELL_WASM_MODE
+
  stdin_is_interactive = 0;
+
  stdout_is_console = 1;
+
#else
  stdin_is_interactive = isatty(0);
  stdout_is_console = isatty(1);
+
#endif

#if !defined(_WIN32_WCE)
  if( getenv("SQLITE_DEBUG_BREAK") ){
@@ -23207,7 +23363,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
  }
  data.out = stdout;
+
#ifndef SQLITE_SHELL_WASM_MODE
  sqlite3_appendvfs_init(0,0,0);
+
#endif

  /* Go ahead and open the database file if it already exists.  If the
  ** file does not exist, delay opening it.  This prevents empty database
@@ -23473,6 +23631,9 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
      rc = process_input(&data);
    }
  }
+
#ifndef SQLITE_SHELL_WASM_MODE
+
  /* In WASM mode we have to leave the db state in place so that
+
  ** client code can "push" SQL into it after this call returns. */
  free(azCmd);
  set_table_name(&data, 0);
  if( data.db ){
@@ -23499,5 +23660,136 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
  /* Clear the global data structure so that valgrind will detect memory
  ** leaks */
  memset(&data, 0, sizeof(data));
+
#ifdef SQLITE_DEBUG
+
  if( sqlite3_memory_used()>mem_main_enter ){
+
    utf8_printf(stderr, "Memory leaked: %u bytes\n",
+
                (unsigned int)(sqlite3_memory_used()-mem_main_enter));
+
  }
+
#endif
+
#endif /* !SQLITE_SHELL_WASM_MODE */
  return rc;
}
+

+

+
#ifdef SQLITE_SHELL_WASM_MODE
+
/* Only for emcc experimentation purposes. */
+
int fiddle_experiment(int a,int b){
+
   return a + b;
+
}
+

+
/* Only for emcc experimentation purposes.
+

+
  Define this function in JS using:
+

+
  emcc ... --js-library somefile.js
+

+
  containing:
+

+
mergeInto(LibraryManager.library, {
+
    my_foo: function(){
+
        console.debug("my_foo()",arguments);
+
    }
+
});
+
*/
+
/*extern void my_foo(sqlite3 *);*/
+
/* Only for emcc experimentation purposes. */
+
sqlite3 * fiddle_the_db(){
+
    printf("fiddle_the_db(%p)\n", (const void*)globalDb);
+
    /*my_foo(globalDb);*/
+
    return globalDb;
+
}
+
/* Only for emcc experimentation purposes. */
+
sqlite3 * fiddle_db_arg(sqlite3 *arg){
+
    printf("fiddle_db_arg(%p)\n", (const void*)arg);
+
    return arg;
+
}
+

+
/*
+
** Intended to be called via a SharedWorker() while a separate
+
** SharedWorker() (which manages the wasm module) is performing work
+
** which should be interrupted. Unfortunately, SharedWorker is not
+
** portable enough to make real use of.
+
*/
+
void fiddle_interrupt(void){
+
  if(globalDb) sqlite3_interrupt(globalDb);
+
}
+

+
/*
+
** Returns the filename of the given db name, assuming "main" if
+
** zDbName is NULL. Returns NULL if globalDb is not opened.
+
*/
+
const char * fiddle_db_filename(const char * zDbName){
+
    return globalDb
+
      ? sqlite3_db_filename(globalDb, zDbName ? zDbName : "main")
+
      : NULL;
+
}
+

+
/*
+
** Closes, unlinks, and reopens the db using its current filename (or
+
** the default if the db is currently closed). It is assumed, for
+
** purposes of the fiddle build, that the file is in a transient
+
** virtual filesystem within the browser.
+
*/
+
void fiddle_reset_db(void){
+
  char *zFilename = 0;
+
  if(0==globalDb){
+
    shellState.pAuxDb->zDbFilename = "/fiddle.sqlite3";
+
  }else{
+
    zFilename =
+
      sqlite3_mprintf("%s", sqlite3_db_filename(globalDb, "main"));
+
    shell_check_oom(zFilename);
+
    close_db(globalDb);
+
    shellDeleteFile(zFilename);
+
    shellState.db = 0;
+
    shellState.pAuxDb->zDbFilename = zFilename;
+
  }
+
  open_db(&shellState, 0);
+
  sqlite3_free(zFilename);
+
}
+

+
/*
+
** Trivial exportable function for emscripten. Needs to be exported using:
+
**
+
** emcc ..flags... -sEXPORTED_FUNCTIONS=_fiddle_exec -sEXPORTED_RUNTIME_METHODS=ccall,cwrap
+
**
+
** (Note the underscore before the function name.) It processes zSql
+
** as if it were input to the sqlite3 shell and redirects all output
+
** to the wasm binding.
+
*/
+
void fiddle_exec(const char * zSql){
+
  static int once = 0;
+
  int rc = 0;
+
  if(!once){
+
    /* Simulate an argv array for main() */
+
    static char * argv[] = {"fiddle",
+
                            "-bail",
+
                            "-safe"};
+
    rc = fiddle_main((int)(sizeof(argv)/sizeof(argv[0])), argv);
+
    once = rc ? -1 : 1;
+
    memset(&shellState.wasm, 0, sizeof(shellState.wasm));
+
    printf(
+
        "SQLite version %s %.19s\n" /*extra-version-info*/,
+
        sqlite3_libversion(), sqlite3_sourceid()
+
    );
+
    puts("WASM shell");
+
    puts("Enter \".help\" for usage hints.");
+
    if(once>0){
+
      fiddle_reset_db();
+
    }
+
    if(shellState.db){
+
      printf("Connected to %s.\n", fiddle_db_filename(NULL));
+
    }else{
+
      fprintf(stderr,"ERROR initializing db!\n");
+
      return;
+
    }
+
  }
+
  if(once<0){
+
    puts("DB init failed. Not executing SQL.");
+
  }else if(zSql && *zSql){
+
    shellState.wasm.zInput = zSql;
+
    shellState.wasm.zPos = zSql;
+
    process_input(&shellState);
+
    memset(&shellState.wasm, 0, sizeof(shellState.wasm));
+
  }
+
}
+
#endif /* SQLITE_SHELL_WASM_MODE */
modified external/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-
** version 3.38.5.  By combining all the individual C code files into this
+
** version 3.39.2.  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
@@ -452,9 +452,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-
#define SQLITE_VERSION        "3.38.5"
-
#define SQLITE_VERSION_NUMBER 3038005
-
#define SQLITE_SOURCE_ID      "2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe"
+
#define SQLITE_VERSION        "3.39.2"
+
#define SQLITE_VERSION_NUMBER 3039002
+
#define SQLITE_SOURCE_ID      "2022-07-21 15:24:47 698edb77537b67c41adc68f9b892db56bcf9a55e00371a61420f3ddd668e6603"

/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -5899,7 +5899,8 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
** object D and returns a pointer to that copy.  ^The [sqlite3_value] returned
** is a [protected sqlite3_value] object even if the input is not.
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
-
** memory allocation fails.
+
** memory allocation fails. ^If V is a [pointer value], then the result
+
** of sqlite3_value_dup(V) is a NULL value.
**
** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
** previously obtained from [sqlite3_value_dup()].  ^If V is a NULL pointer
@@ -6582,6 +6583,28 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*);
SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);

/*
+
** CAPI3REF: Return The Schema Name For A Database Connection
+
** METHOD: sqlite3
+
**
+
** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name
+
** for the N-th database on database connection D, or a NULL pointer of N is
+
** out of range.  An N value of 0 means the main database file.  An N of 1 is
+
** the "temp" schema.  Larger values of N correspond to various ATTACH-ed
+
** databases.
+
**
+
** Space to hold the string that is returned by sqlite3_db_name() is managed
+
** by SQLite itself.  The string might be deallocated by any operation that
+
** changes the schema, including [ATTACH] or [DETACH] or calls to
+
** [sqlite3_serialize()] or [sqlite3_deserialize()], even operations that
+
** occur on a different thread.  Applications that need to
+
** remember the string long-term should make their own copy.  Applications that
+
** are accessing the same database connection simultaneously on multiple
+
** threads should mutex-protect calls to this API and should make their own
+
** private copy of the result prior to releasing the mutex.
+
*/
+
SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N);
+

+
/*
** CAPI3REF: Return The Filename For A Database Connection
** METHOD: sqlite3
**
@@ -9860,8 +9883,8 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_
** of a [virtual table] implementation. The result of calling this
** interface from outside of xBestIndex() is undefined and probably harmful.
**
-
** ^The sqlite3_vtab_distinct() interface returns an integer that is
-
** either 0, 1, or 2.  The integer returned by sqlite3_vtab_distinct()
+
** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and
+
** 3.  The integer returned by sqlite3_vtab_distinct()
** gives the virtual table additional information about how the query
** planner wants the output to be ordered. As long as the virtual table
** can meet the ordering requirements of the query planner, it may set
@@ -9893,6 +9916,13 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_
** that have the same value for all columns identified by "aOrderBy".
** ^However omitting the extra rows is optional.
** This mode is used for a DISTINCT query.
+
** <li value="3"><p>
+
** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
+
** that the query planner needs only distinct rows but it does need the
+
** rows to be sorted.)^ ^The virtual table implementation is free to omit
+
** rows that are identical in all aOrderBy columns, if it wants to, but
+
** it is not required to omit any rows.  This mode is used for queries
+
** that have both DISTINCT and ORDER BY clauses.
** </ol>
**
** ^For the purposes of comparing virtual table output values to see if the
@@ -14357,8 +14387,19 @@ typedef INT16_TYPE LogEst;
/*
** Round up a number to the next larger multiple of 8.  This is used
** to force 8-byte alignment on 64-bit architectures.
+
**
+
** ROUND8() always does the rounding, for any argument.
+
**
+
** ROUND8P() assumes that the argument is already an integer number of
+
** pointers in size, and so it is a no-op on systems where the pointer
+
** size is 8.
*/
#define ROUND8(x)     (((x)+7)&~7)
+
#if SQLITE_PTRSIZE==8
+
# define ROUND8P(x)   (x)
+
#else
+
# define ROUND8P(x)   (((x)+7)&~7)
+
#endif

/*
** Round down to the nearest multiple of 8
@@ -14421,22 +14462,23 @@ typedef INT16_TYPE LogEst;
#endif

/*
-
** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
-
** the Select query generator tracing logic is turned on.
+
** TREETRACE_ENABLED will be either 1 or 0 depending on whether or not
+
** the Abstract Syntax Tree tracing logic is turned on.
*/
#if !defined(SQLITE_AMALGAMATION)
-
SQLITE_PRIVATE u32 sqlite3SelectTrace;
+
SQLITE_PRIVATE u32 sqlite3TreeTrace;
#endif
#if defined(SQLITE_DEBUG) \
-
    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE))
-
# define SELECTTRACE_ENABLED 1
+
    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE) \
+
                             || defined(SQLITE_ENABLE_TREETRACE))
+
# define TREETRACE_ENABLED 1
# define SELECTTRACE(K,P,S,X)  \
-
  if(sqlite3SelectTrace&(K))   \
+
  if(sqlite3TreeTrace&(K))   \
    sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
    sqlite3DebugPrintf X
#else
# define SELECTTRACE(K,P,S,X)
-
# define SELECTTRACE_ENABLED 0
+
# define TREETRACE_ENABLED 0
#endif

/*
@@ -14521,7 +14563,7 @@ struct BusyHandler {
** pointer will work here as long as it is distinct from SQLITE_STATIC
** and SQLITE_TRANSIENT.
*/
-
#define SQLITE_DYNAMIC   ((sqlite3_destructor_type)sqlite3OomFault)
+
#define SQLITE_DYNAMIC   ((sqlite3_destructor_type)sqlite3OomClear)

/*
** When SQLITE_OMIT_WSD is defined, it means that the target platform does
@@ -14597,6 +14639,7 @@ typedef struct Lookaside Lookaside;
typedef struct LookasideSlot LookasideSlot;
typedef struct Module Module;
typedef struct NameContext NameContext;
+
typedef struct OnOrUsing OnOrUsing;
typedef struct Parse Parse;
typedef struct ParseCleanup ParseCleanup;
typedef struct PreUpdate PreUpdate;
@@ -14715,14 +14758,15 @@ typedef struct Pager Pager;
typedef struct PgHdr DbPage;

/*
-
** Page number PAGER_MJ_PGNO is never used in an SQLite database (it is
+
** Page number PAGER_SJ_PGNO is never used in an SQLite database (it is
** reserved for working around a windows/posix incompatibility). It is
** used in the journal to signify that the remainder of the journal file
** is devoted to storing a super-journal name - there are no more pages to
** roll back. See comments for function writeSuperJournal() in pager.c
** for details.
*/
-
#define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
+
#define PAGER_SJ_PGNO_COMPUTED(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1))
+
#define PAGER_SJ_PGNO(x)          ((x)->lckPgno)

/*
** Allowed values for the flags parameter to sqlite3PagerOpen().
@@ -15399,7 +15443,6 @@ struct VdbeOp {
#ifdef SQLITE_ENABLE_CURSOR_HINTS
    Expr *pExpr;           /* Used when p4type is P4_EXPR */
#endif
-
    int (*xAdvance)(BtCursor *, int);
  } p4;
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  char *zComment;          /* Comment to improve readability */
@@ -15450,21 +15493,19 @@ typedef struct VdbeOpList VdbeOpList;
#define P4_COLLSEQ    (-2)  /* P4 is a pointer to a CollSeq structure */
#define P4_INT32      (-3)  /* P4 is a 32-bit signed integer */
#define P4_SUBPROGRAM (-4)  /* P4 is a pointer to a SubProgram structure */
-
#define P4_ADVANCE    (-5)  /* P4 is a pointer to BtreeNext() or BtreePrev() */
-
#define P4_TABLE      (-6)  /* P4 is a pointer to a Table structure */
+
#define P4_TABLE      (-5)  /* P4 is a pointer to a Table structure */
/* Above do not own any resources.  Must free those below */
-
#define P4_FREE_IF_LE (-7)
-
#define P4_DYNAMIC    (-7)  /* Pointer to memory from sqliteMalloc() */
-
#define P4_FUNCDEF    (-8)  /* P4 is a pointer to a FuncDef structure */
-
#define P4_KEYINFO    (-9)  /* P4 is a pointer to a KeyInfo structure */
-
#define P4_EXPR       (-10) /* P4 is a pointer to an Expr tree */
-
#define P4_MEM        (-11) /* P4 is a pointer to a Mem*    structure */
-
#define P4_VTAB       (-12) /* P4 is a pointer to an sqlite3_vtab structure */
-
#define P4_REAL       (-13) /* P4 is a 64-bit floating point value */
-
#define P4_INT64      (-14) /* P4 is a 64-bit signed integer */
-
#define P4_INTARRAY   (-15) /* P4 is a vector of 32-bit integers */
-
#define P4_FUNCCTX    (-16) /* P4 is a pointer to an sqlite3_context object */
-
#define P4_DYNBLOB    (-17) /* Pointer to memory from sqliteMalloc() */
+
#define P4_FREE_IF_LE (-6)
+
#define P4_DYNAMIC    (-6)  /* Pointer to memory from sqliteMalloc() */
+
#define P4_FUNCDEF    (-7)  /* P4 is a pointer to a FuncDef structure */
+
#define P4_KEYINFO    (-8)  /* P4 is a pointer to a KeyInfo structure */
+
#define P4_EXPR       (-9) /* P4 is a pointer to an Expr tree */
+
#define P4_MEM        (-10) /* P4 is a pointer to a Mem*    structure */
+
#define P4_VTAB       (-11) /* P4 is a pointer to an sqlite3_vtab structure */
+
#define P4_REAL       (-12) /* P4 is a 64-bit floating point value */
+
#define P4_INT64      (-13) /* P4 is a 64-bit signed integer */
+
#define P4_INTARRAY   (-14) /* P4 is a vector of 32-bit integers */
+
#define P4_FUNCCTX    (-15) /* P4 is a pointer to an sqlite3_context object */

/* Error message codes for OP_Halt */
#define P5_ConstraintNotNull 1
@@ -15509,42 +15550,42 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Savepoint       0
#define OP_AutoCommit      1
#define OP_Transaction     2
-
#define OP_SorterNext      3 /* jump                                       */
-
#define OP_Prev            4 /* jump                                       */
-
#define OP_Next            5 /* jump                                       */
-
#define OP_Checkpoint      6
-
#define OP_JournalMode     7
-
#define OP_Vacuum          8
-
#define OP_VFilter         9 /* jump, synopsis: iplan=r[P3] zplan='P4'     */
-
#define OP_VUpdate        10 /* synopsis: data=r[P3@P2]                    */
-
#define OP_Goto           11 /* jump                                       */
-
#define OP_Gosub          12 /* jump                                       */
-
#define OP_InitCoroutine  13 /* jump                                       */
-
#define OP_Yield          14 /* jump                                       */
-
#define OP_MustBeInt      15 /* jump                                       */
-
#define OP_Jump           16 /* jump                                       */
-
#define OP_Once           17 /* jump                                       */
-
#define OP_If             18 /* jump                                       */
+
#define OP_Checkpoint      3
+
#define OP_JournalMode     4
+
#define OP_Vacuum          5
+
#define OP_VFilter         6 /* jump, synopsis: iplan=r[P3] zplan='P4'     */
+
#define OP_VUpdate         7 /* synopsis: data=r[P3@P2]                    */
+
#define OP_Goto            8 /* jump                                       */
+
#define OP_Gosub           9 /* jump                                       */
+
#define OP_InitCoroutine  10 /* jump                                       */
+
#define OP_Yield          11 /* jump                                       */
+
#define OP_MustBeInt      12 /* jump                                       */
+
#define OP_Jump           13 /* jump                                       */
+
#define OP_Once           14 /* jump                                       */
+
#define OP_If             15 /* jump                                       */
+
#define OP_IfNot          16 /* jump                                       */
+
#define OP_IsNullOrType   17 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */
+
#define OP_IfNullRow      18 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
#define OP_Not            19 /* same as TK_NOT, synopsis: r[P2]= !r[P1]    */
-
#define OP_IfNot          20 /* jump                                       */
-
#define OP_IsNullOrType   21 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */
-
#define OP_IfNullRow      22 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */
-
#define OP_SeekLT         23 /* jump, synopsis: key=r[P3@P4]               */
-
#define OP_SeekLE         24 /* jump, synopsis: key=r[P3@P4]               */
-
#define OP_SeekGE         25 /* jump, synopsis: key=r[P3@P4]               */
-
#define OP_SeekGT         26 /* jump, synopsis: key=r[P3@P4]               */
-
#define OP_IfNotOpen      27 /* jump, synopsis: if( !csr[P1] ) goto P2     */
-
#define OP_IfNoHope       28 /* jump, synopsis: key=r[P3@P4]               */
-
#define OP_NoConflict     29 /* jump, synopsis: key=r[P3@P4]               */
-
#define OP_NotFound       30 /* jump, synopsis: key=r[P3@P4]               */
-
#define OP_Found          31 /* jump, synopsis: key=r[P3@P4]               */
-
#define OP_SeekRowid      32 /* jump, synopsis: intkey=r[P3]               */
-
#define OP_NotExists      33 /* jump, synopsis: intkey=r[P3]               */
-
#define OP_Last           34 /* jump                                       */
-
#define OP_IfSmaller      35 /* jump                                       */
-
#define OP_SorterSort     36 /* jump                                       */
-
#define OP_Sort           37 /* jump                                       */
-
#define OP_Rewind         38 /* jump                                       */
+
#define OP_SeekLT         20 /* jump, synopsis: key=r[P3@P4]               */
+
#define OP_SeekLE         21 /* jump, synopsis: key=r[P3@P4]               */
+
#define OP_SeekGE         22 /* jump, synopsis: key=r[P3@P4]               */
+
#define OP_SeekGT         23 /* jump, synopsis: key=r[P3@P4]               */
+
#define OP_IfNotOpen      24 /* jump, synopsis: if( !csr[P1] ) goto P2     */
+
#define OP_IfNoHope       25 /* jump, synopsis: key=r[P3@P4]               */
+
#define OP_NoConflict     26 /* jump, synopsis: key=r[P3@P4]               */
+
#define OP_NotFound       27 /* jump, synopsis: key=r[P3@P4]               */
+
#define OP_Found          28 /* jump, synopsis: key=r[P3@P4]               */
+
#define OP_SeekRowid      29 /* jump, synopsis: intkey=r[P3]               */
+
#define OP_NotExists      30 /* jump, synopsis: intkey=r[P3]               */
+
#define OP_Last           31 /* jump                                       */
+
#define OP_IfSmaller      32 /* jump                                       */
+
#define OP_SorterSort     33 /* jump                                       */
+
#define OP_Sort           34 /* jump                                       */
+
#define OP_Rewind         35 /* jump                                       */
+
#define OP_SorterNext     36 /* jump                                       */
+
#define OP_Prev           37 /* jump                                       */
+
#define OP_Next           38 /* jump                                       */
#define OP_IdxLE          39 /* jump, synopsis: key=r[P3@P4]               */
#define OP_IdxGT          40 /* jump, synopsis: key=r[P3@P4]               */
#define OP_IdxLT          41 /* jump, synopsis: key=r[P3@P4]               */
@@ -15580,34 +15621,34 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Integer        71 /* synopsis: r[P2]=P1                         */
#define OP_Int64          72 /* synopsis: r[P2]=P4                         */
#define OP_String         73 /* synopsis: r[P2]='P4' (len=P1)              */
-
#define OP_Null           74 /* synopsis: r[P2..P3]=NULL                   */
-
#define OP_SoftNull       75 /* synopsis: r[P1]=NULL                       */
-
#define OP_Blob           76 /* synopsis: r[P2]=P4 (len=P1)                */
-
#define OP_Variable       77 /* synopsis: r[P2]=parameter(P1,P4)           */
-
#define OP_Move           78 /* synopsis: r[P2@P3]=r[P1@P3]                */
-
#define OP_Copy           79 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
-
#define OP_SCopy          80 /* synopsis: r[P2]=r[P1]                      */
-
#define OP_IntCopy        81 /* synopsis: r[P2]=r[P1]                      */
-
#define OP_FkCheck        82
-
#define OP_ResultRow      83 /* synopsis: output=r[P1@P2]                  */
-
#define OP_CollSeq        84
-
#define OP_AddImm         85 /* synopsis: r[P1]=r[P1]+P2                   */
-
#define OP_RealAffinity   86
-
#define OP_Cast           87 /* synopsis: affinity(r[P1])                  */
-
#define OP_Permutation    88
-
#define OP_Compare        89 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
-
#define OP_IsTrue         90 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
-
#define OP_ZeroOrNull     91 /* synopsis: r[P2] = 0 OR NULL                */
-
#define OP_Offset         92 /* synopsis: r[P3] = sqlite_offset(P1)        */
-
#define OP_Column         93 /* synopsis: r[P3]=PX                         */
-
#define OP_TypeCheck      94 /* synopsis: typecheck(r[P1@P2])              */
-
#define OP_Affinity       95 /* synopsis: affinity(r[P1@P2])               */
-
#define OP_MakeRecord     96 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
-
#define OP_Count          97 /* synopsis: r[P2]=count()                    */
-
#define OP_ReadCookie     98
-
#define OP_SetCookie      99
-
#define OP_ReopenIdx     100 /* synopsis: root=P2 iDb=P3                   */
-
#define OP_OpenRead      101 /* synopsis: root=P2 iDb=P3                   */
+
#define OP_BeginSubrtn    74 /* synopsis: r[P2]=NULL                       */
+
#define OP_Null           75 /* synopsis: r[P2..P3]=NULL                   */
+
#define OP_SoftNull       76 /* synopsis: r[P1]=NULL                       */
+
#define OP_Blob           77 /* synopsis: r[P2]=P4 (len=P1)                */
+
#define OP_Variable       78 /* synopsis: r[P2]=parameter(P1,P4)           */
+
#define OP_Move           79 /* synopsis: r[P2@P3]=r[P1@P3]                */
+
#define OP_Copy           80 /* synopsis: r[P2@P3+1]=r[P1@P3+1]            */
+
#define OP_SCopy          81 /* synopsis: r[P2]=r[P1]                      */
+
#define OP_IntCopy        82 /* synopsis: r[P2]=r[P1]                      */
+
#define OP_FkCheck        83
+
#define OP_ResultRow      84 /* synopsis: output=r[P1@P2]                  */
+
#define OP_CollSeq        85
+
#define OP_AddImm         86 /* synopsis: r[P1]=r[P1]+P2                   */
+
#define OP_RealAffinity   87
+
#define OP_Cast           88 /* synopsis: affinity(r[P1])                  */
+
#define OP_Permutation    89
+
#define OP_Compare        90 /* synopsis: r[P1@P3] <-> r[P2@P3]            */
+
#define OP_IsTrue         91 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
+
#define OP_ZeroOrNull     92 /* synopsis: r[P2] = 0 OR NULL                */
+
#define OP_Offset         93 /* synopsis: r[P3] = sqlite_offset(P1)        */
+
#define OP_Column         94 /* synopsis: r[P3]=PX cursor P1 column P2     */
+
#define OP_TypeCheck      95 /* synopsis: typecheck(r[P1@P2])              */
+
#define OP_Affinity       96 /* synopsis: affinity(r[P1@P2])               */
+
#define OP_MakeRecord     97 /* synopsis: r[P3]=mkrec(r[P1@P2])            */
+
#define OP_Count          98 /* synopsis: r[P2]=count()                    */
+
#define OP_ReadCookie     99
+
#define OP_SetCookie     100
+
#define OP_ReopenIdx     101 /* synopsis: root=P2 iDb=P3                   */
#define OP_BitAnd        102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
#define OP_BitOr         103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
#define OP_ShiftLeft     104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
@@ -15618,79 +15659,81 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Divide        109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
#define OP_Remainder     110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
#define OP_Concat        111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-
#define OP_OpenWrite     112 /* synopsis: root=P2 iDb=P3                   */
-
#define OP_OpenDup       113
+
#define OP_OpenRead      112 /* synopsis: root=P2 iDb=P3                   */
+
#define OP_OpenWrite     113 /* synopsis: root=P2 iDb=P3                   */
#define OP_BitNot        114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
-
#define OP_OpenAutoindex 115 /* synopsis: nColumn=P2                       */
-
#define OP_OpenEphemeral 116 /* synopsis: nColumn=P2                       */
+
#define OP_OpenDup       115
+
#define OP_OpenAutoindex 116 /* synopsis: nColumn=P2                       */
#define OP_String8       117 /* same as TK_STRING, synopsis: r[P2]='P4'    */
-
#define OP_SorterOpen    118
-
#define OP_SequenceTest  119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
-
#define OP_OpenPseudo    120 /* synopsis: P3 columns in r[P2]              */
-
#define OP_Close         121
-
#define OP_ColumnsUsed   122
-
#define OP_SeekScan      123 /* synopsis: Scan-ahead up to P1 rows         */
-
#define OP_SeekHit       124 /* synopsis: set P2<=seekHit<=P3              */
-
#define OP_Sequence      125 /* synopsis: r[P2]=cursor[P1].ctr++           */
-
#define OP_NewRowid      126 /* synopsis: r[P2]=rowid                      */
-
#define OP_Insert        127 /* synopsis: intkey=r[P3] data=r[P2]          */
-
#define OP_RowCell       128
-
#define OP_Delete        129
-
#define OP_ResetCount    130
-
#define OP_SorterCompare 131 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
-
#define OP_SorterData    132 /* synopsis: r[P2]=data                       */
-
#define OP_RowData       133 /* synopsis: r[P2]=data                       */
-
#define OP_Rowid         134 /* synopsis: r[P2]=rowid                      */
-
#define OP_NullRow       135
-
#define OP_SeekEnd       136
-
#define OP_IdxInsert     137 /* synopsis: key=r[P2]                        */
-
#define OP_SorterInsert  138 /* synopsis: key=r[P2]                        */
-
#define OP_IdxDelete     139 /* synopsis: key=r[P2@P3]                     */
-
#define OP_DeferredSeek  140 /* synopsis: Move P3 to P1.rowid if needed    */
-
#define OP_IdxRowid      141 /* synopsis: r[P2]=rowid                      */
-
#define OP_FinishSeek    142
-
#define OP_Destroy       143
-
#define OP_Clear         144
-
#define OP_ResetSorter   145
-
#define OP_CreateBtree   146 /* synopsis: r[P2]=root iDb=P1 flags=P3       */
-
#define OP_SqlExec       147
-
#define OP_ParseSchema   148
-
#define OP_LoadAnalysis  149
-
#define OP_DropTable     150
-
#define OP_DropIndex     151
-
#define OP_DropTrigger   152
+
#define OP_OpenEphemeral 118 /* synopsis: nColumn=P2                       */
+
#define OP_SorterOpen    119
+
#define OP_SequenceTest  120 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
+
#define OP_OpenPseudo    121 /* synopsis: P3 columns in r[P2]              */
+
#define OP_Close         122
+
#define OP_ColumnsUsed   123
+
#define OP_SeekScan      124 /* synopsis: Scan-ahead up to P1 rows         */
+
#define OP_SeekHit       125 /* synopsis: set P2<=seekHit<=P3              */
+
#define OP_Sequence      126 /* synopsis: r[P2]=cursor[P1].ctr++           */
+
#define OP_NewRowid      127 /* synopsis: r[P2]=rowid                      */
+
#define OP_Insert        128 /* synopsis: intkey=r[P3] data=r[P2]          */
+
#define OP_RowCell       129
+
#define OP_Delete        130
+
#define OP_ResetCount    131
+
#define OP_SorterCompare 132 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+
#define OP_SorterData    133 /* synopsis: r[P2]=data                       */
+
#define OP_RowData       134 /* synopsis: r[P2]=data                       */
+
#define OP_Rowid         135 /* synopsis: r[P2]=PX rowid of P1             */
+
#define OP_NullRow       136
+
#define OP_SeekEnd       137
+
#define OP_IdxInsert     138 /* synopsis: key=r[P2]                        */
+
#define OP_SorterInsert  139 /* synopsis: key=r[P2]                        */
+
#define OP_IdxDelete     140 /* synopsis: key=r[P2@P3]                     */
+
#define OP_DeferredSeek  141 /* synopsis: Move P3 to P1.rowid if needed    */
+
#define OP_IdxRowid      142 /* synopsis: r[P2]=rowid                      */
+
#define OP_FinishSeek    143
+
#define OP_Destroy       144
+
#define OP_Clear         145
+
#define OP_ResetSorter   146
+
#define OP_CreateBtree   147 /* synopsis: r[P2]=root iDb=P1 flags=P3       */
+
#define OP_SqlExec       148
+
#define OP_ParseSchema   149
+
#define OP_LoadAnalysis  150
+
#define OP_DropTable     151
+
#define OP_DropIndex     152
#define OP_Real          153 /* same as TK_FLOAT, synopsis: r[P2]=P4       */
-
#define OP_IntegrityCk   154
-
#define OP_RowSetAdd     155 /* synopsis: rowset(P1)=r[P2]                 */
-
#define OP_Param         156
-
#define OP_FkCounter     157 /* synopsis: fkctr[P1]+=P2                    */
-
#define OP_MemMax        158 /* synopsis: r[P1]=max(r[P1],r[P2])           */
-
#define OP_OffsetLimit   159 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
-
#define OP_AggInverse    160 /* synopsis: accum=r[P3] inverse(r[P2@P5])    */
-
#define OP_AggStep       161 /* synopsis: accum=r[P3] step(r[P2@P5])       */
-
#define OP_AggStep1      162 /* synopsis: accum=r[P3] step(r[P2@P5])       */
-
#define OP_AggValue      163 /* synopsis: r[P3]=value N=P2                 */
-
#define OP_AggFinal      164 /* synopsis: accum=r[P1] N=P2                 */
-
#define OP_Expire        165
-
#define OP_CursorLock    166
-
#define OP_CursorUnlock  167
-
#define OP_TableLock     168 /* synopsis: iDb=P1 root=P2 write=P3          */
-
#define OP_VBegin        169
-
#define OP_VCreate       170
-
#define OP_VDestroy      171
-
#define OP_VOpen         172
-
#define OP_VInitIn       173 /* synopsis: r[P2]=ValueList(P1,P3)           */
-
#define OP_VColumn       174 /* synopsis: r[P3]=vcolumn(P2)                */
-
#define OP_VRename       175
-
#define OP_Pagecount     176
-
#define OP_MaxPgcnt      177
-
#define OP_FilterAdd     178 /* synopsis: filter(P1) += key(P3@P4)         */
-
#define OP_Trace         179
-
#define OP_CursorHint    180
-
#define OP_ReleaseReg    181 /* synopsis: release r[P1@P2] mask P3         */
-
#define OP_Noop          182
-
#define OP_Explain       183
-
#define OP_Abortable     184
+
#define OP_DropTrigger   154
+
#define OP_IntegrityCk   155
+
#define OP_RowSetAdd     156 /* synopsis: rowset(P1)=r[P2]                 */
+
#define OP_Param         157
+
#define OP_FkCounter     158 /* synopsis: fkctr[P1]+=P2                    */
+
#define OP_MemMax        159 /* synopsis: r[P1]=max(r[P1],r[P2])           */
+
#define OP_OffsetLimit   160 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
+
#define OP_AggInverse    161 /* synopsis: accum=r[P3] inverse(r[P2@P5])    */
+
#define OP_AggStep       162 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+
#define OP_AggStep1      163 /* synopsis: accum=r[P3] step(r[P2@P5])       */
+
#define OP_AggValue      164 /* synopsis: r[P3]=value N=P2                 */
+
#define OP_AggFinal      165 /* synopsis: accum=r[P1] N=P2                 */
+
#define OP_Expire        166
+
#define OP_CursorLock    167
+
#define OP_CursorUnlock  168
+
#define OP_TableLock     169 /* synopsis: iDb=P1 root=P2 write=P3          */
+
#define OP_VBegin        170
+
#define OP_VCreate       171
+
#define OP_VDestroy      172
+
#define OP_VOpen         173
+
#define OP_VInitIn       174 /* synopsis: r[P2]=ValueList(P1,P3)           */
+
#define OP_VColumn       175 /* synopsis: r[P3]=vcolumn(P2)                */
+
#define OP_VRename       176
+
#define OP_Pagecount     177
+
#define OP_MaxPgcnt      178
+
#define OP_ClrSubtype    179 /* synopsis: r[P1].subtype = 0                */
+
#define OP_FilterAdd     180 /* synopsis: filter(P1) += key(P3@P4)         */
+
#define OP_Trace         181
+
#define OP_CursorHint    182
+
#define OP_ReleaseReg    183 /* synopsis: release r[P1@P2] mask P3         */
+
#define OP_Noop          184
+
#define OP_Explain       185
+
#define OP_Abortable     186

/* Properties such as "out2" or "jump" that are specified in
** comments following the "case" for each opcode in the vdbe.c
@@ -15703,30 +15746,30 @@ typedef struct VdbeOpList VdbeOpList;
#define OPFLG_OUT2        0x10  /* out2:  P2 is an output */
#define OPFLG_OUT3        0x20  /* out3:  P3 is an output */
#define OPFLG_INITIALIZER {\
-
/*   0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\
-
/*   8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\
-
/*  16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x03, 0x01, 0x09,\
-
/*  24 */ 0x09, 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09,\
-
/*  32 */ 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
+
/*   0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\
+
/*   8 */ 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01, 0x03,\
+
/*  16 */ 0x03, 0x03, 0x01, 0x12, 0x09, 0x09, 0x09, 0x09,\
+
/*  24 */ 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x01,\
+
/*  32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
/*  40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
/*  48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
/*  56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
/*  64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
-
/*  72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\
-
/*  80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\
-
/*  88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\
-
/*  96 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\
+
/*  72 */ 0x10, 0x10, 0x00, 0x10, 0x00, 0x10, 0x10, 0x00,\
+
/*  80 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02,\
+
/*  88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00,\
+
/*  96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x26, 0x26,\
/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
/* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\
-
/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
-
/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
-
/* 136 */ 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10,\
-
/* 144 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
-
/* 152 */ 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a,\
-
/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-
/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\
-
/* 176 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-
/* 184 */ 0x00,}
+
/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
+
/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
+
/* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\
+
/* 144 */ 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\
+
/* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\
+
/* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+
/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
+
/* 176 */ 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00,\
+
/* 184 */ 0x00, 0x00, 0x00,}

/* The resolve3P2Values() routine is able to run faster if it knows
** the value of the largest JUMP opcode.  The smaller the maximum
@@ -15772,8 +15815,10 @@ SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p);
#endif
#if defined(SQLITE_DEBUG)
SQLITE_PRIVATE   void sqlite3VdbeVerifyAbortable(Vdbe *p, int);
+
SQLITE_PRIVATE   void sqlite3VdbeNoJumpsOutsideSubrtn(Vdbe*,int,int,int);
#else
# define sqlite3VdbeVerifyAbortable(A,B)
+
# define sqlite3VdbeNoJumpsOutsideSubrtn(A,B,C,D)
#endif
SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno);
#ifndef SQLITE_OMIT_EXPLAIN
@@ -15818,7 +15863,6 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*);
SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*);
-
SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*);
SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*);
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int);
@@ -16267,6 +16311,13 @@ SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache);
# define SQLITE_MAX_PATHLEN FILENAME_MAX
#endif

+
/* Maximum number of symlinks that will be resolved while trying to
+
** expand a filename in xFullPathname() in the VFS.
+
*/
+
#ifndef SQLITE_MAX_SYMLINK
+
# define SQLITE_MAX_SYMLINK 200
+
#endif
+

/*
** The default size of a disk sector
*/
@@ -17033,6 +17084,9 @@ struct sqlite3 {
#define SQLITE_BloomFilter    0x00080000 /* Use a Bloom filter on searches */
#define SQLITE_BloomPulldown  0x00100000 /* Run Bloom filters early */
#define SQLITE_BalancedMerge  0x00200000 /* Balance multi-way merges */
+
#define SQLITE_ReleaseReg     0x00400000 /* Use OP_ReleaseReg for testing */
+
#define SQLITE_FlttnUnionAll  0x00800000 /* Disable the UNION ALL flattener */
+
   /* TH3 expects this value  ^^^^^^^^^^ See flatten04.test */
#define SQLITE_AllOpts        0xffffffff /* All optimizations */

/*
@@ -17135,7 +17189,7 @@ struct FuncDestructor {
#define SQLITE_FUNC_SLOCHNG  0x2000 /* "Slow Change". Value constant during a
                                    ** single query - might change over time */
#define SQLITE_FUNC_TEST     0x4000 /* Built-in testing functions */
-
#define SQLITE_FUNC_OFFSET   0x8000 /* Built-in sqlite_offset() function */
+
/*                           0x8000 -- available for reuse */
#define SQLITE_FUNC_WINDOW   0x00010000 /* Built-in window-only function */
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
#define SQLITE_FUNC_DIRECT   0x00080000 /* Not for use in TRIGGERs or VIEWs */
@@ -17152,6 +17206,7 @@ struct FuncDestructor {
#define INLINEFUNC_expr_compare         3
#define INLINEFUNC_affinity             4
#define INLINEFUNC_iif                  5
+
#define INLINEFUNC_sqlite_offset        6
#define INLINEFUNC_unlikely            99  /* Default case */

/*
@@ -17378,6 +17433,7 @@ struct Column {
#define COLFLAG_NOTAVAIL  0x0080   /* STORED column not yet calculated */
#define COLFLAG_BUSY      0x0100   /* Blocks recursion on GENERATED columns */
#define COLFLAG_HASCOLL   0x0200   /* Has collating sequence name in zCnName */
+
#define COLFLAG_NOEXPAND  0x0400   /* Omit this column when expanding "*" */
#define COLFLAG_GENERATED 0x0060   /* Combo: _STORED, _VIRTUAL */
#define COLFLAG_NOINSERT  0x0062   /* Combo: _HIDDEN, _STORED, _VIRTUAL */

@@ -17784,6 +17840,11 @@ struct KeyInfo {
struct UnpackedRecord {
  KeyInfo *pKeyInfo;  /* Collation and sort-order information */
  Mem *aMem;          /* Values */
+
  union {
+
    char *z;            /* Cache of aMem[0].z for vdbeRecordCompareString() */
+
    i64 i;              /* Cache of aMem[0].u.i for vdbeRecordCompareInt() */
+
  } u;
+
  int n;              /* Cache of aMem[0].n used by vdbeRecordCompareString() */
  u16 nField;         /* Number of entries in apMem[] */
  i8 default_rc;      /* Comparison result if keys are equal */
  u8 errCode;         /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
@@ -18092,7 +18153,7 @@ struct Expr {
                         ** TK_SELECT_COLUMN: column of the result vector */
  i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
  union {
-
    int iRightJoinTable;   /* If EP_FromJoin, the right table of the join */
+
    int iJoin;             /* If EP_OuterON or EP_InnerON, the right table */
    int iOfst;             /* else: start of token from start of statement */
  } w;
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
@@ -18113,29 +18174,29 @@ struct Expr {
**          EP_Agg == NC_HasAgg == SF_HasAgg
**          EP_Win == NC_HasWin
*/
-
#define EP_FromJoin   0x000001 /* Originates in ON/USING clause of outer join */
-
#define EP_Distinct   0x000002 /* Aggregate function with DISTINCT keyword */
-
#define EP_HasFunc    0x000004 /* Contains one or more functions of any kind */
-
#define EP_FixedCol   0x000008 /* TK_Column with a known fixed value */
+
#define EP_OuterON    0x000001 /* Originates in ON/USING clause of outer join */
+
#define EP_InnerON    0x000002 /* Originates in ON/USING of an inner join */
+
#define EP_Distinct   0x000004 /* Aggregate function with DISTINCT keyword */
+
#define EP_HasFunc    0x000008 /* Contains one or more functions of any kind */
#define EP_Agg        0x000010 /* Contains one or more aggregate functions */
-
#define EP_VarSelect  0x000020 /* pSelect is correlated, not constant */
-
#define EP_DblQuoted  0x000040 /* token.z was originally in "..." */
-
#define EP_InfixFunc  0x000080 /* True for an infix function: LIKE, GLOB, etc */
-
#define EP_Collate    0x000100 /* Tree contains a TK_COLLATE operator */
-
#define EP_Commuted   0x000200 /* Comparison operator has been commuted */
-
#define EP_IntValue   0x000400 /* Integer value contained in u.iValue */
-
#define EP_xIsSelect  0x000800 /* x.pSelect is valid (otherwise x.pList is) */
-
#define EP_Skip       0x001000 /* Operator does not contribute to affinity */
-
#define EP_Reduced    0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
-
#define EP_TokenOnly  0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
+
#define EP_FixedCol   0x000020 /* TK_Column with a known fixed value */
+
#define EP_VarSelect  0x000040 /* pSelect is correlated, not constant */
+
#define EP_DblQuoted  0x000080 /* token.z was originally in "..." */
+
#define EP_InfixFunc  0x000100 /* True for an infix function: LIKE, GLOB, etc */
+
#define EP_Collate    0x000200 /* Tree contains a TK_COLLATE operator */
+
#define EP_Commuted   0x000400 /* Comparison operator has been commuted */
+
#define EP_IntValue   0x000800 /* Integer value contained in u.iValue */
+
#define EP_xIsSelect  0x001000 /* x.pSelect is valid (otherwise x.pList is) */
+
#define EP_Skip       0x002000 /* Operator does not contribute to affinity */
+
#define EP_Reduced    0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
#define EP_Win        0x008000 /* Contains window functions */
-
#define EP_MemToken   0x010000 /* Need to sqlite3DbFree() Expr.zToken */
-
#define EP_IfNullRow  0x020000 /* The TK_IF_NULL_ROW opcode */
-
#define EP_Unlikely   0x040000 /* unlikely() or likelihood() function */
-
#define EP_ConstFunc  0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
-
#define EP_CanBeNull  0x100000 /* Can be null despite NOT NULL constraint */
-
#define EP_Subquery   0x200000 /* Tree contains a TK_SELECT operator */
-
                 /*   0x400000 // Available */
+
#define EP_TokenOnly  0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
+
#define EP_MemToken   0x020000 /* Need to sqlite3DbFree() Expr.zToken */
+
#define EP_IfNullRow  0x040000 /* The TK_IF_NULL_ROW opcode */
+
#define EP_Unlikely   0x080000 /* unlikely() or likelihood() function */
+
#define EP_ConstFunc  0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
+
#define EP_CanBeNull  0x200000 /* Can be null despite NOT NULL constraint */
+
#define EP_Subquery   0x400000 /* Tree contains a TK_SELECT operator */
#define EP_Leaf       0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
#define EP_WinFunc   0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
#define EP_Subrtn    0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
@@ -18158,8 +18219,8 @@ struct Expr {
#define ExprHasAllProperty(E,P)  (((E)->flags&(P))==(P))
#define ExprSetProperty(E,P)     (E)->flags|=(P)
#define ExprClearProperty(E,P)   (E)->flags&=~(P)
-
#define ExprAlwaysTrue(E)   (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
-
#define ExprAlwaysFalse(E)  (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
+
#define ExprAlwaysTrue(E)   (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue)
+
#define ExprAlwaysFalse(E)  (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse)

/* Macros used to ensure that the correct members of unions are accessed
** in Expr.
@@ -18246,12 +18307,18 @@ struct ExprList {
  struct ExprList_item { /* For each expression in the list */
    Expr *pExpr;            /* The parse tree for this expression */
    char *zEName;           /* Token associated with this expression */
-
    u8 sortFlags;           /* Mask of KEYINFO_ORDER_* flags */
-
    unsigned eEName :2;     /* Meaning of zEName */
-
    unsigned done :1;       /* A flag to indicate when processing is finished */
-
    unsigned reusable :1;   /* Constant expression is reusable */
-
    unsigned bSorterRef :1; /* Defer evaluation until after sorting */
-
    unsigned bNulls: 1;     /* True if explicit "NULLS FIRST/LAST" */
+
    struct {
+
      u8 sortFlags;           /* Mask of KEYINFO_ORDER_* flags */
+
      unsigned eEName :2;     /* Meaning of zEName */
+
      unsigned done :1;       /* Indicates when processing is finished */
+
      unsigned reusable :1;   /* Constant expression is reusable */
+
      unsigned bSorterRef :1; /* Defer evaluation until after sorting */
+
      unsigned bNulls :1;     /* True if explicit "NULLS FIRST/LAST" */
+
      unsigned bUsed :1;      /* This column used in a SF_NestedFrom subquery */
+
      unsigned bUsingTerm:1;  /* Term from the USING clause of a NestedFrom */
+
      unsigned bNoExpand: 1;  /* Term is an auxiliary in NestedFrom and should
+
                              ** not be expanded by "*" in parent queries */
+
    } fg;
    union {
      struct {             /* Used by any ExprList other than Parse.pConsExpr */
        u16 iOrderByCol;      /* For ORDER BY, column number in result set */
@@ -18286,14 +18353,26 @@ struct ExprList {
** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
*/
struct IdList {
+
  int nId;         /* Number of identifiers on the list */
+
  u8 eU4;          /* Which element of a.u4 is valid */
  struct IdList_item {
    char *zName;      /* Name of the identifier */
-
    int idx;          /* Index in some Table.aCol[] of a column named zName */
-
  } *a;
-
  int nId;         /* Number of identifiers on the list */
+
    union {
+
      int idx;          /* Index in some Table.aCol[] of a column named zName */
+
      Expr *pExpr;      /* Expr to implement a USING variable -- NOT USED */
+
    } u4;
+
  } a[1];
};

/*
+
** Allowed values for IdList.eType, which determines which value of the a.u4
+
** is valid.
+
*/
+
#define EU4_NONE   0   /* Does not use IdList.a.u4 */
+
#define EU4_IDX    1   /* Uses IdList.a.u4.idx */
+
#define EU4_EXPR   2   /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */
+

+
/*
** The SrcItem object represents a single term in the FROM clause of a query.
** The SrcList object is mostly an array of SrcItems.
**
@@ -18320,15 +18399,22 @@ struct SrcItem {
    unsigned isIndexedBy :1;   /* True if there is an INDEXED BY clause */
    unsigned isTabFunc :1;     /* True if table-valued-function syntax */
    unsigned isCorrelated :1;  /* True if sub-query is correlated */
+
    unsigned isMaterialized:1; /* This is a materialized view */
    unsigned viaCoroutine :1;  /* Implemented as a co-routine */
    unsigned isRecursive :1;   /* True for recursive reference in WITH */
    unsigned fromDDL :1;       /* Comes from sqlite_schema */
    unsigned isCte :1;         /* This is a CTE */
    unsigned notCte :1;        /* This item may not match a CTE */
+
    unsigned isUsing :1;       /* u3.pUsing is valid */
+
    unsigned isOn :1;          /* u3.pOn was once valid and non-NULL */
+
    unsigned isSynthUsing :1;  /* u3.pUsing is synthensized from NATURAL */
+
    unsigned isNestedFrom :1;  /* pSelect is a SF_NestedFrom subquery */
  } fg;
  int iCursor;      /* The VDBE cursor number used to access this table */
-
  Expr *pOn;        /* The ON clause of a join */
-
  IdList *pUsing;   /* The USING clause of a join */
+
  union {
+
    Expr *pOn;        /* fg.isUsing==0 =>  The ON clause of a join */
+
    IdList *pUsing;   /* fg.isUsing==1 =>  The USING clause of a join */
+
  } u3;
  Bitmask colUsed;  /* Bit N (1<<N) set if column N of pTab is used */
  union {
    char *zIndexedBy;    /* Identifier from "INDEXED BY <zIndex>" clause */
@@ -18341,6 +18427,15 @@ struct SrcItem {
};

/*
+
** The OnOrUsing object represents either an ON clause or a USING clause.
+
** It can never be both at the same time, but it can be neither.
+
*/
+
struct OnOrUsing {
+
  Expr *pOn;         /* The ON clause of a join */
+
  IdList *pUsing;    /* The USING clause of a join */
+
};
+

+
/*
** The following structure describes the FROM clause of a SELECT statement.
** Each table or subquery in the FROM clause is a separate element of
** the SrcList.a[] array.
@@ -18368,14 +18463,15 @@ struct SrcList {
/*
** Permitted values of the SrcList.a.jointype field
*/
-
#define JT_INNER     0x0001    /* Any kind of inner or cross join */
-
#define JT_CROSS     0x0002    /* Explicit use of the CROSS keyword */
-
#define JT_NATURAL   0x0004    /* True for a "natural" join */
-
#define JT_LEFT      0x0008    /* Left outer join */
-
#define JT_RIGHT     0x0010    /* Right outer join */
-
#define JT_OUTER     0x0020    /* The "OUTER" keyword is present */
-
#define JT_ERROR     0x0040    /* unknown or unsupported join type */
-

+
#define JT_INNER     0x01    /* Any kind of inner or cross join */
+
#define JT_CROSS     0x02    /* Explicit use of the CROSS keyword */
+
#define JT_NATURAL   0x04    /* True for a "natural" join */
+
#define JT_LEFT      0x08    /* Left outer join */
+
#define JT_RIGHT     0x10    /* Right outer join */
+
#define JT_OUTER     0x20    /* The "OUTER" keyword is present */
+
#define JT_LTORJ     0x40    /* One of the LEFT operands of a RIGHT JOIN
+
                             ** Mnemonic: Left Table Of Right Join */
+
#define JT_ERROR     0x80    /* unknown or unsupported join type */

/*
** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin()
@@ -18398,7 +18494,7 @@ struct SrcList {
#define WHERE_SORTBYGROUP      0x0200 /* Support sqlite3WhereIsSorted() */
#define WHERE_AGG_DISTINCT     0x0400 /* Query is "SELECT agg(DISTINCT ...)" */
#define WHERE_ORDERBY_LIMIT    0x0800 /* ORDERBY+LIMIT on the inner loop */
-
                        /*     0x1000    not currently used */
+
#define WHERE_RIGHT_JOIN       0x1000 /* Processing a RIGHT JOIN */
                        /*     0x2000    not currently used */
#define WHERE_USE_LIMIT        0x4000 /* Use the LIMIT in cost estimates */
                        /*     0x8000    not currently used */
@@ -18594,6 +18690,9 @@ struct Select {
#define SF_CopyCte       0x4000000 /* SELECT statement is a copy of a CTE */
#define SF_OrderByReqd   0x8000000 /* The ORDER BY clause may not be omitted */

+
/* True if S exists and has SF_NestedFrom */
+
#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
+

/*
** The results of a SELECT can be distributed in several ways, as defined
** by one of the following macros.  The "SRT" prefix means "SELECT Result
@@ -18805,6 +18904,7 @@ struct Parse {
  u8 okConstFactor;    /* OK to factor out constants */
  u8 disableLookaside; /* Number of times lookaside has been disabled */
  u8 disableVtab;      /* Disable all virtual tables for this parse */
+
  u8 withinRJSubrtn;   /* Nesting level for RIGHT JOIN body subroutines */
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
  u8 earlyCleanup;     /* OOM inside sqlite3ParserAddCleanup() */
#endif
@@ -18977,20 +19077,20 @@ struct AuthContext {
#define OPFLAG_PREFORMAT     0x80    /* OP_Insert uses preformatted cell */

/*
-
 * Each trigger present in the database schema is stored as an instance of
-
 * struct Trigger.
-
 *
-
 * Pointers to instances of struct Trigger are stored in two ways.
-
 * 1. In the "trigHash" hash table (part of the sqlite3* that represents the
-
 *    database). This allows Trigger structures to be retrieved by name.
-
 * 2. All triggers associated with a single table form a linked list, using the
-
 *    pNext member of struct Trigger. A pointer to the first element of the
-
 *    linked list is stored as the "pTrigger" member of the associated
-
 *    struct Table.
-
 *
-
 * The "step_list" member points to the first element of a linked list
-
 * containing the SQL statements specified as the trigger program.
-
 */
+
** Each trigger present in the database schema is stored as an instance of
+
** struct Trigger.
+
**
+
** Pointers to instances of struct Trigger are stored in two ways.
+
** 1. In the "trigHash" hash table (part of the sqlite3* that represents the
+
**    database). This allows Trigger structures to be retrieved by name.
+
** 2. All triggers associated with a single table form a linked list, using the
+
**    pNext member of struct Trigger. A pointer to the first element of the
+
**    linked list is stored as the "pTrigger" member of the associated
+
**    struct Table.
+
**
+
** The "step_list" member points to the first element of a linked list
+
** containing the SQL statements specified as the trigger program.
+
*/
struct Trigger {
  char *zName;            /* The name of the trigger                        */
  char *table;            /* The table or view to which the trigger applies */
@@ -19017,43 +19117,48 @@ struct Trigger {
#define TRIGGER_AFTER   2

/*
-
 * An instance of struct TriggerStep is used to store a single SQL statement
-
 * that is a part of a trigger-program.
-
 *
-
 * Instances of struct TriggerStep are stored in a singly linked list (linked
-
 * using the "pNext" member) referenced by the "step_list" member of the
-
 * associated struct Trigger instance. The first element of the linked list is
-
 * the first step of the trigger-program.
-
 *
-
 * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
-
 * "SELECT" statement. The meanings of the other members is determined by the
-
 * value of "op" as follows:
-
 *
-
 * (op == TK_INSERT)
-
 * orconf    -> stores the ON CONFLICT algorithm
-
 * pSelect   -> If this is an INSERT INTO ... SELECT ... statement, then
-
 *              this stores a pointer to the SELECT statement. Otherwise NULL.
-
 * zTarget   -> Dequoted name of the table to insert into.
-
 * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
-
 *              this stores values to be inserted. Otherwise NULL.
-
 * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ...
-
 *              statement, then this stores the column-names to be
-
 *              inserted into.
-
 *
-
 * (op == TK_DELETE)
-
 * zTarget   -> Dequoted name of the table to delete from.
-
 * pWhere    -> The WHERE clause of the DELETE statement if one is specified.
-
 *              Otherwise NULL.
-
 *
-
 * (op == TK_UPDATE)
-
 * zTarget   -> Dequoted name of the table to update.
-
 * pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
-
 *              Otherwise NULL.
-
 * pExprList -> A list of the columns to update and the expressions to update
-
 *              them to. See sqlite3Update() documentation of "pChanges"
-
 *              argument.
-
 *
-
 */
+
** An instance of struct TriggerStep is used to store a single SQL statement
+
** that is a part of a trigger-program.
+
**
+
** Instances of struct TriggerStep are stored in a singly linked list (linked
+
** using the "pNext" member) referenced by the "step_list" member of the
+
** associated struct Trigger instance. The first element of the linked list is
+
** the first step of the trigger-program.
+
**
+
** The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
+
** "SELECT" statement. The meanings of the other members is determined by the
+
** value of "op" as follows:
+
**
+
** (op == TK_INSERT)
+
** orconf    -> stores the ON CONFLICT algorithm
+
** pSelect   -> The content to be inserted - either a SELECT statement or
+
**              a VALUES clause.
+
** zTarget   -> Dequoted name of the table to insert into.
+
** pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ...
+
**              statement, then this stores the column-names to be
+
**              inserted into.
+
** pUpsert   -> The ON CONFLICT clauses for an Upsert
+
**
+
** (op == TK_DELETE)
+
** zTarget   -> Dequoted name of the table to delete from.
+
** pWhere    -> The WHERE clause of the DELETE statement if one is specified.
+
**              Otherwise NULL.
+
**
+
** (op == TK_UPDATE)
+
** zTarget   -> Dequoted name of the table to update.
+
** pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
+
**              Otherwise NULL.
+
** pExprList -> A list of the columns to update and the expressions to update
+
**              them to. See sqlite3Update() documentation of "pChanges"
+
**              argument.
+
**
+
** (op == TK_SELECT)
+
** pSelect   -> The SELECT statement
+
**
+
** (op == TK_RETURNING)
+
** pExprList -> The list of expressions that follow the RETURNING keyword.
+
**
+
*/
struct TriggerStep {
  u8 op;               /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT,
                       ** or TK_RETURNING */
@@ -19408,7 +19513,7 @@ struct Window {
  Window **ppThis;        /* Pointer to this object in Select.pWin list */
  Window *pNextWin;       /* Next window function belonging to this SELECT */
  Expr *pFilter;          /* The FILTER expression */
-
  FuncDef *pFunc;         /* The function */
+
  FuncDef *pWFunc;        /* The function */
  int iEphCsr;            /* Partition buffer or Peer buffer */
  int regAccum;           /* Accumulator */
  int regResult;          /* Interim result */
@@ -19663,18 +19768,53 @@ SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
#endif

#if defined(SQLITE_DEBUG)
+
SQLITE_PRIVATE   void sqlite3TreeViewLine(TreeView*, const char *zFormat, ...);
SQLITE_PRIVATE   void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
SQLITE_PRIVATE   void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*);
SQLITE_PRIVATE   void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
+
SQLITE_PRIVATE   void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*);
+
SQLITE_PRIVATE   void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*);
+
SQLITE_PRIVATE   void sqlite3TreeViewColumnList(TreeView*, const Column*, int, u8);
SQLITE_PRIVATE   void sqlite3TreeViewSrcList(TreeView*, const SrcList*);
SQLITE_PRIVATE   void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
SQLITE_PRIVATE   void sqlite3TreeViewWith(TreeView*, const With*, u8);
+
SQLITE_PRIVATE   void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8);
+
#if TREETRACE_ENABLED
+
SQLITE_PRIVATE   void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*,
+
                             const ExprList*,const Expr*, const Trigger*);
+
SQLITE_PRIVATE   void sqlite3TreeViewInsert(const With*, const SrcList*,
+
                             const IdList*, const Select*, const ExprList*,
+
                             int, const Upsert*, const Trigger*);
+
SQLITE_PRIVATE   void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*,
+
                             const Expr*, int, const ExprList*, const Expr*,
+
                             const Upsert*, const Trigger*);
+
#endif
+
#ifndef SQLITE_OMIT_TRIGGER
+
SQLITE_PRIVATE   void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8);
+
SQLITE_PRIVATE   void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8);
+
#endif
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE   void sqlite3TreeViewWindow(TreeView*, const Window*, u8);
SQLITE_PRIVATE   void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
#endif
+
SQLITE_PRIVATE   void sqlite3ShowExpr(const Expr*);
+
SQLITE_PRIVATE   void sqlite3ShowExprList(const ExprList*);
+
SQLITE_PRIVATE   void sqlite3ShowIdList(const IdList*);
+
SQLITE_PRIVATE   void sqlite3ShowSrcList(const SrcList*);
+
SQLITE_PRIVATE   void sqlite3ShowSelect(const Select*);
+
SQLITE_PRIVATE   void sqlite3ShowWith(const With*);
+
SQLITE_PRIVATE   void sqlite3ShowUpsert(const Upsert*);
+
#ifndef SQLITE_OMIT_TRIGGER
+
SQLITE_PRIVATE   void sqlite3ShowTriggerStep(const TriggerStep*);
+
SQLITE_PRIVATE   void sqlite3ShowTriggerStepList(const TriggerStep*);
+
SQLITE_PRIVATE   void sqlite3ShowTrigger(const Trigger*);
+
SQLITE_PRIVATE   void sqlite3ShowTriggerList(const Trigger*);
+
#endif
+
#ifndef SQLITE_OMIT_WINDOWFUNC
+
SQLITE_PRIVATE   void sqlite3ShowWindow(const Window*);
+
SQLITE_PRIVATE   void sqlite3ShowWinFunc(const Window*);
+
#endif
#endif
-


SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
@@ -19823,13 +19963,14 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*);
SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*,
-
                                      Token*, Select*, Expr*, IdList*);
+
                                      Token*, Select*, OnOrUsing*);
SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *);
SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*);
SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *);
-
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
+
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse*,SrcList*);
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
+
SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*);
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**);
SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
@@ -20027,7 +20168,8 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(Parse*, TriggerStep*);

SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*);
SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol);
-
SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int);
+
SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem*,int);
+
SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int,u32);
SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int);
#ifndef SQLITE_OMIT_AUTHORIZATION
@@ -20373,7 +20515,7 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *);
SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*);
#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
    && !defined(SQLITE_OMIT_VIRTUALTABLE)
-
SQLITE_PRIVATE   void sqlite3VtabWriteAll(sqlite3_index_info*);
+
SQLITE_PRIVATE   void sqlite3VtabUsesAllSchemas(sqlite3_index_info*);
#endif
SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
@@ -21121,9 +21263,6 @@ static const char * const sqlite3azCompileOpt[] = {
#ifdef SQLITE_ENABLE_RTREE
  "ENABLE_RTREE",
#endif
-
#ifdef SQLITE_ENABLE_SELECTTRACE
-
  "ENABLE_SELECTTRACE",
-
#endif
#ifdef SQLITE_ENABLE_SESSION
  "ENABLE_SESSION",
#endif
@@ -21145,6 +21284,9 @@ static const char * const sqlite3azCompileOpt[] = {
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  "ENABLE_STMT_SCANSTATUS",
#endif
+
#ifdef SQLITE_ENABLE_TREETRACE
+
  "ENABLE_TREETRACE",
+
#endif
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
  "ENABLE_UNKNOWN_SQL_FUNCTION",
#endif
@@ -21894,6 +22036,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
   0x7ffffffe,                /* iOnceResetThreshold */
   SQLITE_DEFAULT_SORTERREF_SIZE,   /* szSorterRef */
   0,                         /* iPrngSeed */
+
#ifdef SQLITE_DEBUG
+
   {0,0,0,0,0,0}              /* aTune */
+
#endif
};

/*
@@ -21948,7 +22093,7 @@ SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
/*
** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS.
*/
-
SQLITE_PRIVATE u32 sqlite3SelectTrace = 0;
+
SQLITE_PRIVATE u32 sqlite3TreeTrace = 0;
SQLITE_PRIVATE u32 sqlite3WhereTrace = 0;

/* #include "opcodes.h" */
@@ -22115,7 +22260,7 @@ struct VdbeCursor {
  Bool isEphemeral:1;     /* True for an ephemeral table */
  Bool useRandomRowid:1;  /* Generate new record numbers semi-randomly */
  Bool isOrdered:1;       /* True if the table is not BTREE_UNORDERED */
-
  Bool hasBeenDuped:1;    /* This cursor was source or target of OP_OpenDup */
+
  Bool noReuse:1;         /* OpenEphemeral may not reuse this cursor */
  u16 seekHit;            /* See the OP_SeekHit and OP_IfNoHope opcodes */
  union {                 /* pBtx for isEphermeral.  pAltMap otherwise */
    Btree *pBtx;            /* Separate file holding temporary table */
@@ -22163,6 +22308,11 @@ struct VdbeCursor {
  u32 aType[1];           /* Type values record decode.  MUST BE LAST */
};

+
/* Return true if P is a null-only cursor
+
*/
+
#define IsNullCursor(P) \
+
  ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0)
+


/*
** A value for VdbeCursor.cacheStatus that means the cache is always invalid.
@@ -22237,16 +22387,16 @@ struct sqlite3_value {
    const char *zPType; /* Pointer type when MEM_Term|MEM_Subtype|MEM_Null */
    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
  } u;
+
  char *z;            /* String or BLOB value */
+
  int n;              /* Number of characters in string value, excluding '\0' */
  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
  u8  eSubtype;       /* Subtype for this value */
-
  int n;              /* Number of characters in string value, excluding '\0' */
-
  char *z;            /* String or BLOB value */
  /* ShallowCopy only needs to copy the information above */
-
  char *zMalloc;      /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
+
  sqlite3 *db;        /* The associated database connection */
  int szMalloc;       /* Size of the zMalloc allocation */
  u32 uTemp;          /* Transient storage for serial_type in OP_MakeRecord */
-
  sqlite3 *db;        /* The associated database connection */
+
  char *zMalloc;      /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
  void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
#ifdef SQLITE_DEBUG
  Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
@@ -22258,11 +22408,43 @@ struct sqlite3_value {
** Size of struct Mem not including the Mem.zMalloc member or anything that
** follows.
*/
-
#define MEMCELLSIZE offsetof(Mem,zMalloc)
+
#define MEMCELLSIZE offsetof(Mem,db)

-
/* One or more of the following flags are set to indicate the validOK
+
/* One or more of the following flags are set to indicate the
** representations of the value stored in the Mem struct.
**
+
**  *  MEM_Null                An SQL NULL value
+
**
+
**  *  MEM_Null|MEM_Zero       An SQL NULL with the virtual table
+
**                             UPDATE no-change flag set
+
**
+
**  *  MEM_Null|MEM_Term|      An SQL NULL, but also contains a
+
**        MEM_Subtype          pointer accessible using
+
**                             sqlite3_value_pointer().
+
**
+
**  *  MEM_Null|MEM_Cleared    Special SQL NULL that compares non-equal
+
**                             to other NULLs even using the IS operator.
+
**
+
**  *  MEM_Str                 A string, stored in Mem.z with
+
**                             length Mem.n.  Zero-terminated if
+
**                             MEM_Term is set.  This flag is
+
**                             incompatible with MEM_Blob and
+
**                             MEM_Null, but can appear with MEM_Int,
+
**                             MEM_Real, and MEM_IntReal.
+
**
+
**  *  MEM_Blob                A blob, stored in Mem.z length Mem.n.
+
**                             Incompatible with MEM_Str, MEM_Null,
+
**                             MEM_Int, MEM_Real, and MEM_IntReal.
+
**
+
**  *  MEM_Blob|MEM_Zero       A blob in Mem.z of length Mem.n plus
+
**                             MEM.u.i extra 0x00 bytes at the end.
+
**
+
**  *  MEM_Int                 Integer stored in Mem.u.i.
+
**
+
**  *  MEM_Real                Real stored in Mem.u.r.
+
**
+
**  *  MEM_IntReal             Real stored as an integer in Mem.u.i.
+
**
** If the MEM_Null flag is set, then the value is an SQL NULL value.
** For a pointer type created using sqlite3_bind_pointer() or
** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set.
@@ -22273,6 +22455,7 @@ struct sqlite3_value {
** set, then the string is nul terminated. The MEM_Int and MEM_Real
** flags may coexist with the MEM_Str flag.
*/
+
#define MEM_Undefined 0x0000   /* Value is undefined */
#define MEM_Null      0x0001   /* Value is NULL (or a pointer) */
#define MEM_Str       0x0002   /* Value is a string */
#define MEM_Int       0x0004   /* Value is an integer */
@@ -22280,28 +22463,24 @@ struct sqlite3_value {
#define MEM_Blob      0x0010   /* Value is a BLOB */
#define MEM_IntReal   0x0020   /* MEM_Int that stringifies like MEM_Real */
#define MEM_AffMask   0x003f   /* Mask of affinity bits */
+

+
/* Extra bits that modify the meanings of the core datatypes above
+
*/
#define MEM_FromBind  0x0040   /* Value originates from sqlite3_bind() */
-
#define MEM_Undefined 0x0080   /* Value is undefined */
+
 /*                   0x0080   // Available */
#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
-
#define MEM_TypeMask  0xc1bf   /* Mask of type bits */
-

+
#define MEM_Term      0x0200   /* String in Mem.z is zero terminated */
+
#define MEM_Zero      0x0400   /* Mem.i contains count of 0s appended to blob */
+
#define MEM_Subtype   0x0800   /* Mem.eSubtype is valid */
+
#define MEM_TypeMask  0x0dbf   /* Mask of type bits */

-
/* Whenever Mem contains a valid string or blob representation, one of
-
** the following flags must be set to determine the memory management
-
** policy for Mem.z.  The MEM_Term flag tells us whether or not the
-
** string is \000 or \u0000 terminated
+
/* Bits that determine the storage for Mem.z for a string or blob or
+
** aggregate accumulator.
*/
-
#define MEM_Term      0x0200   /* String in Mem.z is zero terminated */
-
#define MEM_Dyn       0x0400   /* Need to call Mem.xDel() on Mem.z */
-
#define MEM_Static    0x0800   /* Mem.z points to a static string */
-
#define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
-
#define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
-
#define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
-
#define MEM_Subtype   0x8000   /* Mem.eSubtype is valid */
-
#ifdef SQLITE_OMIT_INCRBLOB
-
  #undef MEM_Zero
-
  #define MEM_Zero 0x0000
-
#endif
+
#define MEM_Dyn       0x1000   /* Need to call Mem.xDel() on Mem.z */
+
#define MEM_Static    0x2000   /* Mem.z points to a static string */
+
#define MEM_Ephem     0x4000   /* Mem.z points to an ephemeral string */
+
#define MEM_Agg       0x8000   /* Mem.z points to an agg function context */

/* Return TRUE if Mem X contains dynamically allocated content - anything
** that needs to be deallocated to avoid a leak.
@@ -22323,11 +22502,15 @@ struct sqlite3_value {
    && (X)->n==0 && (X)->u.nZero==0)

/*
-
** Return true if a memory cell is not marked as invalid.  This macro
+
** Return true if a memory cell has been initialized and is valid.
** is for use inside assert() statements only.
+
**
+
** A Memory cell is initialized if at least one of the
+
** MEM_Null, MEM_Str, MEM_Int, MEM_Real, MEM_Blob, or MEM_IntReal bits
+
** is set.  It is "undefined" if all those bits are zero.
*/
#ifdef SQLITE_DEBUG
-
#define memIsValid(M)  ((M)->flags & MEM_Undefined)==0
+
#define memIsValid(M)  ((M)->flags & MEM_AffMask)!=0
#endif

/*
@@ -22365,6 +22548,7 @@ struct sqlite3_context {
  Vdbe *pVdbe;            /* The VM that owns this context */
  int iOp;                /* Instruction number of OP_Function */
  int isError;            /* Error code returned by the function. */
+
  u8 enc;                 /* Encoding to use for results */
  u8 skipFlag;            /* Skip accumulator loading if true */
  u8 argc;                /* Number of arguments */
  sqlite3_value *argv[1]; /* Argument set */
@@ -22413,7 +22597,6 @@ struct Vdbe {
  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
  Parse *pParse;          /* Parsing context used to create this Vdbe */
  ynVar nVar;             /* Number of entries in aVar[] */
-
  u32 iVdbeMagic;         /* Magic number defining state of the SQL statement */
  int nMem;               /* Number of memory locations currently allocated */
  int nCursor;            /* Number of slots in apCsr[] */
  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
@@ -22451,11 +22634,10 @@ struct Vdbe {
  u8 errorAction;         /* Recovery action to do in case of an error */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
  u8 prepFlags;           /* SQLITE_PREPARE_* flags */
-
  u8 doingRerun;          /* True if rerunning after an auto-reprepare */
+
  u8 eVdbeState;          /* On of the VDBE_*_STATE values */
  bft expired:2;          /* 1: recompile VM immediately  2: when convenient */
  bft explain:2;          /* True if EXPLAIN present on SQL command */
  bft changeCntOn:1;      /* True to update the change-counter */
-
  bft runOnlyOnce:1;      /* Automatically expire on reset */
  bft usesStmtJournal:1;  /* True if uses a statement journal */
  bft readOnly:1;         /* True for statements that do not write */
  bft bIsReader:1;        /* True for statements that read */
@@ -22482,13 +22664,12 @@ struct Vdbe {
};

/*
-
** The following are allowed values for Vdbe.magic
+
** The following are allowed values for Vdbe.eVdbeState
*/
-
#define VDBE_MAGIC_INIT     0x16bceaa5    /* Building a VDBE program */
-
#define VDBE_MAGIC_RUN      0x2df20da3    /* VDBE is ready to execute */
-
#define VDBE_MAGIC_HALT     0x319c2973    /* VDBE has completed execution */
-
#define VDBE_MAGIC_RESET    0x48fa9f76    /* Reset and ready to run again */
-
#define VDBE_MAGIC_DEAD     0x5606c3c8    /* The VDBE has been deallocated */
+
#define VDBE_INIT_STATE     0   /* Prepared statement under construction */
+
#define VDBE_READY_STATE    1   /* Ready to run but not yet started */
+
#define VDBE_RUN_STATE      2   /* Run in progress */
+
#define VDBE_HALT_STATE     3   /* Finished.  Need reset() or finalize() */

/*
** Structure used to store the context required by the
@@ -22529,18 +22710,31 @@ struct ValueList {
  sqlite3_value *pOut;     /* Register to hold each decoded output value */
};

+
/* Size of content associated with serial types that fit into a
+
** single-byte varint.
+
*/
+
#ifndef SQLITE_AMALGAMATION
+
SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[];
+
#endif
+

/*
** Function prototypes
*/
SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
+
SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe*,VdbeCursor*);
void sqliteVdbePopStack(Vdbe*,int);
+
SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p);
SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*);
-
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, u32*);
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8);
-
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
+
#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
+
SQLITE_PRIVATE   u64 sqlite3FloatSwap(u64 in);
+
# define swapMixedEndianFloat(X)  X = sqlite3FloatSwap(X)
+
#else
+
# define swapMixedEndianFloat(X)
+
#endif
SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int);

@@ -22598,6 +22792,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8);
SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemFromBtreeZeroOffset(BtCursor*,u32,Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
+
SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem*p);
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
#ifndef SQLITE_OMIT_WINDOWFUNC
SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*);
@@ -23000,8 +23195,7 @@ SQLITE_API int sqlite3_db_status(

      db->pnBytesFreed = &nByte;
      for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
-
        sqlite3VdbeClearObject(db, pVdbe);
-
        sqlite3DbFree(db, pVdbe);
+
        sqlite3VdbeDelete(pVdbe);
      }
      db->pnBytesFreed = 0;

@@ -26956,8 +27150,13 @@ static void *memsys5Realloc(void *pPrior, int nBytes){
*/
static int memsys5Roundup(int n){
  int iFullSz;
-
  if( n > 0x40000000 ) return 0;
-
  for(iFullSz=mem5.szAtom; iFullSz<n; iFullSz *= 2);
+
  if( n<=mem5.szAtom*2 ){
+
    if( n<=mem5.szAtom ) return mem5.szAtom;
+
    return mem5.szAtom*2;
+
  }
+
  if( n>0x40000000 ) return 0;
+
  for(iFullSz=mem5.szAtom*8; iFullSz<n; iFullSz *= 4);
+
  if( (iFullSz/2)>=n ) return iFullSz/2;
  return iFullSz;
}

@@ -30231,8 +30430,8 @@ SQLITE_API void sqlite3_str_vappendf(
      case etSQLESCAPE:           /* %q: Escape ' characters */
      case etSQLESCAPE2:          /* %Q: Escape ' and enclose in '...' */
      case etSQLESCAPE3: {        /* %w: Escape " characters */
-
        int i, j, k, n, isnull;
-
        int needQuote;
+
        i64 i, j, k, n;
+
        int needQuote, isnull;
        char ch;
        char q = ((xtype==etSQLESCAPE3)?'"':'\'');   /* Quote character */
        char *escarg;
@@ -30312,8 +30511,14 @@ SQLITE_API void sqlite3_str_vappendf(
          sqlite3_str_appendall(pAccum, pItem->zName);
        }else if( pItem->zAlias ){
          sqlite3_str_appendall(pAccum, pItem->zAlias);
-
        }else if( ALWAYS(pItem->pSelect) ){
-
          sqlite3_str_appendf(pAccum, "SUBQUERY %u", pItem->pSelect->selId);
+
        }else{
+
          Select *pSel = pItem->pSelect;
+
          assert( pSel!=0 );
+
          if( pSel->selFlags & SF_NestedFrom ){
+
            sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId);
+
          }else{
+
            sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId);
+
          }
        }
        length = width = 0;
        break;
@@ -30376,7 +30581,9 @@ SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3 *db, const char *z){
** as the error offset.
*/
SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){
-
  while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){
+
  while( pExpr
+
     && (ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) || pExpr->w.iOfst<=0)
+
  ){
    pExpr = pExpr->pLeft;
  }
  if( pExpr==0 ) return;
@@ -30836,40 +31043,44 @@ SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){
** Add a new subitem to the tree.  The moreToFollow flag indicates that this
** is not the last item in the tree.
*/
-
static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
+
static void sqlite3TreeViewPush(TreeView **pp, u8 moreToFollow){
+
  TreeView *p = *pp;
  if( p==0 ){
-
    p = sqlite3_malloc64( sizeof(*p) );
-
    if( p==0 ) return 0;
+
    *pp = p = sqlite3_malloc64( sizeof(*p) );
+
    if( p==0 ) return;
    memset(p, 0, sizeof(*p));
  }else{
    p->iLevel++;
  }
  assert( moreToFollow==0 || moreToFollow==1 );
-
  if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
-
  return p;
+
  if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
}

/*
** Finished with one layer of the tree
*/
-
static void sqlite3TreeViewPop(TreeView *p){
+
static void sqlite3TreeViewPop(TreeView **pp){
+
  TreeView *p = *pp;
  if( p==0 ) return;
  p->iLevel--;
-
  if( p->iLevel<0 ) sqlite3_free(p);
+
  if( p->iLevel<0 ){
+
    sqlite3_free(p);
+
    *pp = 0;
+
  }
}

/*
** Generate a single line of output for the tree, with a prefix that contains
** all the appropriate tree lines
*/
-
static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
+
SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
  va_list ap;
  int i;
  StrAccum acc;
-
  char zBuf[500];
+
  char zBuf[1000];
  sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
  if( p ){
-
    for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
+
    for(i=0; i<p->iLevel && i<(int)sizeof(p->bLine)-1; i++){
      sqlite3_str_append(&acc, p->bLine[i] ? "|   " : "    ", 4);
    }
    sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
@@ -30890,11 +31101,58 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
** Shorthand for starting a new tree item that consists of a single label
*/
static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){
-
  p = sqlite3TreeViewPush(p, moreFollows);
+
  sqlite3TreeViewPush(&p, moreFollows);
  sqlite3TreeViewLine(p, "%s", zLabel);
}

/*
+
** Show a list of Column objects in tree format.
+
*/
+
SQLITE_PRIVATE void sqlite3TreeViewColumnList(
+
  TreeView *pView,
+
  const Column *aCol,
+
  int nCol,
+
  u8 moreToFollow
+
){
+
  int i;
+
  sqlite3TreeViewPush(&pView, moreToFollow);
+
  sqlite3TreeViewLine(pView, "COLUMNS");
+
  for(i=0; i<nCol; i++){
+
    u16 flg = aCol[i].colFlags;
+
    int colMoreToFollow = i<(nCol - 1);
+
    sqlite3TreeViewPush(&pView, colMoreToFollow);
+
    sqlite3TreeViewLine(pView, 0);
+
    printf(" %s", aCol[i].zCnName);
+
    switch( aCol[i].eCType ){
+
      case COLTYPE_ANY:      printf(" ANY");        break;
+
      case COLTYPE_BLOB:     printf(" BLOB");       break;
+
      case COLTYPE_INT:      printf(" INT");        break;
+
      case COLTYPE_INTEGER:  printf(" INTEGER");    break;
+
      case COLTYPE_REAL:     printf(" REAL");       break;
+
      case COLTYPE_TEXT:     printf(" TEXT");       break;
+
      case COLTYPE_CUSTOM: {
+
        if( flg & COLFLAG_HASTYPE ){
+
          const char *z = aCol[i].zCnName;
+
          z += strlen(z)+1;
+
          printf(" X-%s", z);
+
          break;
+
        }
+
      }
+
    }
+
    if( flg & COLFLAG_PRIMKEY ) printf(" PRIMARY KEY");
+
    if( flg & COLFLAG_HIDDEN ) printf(" HIDDEN");
+
#ifdef COLFLAG_NOEXPAND
+
    if( flg & COLFLAG_NOEXPAND ) printf(" NO-EXPAND");
+
#endif
+
    if( flg ) printf(" flags=%04x", flg);
+
    printf("\n");
+
    fflush(stdout);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  sqlite3TreeViewPop(&pView);
+
}
+

+
/*
** Generate a human-readable description of a WITH clause.
*/
SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){
@@ -30907,7 +31165,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
    sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith);
  }
  if( pWith->nCte>0 ){
-
    pView = sqlite3TreeViewPush(pView, 1);
+
    sqlite3TreeViewPush(&pView, moreToFollow);
    for(i=0; i<pWith->nCte; i++){
      StrAccum x;
      char zLine[1000];
@@ -30923,6 +31181,10 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
        }
        sqlite3_str_appendf(&x, ")");
      }
+
      if( pCte->eM10d!=M10d_Any ){
+
        sqlite3_str_appendf(&x, " %sMATERIALIZED",
+
           pCte->eM10d==M10d_No ? "NOT " : "");
+
      }
      if( pCte->pUse ){
        sqlite3_str_appendf(&x, " (pUse=0x%p, nUse=%d)", pCte->pUse,
                 pCte->pUse->nUse);
@@ -30930,9 +31192,9 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
      sqlite3StrAccumFinish(&x);
      sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
      sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
    }
-
    sqlite3TreeViewPop(pView);
+
    sqlite3TreeViewPop(&pView);
  }
}

@@ -30941,10 +31203,12 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m
*/
SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){
  int i;
+
  if( pSrc==0 ) return;
  for(i=0; i<pSrc->nSrc; i++){
    const SrcItem *pItem = &pSrc->a[i];
    StrAccum x;
-
    char zLine[100];
+
    int n = 0;
+
    char zLine[1000];
    sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
    x.printfFlags |= SQLITE_PRINTF_INTERNAL;
    sqlite3_str_appendf(&x, "{%d:*} %!S", pItem->iCursor, pItem);
@@ -30952,26 +31216,48 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc)
      sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx",
           pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed);
    }
-
    if( pItem->fg.jointype & JT_LEFT ){
+
    if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){
+
      sqlite3_str_appendf(&x, " FULL-OUTER-JOIN");
+
    }else if( pItem->fg.jointype & JT_LEFT ){
      sqlite3_str_appendf(&x, " LEFT-JOIN");
+
    }else if( pItem->fg.jointype & JT_RIGHT ){
+
      sqlite3_str_appendf(&x, " RIGHT-JOIN");
    }else if( pItem->fg.jointype & JT_CROSS ){
      sqlite3_str_appendf(&x, " CROSS-JOIN");
    }
+
    if( pItem->fg.jointype & JT_LTORJ ){
+
      sqlite3_str_appendf(&x, " LTORJ");
+
    }
    if( pItem->fg.fromDDL ){
      sqlite3_str_appendf(&x, " DDL");
    }
    if( pItem->fg.isCte ){
      sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);
    }
+
    if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){
+
      sqlite3_str_appendf(&x, " ON");
+
    }
    sqlite3StrAccumFinish(&x);
    sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
+
    n = 0;
+
    if( pItem->pSelect ) n++;
+
    if( pItem->fg.isTabFunc ) n++;
+
    if( pItem->fg.isUsing ) n++;
+
    if( pItem->fg.isUsing ){
+
      sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING");
+
    }
    if( pItem->pSelect ){
-
      sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
+
      if( pItem->pTab ){
+
        Table *pTab = pItem->pTab;
+
        sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1);
+
      }
+
      assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
+
      sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0);
    }
    if( pItem->fg.isTabFunc ){
      sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
    }
-
    sqlite3TreeViewPop(pView);
+
    sqlite3TreeViewPop(&pView);
  }
}

@@ -30985,11 +31271,11 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
    sqlite3TreeViewLine(pView, "nil-SELECT");
    return;
  }
-
  pView = sqlite3TreeViewPush(pView, moreToFollow);
+
  sqlite3TreeViewPush(&pView, moreToFollow);
  if( p->pWith ){
    sqlite3TreeViewWith(pView, p->pWith, 1);
    cnt = 1;
-
    sqlite3TreeViewPush(pView, 1);
+
    sqlite3TreeViewPush(&pView, 1);
  }
  do{
    if( p->selFlags & SF_WhereBegin ){
@@ -31003,7 +31289,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
        (int)p->nSelectRow
      );
    }
-
    if( cnt++ ) sqlite3TreeViewPop(pView);
+
    if( cnt++ ) sqlite3TreeViewPop(&pView);
    if( p->pPrior ){
      n = 1000;
    }else{
@@ -31026,24 +31312,24 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( p->pWin ){
      Window *pX;
-
      pView = sqlite3TreeViewPush(pView, (n--)>0);
+
      sqlite3TreeViewPush(&pView, (n--)>0);
      sqlite3TreeViewLine(pView, "window-functions");
      for(pX=p->pWin; pX; pX=pX->pNextWin){
        sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0);
      }
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
    }
#endif
    if( p->pSrc && p->pSrc->nSrc ){
-
      pView = sqlite3TreeViewPush(pView, (n--)>0);
+
      sqlite3TreeViewPush(&pView, (n--)>0);
      sqlite3TreeViewLine(pView, "FROM");
      sqlite3TreeViewSrcList(pView, p->pSrc);
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
    }
    if( p->pWhere ){
      sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
      sqlite3TreeViewExpr(pView, p->pWhere, 0);
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
    }
    if( p->pGroupBy ){
      sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
@@ -31051,7 +31337,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
    if( p->pHaving ){
      sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
      sqlite3TreeViewExpr(pView, p->pHaving, 0);
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
    }
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( p->pWinDefn ){
@@ -31060,7 +31346,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
      for(pX=p->pWinDefn; pX; pX=pX->pNextWin){
        sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0);
      }
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
    }
#endif
    if( p->pOrderBy ){
@@ -31072,9 +31358,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
      if( p->pLimit->pRight ){
        sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
        sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0);
-
        sqlite3TreeViewPop(pView);
+
        sqlite3TreeViewPop(&pView);
      }
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
    }
    if( p->pPrior ){
      const char *zOp = "UNION";
@@ -31087,7 +31373,7 @@ SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 m
    }
    p = p->pPrior;
  }while( p!=0 );
-
  sqlite3TreeViewPop(pView);
+
  sqlite3TreeViewPop(&pView);
}

#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -31103,24 +31389,24 @@ SQLITE_PRIVATE void sqlite3TreeViewBound(
  switch( eBound ){
    case TK_UNBOUNDED: {
      sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow);
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
      break;
    }
    case TK_CURRENT: {
      sqlite3TreeViewItem(pView, "CURRENT", moreToFollow);
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
      break;
    }
    case TK_PRECEDING: {
      sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow);
      sqlite3TreeViewExpr(pView, pExpr, 0);
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
      break;
    }
    case TK_FOLLOWING: {
      sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow);
      sqlite3TreeViewExpr(pView, pExpr, 0);
-
      sqlite3TreeViewPop(pView);
+
      sqlite3TreeViewPop(&pView);
      break;
    }
  }
@@ -31133,12 +31419,13 @@ SQLITE_PRIVATE void sqlite3TreeViewBound(
*/
SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
  int nElement = 0;
+
  if( pWin==0 ) return;
  if( pWin->pFilter ){
    sqlite3TreeViewItem(pView, "FILTER", 1);
    sqlite3TreeViewExpr(pView, pWin->pFilter, 0);
-
    sqlite3TreeViewPop(pView);
+
    sqlite3TreeViewPop(&pView);
  }
-
  pView = sqlite3TreeViewPush(pView, more);
+
  sqlite3TreeViewPush(&pView, more);
  if( pWin->zName ){
    sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin);
  }else{
@@ -31149,9 +31436,9 @@ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u
  if( pWin->eFrmType ) nElement++;
  if( pWin->eExclude ) nElement++;
  if( pWin->zBase ){
-
    sqlite3TreeViewPush(pView, (--nElement)>0);
+
    sqlite3TreeViewPush(&pView, (--nElement)>0);
    sqlite3TreeViewLine(pView, "window: %s", pWin->zBase);
-
    sqlite3TreeViewPop(pView);
+
    sqlite3TreeViewPop(&pView);
  }
  if( pWin->pPartition ){
    sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY");
@@ -31169,7 +31456,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u
    sqlite3TreeViewItem(pView, zBuf, (--nElement)>0);
    sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
    sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
-
    sqlite3TreeViewPop(pView);
+
    sqlite3TreeViewPop(&pView);
  }
  if( pWin->eExclude ){
    char zBuf[30];
@@ -31184,11 +31471,11 @@ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u
        zExclude = zBuf;
        break;
    }
-
    sqlite3TreeViewPush(pView, 0);
+
    sqlite3TreeViewPush(&pView, 0);
    sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude);
-
    sqlite3TreeViewPop(pView);
+
    sqlite3TreeViewPop(&pView);
  }
-
  sqlite3TreeViewPop(pView);
+
  sqlite3TreeViewPop(&pView);
}
#endif /* SQLITE_OMIT_WINDOWFUNC */

@@ -31197,11 +31484,12 @@ SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u
** Generate a human-readable explanation for a Window Function object
*/
SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){
-
  pView = sqlite3TreeViewPush(pView, more);
+
  if( pWin==0 ) return;
+
  sqlite3TreeViewPush(&pView, more);
  sqlite3TreeViewLine(pView, "WINFUNC %s(%d)",
-
                       pWin->pFunc->zName, pWin->pFunc->nArg);
+
                       pWin->pWFunc->zName, pWin->pWFunc->nArg);
  sqlite3TreeViewWindow(pView, pWin, 0);
-
  sqlite3TreeViewPop(pView);
+
  sqlite3TreeViewPop(&pView);
}
#endif /* SQLITE_OMIT_WINDOWFUNC */

@@ -31212,10 +31500,10 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
  const char *zBinOp = 0;   /* Binary operator */
  const char *zUniOp = 0;   /* Unary operator */
  char zFlgs[200];
-
  pView = sqlite3TreeViewPush(pView, moreToFollow);
+
  sqlite3TreeViewPush(&pView, moreToFollow);
  if( pExpr==0 ){
    sqlite3TreeViewLine(pView, "nil");
-
    sqlite3TreeViewPop(pView);
+
    sqlite3TreeViewPop(&pView);
    return;
  }
  if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
@@ -31223,8 +31511,11 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
    sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
    sqlite3_str_appendf(&x, " fg.af=%x.%c",
      pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
-
    if( ExprHasProperty(pExpr, EP_FromJoin) ){
-
      sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable);
+
    if( ExprHasProperty(pExpr, EP_OuterON) ){
+
      sqlite3_str_appendf(&x, " outer.iJoin=%d", pExpr->w.iJoin);
+
    }
+
    if( ExprHasProperty(pExpr, EP_InnerON) ){
+
      sqlite3_str_appendf(&x, " inner.iJoin=%d", pExpr->w.iJoin);
    }
    if( ExprHasProperty(pExpr, EP_FromDDL) ){
      sqlite3_str_appendf(&x, " DDL");
@@ -31448,7 +31739,17 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
      break;
    }
    case TK_IN: {
-
      sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags);
+
      sqlite3_str *pStr = sqlite3_str_new(0);
+
      char *z;
+
      sqlite3_str_appendf(pStr, "IN flags=0x%x", pExpr->flags);
+
      if( pExpr->iTable ) sqlite3_str_appendf(pStr, " iTable=%d",pExpr->iTable);
+
      if( ExprHasProperty(pExpr, EP_Subrtn) ){
+
        sqlite3_str_appendf(pStr, " subrtn(%d,%d)",
+
            pExpr->y.sub.regReturn, pExpr->y.sub.iAddr);
+
      }
+
      z = sqlite3_str_finish(pStr);
+
      sqlite3TreeViewLine(pView, z);
+
      sqlite3_free(z);
      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
      if( ExprUseXSelect(pExpr) ){
        sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
@@ -31572,7 +31873,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
    sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs);
   sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
  }
-
  sqlite3TreeViewPop(pView);
+
  sqlite3TreeViewPop(&pView);
}


@@ -31594,13 +31895,25 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
      int j = pList->a[i].u.x.iOrderByCol;
      char *zName = pList->a[i].zEName;
      int moreToFollow = i<pList->nExpr - 1;
-
      if( pList->a[i].eEName!=ENAME_NAME ) zName = 0;
      if( j || zName ){
-
        sqlite3TreeViewPush(pView, moreToFollow);
+
        sqlite3TreeViewPush(&pView, moreToFollow);
        moreToFollow = 0;
        sqlite3TreeViewLine(pView, 0);
        if( zName ){
-
          fprintf(stdout, "AS %s ", zName);
+
          switch( pList->a[i].fg.eEName ){
+
            default:
+
              fprintf(stdout, "AS %s ", zName);
+
              break;
+
            case ENAME_TAB:
+
              fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName);
+
              if( pList->a[i].fg.bUsed ) fprintf(stdout, "(used) ");
+
              if( pList->a[i].fg.bUsingTerm ) fprintf(stdout, "(USING-term) ");
+
              if( pList->a[i].fg.bNoExpand ) fprintf(stdout, "(NoExpand) ");
+
              break;
+
            case ENAME_SPAN:
+
              fprintf(stdout, "SPAN(\"%s\") ", zName);
+
              break;
+
          }
        }
        if( j ){
          fprintf(stdout, "iOrderByCol=%d", j);
@@ -31610,7 +31923,7 @@ SQLITE_PRIVATE void sqlite3TreeViewBareExprList(
      }
      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow);
      if( j || zName ){
-
        sqlite3TreeViewPop(pView);
+
        sqlite3TreeViewPop(&pView);
      }
    }
  }
@@ -31621,10 +31934,377 @@ SQLITE_PRIVATE void sqlite3TreeViewExprList(
  u8 moreToFollow,
  const char *zLabel
){
-
  pView = sqlite3TreeViewPush(pView, moreToFollow);
+
  sqlite3TreeViewPush(&pView, moreToFollow);
  sqlite3TreeViewBareExprList(pView, pList, zLabel);
-
  sqlite3TreeViewPop(pView);
+
  sqlite3TreeViewPop(&pView);
+
}
+

+
/*
+
** Generate a human-readable explanation of an id-list.
+
*/
+
SQLITE_PRIVATE void sqlite3TreeViewBareIdList(
+
  TreeView *pView,
+
  const IdList *pList,
+
  const char *zLabel
+
){
+
  if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
+
  if( pList==0 ){
+
    sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
+
  }else{
+
    int i;
+
    sqlite3TreeViewLine(pView, "%s", zLabel);
+
    for(i=0; i<pList->nId; i++){
+
      char *zName = pList->a[i].zName;
+
      int moreToFollow = i<pList->nId - 1;
+
      if( zName==0 ) zName = "(null)";
+
      sqlite3TreeViewPush(&pView, moreToFollow);
+
      sqlite3TreeViewLine(pView, 0);
+
      if( pList->eU4==EU4_NONE ){
+
        fprintf(stdout, "%s\n", zName);
+
      }else if( pList->eU4==EU4_IDX ){
+
        fprintf(stdout, "%s (%d)\n", zName, pList->a[i].u4.idx);
+
      }else{
+
        assert( pList->eU4==EU4_EXPR );
+
        if( pList->a[i].u4.pExpr==0 ){
+
          fprintf(stdout, "%s (pExpr=NULL)\n", zName);
+
        }else{
+
          fprintf(stdout, "%s\n", zName);
+
          sqlite3TreeViewPush(&pView, i<pList->nId-1);
+
          sqlite3TreeViewExpr(pView, pList->a[i].u4.pExpr, 0);
+
          sqlite3TreeViewPop(&pView);
+
        }
+
      }
+
      sqlite3TreeViewPop(&pView);
+
    }
+
  }
+
}
+
SQLITE_PRIVATE void sqlite3TreeViewIdList(
+
  TreeView *pView,
+
  const IdList *pList,
+
  u8 moreToFollow,
+
  const char *zLabel
+
){
+
  sqlite3TreeViewPush(&pView, moreToFollow);
+
  sqlite3TreeViewBareIdList(pView, pList, zLabel);
+
  sqlite3TreeViewPop(&pView);
+
}
+

+
/*
+
** Generate a human-readable explanation of a list of Upsert objects
+
*/
+
SQLITE_PRIVATE void sqlite3TreeViewUpsert(
+
  TreeView *pView,
+
  const Upsert *pUpsert,
+
  u8 moreToFollow
+
){
+
  if( pUpsert==0 ) return;
+
  sqlite3TreeViewPush(&pView, moreToFollow);
+
  while( pUpsert ){
+
    int n;
+
    sqlite3TreeViewPush(&pView, pUpsert->pNextUpsert!=0 || moreToFollow);
+
    sqlite3TreeViewLine(pView, "ON CONFLICT DO %s",
+
         pUpsert->isDoUpdate ? "UPDATE" : "NOTHING");
+
    n = (pUpsert->pUpsertSet!=0) + (pUpsert->pUpsertWhere!=0);
+
    sqlite3TreeViewExprList(pView, pUpsert->pUpsertTarget, (n--)>0, "TARGET");
+
    sqlite3TreeViewExprList(pView, pUpsert->pUpsertSet, (n--)>0, "SET");
+
    if( pUpsert->pUpsertWhere ){
+
      sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
+
      sqlite3TreeViewExpr(pView, pUpsert->pUpsertWhere, 0);
+
      sqlite3TreeViewPop(&pView);
+
    }
+
    sqlite3TreeViewPop(&pView);
+
    pUpsert = pUpsert->pNextUpsert;
+
  }
+
  sqlite3TreeViewPop(&pView);
+
}
+

+
#if TREETRACE_ENABLED
+
/*
+
** Generate a human-readable diagram of the data structure that go
+
** into generating an DELETE statement.
+
*/
+
SQLITE_PRIVATE void sqlite3TreeViewDelete(
+
  const With *pWith,
+
  const SrcList *pTabList,
+
  const Expr *pWhere,
+
  const ExprList *pOrderBy,
+
  const Expr *pLimit,
+
  const Trigger *pTrigger
+
){
+
  int n = 0;
+
  TreeView *pView = 0;
+
  sqlite3TreeViewPush(&pView, 0);
+
  sqlite3TreeViewLine(pView, "DELETE");
+
  if( pWith ) n++;
+
  if( pTabList ) n++;
+
  if( pWhere ) n++;
+
  if( pOrderBy ) n++;
+
  if( pLimit ) n++;
+
  if( pTrigger ) n++;
+
  if( pWith ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewWith(pView, pWith, 0);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pTabList ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewLine(pView, "FROM");
+
    sqlite3TreeViewSrcList(pView, pTabList);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pWhere ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewLine(pView, "WHERE");
+
    sqlite3TreeViewExpr(pView, pWhere, 0);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pOrderBy ){
+
    sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY");
+
  }
+
  if( pLimit ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewLine(pView, "LIMIT");
+
    sqlite3TreeViewExpr(pView, pLimit, 0);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pTrigger ){
+
    sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1);
+
  }
+
  sqlite3TreeViewPop(&pView);
+
}
+
#endif /* TREETRACE_ENABLED */
+

+
#if TREETRACE_ENABLED
+
/*
+
** Generate a human-readable diagram of the data structure that go
+
** into generating an INSERT statement.
+
*/
+
SQLITE_PRIVATE void sqlite3TreeViewInsert(
+
  const With *pWith,
+
  const SrcList *pTabList,
+
  const IdList *pColumnList,
+
  const Select *pSelect,
+
  const ExprList *pExprList,
+
  int onError,
+
  const Upsert *pUpsert,
+
  const Trigger *pTrigger
+
){
+
  TreeView *pView = 0;
+
  int n = 0;
+
  const char *zLabel = "INSERT";
+
  switch( onError ){
+
    case OE_Replace:  zLabel = "REPLACE";             break;
+
    case OE_Ignore:   zLabel = "INSERT OR IGNORE";    break;
+
    case OE_Rollback: zLabel = "INSERT OR ROLLBACK";  break;
+
    case OE_Abort:    zLabel = "INSERT OR ABORT";     break;
+
    case OE_Fail:     zLabel = "INSERT OR FAIL";      break;
+
  }
+
  sqlite3TreeViewPush(&pView, 0);
+
  sqlite3TreeViewLine(pView, zLabel);
+
  if( pWith ) n++;
+
  if( pTabList ) n++;
+
  if( pColumnList ) n++;
+
  if( pSelect ) n++;
+
  if( pExprList ) n++;
+
  if( pUpsert ) n++;
+
  if( pTrigger ) n++;
+
  if( pWith ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewWith(pView, pWith, 0);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pTabList ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewLine(pView, "INTO");
+
    sqlite3TreeViewSrcList(pView, pTabList);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pColumnList ){
+
    sqlite3TreeViewIdList(pView, pColumnList, (--n)>0, "COLUMNS");
+
  }
+
  if( pSelect ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewLine(pView, "DATA-SOURCE");
+
    sqlite3TreeViewSelect(pView, pSelect, 0);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pExprList ){
+
    sqlite3TreeViewExprList(pView, pExprList, (--n)>0, "VALUES");
+
  }
+
  if( pUpsert ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewLine(pView, "UPSERT");
+
    sqlite3TreeViewUpsert(pView, pUpsert, 0);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pTrigger ){
+
    sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1);
+
  }
+
  sqlite3TreeViewPop(&pView);
}
+
#endif /* TREETRACE_ENABLED */
+

+
#if TREETRACE_ENABLED
+
/*
+
** Generate a human-readable diagram of the data structure that go
+
** into generating an UPDATE statement.
+
*/
+
SQLITE_PRIVATE void sqlite3TreeViewUpdate(
+
  const With *pWith,
+
  const SrcList *pTabList,
+
  const ExprList *pChanges,
+
  const Expr *pWhere,
+
  int onError,
+
  const ExprList *pOrderBy,
+
  const Expr *pLimit,
+
  const Upsert *pUpsert,
+
  const Trigger *pTrigger
+
){
+
  int n = 0;
+
  TreeView *pView = 0;
+
  const char *zLabel = "UPDATE";
+
  switch( onError ){
+
    case OE_Replace:  zLabel = "UPDATE OR REPLACE";   break;
+
    case OE_Ignore:   zLabel = "UPDATE OR IGNORE";    break;
+
    case OE_Rollback: zLabel = "UPDATE OR ROLLBACK";  break;
+
    case OE_Abort:    zLabel = "UPDATE OR ABORT";     break;
+
    case OE_Fail:     zLabel = "UPDATE OR FAIL";      break;
+
  }
+
  sqlite3TreeViewPush(&pView, 0);
+
  sqlite3TreeViewLine(pView, zLabel);
+
  if( pWith ) n++;
+
  if( pTabList ) n++;
+
  if( pChanges ) n++;
+
  if( pWhere ) n++;
+
  if( pOrderBy ) n++;
+
  if( pLimit ) n++;
+
  if( pUpsert ) n++;
+
  if( pTrigger ) n++;
+
  if( pWith ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewWith(pView, pWith, 0);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pTabList ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewLine(pView, "FROM");
+
    sqlite3TreeViewSrcList(pView, pTabList);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pChanges ){
+
    sqlite3TreeViewExprList(pView, pChanges, (--n)>0, "SET");
+
  }
+
  if( pWhere ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewLine(pView, "WHERE");
+
    sqlite3TreeViewExpr(pView, pWhere, 0);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pOrderBy ){
+
    sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY");
+
  }
+
  if( pLimit ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewLine(pView, "LIMIT");
+
    sqlite3TreeViewExpr(pView, pLimit, 0);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pUpsert ){
+
    sqlite3TreeViewPush(&pView, (--n)>0);
+
    sqlite3TreeViewLine(pView, "UPSERT");
+
    sqlite3TreeViewUpsert(pView, pUpsert, 0);
+
    sqlite3TreeViewPop(&pView);
+
  }
+
  if( pTrigger ){
+
    sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1);
+
  }
+
  sqlite3TreeViewPop(&pView);
+
}
+
#endif /* TREETRACE_ENABLED */
+

+
#ifndef SQLITE_OMIT_TRIGGER
+
/*
+
** Show a human-readable graph of a TriggerStep
+
*/
+
SQLITE_PRIVATE void sqlite3TreeViewTriggerStep(
+
  TreeView *pView,
+
  const TriggerStep *pStep,
+
  u8 moreToFollow,
+
  u8 showFullList
+
){
+
  int cnt = 0;
+
  if( pStep==0 ) return;
+
  sqlite3TreeViewPush(&pView,
+
      moreToFollow || (showFullList && pStep->pNext!=0));
+
  do{
+
    if( cnt++ && pStep->pNext==0 ){
+
      sqlite3TreeViewPop(&pView);
+
      sqlite3TreeViewPush(&pView, 0);
+
    }
+
    sqlite3TreeViewLine(pView, "%s", pStep->zSpan ? pStep->zSpan : "RETURNING");
+
  }while( showFullList && (pStep = pStep->pNext)!=0 );
+
  sqlite3TreeViewPop(&pView);
+
}
+

+
/*
+
** Show a human-readable graph of a Trigger
+
*/
+
SQLITE_PRIVATE void sqlite3TreeViewTrigger(
+
  TreeView *pView,
+
  const Trigger *pTrigger,
+
  u8 moreToFollow,
+
  u8 showFullList
+
){
+
  int cnt = 0;
+
  if( pTrigger==0 ) return;
+
  sqlite3TreeViewPush(&pView,
+
     moreToFollow || (showFullList && pTrigger->pNext!=0));
+
  do{
+
    if( cnt++ && pTrigger->pNext==0 ){
+
      sqlite3TreeViewPop(&pView);
+
      sqlite3TreeViewPush(&pView, 0);
+
    }
+
    sqlite3TreeViewLine(pView, "TRIGGER %s", pTrigger->zName);
+
    sqlite3TreeViewPush(&pView, 0);
+
    sqlite3TreeViewTriggerStep(pView, pTrigger->step_list, 0, 1);
+
    sqlite3TreeViewPop(&pView);
+
  }while( showFullList && (pTrigger = pTrigger->pNext)!=0 );
+
  sqlite3TreeViewPop(&pView);
+
}
+
#endif /* SQLITE_OMIT_TRIGGER */
+

+

+
/*
+
** These simplified versions of the tree-view routines omit unnecessary
+
** parameters.  These variants are intended to be used from a symbolic
+
** debugger, such as "gdb", during interactive debugging sessions.
+
**
+
** This routines are given external linkage so that they will always be
+
** accessible to the debugging, and to avoid warnings about unused
+
** functions.  But these routines only exist in debugging builds, so they
+
** do not contaminate the interface.
+
*/
+
SQLITE_PRIVATE void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); }
+
SQLITE_PRIVATE void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);}
+
SQLITE_PRIVATE void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); }
+
SQLITE_PRIVATE void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); }
+
SQLITE_PRIVATE void sqlite3ShowSelect(const Select *p){ sqlite3TreeViewSelect(0,p,0); }
+
SQLITE_PRIVATE void sqlite3ShowWith(const With *p){ sqlite3TreeViewWith(0,p,0); }
+
SQLITE_PRIVATE void sqlite3ShowUpsert(const Upsert *p){ sqlite3TreeViewUpsert(0,p,0); }
+
#ifndef SQLITE_OMIT_TRIGGER
+
SQLITE_PRIVATE void sqlite3ShowTriggerStep(const TriggerStep *p){
+
  sqlite3TreeViewTriggerStep(0,p,0,0);
+
}
+
SQLITE_PRIVATE void sqlite3ShowTriggerStepList(const TriggerStep *p){
+
  sqlite3TreeViewTriggerStep(0,p,0,1);
+
}
+
SQLITE_PRIVATE void sqlite3ShowTrigger(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,0); }
+
SQLITE_PRIVATE void sqlite3ShowTriggerList(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,1);}
+
#endif
+
#ifndef SQLITE_OMIT_WINDOWFUNC
+
SQLITE_PRIVATE void sqlite3ShowWindow(const Window *p){ sqlite3TreeViewWindow(0,p,0); }
+
SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window *p){ sqlite3TreeViewWinFunc(0,p,0); }
+
#endif

#endif /* SQLITE_DEBUG */

@@ -34592,42 +35272,42 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
    /*   0 */ "Savepoint"        OpHelp(""),
    /*   1 */ "AutoCommit"       OpHelp(""),
    /*   2 */ "Transaction"      OpHelp(""),
-
    /*   3 */ "SorterNext"       OpHelp(""),
-
    /*   4 */ "Prev"             OpHelp(""),
-
    /*   5 */ "Next"             OpHelp(""),
-
    /*   6 */ "Checkpoint"       OpHelp(""),
-
    /*   7 */ "JournalMode"      OpHelp(""),
-
    /*   8 */ "Vacuum"           OpHelp(""),
-
    /*   9 */ "VFilter"          OpHelp("iplan=r[P3] zplan='P4'"),
-
    /*  10 */ "VUpdate"          OpHelp("data=r[P3@P2]"),
-
    /*  11 */ "Goto"             OpHelp(""),
-
    /*  12 */ "Gosub"            OpHelp(""),
-
    /*  13 */ "InitCoroutine"    OpHelp(""),
-
    /*  14 */ "Yield"            OpHelp(""),
-
    /*  15 */ "MustBeInt"        OpHelp(""),
-
    /*  16 */ "Jump"             OpHelp(""),
-
    /*  17 */ "Once"             OpHelp(""),
-
    /*  18 */ "If"               OpHelp(""),
+
    /*   3 */ "Checkpoint"       OpHelp(""),
+
    /*   4 */ "JournalMode"      OpHelp(""),
+
    /*   5 */ "Vacuum"           OpHelp(""),
+
    /*   6 */ "VFilter"          OpHelp("iplan=r[P3] zplan='P4'"),
+
    /*   7 */ "VUpdate"          OpHelp("data=r[P3@P2]"),
+
    /*   8 */ "Goto"             OpHelp(""),
+
    /*   9 */ "Gosub"            OpHelp(""),
+
    /*  10 */ "InitCoroutine"    OpHelp(""),
+
    /*  11 */ "Yield"            OpHelp(""),
+
    /*  12 */ "MustBeInt"        OpHelp(""),
+
    /*  13 */ "Jump"             OpHelp(""),
+
    /*  14 */ "Once"             OpHelp(""),
+
    /*  15 */ "If"               OpHelp(""),
+
    /*  16 */ "IfNot"            OpHelp(""),
+
    /*  17 */ "IsNullOrType"     OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
+
    /*  18 */ "IfNullRow"        OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
    /*  19 */ "Not"              OpHelp("r[P2]= !r[P1]"),
-
    /*  20 */ "IfNot"            OpHelp(""),
-
    /*  21 */ "IsNullOrType"     OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"),
-
    /*  22 */ "IfNullRow"        OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"),
-
    /*  23 */ "SeekLT"           OpHelp("key=r[P3@P4]"),
-
    /*  24 */ "SeekLE"           OpHelp("key=r[P3@P4]"),
-
    /*  25 */ "SeekGE"           OpHelp("key=r[P3@P4]"),
-
    /*  26 */ "SeekGT"           OpHelp("key=r[P3@P4]"),
-
    /*  27 */ "IfNotOpen"        OpHelp("if( !csr[P1] ) goto P2"),
-
    /*  28 */ "IfNoHope"         OpHelp("key=r[P3@P4]"),
-
    /*  29 */ "NoConflict"       OpHelp("key=r[P3@P4]"),
-
    /*  30 */ "NotFound"         OpHelp("key=r[P3@P4]"),
-
    /*  31 */ "Found"            OpHelp("key=r[P3@P4]"),
-
    /*  32 */ "SeekRowid"        OpHelp("intkey=r[P3]"),
-
    /*  33 */ "NotExists"        OpHelp("intkey=r[P3]"),
-
    /*  34 */ "Last"             OpHelp(""),
-
    /*  35 */ "IfSmaller"        OpHelp(""),
-
    /*  36 */ "SorterSort"       OpHelp(""),
-
    /*  37 */ "Sort"             OpHelp(""),
-
    /*  38 */ "Rewind"           OpHelp(""),
+
    /*  20 */ "SeekLT"           OpHelp("key=r[P3@P4]"),
+
    /*  21 */ "SeekLE"           OpHelp("key=r[P3@P4]"),
+
    /*  22 */ "SeekGE"           OpHelp("key=r[P3@P4]"),
+
    /*  23 */ "SeekGT"           OpHelp("key=r[P3@P4]"),
+
    /*  24 */ "IfNotOpen"        OpHelp("if( !csr[P1] ) goto P2"),
+
    /*  25 */ "IfNoHope"         OpHelp("key=r[P3@P4]"),
+
    /*  26 */ "NoConflict"       OpHelp("key=r[P3@P4]"),
+
    /*  27 */ "NotFound"         OpHelp("key=r[P3@P4]"),
+
    /*  28 */ "Found"            OpHelp("key=r[P3@P4]"),
+
    /*  29 */ "SeekRowid"        OpHelp("intkey=r[P3]"),
+
    /*  30 */ "NotExists"        OpHelp("intkey=r[P3]"),
+
    /*  31 */ "Last"             OpHelp(""),
+
    /*  32 */ "IfSmaller"        OpHelp(""),
+
    /*  33 */ "SorterSort"       OpHelp(""),
+
    /*  34 */ "Sort"             OpHelp(""),
+
    /*  35 */ "Rewind"           OpHelp(""),
+
    /*  36 */ "SorterNext"       OpHelp(""),
+
    /*  37 */ "Prev"             OpHelp(""),
+
    /*  38 */ "Next"             OpHelp(""),
    /*  39 */ "IdxLE"            OpHelp("key=r[P3@P4]"),
    /*  40 */ "IdxGT"            OpHelp("key=r[P3@P4]"),
    /*  41 */ "IdxLT"            OpHelp("key=r[P3@P4]"),
@@ -34663,34 +35343,34 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
    /*  71 */ "Integer"          OpHelp("r[P2]=P1"),
    /*  72 */ "Int64"            OpHelp("r[P2]=P4"),
    /*  73 */ "String"           OpHelp("r[P2]='P4' (len=P1)"),
-
    /*  74 */ "Null"             OpHelp("r[P2..P3]=NULL"),
-
    /*  75 */ "SoftNull"         OpHelp("r[P1]=NULL"),
-
    /*  76 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
-
    /*  77 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
-
    /*  78 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
-
    /*  79 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
-
    /*  80 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
-
    /*  81 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
-
    /*  82 */ "FkCheck"          OpHelp(""),
-
    /*  83 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
-
    /*  84 */ "CollSeq"          OpHelp(""),
-
    /*  85 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
-
    /*  86 */ "RealAffinity"     OpHelp(""),
-
    /*  87 */ "Cast"             OpHelp("affinity(r[P1])"),
-
    /*  88 */ "Permutation"      OpHelp(""),
-
    /*  89 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
-
    /*  90 */ "IsTrue"           OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
-
    /*  91 */ "ZeroOrNull"       OpHelp("r[P2] = 0 OR NULL"),
-
    /*  92 */ "Offset"           OpHelp("r[P3] = sqlite_offset(P1)"),
-
    /*  93 */ "Column"           OpHelp("r[P3]=PX"),
-
    /*  94 */ "TypeCheck"        OpHelp("typecheck(r[P1@P2])"),
-
    /*  95 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
-
    /*  96 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
-
    /*  97 */ "Count"            OpHelp("r[P2]=count()"),
-
    /*  98 */ "ReadCookie"       OpHelp(""),
-
    /*  99 */ "SetCookie"        OpHelp(""),
-
    /* 100 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
-
    /* 101 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
+
    /*  74 */ "BeginSubrtn"      OpHelp("r[P2]=NULL"),
+
    /*  75 */ "Null"             OpHelp("r[P2..P3]=NULL"),
+
    /*  76 */ "SoftNull"         OpHelp("r[P1]=NULL"),
+
    /*  77 */ "Blob"             OpHelp("r[P2]=P4 (len=P1)"),
+
    /*  78 */ "Variable"         OpHelp("r[P2]=parameter(P1,P4)"),
+
    /*  79 */ "Move"             OpHelp("r[P2@P3]=r[P1@P3]"),
+
    /*  80 */ "Copy"             OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+
    /*  81 */ "SCopy"            OpHelp("r[P2]=r[P1]"),
+
    /*  82 */ "IntCopy"          OpHelp("r[P2]=r[P1]"),
+
    /*  83 */ "FkCheck"          OpHelp(""),
+
    /*  84 */ "ResultRow"        OpHelp("output=r[P1@P2]"),
+
    /*  85 */ "CollSeq"          OpHelp(""),
+
    /*  86 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
+
    /*  87 */ "RealAffinity"     OpHelp(""),
+
    /*  88 */ "Cast"             OpHelp("affinity(r[P1])"),
+
    /*  89 */ "Permutation"      OpHelp(""),
+
    /*  90 */ "Compare"          OpHelp("r[P1@P3] <-> r[P2@P3]"),
+
    /*  91 */ "IsTrue"           OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
+
    /*  92 */ "ZeroOrNull"       OpHelp("r[P2] = 0 OR NULL"),
+
    /*  93 */ "Offset"           OpHelp("r[P3] = sqlite_offset(P1)"),
+
    /*  94 */ "Column"           OpHelp("r[P3]=PX cursor P1 column P2"),
+
    /*  95 */ "TypeCheck"        OpHelp("typecheck(r[P1@P2])"),
+
    /*  96 */ "Affinity"         OpHelp("affinity(r[P1@P2])"),
+
    /*  97 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1@P2])"),
+
    /*  98 */ "Count"            OpHelp("r[P2]=count()"),
+
    /*  99 */ "ReadCookie"       OpHelp(""),
+
    /* 100 */ "SetCookie"        OpHelp(""),
+
    /* 101 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
    /* 102 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
    /* 103 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
    /* 104 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
@@ -34701,79 +35381,81 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
    /* 109 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
    /* 110 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
    /* 111 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
-
    /* 112 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
-
    /* 113 */ "OpenDup"          OpHelp(""),
+
    /* 112 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
+
    /* 113 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
    /* 114 */ "BitNot"           OpHelp("r[P2]= ~r[P1]"),
-
    /* 115 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
-
    /* 116 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
+
    /* 115 */ "OpenDup"          OpHelp(""),
+
    /* 116 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
    /* 117 */ "String8"          OpHelp("r[P2]='P4'"),
-
    /* 118 */ "SorterOpen"       OpHelp(""),
-
    /* 119 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
-
    /* 120 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
-
    /* 121 */ "Close"            OpHelp(""),
-
    /* 122 */ "ColumnsUsed"      OpHelp(""),
-
    /* 123 */ "SeekScan"         OpHelp("Scan-ahead up to P1 rows"),
-
    /* 124 */ "SeekHit"          OpHelp("set P2<=seekHit<=P3"),
-
    /* 125 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
-
    /* 126 */ "NewRowid"         OpHelp("r[P2]=rowid"),
-
    /* 127 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
-
    /* 128 */ "RowCell"          OpHelp(""),
-
    /* 129 */ "Delete"           OpHelp(""),
-
    /* 130 */ "ResetCount"       OpHelp(""),
-
    /* 131 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
-
    /* 132 */ "SorterData"       OpHelp("r[P2]=data"),
-
    /* 133 */ "RowData"          OpHelp("r[P2]=data"),
-
    /* 134 */ "Rowid"            OpHelp("r[P2]=rowid"),
-
    /* 135 */ "NullRow"          OpHelp(""),
-
    /* 136 */ "SeekEnd"          OpHelp(""),
-
    /* 137 */ "IdxInsert"        OpHelp("key=r[P2]"),
-
    /* 138 */ "SorterInsert"     OpHelp("key=r[P2]"),
-
    /* 139 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
-
    /* 140 */ "DeferredSeek"     OpHelp("Move P3 to P1.rowid if needed"),
-
    /* 141 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
-
    /* 142 */ "FinishSeek"       OpHelp(""),
-
    /* 143 */ "Destroy"          OpHelp(""),
-
    /* 144 */ "Clear"            OpHelp(""),
-
    /* 145 */ "ResetSorter"      OpHelp(""),
-
    /* 146 */ "CreateBtree"      OpHelp("r[P2]=root iDb=P1 flags=P3"),
-
    /* 147 */ "SqlExec"          OpHelp(""),
-
    /* 148 */ "ParseSchema"      OpHelp(""),
-
    /* 149 */ "LoadAnalysis"     OpHelp(""),
-
    /* 150 */ "DropTable"        OpHelp(""),
-
    /* 151 */ "DropIndex"        OpHelp(""),
-
    /* 152 */ "DropTrigger"      OpHelp(""),
+
    /* 118 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
+
    /* 119 */ "SorterOpen"       OpHelp(""),
+
    /* 120 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+
    /* 121 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
+
    /* 122 */ "Close"            OpHelp(""),
+
    /* 123 */ "ColumnsUsed"      OpHelp(""),
+
    /* 124 */ "SeekScan"         OpHelp("Scan-ahead up to P1 rows"),
+
    /* 125 */ "SeekHit"          OpHelp("set P2<=seekHit<=P3"),
+
    /* 126 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
+
    /* 127 */ "NewRowid"         OpHelp("r[P2]=rowid"),
+
    /* 128 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
+
    /* 129 */ "RowCell"          OpHelp(""),
+
    /* 130 */ "Delete"           OpHelp(""),
+
    /* 131 */ "ResetCount"       OpHelp(""),
+
    /* 132 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+
    /* 133 */ "SorterData"       OpHelp("r[P2]=data"),
+
    /* 134 */ "RowData"          OpHelp("r[P2]=data"),
+
    /* 135 */ "Rowid"            OpHelp("r[P2]=PX rowid of P1"),
+
    /* 136 */ "NullRow"          OpHelp(""),
+
    /* 137 */ "SeekEnd"          OpHelp(""),
+
    /* 138 */ "IdxInsert"        OpHelp("key=r[P2]"),
+
    /* 139 */ "SorterInsert"     OpHelp("key=r[P2]"),
+
    /* 140 */ "IdxDelete"        OpHelp("key=r[P2@P3]"),
+
    /* 141 */ "DeferredSeek"     OpHelp("Move P3 to P1.rowid if needed"),
+
    /* 142 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
+
    /* 143 */ "FinishSeek"       OpHelp(""),
+
    /* 144 */ "Destroy"          OpHelp(""),
+
    /* 145 */ "Clear"            OpHelp(""),
+
    /* 146 */ "ResetSorter"      OpHelp(""),
+
    /* 147 */ "CreateBtree"      OpHelp("r[P2]=root iDb=P1 flags=P3"),
+
    /* 148 */ "SqlExec"          OpHelp(""),
+
    /* 149 */ "ParseSchema"      OpHelp(""),
+
    /* 150 */ "LoadAnalysis"     OpHelp(""),
+
    /* 151 */ "DropTable"        OpHelp(""),
+
    /* 152 */ "DropIndex"        OpHelp(""),
    /* 153 */ "Real"             OpHelp("r[P2]=P4"),
-
    /* 154 */ "IntegrityCk"      OpHelp(""),
-
    /* 155 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
-
    /* 156 */ "Param"            OpHelp(""),
-
    /* 157 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
-
    /* 158 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
-
    /* 159 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
-
    /* 160 */ "AggInverse"       OpHelp("accum=r[P3] inverse(r[P2@P5])"),
-
    /* 161 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
-
    /* 162 */ "AggStep1"         OpHelp("accum=r[P3] step(r[P2@P5])"),
-
    /* 163 */ "AggValue"         OpHelp("r[P3]=value N=P2"),
-
    /* 164 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
-
    /* 165 */ "Expire"           OpHelp(""),
-
    /* 166 */ "CursorLock"       OpHelp(""),
-
    /* 167 */ "CursorUnlock"     OpHelp(""),
-
    /* 168 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
-
    /* 169 */ "VBegin"           OpHelp(""),
-
    /* 170 */ "VCreate"          OpHelp(""),
-
    /* 171 */ "VDestroy"         OpHelp(""),
-
    /* 172 */ "VOpen"            OpHelp(""),
-
    /* 173 */ "VInitIn"          OpHelp("r[P2]=ValueList(P1,P3)"),
-
    /* 174 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
-
    /* 175 */ "VRename"          OpHelp(""),
-
    /* 176 */ "Pagecount"        OpHelp(""),
-
    /* 177 */ "MaxPgcnt"         OpHelp(""),
-
    /* 178 */ "FilterAdd"        OpHelp("filter(P1) += key(P3@P4)"),
-
    /* 179 */ "Trace"            OpHelp(""),
-
    /* 180 */ "CursorHint"       OpHelp(""),
-
    /* 181 */ "ReleaseReg"       OpHelp("release r[P1@P2] mask P3"),
-
    /* 182 */ "Noop"             OpHelp(""),
-
    /* 183 */ "Explain"          OpHelp(""),
-
    /* 184 */ "Abortable"        OpHelp(""),
+
    /* 154 */ "DropTrigger"      OpHelp(""),
+
    /* 155 */ "IntegrityCk"      OpHelp(""),
+
    /* 156 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
+
    /* 157 */ "Param"            OpHelp(""),
+
    /* 158 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
+
    /* 159 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
+
    /* 160 */ "OffsetLimit"      OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
+
    /* 161 */ "AggInverse"       OpHelp("accum=r[P3] inverse(r[P2@P5])"),
+
    /* 162 */ "AggStep"          OpHelp("accum=r[P3] step(r[P2@P5])"),
+
    /* 163 */ "AggStep1"         OpHelp("accum=r[P3] step(r[P2@P5])"),
+
    /* 164 */ "AggValue"         OpHelp("r[P3]=value N=P2"),
+
    /* 165 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
+
    /* 166 */ "Expire"           OpHelp(""),
+
    /* 167 */ "CursorLock"       OpHelp(""),
+
    /* 168 */ "CursorUnlock"     OpHelp(""),
+
    /* 169 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
+
    /* 170 */ "VBegin"           OpHelp(""),
+
    /* 171 */ "VCreate"          OpHelp(""),
+
    /* 172 */ "VDestroy"         OpHelp(""),
+
    /* 173 */ "VOpen"            OpHelp(""),
+
    /* 174 */ "VInitIn"          OpHelp("r[P2]=ValueList(P1,P3)"),
+
    /* 175 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
+
    /* 176 */ "VRename"          OpHelp(""),
+
    /* 177 */ "Pagecount"        OpHelp(""),
+
    /* 178 */ "MaxPgcnt"         OpHelp(""),
+
    /* 179 */ "ClrSubtype"       OpHelp("r[P1].subtype = 0"),
+
    /* 180 */ "FilterAdd"        OpHelp("filter(P1) += key(P3@P4)"),
+
    /* 181 */ "Trace"            OpHelp(""),
+
    /* 182 */ "CursorHint"       OpHelp(""),
+
    /* 183 */ "ReleaseReg"       OpHelp("release r[P1@P2] mask P3"),
+
    /* 184 */ "Noop"             OpHelp(""),
+
    /* 185 */ "Explain"          OpHelp(""),
+
    /* 186 */ "Abortable"        OpHelp(""),
  };
  return azName[i];
}
@@ -40800,20 +41482,23 @@ static int findCreateFileMode(
    **
    ** where NN is a decimal number. The NN naming schemes are
    ** used by the test_multiplex.c module.
+
    **
+
    ** In normal operation, the journal file name will always contain
+
    ** a '-' character.  However in 8+3 filename mode, or if a corrupt
+
    ** rollback journal specifies a super-journal with a goofy name, then
+
    ** the '-' might be missing or the '-' might be the first character in
+
    ** the filename.  In that case, just return SQLITE_OK with *pMode==0.
    */
    nDb = sqlite3Strlen30(zPath) - 1;
-
    while( zPath[nDb]!='-' ){
-
      /* In normal operation, the journal file name will always contain
-
      ** a '-' character.  However in 8+3 filename mode, or if a corrupt
-
      ** rollback journal specifies a super-journal with a goofy name, then
-
      ** the '-' might be missing. */
-
      if( nDb==0 || zPath[nDb]=='.' ) return SQLITE_OK;
+
    while( nDb>0 && zPath[nDb]!='.' ){
+
      if( zPath[nDb]=='-' ){
+
        memcpy(zDb, zPath, nDb);
+
        zDb[nDb] = '\0';
+
        rc = getFileMode(zDb, pMode, pUid, pGid);
+
        break;
+
      }
      nDb--;
    }
-
    memcpy(zDb, zPath, nDb);
-
    zDb[nDb] = '\0';
-

-
    rc = getFileMode(zDb, pMode, pUid, pGid);
  }else if( flags & SQLITE_OPEN_DELETEONCLOSE ){
    *pMode = 0600;
  }else if( flags & SQLITE_OPEN_URI ){
@@ -41203,86 +41888,99 @@ static int unixAccess(
}

/*
-
** If the last component of the pathname in z[0]..z[j-1] is something
-
** other than ".." then back it out and return true.  If the last
-
** component is empty or if it is ".." then return false.
+
** A pathname under construction
*/
-
static int unixBackupDir(const char *z, int *pJ){
-
  int j = *pJ;
-
  int i;
-
  if( j<=0 ) return 0;
-
  for(i=j-1; i>0 && z[i-1]!='/'; i--){}
-
  if( i==0 ) return 0;
-
  if( z[i]=='.' && i==j-2 && z[i+1]=='.' ) return 0;
-
  *pJ = i-1;
-
  return 1;
-
}
+
typedef struct DbPath DbPath;
+
struct DbPath {
+
  int rc;           /* Non-zero following any error */
+
  int nSymlink;     /* Number of symlinks resolved */
+
  char *zOut;       /* Write the pathname here */
+
  int nOut;         /* Bytes of space available to zOut[] */
+
  int nUsed;        /* Bytes of zOut[] currently being used */
+
};
+

+
/* Forward reference */
+
static void appendAllPathElements(DbPath*,const char*);

/*
-
** Convert a relative pathname into a full pathname.  Also
-
** simplify the pathname as follows:
-
**
-
**    Remove all instances of /./
-
**    Remove all isntances of /X/../ for any X
+
** Append a single path element to the DbPath under construction
*/
-
static int mkFullPathname(
-
  const char *zPath,              /* Input path */
-
  char *zOut,                     /* Output buffer */
-
  int nOut                        /* Allocated size of buffer zOut */
+
static void appendOnePathElement(
+
  DbPath *pPath,       /* Path under construction, to which to append zName */
+
  const char *zName,   /* Name to append to pPath.  Not zero-terminated */
+
  int nName            /* Number of significant bytes in zName */
){
-
  int nPath = sqlite3Strlen30(zPath);
-
  int iOff = 0;
-
  int i, j;
-
  if( zPath[0]!='/' ){
-
    if( osGetcwd(zOut, nOut-2)==0 ){
-
      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
+
  assert( nName>0 );
+
  assert( zName!=0 );
+
  if( zName[0]=='.' ){
+
    if( nName==1 ) return;
+
    if( zName[1]=='.' && nName==2 ){
+
      if( pPath->nUsed<=1 ){
+
        pPath->rc = SQLITE_ERROR;
+
        return;
+
      }
+
      assert( pPath->zOut[0]=='/' );
+
      while( pPath->zOut[--pPath->nUsed]!='/' ){}
+
      return;
    }
-
    iOff = sqlite3Strlen30(zOut);
-
    zOut[iOff++] = '/';
-
  }
-
  if( (iOff+nPath+1)>nOut ){
-
    /* SQLite assumes that xFullPathname() nul-terminates the output buffer
-
    ** even if it returns an error.  */
-
    zOut[iOff] = '\0';
-
    return SQLITE_CANTOPEN_BKPT;
  }
-
  sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
-

-
  /* Remove duplicate '/' characters.  Except, two // at the beginning
-
  ** of a pathname is allowed since this is important on windows. */
-
  for(i=j=1; zOut[i]; i++){
-
    zOut[j++] = zOut[i];
-
    while( zOut[i]=='/' && zOut[i+1]=='/' ) i++;
+
  if( pPath->nUsed + nName + 2 >= pPath->nOut ){
+
    pPath->rc = SQLITE_ERROR;
+
    return;
  }
-
  zOut[j] = 0;
-

-
  assert( zOut[0]=='/' );
-
  for(i=j=0; zOut[i]; i++){
-
    if( zOut[i]=='/' ){
-
      /* Skip over internal "/." directory components */
-
      if( zOut[i+1]=='.' && zOut[i+2]=='/' ){
-
        i += 1;
-
        continue;
+
  pPath->zOut[pPath->nUsed++] = '/';
+
  memcpy(&pPath->zOut[pPath->nUsed], zName, nName);
+
  pPath->nUsed += nName;
+
#if defined(HAVE_READLINK) && defined(HAVE_LSTAT)
+
  if( pPath->rc==SQLITE_OK ){
+
    const char *zIn;
+
    struct stat buf;
+
    pPath->zOut[pPath->nUsed] = 0;
+
    zIn = pPath->zOut;
+
    if( osLstat(zIn, &buf)!=0 ){
+
      if( errno!=ENOENT ){
+
        pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
      }
-

-
      /* If this is a "/.." directory component then back out the
-
      ** previous term of the directory if it is something other than "..".
-
      */
-
      if( zOut[i+1]=='.'
-
       && zOut[i+2]=='.'
-
       && zOut[i+3]=='/'
-
       && unixBackupDir(zOut, &j)
-
      ){
-
        i += 2;
-
        continue;
+
    }else if( S_ISLNK(buf.st_mode) ){
+
      ssize_t got;
+
      char zLnk[SQLITE_MAX_PATHLEN+2];
+
      if( pPath->nSymlink++ > SQLITE_MAX_SYMLINK ){
+
        pPath->rc = SQLITE_CANTOPEN_BKPT;
+
        return;
+
      }
+
      got = osReadlink(zIn, zLnk, sizeof(zLnk)-2);
+
      if( got<=0 || got>=(ssize_t)sizeof(zLnk)-2 ){
+
        pPath->rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
+
        return;
+
      }
+
      zLnk[got] = 0;
+
      if( zLnk[0]=='/' ){
+
        pPath->nUsed = 0;
+
      }else{
+
        pPath->nUsed -= nName + 1;
      }
+
      appendAllPathElements(pPath, zLnk);
    }
-
    if( ALWAYS(j>=0) ) zOut[j] = zOut[i];
-
    j++;
  }
-
  if( NEVER(j==0) ) zOut[j++] = '/';
-
  zOut[j] = 0;
-
  return SQLITE_OK;
+
#endif
+
}
+

+
/*
+
** Append all path elements in zPath to the DbPath under construction.
+
*/
+
static void appendAllPathElements(
+
  DbPath *pPath,       /* Path under construction, to which to append zName */
+
  const char *zPath    /* Path to append to pPath.  Is zero-terminated */
+
){
+
  int i = 0;
+
  int j = 0;
+
  do{
+
    while( zPath[i] && zPath[i]!='/' ){ i++; }
+
    if( i>j ){
+
      appendOnePathElement(pPath, &zPath[j], i-j);
+
    }
+
    j = i+1;
+
  }while( zPath[i++] );
}

/*
@@ -41300,86 +41998,27 @@ static int unixFullPathname(
  int nOut,                     /* Size of output buffer in bytes */
  char *zOut                    /* Output buffer */
){
-
#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
-
  return mkFullPathname(zPath, zOut, nOut);
-
#else
-
  int rc = SQLITE_OK;
-
  int nByte;
-
  int nLink = 0;                /* Number of symbolic links followed so far */
-
  const char *zIn = zPath;      /* Input path for each iteration of loop */
-
  char *zDel = 0;
-

-
  assert( pVfs->mxPathname==MAX_PATHNAME );
+
  DbPath path;
  UNUSED_PARAMETER(pVfs);
-

-
  /* It's odd to simulate an io-error here, but really this is just
-
  ** using the io-error infrastructure to test that SQLite handles this
-
  ** function failing. This function could fail if, for example, the
-
  ** current working directory has been unlinked.
-
  */
-
  SimulateIOError( return SQLITE_ERROR );
-

-
  do {
-

-
    /* Call stat() on path zIn. Set bLink to true if the path is a symbolic
-
    ** link, or false otherwise.  */
-
    int bLink = 0;
-
    struct stat buf;
-
    if( osLstat(zIn, &buf)!=0 ){
-
      if( errno!=ENOENT ){
-
        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
-
      }
-
    }else{
-
      bLink = S_ISLNK(buf.st_mode);
-
    }
-

-
    if( bLink ){
-
      nLink++;
-
      if( zDel==0 ){
-
        zDel = sqlite3_malloc(nOut);
-
        if( zDel==0 ) rc = SQLITE_NOMEM_BKPT;
-
      }else if( nLink>=SQLITE_MAX_SYMLINKS ){
-
        rc = SQLITE_CANTOPEN_BKPT;
-
      }
-

-
      if( rc==SQLITE_OK ){
-
        nByte = osReadlink(zIn, zDel, nOut-1);
-
        if( nByte<0 ){
-
          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
-
        }else{
-
          if( zDel[0]!='/' ){
-
            int n;
-
            for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
-
            if( nByte+n+1>nOut ){
-
              rc = SQLITE_CANTOPEN_BKPT;
-
            }else{
-
              memmove(&zDel[n], zDel, nByte+1);
-
              memcpy(zDel, zIn, n);
-
              nByte += n;
-
            }
-
          }
-
          zDel[nByte] = '\0';
-
        }
-
      }
-

-
      zIn = zDel;
-
    }
-

-
    assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' );
-
    if( rc==SQLITE_OK && zIn!=zOut ){
-
      rc = mkFullPathname(zIn, zOut, nOut);
+
  path.rc = 0;
+
  path.nUsed = 0;
+
  path.nSymlink = 0;
+
  path.nOut = nOut;
+
  path.zOut = zOut;
+
  if( zPath[0]!='/' ){
+
    char zPwd[SQLITE_MAX_PATHLEN+2];
+
    if( osGetcwd(zPwd, sizeof(zPwd)-2)==0 ){
+
      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
    }
-
    if( bLink==0 ) break;
-
    zIn = zOut;
-
  }while( rc==SQLITE_OK );
-

-
  sqlite3_free(zDel);
-
  if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK;
-
  return rc;
-
#endif   /* HAVE_READLINK && HAVE_LSTAT */
+
    appendAllPathElements(&path, zPwd);
+
  }
+
  appendAllPathElements(&path, zPath);
+
  zOut[path.nUsed] = 0;
+
  if( path.rc || path.nUsed<2 ) return SQLITE_CANTOPEN_BKPT;
+
  if( path.nSymlink ) return SQLITE_OK_SYMLINK;
+
  return SQLITE_OK;
}

-

#ifndef SQLITE_OMIT_LOAD_EXTENSION
/*
** Interfaces for opening a shared library, finding entry points
@@ -50928,8 +51567,7 @@ SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
** make it so.
*/
SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
-
  assert( p->nRef>0 || p->pCache->bPurgeable==0 );
-
  testcase( p->nRef==0 );
+
  assert( p->nRef>0 );
  assert( sqlite3PcachePageSanity(p) );
  if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){    /*OPTIMIZATION-IF-FALSE*/
    p->flags &= ~PGHDR_DONT_WRITE;
@@ -53898,6 +54536,7 @@ struct Pager {
  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
  u32 sectorSize;             /* Assumed sector size during rollback */
  Pgno mxPgno;                /* Maximum allowed size of the database */
+
  Pgno lckPgno;               /* Page number for the locking page */
  i64 pageSize;               /* Number of bytes in a page */
  i64 journalSizeLimit;       /* Size limit for persistent journal files */
  char *zFilename;            /* Name of the database file */
@@ -54884,7 +55523,7 @@ static int readJournalHdr(
** journal file descriptor is advanced to the next sector boundary before
** anything is written. The format is:
**
-
**   + 4 bytes: PAGER_MJ_PGNO.
+
**   + 4 bytes: PAGER_SJ_PGNO.
**   + N bytes: super-journal filename in utf-8.
**   + 4 bytes: N (length of super-journal name in bytes, no nul-terminator).
**   + 4 bytes: super-journal name checksum.
@@ -54932,7 +55571,7 @@ static int writeSuperJournal(Pager *pPager, const char *zSuper){
  /* Write the super-journal data to the end of the journal file. If
  ** an error occurs, return the error code to the caller.
  */
-
  if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
+
  if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_SJ_PGNO(pPager))))
   || (0 != (rc = sqlite3OsWrite(pPager->jfd, zSuper, nSuper, iHdrOff+4)))
   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper, nSuper)))
   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nSuper+4, cksum)))
@@ -55442,7 +56081,7 @@ static u32 pager_cksum(Pager *pPager, const u8 *aData){
** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
** two circumstances:
**
-
**   * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
+
**   * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or
**   * If the record is being rolled back from the main journal file
**     and the checksum field does not match the record content.
**
@@ -55502,7 +56141,7 @@ static int pager_playback_one_page(
  ** it could cause invalid data to be written into the journal.  We need to
  ** detect this invalid data (with high probability) and ignore it.
  */
-
  if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
+
  if( pgno==0 || pgno==PAGER_SJ_PGNO(pPager) ){
    assert( !isSavepnt );
    return SQLITE_DONE;
  }
@@ -55839,6 +56478,7 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
        memset(pTmp, 0, szPage);
        testcase( (newSize-szPage) == currentSize );
        testcase( (newSize-szPage) >  currentSize );
+
        sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &newSize);
        rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage);
      }
      if( rc==SQLITE_OK ){
@@ -56960,6 +57600,7 @@ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nR
      pPager->pTmpSpace = pNew;
      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
      pPager->pageSize = pageSize;
+
      pPager->lckPgno = (Pgno)(PENDING_BYTE/pageSize) + 1;
    }else{
      sqlite3PageFree(pNew);
    }
@@ -58729,7 +59370,7 @@ static int getPageNormal(
  if( pPg->pPager && !noContent ){
    /* In this case the pcache already contains an initialized copy of
    ** the page. Return without further ado.  */
-
    assert( pgno!=PAGER_MJ_PGNO(pPager) );
+
    assert( pgno!=PAGER_SJ_PGNO(pPager) );
    pPager->aStat[PAGER_STAT_HIT]++;
    return SQLITE_OK;

@@ -58740,7 +59381,7 @@ static int getPageNormal(
    ** (*) obsolete.  Was: maximum page number is 2^31
    ** (2) Never try to fetch the locking page
    */
-
    if( pgno==PAGER_MJ_PGNO(pPager) ){
+
    if( pgno==PAGER_SJ_PGNO(pPager) ){
      rc = SQLITE_CORRUPT_BKPT;
      goto pager_acquire_err;
    }
@@ -59139,7 +59780,7 @@ static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){
  /* We should never write to the journal file the page that
  ** contains the database locks.  The following assert verifies
  ** that we do not. */
-
  assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
+
  assert( pPg->pgno!=PAGER_SJ_PGNO(pPager) );

  assert( pPager->journalHdr<=pPager->journalOff );
  pData2 = pPg->pData;
@@ -59318,7 +59959,7 @@ static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
    Pgno pg = pg1+ii;
    PgHdr *pPage;
    if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
-
      if( pg!=PAGER_MJ_PGNO(pPager) ){
+
      if( pg!=PAGER_SJ_PGNO(pPager) ){
        rc = sqlite3PagerGet(pPager, pg, &pPage, 0);
        if( rc==SQLITE_OK ){
          rc = pager_write(pPage);
@@ -59796,7 +60437,7 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
      ** last page is never written out to disk, leaving the database file
      ** undersized. Fix this now if it is the case.  */
      if( pPager->dbSize>pPager->dbFileSize ){
-
        Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
+
        Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_SJ_PGNO(pPager));
        assert( pPager->eState==PAGER_WRITER_DBMOD );
        rc = pager_truncate(pPager, nNew);
        if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
@@ -65425,7 +66066,7 @@ struct MemPage {
  u8 *aData;           /* Pointer to disk image of the page data */
  u8 *aDataEnd;        /* One byte past the end of the entire page - not just
                       ** the usable space, the entire page.  Used to prevent
-
                       ** corruption-induced of buffer overflow. */
+
                       ** corruption-induced buffer overflow. */
  u8 *aCellIdx;        /* The cell index area */
  u8 *aDataOfst;       /* Same as aData for leaves.  aData+4 for interior */
  DbPage *pDbPage;     /* Pager page handle */
@@ -65730,7 +66371,7 @@ struct BtCursor {
/*
** The database page the PENDING_BYTE occupies. This page is never used.
*/
-
# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
+
#define PENDING_BYTE_PAGE(pBt)  ((Pgno)((PENDING_BYTE/((pBt)->pageSize))+1))

/*
** These macros define the location of the pointer-map entry for a
@@ -66371,7 +67012,7 @@ static int hasSharedCacheTableLock(
    int bSeen = 0;
    for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
      Index *pIdx = (Index *)sqliteHashData(p);
-
      if( pIdx->tnum==(int)iRoot ){
+
      if( pIdx->tnum==iRoot ){
        if( bSeen ){
          /* Two or more indexes share the same root page.  There must
          ** be imposter tables.  So just return true.  The assert is not
@@ -66964,7 +67605,7 @@ SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){
/*
** In this version of BtreeMoveto, pKey is a packed index record
** such as is generated by the OP_MakeRecord opcode.  Unpack the
-
** record and then call BtreeMovetoUnpacked() to do the work.
+
** record and then call sqlite3BtreeIndexMoveto() to do the work.
*/
static int btreeMoveto(
  BtCursor *pCur,     /* Cursor open on the btree to be searched */
@@ -67484,6 +68125,7 @@ static void btreeParseCell(
** the space used by the cell pointer.
**
** cellSizePtrNoPayload()    =>   table internal nodes
+
** cellSizePtrTableLeaf()    =>   table leaf nodes
** cellSizePtr()             =>   all index nodes & table leaf nodes
*/
static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
@@ -67509,13 +68151,6 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
    }while( *(pIter)>=0x80 && pIter<pEnd );
  }
  pIter++;
-
  if( pPage->intKey ){
-
    /* pIter now points at the 64-bit integer key value, a variable length
-
    ** integer. The following block moves pIter to point at the first byte
-
    ** past the end of the key value. */
-
    pEnd = &pIter[9];
-
    while( (*pIter++)&0x80 && pIter<pEnd );
-
  }
  testcase( nSize==pPage->maxLocal );
  testcase( nSize==(u32)pPage->maxLocal+1 );
  if( nSize<=pPage->maxLocal ){
@@ -67555,6 +68190,58 @@ static u16 cellSizePtrNoPayload(MemPage *pPage, u8 *pCell){
  assert( debuginfo.nSize==(u16)(pIter - pCell) || CORRUPT_DB );
  return (u16)(pIter - pCell);
}
+
static u16 cellSizePtrTableLeaf(MemPage *pPage, u8 *pCell){
+
  u8 *pIter = pCell;   /* For looping over bytes of pCell */
+
  u8 *pEnd;            /* End mark for a varint */
+
  u32 nSize;           /* Size value to return */
+

+
#ifdef SQLITE_DEBUG
+
  /* The value returned by this function should always be the same as
+
  ** the (CellInfo.nSize) value found by doing a full parse of the
+
  ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of
+
  ** this function verifies that this invariant is not violated. */
+
  CellInfo debuginfo;
+
  pPage->xParseCell(pPage, pCell, &debuginfo);
+
#endif
+

+
  nSize = *pIter;
+
  if( nSize>=0x80 ){
+
    pEnd = &pIter[8];
+
    nSize &= 0x7f;
+
    do{
+
      nSize = (nSize<<7) | (*++pIter & 0x7f);
+
    }while( *(pIter)>=0x80 && pIter<pEnd );
+
  }
+
  pIter++;
+
  /* pIter now points at the 64-bit integer key value, a variable length
+
  ** integer. The following block moves pIter to point at the first byte
+
  ** past the end of the key value. */
+
  if( (*pIter++)&0x80
+
   && (*pIter++)&0x80
+
   && (*pIter++)&0x80
+
   && (*pIter++)&0x80
+
   && (*pIter++)&0x80
+
   && (*pIter++)&0x80
+
   && (*pIter++)&0x80
+
   && (*pIter++)&0x80 ){ pIter++; }
+
  testcase( nSize==pPage->maxLocal );
+
  testcase( nSize==(u32)pPage->maxLocal+1 );
+
  if( nSize<=pPage->maxLocal ){
+
    nSize += (u32)(pIter - pCell);
+
    if( nSize<4 ) nSize = 4;
+
  }else{
+
    int minLocal = pPage->minLocal;
+
    nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
+
    testcase( nSize==pPage->maxLocal );
+
    testcase( nSize==(u32)pPage->maxLocal+1 );
+
    if( nSize>pPage->maxLocal ){
+
      nSize = minLocal;
+
    }
+
    nSize += 4 + (u16)(pIter - pCell);
+
  }
+
  assert( nSize==debuginfo.nSize || CORRUPT_DB );
+
  return (u16)nSize;
+
}


#ifdef SQLITE_DEBUG
@@ -67568,7 +68255,7 @@ static u16 cellSize(MemPage *pPage, int iCell){
#ifndef SQLITE_OMIT_AUTOVACUUM
/*
** The cell pCell is currently part of page pSrc but will ultimately be part
-
** of pPage.  (pSrc and pPager are often the same.)  If pCell contains a
+
** of pPage.  (pSrc and pPage are often the same.)  If pCell contains a
** pointer to an overflow page, insert an entry into the pointer-map for
** the overflow page that will be valid after pCell has been moved to pPage.
*/
@@ -67743,7 +68430,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
  const int hdr = pPg->hdrOffset;            /* Offset to page header */
  u8 * const aData = pPg->aData;             /* Page data */
  int iAddr = hdr + 1;                       /* Address of ptr to pc */
-
  int pc = get2byte(&aData[iAddr]);          /* Address of a free slot */
+
  u8 *pTmp = &aData[iAddr];                  /* Temporary ptr into aData[] */
+
  int pc = get2byte(pTmp);                   /* Address of a free slot */
  int x;                                     /* Excess size of the slot */
  int maxPC = pPg->pBt->usableSize - nByte;  /* Max address for a usable slot */
  int size;                                  /* Size of the free slot */
@@ -67753,7 +68441,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
    /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
    ** freeblock form a big-endian integer which is the size of the freeblock
    ** in bytes, including the 4-byte header. */
-
    size = get2byte(&aData[pc+2]);
+
    pTmp = &aData[pc+2];
+
    size = get2byte(pTmp);
    if( (x = size - nByte)>=0 ){
      testcase( x==4 );
      testcase( x==3 );
@@ -67780,7 +68469,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
      return &aData[pc + x];
    }
    iAddr = pc;
-
    pc = get2byte(&aData[pc]);
+
    pTmp = &aData[pc];
+
    pc = get2byte(pTmp);
    if( pc<=iAddr+size ){
      if( pc ){
        /* The next slot in the chain is not past the end of the current slot */
@@ -67814,6 +68504,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
  u8 * const data = pPage->aData;      /* Local cache of pPage->aData */
  int top;                             /* First byte of cell content area */
  int rc = SQLITE_OK;                  /* Integer return code */
+
  u8 *pTmp;                            /* Temp ptr into data[] */
  int gap;        /* First byte of gap between cell pointers and cell content */

  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
@@ -67832,7 +68523,8 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
  ** then the cell content offset of an empty page wants to be 65536.
  ** However, that integer is too large to be stored in a 2-byte unsigned
  ** integer, so a value of 0 is used in its place. */
-
  top = get2byte(&data[hdr+5]);
+
  pTmp = &data[hdr+5];
+
  top = get2byte(pTmp);
  assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */
  if( gap>top ){
    if( top==0 && pPage->pBt->usableSize==65536 ){
@@ -67914,6 +68606,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
  u16 x;                                /* Offset to cell content area */
  u32 iEnd = iStart + iSize;            /* First byte past the iStart buffer */
  unsigned char *data = pPage->aData;   /* Page content */
+
  u8 *pTmp;                             /* Temporary ptr into data[] */

  assert( pPage->pBt!=0 );
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
@@ -67976,7 +68669,8 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
    if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_PAGE(pPage);
    data[hdr+7] -= nFrag;
  }
-
  x = get2byte(&data[hdr+5]);
+
  pTmp = &data[hdr+5];
+
  x = get2byte(pTmp);
  if( iStart<=x ){
    /* The new freeblock is at the beginning of the cell content area,
    ** so just extend the cell content area rather than create another
@@ -68020,7 +68714,6 @@ static int decodeFlags(MemPage *pPage, int flagByte){
  pPage->leaf = (u8)(flagByte>>3);  assert( PTF_LEAF == 1<<3 );
  flagByte &= ~PTF_LEAF;
  pPage->childPtrSize = 4-4*pPage->leaf;
-
  pPage->xCellSize = cellSizePtr;
  pBt = pPage->pBt;
  if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
    /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
@@ -68032,6 +68725,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){
    pPage->intKey = 1;
    if( pPage->leaf ){
      pPage->intKeyLeaf = 1;
+
      pPage->xCellSize = cellSizePtrTableLeaf;
      pPage->xParseCell = btreeParseCellPtr;
    }else{
      pPage->intKeyLeaf = 0;
@@ -68049,12 +68743,17 @@ static int decodeFlags(MemPage *pPage, int flagByte){
    assert( (PTF_ZERODATA|PTF_LEAF)==10 );
    pPage->intKey = 0;
    pPage->intKeyLeaf = 0;
+
    pPage->xCellSize = cellSizePtr;
    pPage->xParseCell = btreeParseCellPtrIndex;
    pPage->maxLocal = pBt->maxLocal;
    pPage->minLocal = pBt->minLocal;
  }else{
    /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
    ** an error. */
+
    pPage->intKey = 0;
+
    pPage->intKeyLeaf = 0;
+
    pPage->xCellSize = cellSizePtr;
+
    pPage->xParseCell = btreeParseCellPtrIndex;
    return SQLITE_CORRUPT_PAGE(pPage);
  }
  pPage->max1bytePayload = pBt->max1bytePayload;
@@ -68408,7 +69107,9 @@ getAndInitPage_error1:
    pCur->pPage = pCur->apPage[pCur->iPage];
  }
  testcase( pgno==0 );
-
  assert( pgno!=0 || rc==SQLITE_CORRUPT );
+
  assert( pgno!=0 || rc==SQLITE_CORRUPT
+
                  || rc==SQLITE_IOERR_NOMEM
+
                  || rc==SQLITE_NOMEM );
  return rc;
}

@@ -70030,12 +70731,17 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
      }
      do {
        MemPage *pFreePg;
+
        Pgno dbSize = btreePagecount(pBt);
        rc = allocateBtreePage(pBt, &pFreePg, &iFreePg, iNear, eMode);
        if( rc!=SQLITE_OK ){
          releasePage(pLastPg);
          return rc;
        }
        releasePage(pFreePg);
+
        if( iFreePg>dbSize ){
+
          releasePage(pLastPg);
+
          return SQLITE_CORRUPT_BKPT;
+
        }
      }while( bCommit && iFreePg>nFin );
      assert( iFreePg<iLastPg );

@@ -71797,6 +72503,69 @@ moveto_table_finish:
  return rc;
}

+
/*
+
** Compare the "idx"-th cell on the page the cursor pCur is currently
+
** pointing to to pIdxKey using xRecordCompare.  Return negative or
+
** zero if the cell is less than or equal pIdxKey.  Return positive
+
** if unknown.
+
**
+
**    Return value negative:     Cell at pCur[idx] less than pIdxKey
+
**
+
**    Return value is zero:      Cell at pCur[idx] equals pIdxKey
+
**
+
**    Return value positive:     Nothing is known about the relationship
+
**                               of the cell at pCur[idx] and pIdxKey.
+
**
+
** This routine is part of an optimization.  It is always safe to return
+
** a positive value as that will cause the optimization to be skipped.
+
*/
+
static int indexCellCompare(
+
  BtCursor *pCur,
+
  int idx,
+
  UnpackedRecord *pIdxKey,
+
  RecordCompare xRecordCompare
+
){
+
  MemPage *pPage = pCur->pPage;
+
  int c;
+
  int nCell;  /* Size of the pCell cell in bytes */
+
  u8 *pCell = findCellPastPtr(pPage, idx);
+

+
  nCell = pCell[0];
+
  if( nCell<=pPage->max1bytePayload ){
+
    /* This branch runs if the record-size field of the cell is a
+
    ** single byte varint and the record fits entirely on the main
+
    ** b-tree page.  */
+
    testcase( pCell+nCell+1==pPage->aDataEnd );
+
    c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
+
  }else if( !(pCell[1] & 0x80)
+
    && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
+
  ){
+
    /* The record-size field is a 2 byte varint and the record
+
    ** fits entirely on the main b-tree page.  */
+
    testcase( pCell+nCell+2==pPage->aDataEnd );
+
    c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
+
  }else{
+
    /* If the record extends into overflow pages, do not attempt
+
    ** the optimization. */
+
    c = 99;
+
  }
+
  return c;
+
}
+

+
/*
+
** Return true (non-zero) if pCur is current pointing to the last
+
** page of a table.
+
*/
+
static int cursorOnLastPage(BtCursor *pCur){
+
  int i;
+
  assert( pCur->eState==CURSOR_VALID );
+
  for(i=0; i<pCur->iPage; i++){
+
    MemPage *pPage = pCur->apPage[i];
+
    if( pCur->aiIdx[i]<pPage->nCell ) return 0;
+
  }
+
  return 1;
+
}
+

/* Move the cursor so that it points to an entry in an index table
** near the key pIdxKey.   Return a success code.
**
@@ -71847,6 +72616,43 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto(
       || pIdxKey->default_rc==-1
  );

+

+
  /* Check to see if we can skip a lot of work.  Two cases:
+
  **
+
  **    (1) If the cursor is already pointing to the very last cell
+
  **        in the table and the pIdxKey search key is greater than or
+
  **        equal to that last cell, then no movement is required.
+
  **
+
  **    (2) If the cursor is on the last page of the table and the first
+
  **        cell on that last page is less than or equal to the pIdxKey
+
  **        search key, then we can start the search on the current page
+
  **        without needing to go back to root.
+
  */
+
  if( pCur->eState==CURSOR_VALID
+
   && pCur->pPage->leaf
+
   && cursorOnLastPage(pCur)
+
  ){
+
    int c;
+
    if( pCur->ix==pCur->pPage->nCell-1
+
     && (c = indexCellCompare(pCur, pCur->ix, pIdxKey, xRecordCompare))<=0
+
     && pIdxKey->errCode==SQLITE_OK
+
    ){
+
      *pRes = c;
+
      return SQLITE_OK;  /* Cursor already pointing at the correct spot */
+
    }
+
    if( pCur->iPage>0
+
     && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0
+
     && pIdxKey->errCode==SQLITE_OK
+
    ){
+
      pCur->curFlags &= ~BTCF_ValidOvfl;
+
      if( !pCur->pPage->isInit ){
+
        return SQLITE_CORRUPT_BKPT;
+
      }
+
      goto bypass_moveto_root;  /* Start search on the current page */
+
    }
+
    pIdxKey->errCode = SQLITE_OK;
+
  }
+

  rc = moveToRoot(pCur);
  if( rc ){
    if( rc==SQLITE_EMPTY ){
@@ -71856,12 +72662,14 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto(
    }
    return rc;
  }
+

+
bypass_moveto_root:
  assert( pCur->pPage );
  assert( pCur->pPage->isInit );
  assert( pCur->eState==CURSOR_VALID );
  assert( pCur->pPage->nCell > 0 );
-
  assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey );
-
  assert( pCur->curIntKey || pIdxKey );
+
  assert( pCur->curIntKey==0 );
+
  assert( pIdxKey!=0 );
  for(;;){
    int lwr, upr, idx, c;
    Pgno chldPg;
@@ -71875,7 +72683,7 @@ SQLITE_PRIVATE int sqlite3BtreeIndexMoveto(
    ** be the right kind (index or table) of b-tree page. Otherwise
    ** a moveToChild() or moveToRoot() call would have detected corruption.  */
    assert( pPage->nCell>0 );
-
    assert( pPage->intKey==(pIdxKey==0) );
+
    assert( pPage->intKey==0 );
    lwr = 0;
    upr = pPage->nCell-1;
    idx = upr>>1; /* idx = (lwr+upr)/2; */
@@ -74742,7 +75550,6 @@ static int anotherValidCursor(BtCursor *pCur){
*/
static int balance(BtCursor *pCur){
  int rc = SQLITE_OK;
-
  const int nMin = pCur->pBt->usableSize * 2 / 3;
  u8 aBalanceQuickSpace[13];
  u8 *pFree = 0;

@@ -74754,7 +75561,11 @@ static int balance(BtCursor *pCur){
    MemPage *pPage = pCur->pPage;

    if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break;
-
    if( pPage->nOverflow==0 && pPage->nFree<=nMin ){
+
    if( pPage->nOverflow==0 && pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){
+
      /* No rebalance required as long as:
+
      **   (1) There are no overflow cells
+
      **   (2) The amount of free space on the page is less than 2/3rds of
+
      **       the total usable space on the page. */
      break;
    }else if( (iPage = pCur->iPage)==0 ){
      if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){
@@ -74974,7 +75785,7 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
** pX.pData,nData,nZero fields must be zero.
**
** If the seekResult parameter is non-zero, then a successful call to
-
** MovetoUnpacked() to seek cursor pCur to (pKey,nKey) has already
+
** sqlite3BtreeIndexMoveto() to seek cursor pCur to (pKey,nKey) has already
** been performed.  In other words, if seekResult!=0 then the cursor
** is currently pointing to a cell that will be adjacent to the cell
** to be inserted.  If seekResult<0 then pCur points to a cell that is
@@ -74992,7 +75803,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
  BtCursor *pCur,                /* Insert data into the table of this cursor */
  const BtreePayload *pX,        /* Content of the row to be inserted */
  int flags,                     /* True if this is likely an append */
-
  int seekResult                 /* Result of prior MovetoUnpacked() call */
+
  int seekResult                 /* Result of prior IndexMoveto() call */
){
  int rc;
  int loc = seekResult;          /* -1: before desired location  +1: after */
@@ -75031,7 +75842,12 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
    }
  }

+
  /* Ensure that the cursor is not in the CURSOR_FAULT state and that it
+
  ** points to a valid cell.
+
  */
  if( pCur->eState>=CURSOR_REQUIRESEEK ){
+
    testcase( pCur->eState==CURSOR_REQUIRESEEK );
+
    testcase( pCur->eState==CURSOR_FAULT );
    rc = moveToRoot(pCur);
    if( rc && rc!=SQLITE_EMPTY ) return rc;
  }
@@ -75143,7 +75959,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
  assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
  assert( pPage->leaf || !pPage->intKey );
  if( pPage->nFree<0 ){
-
    if( pCur->eState>CURSOR_INVALID ){
+
    if( NEVER(pCur->eState>CURSOR_INVALID) ){
+
     /* ^^^^^--- due to the moveToRoot() call above */
      rc = SQLITE_CORRUPT_BKPT;
    }else{
      rc = btreeComputeFreeSpace(pPage);
@@ -75154,7 +75971,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
          pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
          loc==0 ? "overwrite" : "new entry"));
-
  assert( pPage->isInit );
+
  assert( pPage->isInit || CORRUPT_DB );
  newCell = pBt->pTmpSpace;
  assert( newCell!=0 );
  if( flags & BTREE_PREFORMAT ){
@@ -75305,7 +76122,11 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64
  u32 nRem;                     /* Bytes of data still to copy */

  getCellInfo(pSrc);
-
  aOut += putVarint32(aOut, pSrc->info.nPayload);
+
  if( pSrc->info.nPayload<0x80 ){
+
    *(aOut++) = pSrc->info.nPayload;
+
  }else{
+
    aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload);
+
  }
  if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey);
  nIn = pSrc->info.nLocal;
  aIn = pSrc->info.pPayload;
@@ -75465,7 +76286,8 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
  bPreserve = (flags & BTREE_SAVEPOSITION)!=0;
  if( bPreserve ){
    if( !pPage->leaf
-
     || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
+
     || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2) >
+
                                                   (int)(pBt->usableSize*2/3)
     || pPage->nCell==1  /* See dbfuzz001.test for a test case */
    ){
      /* A b-tree rebalance will be required after deleting this entry.
@@ -75561,7 +76383,15 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
  ** been corrected, so be it. Otherwise, after balancing the leaf node,
  ** walk the cursor up the tree to the internal node and balance it as
  ** well.  */
-
  rc = balance(pCur);
+
  assert( pCur->pPage->nOverflow==0 );
+
  assert( pCur->pPage->nFree>=0 );
+
  if( pCur->pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){
+
    /* Optimization: If the free space is less than 2/3rds of the page,
+
    ** then balance() will always be a no-op.  No need to invoke it. */
+
    rc = SQLITE_OK;
+
  }else{
+
    rc = balance(pCur);
+
  }
  if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
    releasePageNotNull(pCur->pPage);
    pCur->iPage--;
@@ -78309,9 +79139,10 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
  Mem t;
  assert( pFunc!=0 );
  assert( pMem!=0 );
+
  assert( pMem->db!=0 );
  assert( pFunc->xFinalize!=0 );
  assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
-
  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+
  assert( sqlite3_mutex_held(pMem->db->mutex) );
  memset(&ctx, 0, sizeof(ctx));
  memset(&t, 0, sizeof(t));
  t.flags = MEM_Null;
@@ -78319,6 +79150,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
  ctx.pOut = &t;
  ctx.pMem = pMem;
  ctx.pFunc = pFunc;
+
  ctx.enc = ENC(t.db);
  pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
  assert( (pMem->flags & MEM_Dyn)==0 );
  if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
@@ -78340,12 +79172,14 @@ SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc
  assert( pFunc!=0 );
  assert( pFunc->xValue!=0 );
  assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef );
-
  assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) );
+
  assert( pAccum->db!=0 );
+
  assert( sqlite3_mutex_held(pAccum->db->mutex) );
  memset(&ctx, 0, sizeof(ctx));
  sqlite3VdbeMemSetNull(pOut);
  ctx.pOut = pOut;
  ctx.pMem = pAccum;
  ctx.pFunc = pFunc;
+
  ctx.enc = ENC(pAccum->db);
  pFunc->xValue(&ctx);
  return ctx.isError;
}
@@ -78411,6 +79245,14 @@ SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
  }
}

+
/* Like sqlite3VdbeMemRelease() but faster for cases where we
+
** know in advance that the Mem is not MEM_Dyn or MEM_Agg.
+
*/
+
SQLITE_PRIVATE void sqlite3VdbeMemReleaseMalloc(Mem *p){
+
  assert( !VdbeMemDynamic(p) );
+
  if( p->szMalloc ) vdbeMemClear(p);
+
}
+

/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
** If the double is out of range of a 64-bit signed integer then
@@ -78955,6 +79797,13 @@ SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
** stored without allocating memory, then it is.  If a memory allocation
** is required to store the string, then value of pMem is unchanged.  In
** either case, SQLITE_TOOBIG is returned.
+
**
+
** The "enc" parameter is the text encoding for the string, or zero
+
** to store a blob.
+
**
+
** If n is negative, then the string consists of all bytes up to but
+
** excluding the first zero character.  The n parameter must be
+
** non-negative for blobs.
*/
SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
  Mem *pMem,          /* Memory cell to set to string value */
@@ -78965,11 +79814,12 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
){
  i64 nByte = n;      /* New value for pMem->n */
  int iLimit;         /* Maximum allowed string or blob size */
-
  u16 flags = 0;      /* New value for pMem->flags */
+
  u16 flags;          /* New value for pMem->flags */

  assert( pMem!=0 );
  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
  assert( !sqlite3VdbeMemIsRowSet(pMem) );
+
  assert( enc!=0 || n>=0 );

  /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
  if( !z ){
@@ -78982,7 +79832,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
  }else{
    iLimit = SQLITE_MAX_LENGTH;
  }
-
  flags = (enc==0?MEM_Blob:MEM_Str);
  if( nByte<0 ){
    assert( enc!=0 );
    if( enc==SQLITE_UTF8 ){
@@ -78990,7 +79839,23 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
    }else{
      for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
    }
-
    flags |= MEM_Term;
+
    flags= MEM_Str|MEM_Term;
+
  }else if( enc==0 ){
+
    flags = MEM_Blob;
+
    enc = SQLITE_UTF8;
+
  }else{
+
    flags = MEM_Str;
+
  }
+
  if( nByte>iLimit ){
+
    if( xDel && xDel!=SQLITE_TRANSIENT ){
+
      if( xDel==SQLITE_DYNAMIC ){
+
        sqlite3DbFree(pMem->db, (void*)z);
+
      }else{
+
        xDel((void*)z);
+
      }
+
    }
+
    sqlite3VdbeMemSetNull(pMem);
+
    return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
  }

  /* The following block sets the new values of Mem.z and Mem.xDel. It
@@ -79002,9 +79867,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
    if( flags&MEM_Term ){
      nAlloc += (enc==SQLITE_UTF8?1:2);
    }
-
    if( nByte>iLimit ){
-
      return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
-
    }
    testcase( nAlloc==0 );
    testcase( nAlloc==31 );
    testcase( nAlloc==32 );
@@ -79026,16 +79888,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(

  pMem->n = (int)(nByte & 0x7fffffff);
  pMem->flags = flags;
-
  if( enc ){
-
    pMem->enc = enc;
-
#ifdef SQLITE_ENABLE_SESSION
-
  }else if( pMem->db==0 ){
-
    pMem->enc = SQLITE_UTF8;
-
#endif
-
  }else{
-
    assert( pMem->db!=0 );
-
    pMem->enc = ENC(pMem->db);
-
  }
+
  pMem->enc = enc;

#ifndef SQLITE_OMIT_UTF16
  if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
@@ -79043,9 +79896,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
  }
#endif

-
  if( nByte>iLimit ){
-
    return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
-
  }

  return SQLITE_OK;
}
@@ -79323,10 +80173,12 @@ static int valueFromFunction(
    goto value_from_function_out;
  }

-
  assert( pCtx->pParse->rc==SQLITE_OK );
+
  testcase( pCtx->pParse->rc==SQLITE_ERROR );
+
  testcase( pCtx->pParse->rc==SQLITE_OK );
  memset(&ctx, 0, sizeof(ctx));
  ctx.pOut = pVal;
  ctx.pFunc = pFunc;
+
  ctx.enc = ENC(db);
  pFunc->xSFunc(&ctx, nVal, apVal);
  if( ctx.isError ){
    rc = ctx.isError;
@@ -79402,8 +80254,8 @@ static int valueFromExpr(
    rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
    testcase( rc!=SQLITE_OK );
    if( *ppVal ){
-
      sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8);
-
      sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8);
+
      sqlite3VdbeMemCast(*ppVal, aff, enc);
+
      sqlite3ValueApplyAffinity(*ppVal, affinity, enc);
    }
    return rc;
  }
@@ -79837,7 +80689,7 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
  p->pNext = db->pVdbe;
  p->pPrev = 0;
  db->pVdbe = p;
-
  p->iVdbeMagic = VDBE_MAGIC_INIT;
+
  assert( p->eVdbeState==VDBE_INIT_STATE );
  p->pParse = pParse;
  pParse->pVdbe = p;
  assert( pParse->aLabel==0 );
@@ -79982,7 +80834,7 @@ static int growOpArray(Vdbe *v, int nOp){
    return SQLITE_NOMEM;
  }

-
  assert( nOp<=(1024/sizeof(Op)) );
+
  assert( nOp<=(int)(1024/sizeof(Op)) );
  assert( nNew>=(v->nOpAlloc+nOp) );
  pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
  if( pNew ){
@@ -80038,7 +80890,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
  VdbeOp *pOp;

  i = p->nOp;
-
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
+
  assert( p->eVdbeState==VDBE_INIT_STATE );
  assert( op>=0 && op<0xff );
  if( p->nOpAlloc<=i ){
    return growOp3(p, op, p1, p2, p3);
@@ -80370,7 +81222,7 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
  Parse *p = v->pParse;
  int j = ADDR(x);
-
  assert( v->iVdbeMagic==VDBE_MAGIC_INIT );
+
  assert( v->eVdbeState==VDBE_INIT_STATE );
  assert( j<-p->nLabel );
  assert( j>=0 );
#ifdef SQLITE_DEBUG
@@ -80390,14 +81242,20 @@ SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
** Mark the VDBE as one that can only be run one time.
*/
SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){
-
  p->runOnlyOnce = 1;
+
  sqlite3VdbeAddOp2(p, OP_Expire, 1, 1);
}

/*
-
** Mark the VDBE as one that can only be run multiple times.
+
** Mark the VDBE as one that can be run multiple times.
*/
SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){
-
  p->runOnlyOnce = 0;
+
  int i;
+
  for(i=1; ALWAYS(i<p->nOp); i++){
+
    if( ALWAYS(p->aOp[i].opcode==OP_Expire) ){
+
      p->aOp[1].opcode = OP_Noop;
+
      break;
+
    }
+
  }
}

#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */
@@ -80501,6 +81359,8 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
  int hasInitCoroutine = 0;
  Op *pOp;
  VdbeOpIter sIter;
+

+
  if( v==0 ) return 0;
  memset(&sIter, 0, sizeof(sIter));
  sIter.v = v;

@@ -80584,7 +81444,7 @@ SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){
** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
**     indicate what the prepared statement actually does.
**
-
** (4) Initialize the p4.xAdvance pointer on opcodes that use it.
+
** (4) (discontinued)
**
** (5) Reclaim the memory allocated for storing labels.
**
@@ -80630,25 +81490,6 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
          p->bIsReader = 1;
          break;
        }
-
        case OP_Next:
-
        case OP_SorterNext: {
-
          pOp->p4.xAdvance = sqlite3BtreeNext;
-
          pOp->p4type = P4_ADVANCE;
-
          /* The code generator never codes any of these opcodes as a jump
-
          ** to a label.  They are always coded as a jump backwards to a
-
          ** known address */
-
          assert( pOp->p2>=0 );
-
          break;
-
        }
-
        case OP_Prev: {
-
          pOp->p4.xAdvance = sqlite3BtreePrevious;
-
          pOp->p4type = P4_ADVANCE;
-
          /* The code generator never codes any of these opcodes as a jump
-
          ** to a label.  They are always coded as a jump backwards to a
-
          ** known address */
-
          assert( pOp->p2>=0 );
-
          break;
-
        }
#ifndef SQLITE_OMIT_VIRTUALTABLE
        case OP_VUpdate: {
          if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
@@ -80684,18 +81525,104 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
    if( pOp==p->aOp ) break;
    pOp--;
  }
-
  sqlite3DbFree(p->db, pParse->aLabel);
-
  pParse->aLabel = 0;
+
  if( aLabel ){
+
    sqlite3DbFreeNN(p->db, pParse->aLabel);
+
    pParse->aLabel = 0;
+
  }
  pParse->nLabel = 0;
  *pMaxFuncArgs = nMaxArgs;
  assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
}

+
#ifdef SQLITE_DEBUG
+
/*
+
** Check to see if a subroutine contains a jump to a location outside of
+
** the subroutine.  If a jump outside the subroutine is detected, add code
+
** that will cause the program to halt with an error message.
+
**
+
** The subroutine consists of opcodes between iFirst and iLast.  Jumps to
+
** locations within the subroutine are acceptable.  iRetReg is a register
+
** that contains the return address.  Jumps to outside the range of iFirst
+
** through iLast are also acceptable as long as the jump destination is
+
** an OP_Return to iReturnAddr.
+
**
+
** A jump to an unresolved label means that the jump destination will be
+
** beyond the current address.  That is normally a jump to an early
+
** termination and is consider acceptable.
+
**
+
** This routine only runs during debug builds.  The purpose is (of course)
+
** to detect invalid escapes out of a subroutine.  The OP_Halt opcode
+
** is generated rather than an assert() or other error, so that ".eqp full"
+
** will still work to show the original bytecode, to aid in debugging.
+
*/
+
SQLITE_PRIVATE void sqlite3VdbeNoJumpsOutsideSubrtn(
+
  Vdbe *v,          /* The byte-code program under construction */
+
  int iFirst,       /* First opcode of the subroutine */
+
  int iLast,        /* Last opcode of the subroutine */
+
  int iRetReg       /* Subroutine return address register */
+
){
+
  VdbeOp *pOp;
+
  Parse *pParse;
+
  int i;
+
  sqlite3_str *pErr = 0;
+
  assert( v!=0 );
+
  pParse = v->pParse;
+
  assert( pParse!=0 );
+
  if( pParse->nErr ) return;
+
  assert( iLast>=iFirst );
+
  assert( iLast<v->nOp );
+
  pOp = &v->aOp[iFirst];
+
  for(i=iFirst; i<=iLast; i++, pOp++){
+
    if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ){
+
      int iDest = pOp->p2;   /* Jump destination */
+
      if( iDest==0 ) continue;
+
      if( pOp->opcode==OP_Gosub ) continue;
+
      if( iDest<0 ){
+
        int j = ADDR(iDest);
+
        assert( j>=0 );
+
        if( j>=-pParse->nLabel || pParse->aLabel[j]<0 ){
+
          continue;
+
        }
+
        iDest = pParse->aLabel[j];
+
      }
+
      if( iDest<iFirst || iDest>iLast ){
+
        int j = iDest;
+
        for(; j<v->nOp; j++){
+
          VdbeOp *pX = &v->aOp[j];
+
          if( pX->opcode==OP_Return ){
+
            if( pX->p1==iRetReg ) break;
+
            continue;
+
          }
+
          if( pX->opcode==OP_Noop ) continue;
+
          if( pX->opcode==OP_Explain ) continue;
+
          if( pErr==0 ){
+
            pErr = sqlite3_str_new(0);
+
          }else{
+
            sqlite3_str_appendchar(pErr, 1, '\n');
+
          }
+
          sqlite3_str_appendf(pErr,
+
              "Opcode at %d jumps to %d which is outside the "
+
              "subroutine at %d..%d",
+
              i, iDest, iFirst, iLast);
+
          break;
+
        }
+
      }
+
    }
+
  }
+
  if( pErr ){
+
    char *zErr = sqlite3_str_finish(pErr);
+
    sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_INTERNAL, OE_Abort, 0, zErr, 0);
+
    sqlite3_free(zErr);
+
    sqlite3MayAbort(pParse);
+
  }
+
}
+
#endif /* SQLITE_DEBUG */
+

/*
** Return the address of the next instruction to be inserted.
*/
SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){
-
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
+
  assert( p->eVdbeState==VDBE_INIT_STATE );
  return p->nOp;
}

@@ -80780,7 +81707,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(
  int i;
  VdbeOp *pOut, *pFirst;
  assert( nOp>0 );
-
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
+
  assert( p->eVdbeState==VDBE_INIT_STATE );
  if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
    return 0;
  }
@@ -80932,7 +81859,6 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
    case P4_REAL:
    case P4_INT64:
    case P4_DYNAMIC:
-
    case P4_DYNBLOB:
    case P4_INTARRAY: {
      sqlite3DbFree(db, p4);
      break;
@@ -80972,13 +81898,16 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
** nOp entries.
*/
static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){
+
  assert( nOp>=0 );
  if( aOp ){
-
    Op *pOp;
-
    for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){
+
    Op *pOp = &aOp[nOp-1];
+
    while(1){  /* Exit via break */
      if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
      sqlite3DbFree(db, pOp->zComment);
#endif
+
      if( pOp==aOp ) break;
+
      pOp--;
    }
    sqlite3DbFreeNN(db, aOp);
  }
@@ -81040,7 +81969,7 @@ SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters(
  u32 mask,            /* Mask of registers to NOT release */
  int bUndefine        /* If true, mark registers as undefined */
){
-
  if( N==0 ) return;
+
  if( N==0 || OptimizationDisabled(pParse->db, SQLITE_ReleaseReg) ) return;
  assert( pParse->pVdbe );
  assert( iFirst>=1 );
  assert( iFirst+N-1<=pParse->nMem );
@@ -81104,7 +82033,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int
  sqlite3 *db;
  assert( p!=0 );
  db = p->db;
-
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
+
  assert( p->eVdbeState==VDBE_INIT_STATE );
  assert( p->aOp!=0 || db->mallocFailed );
  if( db->mallocFailed ){
    if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4);
@@ -81232,7 +82161,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
  /* C89 specifies that the constant "dummy" will be initialized to all
  ** zeros, which is correct.  MSVC generates a warning, nevertheless. */
  static VdbeOp dummy;  /* Ignore the MSVC warning about no initializer */
-
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
+
  assert( p->eVdbeState==VDBE_INIT_STATE );
  if( addr<0 ){
    addr = p->nOp - 1;
  }
@@ -81299,8 +82228,11 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayComment(
        if( c=='4' ){
          sqlite3_str_appendall(&x, zP4);
        }else if( c=='X' ){
-
          sqlite3_str_appendall(&x, pOp->zComment);
-
          seenCom = 1;
+
          if( pOp->zComment && pOp->zComment[0] ){
+
            sqlite3_str_appendall(&x, pOp->zComment);
+
            seenCom = 1;
+
            break;
+
          }
        }else{
          int v1 = translateP(c, pOp);
          int v2;
@@ -81529,10 +82461,6 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){
      zP4 = "program";
      break;
    }
-
    case P4_DYNBLOB:
-
    case P4_ADVANCE: {
-
      break;
-
    }
    case P4_TABLE: {
      zP4 = pOp->p4.pTab->zName;
      break;
@@ -81664,21 +82592,40 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){

/*
** Initialize an array of N Mem element.
+
**
+
** This is a high-runner, so only those fields that really do need to
+
** be initialized are set.  The Mem structure is organized so that
+
** the fields that get initialized are nearby and hopefully on the same
+
** cache line.
+
**
+
**    Mem.flags = flags
+
**    Mem.db = db
+
**    Mem.szMalloc = 0
+
**
+
** All other fields of Mem can safely remain uninitialized for now.  They
+
** will be initialized before use.
*/
static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
-
  while( (N--)>0 ){
-
    p->db = db;
-
    p->flags = flags;
-
    p->szMalloc = 0;
+
  if( N>0 ){
+
    do{
+
      p->flags = flags;
+
      p->db = db;
+
      p->szMalloc = 0;
#ifdef SQLITE_DEBUG
-
    p->pScopyFrom = 0;
+
      p->pScopyFrom = 0;
#endif
-
    p++;
+
      p++;
+
    }while( (--N)>0 );
  }
}

/*
-
** Release an array of N Mem elements
+
** Release auxiliary memory held in an array of N Mem elements.
+
**
+
** After this routine returns, all Mem elements in the array will still
+
** be valid.  Those Mem elements that were not holding auxiliary resources
+
** will be unchanged.  Mem elements which had something freed will be
+
** set to MEM_Undefined.
*/
static void releaseMemArray(Mem *p, int N){
  if( p && N ){
@@ -81711,12 +82658,17 @@ static void releaseMemArray(Mem *p, int N){
      if( p->flags&(MEM_Agg|MEM_Dyn) ){
        testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel );
        sqlite3VdbeMemRelease(p);
+
        p->flags = MEM_Undefined;
      }else if( p->szMalloc ){
        sqlite3DbFreeNN(db, p->zMalloc);
        p->szMalloc = 0;
+
        p->flags = MEM_Undefined;
      }
-

-
      p->flags = MEM_Undefined;
+
#ifdef SQLITE_DEBUG
+
      else{
+
        p->flags = MEM_Undefined;
+
      }
+
#endif
    }while( (++p)<pEnd );
  }
}
@@ -81875,7 +82827,7 @@ SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){
  VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem];
  assert( sqlite3VdbeFrameIsValid(p) );
  for(i=0; i<p->nChildCsr; i++){
-
    sqlite3VdbeFreeCursor(p->v, apCsr[i]);
+
    if( apCsr[i] ) sqlite3VdbeFreeCursorNN(p->v, apCsr[i]);
  }
  releaseMemArray(aMem, p->nChildMem);
  sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0);
@@ -81914,7 +82866,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
  Op *pOp;                             /* Current opcode */

  assert( p->explain );
-
  assert( p->iVdbeMagic==VDBE_MAGIC_RUN );
+
  assert( p->eVdbeState==VDBE_RUN_STATE );
  assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );

  /* Even though this opcode does not use dynamic strings for
@@ -82069,11 +83021,11 @@ struct ReusableSpace {
static void *allocSpace(
  struct ReusableSpace *p,  /* Bulk memory available for allocation */
  void *pBuf,               /* Pointer to a prior allocation */
-
  sqlite3_int64 nByte       /* Bytes of memory needed */
+
  sqlite3_int64 nByte       /* Bytes of memory needed. */
){
  assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
  if( pBuf==0 ){
-
    nByte = ROUND8(nByte);
+
    nByte = ROUND8P(nByte);
    if( nByte <= p->nFree ){
      p->nFree -= nByte;
      pBuf = &p->pSpace[p->nFree];
@@ -82094,14 +83046,15 @@ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
  int i;
#endif
  assert( p!=0 );
-
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT || p->iVdbeMagic==VDBE_MAGIC_RESET );
+
  assert( p->eVdbeState==VDBE_INIT_STATE
+
       || p->eVdbeState==VDBE_READY_STATE
+
       || p->eVdbeState==VDBE_HALT_STATE );

  /* There should be at least one opcode.
  */
  assert( p->nOp>0 );

-
  /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */
-
  p->iVdbeMagic = VDBE_MAGIC_RUN;
+
  p->eVdbeState = VDBE_READY_STATE;

#ifdef SQLITE_DEBUG
  for(i=0; i<p->nMem; i++){
@@ -82157,7 +83110,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
  assert( p!=0 );
  assert( p->nOp>0 );
  assert( pParse!=0 );
-
  assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
+
  assert( p->eVdbeState==VDBE_INIT_STATE );
  assert( pParse==p->pParse );
  p->pVList = pParse->pVList;
  pParse->pVList =  0;
@@ -82180,7 +83133,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
  ** opcode array.  This extra memory will be reallocated for other elements
  ** of the prepared statement.
  */
-
  n = ROUND8(sizeof(Op)*p->nOp);              /* Bytes of opcode memory used */
+
  n = ROUND8P(sizeof(Op)*p->nOp);             /* Bytes of opcode memory used */
  x.pSpace = &((u8*)p->aOp)[n];               /* Unused opcode memory */
  assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
  x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n);  /* Bytes of unused memory */
@@ -82268,9 +83221,9 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
** happens to hold.
*/
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
-
  if( pCx==0 ){
-
    return;
-
  }
+
  if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx);
+
}
+
SQLITE_PRIVATE void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){
  switch( pCx->eCurType ){
    case CURTYPE_SORTER: {
      sqlite3VdbeSorterClose(p->db, pCx);
@@ -82298,14 +83251,12 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
** Close all cursors in the current frame.
*/
static void closeCursorsInFrame(Vdbe *p){
-
  if( p->apCsr ){
-
    int i;
-
    for(i=0; i<p->nCursor; i++){
-
      VdbeCursor *pC = p->apCsr[i];
-
      if( pC ){
-
        sqlite3VdbeFreeCursor(p, pC);
-
        p->apCsr[i] = 0;
-
      }
+
  int i;
+
  for(i=0; i<p->nCursor; i++){
+
    VdbeCursor *pC = p->apCsr[i];
+
    if( pC ){
+
      sqlite3VdbeFreeCursorNN(p, pC);
+
      p->apCsr[i] = 0;
    }
  }
}
@@ -82354,9 +83305,7 @@ static void closeAllCursors(Vdbe *p){
  }
  assert( p->nFrame==0 );
  closeCursorsInFrame(p);
-
  if( p->aMem ){
-
    releaseMemArray(p->aMem, p->nMem);
-
  }
+
  releaseMemArray(p->aMem, p->nMem);
  while( p->pDelFrame ){
    VdbeFrame *pDel = p->pDelFrame;
    p->pDelFrame = pDel->pParent;
@@ -82796,7 +83745,8 @@ SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
    p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
    p->errorAction = OE_Abort;
    sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
-
    return SQLITE_ERROR;
+
    if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR;
+
    return SQLITE_CONSTRAINT_FOREIGNKEY;
  }
  return SQLITE_OK;
}
@@ -82835,9 +83785,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
  ** one, or the complete transaction if there is no statement transaction.
  */

-
  if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
-
    return SQLITE_OK;
-
  }
+
  assert( p->eVdbeState==VDBE_RUN_STATE );
  if( db->mallocFailed ){
    p->rc = SQLITE_NOMEM_BKPT;
  }
@@ -82846,7 +83794,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){

  /* No commit or rollback needed if the program never started or if the
  ** SQL statement does not read or write a database file.  */
-
  if( p->pc>=0 && p->bIsReader ){
+
  if( p->bIsReader ){
    int mrc;   /* Primary error code from p->rc */
    int eStatementOp = 0;
    int isSpecialError;            /* Set to true if a 'special' error */
@@ -82994,15 +83942,13 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
  }

  /* We have successfully halted and closed the VM.  Record this fact. */
-
  if( p->pc>=0 ){
-
    db->nVdbeActive--;
-
    if( !p->readOnly ) db->nVdbeWrite--;
-
    if( p->bIsReader ) db->nVdbeRead--;
-
    assert( db->nVdbeActive>=db->nVdbeRead );
-
    assert( db->nVdbeRead>=db->nVdbeWrite );
-
    assert( db->nVdbeWrite>=0 );
-
  }
-
  p->iVdbeMagic = VDBE_MAGIC_HALT;
+
  db->nVdbeActive--;
+
  if( !p->readOnly ) db->nVdbeWrite--;
+
  if( p->bIsReader ) db->nVdbeRead--;
+
  assert( db->nVdbeActive>=db->nVdbeRead );
+
  assert( db->nVdbeRead>=db->nVdbeWrite );
+
  assert( db->nVdbeWrite>=0 );
+
  p->eVdbeState = VDBE_HALT_STATE;
  checkActiveVdbeCnt(db);
  if( db->mallocFailed ){
    p->rc = SQLITE_NOMEM_BKPT;
@@ -83084,8 +84030,8 @@ static void vdbeInvokeSqllog(Vdbe *v){
** again.
**
** To look at it another way, this routine resets the state of the
-
** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
-
** VDBE_MAGIC_INIT.
+
** virtual machine from VDBE_RUN_STATE or VDBE_HALT_STATE back to
+
** VDBE_READY_STATE.
*/
SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
@@ -83099,7 +84045,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
  ** error, then it might not have been halted properly.  So halt
  ** it now.
  */
-
  sqlite3VdbeHalt(p);
+
  if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p);

  /* If the VDBE has been run even partially, then transfer the error code
  ** and error message from the VDBE into the main database structure.  But
@@ -83113,13 +84059,6 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
    }else{
      db->errCode = p->rc;
    }
-
    if( p->runOnlyOnce ) p->expired = 1;
-
  }else if( p->rc && p->expired ){
-
    /* The expired flag was set on the VDBE before the first call
-
    ** to sqlite3_step(). For consistency (since sqlite3_step() was
-
    ** called), set the database error in this case as well.
-
    */
-
    sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
  }

  /* Reset register contents and reclaim error message memory.
@@ -83176,7 +84115,6 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
    }
  }
#endif
-
  p->iVdbeMagic = VDBE_MAGIC_RESET;
  return p->rc & db->errMask;
}

@@ -83186,7 +84124,10 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
*/
SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
  int rc = SQLITE_OK;
-
  if( p->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){
+
  assert( VDBE_RUN_STATE>VDBE_READY_STATE );
+
  assert( VDBE_HALT_STATE>VDBE_READY_STATE );
+
  assert( VDBE_INIT_STATE<VDBE_READY_STATE );
+
  if( p->eVdbeState>=VDBE_READY_STATE ){
    rc = sqlite3VdbeReset(p);
    assert( (rc & p->db->errMask)==rc );
  }
@@ -83238,22 +84179,24 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp,
** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with
** the database connection and frees the object itself.
*/
-
SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
+
static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
  SubProgram *pSub, *pNext;
  assert( p->db==0 || p->db==db );
-
  releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+
  if( p->aColName ){
+
    releaseMemArray(p->aColName, p->nResColumn*COLNAME_N);
+
    sqlite3DbFreeNN(db, p->aColName);
+
  }
  for(pSub=p->pProgram; pSub; pSub=pNext){
    pNext = pSub->pNext;
    vdbeFreeOpArray(db, pSub->aOp, pSub->nOp);
    sqlite3DbFree(db, pSub);
  }
-
  if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){
+
  if( p->eVdbeState!=VDBE_INIT_STATE ){
    releaseMemArray(p->aVar, p->nVar);
-
    sqlite3DbFree(db, p->pVList);
-
    sqlite3DbFree(db, p->pFree);
+
    if( p->pVList ) sqlite3DbFreeNN(db, p->pVList);
+
    if( p->pFree ) sqlite3DbFreeNN(db, p->pFree);
  }
  vdbeFreeOpArray(db, p->aOp, p->nOp);
-
  sqlite3DbFree(db, p->aColName);
  sqlite3DbFree(db, p->zSql);
#ifdef SQLITE_ENABLE_NORMALIZE
  sqlite3DbFree(db, p->zNormSql);
@@ -83286,17 +84229,17 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
  db = p->db;
  assert( sqlite3_mutex_held(db->mutex) );
  sqlite3VdbeClearObject(db, p);
-
  if( p->pPrev ){
-
    p->pPrev->pNext = p->pNext;
-
  }else{
-
    assert( db->pVdbe==p );
-
    db->pVdbe = p->pNext;
-
  }
-
  if( p->pNext ){
-
    p->pNext->pPrev = p->pPrev;
+
  if( db->pnBytesFreed==0 ){
+
    if( p->pPrev ){
+
      p->pPrev->pNext = p->pNext;
+
    }else{
+
      assert( db->pVdbe==p );
+
      db->pVdbe = p->pNext;
+
    }
+
    if( p->pNext ){
+
      p->pNext->pPrev = p->pPrev;
+
    }
  }
-
  p->iVdbeMagic = VDBE_MAGIC_DEAD;
-
  p->db = 0;
  sqlite3DbFreeNN(db, p);
}

@@ -83331,7 +84274,7 @@ SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){
** is supposed to be pointing.  If the row was deleted out from under the
** cursor, set the cursor to point to a NULL row.
*/
-
static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
+
SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){
  int isDifferentRow, rc;
  assert( p->eCurType==CURTYPE_BTREE );
  assert( p->uc.pCursor!=0 );
@@ -83347,41 +84290,9 @@ static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
** if need be.  Return any I/O error from the restore operation.
*/
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
-
  assert( p->eCurType==CURTYPE_BTREE );
+
  assert( p->eCurType==CURTYPE_BTREE || IsNullCursor(p) );
  if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
-
    return handleMovedCursor(p);
-
  }
-
  return SQLITE_OK;
-
}
-

-
/*
-
** Make sure the cursor p is ready to read or write the row to which it
-
** was last positioned.  Return an error code if an OOM fault or I/O error
-
** prevents us from positioning the cursor to its correct position.
-
**
-
** If a MoveTo operation is pending on the given cursor, then do that
-
** MoveTo now.  If no move is pending, check to see if the row has been
-
** deleted out from under the cursor and if it has, mark the row as
-
** a NULL row.
-
**
-
** If the cursor is already pointing to the correct row and that row has
-
** not been deleted out from under the cursor, then this routine is a no-op.
-
*/
-
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){
-
  VdbeCursor *p = *pp;
-
  assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO );
-
  if( p->deferredMoveto ){
-
    u32 iMap;
-
    assert( !p->isEphemeral );
-
    if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){
-
      *pp = p->pAltCursor;
-
      *piCol = iMap - 1;
-
      return SQLITE_OK;
-
    }
-
    return sqlite3VdbeFinishMoveto(p);
-
  }
-
  if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
-
    return handleMovedCursor(p);
+
    return sqlite3VdbeHandleMovedCursor(p);
  }
  return SQLITE_OK;
}
@@ -83392,7 +84303,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){
** sqlite3VdbeSerialType()
** sqlite3VdbeSerialTypeLen()
** sqlite3VdbeSerialLen()
-
** sqlite3VdbeSerialPut()
+
** sqlite3VdbeSerialPut()  <--- in-lined into OP_MakeRecord as of 2022-04-02
** sqlite3VdbeSerialGet()
**
** encapsulate the code that serializes values for storage in SQLite
@@ -83504,7 +84415,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){
/*
** The sizes for serial types less than 128
*/
-
static const u8 sqlite3SmallTypeSizes[] = {
+
SQLITE_PRIVATE const u8 sqlite3SmallTypeSizes[128] = {
        /*  0   1   2   3   4   5   6   7   8   9 */
/*   0 */   0,  1,  2,  3,  4,  6,  8,  8,  0,  0,
/*  10 */   0,  0,  0,  0,  1,  1,  2,  2,  3,  3,
@@ -83573,7 +84484,7 @@ SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){
** so we trust him.
*/
#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
-
static u64 floatSwap(u64 in){
+
SQLITE_PRIVATE u64 sqlite3FloatSwap(u64 in){
  union {
    u64 r;
    u32 i[2];
@@ -83586,59 +84497,8 @@ static u64 floatSwap(u64 in){
  u.i[1] = t;
  return u.r;
}
-
# define swapMixedEndianFloat(X)  X = floatSwap(X)
-
#else
-
# define swapMixedEndianFloat(X)
-
#endif
+
#endif /* SQLITE_MIXED_ENDIAN_64BIT_FLOAT */

-
/*
-
** Write the serialized data blob for the value stored in pMem into
-
** buf. It is assumed that the caller has allocated sufficient space.
-
** Return the number of bytes written.
-
**
-
** nBuf is the amount of space left in buf[].  The caller is responsible
-
** for allocating enough space to buf[] to hold the entire field, exclusive
-
** of the pMem->u.nZero bytes for a MEM_Zero value.
-
**
-
** Return the number of bytes actually written into buf[].  The number
-
** of bytes in the zero-filled tail is included in the return value only
-
** if those bytes were zeroed in buf[].
-
*/
-
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
-
  u32 len;
-

-
  /* Integer and Real */
-
  if( serial_type<=7 && serial_type>0 ){
-
    u64 v;
-
    u32 i;
-
    if( serial_type==7 ){
-
      assert( sizeof(v)==sizeof(pMem->u.r) );
-
      memcpy(&v, &pMem->u.r, sizeof(v));
-
      swapMixedEndianFloat(v);
-
    }else{
-
      v = pMem->u.i;
-
    }
-
    len = i = sqlite3SmallTypeSizes[serial_type];
-
    assert( i>0 );
-
    do{
-
      buf[--i] = (u8)(v&0xFF);
-
      v >>= 8;
-
    }while( i );
-
    return len;
-
  }
-

-
  /* String or blob */
-
  if( serial_type>=12 ){
-
    assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
-
             == (int)sqlite3VdbeSerialTypeLen(serial_type) );
-
    len = pMem->n;
-
    if( len>0 ) memcpy(buf, pMem->z, len);
-
    return len;
-
  }
-

-
  /* NULL or constants 0 or 1 */
-
  return 0;
-
}

/* Input "x" is a sequence of unsigned characters that represent a
** big-endian integer.  Return the equivalent native integer
@@ -83804,10 +84664,10 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
){
  UnpackedRecord *p;              /* Unpacked record to return */
  int nByte;                      /* Number of bytes required for *p */
-
  nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
+
  nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
  p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
  if( !p ) return 0;
-
  p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))];
+
  p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))];
  assert( pKeyInfo->aSortFlags!=0 );
  p->pKeyInfo = pKeyInfo;
  p->nField = pKeyInfo->nKeyField + 1;
@@ -84043,8 +84903,8 @@ static int vdbeCompareMemString(
    }else{
      rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2);
    }
-
    sqlite3VdbeMemRelease(&c1);
-
    sqlite3VdbeMemRelease(&c2);
+
    sqlite3VdbeMemReleaseMalloc(&c1);
+
    sqlite3VdbeMemReleaseMalloc(&c2);
    return rc;
  }
}
@@ -84305,14 +85165,22 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
  ** two elements in the keys are equal. Fix the various stack variables so
  ** that this routine begins comparing at the second field. */
  if( bSkip ){
-
    u32 s1;
-
    idx1 = 1 + getVarint32(&aKey1[1], s1);
+
    u32 s1 = aKey1[1];
+
    if( s1<0x80 ){
+
      idx1 = 2;
+
    }else{
+
      idx1 = 1 + sqlite3GetVarint32(&aKey1[1], &s1);
+
    }
    szHdr1 = aKey1[0];
    d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
    i = 1;
    pRhs++;
  }else{
-
    idx1 = getVarint32(aKey1, szHdr1);
+
    if( (szHdr1 = aKey1[0])<0x80 ){
+
      idx1 = 1;
+
    }else{
+
      idx1 = sqlite3GetVarint32(aKey1, &szHdr1);
+
    }
    d1 = szHdr1;
    i = 0;
  }
@@ -84568,7 +85436,8 @@ static int vdbeRecordCompareInt(
      return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
  }

-
  v = pPKey2->aMem[0].u.i;
+
  assert( pPKey2->u.i == pPKey2->aMem[0].u.i );
+
  v = pPKey2->u.i;
  if( v>lhs ){
    res = pPKey2->r1;
  }else if( v<lhs ){
@@ -84603,12 +85472,18 @@ static int vdbeRecordCompareString(
  int res;

  assert( pPKey2->aMem[0].flags & MEM_Str );
+
  assert( pPKey2->aMem[0].n == pPKey2->n );
+
  assert( pPKey2->aMem[0].z == pPKey2->u.z );
  vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
-
  serial_type = (u8)(aKey1[1]);
-
  if( serial_type >= 0x80 ){
-
    sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
-
  }
+
  serial_type = (signed char)(aKey1[1]);
+

+
vrcs_restart:
  if( serial_type<12 ){
+
    if( serial_type<0 ){
+
      sqlite3GetVarint32(&aKey1[1], (u32*)&serial_type);
+
      if( serial_type>=12 ) goto vrcs_restart;
+
      assert( CORRUPT_DB );
+
    }
    res = pPKey2->r1;      /* (pKey1/nKey1) is a number or a null */
  }else if( !(serial_type & 0x01) ){
    res = pPKey2->r2;      /* (pKey1/nKey1) is a blob */
@@ -84622,15 +85497,15 @@ static int vdbeRecordCompareString(
      pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
      return 0;    /* Corruption */
    }
-
    nCmp = MIN( pPKey2->aMem[0].n, nStr );
-
    res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
+
    nCmp = MIN( pPKey2->n, nStr );
+
    res = memcmp(&aKey1[szHdr], pPKey2->u.z, nCmp);

    if( res>0 ){
      res = pPKey2->r2;
    }else if( res<0 ){
      res = pPKey2->r1;
    }else{
-
      res = nStr - pPKey2->aMem[0].n;
+
      res = nStr - pPKey2->n;
      if( res==0 ){
        if( pPKey2->nField>1 ){
          res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
@@ -84685,6 +85560,7 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
      p->r2 = 1;
    }
    if( (flags & MEM_Int) ){
+
      p->u.i = p->aMem[0].u.i;
      return vdbeRecordCompareInt;
    }
    testcase( flags & MEM_Real );
@@ -84694,6 +85570,8 @@ SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
     && p->pKeyInfo->aColl[0]==0
    ){
      assert( flags & MEM_Str );
+
      p->u.z = p->aMem[0].z;
+
      p->n = p->aMem[0].n;
      return vdbeRecordCompareString;
    }
  }
@@ -84766,14 +85644,14 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
  /* Fetch the integer off the end of the index record */
  sqlite3VdbeSerialGet((u8*)&m.z[m.n-lenRowid], typeRowid, &v);
  *rowid = v.u.i;
-
  sqlite3VdbeMemRelease(&m);
+
  sqlite3VdbeMemReleaseMalloc(&m);
  return SQLITE_OK;

  /* Jump here if database corruption is detected after m has been
  ** allocated.  Free the m object and return SQLITE_CORRUPT. */
idx_rowid_corruption:
  testcase( m.szMalloc!=0 );
-
  sqlite3VdbeMemRelease(&m);
+
  sqlite3VdbeMemReleaseMalloc(&m);
  return SQLITE_CORRUPT_BKPT;
}

@@ -84815,7 +85693,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
    return rc;
  }
  *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0);
-
  sqlite3VdbeMemRelease(&m);
+
  sqlite3VdbeMemReleaseMalloc(&m);
  return SQLITE_OK;
}

@@ -84982,7 +85860,7 @@ static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){
    int i;
    for(i=0; i<nField; i++){
      Mem *pMem = &p->aMem[i];
-
      if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem);
+
      if( pMem->zMalloc ) sqlite3VdbeMemReleaseMalloc(pMem);
    }
    sqlite3DbFreeNN(db, p);
  }
@@ -85409,6 +86287,9 @@ SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
      sqlite3ValueFree(pNew);
      pNew = 0;
    }
+
  }else if( pNew->flags & MEM_Null ){
+
    /* Do not duplicate pointer values */
+
    pNew->flags &= ~(MEM_Term|MEM_Subtype);
  }
  return pNew;
}
@@ -85439,7 +86320,8 @@ static void setResultStrOrError(
  u8 enc,                 /* Encoding of z.  0 for BLOBs */
  void (*xDel)(void*)     /* Destructor function */
){
-
  int rc = sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel);
+
  Mem *pOut = pCtx->pOut;
+
  int rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel);
  if( rc ){
    if( rc==SQLITE_TOOBIG ){
      sqlite3_result_error_toobig(pCtx);
@@ -85449,6 +86331,11 @@ static void setResultStrOrError(
      assert( rc==SQLITE_NOMEM );
      sqlite3_result_error_nomem(pCtx);
    }
+
    return;
+
  }
+
  sqlite3VdbeChangeEncoding(pOut, pCtx->enc);
+
  if( sqlite3VdbeMemTooBig(pOut) ){
+
    sqlite3_result_error_toobig(pCtx);
  }
}
static int invokeValueDestructor(
@@ -85592,17 +86479,22 @@ SQLITE_API void sqlite3_result_text16le(
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
+
  Mem *pOut = pCtx->pOut;
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
-
  sqlite3VdbeMemCopy(pCtx->pOut, pValue);
+
  sqlite3VdbeMemCopy(pOut, pValue);
+
  sqlite3VdbeChangeEncoding(pOut, pCtx->enc);
+
  if( sqlite3VdbeMemTooBig(pOut) ){
+
    sqlite3_result_error_toobig(pCtx);
+
  }
}
SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
-
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
-
  sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
+
  sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0);
}
SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){
  Mem *pOut = pCtx->pOut;
  assert( sqlite3_mutex_held(pOut->db->mutex) );
  if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
+
    sqlite3_result_error_toobig(pCtx);
    return SQLITE_TOOBIG;
  }
#ifndef SQLITE_OMIT_INCRBLOB
@@ -85618,8 +86510,8 @@ SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
  if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
#endif
  if( pCtx->pOut->flags & MEM_Null ){
-
    sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1,
-
                         SQLITE_UTF8, SQLITE_STATIC);
+
    setResultStrOrError(pCtx, sqlite3ErrStr(errCode), -1, SQLITE_UTF8,
+
                        SQLITE_STATIC);
  }
}

@@ -85693,80 +86585,83 @@ static int sqlite3Step(Vdbe *p){
  int rc;

  assert(p);
-
  if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){
-
    /* We used to require that sqlite3_reset() be called before retrying
-
    ** sqlite3_step() after any error or after SQLITE_DONE.  But beginning
-
    ** with version 3.7.0, we changed this so that sqlite3_reset() would
-
    ** be called automatically instead of throwing the SQLITE_MISUSE error.
-
    ** This "automatic-reset" change is not technically an incompatibility,
-
    ** since any application that receives an SQLITE_MISUSE is broken by
-
    ** definition.
-
    **
-
    ** Nevertheless, some published applications that were originally written
-
    ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
-
    ** returns, and those were broken by the automatic-reset change.  As a
-
    ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
-
    ** legacy behavior of returning SQLITE_MISUSE for cases where the
-
    ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
-
    ** or SQLITE_BUSY error.
-
    */
-
#ifdef SQLITE_OMIT_AUTORESET
-
    if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
-
      sqlite3_reset((sqlite3_stmt*)p);
-
    }else{
-
      return SQLITE_MISUSE_BKPT;
-
    }
-
#else
-
    sqlite3_reset((sqlite3_stmt*)p);
-
#endif
-
  }
-

-
  /* Check that malloc() has not failed. If it has, return early. */
  db = p->db;
-
  if( db->mallocFailed ){
-
    p->rc = SQLITE_NOMEM;
-
    return SQLITE_NOMEM_BKPT;
-
  }
+
  if( p->eVdbeState!=VDBE_RUN_STATE ){
+
    restart_step:
+
    if( p->eVdbeState==VDBE_READY_STATE ){
+
      if( p->expired ){
+
        p->rc = SQLITE_SCHEMA;
+
        rc = SQLITE_ERROR;
+
        if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){
+
          /* If this statement was prepared using saved SQL and an
+
          ** error has occurred, then return the error code in p->rc to the
+
          ** caller. Set the error code in the database handle to the same
+
          ** value.
+
          */
+
          rc = sqlite3VdbeTransferError(p);
+
        }
+
        goto end_of_step;
+
      }

-
  if( p->pc<0 && p->expired ){
-
    p->rc = SQLITE_SCHEMA;
-
    rc = SQLITE_ERROR;
-
    if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){
-
      /* If this statement was prepared using saved SQL and an
-
      ** error has occurred, then return the error code in p->rc to the
-
      ** caller. Set the error code in the database handle to the same value.
+
      /* If there are no other statements currently running, then
+
      ** reset the interrupt flag.  This prevents a call to sqlite3_interrupt
+
      ** from interrupting a statement that has not yet started.
      */
-
      rc = sqlite3VdbeTransferError(p);
-
    }
-
    goto end_of_step;
-
  }
-
  if( p->pc<0 ){
-
    /* If there are no other statements currently running, then
-
    ** reset the interrupt flag.  This prevents a call to sqlite3_interrupt
-
    ** from interrupting a statement that has not yet started.
-
    */
-
    if( db->nVdbeActive==0 ){
-
      AtomicStore(&db->u1.isInterrupted, 0);
-
    }
+
      if( db->nVdbeActive==0 ){
+
        AtomicStore(&db->u1.isInterrupted, 0);
+
      }

-
    assert( db->nVdbeWrite>0 || db->autoCommit==0
-
        || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
-
    );
+
      assert( db->nVdbeWrite>0 || db->autoCommit==0
+
          || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
+
      );

#ifndef SQLITE_OMIT_TRACE
-
    if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
-
        && !db->init.busy && p->zSql ){
-
      sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
-
    }else{
-
      assert( p->startTime==0 );
-
    }
+
      if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
+
          && !db->init.busy && p->zSql ){
+
        sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
+
      }else{
+
        assert( p->startTime==0 );
+
      }
#endif

-
    db->nVdbeActive++;
-
    if( p->readOnly==0 ) db->nVdbeWrite++;
-
    if( p->bIsReader ) db->nVdbeRead++;
-
    p->pc = 0;
+
      db->nVdbeActive++;
+
      if( p->readOnly==0 ) db->nVdbeWrite++;
+
      if( p->bIsReader ) db->nVdbeRead++;
+
      p->pc = 0;
+
      p->eVdbeState = VDBE_RUN_STATE;
+
    }else
+

+
    if( ALWAYS(p->eVdbeState==VDBE_HALT_STATE) ){
+
      /* We used to require that sqlite3_reset() be called before retrying
+
      ** sqlite3_step() after any error or after SQLITE_DONE.  But beginning
+
      ** with version 3.7.0, we changed this so that sqlite3_reset() would
+
      ** be called automatically instead of throwing the SQLITE_MISUSE error.
+
      ** This "automatic-reset" change is not technically an incompatibility,
+
      ** since any application that receives an SQLITE_MISUSE is broken by
+
      ** definition.
+
      **
+
      ** Nevertheless, some published applications that were originally written
+
      ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE
+
      ** returns, and those were broken by the automatic-reset change.  As a
+
      ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
+
      ** legacy behavior of returning SQLITE_MISUSE for cases where the
+
      ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
+
      ** or SQLITE_BUSY error.
+
      */
+
#ifdef SQLITE_OMIT_AUTORESET
+
      if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
+
        sqlite3_reset((sqlite3_stmt*)p);
+
      }else{
+
        return SQLITE_MISUSE_BKPT;
+
      }
+
#else
+
      sqlite3_reset((sqlite3_stmt*)p);
+
#endif
+
      assert( p->eVdbeState==VDBE_READY_STATE );
+
      goto restart_step;
+
    }
  }
+

#ifdef SQLITE_DEBUG
  p->rcApp = SQLITE_OK;
#endif
@@ -85781,7 +86676,12 @@ static int sqlite3Step(Vdbe *p){
    db->nVdbeExec--;
  }

-
  if( rc!=SQLITE_ROW ){
+
  if( rc==SQLITE_ROW ){
+
    assert( p->rc==SQLITE_OK );
+
    assert( db->mallocFailed==0 );
+
    db->errCode = SQLITE_ROW;
+
    return SQLITE_ROW;
+
  }else{
#ifndef SQLITE_OMIT_TRACE
    /* If the statement completed successfully, invoke the profile callback */
    checkProfileCallback(db, p);
@@ -85833,7 +86733,6 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
  }
  db = v->db;
  sqlite3_mutex_enter(db->mutex);
-
  v->doingRerun = 0;
  while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
         && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
    int savedPc = v->pc;
@@ -85859,7 +86758,13 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
      break;
    }
    sqlite3_reset(pStmt);
-
    if( savedPc>=0 ) v->doingRerun = 1;
+
    if( savedPc>=0 ){
+
      /* Setting minWriteFileFormat to 254 is a signal to the OP_Init and
+
      ** OP_Trace opcodes to *not* perform SQLITE_TRACE_STMT because it has
+
      ** already been done once on a prior invocation that failed due to
+
      ** SQLITE_SCHEMA.   tag-20220401a  */
+
      v->minWriteFileFormat = 254;
+
    }
    assert( v->expired==0 );
  }
  sqlite3_mutex_leave(db->mutex);
@@ -86168,15 +87073,15 @@ static const Mem *columnNullValue(void){
#endif
    = {
        /* .u          = */ {0},
+
        /* .z          = */ (char*)0,
+
        /* .n          = */ (int)0,
        /* .flags      = */ (u16)MEM_Null,
        /* .enc        = */ (u8)0,
        /* .eSubtype   = */ (u8)0,
-
        /* .n          = */ (int)0,
-
        /* .z          = */ (char*)0,
-
        /* .zMalloc    = */ (char*)0,
+
        /* .db         = */ (sqlite3*)0,
        /* .szMalloc   = */ (int)0,
        /* .uTemp      = */ (u32)0,
-
        /* .db         = */ (sqlite3*)0,
+
        /* .zMalloc    = */ (char*)0,
        /* .xDel       = */ (void(*)(void*))0,
#ifdef SQLITE_DEBUG
        /* .pScopyFrom = */ (Mem*)0,
@@ -86473,7 +87378,7 @@ static int vdbeUnbind(Vdbe *p, int i){
    return SQLITE_MISUSE_BKPT;
  }
  sqlite3_mutex_enter(p->db->mutex);
-
  if( p->iVdbeMagic!=VDBE_MAGIC_RUN || p->pc>=0 ){
+
  if( p->eVdbeState!=VDBE_READY_STATE ){
    sqlite3Error(p->db, SQLITE_MISUSE);
    sqlite3_mutex_leave(p->db->mutex);
    sqlite3_log(SQLITE_MISUSE,
@@ -86826,7 +87731,7 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){
*/
SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
  Vdbe *v = (Vdbe*)pStmt;
-
  return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0;
+
  return v!=0 && v->eVdbeState==VDBE_RUN_STATE;
}

/*
@@ -86872,8 +87777,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
    sqlite3_mutex_enter(db->mutex);
    v = 0;
    db->pnBytesFreed = (int*)&v;
-
    sqlite3VdbeClearObject(db, pVdbe);
-
    sqlite3DbFree(db, pVdbe);
+
    sqlite3VdbeDelete(pVdbe);
    db->pnBytesFreed = 0;
    sqlite3_mutex_leave(db->mutex);
  }else{
@@ -87666,12 +88570,12 @@ static VdbeCursor *allocateCursor(
  int nByte;
  VdbeCursor *pCx = 0;
  nByte =
-
      ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField +
+
      ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField +
      (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);

  assert( iCur>=0 && iCur<p->nCursor );
  if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
-
    sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
+
    sqlite3VdbeFreeCursorNN(p, p->apCsr[iCur]);
    p->apCsr[iCur] = 0;
  }

@@ -87701,7 +88605,7 @@ static VdbeCursor *allocateCursor(
  pCx->aOffset = &pCx->aType[nField];
  if( eCurType==CURTYPE_BTREE ){
    pCx->uc.pCursor = (BtCursor*)
-
        &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
+
        &pMem->z[ROUND8P(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
    sqlite3BtreeCursorZero(pCx->uc.pCursor);
  }
  return pCx;
@@ -88140,7 +89044,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
#endif
  /*** INSERT STACK UNION HERE ***/

-
  assert( p->iVdbeMagic==VDBE_MAGIC_RUN );  /* sqlite3_step() verifies this */
+
  assert( p->eVdbeState==VDBE_RUN_STATE );  /* sqlite3_step() verifies this */
  sqlite3VdbeEnter(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  if( db->xProgress ){
@@ -88383,26 +89287,39 @@ case OP_Gosub: { /* jump */
  pIn1->flags = MEM_Int;
  pIn1->u.i = (int)(pOp-aOp);
  REGISTER_TRACE(pOp->p1, pIn1);
-

-
  /* Most jump operations do a goto to this spot in order to update
-
  ** the pOp pointer. */
-
jump_to_p2:
-
  assert( pOp->p2>0 );       /* There are never any jumps to instruction 0 */
-
  assert( pOp->p2<p->nOp );  /* Jumps must be in range */
-
  pOp = &aOp[pOp->p2 - 1];
-
  break;
+
  goto jump_to_p2_and_check_for_interrupt;
}

-
/* Opcode:  Return P1 * * * *
+
/* Opcode:  Return P1 P2 P3 * *
+
**
+
** Jump to the address stored in register P1.  If P1 is a return address
+
** register, then this accomplishes a return from a subroutine.
+
**
+
** If P3 is 1, then the jump is only taken if register P1 holds an integer
+
** values, otherwise execution falls through to the next opcode, and the
+
** OP_Return becomes a no-op. If P3 is 0, then register P1 must hold an
+
** integer or else an assert() is raised.  P3 should be set to 1 when
+
** this opcode is used in combination with OP_BeginSubrtn, and set to 0
+
** otherwise.
+
**
+
** The value in register P1 is unchanged by this opcode.
**
-
** Jump to the next instruction after the address in register P1.  After
-
** the jump, register P1 becomes undefined.
+
** P2 is not used by the byte-code engine.  However, if P2 is positive
+
** and also less than the current address, then the "EXPLAIN" output
+
** formatter in the CLI will indent all opcodes from the P2 opcode up
+
** to be not including the current Return.   P2 should be the first opcode
+
** in the subroutine from which this opcode is returning.  Thus the P2
+
** value is a byte-code indentation hint.  See tag-20220407a in
+
** wherecode.c and shell.c.
*/
case OP_Return: {           /* in1 */
  pIn1 = &aMem[pOp->p1];
-
  assert( pIn1->flags==MEM_Int );
-
  pOp = &aOp[pIn1->u.i];
-
  pIn1->flags = MEM_Undefined;
+
  if( pIn1->flags & MEM_Int ){
+
    if( pOp->p3 ){ VdbeBranchTaken(1, 2); }
+
    pOp = &aOp[pIn1->u.i];
+
  }else if( ALWAYS(pOp->p3) ){
+
    VdbeBranchTaken(0, 2);
+
  }
  break;
}

@@ -88425,7 +89342,14 @@ case OP_InitCoroutine: { /* jump */
  assert( !VdbeMemDynamic(pOut) );
  pOut->u.i = pOp->p3 - 1;
  pOut->flags = MEM_Int;
-
  if( pOp->p2 ) goto jump_to_p2;
+
  if( pOp->p2==0 ) break;
+

+
  /* Most jump operations do a goto to this spot in order to update
+
  ** the pOp pointer. */
+
jump_to_p2:
+
  assert( pOp->p2>0 );       /* There are never any jumps to instruction 0 */
+
  assert( pOp->p2<p->nOp );  /* Jumps must be in range */
+
  pOp = &aOp[pOp->p2 - 1];
  break;
}

@@ -88527,11 +89451,10 @@ case OP_Halt: {
  VdbeFrame *pFrame;
  int pcx;

-
  pcx = (int)(pOp - aOp);
#ifdef SQLITE_DEBUG
  if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
#endif
-
  if( pOp->p1==SQLITE_OK && p->pFrame ){
+
  if( p->pFrame && pOp->p1==SQLITE_OK ){
    /* Halt the sub-program. Return control to the parent frame. */
    pFrame = p->pFrame;
    p->pFrame = pFrame->pParent;
@@ -88553,7 +89476,6 @@ case OP_Halt: {
  }
  p->rc = pOp->p1;
  p->errorAction = (u8)pOp->p2;
-
  p->pc = pcx;
  assert( pOp->p5<=4 );
  if( p->rc ){
    if( pOp->p5 ){
@@ -88570,6 +89492,7 @@ case OP_Halt: {
    }else{
      sqlite3VdbeError(p, "%s", pOp->p4.z);
    }
+
    pcx = (int)(pOp - aOp);
    sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg);
  }
  rc = sqlite3VdbeHalt(p);
@@ -88695,6 +89618,28 @@ case OP_String: { /* out2 */
  break;
}

+
/* Opcode: BeginSubrtn * P2 * * *
+
** Synopsis: r[P2]=NULL
+
**
+
** Mark the beginning of a subroutine that can be entered in-line
+
** or that can be called using OP_Gosub.  The subroutine should
+
** be terminated by an OP_Return instruction that has a P1 operand that
+
** is the same as the P2 operand to this opcode and that has P3 set to 1.
+
** If the subroutine is entered in-line, then the OP_Return will simply
+
** fall through.  But if the subroutine is entered using OP_Gosub, then
+
** the OP_Return will jump back to the first instruction after the OP_Gosub.
+
**
+
** This routine works by loading a NULL into the P2 register.  When the
+
** return address register contains a NULL, the OP_Return instruction is
+
** a no-op that simply falls through to the next instruction (assuming that
+
** the OP_Return opcode has a P3 value of 1).  Thus if the subroutine is
+
** entered in-line, then the OP_Return will cause in-line execution to
+
** continue.  But if the subroutine is entered via OP_Gosub, then the
+
** OP_Return will cause a return to the address following the OP_Gosub.
+
**
+
** This opcode is identical to OP_Null.  It has a different name
+
** only to make the byte code easier to read and verify.
+
*/
/* Opcode: Null P1 P2 P3 * *
** Synopsis: r[P2..P3]=NULL
**
@@ -88707,6 +89652,7 @@ case OP_String: { /* out2 */
** NULL values will not compare equal even if SQLITE_NULLEQ is set on
** OP_Ne or OP_Eq.
*/
+
case OP_BeginSubrtn:
case OP_Null: {           /* out2 */
  int cnt;
  u16 nullFlag;
@@ -88837,11 +89783,16 @@ case OP_Move: {
  break;
}

-
/* Opcode: Copy P1 P2 P3 * *
+
/* Opcode: Copy P1 P2 P3 * P5
** Synopsis: r[P2@P3+1]=r[P1@P3+1]
**
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
**
+
** If the 0x0002 bit of P5 is set then also clear the MEM_Subtype flag in the
+
** destination.  The 0x0001 bit of P5 indicates that this Copy opcode cannot
+
** be merged.  The 0x0001 bit is used by the query planner and does not
+
** come into play during query execution.
+
**
** This instruction makes a deep copy of the value.  A duplicate
** is made of any string or blob constant.  See also OP_SCopy.
*/
@@ -88856,6 +89807,9 @@ case OP_Copy: {
    memAboutToChange(p, pOut);
    sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem);
    Deephemeralize(pOut);
+
    if( (pOut->flags & MEM_Subtype)!=0 &&  (pOp->p5 & 0x0002)!=0 ){
+
      pOut->flags &= ~MEM_Subtype;
+
    }
#ifdef SQLITE_DEBUG
    pOut->pScopyFrom = 0;
#endif
@@ -88936,45 +89890,32 @@ case OP_FkCheck: {
** the result row.
*/
case OP_ResultRow: {
-
  Mem *pMem;
-
  int i;
  assert( p->nResColumn==pOp->p2 );
  assert( pOp->p1>0 || CORRUPT_DB );
  assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );

-
  /* Invalidate all ephemeral cursor row caches */
  p->cacheCtr = (p->cacheCtr + 2)|1;
-

-
  /* Make sure the results of the current row are \000 terminated
-
  ** and have an assigned type.  The results are de-ephemeralized as
-
  ** a side effect.
-
  */
-
  pMem = p->pResultSet = &aMem[pOp->p1];
-
  for(i=0; i<pOp->p2; i++){
-
    assert( memIsValid(&pMem[i]) );
-
    Deephemeralize(&pMem[i]);
-
    assert( (pMem[i].flags & MEM_Ephem)==0
-
            || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 );
-
    sqlite3VdbeMemNulTerminate(&pMem[i]);
-
    REGISTER_TRACE(pOp->p1+i, &pMem[i]);
+
  p->pResultSet = &aMem[pOp->p1];
#ifdef SQLITE_DEBUG
-
    /* The registers in the result will not be used again when the
-
    ** prepared statement restarts.  This is because sqlite3_column()
-
    ** APIs might have caused type conversions of made other changes to
-
    ** the register values.  Therefore, we can go ahead and break any
-
    ** OP_SCopy dependencies. */
-
    pMem[i].pScopyFrom = 0;
-
#endif
+
  {
+
    Mem *pMem = p->pResultSet;
+
    int i;
+
    for(i=0; i<pOp->p2; i++){
+
      assert( memIsValid(&pMem[i]) );
+
      REGISTER_TRACE(pOp->p1+i, &pMem[i]);
+
      /* The registers in the result will not be used again when the
+
      ** prepared statement restarts.  This is because sqlite3_column()
+
      ** APIs might have caused type conversions of made other changes to
+
      ** the register values.  Therefore, we can go ahead and break any
+
      ** OP_SCopy dependencies. */
+
      pMem[i].pScopyFrom = 0;
+
    }
  }
+
#endif
  if( db->mallocFailed ) goto no_mem;
-

  if( db->mTrace & SQLITE_TRACE_ROW ){
    db->trace.xV2(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
  }
-

-

-
  /* Return SQLITE_ROW
-
  */
  p->pc = (int)(pOp - aOp) + 1;
  rc = SQLITE_ROW;
  goto vdbe_return;
@@ -89029,7 +89970,7 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
  if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
    goto too_big;
  }
-
  if( sqlite3VdbeMemGrow(pOut, (int)nByte+3, pOut==pIn2) ){
+
  if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
    goto no_mem;
  }
  MemSetTypeFlag(pOut, MEM_Str);
@@ -89041,9 +89982,9 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
  memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
  assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
  pIn1->flags = flags1;
+
  if( encoding>SQLITE_UTF8 ) nByte &= ~1;
  pOut->z[nByte]=0;
  pOut->z[nByte+1] = 0;
-
  pOut->z[nByte+2] = 0;
  pOut->flags |= MEM_Term;
  pOut->n = (int)nByte;
  pOut->enc = encoding;
@@ -89488,23 +90429,23 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
    assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB );
    /* Common case of comparison of two integers */
    if( pIn3->u.i > pIn1->u.i ){
-
      iCompare = +1;
      if( sqlite3aGTb[pOp->opcode] ){
        VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
        goto jump_to_p2;
      }
+
      iCompare = +1;
    }else if( pIn3->u.i < pIn1->u.i ){
-
      iCompare = -1;
      if( sqlite3aLTb[pOp->opcode] ){
        VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
        goto jump_to_p2;
      }
+
      iCompare = -1;
    }else{
-
      iCompare = 0;
      if( sqlite3aEQb[pOp->opcode] ){
        VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
        goto jump_to_p2;
      }
+
      iCompare = 0;
    }
    VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
    break;
@@ -89531,11 +90472,11 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
      ** then the result is always NULL.
      ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
      */
-
      iCompare = 1;    /* Operands are not equal */
      VdbeBranchTaken(2,3);
      if( pOp->p5 & SQLITE_JUMPIFNULL ){
        goto jump_to_p2;
      }
+
      iCompare = 1;    /* Operands are not equal */
      break;
    }
  }else{
@@ -89641,9 +90582,8 @@ case OP_ElseEq: { /* same as TK_ESCAPE, jump */
** Set the permutation used by the OP_Compare operator in the next
** instruction.  The permutation is stored in the P4 operand.
**
-
** The permutation is only valid until the next OP_Compare that has
-
** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should
-
** occur immediately prior to the OP_Compare.
+
** The permutation is only valid for the next opcode which must be
+
** an OP_Compare that has the OPFLAG_PERMUTE bit set in P5.
**
** The first integer in the P4 integer array is the length of the array
** and does not become part of the permutation.
@@ -89675,6 +90615,8 @@ case OP_Permutation: {
** The comparison is a sort comparison, so NULLs compare equal,
** NULLs are less than numbers, numbers are less than strings,
** and strings are less than blobs.
+
**
+
** This opcode must be immediately followed by an OP_Jump opcode.
*/
case OP_Compare: {
  int n;
@@ -89733,6 +90675,7 @@ case OP_Compare: {
      break;
    }
  }
+
  assert( pOp[1].opcode==OP_Jump );
  break;
}

@@ -89741,8 +90684,11 @@ case OP_Compare: {
** Jump to the instruction at address P1, P2, or P3 depending on whether
** in the most recent OP_Compare instruction the P1 vector was less than
** equal to, or greater than the P2 vector, respectively.
+
**
+
** This opcode must immediately follow an OP_Compare opcode.
*/
case OP_Jump: {             /* jump */
+
  assert( pOp>aOp && pOp[-1].opcode==OP_Compare );
  if( iCompare<0 ){
    VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1];
  }else if( iCompare==0 ){
@@ -90047,7 +90993,7 @@ case OP_Offset: { /* out3 */
#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */

/* Opcode: Column P1 P2 P3 P4 P5
-
** Synopsis: r[P3]=PX
+
** Synopsis: r[P3]=PX cursor P1 column P2
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction.  (See the MakeRecord opcode for additional
@@ -90069,7 +91015,7 @@ case OP_Offset: { /* out3 */
case OP_Column: {
  u32 p2;            /* column number to retrieve */
  VdbeCursor *pC;    /* The VDBE cursor */
-
  BtCursor *pCrsr;   /* The BTree cursor */
+
  BtCursor *pCrsr;   /* The B-Tree cursor corresponding to pC */
  u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
  int len;           /* The length of the serialized data for the column */
  int i;             /* Loop counter */
@@ -90083,21 +91029,14 @@ case OP_Column: {
  Mem *pReg;         /* PseudoTable input register */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+
  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
  pC = p->apCsr[pOp->p1];
-
  assert( pC!=0 );
  p2 = (u32)pOp->p2;

-
  /* If the cursor cache is stale (meaning it is not currently point at
-
  ** the correct row) then bring it up-to-date by doing the necessary
-
  ** B-Tree seek. */
-
  rc = sqlite3VdbeCursorMoveto(&pC, &p2);
-
  if( rc ) goto abort_due_to_error;
-

-
  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
-
  pDest = &aMem[pOp->p3];
-
  memAboutToChange(p, pDest);
+
op_column_restart:
  assert( pC!=0 );
-
  assert( p2<(u32)pC->nField );
+
  assert( p2<(u32)pC->nField
+
       || (pC->eCurType==CURTYPE_PSEUDO && pC->seekResult==0) );
  aOffset = pC->aOffset;
  assert( aOffset==pC->aType+pC->nField );
  assert( pC->eCurType!=CURTYPE_VTAB );
@@ -90106,21 +91045,37 @@ case OP_Column: {

  if( pC->cacheStatus!=p->cacheCtr ){                /*OPTIMIZATION-IF-FALSE*/
    if( pC->nullRow ){
-
      if( pC->eCurType==CURTYPE_PSEUDO ){
+
      if( pC->eCurType==CURTYPE_PSEUDO && pC->seekResult>0 ){
        /* For the special case of as pseudo-cursor, the seekResult field
        ** identifies the register that holds the record */
-
        assert( pC->seekResult>0 );
        pReg = &aMem[pC->seekResult];
        assert( pReg->flags & MEM_Blob );
        assert( memIsValid(pReg) );
        pC->payloadSize = pC->szRow = pReg->n;
        pC->aRow = (u8*)pReg->z;
      }else{
+
        pDest = &aMem[pOp->p3];
+
        memAboutToChange(p, pDest);
        sqlite3VdbeMemSetNull(pDest);
        goto op_column_out;
      }
    }else{
      pCrsr = pC->uc.pCursor;
+
      if( pC->deferredMoveto ){
+
        u32 iMap;
+
        assert( !pC->isEphemeral );
+
        if( pC->ub.aAltMap && (iMap = pC->ub.aAltMap[1+p2])>0  ){
+
          pC = pC->pAltCursor;
+
          p2 = iMap - 1;
+
          goto op_column_restart;
+
        }
+
        rc = sqlite3VdbeFinishMoveto(pC);
+
        if( rc ) goto abort_due_to_error;
+
      }else if( sqlite3BtreeCursorHasMoved(pCrsr) ){
+
        rc = sqlite3VdbeHandleMovedCursor(pC);
+
        if( rc ) goto abort_due_to_error;
+
        goto op_column_restart;
+
      }
      assert( pC->eCurType==CURTYPE_BTREE );
      assert( pCrsr );
      assert( sqlite3BtreeCursorIsValid(pCrsr) );
@@ -90128,15 +91083,15 @@ case OP_Column: {
      pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow);
      assert( pC->szRow<=pC->payloadSize );
      assert( pC->szRow<=65536 );  /* Maximum page size is 64KiB */
-
      if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
-
        goto too_big;
-
      }
    }
    pC->cacheStatus = p->cacheCtr;
-
    pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]);
+
    if( (aOffset[0] = pC->aRow[0])<0x80 ){
+
      pC->iHdrOffset = 1;
+
    }else{
+
      pC->iHdrOffset = sqlite3GetVarint32(pC->aRow, aOffset);
+
    }
    pC->nHdrParsed = 0;

-

    if( pC->szRow<aOffset[0] ){      /*OPTIMIZATION-IF-FALSE*/
      /* pC->aRow does not have to hold the entire row, but it does at least
      ** need to cover the header of the record.  If pC->aRow does not contain
@@ -90176,6 +91131,10 @@ case OP_Column: {
      testcase( aOffset[0]==0 );
      goto op_column_read_header;
    }
+
  }else if( sqlite3BtreeCursorHasMoved(pC->uc.pCursor) ){
+
    rc = sqlite3VdbeHandleMovedCursor(pC);
+
    if( rc ) goto abort_due_to_error;
+
    goto op_column_restart;
  }

  /* Make sure at least the first p2+1 entries of the header have been
@@ -90244,6 +91203,8 @@ case OP_Column: {
    ** columns.  So the result will be either the default value or a NULL.
    */
    if( pC->nHdrParsed<=p2 ){
+
      pDest = &aMem[pOp->p3];
+
      memAboutToChange(p, pDest);
      if( pOp->p4type==P4_MEM ){
        sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
      }else{
@@ -90261,6 +91222,8 @@ case OP_Column: {
  */
  assert( p2<pC->nHdrParsed );
  assert( rc==SQLITE_OK );
+
  pDest = &aMem[pOp->p3];
+
  memAboutToChange(p, pDest);
  assert( sqlite3VdbeCheckMemInvariants(pDest) );
  if( VdbeMemDynamic(pDest) ){
    sqlite3VdbeMemSetNull(pDest);
@@ -90281,6 +91244,7 @@ case OP_Column: {
      pDest->n = len = (t-12)/2;
      pDest->enc = encoding;
      if( pDest->szMalloc < len+2 ){
+
        if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
        pDest->flags = MEM_Null;
        if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem;
      }else{
@@ -90313,6 +91277,7 @@ case OP_Column: {
      */
      sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest);
    }else{
+
      if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big;
      rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
      if( rc!=SQLITE_OK ) goto abort_due_to_error;
      sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
@@ -90525,7 +91490,6 @@ case OP_MakeRecord: {
  Mem *pLast;            /* Last field of the record */
  int nField;            /* Number of fields in the record */
  char *zAffinity;       /* The affinity string for the record */
-
  int file_format;       /* File format to use for encoding */
  u32 len;               /* Length of a field */
  u8 *zHdr;              /* Where to write next byte of the header */
  u8 *zPayload;          /* Where to write next byte of the payload */
@@ -90554,7 +91518,6 @@ case OP_MakeRecord: {
  pData0 = &aMem[nField];
  nField = pOp->p2;
  pLast = &pData0[nField-1];
-
  file_format = p->minWriteFileFormat;

  /* Identify the output register */
  assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
@@ -90656,7 +91619,7 @@ case OP_MakeRecord: {
      testcase( uu==2147483647 );        testcase( uu==2147483648LL );
      testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL );
      if( uu<=127 ){
-
        if( (i&1)==i && file_format>=4 ){
+
        if( (i&1)==i && p->minWriteFileFormat>=4 ){
          pRec->uTemp = 8+(u32)uu;
        }else{
          nData++;
@@ -90761,18 +91724,60 @@ case OP_MakeRecord: {
  zPayload = zHdr + nHdr;

  /* Write the record */
-
  zHdr += putVarint32(zHdr, nHdr);
+
  if( nHdr<0x80 ){
+
    *(zHdr++) = nHdr;
+
  }else{
+
    zHdr += sqlite3PutVarint(zHdr,nHdr);
+
  }
  assert( pData0<=pLast );
  pRec = pData0;
-
  do{
+
  while( 1 /*exit-by-break*/ ){
    serial_type = pRec->uTemp;
    /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
-
    ** additional varints, one per column. */
-
    zHdr += putVarint32(zHdr, serial_type);            /* serial type */
-
    /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
+
    ** additional varints, one per column.
+
    ** EVIDENCE-OF: R-64536-51728 The values for each column in the record
    ** immediately follow the header. */
-
    zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */
-
  }while( (++pRec)<=pLast );
+
    if( serial_type<=7 ){
+
      *(zHdr++) = serial_type;
+
      if( serial_type==0 ){
+
        /* NULL value.  No change in zPayload */
+
      }else{
+
        u64 v;
+
        u32 i;
+
        if( serial_type==7 ){
+
          assert( sizeof(v)==sizeof(pRec->u.r) );
+
          memcpy(&v, &pRec->u.r, sizeof(v));
+
          swapMixedEndianFloat(v);
+
        }else{
+
          v = pRec->u.i;
+
        }
+
        len = i = sqlite3SmallTypeSizes[serial_type];
+
        assert( i>0 );
+
        while( 1 /*exit-by-break*/ ){
+
          zPayload[--i] = (u8)(v&0xFF);
+
          if( i==0 ) break;
+
          v >>= 8;
+
        }
+
        zPayload += len;
+
      }
+
    }else if( serial_type<0x80 ){
+
      *(zHdr++) = serial_type;
+
      if( serial_type>=14 && pRec->n>0 ){
+
        assert( pRec->z!=0 );
+
        memcpy(zPayload, pRec->z, pRec->n);
+
        zPayload += pRec->n;
+
      }
+
    }else{
+
      zHdr += sqlite3PutVarint(zHdr, serial_type);
+
      if( pRec->n ){
+
        assert( pRec->z!=0 );
+
        memcpy(zPayload, pRec->z, pRec->n);
+
        zPayload += pRec->n;
+
      }
+
    }
+
    if( pRec==pLast ) break;
+
    pRec++;
+
  }
  assert( nHdr==(int)(zHdr - (u8*)pOut->z) );
  assert( nByte==(int)(zPayload - (u8*)pOut->z) );

@@ -90991,7 +91996,10 @@ case OP_Savepoint: {
    }
  }
  if( rc ) goto abort_due_to_error;
-

+
  if( p->eVdbeState==VDBE_HALT_STATE ){
+
    rc = SQLITE_DONE;
+
    goto vdbe_return;
+
  }
  break;
}

@@ -91095,6 +92103,7 @@ case OP_AutoCommit: {
*/
case OP_Transaction: {
  Btree *pBt;
+
  Db *pDb;
  int iMeta = 0;

  assert( p->bIsReader );
@@ -91114,7 +92123,8 @@ case OP_Transaction: {
    }
    goto abort_due_to_error;
  }
-
  pBt = db->aDb[pOp->p1].pBt;
+
  pDb = &db->aDb[pOp->p1];
+
  pBt = pDb->pBt;

  if( pBt ){
    rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta);
@@ -91155,8 +92165,7 @@ case OP_Transaction: {
  assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
  if( rc==SQLITE_OK
   && pOp->p5
-
   && (iMeta!=pOp->p3
-
      || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
+
   && (iMeta!=pOp->p3 || pDb->pSchema->iGeneration!=pOp->p4.i)
  ){
    /*
    ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
@@ -91183,6 +92192,11 @@ case OP_Transaction: {
    }
    p->expired = 1;
    rc = SQLITE_SCHEMA;
+

+
    /* Set changeCntOn to 0 to prevent the value returned by sqlite3_changes()
+
    ** from being modified in sqlite3VdbeHalt(). If this statement is
+
    ** reprepared, changeCntOn will be set again. */
+
    p->changeCntOn = 0;
  }
  if( rc ) goto abort_due_to_error;
  break;
@@ -91249,7 +92263,7 @@ case OP_SetCookie: {
  rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3);
  if( pOp->p2==BTREE_SCHEMA_VERSION ){
    /* When the schema cookie changes, record the new cookie internally */
-
    pDb->pSchema->schema_cookie = pOp->p3 - pOp->p5;
+
    *(u32*)&pDb->pSchema->schema_cookie = *(u32*)&pOp->p3 - pOp->p5;
    db->mDbFlags |= DBFLAG_SchemaChange;
    sqlite3FkClearTriggerCache(db, pOp->p1);
  }else if( pOp->p2==BTREE_FILE_FORMAT ){
@@ -91482,8 +92496,8 @@ case OP_OpenDup: {
  pCx->pgnoRoot = pOrig->pgnoRoot;
  pCx->isOrdered = pOrig->isOrdered;
  pCx->ub.pBtx = pOrig->ub.pBtx;
-
  pCx->hasBeenDuped = 1;
-
  pOrig->hasBeenDuped = 1;
+
  pCx->noReuse = 1;
+
  pOrig->noReuse = 1;
  rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR,
                          pCx->pKeyInfo, pCx->uc.pCursor);
  /* The sqlite3BtreeCursor() routine can only fail for the first cursor
@@ -91550,7 +92564,7 @@ case OP_OpenEphemeral: {
    aMem[pOp->p3].z = "";
  }
  pCx = p->apCsr[pOp->p1];
-
  if( pCx && !pCx->hasBeenDuped &&  ALWAYS(pOp->p2<=pCx->nField) ){
+
  if( pCx && !pCx->noReuse &&  ALWAYS(pOp->p2<=pCx->nField) ){
    /* If the ephermeral table is already open and has no duplicates from
    ** OP_OpenDup, then erase all existing content so that the table is
    ** empty again, rather than creating a new table. */
@@ -92299,11 +93313,8 @@ case OP_NoConflict: /* jump, in3 */
case OP_NotFound:       /* jump, in3 */
case OP_Found: {        /* jump, in3 */
  int alreadyExists;
-
  int takeJump;
  int ii;
  VdbeCursor *pC;
-
  int res;
-
  UnpackedRecord *pFree;
  UnpackedRecord *pIdxKey;
  UnpackedRecord r;

@@ -92318,14 +93329,15 @@ case OP_Found: { /* jump, in3 */
#ifdef SQLITE_DEBUG
  pC->seekOp = pOp->opcode;
#endif
-
  pIn3 = &aMem[pOp->p3];
+
  r.aMem = &aMem[pOp->p3];
  assert( pC->eCurType==CURTYPE_BTREE );
  assert( pC->uc.pCursor!=0 );
  assert( pC->isTable==0 );
-
  if( pOp->p4.i>0 ){
+
  r.nField = (u16)pOp->p4.i;
+
  if( r.nField>0 ){
+
    /* Key values in an array of registers */
    r.pKeyInfo = pC->pKeyInfo;
-
    r.nField = (u16)pOp->p4.i;
-
    r.aMem = pIn3;
+
    r.default_rc = 0;
#ifdef SQLITE_DEBUG
    for(ii=0; ii<r.nField; ii++){
      assert( memIsValid(&r.aMem[ii]) );
@@ -92333,37 +93345,25 @@ case OP_Found: { /* jump, in3 */
      if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
    }
#endif
-
    pIdxKey = &r;
-
    pFree = 0;
+
    rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &pC->seekResult);
  }else{
-
    assert( pIn3->flags & MEM_Blob );
-
    rc = ExpandBlob(pIn3);
+
    /* Composite key generated by OP_MakeRecord */
+
    assert( r.aMem->flags & MEM_Blob );
+
    assert( pOp->opcode!=OP_NoConflict );
+
    rc = ExpandBlob(r.aMem);
    assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
    if( rc ) goto no_mem;
-
    pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
+
    pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo);
    if( pIdxKey==0 ) goto no_mem;
-
    sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
-
  }
-
  pIdxKey->default_rc = 0;
-
  takeJump = 0;
-
  if( pOp->opcode==OP_NoConflict ){
-
    /* For the OP_NoConflict opcode, take the jump if any of the
-
    ** input fields are NULL, since any key with a NULL will not
-
    ** conflict */
-
    for(ii=0; ii<pIdxKey->nField; ii++){
-
      if( pIdxKey->aMem[ii].flags & MEM_Null ){
-
        takeJump = 1;
-
        break;
-
      }
-
    }
+
    sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey);
+
    pIdxKey->default_rc = 0;
+
    rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult);
+
    sqlite3DbFreeNN(db, pIdxKey);
  }
-
  rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res);
-
  if( pFree ) sqlite3DbFreeNN(db, pFree);
  if( rc!=SQLITE_OK ){
    goto abort_due_to_error;
  }
-
  pC->seekResult = res;
-
  alreadyExists = (res==0);
+
  alreadyExists = (pC->seekResult==0);
  pC->nullRow = 1-alreadyExists;
  pC->deferredMoveto = 0;
  pC->cacheStatus = CACHE_STALE;
@@ -92371,9 +93371,25 @@ case OP_Found: { /* jump, in3 */
    VdbeBranchTaken(alreadyExists!=0,2);
    if( alreadyExists ) goto jump_to_p2;
  }else{
-
    VdbeBranchTaken(takeJump||alreadyExists==0,2);
-
    if( takeJump || !alreadyExists ) goto jump_to_p2;
-
    if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i;
+
    if( !alreadyExists ){
+
      VdbeBranchTaken(1,2);
+
      goto jump_to_p2;
+
    }
+
    if( pOp->opcode==OP_NoConflict ){
+
      /* For the OP_NoConflict opcode, take the jump if any of the
+
      ** input fields are NULL, since any key with a NULL will not
+
      ** conflict */
+
      for(ii=0; ii<r.nField; ii++){
+
        if( r.aMem[ii].flags & MEM_Null ){
+
          VdbeBranchTaken(1,2);
+
          goto jump_to_p2;
+
        }
+
      }
+
    }
+
    VdbeBranchTaken(0,2);
+
    if( pOp->opcode==OP_IfNoHope ){
+
      pC->seekHit = pOp->p4.i;
+
    }
  }
  break;
}
@@ -93064,7 +94080,7 @@ case OP_RowData: {
}

/* Opcode: Rowid P1 P2 * * *
-
** Synopsis: r[P2]=rowid
+
** Synopsis: r[P2]=PX rowid of P1
**
** Store in register P2 an integer which is the key of the table entry that
** P1 is currently point to.
@@ -93120,16 +94136,24 @@ case OP_Rowid: { /* out2 */
** that occur while the cursor is on the null row will always
** write a NULL.
**
-
** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo)
-
** just reset the cache for that cursor.  This causes the row of
-
** content held by the pseudo-cursor to be reparsed.
+
** If cursor P1 is not previously opened, open it now to a special
+
** pseudo-cursor that always returns NULL for every column.
*/
case OP_NullRow: {
  VdbeCursor *pC;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
-
  assert( pC!=0 );
+
  if( pC==0 ){
+
    /* If the cursor is not already open, create a special kind of
+
    ** pseudo-cursor that always gives null rows. */
+
    pC = allocateCursor(p, pOp->p1, 1, CURTYPE_PSEUDO);
+
    if( pC==0 ) goto no_mem;
+
    pC->seekResult = 0;
+
    pC->isTable = 1;
+
    pC->noReuse = 1;
+
    pC->uc.pCursor = sqlite3BtreeFakeValidCursor();
+
  }
  pC->nullRow = 1;
  pC->cacheStatus = CACHE_STALE;
  if( pC->eCurType==CURTYPE_BTREE ){
@@ -93302,7 +94326,7 @@ case OP_Rewind: { /* jump */
  break;
}

-
/* Opcode: Next P1 P2 P3 P4 P5
+
/* Opcode: Next P1 P2 P3 * P5
**
** Advance cursor P1 so that it points to the next key/data pair in its
** table or index.  If there are no more key/value pairs then fall through
@@ -93321,15 +94345,12 @@ case OP_Rewind: { /* jump */
** omitted if that index had been unique.  P3 is usually 0.  P3 is
** always either 0 or 1.
**
-
** P4 is always of type P4_ADVANCE. The function pointer points to
-
** sqlite3BtreeNext().
-
**
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
**
** See also: Prev
*/
-
/* Opcode: Prev P1 P2 P3 P4 P5
+
/* Opcode: Prev P1 P2 P3 * P5
**
** Back up cursor P1 so that it points to the previous key/data pair in its
** table or index.  If there is no previous key/value pairs then fall through
@@ -93349,9 +94370,6 @@ case OP_Rewind: { /* jump */
** omitted if that index had been unique.  P3 is usually 0.  P3 is
** always either 0 or 1.
**
-
** P4 is always of type P4_ADVANCE. The function pointer points to
-
** sqlite3BtreePrevious().
-
**
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
*/
@@ -93369,30 +94387,33 @@ case OP_SorterNext: { /* jump */
  assert( isSorter(pC) );
  rc = sqlite3VdbeSorterNext(db, pC);
  goto next_tail;
+

case OP_Prev:          /* jump */
-
case OP_Next:          /* jump */
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p5<ArraySize(p->aCounter) );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( pC->deferredMoveto==0 );
  assert( pC->eCurType==CURTYPE_BTREE );
-
  assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
-
  assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
+
  assert( pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
+
       || pC->seekOp==OP_Last   || pC->seekOp==OP_IfNoHope
+
       || pC->seekOp==OP_NullRow);
+
  rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3);
+
  goto next_tail;

-
  /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
-
  ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
-
  assert( pOp->opcode!=OP_Next
-
       || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
+
case OP_Next:          /* jump */
+
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+
  assert( pOp->p5<ArraySize(p->aCounter) );
+
  pC = p->apCsr[pOp->p1];
+
  assert( pC!=0 );
+
  assert( pC->deferredMoveto==0 );
+
  assert( pC->eCurType==CURTYPE_BTREE );
+
  assert( pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
       || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found
       || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid
       || pC->seekOp==OP_IfNoHope);
-
  assert( pOp->opcode!=OP_Prev
-
       || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
-
       || pC->seekOp==OP_Last   || pC->seekOp==OP_IfNoHope
-
       || pC->seekOp==OP_NullRow);
+
  rc = sqlite3BtreeNext(pC->uc.pCursor, pOp->p3);

-
  rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
next_tail:
  pC->cacheStatus = CACHE_STALE;
  VdbeBranchTaken(rc==SQLITE_OK,2);
@@ -93579,9 +94600,9 @@ case OP_IdxRowid: { /* out2 */
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
-
  assert( pC->eCurType==CURTYPE_BTREE );
+
  assert( pC->eCurType==CURTYPE_BTREE || IsNullCursor(pC) );
  assert( pC->uc.pCursor!=0 );
-
  assert( pC->isTable==0 );
+
  assert( pC->isTable==0 || IsNullCursor(pC) );
  assert( pC->deferredMoveto==0 );
  assert( !pC->nullRow || pOp->opcode==OP_IdxRowid );

@@ -93610,6 +94631,7 @@ case OP_IdxRowid: { /* out2 */
      pTabCur->nullRow = 0;
      pTabCur->movetoTarget = rowid;
      pTabCur->deferredMoveto = 1;
+
      pTabCur->cacheStatus = CACHE_STALE;
      assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
      assert( !pTabCur->isEphemeral );
      pTabCur->ub.aAltMap = pOp->p4.ai;
@@ -93744,7 +94766,7 @@ case OP_IdxGE: { /* jump */
    rc = sqlite3VdbeMemFromBtreeZeroOffset(pCur, (u32)nCellKey, &m);
    if( rc ) goto abort_due_to_error;
    res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, &r, 0);
-
    sqlite3VdbeMemRelease(&m);
+
    sqlite3VdbeMemReleaseMalloc(&m);
  }
  /* End of inlined sqlite3VdbeIdxKeyCompare() */

@@ -94625,6 +95647,7 @@ case OP_AggStep: {
  pCtx->pVdbe = p;
  pCtx->skipFlag = 0;
  pCtx->isError = 0;
+
  pCtx->enc = encoding;
  pCtx->argc = n;
  pOp->p4type = P4_FUNCCTX;
  pOp->p4.pCtx = pCtx;
@@ -94754,9 +95777,6 @@ case OP_AggFinal: {
  }
  sqlite3VdbeChangeEncoding(pMem, encoding);
  UPDATE_MAX_BLOBSIZE(pMem);
-
  if( sqlite3VdbeMemTooBig(pMem) ){
-
    goto too_big;
-
  }
  break;
}

@@ -95264,7 +96284,6 @@ case OP_VColumn: {

  VdbeCursor *pCur = p->apCsr[pOp->p1];
  assert( pCur!=0 );
-
  assert( pCur->eCurType==CURTYPE_VTAB );
  assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
  pDest = &aMem[pOp->p3];
  memAboutToChange(p, pDest);
@@ -95272,11 +96291,13 @@ case OP_VColumn: {
    sqlite3VdbeMemSetNull(pDest);
    break;
  }
+
  assert( pCur->eCurType==CURTYPE_VTAB );
  pVtab = pCur->uc.pVCur->pVtab;
  pModule = pVtab->pModule;
  assert( pModule->xColumn );
  memset(&sContext, 0, sizeof(sContext));
  sContext.pOut = pDest;
+
  sContext.enc = encoding;
  assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 );
  if( pOp->p5 & OPFLAG_NOCHNG ){
    sqlite3VdbeMemSetNull(pDest);
@@ -95295,9 +96316,6 @@ case OP_VColumn: {
  REGISTER_TRACE(pOp->p3, pDest);
  UPDATE_MAX_BLOBSIZE(pDest);

-
  if( sqlite3VdbeMemTooBig(pDest) ){
-
    goto too_big;
-
  }
  if( rc ) goto abort_due_to_error;
  break;
}
@@ -95564,6 +96582,7 @@ case OP_Function: { /* group */
  if( pCtx->pOut != pOut ){
    pCtx->pVdbe = p;
    pCtx->pOut = pOut;
+
    pCtx->enc = encoding;
    for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i];
  }
  assert( pCtx->pVdbe==p );
@@ -95590,17 +96609,27 @@ case OP_Function: { /* group */
    if( rc ) goto abort_due_to_error;
  }

-
  /* Copy the result of the function into register P3 */
-
  if( pOut->flags & (MEM_Str|MEM_Blob) ){
-
    sqlite3VdbeChangeEncoding(pOut, encoding);
-
    if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
-
  }
+
  assert( (pOut->flags&MEM_Str)==0
+
       || pOut->enc==encoding
+
       || db->mallocFailed );
+
  assert( !sqlite3VdbeMemTooBig(pOut) );

  REGISTER_TRACE(pOp->p3, pOut);
  UPDATE_MAX_BLOBSIZE(pOut);
  break;
}

+
/* Opcode: ClrSubtype P1 * * * *
+
** Synopsis:  r[P1].subtype = 0
+
**
+
** Clear the subtype from register P1.
+
*/
+
case OP_ClrSubtype: {   /* in1 */
+
  pIn1 = &aMem[pOp->p1];
+
  pIn1->flags &= ~MEM_Subtype;
+
  break;
+
}
+

/* Opcode: FilterAdd P1 * P3 P4 *
** Synopsis: filter(P1) += key(P3@P4)
**
@@ -95720,7 +96749,7 @@ case OP_Init: { /* jump */

#ifndef SQLITE_OMIT_TRACE
  if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
-
   && !p->doingRerun
+
   && p->minWriteFileFormat!=254  /* tag-20220401a */
   && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
  ){
#ifndef SQLITE_OMIT_DEPRECATED
@@ -95949,7 +96978,7 @@ abort_due_to_error:
  testcase( sqlite3GlobalConfig.xLog!=0 );
  sqlite3_log(rc, "statement aborts at %d: [%s] %s",
                   (int)(pOp - aOp), p->zSql, p->zErrMsg);
-
  sqlite3VdbeHalt(p);
+
  if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p);
  if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
  if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
    db->flags |= SQLITE_CorruptRdOnly;
@@ -100511,51 +101540,24 @@ static void resolveAlias(
    sqlite3ExprDelete(db, pDup);
    pDup = 0;
  }else{
+
    Expr temp;
    incrAggFunctionDepth(pDup, nSubquery);
    if( pExpr->op==TK_COLLATE ){
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
      pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
    }
-

-
    /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
-
    ** prevents ExprDelete() from deleting the Expr structure itself,
-
    ** allowing it to be repopulated by the memcpy() on the following line.
-
    ** The pExpr->u.zToken might point into memory that will be freed by the
-
    ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
-
    ** make a copy of the token before doing the sqlite3DbFree().
-
    */
-
    ExprSetProperty(pExpr, EP_Static);
-
    sqlite3ExprDelete(db, pExpr);
-
    memcpy(pExpr, pDup, sizeof(*pExpr));
-
    if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){
-
      assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 );
-
      pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken);
-
      pExpr->flags |= EP_MemToken;
-
    }
+
    memcpy(&temp, pDup, sizeof(Expr));
+
    memcpy(pDup, pExpr, sizeof(Expr));
+
    memcpy(pExpr, &temp, sizeof(Expr));
    if( ExprHasProperty(pExpr, EP_WinFunc) ){
      if( ALWAYS(pExpr->y.pWin!=0) ){
        pExpr->y.pWin->pOwner = pExpr;
      }
    }
-
    sqlite3DbFree(db, pDup);
-
  }
-
}
-

-

-
/*
-
** Return TRUE if the name zCol occurs anywhere in the USING clause.
-
**
-
** Return FALSE if the USING clause is NULL or if it does not contain
-
** zCol.
-
*/
-
static int nameInUsingClause(IdList *pUsing, const char *zCol){
-
  if( pUsing ){
-
    int k;
-
    for(k=0; k<pUsing->nId; k++){
-
      if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1;
-
    }
+
    sqlite3ParserAddCleanup(pParse,
+
      (void(*)(sqlite3*,void*))sqlite3ExprDelete,
+
      pDup);
  }
-
  return 0;
}

/*
@@ -100573,7 +101575,7 @@ SQLITE_PRIVATE int sqlite3MatchEName(
){
  int n;
  const char *zSpan;
-
  if( pItem->eEName!=ENAME_TAB ) return 0;
+
  if( pItem->fg.eEName!=ENAME_TAB ) return 0;
  zSpan = pItem->zEName;
  for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){}
  if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){
@@ -100635,6 +101637,29 @@ SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){
}

/*
+
** Create a new expression term for the column specified by pMatch and
+
** iColumn.  Append this new expression term to the FULL JOIN Match set
+
** in *ppList.  Create a new *ppList if this is the first term in the
+
** set.
+
*/
+
static void extendFJMatch(
+
  Parse *pParse,          /* Parsing context */
+
  ExprList **ppList,      /* ExprList to extend */
+
  SrcItem *pMatch,        /* Source table containing the column */
+
  i16 iColumn             /* The column number */
+
){
+
  Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
+
  if( pNew ){
+
    pNew->iTable = pMatch->iCursor;
+
    pNew->iColumn = iColumn;
+
    pNew->y.pTab = pMatch->pTab;
+
    assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 );
+
    ExprSetProperty(pNew, EP_CanBeNull);
+
    *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew);
+
  }
+
}
+

+
/*
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
** that name in the set of source tables in pSrcList and make the pExpr
** expression node refer back to that source column.  The following changes
@@ -100679,11 +101704,13 @@ static int lookupName(
  NameContext *pTopNC = pNC;        /* First namecontext in the list */
  Schema *pSchema = 0;              /* Schema of the expression */
  int eNewExprOp = TK_COLUMN;       /* New value for pExpr->op on success */
-
  Table *pTab = 0;                  /* Table hold the row */
+
  Table *pTab = 0;                  /* Table holding the row */
  Column *pCol;                     /* A column of pTab */
+
  ExprList *pFJMatch = 0;           /* Matches for FULL JOIN .. USING */

  assert( pNC );     /* the name context cannot be NULL. */
  assert( zCol );    /* The Z in X.Y.Z cannot be NULL */
+
  assert( zDb==0 || zTab!=0 );
  assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );

  /* Initialize the node to no-match */
@@ -100732,26 +101759,65 @@ static int lookupName(
        pTab = pItem->pTab;
        assert( pTab!=0 && pTab->zName!=0 );
        assert( pTab->nCol>0 || pParse->nErr );
-
        if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
+
        assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
+
        if( pItem->fg.isNestedFrom ){
+
          /* In this case, pItem is a subquery that has been formed from a
+
          ** parenthesized subset of the FROM clause terms.  Example:
+
          **   .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ...
+
          **                          \_________________________/
+
          **             This pItem -------------^
+
          */
          int hit = 0;
+
          assert( pItem->pSelect!=0 );
          pEList = pItem->pSelect->pEList;
+
          assert( pEList!=0 );
+
          assert( pEList->nExpr==pTab->nCol );
          for(j=0; j<pEList->nExpr; j++){
-
            if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){
-
              cnt++;
-
              cntTab = 2;
-
              pMatch = pItem;
-
              pExpr->iColumn = j;
-
              hit = 1;
+
            if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){
+
              continue;
            }
+
            if( cnt>0 ){
+
              if( pItem->fg.isUsing==0
+
               || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
+
              ){
+
                /* Two or more tables have the same column name which is
+
                ** not joined by USING.  This is an error.  Signal as much
+
                ** by clearing pFJMatch and letting cnt go above 1. */
+
                sqlite3ExprListDelete(db, pFJMatch);
+
                pFJMatch = 0;
+
              }else
+
              if( (pItem->fg.jointype & JT_RIGHT)==0 ){
+
                /* An INNER or LEFT JOIN.  Use the left-most table */
+
                continue;
+
              }else
+
              if( (pItem->fg.jointype & JT_LEFT)==0 ){
+
                /* A RIGHT JOIN.  Use the right-most table */
+
                cnt = 0;
+
                sqlite3ExprListDelete(db, pFJMatch);
+
                pFJMatch = 0;
+
              }else{
+
                /* For a FULL JOIN, we must construct a coalesce() func */
+
                extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn);
+
              }
+
            }
+
            cnt++;
+
            cntTab = 2;
+
            pMatch = pItem;
+
            pExpr->iColumn = j;
+
            pEList->a[j].fg.bUsed = 1;
+
            hit = 1;
+
            if( pEList->a[j].fg.bUsingTerm ) break;
          }
          if( hit || zTab==0 ) continue;
        }
-
        if( zDb ){
-
          if( pTab->pSchema!=pSchema ) continue;
-
          if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue;
-
        }
+
        assert( zDb==0 || zTab!=0 );
        if( zTab ){
-
          const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
+
          const char *zTabName;
+
          if( zDb ){
+
            if( pTab->pSchema!=pSchema ) continue;
+
            if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue;
+
          }
+
          zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
          assert( zTabName!=0 );
          if( sqlite3StrICmp(zTabName, zTab)!=0 ){
            continue;
@@ -100766,18 +101832,37 @@ static int lookupName(
          if( pCol->hName==hCol
           && sqlite3StrICmp(pCol->zCnName, zCol)==0
          ){
-
            /* If there has been exactly one prior match and this match
-
            ** is for the right-hand table of a NATURAL JOIN or is in a
-
            ** USING clause, then skip this match.
-
            */
-
            if( cnt==1 ){
-
              if( pItem->fg.jointype & JT_NATURAL ) continue;
-
              if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
+
            if( cnt>0 ){
+
              if( pItem->fg.isUsing==0
+
               || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
+
              ){
+
                /* Two or more tables have the same column name which is
+
                ** not joined by USING.  This is an error.  Signal as much
+
                ** by clearing pFJMatch and letting cnt go above 1. */
+
                sqlite3ExprListDelete(db, pFJMatch);
+
                pFJMatch = 0;
+
              }else
+
              if( (pItem->fg.jointype & JT_RIGHT)==0 ){
+
                /* An INNER or LEFT JOIN.  Use the left-most table */
+
                continue;
+
              }else
+
              if( (pItem->fg.jointype & JT_LEFT)==0 ){
+
                /* A RIGHT JOIN.  Use the right-most table */
+
                cnt = 0;
+
                sqlite3ExprListDelete(db, pFJMatch);
+
                pFJMatch = 0;
+
              }else{
+
                /* For a FULL JOIN, we must construct a coalesce() func */
+
                extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn);
+
              }
            }
            cnt++;
            pMatch = pItem;
            /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
            pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
+
            if( pItem->fg.isNestedFrom ){
+
              sqlite3SrcItemColumnUsed(pItem, j);
+
            }
            break;
          }
        }
@@ -100790,9 +101875,7 @@ static int lookupName(
        pExpr->iTable = pMatch->iCursor;
        assert( ExprUseYTab(pExpr) );
        pExpr->y.pTab = pMatch->pTab;
-
        /* RIGHT JOIN not (yet) supported */
-
        assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
-
        if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
+
        if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){
          ExprSetProperty(pExpr, EP_CanBeNull);
        }
        pSchema = pExpr->y.pTab->pSchema;
@@ -100946,7 +102029,7 @@ static int lookupName(
      assert( pEList!=0 );
      for(j=0; j<pEList->nExpr; j++){
        char *zAs = pEList->a[j].zEName;
-
        if( pEList->a[j].eEName==ENAME_NAME
+
        if( pEList->a[j].fg.eEName==ENAME_NAME
         && sqlite3_stricmp(zAs, zCol)==0
        ){
          Expr *pOrig;
@@ -101033,11 +102116,37 @@ static int lookupName(
  }

  /*
-
  ** cnt==0 means there was not match.  cnt>1 means there were two or
-
  ** more matches.  Either way, we have an error.
+
  ** cnt==0 means there was not match.
+
  ** cnt>1 means there were two or more matches.
+
  **
+
  ** cnt==0 is always an error.  cnt>1 is often an error, but might
+
  ** be multiple matches for a NATURAL LEFT JOIN or a LEFT JOIN USING.
  */
+
  assert( pFJMatch==0 || cnt>0 );
+
  assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
  if( cnt!=1 ){
    const char *zErr;
+
    if( pFJMatch ){
+
      if( pFJMatch->nExpr==cnt-1 ){
+
        if( ExprHasProperty(pExpr,EP_Leaf) ){
+
          ExprClearProperty(pExpr,EP_Leaf);
+
        }else{
+
          sqlite3ExprDelete(db, pExpr->pLeft);
+
          pExpr->pLeft = 0;
+
          sqlite3ExprDelete(db, pExpr->pRight);
+
          pExpr->pRight = 0;
+
        }
+
        extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn);
+
        pExpr->op = TK_FUNCTION;
+
        pExpr->u.zToken = "coalesce";
+
        pExpr->x.pList = pFJMatch;
+
        cnt = 1;
+
        goto lookupname_end;
+
      }else{
+
        sqlite3ExprListDelete(db, pFJMatch);
+
        pFJMatch = 0;
+
      }
+
    }
    zErr = cnt==0 ? "no such column" : "ambiguous column name";
    if( zDb ){
      sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol);
@@ -101050,6 +102159,16 @@ static int lookupName(
    pParse->checkSchema = 1;
    pTopNC->nNcErr++;
  }
+
  assert( pFJMatch==0 );
+

+
  /* Remove all substructure from pExpr */
+
  if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
+
    sqlite3ExprDelete(db, pExpr->pLeft);
+
    pExpr->pLeft = 0;
+
    sqlite3ExprDelete(db, pExpr->pRight);
+
    pExpr->pRight = 0;
+
    ExprSetProperty(pExpr, EP_Leaf);
+
  }

  /* If a column from a table in pSrcList is referenced, then record
  ** this fact in the pSrcList.a[].colUsed bitmask.  Column 0 causes
@@ -101069,16 +102188,7 @@ static int lookupName(
    pMatch->colUsed |= sqlite3ExprColUsed(pExpr);
  }

-
  /* Clean up and return
-
  */
-
  if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){
-
    sqlite3ExprDelete(db, pExpr->pLeft);
-
    pExpr->pLeft = 0;
-
    sqlite3ExprDelete(db, pExpr->pRight);
-
    pExpr->pRight = 0;
-
  }
  pExpr->op = eNewExprOp;
-
  ExprSetProperty(pExpr, EP_Leaf);
lookupname_end:
  if( cnt==1 ){
    assert( pNC!=0 );
@@ -101263,7 +102373,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
      }
      sqlite3WalkExpr(pWalker, pExpr->pLeft);
      if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
-
        testcase( ExprHasProperty(pExpr, EP_FromJoin) );
+
        testcase( ExprHasProperty(pExpr, EP_OuterON) );
        assert( !ExprHasProperty(pExpr, EP_IntValue) );
        if( pExpr->op==TK_NOTNULL ){
          pExpr->u.zToken = "true";
@@ -101672,7 +102782,7 @@ static int resolveAsName(
    assert( !ExprHasProperty(pE, EP_IntValue) );
    zCol = pE->u.zToken;
    for(i=0; i<pEList->nExpr; i++){
-
      if( pEList->a[i].eEName==ENAME_NAME
+
      if( pEList->a[i].fg.eEName==ENAME_NAME
       && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0
      ){
        return i+1;
@@ -101793,7 +102903,7 @@ static int resolveCompoundOrderBy(
    return 1;
  }
  for(i=0; i<pOrderBy->nExpr; i++){
-
    pOrderBy->a[i].done = 0;
+
    pOrderBy->a[i].fg.done = 0;
  }
  pSelect->pNext = 0;
  while( pSelect->pPrior ){
@@ -101808,7 +102918,7 @@ static int resolveCompoundOrderBy(
    for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
      int iCol = -1;
      Expr *pE, *pDup;
-
      if( pItem->done ) continue;
+
      if( pItem->fg.done ) continue;
      pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr);
      if( NEVER(pE==0) ) continue;
      if( sqlite3ExprIsInteger(pE, &iCol) ){
@@ -101861,7 +102971,7 @@ static int resolveCompoundOrderBy(
          sqlite3ExprDelete(db, pE);
          pItem->u.x.iOrderByCol = (u16)iCol;
        }
-
        pItem->done = 1;
+
        pItem->fg.done = 1;
      }else{
        moreToDo = 1;
      }
@@ -101869,7 +102979,7 @@ static int resolveCompoundOrderBy(
    pSelect = pSelect->pNext;
  }
  for(i=0; i<pOrderBy->nExpr; i++){
-
    if( pOrderBy->a[i].done==0 ){
+
    if( pOrderBy->a[i].fg.done==0 ){
      sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any "
            "column in the result set", i+1);
      return 1;
@@ -102159,8 +103269,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
    sNC.uNC.pEList = p->pEList;
    sNC.ncFlags |= NC_UEList;
    if( p->pHaving ){
-
      if( !pGroupBy ){
-
        sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
+
      if( (p->selFlags & SF_Aggregate)==0 ){
+
        sqlite3ErrorMsg(pParse, "HAVING clause on a non-aggregate query");
        return WRC_Abort;
      }
      if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort;
@@ -103554,6 +104664,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(
    sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
    return 0;
  }
+
  assert( !ExprHasProperty(pNew, EP_InnerON|EP_OuterON) );
  pNew->w.iOfst = (int)(pToken->z - pParse->zTail);
  if( pList
   && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG]
@@ -103734,6 +104845,18 @@ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
  if( p ) sqlite3ExprDeleteNN(db, p);
}

+
/*
+
** Clear both elements of an OnOrUsing object
+
*/
+
SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){
+
  if( p==0 ){
+
    /* Nothing to clear */
+
  }else if( p->pOn ){
+
    sqlite3ExprDeleteNN(db, p->pOn);
+
  }else if( p->pUsing ){
+
    sqlite3IdListDelete(db, p->pUsing);
+
  }
+
}

/*
** Arrange to cause pExpr to be deleted when the pParse is deleted.
@@ -103820,7 +104943,7 @@ static int dupedExprStructSize(const Expr *p, int flags){
    nSize = EXPR_FULLSIZE;
  }else{
    assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
-
    assert( !ExprHasProperty(p, EP_FromJoin) );
+
    assert( !ExprHasProperty(p, EP_OuterON) );
    assert( !ExprHasProperty(p, EP_MemToken) );
    assert( !ExprHasVVAProperty(p, EP_NoReduce) );
    if( p->pLeft || p->x.pList ){
@@ -104000,6 +105123,7 @@ SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p){
        pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0);
        pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0);
        pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName);
+
        pRet->a[i].eM10d = p->a[i].eM10d;
      }
    }
  }
@@ -104100,11 +105224,8 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int
      }
    }
    pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
-
    pItem->sortFlags = pOldItem->sortFlags;
-
    pItem->eEName = pOldItem->eEName;
-
    pItem->done = 0;
-
    pItem->bNulls = pOldItem->bNulls;
-
    pItem->bSorterRef = pOldItem->bSorterRef;
+
    pItem->fg = pOldItem->fg;
+
    pItem->fg.done = 0;
    pItem->u = pOldItem->u;
  }
  return pNew;
@@ -104156,8 +105277,12 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int fla
      pTab->nTabRef++;
    }
    pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
-
    pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
-
    pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing);
+
    if( pOldItem->fg.isUsing ){
+
      assert( pNewItem->fg.isUsing );
+
      pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing);
+
    }else{
+
      pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags);
+
    }
    pNewItem->colUsed = pOldItem->colUsed;
  }
  return pNew;
@@ -104167,22 +105292,16 @@ SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
  int i;
  assert( db!=0 );
  if( p==0 ) return 0;
-
  pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
+
  assert( p->eU4!=EU4_EXPR );
+
  pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) );
  if( pNew==0 ) return 0;
  pNew->nId = p->nId;
-
  pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) );
-
  if( pNew->a==0 ){
-
    sqlite3DbFreeNN(db, pNew);
-
    return 0;
-
  }
-
  /* Note that because the size of the allocation for p->a[] is not
-
  ** necessarily a power of two, sqlite3IdListAppend() may not be called
-
  ** on the duplicate created by this function. */
+
  pNew->eU4 = p->eU4;
  for(i=0; i<p->nId; i++){
    struct IdList_item *pNewItem = &pNew->a[i];
-
    struct IdList_item *pOldItem = &p->a[i];
+
    const struct IdList_item *pOldItem = &p->a[i];
    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
-
    pNewItem->idx = pOldItem->idx;
+
    pNewItem->u4 = pOldItem->u4;
  }
  return pNew;
}
@@ -104406,16 +105525,16 @@ SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int
  );

  pItem = &p->a[p->nExpr-1];
-
  assert( pItem->bNulls==0 );
+
  assert( pItem->fg.bNulls==0 );
  if( iSortOrder==SQLITE_SO_UNDEFINED ){
    iSortOrder = SQLITE_SO_ASC;
  }
-
  pItem->sortFlags = (u8)iSortOrder;
+
  pItem->fg.sortFlags = (u8)iSortOrder;

  if( eNulls!=SQLITE_SO_UNDEFINED ){
-
    pItem->bNulls = 1;
+
    pItem->fg.bNulls = 1;
    if( iSortOrder!=eNulls ){
-
      pItem->sortFlags |= KEYINFO_ORDER_BIGNULL;
+
      pItem->fg.sortFlags |= KEYINFO_ORDER_BIGNULL;
    }
  }
}
@@ -104441,7 +105560,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetName(
    assert( pList->nExpr>0 );
    pItem = &pList->a[pList->nExpr-1];
    assert( pItem->zEName==0 );
-
    assert( pItem->eEName==ENAME_NAME );
+
    assert( pItem->fg.eEName==ENAME_NAME );
    pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
    if( dequote ){
      /* If dequote==0, then pName->z does not point to part of a DDL
@@ -104476,7 +105595,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetSpan(
    assert( pList->nExpr>0 );
    if( pItem->zEName==0 ){
      pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd);
-
      pItem->eEName = ENAME_SPAN;
+
      pItem->fg.eEName = ENAME_SPAN;
    }
  }
}
@@ -104648,9 +105767,9 @@ SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){

  /* If pWalker->eCode is 2 then any term of the expression that comes from
-
  ** the ON or USING clauses of a left join disqualifies the expression
+
  ** the ON or USING clauses of an outer join disqualifies the expression
  ** from being considered constant. */
-
  if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
+
  if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_OuterON) ){
    pWalker->eCode = 0;
    return WRC_Abort;
  }
@@ -104773,7 +105892,7 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
** Check pExpr to see if it is an invariant constraint on data source pSrc.
** This is an optimization.  False negatives will perhaps cause slower
** queries, but false positives will yield incorrect answers.  So when in
-
** double, return 0.
+
** doubt, return 0.
**
** To be an invariant constraint, the following must be true:
**
@@ -104781,24 +105900,28 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
**
**   (2)  pExpr cannot use subqueries or non-deterministic functions.
**
-
**   (*)  ** Not applicable to this branch **
+
**   (3)  pSrc cannot be part of the left operand for a RIGHT JOIN.
+
**        (Is there some way to relax this constraint?)
**
**   (4)  If pSrc is the right operand of a LEFT JOIN, then...
**         (4a)  pExpr must come from an ON clause..
-
**         (4b)  and specifically the ON clause associated with the LEFT JOIN.
+
           (4b)  and specifically the ON clause associated with the LEFT JOIN.
**
**   (5)  If pSrc is not the right operand of a LEFT JOIN or the left
**        operand of a RIGHT JOIN, then pExpr must be from the WHERE
**        clause, not an ON clause.
*/
SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){
+
  if( pSrc->fg.jointype & JT_LTORJ ){
+
    return 0;  /* rule (3) */
+
  }
  if( pSrc->fg.jointype & JT_LEFT ){
-
    if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0;    /* rule (4a) */
-
    if( pExpr->w.iRightJoinTable!=pSrc->iCursor ) return 0; /* rule (4b) */
+
    if( !ExprHasProperty(pExpr, EP_OuterON) ) return 0;   /* rule (4a) */
+
    if( pExpr->w.iJoin!=pSrc->iCursor ) return 0;         /* rule (4b) */
  }else{
-
    if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;     /* rule (5) */
+
    if( ExprHasProperty(pExpr, EP_OuterON) ) return 0;    /* rule (5) */
  }
-
  return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor);  /* rules (1), (2) */
+
  return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
}


@@ -105128,7 +106251,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
** all members of the RHS set, skipping duplicates.
**
** A cursor is opened on the b-tree object that is the RHS of the IN operator
-
** and pX->iTable is set to the index of that cursor.
+
** and the *piTab parameter is set to the index of that cursor.
**
** The returned value of this function indicates the b-tree type, as follows:
**
@@ -105148,7 +106271,10 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
** If the RHS of the IN operator is a list or a more complex subquery, then
** an ephemeral table might need to be generated from the RHS and then
** pX->iTable made to point to the ephemeral table instead of an
-
** existing table.
+
** existing table.  In this case, the creation and initialization of the
+
** ephmeral table might be put inside of a subroutine, the EP_Subrtn flag
+
** will be set on pX and the pX->y.sub fields will be set to show where
+
** the subroutine is coded.
**
** The inFlags parameter must contain, at a minimum, one of the bits
** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both.  If inFlags contains
@@ -105209,12 +106335,13 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
){
  Select *p;                            /* SELECT to the right of IN operator */
  int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
-
  int iTab = pParse->nTab++;            /* Cursor of the RHS table */
+
  int iTab;                             /* Cursor of the RHS table */
  int mustBeUnique;                     /* True if RHS must be unique */
  Vdbe *v = sqlite3GetVdbe(pParse);     /* Virtual machine being coded */

  assert( pX->op==TK_IN );
  mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0;
+
  iTab = pParse->nTab++;

  /* If the RHS of this IN(...) operator is a SELECT, and if it matters
  ** whether or not the SELECT result contains NULL values, check whether
@@ -105380,6 +106507,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
   && ExprUseXList(pX)
   && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2)
  ){
+
    pParse->nTab--;  /* Back out the allocation of the unused cursor */
+
    iTab = -1;       /* Cursor is not allocated */
    eType = IN_INDEX_NOOP;
  }

@@ -105546,6 +106675,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
      assert( ExprUseYSub(pExpr) );
      sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
                        pExpr->y.sub.iAddr);
+
      assert( iTab!=pExpr->iTable );
      sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
      sqlite3VdbeJumpHere(v, addrOnce);
      return;
@@ -105557,8 +106687,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
    assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
    pExpr->y.sub.regReturn = ++pParse->nMem;
    pExpr->y.sub.iAddr =
-
      sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
-
    VdbeComment((v, "return address"));
+
      sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;

    addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  }
@@ -105660,6 +106789,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
      ** expression we need to rerun this code each time.
      */
      if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
+
        sqlite3VdbeChangeToNoop(v, addrOnce-1);
        sqlite3VdbeChangeToNoop(v, addrOnce);
        ExprClearProperty(pExpr, EP_Subrtn);
        addrOnce = 0;
@@ -105680,8 +106810,11 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
    sqlite3VdbeJumpHere(v, addrOnce);
    /* Subroutine return */
    assert( ExprUseYSub(pExpr) );
-
    sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
-
    sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
+
    assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
+
            || pParse->nErr );
+
    sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn,
+
                      pExpr->y.sub.iAddr, 1);
+
    VdbeCoverage(v);
    sqlite3ClearTempRegCache(pParse);
  }
}
@@ -105735,9 +106868,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
  ExprSetProperty(pExpr, EP_Subrtn);
  pExpr->y.sub.regReturn = ++pParse->nMem;
  pExpr->y.sub.iAddr =
-
    sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
-
  VdbeComment((v, "return address"));
-

+
    sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1;

  /* The evaluation of the EXISTS/SELECT must be repeated every time it
  ** is encountered if any of the following is true:
@@ -105810,8 +106941,11 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){

  /* Subroutine return */
  assert( ExprUseYSub(pExpr) );
-
  sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
-
  sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
+
  assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn
+
          || pParse->nErr );
+
  sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn,
+
                    pExpr->y.sub.iAddr, 1);
+
  VdbeCoverage(v);
  sqlite3ClearTempRegCache(pParse);
  return rReg;
}
@@ -106245,6 +107379,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
  }
  if( iCol<0 || iCol==pTab->iPKey ){
    sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
+
    VdbeComment((v, "%s.rowid", pTab->zName));
  }else{
    int op;
    int x;
@@ -106415,7 +107550,17 @@ static int exprCodeInlineFunction(
      caseExpr.x.pList = pFarg;
      return sqlite3ExprCodeTarget(pParse, &caseExpr, target);
    }
-

+
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
+
    case INLINEFUNC_sqlite_offset: {
+
      Expr *pArg = pFarg->a[0].pExpr;
+
      if( pArg->op==TK_COLUMN && pArg->iTable>=0 ){
+
        sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
+
      }else{
+
        sqlite3VdbeAddOp2(v, OP_Null, 0, target);
+
      }
+
      break;
+
    }
+
#endif
    default: {
      /* The UNLIKELY() function is a no-op.  The result is the value
      ** of the first argument.
@@ -106954,20 +108099,8 @@ expr_code_doover:
        if( !pColl ) pColl = db->pDfltColl;
        sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
      }
-
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
-
      if( (pDef->funcFlags & SQLITE_FUNC_OFFSET)!=0 && ALWAYS(pFarg!=0) ){
-
        Expr *pArg = pFarg->a[0].pExpr;
-
        if( pArg->op==TK_COLUMN ){
-
          sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
-
        }else{
-
          sqlite3VdbeAddOp2(v, OP_Null, 0, target);
-
        }
-
      }else
-
#endif
-
      {
-
        sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
-
                                   pDef, pExpr->op2);
-
      }
+
      sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg,
+
                                 pDef, pExpr->op2);
      if( nFarg ){
        if( constMask==0 ){
          sqlite3ReleaseTempRange(pParse, r1, nFarg);
@@ -106997,16 +108130,18 @@ expr_code_doover:
    }
    case TK_SELECT_COLUMN: {
      int n;
-
      if( pExpr->pLeft->iTable==0 ){
-
        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
+
      Expr *pLeft = pExpr->pLeft;
+
      if( pLeft->iTable==0 || pParse->withinRJSubrtn > pLeft->op2 ){
+
        pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft);
+
        pLeft->op2 = pParse->withinRJSubrtn;
      }
-
      assert( pExpr->pLeft->op==TK_SELECT || pExpr->pLeft->op==TK_ERROR );
-
      n = sqlite3ExprVectorSize(pExpr->pLeft);
+
      assert( pLeft->op==TK_SELECT || pLeft->op==TK_ERROR );
+
      n = sqlite3ExprVectorSize(pLeft);
      if( pExpr->iTable!=n ){
        sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
                                pExpr->iTable, n);
      }
-
      return pExpr->pLeft->iTable + pExpr->iColumn;
+
      return pLeft->iTable + pExpr->iColumn;
    }
    case TK_IN: {
      int destIfFalse = sqlite3VdbeMakeLabel(pParse);
@@ -107037,8 +108172,24 @@ expr_code_doover:
      exprCodeBetween(pParse, pExpr, target, 0, 0);
      return target;
    }
+
    case TK_COLLATE: {
+
      if( !ExprHasProperty(pExpr, EP_Collate)
+
       && ALWAYS(pExpr->pLeft)
+
       && pExpr->pLeft->op==TK_FUNCTION
+
      ){
+
        inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
+
        if( inReg!=target ){
+
          sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
+
          inReg = target;
+
        }
+
        sqlite3VdbeAddOp1(v, OP_ClrSubtype, inReg);
+
        return inReg;
+
      }else{
+
        pExpr = pExpr->pLeft;
+
        goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. */
+
      }
+
    }
    case TK_SPAN:
-
    case TK_COLLATE:
    case TK_UPLUS: {
      pExpr = pExpr->pLeft;
      goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. OSSFuzz. */
@@ -107279,7 +108430,9 @@ SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(
    struct ExprList_item *pItem;
    int i;
    for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
-
      if( pItem->reusable && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){
+
      if( pItem->fg.reusable
+
       && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0
+
      ){
        return pItem->u.iConstExprReg;
      }
    }
@@ -107302,7 +108455,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeRunJustOnce(
    p = sqlite3ExprListAppend(pParse, p, pExpr);
    if( p ){
       struct ExprList_item *pItem = &p->a[p->nExpr-1];
-
       pItem->reusable = regDest<0;
+
       pItem->fg.reusable = regDest<0;
       if( regDest<0 ) regDest = ++pParse->nMem;
       pItem->u.iConstExprReg = regDest;
    }
@@ -107436,7 +108589,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
  for(pItem=pList->a, i=0; i<n; i++, pItem++){
    Expr *pExpr = pItem->pExpr;
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
-
    if( pItem->bSorterRef ){
+
    if( pItem->fg.bSorterRef ){
      i--;
      n--;
    }else
@@ -107530,8 +108683,8 @@ static void exprCodeBetween(
      ** so that the sqlite3ExprCodeTarget() routine will not attempt to move
      ** it into the Parse.pConstExpr list.  We should use a new bit for this,
      ** for clarity, but we are out of bits in the Expr.flags field so we
-
      ** have to reuse the EP_FromJoin bit.  Bummer. */
-
      pDel->flags |= EP_FromJoin;
+
      ** have to reuse the EP_OuterON bit.  Bummer. */
+
      pDel->flags |= EP_OuterON;
      sqlite3ExprCodeTarget(pParse, &exprAnd, dest);
    }
    sqlite3ReleaseTempReg(pParse, regFree1);
@@ -108061,7 +109214,7 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB
    int res;
    Expr *pExprA = pA->a[i].pExpr;
    Expr *pExprB = pB->a[i].pExpr;
-
    if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1;
+
    if( pA->a[i].fg.sortFlags!=pB->a[i].fg.sortFlags ) return 1;
    if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res;
  }
  return 0;
@@ -108216,7 +109369,7 @@ SQLITE_PRIVATE int sqlite3ExprImpliesExpr(
static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
  testcase( pExpr->op==TK_AGG_COLUMN );
  testcase( pExpr->op==TK_AGG_FUNCTION );
-
  if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune;
+
  if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune;
  switch( pExpr->op ){
    case TK_ISNOT:
    case TK_ISNULL:
@@ -108313,8 +109466,8 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
** False positives are not allowed, however.  A false positive may result
** in an incorrect answer.
**
-
** Terms of p that are marked with EP_FromJoin (and hence that come from
-
** the ON or USING clauses of LEFT JOINS) are excluded from the analysis.
+
** Terms of p that are marked with EP_OuterON (and hence that come from
+
** the ON or USING clauses of OUTER JOINS) are excluded from the analysis.
**
** This routine is used to check if a LEFT JOIN can be converted into
** an ordinary JOIN.  The p argument is the WHERE clause.  If the WHERE
@@ -109728,11 +110881,10 @@ static void unmapColumnIdlistNames(
  Parse *pParse,
  const IdList *pIdList
){
-
  if( pIdList ){
-
    int ii;
-
    for(ii=0; ii<pIdList->nId; ii++){
-
      sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName);
-
    }
+
  int ii;
+
  assert( pIdList!=0 );
+
  for(ii=0; ii<pIdList->nId; ii++){
+
    sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName);
  }
}

@@ -109751,7 +110903,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
  if( ALWAYS(p->pEList) ){
    ExprList *pList = p->pEList;
    for(i=0; i<pList->nExpr; i++){
-
      if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){
+
      if( pList->a[i].zEName && pList->a[i].fg.eEName==ENAME_NAME ){
        sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName);
      }
    }
@@ -109760,8 +110912,11 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){
    SrcList *pSrc = p->pSrc;
    for(i=0; i<pSrc->nSrc; i++){
      sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
-
      sqlite3WalkExpr(pWalker, pSrc->a[i].pOn);
-
      unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
+
      if( pSrc->a[i].fg.isUsing==0 ){
+
        sqlite3WalkExpr(pWalker, pSrc->a[i].u3.pOn);
+
      }else{
+
        unmapColumnIdlistNames(pParse, pSrc->a[i].u3.pUsing);
+
      }
    }
  }

@@ -109797,7 +110952,7 @@ SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){
    sWalker.xExprCallback = renameUnmapExprCb;
    sqlite3WalkExprList(&sWalker, pEList);
    for(i=0; i<pEList->nExpr; i++){
-
      if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) ){
+
      if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) ){
        sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName);
      }
    }
@@ -109955,7 +111110,7 @@ static void renameColumnElistNames(
    int i;
    for(i=0; i<pEList->nExpr; i++){
      const char *zName = pEList->a[i].zEName;
-
      if( ALWAYS(pEList->a[i].eEName==ENAME_NAME)
+
      if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME)
       && ALWAYS(zName!=0)
       && 0==sqlite3_stricmp(zName, zOld)
      ){
@@ -110185,27 +111340,33 @@ static int renameResolveTrigger(Parse *pParse){
    if( rc==SQLITE_OK && pStep->zTarget ){
      SrcList *pSrc = sqlite3TriggerStepSrc(pParse, pStep);
      if( pSrc ){
-
        int i;
-
        for(i=0; i<pSrc->nSrc && rc==SQLITE_OK; i++){
-
          SrcItem *p = &pSrc->a[i];
-
          p->iCursor = pParse->nTab++;
-
          if( p->pSelect ){
-
            sqlite3SelectPrep(pParse, p->pSelect, 0);
-
            sqlite3ExpandSubquery(pParse, p);
-
            assert( i>0 );
-
            assert( pStep->pFrom->a[i-1].pSelect );
-
            sqlite3SelectPrep(pParse, pStep->pFrom->a[i-1].pSelect, 0);
-
          }else{
-
            p->pTab = sqlite3LocateTableItem(pParse, 0, p);
-
            if( p->pTab==0 ){
-
              rc = SQLITE_ERROR;
-
            }else{
-
              p->pTab->nTabRef++;
-
              rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
+
        Select *pSel = sqlite3SelectNew(
+
            pParse, pStep->pExprList, pSrc, 0, 0, 0, 0, 0, 0
+
        );
+
        if( pSel==0 ){
+
          pStep->pExprList = 0;
+
          pSrc = 0;
+
          rc = SQLITE_NOMEM;
+
        }else{
+
          sqlite3SelectPrep(pParse, pSel, 0);
+
          rc = pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
+
          assert( pStep->pExprList==0 || pStep->pExprList==pSel->pEList );
+
          assert( pSrc==pSel->pSrc );
+
          if( pStep->pExprList ) pSel->pEList = 0;
+
          pSel->pSrc = 0;
+
          sqlite3SelectDelete(db, pSel);
+
        }
+
        if( pStep->pFrom ){
+
          int i;
+
          for(i=0; i<pStep->pFrom->nSrc && rc==SQLITE_OK; i++){
+
            SrcItem *p = &pStep->pFrom->a[i];
+
            if( p->pSelect ){
+
              sqlite3SelectPrep(pParse, p->pSelect, 0);
            }
          }
        }
-
        if( rc==SQLITE_OK && db->mallocFailed ){
+

+
        if(  db->mallocFailed ){
          rc = SQLITE_NOMEM;
        }
        sNC.pSrcList = pSrc;
@@ -110657,6 +111818,15 @@ static void renameTableFunc(
              if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){
                renameTokenFind(&sParse, &sCtx, pStep->zTarget);
              }
+
              if( pStep->pFrom ){
+
                int i;
+
                for(i=0; i<pStep->pFrom->nSrc; i++){
+
                  SrcItem *pItem = &pStep->pFrom->a[i];
+
                  if( 0==sqlite3_stricmp(pItem->zName, zOld) ){
+
                    renameTokenFind(&sParse, &sCtx, pItem->zName);
+
                  }
+
                }
+
              }
            }
          }
        }
@@ -111980,9 +113150,14 @@ static void statGet(
    **   * "WHERE a=? AND b=?" matches 2 rows.
    **
    ** If D is the count of distinct values and K is the total number of
-
    ** rows, then each estimate is computed as:
+
    ** rows, then each estimate is usually computed as:
    **
    **        I = (K+D-1)/D
+
    **
+
    ** In other words, I is K/D rounded up to the next whole integer.
+
    ** However, if I is between 1.0 and 1.1 (in other words if I is
+
    ** close to 1.0 but just a little larger) then do not round up but
+
    ** instead keep the I value at 1.0.
    */
    sqlite3_str sStat;   /* Text of the constructed "stat" line */
    int i;               /* Loop counter */
@@ -111993,6 +113168,7 @@ static void statGet(
    for(i=0; i<p->nKeyCol; i++){
      u64 nDistinct = p->current.anDLt[i] + 1;
      u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
+
      if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1;
      sqlite3_str_appendf(&sStat, " %llu", iVal);
      assert( p->current.anEq[i] );
    }
@@ -112156,7 +113332,7 @@ static void analyzeOneTable(
    memcpy(pStat1->zName, "sqlite_stat1", 13);
    pStat1->nCol = 3;
    pStat1->iPKey = -1;
-
    sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
+
    sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNAMIC);
  }
#endif

@@ -113546,7 +114722,11 @@ static int fixSelectCb(Walker *p, Select *pSelect){
      pItem->fg.fromDDL = 1;
    }
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
-
    if( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort;
+
    if( pList->a[i].fg.isUsing==0
+
     && sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn)
+
    ){
+
      return WRC_Abort;
+
    }
#endif
  }
  if( pSelect->pWith ){
@@ -114110,9 +115290,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
      int i;
      int reg;

-
      if( NEVER(pReturning->nRetCol==0) ){
-
        assert( CORRUPT_DB );
-
      }else{
+
      if( pReturning->nRetCol ){
        sqlite3VdbeAddOp0(v, OP_FkCheck);
        addrRewind =
           sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur);
@@ -114152,7 +115330,9 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
      int iDb, i;
      assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
      sqlite3VdbeJumpHere(v, 0);
-
      for(iDb=0; iDb<db->nDb; iDb++){
+
      assert( db->nDb>0 );
+
      iDb = 0;
+
      do{
        Schema *pSchema;
        if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
        sqlite3VdbeUsesBtree(v, iDb);
@@ -114167,7 +115347,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
        if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
        VdbeComment((v,
              "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
-
      }
+
      }while( ++iDb<db->nDb );
#ifndef SQLITE_OMIT_VIRTUALTABLE
      for(i=0; i<pParse->nVtabLock; i++){
        char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
@@ -114206,9 +115386,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){

      if( pParse->bReturning ){
        Returning *pRet = pParse->u1.pReturning;
-
        if( NEVER(pRet->nRetCol==0) ){
-
          assert( CORRUPT_DB );
-
        }else{
+
        if( pRet->nRetCol ){
          sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol);
        }
      }
@@ -114271,8 +115449,6 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
  db->mDbFlags |= DBFLAG_PreferBuiltin;
  sqlite3RunParser(pParse, zSql);
-
  sqlite3DbFree(db, pParse->zErrMsg);
-
  pParse->zErrMsg = 0;
  db->mDbFlags = savedDbFlags;
  sqlite3DbFree(db, zSql);
  memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ);
@@ -115830,7 +117006,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey(
    pTab->keyConf = (u8)onError;
    assert( autoInc==0 || autoInc==1 );
    pTab->tabFlags |= autoInc*TF_Autoincrement;
-
    if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags;
+
    if( pList ) pParse->iPkSortOrder = pList->a[0].fg.sortFlags;
    (void)sqlite3HasExplicitNulls(pParse, pList);
  }else if( autoInc ){
#ifndef SQLITE_OMIT_AUTOINCREMENT
@@ -116324,7 +117500,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
    if( IN_RENAME_OBJECT ){
      sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey);
    }
-
    pList->a[0].sortFlags = pParse->iPkSortOrder;
+
    pList->a[0].fg.sortFlags = pParse->iPkSortOrder;
    assert( pParse->pNewTable==pTab );
    pTab->iPKey = -1;
    sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0,
@@ -116995,7 +118171,6 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
  Table *pSelTab;   /* A fake table from which we get the result set */
  Select *pSel;     /* Copy of the SELECT that implements the view */
  int nErr = 0;     /* Number of errors encountered */
-
  int n;            /* Temporarily holds the number of cursors assigned */
  sqlite3 *db = pParse->db;  /* Database connection for malloc errors */
#ifndef SQLITE_OMIT_VIRTUALTABLE
  int rc;
@@ -117053,8 +118228,9 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
  pSel = sqlite3SelectDup(db, pTable->u.view.pSelect, 0);
  if( pSel ){
    u8 eParseMode = pParse->eParseMode;
+
    int nTab = pParse->nTab;
+
    int nSelect = pParse->nSelect;
    pParse->eParseMode = PARSE_MODE_NORMAL;
-
    n = pParse->nTab;
    sqlite3SrcListAssignCursors(pParse, pSel->pSrc);
    pTable->nCol = -1;
    DisableLookaside;
@@ -117066,7 +118242,8 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
#else
    pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE);
#endif
-
    pParse->nTab = n;
+
    pParse->nTab = nTab;
+
    pParse->nSelect = nSelect;
    if( pSelTab==0 ){
      pTable->nCol = 0;
      nErr++;
@@ -117811,8 +118988,8 @@ SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){
  if( pList ){
    int i;
    for(i=0; i<pList->nExpr; i++){
-
      if( pList->a[i].bNulls ){
-
        u8 sf = pList->a[i].sortFlags;
+
      if( pList->a[i].fg.bNulls ){
+
        u8 sf = pList->a[i].fg.sortFlags;
        sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s",
            (sf==0 || sf==3) ? "FIRST" : "LAST"
        );
@@ -118165,7 +119342,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex(
      goto exit_create_index;
    }
    pIndex->azColl[i] = zColl;
-
    requestedSortOrder = pListItem->sortFlags & sortOrderMask;
+
    requestedSortOrder = pListItem->fg.sortFlags & sortOrderMask;
    pIndex->aSortOrder[i] = (u8)requestedSortOrder;
  }

@@ -118608,18 +119785,17 @@ SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *
  if( pList==0 ){
    pList = sqlite3DbMallocZero(db, sizeof(IdList) );
    if( pList==0 ) return 0;
+
  }else{
+
    IdList *pNew;
+
    pNew = sqlite3DbRealloc(db, pList,
+
                 sizeof(IdList) + pList->nId*sizeof(pList->a));
+
    if( pNew==0 ){
+
      sqlite3IdListDelete(db, pList);
+
      return 0;
+
    }
+
    pList = pNew;
  }
-
  pList->a = sqlite3ArrayAllocate(
-
      db,
-
      pList->a,
-
      sizeof(pList->a[0]),
-
      &pList->nId,
-
      &i
-
  );
-
  if( i<0 ){
-
    sqlite3IdListDelete(db, pList);
-
    return 0;
-
  }
+
  i = pList->nId++;
  pList->a[i].zName = sqlite3NameFromToken(db, pToken);
  if( IN_RENAME_OBJECT && pList->a[i].zName ){
    sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken);
@@ -118633,10 +119809,10 @@ SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
  int i;
  if( pList==0 ) return;
+
  assert( pList->eU4!=EU4_EXPR ); /* EU4_EXPR mode is not currently used */
  for(i=0; i<pList->nId; i++){
    sqlite3DbFree(db, pList->a[i].zName);
  }
-
  sqlite3DbFree(db, pList->a);
  sqlite3DbFreeNN(db, pList);
}

@@ -118646,7 +119822,7 @@ SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
*/
SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){
  int i;
-
  if( pList==0 ) return -1;
+
  assert( pList!=0 );
  for(i=0; i<pList->nId; i++){
    if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i;
  }
@@ -118849,8 +120025,11 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
    if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg);
    sqlite3DeleteTable(db, pItem->pTab);
    if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect);
-
    if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn);
-
    if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing);
+
    if( pItem->fg.isUsing ){
+
      sqlite3IdListDelete(db, pItem->u3.pUsing);
+
    }else if( pItem->u3.pOn ){
+
      sqlite3ExprDelete(db, pItem->u3.pOn);
+
    }
  }
  sqlite3DbFreeNN(db, pList);
}
@@ -118878,14 +120057,13 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
  Token *pDatabase,       /* Name of the database containing pTable */
  Token *pAlias,          /* The right-hand side of the AS subexpression */
  Select *pSubquery,      /* A subquery used in place of a table name */
-
  Expr *pOn,              /* The ON clause of a join */
-
  IdList *pUsing          /* The USING clause of a join */
+
  OnOrUsing *pOnUsing     /* Either the ON clause or the USING clause */
){
  SrcItem *pItem;
  sqlite3 *db = pParse->db;
-
  if( !p && (pOn || pUsing) ){
+
  if( !p && pOnUsing!=0 && (pOnUsing->pOn || pOnUsing->pUsing) ){
    sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s",
-
      (pOn ? "ON" : "USING")
+
      (pOnUsing->pOn ? "ON" : "USING")
    );
    goto append_from_error;
  }
@@ -118905,15 +120083,27 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(
  if( pAlias->n ){
    pItem->zAlias = sqlite3NameFromToken(db, pAlias);
  }
-
  pItem->pSelect = pSubquery;
-
  pItem->pOn = pOn;
-
  pItem->pUsing = pUsing;
+
  if( pSubquery ){
+
    pItem->pSelect = pSubquery;
+
    if( pSubquery->selFlags & SF_NestedFrom ){
+
      pItem->fg.isNestedFrom = 1;
+
    }
+
  }
+
  assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 );
+
  assert( pItem->fg.isUsing==0 );
+
  if( pOnUsing==0 ){
+
    pItem->u3.pOn = 0;
+
  }else if( pOnUsing->pUsing ){
+
    pItem->fg.isUsing = 1;
+
    pItem->u3.pUsing = pOnUsing->pUsing;
+
  }else{
+
    pItem->u3.pOn = pOnUsing->pOn;
+
  }
  return p;

append_from_error:
  assert( p==0 );
-
  sqlite3ExprDelete(db, pOn);
-
  sqlite3IdListDelete(db, pUsing);
+
  sqlite3ClearOnOrUsing(db, pOnUsing);
  sqlite3SelectDelete(db, pSubquery);
  return 0;
}
@@ -118958,6 +120148,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, Src
      p1 = pNew;
      memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem));
      sqlite3DbFree(pParse->db, p2);
+
      p1->a[0].fg.jointype |= (JT_LTORJ & p1->a[1].fg.jointype);
    }
  }
  return p1;
@@ -118994,14 +120185,34 @@ SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *
** The operator is "natural cross join".  The A and B operands are stored
** in p->a[0] and p->a[1], respectively.  The parser initially stores the
** operator with A.  This routine shifts that operator over to B.
+
**
+
** Additional changes:
+
**
+
**   *   All tables to the left of the right-most RIGHT JOIN are tagged with
+
**       JT_LTORJ (mnemonic: Left Table Of Right Join) so that the
+
**       code generator can easily tell that the table is part of
+
**       the left operand of at least one RIGHT JOIN.
*/
-
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
-
  if( p ){
-
    int i;
-
    for(i=p->nSrc-1; i>0; i--){
-
      p->a[i].fg.jointype = p->a[i-1].fg.jointype;
-
    }
+
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(Parse *pParse, SrcList *p){
+
  (void)pParse;
+
  if( p && p->nSrc>1 ){
+
    int i = p->nSrc-1;
+
    u8 allFlags = 0;
+
    do{
+
      allFlags |= p->a[i].fg.jointype = p->a[i-1].fg.jointype;
+
    }while( (--i)>0 );
    p->a[0].fg.jointype = 0;
+

+
    /* All terms to the left of a RIGHT JOIN should be tagged with the
+
    ** JT_LTORJ flags */
+
    if( allFlags & JT_RIGHT ){
+
      for(i=p->nSrc-1; ALWAYS(i>0) && (p->a[i].fg.jointype&JT_RIGHT)==0; i--){}
+
      i--;
+
      assert( i>=0 );
+
      do{
+
        p->a[i].fg.jointype |= JT_LTORJ;
+
      }while( (--i)>=0 );
+
    }
  }
}

@@ -120250,8 +121461,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
    assert( pFrom->nSrc==1 );
    pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
    pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
-
    assert( pFrom->a[0].pOn==0 );
-
    assert( pFrom->a[0].pUsing==0 );
+
    assert( pFrom->a[0].fg.isUsing==0 );
+
    assert( pFrom->a[0].u3.pOn==0 );
  }
  pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy,
                          SF_IncludeHidden, pLimit);
@@ -120422,7 +121633,6 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
  assert( db->mallocFailed==0 );
  assert( pTabList->nSrc==1 );

-

  /* Locate the table which we want to delete.  This table has to be
  ** put in an SrcList structure because some of the subroutines we
  ** will be calling are designed to work with multiple tables and expect
@@ -120447,6 +121657,14 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
# define isView 0
#endif

+
#if TREETRACE_ENABLED
+
  if( sqlite3TreeTrace & 0x10000 ){
+
    sqlite3TreeViewLine(0, "In sqlite3Delete() at %s:%d", __FILE__, __LINE__);
+
    sqlite3TreeViewDelete(pParse->pWith, pTabList, pWhere,
+
                          pOrderBy, pLimit, pTrigger);
+
  }
+
#endif
+

#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
  if( !isView ){
    pWhere = sqlite3LimitWhere(
@@ -123205,11 +124423,11 @@ static void logFunc(
    switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){
      case 1:
        /* Convert from natural logarithm to log base 10 */
-
        ans *= 1.0/M_LN10;
+
        ans /= M_LN10;
        break;
      case 2:
        /* Convert from natural logarithm to log base 2 */
-
        ans *= 1.0/M_LN2;
+
        ans /= M_LN2;
        break;
      default:
        break;
@@ -123348,8 +124566,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
    INLINE_FUNC(likelihood,      2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
    INLINE_FUNC(likely,          1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
-
    {1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF,
-
     0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} },
+
    INLINE_FUNC(sqlite_offset,   1, INLINEFUNC_sqlite_offset, 0 ),
#endif
    FUNCTION(ltrim,              1, 1, 0, trimFunc         ),
    FUNCTION(ltrim,              2, 1, 0, trimFunc         ),
@@ -123884,7 +125101,6 @@ static void fkLookupParent(
    }else{
      int nCol = pFKey->nCol;
      int regTemp = sqlite3GetTempRange(pParse, nCol);
-
      int regRec = sqlite3GetTempReg(pParse);

      sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb);
      sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
@@ -123924,11 +125140,10 @@ static void fkLookupParent(
        sqlite3VdbeGoto(v, iOk);
      }

-
      sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
+
      sqlite3VdbeAddOp4(v, OP_Affinity, regTemp, nCol, 0,
                        sqlite3IndexAffinityStr(pParse->db,pIdx), nCol);
-
      sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
-

-
      sqlite3ReleaseTempReg(pParse, regRec);
+
      sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regTemp, nCol);
+
      VdbeCoverage(v);
      sqlite3ReleaseTempRange(pParse, regTemp, nCol);
    }
  }
@@ -124030,14 +125245,10 @@ static Expr *exprTableColumn(
**   Operation | FK type   | Action taken
**   --------------------------------------------------------------------------
**   DELETE      immediate   Increment the "immediate constraint counter".
-
**                           Or, if the ON (UPDATE|DELETE) action is RESTRICT,
-
**                           throw a "FOREIGN KEY constraint failed" exception.
**
**   INSERT      immediate   Decrement the "immediate constraint counter".
**
**   DELETE      deferred    Increment the "deferred constraint counter".
-
**                           Or, if the ON (UPDATE|DELETE) action is RESTRICT,
-
**                           throw a "FOREIGN KEY constraint failed" exception.
**
**   INSERT      deferred    Decrement the "deferred constraint counter".
**
@@ -124685,9 +125896,9 @@ SQLITE_PRIVATE int sqlite3FkRequired(
**
** It returns a pointer to a Trigger structure containing a trigger
** equivalent to the ON UPDATE or ON DELETE action specified by pFKey.
-
** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is
-
** returned (these actions require no special handling by the triggers
-
** sub-system, code for them is created by fkScanChildren()).
+
** If the action is "NO ACTION" then a NULL pointer is returned (these actions
+
** require no special handling by the triggers sub-system, code for them is
+
** created by fkScanChildren()).
**
** For example, if pFKey is the foreign key and pTab is table "p" in
** the following schema:
@@ -124816,18 +126027,23 @@ static Trigger *fkActionTrigger(
    nFrom = sqlite3Strlen30(zFrom);

    if( action==OE_Restrict ){
+
      int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
      Token tFrom;
+
      Token tDb;
      Expr *pRaise;

      tFrom.z = zFrom;
      tFrom.n = nFrom;
+
      tDb.z = db->aDb[iDb].zDbSName;
+
      tDb.n = sqlite3Strlen30(tDb.z);
+

      pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed");
      if( pRaise ){
        pRaise->affExpr = OE_Abort;
      }
      pSelect = sqlite3SelectNew(pParse,
          sqlite3ExprListAppend(pParse, 0, pRaise),
-
          sqlite3SrcListAppend(pParse, 0, &tFrom, 0),
+
          sqlite3SrcListAppend(pParse, 0, &tDb, &tFrom),
          pWhere,
          0, 0, 0, 0, 0
      );
@@ -125737,6 +126953,14 @@ SQLITE_PRIVATE void sqlite3Insert(
#endif
  assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) );

+
#if TREETRACE_ENABLED
+
  if( sqlite3TreeTrace & 0x10000 ){
+
    sqlite3TreeViewLine(0, "In sqlite3Insert() at %s:%d", __FILE__, __LINE__);
+
    sqlite3TreeViewInsert(pParse->pWith, pTabList, pColumn, pSelect, pList,
+
                          onError, pUpsert, pTrigger);
+
  }
+
#endif
+

  /* If pTab is really a view, make sure it has been initialized.
  ** ViewGetColumnNames() is a no-op if pTab is not a view.
  */
@@ -125815,13 +127039,15 @@ SQLITE_PRIVATE void sqlite3Insert(
  */
  bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0;
  if( pColumn ){
+
    assert( pColumn->eU4!=EU4_EXPR );
+
    pColumn->eU4 = EU4_IDX;
    for(i=0; i<pColumn->nId; i++){
-
      pColumn->a[i].idx = -1;
+
      pColumn->a[i].u4.idx = -1;
    }
    for(i=0; i<pColumn->nId; i++){
      for(j=0; j<pTab->nCol; j++){
        if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zCnName)==0 ){
-
          pColumn->a[i].idx = j;
+
          pColumn->a[i].u4.idx = j;
          if( i!=j ) bIdListInOrder = 0;
          if( j==pTab->iPKey ){
            ipkColumn = i;  assert( !withoutRowid );
@@ -126123,7 +127349,8 @@ SQLITE_PRIVATE void sqlite3Insert(
      }
    }
    if( pColumn ){
-
      for(j=0; j<pColumn->nId && pColumn->a[j].idx!=i; j++){}
+
      assert( pColumn->eU4==EU4_IDX );
+
      for(j=0; j<pColumn->nId && pColumn->a[j].u4.idx!=i; j++){}
      if( j>=pColumn->nId ){
        /* A column not named in the insert column list gets its
        ** default value */
@@ -127254,7 +128481,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
        if( isUpdate ){
          /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
          ** table, only conflict if the new PRIMARY KEY values are actually
-
          ** different from the old.
+
          ** different from the old.  See TH3 withoutrowid04.test.
          **
          ** For a UNIQUE index, only conflict if the PRIMARY KEY values
          ** of the matched index row are different from the original PRIMARY
@@ -128618,6 +129845,12 @@ struct sqlite3_api_routines {
  int (*vtab_in)(sqlite3_index_info*,int,int);
  int (*vtab_in_first)(sqlite3_value*,sqlite3_value**);
  int (*vtab_in_next)(sqlite3_value*,sqlite3_value**);
+
  /* Version 3.39.0 and later */
+
  int (*deserialize)(sqlite3*,const char*,unsigned char*,
+
                     sqlite3_int64,sqlite3_int64,unsigned);
+
  unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
+
                              unsigned int);
+
  const char *(*db_name)(sqlite3*,int);
};

/*
@@ -128936,6 +130169,12 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_vtab_in                sqlite3_api->vtab_in
#define sqlite3_vtab_in_first          sqlite3_api->vtab_in_first
#define sqlite3_vtab_in_next           sqlite3_api->vtab_in_next
+
/* Version 3.39.0 and later */
+
#ifndef SQLITE_OMIT_DESERIALIZE
+
#define sqlite3_deserialize            sqlite3_api->deserialize
+
#define sqlite3_serialize              sqlite3_api->serialize
+
#endif
+
#define sqlite3_db_name                sqlite3_api->db_name
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */

#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -129427,11 +130666,28 @@ static const sqlite3_api_routines sqlite3Apis = {
  sqlite3_autovacuum_pages,
  /* Version 3.38.0 and later */
  sqlite3_error_offset,
+
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3_vtab_rhs_value,
  sqlite3_vtab_distinct,
  sqlite3_vtab_in,
  sqlite3_vtab_in_first,
-
  sqlite3_vtab_in_next
+
  sqlite3_vtab_in_next,
+
#else
+
  0,
+
  0,
+
  0,
+
  0,
+
  0,
+
#endif
+
  /* Version 3.39.0 and later */
+
#ifndef SQLITE_OMIT_DESERIALIZE
+
  sqlite3_deserialize,
+
  sqlite3_serialize,
+
#else
+
  0,
+
  0,
+
#endif
+
  sqlite3_db_name
};

/* True if x is the directory separator character
@@ -130102,7 +131358,7 @@ static const PragmaName aPragmaName[] = {
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "database_list",
  /* ePragTyp:  */ PragTyp_DATABASE_LIST,
-
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
+
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 47, 3,
  /* iArg:      */ 0 },
#endif
@@ -130790,15 +132046,16 @@ static void pragmaFunclistLine(
  int isBuiltin,         /* True if this is a built-in function */
  int showInternFuncs    /* True if showing internal functions */
){
+
  u32 mask =
+
      SQLITE_DETERMINISTIC |
+
      SQLITE_DIRECTONLY |
+
      SQLITE_SUBTYPE |
+
      SQLITE_INNOCUOUS |
+
      SQLITE_FUNC_INTERNAL
+
  ;
+
  if( showInternFuncs ) mask = 0xffffffff;
  for(; p; p=p->pNext){
    const char *zType;
-
    static const u32 mask =
-
        SQLITE_DETERMINISTIC |
-
        SQLITE_DIRECTONLY |
-
        SQLITE_SUBTYPE |
-
        SQLITE_INNOCUOUS |
-
        SQLITE_FUNC_INTERNAL
-
    ;
    static const char *azEnc[] = { 0, "utf8", "utf16le", "utf16be" };

    assert( SQLITE_FUNC_ENCMASK==0x3 );
@@ -131290,7 +132547,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
  */
#ifndef SQLITE_OMIT_AUTOVACUUM
  case PragTyp_INCREMENTAL_VACUUM: {
-
    int iLimit, addr;
+
    int iLimit = 0, addr;
    if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){
      iLimit = 0x7fffffff;
    }
@@ -131978,7 +133235,6 @@ SQLITE_PRIVATE void sqlite3Pragma(
    HashElem *k;           /* Loop counter:  Next table in schema */
    int x;                 /* result variable */
    int regResult;         /* 3 registers to hold a result row */
-
    int regKey;            /* Register to hold key for checking the FK */
    int regRow;            /* Registers to hold a row from pTab */
    int addrTop;           /* Top of a loop checking foreign keys */
    int addrOk;            /* Jump here if the key is OK */
@@ -131986,7 +133242,6 @@ SQLITE_PRIVATE void sqlite3Pragma(

    regResult = pParse->nMem+1;
    pParse->nMem += 4;
-
    regKey = ++pParse->nMem;
    regRow = ++pParse->nMem;
    k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash);
    while( k ){
@@ -132053,9 +133308,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
        /* Generate code to query the parent index for a matching parent
        ** key. If a match is found, jump to addrOk. */
        if( pIdx ){
-
          sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
+
          sqlite3VdbeAddOp4(v, OP_Affinity, regRow, pFK->nCol, 0,
              sqlite3IndexAffinityStr(db,pIdx), pFK->nCol);
-
          sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+
          sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regRow, pFK->nCol);
          VdbeCoverage(v);
        }else if( pParent ){
          int jmp = sqlite3VdbeCurrentAddr(v)+2;
@@ -134291,7 +135546,7 @@ SQLITE_API int sqlite3_prepare16_v3(
*/
typedef struct DistinctCtx DistinctCtx;
struct DistinctCtx {
-
  u8 isTnct;      /* True if the DISTINCT keyword is present */
+
  u8 isTnct;      /* 0: Not distinct. 1: DISTICT  2: DISTINCT and ORDER BY */
  u8 eTnctType;   /* One of the WHERE_DISTINCT_* operators */
  int tabTnct;    /* Ephemeral table used for DISTINCT processing */
  int addrTnct;   /* Address of OP_OpenEphemeral opcode for tabTnct */
@@ -134474,6 +135729,52 @@ static Select *findRightmost(Select *p){
**
** If an illegal or unsupported join type is seen, then still return
** a join type, but put an error in the pParse structure.
+
**
+
** These are the valid join types:
+
**
+
**
+
**      pA       pB       pC               Return Value
+
**     -------  -----    -----             ------------
+
**     CROSS      -        -                 JT_CROSS
+
**     INNER      -        -                 JT_INNER
+
**     LEFT       -        -                 JT_LEFT|JT_OUTER
+
**     LEFT     OUTER      -                 JT_LEFT|JT_OUTER
+
**     RIGHT      -        -                 JT_RIGHT|JT_OUTER
+
**     RIGHT    OUTER      -                 JT_RIGHT|JT_OUTER
+
**     FULL       -        -                 JT_LEFT|JT_RIGHT|JT_OUTER
+
**     FULL     OUTER      -                 JT_LEFT|JT_RIGHT|JT_OUTER
+
**     NATURAL  INNER      -                 JT_NATURAL|JT_INNER
+
**     NATURAL  LEFT       -                 JT_NATURAL|JT_LEFT|JT_OUTER
+
**     NATURAL  LEFT     OUTER               JT_NATURAL|JT_LEFT|JT_OUTER
+
**     NATURAL  RIGHT      -                 JT_NATURAL|JT_RIGHT|JT_OUTER
+
**     NATURAL  RIGHT    OUTER               JT_NATURAL|JT_RIGHT|JT_OUTER
+
**     NATURAL  FULL       -                 JT_NATURAL|JT_LEFT|JT_RIGHT
+
**     NATURAL  FULL     OUTER               JT_NATRUAL|JT_LEFT|JT_RIGHT
+
**
+
** To preserve historical compatibly, SQLite also accepts a variety
+
** of other non-standard and in many cases non-sensical join types.
+
** This routine makes as much sense at it can from the nonsense join
+
** type and returns a result.  Examples of accepted nonsense join types
+
** include but are not limited to:
+
**
+
**          INNER CROSS JOIN        ->   same as JOIN
+
**          NATURAL CROSS JOIN      ->   same as NATURAL JOIN
+
**          OUTER LEFT JOIN         ->   same as LEFT JOIN
+
**          LEFT NATURAL JOIN       ->   same as NATURAL LEFT JOIN
+
**          LEFT RIGHT JOIN         ->   same as FULL JOIN
+
**          RIGHT OUTER FULL JOIN   ->   same as FULL JOIN
+
**          CROSS CROSS CROSS JOIN  ->   same as JOIN
+
**
+
** The only restrictions on the join type name are:
+
**
+
**    *   "INNER" cannot appear together with "OUTER", "LEFT", "RIGHT",
+
**        or "FULL".
+
**
+
**    *   "CROSS" cannot appear together with "OUTER", "LEFT", "RIGHT,
+
**        or "FULL".
+
**
+
**    *   If "OUTER" is present then there must also be one of
+
**        "LEFT", "RIGHT", or "FULL"
*/
SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
  int jointype = 0;
@@ -134486,13 +135787,13 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p
    u8 nChar;    /* Length of the keyword in characters */
    u8 code;     /* Join type mask */
  } aKeyword[] = {
-
    /* natural */ { 0,  7, JT_NATURAL                },
-
    /* left    */ { 6,  4, JT_LEFT|JT_OUTER          },
-
    /* outer   */ { 10, 5, JT_OUTER                  },
-
    /* right   */ { 14, 5, JT_RIGHT|JT_OUTER         },
-
    /* full    */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
-
    /* inner   */ { 23, 5, JT_INNER                  },
-
    /* cross   */ { 28, 5, JT_INNER|JT_CROSS         },
+
    /* (0) natural */ { 0,  7, JT_NATURAL                },
+
    /* (1) left    */ { 6,  4, JT_LEFT|JT_OUTER          },
+
    /* (2) outer   */ { 10, 5, JT_OUTER                  },
+
    /* (3) right   */ { 14, 5, JT_RIGHT|JT_OUTER         },
+
    /* (4) full    */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER },
+
    /* (5) inner   */ { 23, 5, JT_INNER                  },
+
    /* (6) cross   */ { 28, 5, JT_INNER|JT_CROSS         },
  };
  int i, j;
  apAll[0] = pA;
@@ -134515,18 +135816,15 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p
  }
  if(
     (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
-
     (jointype & JT_ERROR)!=0
+
     (jointype & JT_ERROR)!=0 ||
+
     (jointype & (JT_OUTER|JT_LEFT|JT_RIGHT))==JT_OUTER
  ){
-
    const char *zSp = " ";
-
    assert( pB!=0 );
-
    if( pC==0 ){ zSp++; }
-
    sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
-
       "%T %T%s%T", pA, pB, zSp, pC);
-
    jointype = JT_INNER;
-
  }else if( (jointype & JT_OUTER)!=0
-
         && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){
-
    sqlite3ErrorMsg(pParse,
-
      "RIGHT and FULL OUTER JOINs are not currently supported");
+
    const char *zSp1 = " ";
+
    const char *zSp2 = " ";
+
    if( pB==0 ){ zSp1++; }
+
    if( pC==0 ){ zSp2++; }
+
    sqlite3ErrorMsg(pParse, "unknown join type: "
+
       "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC);
    jointype = JT_INNER;
  }
  return jointype;
@@ -134547,8 +135845,25 @@ SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){
}

/*
-
** Search the first N tables in pSrc, from left to right, looking for a
-
** table that has a column named zCol.
+
** Mark a subquery result column as having been used.
+
*/
+
SQLITE_PRIVATE void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){
+
  assert( pItem!=0 );
+
  assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) );
+
  if( pItem->fg.isNestedFrom ){
+
    ExprList *pResults;
+
    assert( pItem->pSelect!=0 );
+
    pResults = pItem->pSelect->pEList;
+
    assert( pResults!=0 );
+
    assert( iCol>=0 && iCol<pResults->nExpr );
+
    pResults->a[iCol].fg.bUsed = 1;
+
  }
+
}
+

+
/*
+
** Search the tables iStart..iEnd (inclusive) in pSrc, looking for a
+
** table that has a column named zCol.  The search is left-to-right.
+
** The first match found is returned.
**
** When found, set *piTab and *piCol to the table index and column index
** of the matching column and return TRUE.
@@ -134557,22 +135872,27 @@ SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){
*/
static int tableAndColumnIndex(
  SrcList *pSrc,       /* Array of tables to search */
-
  int N,               /* Number of tables in pSrc->a[] to search */
+
  int iStart,          /* First member of pSrc->a[] to check */
+
  int iEnd,            /* Last member of pSrc->a[] to check */
  const char *zCol,    /* Name of the column we are looking for */
  int *piTab,          /* Write index of pSrc->a[] here */
  int *piCol,          /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
-
  int bIgnoreHidden    /* True to ignore hidden columns */
+
  int bIgnoreHidden    /* Ignore hidden columns */
){
  int i;               /* For looping over tables in pSrc */
  int iCol;            /* Index of column matching zCol */

+
  assert( iEnd<pSrc->nSrc );
+
  assert( iStart>=0 );
  assert( (piTab==0)==(piCol==0) );  /* Both or neither are NULL */
-
  for(i=0; i<N; i++){
+

+
  for(i=iStart; i<=iEnd; i++){
    iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol);
    if( iCol>=0
     && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0)
    ){
      if( piTab ){
+
        sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol);
        *piTab = i;
        *piCol = iCol;
      }
@@ -134583,66 +135903,19 @@ static int tableAndColumnIndex(
}

/*
-
** This function is used to add terms implied by JOIN syntax to the
-
** WHERE clause expression of a SELECT statement. The new term, which
-
** is ANDed with the existing WHERE clause, is of the form:
-
**
-
**    (tab1.col1 = tab2.col2)
-
**
-
** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the
-
** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is
-
** column iColRight of tab2.
-
*/
-
static void addWhereTerm(
-
  Parse *pParse,                  /* Parsing context */
-
  SrcList *pSrc,                  /* List of tables in FROM clause */
-
  int iLeft,                      /* Index of first table to join in pSrc */
-
  int iColLeft,                   /* Index of column in first table */
-
  int iRight,                     /* Index of second table in pSrc */
-
  int iColRight,                  /* Index of column in second table */
-
  int isOuterJoin,                /* True if this is an OUTER join */
-
  Expr **ppWhere                  /* IN/OUT: The WHERE clause to add to */
-
){
-
  sqlite3 *db = pParse->db;
-
  Expr *pE1;
-
  Expr *pE2;
-
  Expr *pEq;
-

-
  assert( iLeft<iRight );
-
  assert( pSrc->nSrc>iRight );
-
  assert( pSrc->a[iLeft].pTab );
-
  assert( pSrc->a[iRight].pTab );
-

-
  pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
-
  pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);
-

-
  pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
-
  assert( pE2!=0 || pEq==0 );  /* Due to db->mallocFailed test
-
                               ** in sqlite3DbMallocRawNN() called from
-
                               ** sqlite3PExpr(). */
-
  if( pEq && isOuterJoin ){
-
    ExprSetProperty(pEq, EP_FromJoin);
-
    assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
-
    ExprSetVVAProperty(pEq, EP_NoReduce);
-
    pEq->w.iRightJoinTable = pE2->iTable;
-
  }
-
  *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
-
}
-

-
/*
-
** Set the EP_FromJoin property on all terms of the given expression.
-
** And set the Expr.w.iRightJoinTable to iTable for every term in the
+
** Set the EP_OuterON property on all terms of the given expression.
+
** And set the Expr.w.iJoin to iTable for every term in the
** expression.
**
-
** The EP_FromJoin property is used on terms of an expression to tell
-
** the LEFT OUTER JOIN processing logic that this term is part of the
+
** The EP_OuterON property is used on terms of an expression to tell
+
** the OUTER JOIN processing logic that this term is part of the
** join restriction specified in the ON or USING clause and not a part
** of the more general WHERE clause.  These terms are moved over to the
** WHERE clause during join processing but we need to remember that they
** originated in the ON or USING clause.
**
-
** The Expr.w.iRightJoinTable tells the WHERE clause processing that the
-
** expression depends on table w.iRightJoinTable even if that table is not
+
** The Expr.w.iJoin tells the WHERE clause processing that the
+
** expression depends on table w.iJoin even if that table is not
** explicitly mentioned in the expression.  That information is needed
** for cases like this:
**
@@ -134655,39 +135928,48 @@ static void addWhereTerm(
** after the t1 loop and rows with t1.x!=5 will never appear in
** the output, which is incorrect.
*/
-
SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){
+
SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){
+
  assert( joinFlag==EP_OuterON || joinFlag==EP_InnerON );
  while( p ){
-
    ExprSetProperty(p, EP_FromJoin);
+
    ExprSetProperty(p, joinFlag);
    assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
    ExprSetVVAProperty(p, EP_NoReduce);
-
    p->w.iRightJoinTable = iTable;
+
    p->w.iJoin = iTable;
    if( p->op==TK_FUNCTION ){
      assert( ExprUseXList(p) );
      if( p->x.pList ){
        int i;
        for(i=0; i<p->x.pList->nExpr; i++){
-
          sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
+
          sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable, joinFlag);
        }
      }
    }
-
    sqlite3SetJoinExpr(p->pLeft, iTable);
+
    sqlite3SetJoinExpr(p->pLeft, iTable, joinFlag);
    p = p->pRight;
  }
}

-
/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
-
** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into
-
** an ordinary term that omits the EP_FromJoin mark.
+
/* Undo the work of sqlite3SetJoinExpr().  This is used when a LEFT JOIN
+
** is simplified into an ordinary JOIN, and when an ON expression is
+
** "pushed down" into the WHERE clause of a subquery.
+
**
+
** Convert every term that is marked with EP_OuterON and w.iJoin==iTable into
+
** an ordinary term that omits the EP_OuterON mark.  Or if iTable<0, then
+
** just clear every EP_OuterON and EP_InnerON mark from the expression tree.
**
-
** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
+
** If nullable is true, that means that Expr p might evaluate to NULL even
+
** if it is a reference to a NOT NULL column.  This can happen, for example,
+
** if the table that p references is on the left side of a RIGHT JOIN.
+
** If nullable is true, then take care to not remove the EP_CanBeNull bit.
+
** See forum thread https://sqlite.org/forum/forumpost/b40696f50145d21c
*/
-
static void unsetJoinExpr(Expr *p, int iTable){
+
static void unsetJoinExpr(Expr *p, int iTable, int nullable){
  while( p ){
-
    if( ExprHasProperty(p, EP_FromJoin)
-
     && (iTable<0 || p->w.iRightJoinTable==iTable) ){
-
      ExprClearProperty(p, EP_FromJoin);
+
    if( iTable<0 || (ExprHasProperty(p, EP_OuterON) && p->w.iJoin==iTable) ){
+
      ExprClearProperty(p, EP_OuterON|EP_InnerON);
+
      if( iTable>=0 ) ExprSetProperty(p, EP_InnerON);
    }
-
    if( p->op==TK_COLUMN && p->iTable==iTable ){
+
    if( p->op==TK_COLUMN && p->iTable==iTable && !nullable ){
      ExprClearProperty(p, EP_CanBeNull);
    }
    if( p->op==TK_FUNCTION ){
@@ -134695,30 +135977,37 @@ static void unsetJoinExpr(Expr *p, int iTable){
      if( p->x.pList ){
        int i;
        for(i=0; i<p->x.pList->nExpr; i++){
-
          unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
+
          unsetJoinExpr(p->x.pList->a[i].pExpr, iTable, nullable);
        }
      }
    }
-
    unsetJoinExpr(p->pLeft, iTable);
+
    unsetJoinExpr(p->pLeft, iTable, nullable);
    p = p->pRight;
  }
}

/*
** This routine processes the join information for a SELECT statement.
-
** ON and USING clauses are converted into extra terms of the WHERE clause.
-
** NATURAL joins also create extra WHERE clause terms.
+
**
+
**   *  A NATURAL join is converted into a USING join.  After that, we
+
**      do not need to be concerned with NATURAL joins and we only have
+
**      think about USING joins.
+
**
+
**   *  ON and USING clauses result in extra terms being added to the
+
**      WHERE clause to enforce the specified constraints.  The extra
+
**      WHERE clause terms will be tagged with EP_OuterON or
+
**      EP_InnerON so that we know that they originated in ON/USING.
**
** The terms of a FROM clause are contained in the Select.pSrc structure.
** The left most table is the first entry in Select.pSrc.  The right-most
** table is the last entry.  The join operator is held in the entry to
-
** the left.  Thus entry 0 contains the join operator for the join between
+
** the right.  Thus entry 1 contains the join operator for the join between
** entries 0 and 1.  Any ON or USING clauses associated with the join are
-
** also attached to the left entry.
+
** also attached to the right entry.
**
** This routine returns the number of errors encountered.
*/
-
static int sqliteProcessJoin(Parse *pParse, Select *p){
+
static int sqlite3ProcessJoin(Parse *pParse, Select *p){
  SrcList *pSrc;                  /* All tables in the FROM clause */
  int i, j;                       /* Loop counters */
  SrcItem *pLeft;                 /* Left table being joined */
@@ -134729,49 +136018,41 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
  pRight = &pLeft[1];
  for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){
    Table *pRightTab = pRight->pTab;
-
    int isOuter;
+
    u32 joinType;

    if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue;
-
    isOuter = (pRight->fg.jointype & JT_OUTER)!=0;
+
    joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON;

-
    /* When the NATURAL keyword is present, add WHERE clause terms for
-
    ** every column that the two tables have in common.
+
    /* If this is a NATURAL join, synthesize an approprate USING clause
+
    ** to specify which columns should be joined.
    */
    if( pRight->fg.jointype & JT_NATURAL ){
-
      if( pRight->pOn || pRight->pUsing ){
+
      IdList *pUsing = 0;
+
      if( pRight->fg.isUsing || pRight->u3.pOn ){
        sqlite3ErrorMsg(pParse, "a NATURAL join may not have "
           "an ON or USING clause", 0);
        return 1;
      }
      for(j=0; j<pRightTab->nCol; j++){
        char *zName;   /* Name of column in the right table */
-
        int iLeft;     /* Matching left table */
-
        int iLeftCol;  /* Matching column in the left table */

        if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue;
        zName = pRightTab->aCol[j].zCnName;
-
        if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){
-
          addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j,
-
                isOuter, &p->pWhere);
+
        if( tableAndColumnIndex(pSrc, 0, i, zName, 0, 0, 1) ){
+
          pUsing = sqlite3IdListAppend(pParse, pUsing, 0);
+
          if( pUsing ){
+
            assert( pUsing->nId>0 );
+
            assert( pUsing->a[pUsing->nId-1].zName==0 );
+
            pUsing->a[pUsing->nId-1].zName = sqlite3DbStrDup(pParse->db, zName);
+
          }
        }
      }
-
    }
-

-
    /* Disallow both ON and USING clauses in the same join
-
    */
-
    if( pRight->pOn && pRight->pUsing ){
-
      sqlite3ErrorMsg(pParse, "cannot have both ON and USING "
-
        "clauses in the same join");
-
      return 1;
-
    }
-

-
    /* Add the ON clause to the end of the WHERE clause, connected by
-
    ** an AND operator.
-
    */
-
    if( pRight->pOn ){
-
      if( isOuter ) sqlite3SetJoinExpr(pRight->pOn, pRight->iCursor);
-
      p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn);
-
      pRight->pOn = 0;
+
      if( pUsing ){
+
        pRight->fg.isUsing = 1;
+
        pRight->fg.isSynthUsing = 1;
+
        pRight->u3.pUsing = pUsing;
+
      }
+
      if( pParse->nErr ) return 1;
    }

    /* Create extra terms on the WHERE clause for each column named
@@ -134781,27 +136062,88 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
    ** Report an error if any column mentioned in the USING clause is
    ** not contained in both tables to be joined.
    */
-
    if( pRight->pUsing ){
-
      IdList *pList = pRight->pUsing;
+
    if( pRight->fg.isUsing ){
+
      IdList *pList = pRight->u3.pUsing;
+
      sqlite3 *db = pParse->db;
+
      assert( pList!=0 );
      for(j=0; j<pList->nId; j++){
        char *zName;     /* Name of the term in the USING clause */
        int iLeft;       /* Table on the left with matching column name */
        int iLeftCol;    /* Column number of matching column on the left */
        int iRightCol;   /* Column number of matching column on the right */
+
        Expr *pE1;       /* Reference to the column on the LEFT of the join */
+
        Expr *pE2;       /* Reference to the column on the RIGHT of the join */
+
        Expr *pEq;       /* Equality constraint.  pE1 == pE2 */

        zName = pList->a[j].zName;
        iRightCol = sqlite3ColumnIndex(pRightTab, zName);
        if( iRightCol<0
-
         || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0)
+
         || tableAndColumnIndex(pSrc, 0, i, zName, &iLeft, &iLeftCol,
+
                                pRight->fg.isSynthUsing)==0
        ){
          sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
            "not present in both tables", zName);
          return 1;
        }
-
        addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol,
-
                     isOuter, &p->pWhere);
+
        pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol);
+
        sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol);
+
        if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
+
          /* This branch runs if the query contains one or more RIGHT or FULL
+
          ** JOINs.  If only a single table on the left side of this join
+
          ** contains the zName column, then this branch is a no-op.
+
          ** But if there are two or more tables on the left side
+
          ** of the join, construct a coalesce() function that gathers all
+
          ** such tables.  Raise an error if more than one of those references
+
          ** to zName is not also within a prior USING clause.
+
          **
+
          ** We really ought to raise an error if there are two or more
+
          ** non-USING references to zName on the left of an INNER or LEFT
+
          ** JOIN.  But older versions of SQLite do not do that, so we avoid
+
          ** adding a new error so as to not break legacy applications.
+
          */
+
          ExprList *pFuncArgs = 0;   /* Arguments to the coalesce() */
+
          static const Token tkCoalesce = { "coalesce", 8 };
+
          while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol,
+
                                     pRight->fg.isSynthUsing)!=0 ){
+
            if( pSrc->a[iLeft].fg.isUsing==0
+
             || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0
+
            ){
+
              sqlite3ErrorMsg(pParse, "ambiguous reference to %s in USING()",
+
                              zName);
+
              break;
+
            }
+
            pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1);
+
            pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol);
+
            sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol);
+
          }
+
          if( pFuncArgs ){
+
            pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1);
+
            pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0);
+
          }
+
        }
+
        pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol);
+
        sqlite3SrcItemColumnUsed(pRight, iRightCol);
+
        pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
+
        assert( pE2!=0 || pEq==0 );
+
        if( pEq ){
+
          ExprSetProperty(pEq, joinType);
+
          assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
+
          ExprSetVVAProperty(pEq, EP_NoReduce);
+
          pEq->w.iJoin = pE2->iTable;
+
        }
+
        p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pEq);
      }
    }
+

+
    /* Add the ON clause to the end of the WHERE clause, connected by
+
    ** an AND operator.
+
    */
+
    else if( pRight->u3.pOn ){
+
      sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType);
+
      p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn);
+
      pRight->u3.pOn = 0;
+
      pRight->fg.isOn = 1;
+
    }
  }
  return 0;
}
@@ -135190,7 +136532,7 @@ static void fixDistinctOpenEph(
** retrieved directly from table t1. If the values are very large, this
** can be more efficient than storing them directly in the sorter records.
**
-
** The ExprList_item.bSorterRef flag is set for each expression in pEList
+
** The ExprList_item.fg.bSorterRef flag is set for each expression in pEList
** for which the sorter-reference optimization should be enabled.
** Additionally, the pSort->aDefer[] array is populated with entries
** for all cursors required to evaluate all selected expressions. Finally.
@@ -135250,7 +136592,7 @@ static void selectExprDefer(
            nDefer++;
          }
        }
-
        pItem->bSorterRef = 1;
+
        pItem->fg.bSorterRef = 1;
      }
    }
  }
@@ -135381,7 +136723,7 @@ static void selectInnerLoop(
      for(i=0; i<pEList->nExpr; i++){
        if( pEList->a[i].u.x.iOrderByCol>0
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
-
         || pEList->a[i].bSorterRef
+
         || pEList->a[i].fg.bSorterRef
#endif
        ){
          nResultCol--;
@@ -135743,7 +137085,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(
    assert( sqlite3KeyInfoIsWriteable(pInfo) );
    for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
      pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr);
-
      pInfo->aSortFlags[i-iStart] = pItem->sortFlags;
+
      pInfo->aSortFlags[i-iStart] = pItem->fg.sortFlags;
    }
  }
  return pInfo;
@@ -135882,7 +137224,7 @@ static void generateSortTail(
  }
  for(i=0, iCol=nKey+bSeq-1; i<nColumn; i++){
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
-
    if( aOutEx[i].bSorterRef ) continue;
+
    if( aOutEx[i].fg.bSorterRef ) continue;
#endif
    if( aOutEx[i].u.x.iOrderByCol==0 ) iCol++;
  }
@@ -135919,7 +137261,7 @@ static void generateSortTail(
#endif
  for(i=nColumn-1; i>=0; i--){
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
-
    if( aOutEx[i].bSorterRef ){
+
    if( aOutEx[i].fg.bSorterRef ){
      sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i);
    }else
#endif
@@ -136285,7 +137627,7 @@ SQLITE_PRIVATE void sqlite3GenerateColumnNames(
    assert( p->op!=TK_AGG_COLUMN );  /* Agg processing has not run yet */
    assert( p->op!=TK_COLUMN
        || (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */
-
    if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){
+
    if( pEList->a[i].zEName && pEList->a[i].fg.eEName==ENAME_NAME ){
      /* An AS clause always takes first priority */
      char *zName = pEList->a[i].zEName;
      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
@@ -136370,22 +137712,25 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
  *paCol = aCol;

  for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
+
    struct ExprList_item *pX = &pEList->a[i];
+
    struct ExprList_item *pCollide;
    /* Get an appropriate name for the column
    */
-
    if( (zName = pEList->a[i].zEName)!=0 && pEList->a[i].eEName==ENAME_NAME ){
+
    if( (zName = pX->zEName)!=0 && pX->fg.eEName==ENAME_NAME ){
      /* If the column contains an "AS <name>" phrase, use <name> as the name */
    }else{
-
      Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr);
+
      Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pX->pExpr);
      while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){
        pColExpr = pColExpr->pRight;
        assert( pColExpr!=0 );
      }
      if( pColExpr->op==TK_COLUMN
       && ALWAYS( ExprUseYTab(pColExpr) )
-
       && (pTab = pColExpr->y.pTab)!=0
+
       && ALWAYS( pColExpr->y.pTab!=0 )
      ){
        /* For columns use the column name name */
        int iCol = pColExpr->iColumn;
+
        pTab = pColExpr->y.pTab;
        if( iCol<0 ) iCol = pTab->iPKey;
        zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid";
      }else if( pColExpr->op==TK_ID ){
@@ -136393,7 +137738,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
        zName = pColExpr->u.zToken;
      }else{
        /* Use the original text of the column expression as its name */
-
        zName = pEList->a[i].zEName;
+
        assert( zName==pX->zEName );  /* pointer comparison intended */
      }
    }
    if( zName && !sqlite3IsTrueOrFalse(zName) ){
@@ -136406,7 +137751,10 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
    ** append an integer to the name so that it becomes unique.
    */
    cnt = 0;
-
    while( zName && sqlite3HashFind(&ht, zName)!=0 ){
+
    while( zName && (pCollide = sqlite3HashFind(&ht, zName))!=0 ){
+
      if( pCollide->fg.bUsingTerm ){
+
        pCol->colFlags |= COLFLAG_NOEXPAND;
+
      }
      nName = sqlite3Strlen30(zName);
      if( nName>0 ){
        for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){}
@@ -136417,8 +137765,11 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
    }
    pCol->zCnName = zName;
    pCol->hName = sqlite3StrIHash(zName);
+
    if( pX->fg.bNoExpand ){
+
      pCol->colFlags |= COLFLAG_NOEXPAND;
+
    }
    sqlite3ColumnPropertiesFromName(0, pCol);
-
    if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){
+
    if( zName && sqlite3HashInsert(&ht, zName, pX)==pX ){
      sqlite3OomFault(db);
    }
  }
@@ -136675,7 +138026,7 @@ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
      }
      assert( sqlite3KeyInfoIsWriteable(pRet) );
      pRet->aColl[i] = pColl;
-
      pRet->aSortFlags[i] = pOrderBy->a[i].sortFlags;
+
      pRet->aSortFlags[i] = pOrderBy->a[i].fg.sortFlags;
    }
  }

@@ -136893,7 +138244,7 @@ static int multiSelectOrderBy(
** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
-
** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
+
** Since the limit is exactly 1, we only need to evaluate the left-most VALUES.
*/
static int multiSelectValues(
  Parse *pParse,        /* Parsing context */
@@ -137886,12 +139237,40 @@ static int multiSelectOrderBy(
**
** All references to columns in table iTable are to be replaced by corresponding
** expressions in pEList.
+
**
+
** ## About "isOuterJoin":
+
**
+
** The isOuterJoin column indicates that the replacement will occur into a
+
** position in the parent that NULL-able due to an OUTER JOIN.  Either the
+
** target slot in the parent is the right operand of a LEFT JOIN, or one of
+
** the left operands of a RIGHT JOIN.  In either case, we need to potentially
+
** bypass the substituted expression with OP_IfNullRow.
+
**
+
** Suppose the original expression integer constant.  Even though the table
+
** has the nullRow flag set, because the expression is an integer constant,
+
** it will not be NULLed out.  So instead, we insert an OP_IfNullRow opcode
+
** that checks to see if the nullRow flag is set on the table.  If the nullRow
+
** flag is set, then the value in the register is set to NULL and the original
+
** expression is bypassed.  If the nullRow flag is not set, then the original
+
** expression runs to populate the register.
+
**
+
** Example where this is needed:
+
**
+
**      CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT);
+
**      CREATE TABLE t2(x INT UNIQUE);
+
**
+
**      SELECT a,b,m,x FROM t1 LEFT JOIN (SELECT 59 AS m,x FROM t2) ON b=x;
+
**
+
** When the subquery on the right side of the LEFT JOIN is flattened, we
+
** have to add OP_IfNullRow in front of the OP_Integer that implements the
+
** "m" value of the subquery so that a NULL will be loaded instead of 59
+
** when processing a non-matched row of the left.
*/
typedef struct SubstContext {
  Parse *pParse;            /* The parsing context */
  int iTable;               /* Replace references to this table */
  int iNewTable;            /* New table number */
-
  int isLeftJoin;           /* Add TK_IF_NULL_ROW opcodes on each replacement */
+
  int isOuterJoin;          /* Add TK_IF_NULL_ROW opcodes on each replacement */
  ExprList *pEList;         /* Replacement expressions */
} SubstContext;

@@ -137917,10 +139296,11 @@ static Expr *substExpr(
  Expr *pExpr            /* Expr in which substitution occurs */
){
  if( pExpr==0 ) return 0;
-
  if( ExprHasProperty(pExpr, EP_FromJoin)
-
   && pExpr->w.iRightJoinTable==pSubst->iTable
+
  if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON)
+
   && pExpr->w.iJoin==pSubst->iTable
  ){
-
    pExpr->w.iRightJoinTable = pSubst->iNewTable;
+
    testcase( ExprHasProperty(pExpr, EP_InnerON) );
+
    pExpr->w.iJoin = pSubst->iNewTable;
  }
  if( pExpr->op==TK_COLUMN
   && pExpr->iTable==pSubst->iTable
@@ -137941,7 +139321,7 @@ static Expr *substExpr(
        sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
      }else{
        sqlite3 *db = pSubst->pParse->db;
-
        if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){
+
        if( pSubst->isOuterJoin && pCopy->op!=TK_COLUMN ){
          memset(&ifNullRow, 0, sizeof(ifNullRow));
          ifNullRow.op = TK_IF_NULL_ROW;
          ifNullRow.pLeft = pCopy;
@@ -137955,14 +139335,20 @@ static Expr *substExpr(
          sqlite3ExprDelete(db, pNew);
          return pExpr;
        }
-
        if( pSubst->isLeftJoin ){
+
        if( pSubst->isOuterJoin ){
          ExprSetProperty(pNew, EP_CanBeNull);
        }
-
        if( ExprHasProperty(pExpr,EP_FromJoin) ){
-
          sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable);
+
        if( ExprHasProperty(pExpr,EP_OuterON|EP_InnerON) ){
+
          sqlite3SetJoinExpr(pNew, pExpr->w.iJoin,
+
                             pExpr->flags & (EP_OuterON|EP_InnerON));
        }
        sqlite3ExprDelete(db, pExpr);
        pExpr = pNew;
+
        if( pExpr->op==TK_TRUEFALSE ){
+
          pExpr->u.iValue = sqlite3ExprTruthValue(pExpr);
+
          pExpr->op = TK_INTEGER;
+
          ExprSetProperty(pExpr, EP_IntValue);
+
        }

        /* Ensure that the expression now has an implicit collation sequence,
        ** just as it did when it was a column of a view or sub-query. */
@@ -138123,8 +139509,8 @@ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){
  if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){
    renumberCursorDoMapping(pWalker, &pExpr->iTable);
  }
-
  if( ExprHasProperty(pExpr, EP_FromJoin) ){
-
    renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable);
+
  if( ExprHasProperty(pExpr, EP_OuterON) ){
+
    renumberCursorDoMapping(pWalker, &pExpr->w.iJoin);
  }
  return WRC_Continue;
}
@@ -138209,6 +139595,7 @@ static void renumberCursors(
**             table and
**        (3c) the outer query may not be an aggregate.
**        (3d) the outer query may not be DISTINCT.
+
**        See also (26) for restrictions on RIGHT JOIN.
**
**   (4)  The subquery can not be DISTINCT.
**
@@ -138260,6 +139647,9 @@ static void renumberCursors(
**              (17d2) DISTINCT
**        (17e) the subquery may not contain window functions, and
**        (17f) the subquery must not be the RHS of a LEFT JOIN.
+
**        (17g) either the subquery is the first element of the outer
+
**              query or there are no RIGHT or FULL JOINs in any arm
+
**              of the subquery.  (This is a duplicate of condition (27b).)
**
**        The parent and sub-query may contain WHERE clauses. Subject to
**        rules (11), (13) and (14), they may also contain ORDER BY,
@@ -138307,6 +139697,23 @@ static void renumberCursors(
**        function in the select list or ORDER BY clause, flattening
**        is not attempted.
**
+
**  (26)  The subquery may not be the right operand of a RIGHT JOIN.
+
**        See also (3) for restrictions on LEFT JOIN.
+
**
+
**  (27)  The subquery may not contain a FULL or RIGHT JOIN unless it
+
**        is the first element of the parent query.  This must be the
+
**        the case if:
+
**        (27a) the subquery is not compound query, and
+
**        (27b) the subquery is a compound query and the RIGHT JOIN occurs
+
**              in any arm of the compound query.  (See also (17g).)
+
**
+
**  (28)  The subquery is not a MATERIALIZED CTE.
+
**
+
**  (29)  Either the subquery is not the right-hand operand of a join with an
+
**        ON or USING clause nor the right-hand operand of a NATURAL JOIN, or
+
**        the right-most table within the FROM clause of the subquery
+
**        is not part of an outer join.
+
**
**
** In this routine, the "p" parameter is a pointer to the outer query.
** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
@@ -138332,7 +139739,7 @@ static int flattenSubquery(
  SrcList *pSubSrc;   /* The FROM clause of the subquery */
  int iParent;        /* VDBE cursor number of the pSub result set temp table */
  int iNewParent = -1;/* Replacement table for iParent */
-
  int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
+
  int isOuterJoin = 0; /* True if pSub is the right side of a LEFT JOIN */
  int i;              /* Loop counter */
  Expr *pWhere;                    /* The WHERE clause */
  SrcItem *pSubitem;               /* The subquery */
@@ -138405,26 +139812,64 @@ static int flattenSubquery(
  **
  ** See also tickets #306, #350, and #3300.
  */
-
  if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
-
    isLeftJoin = 1;
-
    if( pSubSrc->nSrc>1                   /* (3a) */
-
     || isAgg                             /* (3b) */
-
     || IsVirtual(pSubSrc->a[0].pTab)     /* (3c) */
-
     || (p->selFlags & SF_Distinct)!=0    /* (3d) */
+
  if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){
+
    if( pSubSrc->nSrc>1                        /* (3a) */
+
     || isAgg                                  /* (3c) */
+
     || IsVirtual(pSubSrc->a[0].pTab)          /* (3b) */
+
     || (p->selFlags & SF_Distinct)!=0         /* (3d) */
+
     || (pSubitem->fg.jointype & JT_RIGHT)!=0  /* (26) */
    ){
      return 0;
    }
+
    isOuterJoin = 1;
  }
#ifdef SQLITE_EXTRA_IFNULLROW
  else if( iFrom>0 && !isAgg ){
-
    /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for
+
    /* Setting isOuterJoin to -1 causes OP_IfNullRow opcodes to be generated for
    ** every reference to any result column from subquery in a join, even
    ** though they are not necessary.  This will stress-test the OP_IfNullRow
    ** opcode. */
-
    isLeftJoin = -1;
+
    isOuterJoin = -1;
  }
#endif

+
  assert( pSubSrc->nSrc>0 );  /* True by restriction (7) */
+
  if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
+
    return 0;   /* Restriction (27a) */
+
  }
+
  if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){
+
    return 0;       /* (28) */
+
  }
+

+
  /* Restriction (29):
+
  **
+
  ** We do not want two constraints on the same term of the flattened
+
  ** query where one constraint has EP_InnerON and the other is EP_OuterON.
+
  ** To prevent this, one or the other of the following conditions must be
+
  ** false:
+
  **
+
  **   (29a)  The right-most entry in the FROM clause of the subquery
+
  **          must not be part of an outer join.
+
  **
+
  **   (29b)  The subquery itself must not be the right operand of a
+
  **          NATURAL join or a join that as an ON or USING clause.
+
  **
+
  ** These conditions are sufficient to keep an EP_OuterON from being
+
  ** flattened into an EP_InnerON.  Restrictions (3a) and (27a) prevent
+
  ** an EP_InnerON from being flattened into an EP_OuterON.
+
  */
+
  if( pSubSrc->nSrc>=2
+
   && (pSubSrc->a[pSubSrc->nSrc-1].fg.jointype & JT_OUTER)!=0
+
  ){
+
    if( (pSubitem->fg.jointype & JT_NATURAL)!=0
+
     || pSubitem->fg.isUsing
+
     || NEVER(pSubitem->u3.pOn!=0) /* ON clause already shifted into WHERE */
+
     || pSubitem->fg.isOn
+
    ){
+
      return 0;
+
    }
+
  }
+

  /* Restriction (17): If the sub-query is a compound SELECT, then it must
  ** use only the UNION ALL operator. And none of the simple select queries
  ** that make up the compound SELECT are allowed to be aggregate or distinct
@@ -138434,7 +139879,7 @@ static int flattenSubquery(
    if( pSub->pOrderBy ){
      return 0;  /* Restriction (20) */
    }
-
    if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){
+
    if( isAgg || (p->selFlags & SF_Distinct)!=0 || isOuterJoin>0 ){
      return 0; /* (17d1), (17d2), or (17f) */
    }
    for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
@@ -138452,6 +139897,12 @@ static int flattenSubquery(
      ){
        return 0;
      }
+
      if( iFrom>0 && (pSub1->pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
+
        /* Without this restriction, the JT_LTORJ flag would end up being
+
        ** omitted on left-hand tables of the right join that is being
+
        ** flattened. */
+
        return 0;   /* Restrictions (17g), (27b) */
+
      }
      testcase( pSub1->pSrc->nSrc>1 );
    }

@@ -138468,6 +139919,7 @@ static int flattenSubquery(

    if( pSrc->nSrc>1 ){
      if( pParse->nSelect>500 ) return 0;
+
      if( OptimizationDisabled(db, SQLITE_FlttnUnionAll) ) return 0;
      aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int));
      if( aCsrMap ) aCsrMap[0] = pParse->nTab;
    }
@@ -138492,7 +139944,7 @@ static int flattenSubquery(
  pSubitem->zName = 0;
  pSubitem->zAlias = 0;
  pSubitem->pSelect = 0;
-
  assert( pSubitem->pOn==0 );
+
  assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 );

  /* If the sub-query is a compound SELECT statement, then (by restrictions
  ** 17 and 18 above) it must be a UNION ALL and the parent query must
@@ -138602,6 +140054,7 @@ static int flattenSubquery(
  for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
    int nSubSrc;
    u8 jointype = 0;
+
    u8 ltorj = pSrc->a[iFrom].fg.jointype & JT_LTORJ;
    assert( pSub!=0 );
    pSubSrc = pSub->pSrc;     /* FROM clause of subquery */
    nSubSrc = pSubSrc->nSrc;  /* Number of terms in subquery FROM clause */
@@ -138636,13 +140089,16 @@ static int flattenSubquery(
    ** outer query.
    */
    for(i=0; i<nSubSrc; i++){
-
      sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
-
      assert( pSrc->a[i+iFrom].fg.isTabFunc==0 );
-
      pSrc->a[i+iFrom] = pSubSrc->a[i];
+
      SrcItem *pItem = &pSrc->a[i+iFrom];
+
      if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing);
+
      assert( pItem->fg.isTabFunc==0 );
+
      *pItem = pSubSrc->a[i];
+
      pItem->fg.jointype |= ltorj;
      iNewParent = pSubSrc->a[i].iCursor;
      memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
    }
-
    pSrc->a[iFrom].fg.jointype = jointype;
+
    pSrc->a[iFrom].fg.jointype &= JT_LTORJ;
+
    pSrc->a[iFrom].fg.jointype |= jointype | ltorj;

    /* Now begin substituting subquery result set expressions for
    ** references to the iParent in the outer query.
@@ -138677,8 +140133,8 @@ static int flattenSubquery(
    }
    pWhere = pSub->pWhere;
    pSub->pWhere = 0;
-
    if( isLeftJoin>0 ){
-
      sqlite3SetJoinExpr(pWhere, iNewParent);
+
    if( isOuterJoin>0 ){
+
      sqlite3SetJoinExpr(pWhere, iNewParent, EP_OuterON);
    }
    if( pWhere ){
      if( pParent->pWhere ){
@@ -138692,7 +140148,7 @@ static int flattenSubquery(
      x.pParse = pParse;
      x.iTable = iParent;
      x.iNewTable = iNewParent;
-
      x.isLeftJoin = isLeftJoin;
+
      x.isOuterJoin = isOuterJoin;
      x.pEList = pSub->pEList;
      substSelect(&x, pParent, 0);
    }
@@ -138727,8 +140183,8 @@ static int flattenSubquery(
  sqlite3WalkSelect(&w,pSub1);
  sqlite3SelectDelete(db, pSub1);

-
#if SELECTTRACE_ENABLED
-
  if( sqlite3SelectTrace & 0x100 ){
+
#if TREETRACE_ENABLED
+
  if( sqlite3TreeTrace & 0x100 ){
    SELECTTRACE(0x100,pParse,p,("After flattening:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
@@ -138749,6 +140205,8 @@ struct WhereConst {
  int nConst;      /* Number for COLUMN=CONSTANT terms */
  int nChng;       /* Number of times a constant is propagated */
  int bHasAffBlob; /* At least one column in apExpr[] as affinity BLOB */
+
  u32 mExcludeOn;  /* Which ON expressions to exclude from considertion.
+
                   ** Either EP_OuterON or EP_InnerON|EP_OuterON */
  Expr **apExpr;   /* [i*2] is COLUMN and [i*2+1] is VALUE */
};

@@ -138811,7 +140269,11 @@ static void constInsert(
static void findConstInWhere(WhereConst *pConst, Expr *pExpr){
  Expr *pRight, *pLeft;
  if( NEVER(pExpr==0) ) return;
-
  if( ExprHasProperty(pExpr, EP_FromJoin) ) return;
+
  if( ExprHasProperty(pExpr, pConst->mExcludeOn) ){
+
    testcase( ExprHasProperty(pExpr, EP_OuterON) );
+
    testcase( ExprHasProperty(pExpr, EP_InnerON) );
+
    return;
+
  }
  if( pExpr->op==TK_AND ){
    findConstInWhere(pConst, pExpr->pRight);
    findConstInWhere(pConst, pExpr->pLeft);
@@ -138847,9 +140309,10 @@ static int propagateConstantExprRewriteOne(
  int i;
  if( pConst->pOomFault[0] ) return WRC_Prune;
  if( pExpr->op!=TK_COLUMN ) return WRC_Continue;
-
  if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ){
+
  if( ExprHasProperty(pExpr, EP_FixedCol|pConst->mExcludeOn) ){
    testcase( ExprHasProperty(pExpr, EP_FixedCol) );
-
    testcase( ExprHasProperty(pExpr, EP_FromJoin) );
+
    testcase( ExprHasProperty(pExpr, EP_OuterON) );
+
    testcase( ExprHasProperty(pExpr, EP_InnerON) );
    return WRC_Continue;
  }
  for(i=0; i<pConst->nConst; i++){
@@ -138973,6 +140436,17 @@ static int propagateConstants(
    x.nChng = 0;
    x.apExpr = 0;
    x.bHasAffBlob = 0;
+
    if( ALWAYS(p->pSrc!=0)
+
     && p->pSrc->nSrc>0
+
     && (p->pSrc->a[0].fg.jointype & JT_LTORJ)!=0
+
    ){
+
      /* Do not propagate constants on any ON clause if there is a
+
      ** RIGHT JOIN anywhere in the query */
+
      x.mExcludeOn = EP_InnerON | EP_OuterON;
+
    }else{
+
      /* Do not propagate constants through the ON clause of a LEFT JOIN */
+
      x.mExcludeOn = EP_OuterON;
+
    }
    findConstInWhere(&x, p->pWhere);
    if( x.nConst ){
      memset(&w, 0, sizeof(w));
@@ -139098,6 +140572,7 @@ static int pushDownWhereTerms(
  int nChng = 0;
  if( pWhere==0 ) return 0;
  if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0;
+
  if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ) return 0;

#ifndef SQLITE_OMIT_WINDOWFUNC
  if( pSubq->pPrior ){
@@ -139133,13 +140608,13 @@ static int pushDownWhereTerms(

#if 0  /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */
  if( isLeftJoin
-
   && (ExprHasProperty(pWhere,EP_FromJoin)==0
-
         || pWhere->w.iRightJoinTable!=iCursor)
+
   && (ExprHasProperty(pWhere,EP_OuterON)==0
+
         || pWhere->w.iJoin!=iCursor)
  ){
    return 0; /* restriction (4) */
  }
-
  if( ExprHasProperty(pWhere,EP_FromJoin)
-
   && pWhere->w.iRightJoinTable!=iCursor
+
  if( ExprHasProperty(pWhere,EP_OuterON)
+
   && pWhere->w.iJoin!=iCursor
  ){
    return 0; /* restriction (5) */
  }
@@ -139151,11 +140626,11 @@ static int pushDownWhereTerms(
    while( pSubq ){
      SubstContext x;
      pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
-
      unsetJoinExpr(pNew, -1);
+
      unsetJoinExpr(pNew, -1, 1);
      x.pParse = pParse;
      x.iTable = pSrc->iCursor;
      x.iNewTable = pSrc->iCursor;
-
      x.isLeftJoin = 0;
+
      x.isOuterJoin = 0;
      x.pEList = pSubq->pEList;
      pNew = substExpr(&x, pNew);
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -139228,7 +140703,7 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
  }
  *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0);
  assert( pOrderBy!=0 || db->mallocFailed );
-
  if( pOrderBy ) pOrderBy->a[0].sortFlags = sortFlags;
+
  if( pOrderBy ) pOrderBy->a[0].fg.sortFlags = sortFlags;
  return eRet;
}

@@ -139364,7 +140839,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
  pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
  if( pNew==0 ) return WRC_Abort;
  memset(&dummy, 0, sizeof(dummy));
-
  pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0);
+
  pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0);
  if( pNewSrc==0 ) return WRC_Abort;
  *pNew = *p;
  p->pSrc = pNewSrc;
@@ -139697,7 +141172,7 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){
  if( pFrom->zAlias ){
    pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias);
  }else{
-
    pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId);
+
    pTab->zName = sqlite3MPrintf(pParse->db, "%!S", pFrom);
  }
  while( pSel->pPrior ){ pSel = pSel->pPrior; }
  sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol);
@@ -139709,11 +141184,35 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){
#else
  pTab->tabFlags |= TF_Ephemeral;  /* Legacy compatibility mode */
#endif
+
  return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
+
}


-
  return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
+
/*
+
** Check the N SrcItem objects to the right of pBase.  (N might be zero!)
+
** If any of those SrcItem objects have a USING clause containing zName
+
** then return true.
+
**
+
** If N is zero, or none of the N SrcItem objects to the right of pBase
+
** contains a USING clause, or if none of the USING clauses contain zName,
+
** then return false.
+
*/
+
static int inAnyUsingClause(
+
  const char *zName, /* Name we are looking for */
+
  SrcItem *pBase,    /* The base SrcItem.  Looking at pBase[1] and following */
+
  int N              /* How many SrcItems to check */
+
){
+
  while( N>0 ){
+
    N--;
+
    pBase++;
+
    if( pBase->fg.isUsing==0 ) continue;
+
    if( NEVER(pBase->u3.pUsing==0) ) continue;
+
    if( sqlite3IdListIndex(pBase->u3.pUsing, zName)>=0 ) return 1;
+
  }
+
  return 0;
}

+

/*
** This routine is a Walker callback for "expanding" a SELECT statement.
** "Expanding" means to do the following:
@@ -139863,7 +141362,7 @@ static int selectExpander(Walker *pWalker, Select *p){
  /* Process NATURAL keywords, and ON and USING clauses of joins.
  */
  assert( db->mallocFailed==0 || pParse->nErr!=0 );
-
  if( pParse->nErr || sqliteProcessJoin(pParse, p) ){
+
  if( pParse->nErr || sqlite3ProcessJoin(pParse, p) ){
    return WRC_Abort;
  }

@@ -139911,7 +141410,7 @@ static int selectExpander(Walker *pWalker, Select *p){
        pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr);
        if( pNew ){
          pNew->a[pNew->nExpr-1].zEName = a[k].zEName;
-
          pNew->a[pNew->nExpr-1].eEName = a[k].eEName;
+
          pNew->a[pNew->nExpr-1].fg.eEName = a[k].fg.eEName;
          a[k].zEName = 0;
        }
        a[k].pExpr = 0;
@@ -139926,32 +141425,60 @@ static int selectExpander(Walker *pWalker, Select *p){
          zTName = pE->pLeft->u.zToken;
        }
        for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
-
          Table *pTab = pFrom->pTab;
-
          Select *pSub = pFrom->pSelect;
-
          char *zTabName = pFrom->zAlias;
-
          const char *zSchemaName = 0;
-
          int iDb;
-
          if( zTabName==0 ){
+
          Table *pTab = pFrom->pTab;   /* Table for this data source */
+
          ExprList *pNestedFrom;       /* Result-set of a nested FROM clause */
+
          char *zTabName;              /* AS name for this data source */
+
          const char *zSchemaName = 0; /* Schema name for this data source */
+
          int iDb;                     /* Schema index for this data src */
+
          IdList *pUsing;              /* USING clause for pFrom[1] */
+

+
          if( (zTabName = pFrom->zAlias)==0 ){
            zTabName = pTab->zName;
          }
          if( db->mallocFailed ) break;
-
          if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){
-
            pSub = 0;
+
          assert( (int)pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) );
+
          if( pFrom->fg.isNestedFrom ){
+
            assert( pFrom->pSelect!=0 );
+
            pNestedFrom = pFrom->pSelect->pEList;
+
            assert( pNestedFrom!=0 );
+
            assert( pNestedFrom->nExpr==pTab->nCol );
+
          }else{
            if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
              continue;
            }
+
            pNestedFrom = 0;
            iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
            zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*";
          }
+
          if( i+1<pTabList->nSrc
+
           && pFrom[1].fg.isUsing
+
           && (selFlags & SF_NestedFrom)!=0
+
          ){
+
            int ii;
+
            pUsing = pFrom[1].u3.pUsing;
+
            for(ii=0; ii<pUsing->nId; ii++){
+
              const char *zUName = pUsing->a[ii].zName;
+
              pRight = sqlite3Expr(db, TK_ID, zUName);
+
              pNew = sqlite3ExprListAppend(pParse, pNew, pRight);
+
              if( pNew ){
+
                struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
+
                assert( pX->zEName==0 );
+
                pX->zEName = sqlite3MPrintf(db,"..%s", zUName);
+
                pX->fg.eEName = ENAME_TAB;
+
                pX->fg.bUsingTerm = 1;
+
              }
+
            }
+
          }else{
+
            pUsing = 0;
+
          }
          for(j=0; j<pTab->nCol; j++){
            char *zName = pTab->aCol[j].zCnName;
-
            char *zColname;  /* The computed column name */
-
            char *zToFree;   /* Malloced string that needs to be freed */
-
            Token sColname;  /* Computed column name as a token */
+
            struct ExprList_item *pX; /* Newly added ExprList term */

            assert( zName );
-
            if( zTName && pSub
-
             && sqlite3MatchEName(&pSub->pEList->a[j], 0, zTName, 0)==0
+
            if( zTName
+
             && pNestedFrom
+
             && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0)==0
            ){
              continue;
            }
@@ -139965,57 +141492,75 @@ static int selectExpander(Walker *pWalker, Select *p){
            ){
              continue;
            }
+
            if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0
+
             && zTName==0
+
             && (selFlags & (SF_NestedFrom))==0
+
            ){
+
              continue;
+
            }
            tableSeen = 1;

-
            if( i>0 && zTName==0 ){
-
              if( (pFrom->fg.jointype & JT_NATURAL)!=0
-
                && tableAndColumnIndex(pTabList, i, zName, 0, 0, 1)
+
            if( i>0 && zTName==0 && (selFlags & SF_NestedFrom)==0 ){
+
              if( pFrom->fg.isUsing
+
               && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0
              ){
-
                /* In a NATURAL join, omit the join columns from the
-
                ** table to the right of the join */
-
                continue;
-
              }
-
              if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){
                /* In a join with a USING clause, omit columns in the
                ** using clause from the table on the right. */
                continue;
              }
            }
            pRight = sqlite3Expr(db, TK_ID, zName);
-
            zColname = zName;
-
            zToFree = 0;
-
            if( longNames || pTabList->nSrc>1 ){
+
            if( (pTabList->nSrc>1
+
                 && (  (pFrom->fg.jointype & JT_LTORJ)==0
+
                     || (selFlags & SF_NestedFrom)!=0
+
                     || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1)
+
                    )
+
                )
+
             || IN_RENAME_OBJECT
+
            ){
              Expr *pLeft;
              pLeft = sqlite3Expr(db, TK_ID, zTabName);
              pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
+
              if( IN_RENAME_OBJECT && pE->pLeft ){
+
                sqlite3RenameTokenRemap(pParse, pLeft, pE->pLeft);
+
              }
              if( zSchemaName ){
                pLeft = sqlite3Expr(db, TK_ID, zSchemaName);
                pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr);
              }
-
              if( longNames ){
-
                zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
-
                zToFree = zColname;
-
              }
            }else{
              pExpr = pRight;
            }
            pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
-
            sqlite3TokenInit(&sColname, zColname);
-
            sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
-
            if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
-
              struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
-
              sqlite3DbFree(db, pX->zEName);
-
              if( pSub ){
-
                pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName);
+
            if( pNew==0 ){
+
              break;  /* OOM */
+
            }
+
            pX = &pNew->a[pNew->nExpr-1];
+
            assert( pX->zEName==0 );
+
            if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){
+
              if( pNestedFrom ){
+
                pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName);
                testcase( pX->zEName==0 );
              }else{
                pX->zEName = sqlite3MPrintf(db, "%s.%s.%s",
-
                                           zSchemaName, zTabName, zColname);
+
                                           zSchemaName, zTabName, zName);
                testcase( pX->zEName==0 );
              }
-
              pX->eEName = ENAME_TAB;
+
              pX->fg.eEName = ENAME_TAB;
+
              if( (pFrom->fg.isUsing
+
                   && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0)
+
               || (pUsing && sqlite3IdListIndex(pUsing, zName)>=0)
+
               || (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0
+
              ){
+
                pX->fg.bNoExpand = 1;
+
              }
+
            }else if( longNames ){
+
              pX->zEName = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
+
              pX->fg.eEName = ENAME_NAME;
+
            }else{
+
              pX->zEName = sqlite3DbStrDup(db, zName);
+
              pX->fg.eEName = ENAME_NAME;
            }
-
            sqlite3DbFree(db, zToFree);
          }
        }
        if( !tableSeen ){
@@ -140039,6 +141584,12 @@ static int selectExpander(Walker *pWalker, Select *p){
      p->selFlags |= SF_ComplexResult;
    }
  }
+
#if TREETRACE_ENABLED
+
  if( sqlite3TreeTrace & 0x100 ){
+
    SELECTTRACE(0x100,pParse,p,("After result-set wildcard expansion:\n"));
+
    sqlite3TreeViewSelect(0, p, 0);
+
  }
+
#endif
  return WRC_Continue;
}

@@ -140429,8 +141980,8 @@ static void havingToWhere(Parse *pParse, Select *p){
  sWalker.xExprCallback = havingToWhereExprCb;
  sWalker.u.pSelect = p;
  sqlite3WalkExpr(&sWalker, p->pHaving);
-
#if SELECTTRACE_ENABLED
-
  if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){
+
#if TREETRACE_ENABLED
+
  if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){
    SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
@@ -140562,8 +142113,8 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
  p->pEList->a[0].pExpr = pExpr;
  p->selFlags &= ~SF_Aggregate;

-
#if SELECTTRACE_ENABLED
-
  if( sqlite3SelectTrace & 0x400 ){
+
#if TREETRACE_ENABLED
+
  if( sqlite3TreeTrace & 0x400 ){
    SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
@@ -140573,6 +142124,29 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */

/*
+
** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same
+
** as pSrcItem but has the same alias as p0, then return true.
+
** Otherwise return false.
+
*/
+
static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
+
  int i;
+
  for(i=0; i<pSrc->nSrc; i++){
+
    SrcItem *p1 = &pSrc->a[i];
+
    if( p1==p0 ) continue;
+
    if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
+
      return 1;
+
    }
+
    if( p1->pSelect
+
     && (p1->pSelect->selFlags & SF_NestedFrom)!=0
+
     && sameSrcAlias(p0, p1->pSelect->pSrc)
+
    ){
+
      return 1;
+
    }
+
  }
+
  return 0;
+
}
+

+
/*
** Generate code for the SELECT statement given in the p argument.
**
** The results are returned according to the SelectDest structure.
@@ -140616,10 +142190,14 @@ SQLITE_PRIVATE int sqlite3Select(
  }
  assert( db->mallocFailed==0 );
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
-
#if SELECTTRACE_ENABLED
+
#if TREETRACE_ENABLED
  SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
-
  if( sqlite3SelectTrace & 0x100 ){
-
    sqlite3TreeViewSelect(0, p, 0);
+
  if( sqlite3TreeTrace & 0x10100 ){
+
    if( (sqlite3TreeTrace & 0x10001)==0x10000 ){
+
      sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d",
+
                           __FILE__, __LINE__);
+
    }
+
    sqlite3ShowSelect(p);
  }
#endif

@@ -140633,9 +142211,9 @@ SQLITE_PRIVATE int sqlite3Select(
           pDest->eDest==SRT_DistQueue  || pDest->eDest==SRT_DistFifo );
    /* All of these destinations are also able to ignore the ORDER BY clause */
    if( p->pOrderBy ){
-
#if SELECTTRACE_ENABLED
+
#if TREETRACE_ENABLED
      SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n"));
-
      if( sqlite3SelectTrace & 0x100 ){
+
      if( sqlite3TreeTrace & 0x100 ){
        sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY");
      }
#endif
@@ -140654,8 +142232,8 @@ SQLITE_PRIVATE int sqlite3Select(
  }
  assert( db->mallocFailed==0 );
  assert( p->pEList!=0 );
-
#if SELECTTRACE_ENABLED
-
  if( sqlite3SelectTrace & 0x104 ){
+
#if TREETRACE_ENABLED
+
  if( sqlite3TreeTrace & 0x104 ){
    SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
@@ -140672,15 +142250,12 @@ SQLITE_PRIVATE int sqlite3Select(
  ** disallow it altogether.  */
  if( p->selFlags & SF_UFSrcCheck ){
    SrcItem *p0 = &p->pSrc->a[0];
-
    for(i=1; i<p->pSrc->nSrc; i++){
-
      SrcItem *p1 = &p->pSrc->a[i];
-
      if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
-
        sqlite3ErrorMsg(pParse,
-
            "target object/alias may not appear in FROM clause: %s",
-
            p0->zAlias ? p0->zAlias : p0->pTab->zName
-
        );
-
        goto select_end;
-
      }
+
    if( sameSrcAlias(p0, p->pSrc) ){
+
      sqlite3ErrorMsg(pParse,
+
          "target object/alias may not appear in FROM clause: %s",
+
          p0->zAlias ? p0->zAlias : p0->pTab->zName
+
      );
+
      goto select_end;
    }

    /* Clear the SF_UFSrcCheck flag. The check has already been performed,
@@ -140699,8 +142274,8 @@ SQLITE_PRIVATE int sqlite3Select(
    assert( pParse->nErr );
    goto select_end;
  }
-
#if SELECTTRACE_ENABLED
-
  if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){
+
#if TREETRACE_ENABLED
+
  if( p->pWin && (sqlite3TreeTrace & 0x108)!=0 ){
    SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
@@ -140728,14 +142303,16 @@ SQLITE_PRIVATE int sqlite3Select(
    /* Convert LEFT JOIN into JOIN if there are terms of the right table
    ** of the LEFT JOIN used in the WHERE clause.
    */
-
    if( (pItem->fg.jointype & JT_LEFT)!=0
+
    if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==JT_LEFT
     && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
     && OptimizationEnabled(db, SQLITE_SimplifyJoin)
    ){
      SELECTTRACE(0x100,pParse,p,
                ("LEFT-JOIN simplifies to JOIN on term %d\n",i));
      pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
-
      unsetJoinExpr(p->pWhere, pItem->iCursor);
+
      assert( pItem->iCursor>=0 );
+
      unsetJoinExpr(p->pWhere, pItem->iCursor,
+
                    pTabList->a[0].fg.jointype & JT_LTORJ);
    }

    /* No futher action if this term of the FROM clause is no a subquery */
@@ -140788,7 +142365,9 @@ SQLITE_PRIVATE int sqlite3Select(
    ){
      SELECTTRACE(0x100,pParse,p,
                ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1));
-
      sqlite3ExprListDelete(db, pSub->pOrderBy);
+
      sqlite3ParserAddCleanup(pParse,
+
         (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
+
         pSub->pOrderBy);
      pSub->pOrderBy = 0;
    }

@@ -140814,7 +142393,7 @@ SQLITE_PRIVATE int sqlite3Select(
     && i==0
     && (p->selFlags & SF_ComplexResult)!=0
     && (pTabList->nSrc==1
-
         || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)
+
         || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0)
    ){
      continue;
    }
@@ -140838,9 +142417,9 @@ SQLITE_PRIVATE int sqlite3Select(
  */
  if( p->pPrior ){
    rc = multiSelect(pParse, p, pDest);
-
#if SELECTTRACE_ENABLED
+
#if TREETRACE_ENABLED
    SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
-
    if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
+
    if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
      sqlite3TreeViewSelect(0, p, 0);
    }
#endif
@@ -140859,8 +142438,8 @@ SQLITE_PRIVATE int sqlite3Select(
   && OptimizationEnabled(db, SQLITE_PropagateConst)
   && propagateConstants(pParse, p)
  ){
-
#if SELECTTRACE_ENABLED
-
    if( sqlite3SelectTrace & 0x100 ){
+
#if TREETRACE_ENABLED
+
    if( sqlite3TreeTrace & 0x100 ){
      SELECTTRACE(0x100,pParse,p,("After constant propagation:\n"));
      sqlite3TreeViewSelect(0, p, 0);
    }
@@ -140938,8 +142517,8 @@ SQLITE_PRIVATE int sqlite3Select(
         || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
     && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem)
    ){
-
#if SELECTTRACE_ENABLED
-
      if( sqlite3SelectTrace & 0x100 ){
+
#if TREETRACE_ENABLED
+
      if( sqlite3TreeTrace & 0x100 ){
        SELECTTRACE(0x100,pParse,p,
            ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
        sqlite3TreeViewSelect(0, p, 0);
@@ -140955,18 +142534,19 @@ SQLITE_PRIVATE int sqlite3Select(

    /* Generate code to implement the subquery
    **
-
    ** The subquery is implemented as a co-routine if:
+
    ** The subquery is implemented as a co-routine if all of the following are
+
    ** true:
+
    **
    **    (1)  the subquery is guaranteed to be the outer loop (so that
    **         it does not need to be computed more than once), and
    **    (2)  the subquery is not a CTE that should be materialized
-
    **
-
    ** TODO: Are there other reasons beside (1) and (2) to use a co-routine
-
    ** implementation?
+
    **    (3)  the subquery is not part of a left operand for a RIGHT JOIN
    */
    if( i==0
     && (pTabList->nSrc==1
-
            || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0)  /* (1) */
-
     && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes)  /* (2) */
+
            || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0)  /* (1) */
+
     && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes)   /* (2) */
+
     && (pTabList->a[0].fg.jointype & JT_LTORJ)==0                   /* (3) */
    ){
      /* Implement a co-routine that will return a single row of the result
      ** set on each invocation.
@@ -141012,11 +142592,11 @@ SQLITE_PRIVATE int sqlite3Select(
      ** the same view can reuse the materialization. */
      int topAddr;
      int onceAddr = 0;
-
      int retAddr;

      pItem->regReturn = ++pParse->nMem;
-
      topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
+
      topAddr = sqlite3VdbeAddOp0(v, OP_Goto);
      pItem->addrFillSub = topAddr+1;
+
      pItem->fg.isMaterialized = 1;
      if( pItem->fg.isCorrelated==0 ){
        /* If the subquery is not correlated and if we are not inside of
        ** a trigger, then we only need to compute the value of the subquery
@@ -141031,9 +142611,9 @@ SQLITE_PRIVATE int sqlite3Select(
      sqlite3Select(pParse, pSub, &dest);
      pItem->pTab->nRowLogEst = pSub->nSelectRow;
      if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
-
      retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
+
      sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1);
      VdbeComment((v, "end %!S", pItem));
-
      sqlite3VdbeChangeP1(v, topAddr, retAddr);
+
      sqlite3VdbeJumpHere(v, topAddr);
      sqlite3ClearTempRegCache(pParse);
      if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){
        CteUse *pCteUse = pItem->u2.pCteUse;
@@ -141057,8 +142637,8 @@ SQLITE_PRIVATE int sqlite3Select(
  pHaving = p->pHaving;
  sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;

-
#if SELECTTRACE_ENABLED
-
  if( sqlite3SelectTrace & 0x400 ){
+
#if TREETRACE_ENABLED
+
  if( sqlite3TreeTrace & 0x400 ){
    SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
@@ -141092,9 +142672,10 @@ SQLITE_PRIVATE int sqlite3Select(
    ** the sDistinct.isTnct is still set.  Hence, isTnct represents the
    ** original setting of the SF_Distinct flag, not the current setting */
    assert( sDistinct.isTnct );
+
    sDistinct.isTnct = 2;

-
#if SELECTTRACE_ENABLED
-
    if( sqlite3SelectTrace & 0x400 ){
+
#if TREETRACE_ENABLED
+
    if( sqlite3TreeTrace & 0x400 ){
      SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
      sqlite3TreeViewSelect(0, p, 0);
    }
@@ -141127,6 +142708,18 @@ SQLITE_PRIVATE int sqlite3Select(
  */
  if( pDest->eDest==SRT_EphemTab ){
    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
+
    if( p->selFlags & SF_NestedFrom ){
+
      /* Delete or NULL-out result columns that will never be used */
+
      int ii;
+
      for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].fg.bUsed==0; ii--){
+
        sqlite3ExprDelete(db, pEList->a[ii].pExpr);
+
        sqlite3DbFree(db, pEList->a[ii].zEName);
+
        pEList->nExpr--;
+
      }
+
      for(ii=0; ii<pEList->nExpr; ii++){
+
        if( pEList->a[ii].fg.bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL;
+
      }
+
    }
  }

  /* Set the limiter.
@@ -141276,8 +142869,9 @@ SQLITE_PRIVATE int sqlite3Select(
        ** ORDER BY to maximize the chances of rows being delivered in an
        ** order that makes the ORDER BY redundant.  */
        for(ii=0; ii<pGroupBy->nExpr; ii++){
-
          u8 sortFlags = sSort.pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_DESC;
-
          pGroupBy->a[ii].sortFlags = sortFlags;
+
          u8 sortFlags;
+
          sortFlags = sSort.pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_DESC;
+
          pGroupBy->a[ii].fg.sortFlags = sortFlags;
        }
        if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
          orderByGrp = 1;
@@ -141346,8 +142940,8 @@ SQLITE_PRIVATE int sqlite3Select(
    }
    pAggInfo->mxReg = pParse->nMem;
    if( db->mallocFailed ) goto select_end;
-
#if SELECTTRACE_ENABLED
-
    if( sqlite3SelectTrace & 0x400 ){
+
#if TREETRACE_ENABLED
+
    if( sqlite3TreeTrace & 0x400 ){
      int ii;
      SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo));
      sqlite3TreeViewSelect(0, p, 0);
@@ -141435,7 +143029,8 @@ SQLITE_PRIVATE int sqlite3Select(
      sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
      SELECTTRACE(1,pParse,p,("WhereBegin\n"));
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct,
-
          0, (WHERE_GROUPBY|(orderByGrp ? WHERE_SORTBYGROUP : 0)|distFlag), 0
+
          0, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY)
+
          |  (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
      );
      if( pWInfo==0 ){
        sqlite3ExprListDelete(db, pDistinct);
@@ -141617,7 +143212,7 @@ SQLITE_PRIVATE int sqlite3Select(
      VdbeComment((v, "indicate accumulator empty"));
      sqlite3VdbeAddOp1(v, OP_Return, regReset);

-
      if( eDist!=WHERE_DISTINCT_NOOP ){
+
      if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){
        struct AggInfo_func *pF = &pAggInfo->aFunc[0];
        fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
      }
@@ -141741,8 +143336,10 @@ SQLITE_PRIVATE int sqlite3Select(
        eDist = sqlite3WhereIsDistinct(pWInfo);
        updateAccumulator(pParse, regAcc, pAggInfo, eDist);
        if( eDist!=WHERE_DISTINCT_NOOP ){
-
          struct AggInfo_func *pF = &pAggInfo->aFunc[0];
-
          fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
+
          struct AggInfo_func *pF = pAggInfo->aFunc;
+
          if( pF ){
+
            fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr);
+
          }
        }

        if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
@@ -141809,9 +143406,9 @@ select_end:
  }
#endif

-
#if SELECTTRACE_ENABLED
+
#if TREETRACE_ENABLED
  SELECTTRACE(0x1,pParse,p,("end processing\n"));
-
  if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
+
  if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
@@ -142076,9 +143673,7 @@ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
  Trigger *pList;           /* List of triggers to return */
  HashElem *p;              /* Loop variable for TEMP triggers */

-
  if( pParse->disableTriggers ){
-
    return 0;
-
  }
+
  assert( pParse->disableTriggers==0 );
  pTmpSchema = pParse->db->aDb[1].pSchema;
  p = sqliteHashFirst(&pTmpSchema->trigHash);
  pList = pTab->pTrigger;
@@ -142091,11 +143686,10 @@ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
    ){
      pTrig->pNext = pList;
      pList = pTrig;
-
    }else if( pTrig->op==TK_RETURNING
+
    }else if( pTrig->op==TK_RETURNING ){
#ifndef SQLITE_OMIT_VIRTUALTABLE
-
              && pParse->db->pVtabCtx==0
+
      assert( pParse->db->pVtabCtx==0 );
#endif
-
    ){
      assert( pParse->bReturning );
      assert( &(pParse->u1.pReturning->retTrig) == pTrig );
      pTrig->table = pTab->zName;
@@ -142541,7 +144135,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(
  Parse *pParse,          /* Parser */
  Token *pTableName,   /* Name of the table to be updated */
-
  SrcList *pFrom,
+
  SrcList *pFrom,      /* FROM clause for an UPDATE-FROM, or NULL */
  ExprList *pEList,    /* The SET clause: list of column and new values */
  Expr *pWhere,        /* The WHERE clause */
  u8 orconf,           /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
@@ -142755,12 +144349,21 @@ static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){
}

/*
+
** Return true if any TEMP triggers exist
+
*/
+
static int tempTriggersExist(sqlite3 *db){
+
  if( NEVER(db->aDb[1].pSchema==0) ) return 0;
+
  if( sqliteHashFirst(&db->aDb[1].pSchema->trigHash)==0 ) return 0;
+
  return 1;
+
}
+

+
/*
** Return a list of all triggers on table pTab if there exists at least
** one trigger that must be fired when an operation of type 'op' is
** performed on the table, and, if that operation is an UPDATE, if at
** least one of the columns in pChanges is being modified.
*/
-
SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
+
static SQLITE_NOINLINE Trigger *triggersReallyExist(
  Parse *pParse,          /* Parse context */
  Table *pTab,            /* The table the contains the triggers */
  int op,                 /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
@@ -142823,6 +144426,22 @@ exit_triggers_exist:
  }
  return (mask ? pList : 0);
}
+
SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
+
  Parse *pParse,          /* Parse context */
+
  Table *pTab,            /* The table the contains the triggers */
+
  int op,                 /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
+
  ExprList *pChanges,     /* Columns that change in an UPDATE statement */
+
  int *pMask              /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */
+
){
+
  assert( pTab!=0 );
+
  if( (pTab->pTrigger==0 && !tempTriggersExist(pParse->db))
+
   || pParse->disableTriggers
+
  ){
+
    if( pMask ) *pMask = 0;
+
    return 0;
+
  }
+
  return triggersReallyExist(pParse,pTab,op,pChanges,pMask);
+
}

/*
** Convert the pStep->zTarget string into a SrcList and return a pointer
@@ -142852,6 +144471,14 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(
    }
    if( pStep->pFrom ){
      SrcList *pDup = sqlite3SrcListDup(db, pStep->pFrom, 0);
+
      if( pDup && pDup->nSrc>1 && !IN_RENAME_OBJECT ){
+
        Select *pSubquery;
+
        Token as;
+
        pSubquery = sqlite3SelectNew(pParse,0,pDup,0,0,0,0,SF_NestedFrom,0);
+
        as.n = 0;
+
        as.z = 0;
+
        pDup = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
+
      }
      pSrc = sqlite3SrcListAppendList(pParse, pSrc, pDup);
    }
  }else{
@@ -142907,7 +144534,7 @@ static ExprList *sqlite3ExpandReturning(
        if( !db->mallocFailed ){
          struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1];
          pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zCnName);
-
          pItem->eEName = ENAME_NAME;
+
          pItem->fg.eEName = ENAME_NAME;
        }
      }
    }else{
@@ -142916,7 +144543,7 @@ static ExprList *sqlite3ExpandReturning(
      if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){
        struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1];
        pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName);
-
        pItem->eEName = pList->a[i].eEName;
+
        pItem->fg.eEName = pList->a[i].fg.eEName;
      }
    }
  }
@@ -143831,6 +145458,14 @@ SQLITE_PRIVATE void sqlite3Update(
# define isView 0
#endif

+
#if TREETRACE_ENABLED
+
  if( sqlite3TreeTrace & 0x10000 ){
+
    sqlite3TreeViewLine(0, "In sqlite3Update() at %s:%d", __FILE__, __LINE__);
+
    sqlite3TreeViewUpdate(pParse->pWith, pTabList, pChanges, pWhere,
+
                          onError, pOrderBy, pLimit, pUpsert, pTrigger);
+
  }
+
#endif
+

  /* If there was a FROM clause, set nChangeFrom to the number of expressions
  ** in the change-list. Otherwise, set it to 0. There cannot be a FROM
  ** clause if this function is being called to generate code for part of
@@ -144475,7 +146110,7 @@ SQLITE_PRIVATE void sqlite3Update(
      }else{
        sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid);
      }
-
      VdbeCoverageNeverTaken(v);
+
      VdbeCoverage(v);
    }

    /* Do FK constraint checks. */
@@ -145481,6 +147116,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum(

  assert( rc==SQLITE_OK );
  if( pOut==0 ){
+
    nRes = sqlite3BtreeGetRequestedReserve(pTemp);
    rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1);
  }

@@ -146923,6 +148559,28 @@ typedef struct WhereLoopBuilder WhereLoopBuilder;
typedef struct WhereScan WhereScan;
typedef struct WhereOrCost WhereOrCost;
typedef struct WhereOrSet WhereOrSet;
+
typedef struct WhereMemBlock WhereMemBlock;
+
typedef struct WhereRightJoin WhereRightJoin;
+

+
/*
+
** This object is a header on a block of allocated memory that will be
+
** automatically freed when its WInfo oject is destructed.
+
*/
+
struct WhereMemBlock {
+
  WhereMemBlock *pNext;      /* Next block in the chain */
+
  u64 sz;                    /* Bytes of space */
+
};
+

+
/*
+
** Extra information attached to a WhereLevel that is a RIGHT JOIN.
+
*/
+
struct WhereRightJoin {
+
  int iMatch;          /* Cursor used to determine prior matched rows */
+
  int regBloom;        /* Bloom filter for iRJMatch */
+
  int regReturn;       /* Return register for the interior subroutine */
+
  int addrSubrtn;      /* Starting address for the interior subroutine */
+
  int endSubrtn;       /* The last opcode in the interior subroutine */
+
};

/*
** This object contains information needed to implement a single nested
@@ -146956,6 +148614,7 @@ struct WhereLevel {
  int addrLikeRep;      /* LIKE range processing address */
#endif
  int regFilter;        /* Bloom filter */
+
  WhereRightJoin *pRJ;  /* Extra information for RIGHT JOIN */
  u8 iFrom;             /* Which entry in the FROM clause */
  u8 op, p3, p5;        /* Opcode, P3 & P5 of the opcode that ends the loop */
  int p1, p2;           /* Operands of the opcode used to end the loop */
@@ -147369,6 +149028,7 @@ struct WhereInfo {
  int iEndWhere;            /* End of the WHERE clause itself */
  WhereLoop *pLoops;        /* List of all WhereLoop objects */
  WhereExprMod *pExprMods;  /* Expression modifications */
+
  WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */
  Bitmask revMask;          /* Mask of ORDER BY terms that need reversing */
  WhereClause sWC;          /* Decomposition of the WHERE clause */
  WhereMaskSet sMaskSet;    /* Map cursor numbers to bitmasks */
@@ -147394,6 +149054,8 @@ SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm(
  u32 op,               /* Mask of WO_xx values describing operator */
  Index *pIdx           /* Must be compatible with this index, if not NULL */
);
+
SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte);
+
SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte);

/* wherecode.c: */
#ifndef SQLITE_OMIT_EXPLAIN
@@ -147430,6 +149092,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
  WhereLevel *pLevel,  /* The current level pointer */
  Bitmask notReady     /* Which tables are currently available */
);
+
SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop(
+
  WhereInfo *pWInfo,
+
  int iLevel,
+
  WhereLevel *pLevel
+
);

/* whereexpr.c: */
SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
@@ -147472,8 +149139,9 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
#define WO_AND    0x0400       /* Two or more AND-connected terms */
#define WO_EQUIV  0x0800       /* Of the form A==B, both columns */
#define WO_NOOP   0x1000       /* This term does not restrict search space */
+
#define WO_ROWVAL 0x2000       /* A row-value term */

-
#define WO_ALL    0x1fff       /* Mask of all possible WO_* values */
+
#define WO_ALL    0x3fff       /* Mask of all possible WO_* values */
#define WO_SINGLE 0x01ff       /* Mask of all non-compound WO_* values */

/*
@@ -147697,6 +149365,9 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
                  pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
    }
#endif
+
    if( pItem->fg.jointype & JT_LEFT ){
+
      sqlite3_str_appendf(&str, " LEFT-JOIN");
+
    }
#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
    if( pLoop->nOut>=10 ){
      sqlite3_str_appendf(&str, " (~%llu rows)",
@@ -147840,7 +149511,7 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
  int nLoop = 0;
  assert( pTerm!=0 );
  while( (pTerm->wtFlags & TERM_CODED)==0
-
      && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+
      && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_OuterON))
      && (pLevel->notReady & pTerm->prereqAll)==0
  ){
    if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){
@@ -148101,16 +149772,21 @@ static int codeEqualityTerm(
    if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){
      eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
    }else{
-
      sqlite3 *db = pParse->db;
-
      pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
-

-
      if( !db->mallocFailed ){
+
      Expr *pExpr = pTerm->pExpr;
+
      if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){
+
        sqlite3 *db = pParse->db;
+
        pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
+
        if( !db->mallocFailed ){
+
          aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
+
          eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab);
+
          pExpr->iTable = iTab;
+
        }
+
        sqlite3ExprDelete(db, pX);
+
      }else{
        aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
        eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
-
        pTerm->pExpr->iTable = iTab;
      }
-
      sqlite3ExprDelete(db, pX);
-
      pX = pTerm->pExpr;
+
      pX = pExpr;
    }

    if( eType==IN_INDEX_INDEX_DESC ){
@@ -148133,8 +149809,9 @@ static int codeEqualityTerm(
    i = pLevel->u.in.nIn;
    pLevel->u.in.nIn += nEq;
    pLevel->u.in.aInLoop =
-
       sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
-
                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
+
       sqlite3WhereRealloc(pTerm->pWC->pWInfo,
+
                           pLevel->u.in.aInLoop,
+
                           sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
    pIn = pLevel->u.in.aInLoop;
    if( pIn ){
      int iMap = 0;               /* Index in aiMap[] */
@@ -148555,8 +150232,8 @@ static void codeCursorHint(
    */
    if( pTabItem->fg.jointype & JT_LEFT ){
      Expr *pExpr = pTerm->pExpr;
-
      if( !ExprHasProperty(pExpr, EP_FromJoin)
-
       || pExpr->w.iRightJoinTable!=pTabItem->iCursor
+
      if( !ExprHasProperty(pExpr, EP_OuterON)
+
       || pExpr->w.iJoin!=pTabItem->iCursor
      ){
        sWalker.eCode = 0;
        sWalker.xExprCallback = codeCursorHintIsOrFunction;
@@ -148564,7 +150241,7 @@ static void codeCursorHint(
        if( sWalker.eCode ) continue;
      }
    }else{
-
      if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue;
+
      if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) continue;
    }

    /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize
@@ -148612,13 +150289,21 @@ static void codeCursorHint(
**
**   OP_DeferredSeek $iCur $iRowid
**
+
** Which causes a seek on $iCur to the row with rowid $iRowid.
+
**
** However, if the scan currently being coded is a branch of an OR-loop and
-
** the statement currently being coded is a SELECT, then P3 of OP_DeferredSeek
-
** is set to iIdxCur and P4 is set to point to an array of integers
-
** containing one entry for each column of the table cursor iCur is open
-
** on. For each table column, if the column is the i'th column of the
-
** index, then the corresponding array entry is set to (i+1). If the column
-
** does not appear in the index at all, the array entry is set to 0.
+
** the statement currently being coded is a SELECT, then additional information
+
** is added that might allow OP_Column to omit the seek and instead do its
+
** lookup on the index, thus avoiding an expensive seek operation.  To
+
** enable this optimization, the P3 of OP_DeferredSeek is set to iIdxCur
+
** and P4 is set to an array of integers containing one entry for each column
+
** in the table.  For each table column, if the column is the i'th
+
** column of the index, then the corresponding array entry is set to (i+1).
+
** If the column does not appear in the index at all, the array entry is set
+
** to 0.  The OP_Column opcode can check this array to see if the column it
+
** wants is in the index and if it is, it will substitute the index cursor
+
** and column number and continue with those new values, rather than seeking
+
** the table cursor.
*/
static void codeDeferredSeek(
  WhereInfo *pWInfo,              /* Where clause context */
@@ -148634,7 +150319,7 @@ static void codeDeferredSeek(

  pWInfo->bDeferredSeek = 1;
  sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur);
-
  if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
+
  if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))
   && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask)
  ){
    int i;
@@ -148734,7 +150419,6 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
    pExpr->op = TK_COLUMN;
    pExpr->iTable = pX->iIdxCur;
    pExpr->iColumn = pX->iIdxCol;
-
    testcase( ExprHasProperty(pExpr, EP_Skip) );
    testcase( ExprHasProperty(pExpr, EP_Unlikely) );
    ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn);
    pExpr->y.pTab = 0;
@@ -148990,7 +150674,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
  ** initialize a memory cell that records if this table matches any
  ** row of the left table of the join.
  */
-
  assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
+
  assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))
       || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
  );
  if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){
@@ -149001,7 +150685,10 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(

  /* Compute a safe address to jump to if we discover that the table for
  ** this loop is empty and can never contribute content. */
-
  for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){}
+
  for(j=iLevel; j>0; j--){
+
    if( pWInfo->a[j].iLeftJoin ) break;
+
    if( pWInfo->a[j].pRJ ) break;
+
  }
  addrHalt = pWInfo->a[j].addrBrk;

  /* Special case of a FROM clause subquery implemented as a co-routine */
@@ -149628,7 +151315,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(

    /* Seek the table cursor, if required */
    omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0
-
           && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
+
           && (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0;
    if( omitTable ){
      /* pIdx is a covering index.  No need to access the main table. */
    }else if( HasRowid(pIdx->pTable) ){
@@ -149662,7 +151349,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
      ** move forward to the next index.
      ** https://sqlite.org/src/info/4e8e4857d32d401f
      */
-
      if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
+
      if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ){
        whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo);
      }

@@ -149681,7 +151368,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
      /* The following assert() is not a requirement, merely an observation:
      ** The OR-optimization doesn't work for the right hand table of
      ** a LEFT JOIN: */
-
      assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 );
+
      assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 );
    }

    /* Record the instruction used to terminate the loop. */
@@ -149885,7 +151572,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
        Expr *pDelete;                  /* Local copy of OR clause term */
        int jmp1 = 0;                   /* Address of jump operation */
        testcase( (pTabItem[0].fg.jointype & JT_LEFT)!=0
-
               && !ExprHasProperty(pOrExpr, EP_FromJoin)
+
               && !ExprHasProperty(pOrExpr, EP_OuterON)
        ); /* See TH3 vtab25.400 and ticket 614b25314c766238 */
        pDelete = pOrExpr = sqlite3ExprDup(db, pOrExpr, 0);
        if( db->mallocFailed ){
@@ -150023,6 +151710,14 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
    sqlite3VdbeGoto(v, pLevel->addrBrk);
    sqlite3VdbeResolveLabel(v, iLoopBody);

+
    /* Set the P2 operand of the OP_Return opcode that will end the current
+
    ** loop to point to this spot, which is the top of the next containing
+
    ** loop.  The byte-code formatter will use that P2 value as a hint to
+
    ** indent everything in between the this point and the final OP_Return.
+
    ** See tag-20220407a in vdbe.c and shell.c */
+
    assert( pLevel->op==OP_Return );
+
    pLevel->p2 = sqlite3VdbeCurrentAddr(v);
+

    if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); }
    if( !untestedTerms ) disableTerm(pLevel, pTerm);
  }else
@@ -150085,10 +151780,22 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
      }
      pE = pTerm->pExpr;
      assert( pE!=0 );
-
      if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){
-
        continue;
+
      if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ){
+
        if( !ExprHasProperty(pE,EP_OuterON|EP_InnerON) ){
+
          /* Defer processing WHERE clause constraints until after outer
+
          ** join processing.  tag-20220513a */
+
          continue;
+
        }else if( (pTabItem->fg.jointype & JT_LEFT)==JT_LEFT
+
               && !ExprHasProperty(pE,EP_OuterON) ){
+
          continue;
+
        }else{
+
          Bitmask m = sqlite3WhereGetMask(&pWInfo->sMaskSet, pE->w.iJoin);
+
          if( m & pLevel->notReady ){
+
            /* An ON clause that is not ripe */
+
            continue;
+
          }
+
        }
      }
-

      if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){
        iNext = 2;
        continue;
@@ -150147,7 +151854,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
    if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
    if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
    if( pTerm->leftCursor!=iCur ) continue;
-
    if( pTabItem->fg.jointype & JT_LEFT ) continue;
+
    if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ) continue;
    pE = pTerm->pExpr;
#ifdef WHERETRACE_ENABLED /* 0x800 */
    if( sqlite3WhereTrace & 0x800 ){
@@ -150155,7 +151862,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
      sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
    }
#endif
-
    assert( !ExprHasProperty(pE, EP_FromJoin) );
+
    assert( !ExprHasProperty(pE, EP_OuterON) );
    assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
    assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
    pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady,
@@ -150178,6 +151885,47 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
    pAlt->wtFlags |= TERM_CODED;
  }

+
  /* For a RIGHT OUTER JOIN, record the fact that the current row has
+
  ** been matched at least once.
+
  */
+
  if( pLevel->pRJ ){
+
    Table *pTab;
+
    int nPk;
+
    int r;
+
    int jmp1 = 0;
+
    WhereRightJoin *pRJ = pLevel->pRJ;
+

+
    /* pTab is the right-hand table of the RIGHT JOIN.  Generate code that
+
    ** will record that the current row of that table has been matched at
+
    ** least once.  This is accomplished by storing the PK for the row in
+
    ** both the iMatch index and the regBloom Bloom filter.
+
    */
+
    pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab;
+
    if( HasRowid(pTab) ){
+
      r = sqlite3GetTempRange(pParse, 2);
+
      sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1);
+
      nPk = 1;
+
    }else{
+
      int iPk;
+
      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+
      nPk = pPk->nKeyCol;
+
      r = sqlite3GetTempRange(pParse, nPk+1);
+
      for(iPk=0; iPk<nPk; iPk++){
+
        int iCol = pPk->aiColumn[iPk];
+
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+1+iPk);
+
      }
+
    }
+
    jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, 0, r+1, nPk);
+
    VdbeCoverage(v);
+
    VdbeComment((v, "match against %s", pTab->zName));
+
    sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r);
+
    sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r, r+1, nPk);
+
    sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk);
+
    sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+
    sqlite3VdbeJumpHere(v, jmp1);
+
    sqlite3ReleaseTempRange(pParse, r, nPk+1);
+
  }
+

  /* For a LEFT OUTER JOIN, generate code that will record the fact that
  ** at least one row of the right table has matched the left table.
  */
@@ -150185,6 +151933,30 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
    pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
    VdbeComment((v, "record LEFT JOIN hit"));
+
    if( pLevel->pRJ==0 ){
+
      goto code_outer_join_constraints; /* WHERE clause constraints */
+
    }
+
  }
+

+
  if( pLevel->pRJ ){
+
    /* Create a subroutine used to process all interior loops and code
+
    ** of the RIGHT JOIN.  During normal operation, the subroutine will
+
    ** be in-line with the rest of the code.  But at the end, a separate
+
    ** loop will run that invokes this subroutine for unmatched rows
+
    ** of pTab, with all tables to left begin set to NULL.
+
    */
+
    WhereRightJoin *pRJ = pLevel->pRJ;
+
    sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn);
+
    pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v);
+
    assert( pParse->withinRJSubrtn < 255 );
+
    pParse->withinRJSubrtn++;
+

+
    /* WHERE clause constraints must be deferred until after outer join
+
    ** row elimination has completed, since WHERE clause constraints apply
+
    ** to the results of the OUTER JOIN.  The following loop generates the
+
    ** appropriate WHERE clause constraint checks.  tag-20220513a.
+
    */
+
  code_outer_join_constraints:
    for(pTerm=pWC->a, j=0; j<pWC->nBase; j++, pTerm++){
      testcase( pTerm->wtFlags & TERM_VIRTUAL );
      testcase( pTerm->wtFlags & TERM_CODED );
@@ -150193,6 +151965,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
        assert( pWInfo->untestedTerms );
        continue;
      }
+
      if( pTabItem->fg.jointype & JT_LTORJ ) continue;
      assert( pTerm->pExpr );
      sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
      pTerm->wtFlags |= TERM_CODED;
@@ -150213,6 +151986,96 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
  return pLevel->notReady;
}

+
/*
+
** Generate the code for the loop that finds all non-matched terms
+
** for a RIGHT JOIN.
+
*/
+
SQLITE_PRIVATE SQLITE_NOINLINE void sqlite3WhereRightJoinLoop(
+
  WhereInfo *pWInfo,
+
  int iLevel,
+
  WhereLevel *pLevel
+
){
+
  Parse *pParse = pWInfo->pParse;
+
  Vdbe *v = pParse->pVdbe;
+
  WhereRightJoin *pRJ = pLevel->pRJ;
+
  Expr *pSubWhere = 0;
+
  WhereClause *pWC = &pWInfo->sWC;
+
  WhereInfo *pSubWInfo;
+
  WhereLoop *pLoop = pLevel->pWLoop;
+
  SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
+
  SrcList sFrom;
+
  Bitmask mAll = 0;
+
  int k;
+

+
  ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName));
+
  sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn,
+
                                  pRJ->regReturn);
+
  for(k=0; k<iLevel; k++){
+
    int iIdxCur;
+
    mAll |= pWInfo->a[k].pWLoop->maskSelf;
+
    sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur);
+
    iIdxCur = pWInfo->a[k].iIdxCur;
+
    if( iIdxCur ){
+
      sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur);
+
    }
+
  }
+
  if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){
+
    mAll |= pLoop->maskSelf;
+
    for(k=0; k<pWC->nTerm; k++){
+
      WhereTerm *pTerm = &pWC->a[k];
+
      if( (pTerm->wtFlags & (TERM_VIRTUAL|TERM_SLICE))!=0
+
       && pTerm->eOperator!=WO_ROWVAL
+
      ){
+
        break;
+
      }
+
      if( pTerm->prereqAll & ~mAll ) continue;
+
      if( ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON) ) continue;
+
      pSubWhere = sqlite3ExprAnd(pParse, pSubWhere,
+
                                 sqlite3ExprDup(pParse->db, pTerm->pExpr, 0));
+
    }
+
  }
+
  sFrom.nSrc = 1;
+
  sFrom.nAlloc = 1;
+
  memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem));
+
  sFrom.a[0].fg.jointype = 0;
+
  assert( pParse->withinRJSubrtn < 100 );
+
  pParse->withinRJSubrtn++;
+
  pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0,
+
                                WHERE_RIGHT_JOIN, 0);
+
  if( pSubWInfo ){
+
    int iCur = pLevel->iTabCur;
+
    int r = ++pParse->nMem;
+
    int nPk;
+
    int jmp;
+
    int addrCont = sqlite3WhereContinueLabel(pSubWInfo);
+
    Table *pTab = pTabItem->pTab;
+
    if( HasRowid(pTab) ){
+
      sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r);
+
      nPk = 1;
+
    }else{
+
      int iPk;
+
      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+
      nPk = pPk->nKeyCol;
+
      pParse->nMem += nPk - 1;
+
      for(iPk=0; iPk<nPk; iPk++){
+
        int iCol = pPk->aiColumn[iPk];
+
        sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk);
+
      }
+
    }
+
    jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk);
+
    VdbeCoverage(v);
+
    sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk);
+
    VdbeCoverage(v);
+
    sqlite3VdbeJumpHere(v, jmp);
+
    sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn);
+
    sqlite3WhereEnd(pSubWInfo);
+
  }
+
  sqlite3ExprDelete(pParse->db, pSubWhere);
+
  ExplainQueryPlanPop(pParse);
+
  assert( pParse->withinRJSubrtn>0 );
+
  pParse->withinRJSubrtn--;
+
}
+

/************** End of wherecode.c *******************************************/
/************** Begin file whereexpr.c ***************************************/
/*
@@ -150281,7 +152144,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
  if( pWC->nTerm>=pWC->nSlot ){
    WhereTerm *pOld = pWC->a;
    sqlite3 *db = pWC->pWInfo->pParse->db;
-
    pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
+
    pWC->a = sqlite3WhereMalloc(pWC->pWInfo, sizeof(pWC->a[0])*pWC->nSlot*2 );
    if( pWC->a==0 ){
      if( wtFlags & TERM_DYNAMIC ){
        sqlite3ExprDelete(db, p);
@@ -150290,10 +152153,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
      return 0;
    }
    memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm);
-
    if( pOld!=pWC->aStatic ){
-
      sqlite3DbFree(db, pOld);
-
    }
-
    pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
+
    pWC->nSlot = pWC->nSlot*2;
  }
  pTerm = &pWC->a[idx = pWC->nTerm++];
  if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm;
@@ -150681,9 +152541,9 @@ static int isAuxiliaryVtabOperator(
** a join, then transfer the appropriate markings over to derived.
*/
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
-
  if( pDerived ){
-
    pDerived->flags |= pBase->flags & EP_FromJoin;
-
    pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable;
+
  if( pDerived && ExprHasProperty(pBase, EP_OuterON|EP_InnerON) ){
+
    pDerived->flags |= pBase->flags & (EP_OuterON|EP_InnerON);
+
    pDerived->w.iJoin = pBase->w.iJoin;
  }
}

@@ -151137,7 +152997,7 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){
  CollSeq *pColl;
  if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
  if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
-
  if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
+
  if( ExprHasProperty(pExpr, EP_OuterON) ) return 0;
  aff1 = sqlite3ExprAffinity(pExpr->pLeft);
  aff2 = sqlite3ExprAffinity(pExpr->pRight);
  if( aff1!=aff2
@@ -151168,7 +153028,9 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
      int i;
      for(i=0; i<pSrc->nSrc; i++){
        mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect);
-
        mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn);
+
        if( pSrc->a[i].fg.isUsing==0 ){
+
          mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn);
+
        }
        if( pSrc->a[i].fg.isTabFunc ){
          mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg);
        }
@@ -151323,18 +153185,32 @@ static void exprAnalyze(
  if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){
    printf("\n*** Incorrect prereqAll computed for:\n");
    sqlite3TreeViewExpr(0,pExpr,0);
-
    abort();
+
    assert( 0 );
  }
#endif

-
  if( ExprHasProperty(pExpr, EP_FromJoin) ){
-
    Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable);
-
    prereqAll |= x;
-
    extraRight = x-1;  /* ON clause terms may not be used with an index
-
                       ** on left table of a LEFT JOIN.  Ticket #3015 */
-
    if( (prereqAll>>1)>=x ){
-
      sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
-
      return;
+
  if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON) ){
+
    Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin);
+
    if( ExprHasProperty(pExpr, EP_OuterON) ){
+
      prereqAll |= x;
+
      extraRight = x-1;  /* ON clause terms may not be used with an index
+
                         ** on left table of a LEFT JOIN.  Ticket #3015 */
+
      if( (prereqAll>>1)>=x ){
+
        sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
+
        return;
+
      }
+
    }else if( (prereqAll>>1)>=x ){
+
      /* The ON clause of an INNER JOIN references a table to its right.
+
      ** Most other SQL database engines raise an error.  But SQLite versions
+
      ** 3.0 through 3.38 just put the ON clause constraint into the WHERE
+
      ** clause and carried on.   Beginning with 3.39, raise an error only
+
      ** if there is a RIGHT or FULL JOIN in the query.  This makes SQLite
+
      ** more like other systems, and also preserves legacy. */
+
      if( ALWAYS(pSrc->nSrc>0) && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){
+
        sqlite3ErrorMsg(pParse, "ON clause references tables to its right");
+
        return;
+
      }
+
      ExprClearProperty(pExpr, EP_InnerON);
    }
  }
  pTerm->prereqAll = prereqAll;
@@ -151402,7 +153278,7 @@ static void exprAnalyze(
      pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
    }else
    if( op==TK_ISNULL
-
     && !ExprHasProperty(pExpr,EP_FromJoin)
+
     && !ExprHasProperty(pExpr,EP_OuterON)
     && 0==sqlite3ExprCanBeNull(pLeft)
    ){
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
@@ -151473,7 +153349,7 @@ static void exprAnalyze(
  else if( pExpr->op==TK_NOTNULL ){
    if( pExpr->pLeft->op==TK_COLUMN
     && pExpr->pLeft->iColumn>=0
-
     && !ExprHasProperty(pExpr, EP_FromJoin)
+
     && !ExprHasProperty(pExpr, EP_OuterON)
    ){
      Expr *pNewExpr;
      Expr *pLeft = pExpr->pLeft;
@@ -151621,7 +153497,7 @@ static void exprAnalyze(
    }
    pTerm = &pWC->a[idxTerm];
    pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL;  /* Disable the original */
-
    pTerm->eOperator = 0;
+
    pTerm->eOperator = WO_ROWVAL;
  }

  /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
@@ -151677,9 +153553,9 @@ static void exprAnalyze(
        Expr *pNewExpr;
        pNewExpr = sqlite3PExpr(pParse, TK_MATCH,
            0, sqlite3ExprDup(db, pRight, 0));
-
        if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
-
          ExprSetProperty(pNewExpr, EP_FromJoin);
-
          pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable;
+
        if( ExprHasProperty(pExpr, EP_OuterON) && pNewExpr ){
+
          ExprSetProperty(pNewExpr, EP_OuterON);
+
          pNewExpr->w.iJoin = pExpr->w.iJoin;
        }
        idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
        testcase( idxNew==0 );
@@ -151822,7 +153698,7 @@ SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
        /* This term is a vector operation that has been decomposed into
        ** other, subsequent terms.  It can be ignored. See tag-20220128a */
        assert( pWC->a[ii].wtFlags & TERM_VIRTUAL );
-
        assert( pWC->a[ii].eOperator==0 );
+
        assert( pWC->a[ii].eOperator==WO_ROWVAL );
        continue;
      }
      if( pWC->a[ii].leftCursor!=iCsr ) return;
@@ -151834,7 +153710,7 @@ SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){
        Expr *pExpr = pOrderBy->a[ii].pExpr;
        if( pExpr->op!=TK_COLUMN ) return;
        if( pExpr->iTable!=iCsr ) return;
-
        if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return;
+
        if( pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) return;
      }
    }

@@ -151901,9 +153777,6 @@ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){
      a++;
    }
  }
-
  if( pWC->a!=pWC->aStatic ){
-
    sqlite3DbFree(db, pWC->a);
-
  }
}


@@ -152030,6 +153903,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
  if( pArgs==0 ) return;
  for(j=k=0; j<pArgs->nExpr; j++){
    Expr *pRhs;
+
    u32 joinType;
    while( k<pTab->nCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;}
    if( k>=pTab->nCol ){
      sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d",
@@ -152046,9 +153920,12 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(
    pRhs = sqlite3PExpr(pParse, TK_UPLUS,
        sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
    pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
-
    if( pItem->fg.jointype & JT_LEFT ){
-
      sqlite3SetJoinExpr(pTerm, pItem->iCursor);
+
    if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ) ){
+
      joinType = EP_OuterON;
+
    }else{
+
      joinType = EP_InnerON;
    }
+
    sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType);
    whereClauseInsert(pWC, pTerm, TERM_DYNAMIC);
  }
}
@@ -152159,7 +154036,7 @@ SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){
  }
  pInner = &pWInfo->a[pWInfo->nLevel-1];
  assert( pInner->addrNxt!=0 );
-
  return pInner->addrNxt;
+
  return pInner->pRJ ? pWInfo->iContinue : pInner->addrNxt;
}

/*
@@ -152310,6 +154187,30 @@ SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){
  return 0;
}

+
/* Allocate memory that is automatically freed when pWInfo is freed.
+
*/
+
SQLITE_PRIVATE void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte){
+
  WhereMemBlock *pBlock;
+
  pBlock = sqlite3DbMallocRawNN(pWInfo->pParse->db, nByte+sizeof(*pBlock));
+
  if( pBlock ){
+
    pBlock->pNext = pWInfo->pMemToFree;
+
    pBlock->sz = nByte;
+
    pWInfo->pMemToFree = pBlock;
+
    pBlock++;
+
  }
+
  return (void*)pBlock;
+
}
+
SQLITE_PRIVATE void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte){
+
  void *pNew = sqlite3WhereMalloc(pWInfo, nByte);
+
  if( pNew && pOld ){
+
    WhereMemBlock *pOldBlk = (WhereMemBlock*)pOld;
+
    pOldBlk--;
+
    assert( pOldBlk->sz<nByte );
+
    memcpy(pNew, pOld, pOldBlk->sz);
+
  }
+
  return pNew;
+
}
+

/*
** Create a new mask for cursor iCursor.
**
@@ -152363,7 +154264,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){
         && (iColumn!=XN_EXPR
             || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
                                       pScan->pIdxExpr,iCur)==0)
-
         && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
+
         && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_OuterON))
        ){
          if( (pTerm->eOperator & WO_EQUIV)!=0
           && pScan->nEquiv<ArraySize(pScan->aiCur)
@@ -152715,6 +154616,7 @@ static void translateColumnToCopy(
      pOp->p1 = pOp->p2 + iRegister;
      pOp->p2 = pOp->p3;
      pOp->p3 = 0;
+
      pOp->p5 = 2;  /* Cause the MEM_Subtype flag to be cleared */
    }else if( pOp->opcode==OP_Rowid ){
      pOp->opcode = OP_Sequence;
      pOp->p1 = iAutoidxCur;
@@ -152789,14 +154691,17 @@ static int termCanDriveIndex(
  char aff;
  if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
  if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
-
  if( (pSrc->fg.jointype & JT_LEFT)
-
   && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
-
   && (pTerm->eOperator & WO_IS)
-
  ){
-
    /* Cannot use an IS term from the WHERE clause as an index driver for
-
    ** the RHS of a LEFT JOIN. Such a term can only be used if it is from
-
    ** the ON clause.  */
-
    return 0;
+
  assert( (pSrc->fg.jointype & JT_RIGHT)==0 );
+
  if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
+
    testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
+
    testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
+
    testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
+
    testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
+
    if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
+
     || pTerm->pExpr->w.iJoin != pSrc->iCursor
+
    ){
+
      return 0;  /* See tag-20191211-001 */
+
    }
  }
  if( (pTerm->prereqRight & notReady)!=0 ) return 0;
  assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
@@ -153137,7 +155042,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
      const SrcItem *pTabItem;
      pLevel = &pWInfo->a[iLevel];
      pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
-
      if( pTabItem->fg.jointype & JT_LEFT ) continue;
+
      if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue;
      pLoop = pLevel->pWLoop;
      if( NEVER(pLoop==0) ) continue;
      if( pLoop->prereq & notReady ) continue;
@@ -153210,12 +155115,20 @@ static sqlite3_index_info *allocateIndexInfo(
    assert( pTerm->u.x.leftColumn<pTab->nCol );

    /* tag-20191211-002: WHERE-clause constraints are not useful to the
-
    ** right-hand table of a LEFT JOIN.  See tag-20191211-001 for the
+
    ** right-hand table of a LEFT JOIN nor to the either table of a
+
    ** RIGHT JOIN.  See tag-20191211-001 for the
    ** equivalent restriction for ordinary tables. */
-
    if( (pSrc->fg.jointype & JT_LEFT)!=0
-
     && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
-
    ){
-
      continue;
+
    if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
+
      testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
+
      testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
+
      testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
+
      testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) );
+
      testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
+
      if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
+
       || pTerm->pExpr->w.iJoin != pSrc->iCursor
+
      ){
+
        continue;
+
      }
    }
    nTerm++;
    pTerm->wtFlags |= TERM_OK;
@@ -153238,7 +155151,7 @@ static sqlite3_index_info *allocateIndexInfo(
      }

      /* Virtual tables are unable to deal with NULLS FIRST */
-
      if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break;
+
      if( pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) break;

      /* First case - a direct column references without a COLLATE operator */
      if( pExpr->op==TK_COLUMN && pExpr->iTable==pSrc->iCursor ){
@@ -153268,8 +155181,10 @@ static sqlite3_index_info *allocateIndexInfo(
    }
    if( i==n ){
      nOrderBy = n;
-
      if( (pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY)) ){
-
        eDistinct = 1 + ((pWInfo->wctrlFlags & WHERE_DISTINCTBY)!=0);
+
      if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){
+
        eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0);
+
      }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){
+
        eDistinct = 1;
      }
    }
  }
@@ -153348,7 +155263,7 @@ static sqlite3_index_info *allocateIndexInfo(
         || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN
              && pExpr->iColumn==pExpr->pLeft->iColumn) );
    pIdxOrderBy[j].iColumn = pExpr->iColumn;
-
    pIdxOrderBy[j].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC;
+
    pIdxOrderBy[j].desc = pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC;
    j++;
  }
  pIdxInfo->nOrderBy = j;
@@ -153452,7 +155367,7 @@ static int whereKeyStats(
#endif
  assert( pRec!=0 );
  assert( pIdx->nSample>0 );
-
  assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol );
+
  assert( pRec->nField>0 );

  /* Do a binary search to find the first sample greater than or equal
  ** to pRec. If pRec contains a single field, the set of samples to search
@@ -153498,7 +155413,7 @@ static int whereKeyStats(
  ** it is extended to two fields. The duplicates that this creates do not
  ** cause any problems.
  */
-
  nField = pRec->nField;
+
  nField = MIN(pRec->nField, pIdx->nSample);
  iCol = 0;
  iSample = pIdx->nSample * nField;
  do{
@@ -154089,7 +156004,7 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){
    memcpy(zType, "....", 5);
    if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
    if( pTerm->eOperator & WO_EQUIV  ) zType[1] = 'E';
-
    if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
+
    if( ExprHasProperty(pTerm->pExpr, EP_OuterON) ) zType[2] = 'L';
    if( pTerm->wtFlags & TERM_CODED  ) zType[3] = 'C';
    if( pTerm->eOperator & WO_SINGLE ){
      assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
@@ -154270,15 +156185,7 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
** Free a WhereInfo structure
*/
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
-
  int i;
  assert( pWInfo!=0 );
-
  for(i=0; i<pWInfo->nLevel; i++){
-
    WhereLevel *pLevel = &pWInfo->a[i];
-
    if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE)!=0 ){
-
      assert( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 );
-
      sqlite3DbFree(db, pLevel->u.in.aInLoop);
-
    }
-
  }
  sqlite3WhereClauseClear(&pWInfo->sWC);
  while( pWInfo->pLoops ){
    WhereLoop *p = pWInfo->pLoops;
@@ -154286,6 +156193,11 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
    whereLoopDelete(db, p);
  }
  assert( pWInfo->pExprMods==0 );
+
  while( pWInfo->pMemToFree ){
+
    WhereMemBlock *pNext = pWInfo->pMemToFree->pNext;
+
    sqlite3DbFreeNN(db, pWInfo->pMemToFree);
+
    pWInfo->pMemToFree = pNext;
+
  }
  sqlite3DbFreeNN(db, pWInfo);
}

@@ -154654,10 +156566,11 @@ static void whereLoopOutputAdjust(
        **
        ** 2022-03-24:  Self-culling only applies if either the extra terms
        ** are straight comparison operators that are non-true with NULL
-
        ** operand, or if the loop is not a LEFT JOIN.
+
        ** operand, or if the loop is not an OUTER JOIN.
        */
        if( (pTerm->eOperator & 0x3f)!=0
-
         || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0
+
         || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype
+
                  & (JT_LEFT|JT_LTORJ))==0
        ){
          pLoop->wsFlags |= WHERE_SELFCULL;
        }
@@ -154864,12 +156777,29 @@ static int whereLoopAddBtreeIndex(
    if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;

    /* tag-20191211-001:  Do not allow constraints from the WHERE clause to
-
    ** be used by the right table of a LEFT JOIN.  Only constraints in the
-
    ** ON clause are allowed.  See tag-20191211-002 for the vtab equivalent. */
-
    if( (pSrc->fg.jointype & JT_LEFT)!=0
-
     && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
-
    ){
-
      continue;
+
    ** be used by the right table of a LEFT JOIN nor by the left table of a
+
    ** RIGHT JOIN.  Only constraints in the ON clause are allowed.
+
    ** See tag-20191211-002 for the vtab equivalent.
+
    **
+
    ** 2022-06-06: See https://sqlite.org/forum/forumpost/206d99a16dd9212f
+
    ** for an example of a WHERE clause constraints that may not be used on
+
    ** the right table of a RIGHT JOIN because the constraint implies a
+
    ** not-NULL condition on the left table of the RIGHT JOIN.
+
    **
+
    ** 2022-06-10: The same condition applies to termCanDriveIndex() above.
+
    ** https://sqlite.org/forum/forumpost/51e6959f61
+
    */
+
    if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))!=0 ){
+
      testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LEFT );
+
      testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_RIGHT );
+
      testcase( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT))==JT_LTORJ );
+
      testcase( ExprHasProperty(pTerm->pExpr, EP_OuterON) )
+
      testcase( ExprHasProperty(pTerm->pExpr, EP_InnerON) );
+
      if( !ExprHasProperty(pTerm->pExpr, EP_OuterON|EP_InnerON)
+
       || pTerm->pExpr->w.iJoin != pSrc->iCursor
+
      ){
+
        continue;
+
      }
    }

    if( IsUniqueIndex(pProbe) && saved_nEq==pProbe->nKeyCol-1 ){
@@ -155221,23 +157151,26 @@ static int indexMightHelpWithOrderBy(
*/
static int whereUsablePartialIndex(
  int iTab,             /* The table for which we want an index */
-
  int isLeft,           /* True if iTab is the right table of a LEFT JOIN */
+
  u8 jointype,          /* The JT_* flags on the join */
  WhereClause *pWC,     /* The WHERE clause of the query */
  Expr *pWhere          /* The WHERE clause from the partial index */
){
  int i;
  WhereTerm *pTerm;
-
  Parse *pParse = pWC->pWInfo->pParse;
+
  Parse *pParse;
+

+
  if( jointype & JT_LTORJ ) return 0;
+
  pParse = pWC->pWInfo->pParse;
  while( pWhere->op==TK_AND ){
-
    if( !whereUsablePartialIndex(iTab,isLeft,pWC,pWhere->pLeft) ) return 0;
+
    if( !whereUsablePartialIndex(iTab,jointype,pWC,pWhere->pLeft) ) return 0;
    pWhere = pWhere->pRight;
  }
  if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0;
  for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
    Expr *pExpr;
    pExpr = pTerm->pExpr;
-
    if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab)
-
     && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
+
    if( (!ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin==iTab)
+
     && ((jointype & JT_OUTER)==0 || ExprHasProperty(pExpr, EP_OuterON))
     && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
     && (pTerm->wtFlags & TERM_VNULL)==0
    ){
@@ -155346,13 +157279,14 @@ static int whereLoopAddBtree(
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet      /* Not part of an OR optimization */
-
   && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
+
   && (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0
   && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
   && !pSrc->fg.isIndexedBy  /* Has no INDEXED BY clause */
   && !pSrc->fg.notIndexed   /* Has no NOT INDEXED clause */
   && HasRowid(pTab)         /* Not WITHOUT ROWID table. (FIXME: Why not?) */
   && !pSrc->fg.isCorrelated /* Not a correlated subquery */
   && !pSrc->fg.isRecursive  /* Not a recursive common table expression. */
+
   && (pSrc->fg.jointype & JT_RIGHT)==0 /* Not the right tab of a RIGHT JOIN */
  ){
    /* Generate auto-index WhereLoops */
    LogEst rLogSize;         /* Logarithm of the number of rows in the table */
@@ -155402,9 +157336,8 @@ static int whereLoopAddBtree(
  for(; rc==SQLITE_OK && pProbe;
      pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++
  ){
-
    int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0;
    if( pProbe->pPartIdxWhere!=0
-
     && !whereUsablePartialIndex(pSrc->iCursor, isLeft, pWC,
+
     && !whereUsablePartialIndex(pSrc->iCursor, pSrc->fg.jointype, pWC,
                                 pProbe->pPartIdxWhere)
    ){
      testcase( pNew->iTab!=pSrc->iCursor );  /* See ticket [98d973b8f5] */
@@ -155512,7 +157445,14 @@ static int whereLoopAddBtree(
        }
        ApplyCostMultiplier(pNew->rRun, pTab->costMult);
        whereLoopOutputAdjust(pWC, pNew, rSize);
-
        rc = whereLoopInsert(pBuilder, pNew);
+
        if( (pSrc->fg.jointype & JT_RIGHT)!=0 && pProbe->aColExpr ){
+
          /* Do not do an SCAN of a index-on-expression in a RIGHT JOIN
+
          ** because the cursor used to access the index might not be
+
          ** positioned to the correct row during the right-join no-match
+
          ** loop. */
+
        }else{
+
          rc = whereLoopInsert(pBuilder, pNew);
+
        }
        pNew->nOut = rSize;
        if( rc ) break;
      }
@@ -155687,6 +157627,7 @@ static int whereLoopAddVirtualOne(
        *pbIn = 1; assert( (mExclude & WO_IN)==0 );
      }

+
      assert( pbRetryLimit || !isLimitTerm(pTerm) );
      if( isLimitTerm(pTerm) && *pbIn ){
        /* If there is an IN(...) term handled as an == (separate call to
        ** xFilter for each value on the RHS of the IN) and a LIMIT or
@@ -155834,9 +157775,7 @@ SQLITE_API int sqlite3_vtab_rhs_value(
*/
SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){
  HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
-
  assert( pHidden->eDistinct==0
-
       || pHidden->eDistinct==1
-
       || pHidden->eDistinct==2 );
+
  assert( pHidden->eDistinct>=0 && pHidden->eDistinct<=3 );
  return pHidden->eDistinct;
}

@@ -155844,15 +157783,26 @@ SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){
    && !defined(SQLITE_OMIT_VIRTUALTABLE)
/*
** Cause the prepared statement that is associated with a call to
-
** xBestIndex to open write transactions on all attached schemas.
+
** xBestIndex to potentiall use all schemas.  If the statement being
+
** prepared is read-only, then just start read transactions on all
+
** schemas.  But if this is a write operation, start writes on all
+
** schemas.
+
**
** This is used by the (built-in) sqlite_dbpage virtual table.
*/
-
SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){
+
SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(sqlite3_index_info *pIdxInfo){
  HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
  Parse *pParse = pHidden->pParse;
  int nDb = pParse->db->nDb;
  int i;
-
  for(i=0; i<nDb; i++) sqlite3BeginWriteOperation(pParse, 0, i);
+
  for(i=0; i<nDb; i++){
+
    sqlite3CodeVerifySchema(pParse, i);
+
  }
+
  if( pParse->writeMask ){
+
    for(i=0; i<nDb; i++){
+
      sqlite3BeginWriteOperation(pParse, 0, i);
+
    }
+
  }
}
#endif

@@ -156035,6 +157985,9 @@ static int whereLoopAddOr(
  pItem = pWInfo->pTabList->a + pNew->iTab;
  iCur = pItem->iCursor;

+
  /* The multi-index OR optimization does not work for RIGHT and FULL JOIN */
+
  if( pItem->fg.jointype & JT_RIGHT ) return SQLITE_OK;
+

  for(pTerm=pWC->a; pTerm<pWCEnd && rc==SQLITE_OK; pTerm++){
    if( (pTerm->eOperator & WO_OR)!=0
     && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0
@@ -156148,8 +158101,11 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
  SrcItem *pEnd = &pTabList->a[pWInfo->nLevel];
  sqlite3 *db = pWInfo->pParse->db;
  int rc = SQLITE_OK;
+
  int bFirstPastRJ = 0;
+
  int hasRightJoin = 0;
  WhereLoop *pNew;

+

  /* Loop over the tables in the join, from left to right */
  pNew = pBuilder->pNew;
  whereLoopInit(pNew);
@@ -156159,18 +158115,30 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
    pNew->iTab = iTab;
    pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR;
    pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor);
-
    if( (pItem->fg.jointype & (JT_LEFT|JT_CROSS))!=0 ){
-
      /* This condition is true when pItem is the FROM clause term on the
-
      ** right-hand-side of a LEFT or CROSS JOIN.  */
-
      mPrereq = mPrior;
-
    }else{
+
    if( bFirstPastRJ
+
     || (pItem->fg.jointype & (JT_OUTER|JT_CROSS|JT_LTORJ))!=0
+
    ){
+
      /* Add prerequisites to prevent reordering of FROM clause terms
+
      ** across CROSS joins and outer joins.  The bFirstPastRJ boolean
+
      ** prevents the right operand of a RIGHT JOIN from being swapped with
+
      ** other elements even further to the right.
+
      **
+
      ** The JT_LTORJ case and the hasRightJoin flag work together to
+
      ** prevent FROM-clause terms from moving from the right side of
+
      ** a LEFT JOIN over to the left side of that join if the LEFT JOIN
+
      ** is itself on the left side of a RIGHT JOIN.
+
      */
+
      if( pItem->fg.jointype & JT_LTORJ ) hasRightJoin = 1;
+
      mPrereq |= mPrior;
+
      bFirstPastRJ = (pItem->fg.jointype & JT_RIGHT)!=0;
+
    }else if( !hasRightJoin ){
      mPrereq = 0;
    }
#ifndef SQLITE_OMIT_VIRTUALTABLE
    if( IsVirtual(pItem->pTab) ){
      SrcItem *p;
      for(p=&pItem[1]; p<pEnd; p++){
-
        if( mUnusable || (p->fg.jointype & (JT_LEFT|JT_CROSS)) ){
+
        if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){
          mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor);
        }
      }
@@ -156295,7 +158263,9 @@ static i8 wherePathSatisfiesOrderBy(
      pLoop = pLast;
    }
    if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){
-
      if( pLoop->u.vtab.isOrdered && (wctrlFlags & WHERE_DISTINCTBY)==0 ){
+
      if( pLoop->u.vtab.isOrdered
+
       && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY)
+
      ){
        obSat = obDone;
      }
      break;
@@ -156473,16 +158443,18 @@ static i8 wherePathSatisfiesOrderBy(
          /* Make sure the sort order is compatible in an ORDER BY clause.
          ** Sort order is irrelevant for a GROUP BY clause. */
          if( revSet ){
-
            if( (rev ^ revIdx)!=(pOrderBy->a[i].sortFlags&KEYINFO_ORDER_DESC) ){
+
            if( (rev ^ revIdx)
+
                           != (pOrderBy->a[i].fg.sortFlags&KEYINFO_ORDER_DESC)
+
            ){
              isMatch = 0;
            }
          }else{
-
            rev = revIdx ^ (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC);
+
            rev = revIdx ^ (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC);
            if( rev ) *pRevMask |= MASKBIT(iLoop);
            revSet = 1;
          }
        }
-
        if( isMatch && (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL) ){
+
        if( isMatch && (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL) ){
          if( j==pLoop->u.btree.nEq ){
            pLoop->wsFlags |= WHERE_BIGNULL_SORT;
          }else{
@@ -156562,7 +158534,7 @@ static i8 wherePathSatisfiesOrderBy(
**   SELECT * FROM t1 GROUP BY y,x ORDER BY y,x;   -- IsSorted()==0
*/
SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){
-
  assert( pWInfo->wctrlFlags & WHERE_GROUPBY );
+
  assert( pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY) );
  assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP );
  return pWInfo->sorted;
}
@@ -156963,12 +158935,12 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
  }
  pWInfo->bOrderedInnerLoop = 0;
  if( pWInfo->pOrderBy ){
+
    pWInfo->nOBSat = pFrom->isOrdered;
    if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){
      if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
        pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
      }
    }else{
-
      pWInfo->nOBSat = pFrom->isOrdered;
      pWInfo->revMask = pFrom->revLoop;
      if( pWInfo->nOBSat<=0 ){
        pWInfo->nOBSat = 0;
@@ -157047,7 +159019,11 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
  pItem = pWInfo->pTabList->a;
  pTab = pItem->pTab;
  if( IsVirtual(pTab) ) return 0;
-
  if( pItem->fg.isIndexedBy ) return 0;
+
  if( pItem->fg.isIndexedBy || pItem->fg.notIndexed ){
+
    testcase( pItem->fg.isIndexedBy );
+
    testcase( pItem->fg.notIndexed );
+
    return 0;
+
  }
  iCur = pItem->iCursor;
  pWC = &pWInfo->sWC;
  pLoop = pBuilder->pNew;
@@ -157220,7 +159196,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
    WhereLoop *pLoop;
    pLoop = pWInfo->a[i].pWLoop;
    pItem = &pWInfo->pTabList->a[pLoop->iTab];
-
    if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
+
    if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ) continue;
    if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0
     && (pLoop->wsFlags & WHERE_ONEROW)==0
    ){
@@ -157230,8 +159206,8 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
    pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
    for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
      if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
-
        if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
-
         || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor
+
        if( !ExprHasProperty(pTerm->pExpr, EP_OuterON)
+
         || pTerm->pExpr->w.iJoin!=pItem->iCursor
        ){
          break;
        }
@@ -157462,7 +159438,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
  ** field (type Bitmask) it must be aligned on an 8-byte boundary on
  ** some architectures. Hence the ROUND8() below.
  */
-
  nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
+
  nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel));
  pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop));
  if( db->mallocFailed ){
    sqlite3DbFree(db, pWInfo);
@@ -157552,7 +159528,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
  /* Analyze all of the subexpressions. */
  sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC);
  sqlite3WhereAddLimit(&pWInfo->sWC, pLimit);
-
  if( db->mallocFailed ) goto whereBeginError;
+
  if( pParse->nErr ) goto whereBeginError;

  /* Special case: WHERE terms that do not refer to any tables in the join
  ** (constant expressions). Evaluate each such term, and jump over all the
@@ -157784,8 +159760,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
      /* noop */
    }else
#endif
-
    if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
-
         && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){
+
    if( ((pLoop->wsFlags & WHERE_IDX_ONLY)==0
+
         && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0)
+
     || (pTabItem->fg.jointype & (JT_LTORJ|JT_RIGHT))!=0
+
    ){
      int op = OP_OpenRead;
      if( pWInfo->eOnePass!=ONEPASS_OFF ){
        op = OP_OpenWrite;
@@ -157854,6 +159832,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
        iIndexCur = pParse->nTab++;
      }
      pLevel->iIdxCur = iIndexCur;
+
      assert( pIx!=0 );
      assert( pIx->pSchema==pTab->pSchema );
      assert( iIndexCur>=0 );
      if( op ){
@@ -157887,6 +159866,37 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
      }
    }
    if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb);
+
    if( (pTabItem->fg.jointype & JT_RIGHT)!=0
+
     && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0
+
    ){
+
      WhereRightJoin *pRJ = pLevel->pRJ;
+
      pRJ->iMatch = pParse->nTab++;
+
      pRJ->regBloom = ++pParse->nMem;
+
      sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom);
+
      pRJ->regReturn = ++pParse->nMem;
+
      sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn);
+
      assert( pTab==pTabItem->pTab );
+
      if( HasRowid(pTab) ){
+
        KeyInfo *pInfo;
+
        sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1);
+
        pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0);
+
        if( pInfo ){
+
          pInfo->aColl[0] = 0;
+
          pInfo->aSortFlags[0] = 0;
+
          sqlite3VdbeAppendP4(v, pInfo, P4_KEYINFO);
+
        }
+
      }else{
+
        Index *pPk = sqlite3PrimaryKeyIndex(pTab);
+
        sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, pPk->nKeyCol);
+
        sqlite3VdbeSetP4KeyInfo(pParse, pPk);
+
      }
+
      pLoop->wsFlags &= ~WHERE_IDX_ONLY;
+
      /* The nature of RIGHT JOIN processing is such that it messes up
+
      ** the output order.  So omit any ORDER BY/GROUP BY elimination
+
      ** optimizations.  We need to do an actual sort for RIGHT JOIN. */
+
      pWInfo->nOBSat = 0;
+
      pWInfo->eDistinct = WHERE_DISTINCT_UNORDERED;
+
    }
  }
  pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
  if( db->mallocFailed ) goto whereBeginError;
@@ -157898,9 +159908,20 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
  for(ii=0; ii<nTabList; ii++){
    int addrExplain;
    int wsFlags;
+
    SrcItem *pSrc;
    if( pParse->nErr ) goto whereBeginError;
    pLevel = &pWInfo->a[ii];
    wsFlags = pLevel->pWLoop->wsFlags;
+
    pSrc = &pTabList->a[pLevel->iFrom];
+
    if( pSrc->fg.isMaterialized ){
+
      if( pSrc->fg.isCorrelated ){
+
        sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
+
      }else{
+
        int iOnce = sqlite3VdbeAddOp0(v, OP_Once);  VdbeCoverage(v);
+
        sqlite3VdbeAddOp2(v, OP_Gosub, pSrc->regReturn, pSrc->addrFillSub);
+
        sqlite3VdbeJumpHere(v, iOnce);
+
      }
+
    }
    if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
      if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
@@ -157992,6 +160013,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
  SrcList *pTabList = pWInfo->pTabList;
  sqlite3 *db = pParse->db;
  int iEnd = sqlite3VdbeCurrentAddr(v);
+
  int nRJ = 0;

  /* Generate loop termination code.
  */
@@ -157999,6 +160021,17 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
  for(i=pWInfo->nLevel-1; i>=0; i--){
    int addr;
    pLevel = &pWInfo->a[i];
+
    if( pLevel->pRJ ){
+
      /* Terminate the subroutine that forms the interior of the loop of
+
      ** the RIGHT JOIN table */
+
      WhereRightJoin *pRJ = pLevel->pRJ;
+
      sqlite3VdbeResolveLabel(v, pLevel->addrCont);
+
      pLevel->addrCont = 0;
+
      pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v);
+
      sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1);
+
      VdbeCoverage(v);
+
      nRJ++;
+
    }
    pLoop = pLevel->pWLoop;
    if( pLevel->op!=OP_Noop ){
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
@@ -158026,7 +160059,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
      }
#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
      /* The common case: Advance to the next row */
-
      sqlite3VdbeResolveLabel(v, pLevel->addrCont);
+
      if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
      sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
      sqlite3VdbeChangeP5(v, pLevel->p5);
      VdbeCoverage(v);
@@ -158041,7 +160074,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
#ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT
      if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
#endif
-
    }else{
+
    }else if( pLevel->addrCont ){
      sqlite3VdbeResolveLabel(v, pLevel->addrCont);
    }
    if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){
@@ -158091,6 +160124,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
      }
    }
    sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
+
    if( pLevel->pRJ ){
+
      sqlite3VdbeAddOp3(v, OP_Return, pLevel->pRJ->regReturn, 0, 1);
+
      VdbeCoverage(v);
+
    }
    if( pLevel->addrSkip ){
      sqlite3VdbeGoto(v, pLevel->addrSkip);
      VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName));
@@ -158134,12 +160171,8 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
                     pWInfo->pTabList->a[pLevel->iFrom].pTab->zName));
  }

-
  /* The "break" point is here, just past the end of the outer loop.
-
  ** Set it.
-
  */
-
  sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
-

  assert( pWInfo->nLevel<=pTabList->nSrc );
+
  if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo);
  for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
    int k, last;
    VdbeOp *pOp, *pLastOp;
@@ -158149,6 +160182,15 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
    assert( pTab!=0 );
    pLoop = pLevel->pWLoop;

+
    /* Do RIGHT JOIN processing.  Generate code that will output the
+
    ** unmatched rows of the right operand of the RIGHT JOIN with
+
    ** all of the columns of the left operand set to NULL.
+
    */
+
    if( pLevel->pRJ ){
+
      sqlite3WhereRightJoinLoop(pWInfo, i, pLevel);
+
      continue;
+
    }
+

    /* For a co-routine, change all OP_Column references to the table of
    ** the co-routine into OP_Copy of result contained in a register.
    ** OP_Rowid becomes OP_Null.
@@ -158160,29 +160202,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
      continue;
    }

-
#ifdef SQLITE_ENABLE_EARLY_CURSOR_CLOSE
-
    /* Close all of the cursors that were opened by sqlite3WhereBegin.
-
    ** Except, do not close cursors that will be reused by the OR optimization
-
    ** (WHERE_OR_SUBCLAUSE).  And do not close the OP_OpenWrite cursors
-
    ** created for the ONEPASS optimization.
-
    */
-
    if( (pTab->tabFlags & TF_Ephemeral)==0
-
     && !IsView(pTab)
-
     && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0
-
    ){
-
      int ws = pLoop->wsFlags;
-
      if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){
-
        sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
-
      }
-
      if( (ws & WHERE_INDEXED)!=0
-
       && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0
-
       && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1]
-
      ){
-
        sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur);
-
      }
-
    }
-
#endif
-

    /* If this scan uses an index, make VDBE code substitutions to read data
    ** from the index instead of from the table where possible.  In some cases
    ** this optimization prevents the table from ever being read, which can
@@ -158283,11 +160302,16 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
    }
  }

+
  /* The "break" point is here, just past the end of the outer loop.
+
  ** Set it.
+
  */
+
  sqlite3VdbeResolveLabel(v, pWInfo->iBreak);
+

  /* Final cleanup
  */
-
  if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo);
  pParse->nQueryLoop = pWInfo->savedNQueryLoop;
  whereInfoFree(db, pWInfo);
+
  pParse->withinRJSubrtn -= nRJ;
  return;
}

@@ -159019,7 +161043,7 @@ SQLITE_PRIVATE void sqlite3WindowUpdate(
      }
    }
  }
-
  pWin->pFunc = pFunc;
+
  pWin->pWFunc = pFunc;
}

/*
@@ -159211,7 +161235,7 @@ static ExprList *exprListAppendList(
        }
      }
      pList = sqlite3ExprListAppend(pParse, pList, pDup);
-
      if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags;
+
      if( pList ) pList->a[nInit+i].fg.sortFlags = pAppend->a[i].fg.sortFlags;
    }
  }
  return pList;
@@ -159331,9 +161355,9 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
    for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
      ExprList *pArgs;
      assert( ExprUseXList(pWin->pOwner) );
-
      assert( pWin->pFunc!=0 );
+
      assert( pWin->pWFunc!=0 );
      pArgs = pWin->pOwner->x.pList;
-
      if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
+
      if( pWin->pWFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
        selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
        pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
        pWin->bExprArgs = 1;
@@ -159715,7 +161739,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){
  }

  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
-
    FuncDef *p = pWin->pFunc;
+
    FuncDef *p = pWin->pWFunc;
    if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
      /* The inline versions of min() and max() require a single ephemeral
      ** table and 3 registers. The registers are used as follows:
@@ -159732,7 +161756,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){
      pWin->csrApp = pParse->nTab++;
      pWin->regApp = pParse->nMem+1;
      pParse->nMem += 3;
-
      if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
+
      if( pKeyInfo && pWin->pWFunc->zName[1]=='i' ){
        assert( pKeyInfo->aSortFlags[0]==0 );
        pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC;
      }
@@ -159955,7 +161979,7 @@ static void windowAggStep(
  Vdbe *v = sqlite3GetVdbe(pParse);
  Window *pWin;
  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
-
    FuncDef *pFunc = pWin->pFunc;
+
    FuncDef *pFunc = pWin->pWFunc;
    int regArg;
    int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
    int i;
@@ -160069,7 +162093,7 @@ static void windowAggFinal(WindowCodeArg *p, int bFin){

  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
    if( pMWin->regStartRowid==0
-
     && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX)
+
     && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX)
     && (pWin->eStart!=TK_UNBOUNDED)
    ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
@@ -160083,12 +162107,12 @@ static void windowAggFinal(WindowCodeArg *p, int bFin){
      int nArg = windowArgCount(pWin);
      if( bFin ){
        sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
-
        sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
+
        sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
        sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
      }else{
        sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
-
        sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
+
        sqlite3VdbeAppendP4(v, pWin->pWFunc, P4_FUNCDEF);
      }
    }
  }
@@ -160217,7 +162241,7 @@ static void windowReturnOneRow(WindowCodeArg *p){
    Window *pWin;

    for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
-
      FuncDef *pFunc = pWin->pFunc;
+
      FuncDef *pFunc = pWin->pWFunc;
      assert( ExprUseXList(pWin->pOwner) );
      if( pFunc->zName==nth_valueName
       || pFunc->zName==first_valueName
@@ -160289,7 +162313,7 @@ static int windowInitAccum(Parse *pParse, Window *pMWin){
  int nArg = 0;
  Window *pWin;
  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
-
    FuncDef *pFunc = pWin->pFunc;
+
    FuncDef *pFunc = pWin->pWFunc;
    assert( pWin->regAccum );
    sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
    nArg = MAX(nArg, windowArgCount(pWin));
@@ -160319,7 +162343,7 @@ static int windowCacheFrame(Window *pMWin){
  Window *pWin;
  if( pMWin->regStartRowid ) return 1;
  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
-
    FuncDef *pFunc = pWin->pFunc;
+
    FuncDef *pFunc = pWin->pWFunc;
    if( (pFunc->zName==nth_valueName)
     || (pFunc->zName==first_valueName)
     || (pFunc->zName==leadName)
@@ -160412,7 +162436,7 @@ static void windowCodeRangeTest(

  assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
  assert( pOrderBy && pOrderBy->nExpr==1 );
-
  if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){
+
  if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_DESC ){
    switch( op ){
      case OP_Ge: op = OP_Le; break;
      case OP_Gt: op = OP_Lt; break;
@@ -160445,7 +162469,7 @@ static void windowCodeRangeTest(
  ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is
  ** not taken, control jumps over the comparison operator coded below this
  ** block.  */
-
  if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){
+
  if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_BIGNULL ){
    /* This block runs if reg1 contains a NULL. */
    int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v);
    switch( op ){
@@ -160677,7 +162701,7 @@ SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
      pNew->zName = sqlite3DbStrDup(db, p->zName);
      pNew->zBase = sqlite3DbStrDup(db, p->zBase);
      pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
-
      pNew->pFunc = p->pFunc;
+
      pNew->pWFunc = p->pWFunc;
      pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
      pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
      pNew->eFrmType = p->eFrmType;
@@ -161563,7 +163587,7 @@ static void updateDeleteLimitError(
      p->affExpr = 0;
      p->flags = EP_Leaf;
      ExprClearVVAProperties(p);
-
      p->iAgg = -1;
+
      /* p->iAgg = -1; // Not required */
      p->pLeft = p->pRight = 0;
      p->pAggInfo = 0;
      memset(&p->x, 0, sizeof(p->x));
@@ -161896,6 +163920,7 @@ typedef union {
  With* yy521;
  const char* yy522;
  Expr* yy528;
+
  OnOrUsing yy561;
  struct FrameBound yy595;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
@@ -161912,18 +163937,18 @@ typedef union {
#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
#define YYFALLBACK 1
-
#define YYNSTATE             574
-
#define YYNRULE              402
-
#define YYNRULE_WITH_ACTION  340
+
#define YYNSTATE             576
+
#define YYNRULE              405
+
#define YYNRULE_WITH_ACTION  342
#define YYNTOKEN             185
-
#define YY_MAX_SHIFT         573
-
#define YY_MIN_SHIFTREDUCE   831
-
#define YY_MAX_SHIFTREDUCE   1232
-
#define YY_ERROR_ACTION      1233
-
#define YY_ACCEPT_ACTION     1234
-
#define YY_NO_ACTION         1235
-
#define YY_MIN_REDUCE        1236
-
#define YY_MAX_REDUCE        1637
+
#define YY_MAX_SHIFT         575
+
#define YY_MIN_SHIFTREDUCE   835
+
#define YY_MAX_SHIFTREDUCE   1239
+
#define YY_ERROR_ACTION      1240
+
#define YY_ACCEPT_ACTION     1241
+
#define YY_NO_ACTION         1242
+
#define YY_MIN_REDUCE        1243
+
#define YY_MAX_REDUCE        1647
/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))

@@ -161990,427 +164015,430 @@ typedef union {
**  yy_default[]       Default action for each state.
**
*********** Begin parsing tables **********************************************/
-
#define YY_ACTTAB_COUNT (2070)
+
#define YY_ACTTAB_COUNT (2098)
static const YYACTIONTYPE yy_action[] = {
-
 /*     0 */   566, 1307,  566, 1286,  201,  201,  566,  116,  112,  222,
-
 /*    10 */   566, 1307,  377,  566,  116,  112,  222,  397,  408,  409,
-
 /*    20 */  1260,  378, 1269,   41,   41,   41,   41, 1412, 1517,   71,
-
 /*    30 */    71,  967, 1258,   41,   41,  491,   71,   71,  272,  968,
-
 /*    40 */   298,  476,  298,  123,  124,  114, 1210, 1210, 1044, 1047,
-
 /*    50 */  1036, 1036,  121,  121,  122,  122,  122,  122,  543,  409,
-
 /*    60 */  1234,    1,    1,  573,    2, 1238,  548,  116,  112,  222,
-
 /*    70 */   309,  480,  142,  548, 1272,  524,  116,  112,  222, 1320,
-
 /*    80 */   417,  523,  547,  123,  124,  114, 1210, 1210, 1044, 1047,
-
 /*    90 */  1036, 1036,  121,  121,  122,  122,  122,  122,  424,  116,
-
 /*   100 */   112,  222,  120,  120,  120,  120,  119,  119,  118,  118,
-
 /*   110 */   118,  117,  113,  444,  277,  277,  277,  277,  560,  560,
-
 /*   120 */   560, 1558,  376, 1560, 1186,  375, 1157,  563, 1157,  563,
-
 /*   130 */   409, 1558,  537,  252,  219, 1553,   99,  141,  449,    6,
-
 /*   140 */   365,  233,  120,  120,  120,  120,  119,  119,  118,  118,
-
 /*   150 */   118,  117,  113,  444,  123,  124,  114, 1210, 1210, 1044,
-
 /*   160 */  1047, 1036, 1036,  121,  121,  122,  122,  122,  122,  138,
-
 /*   170 */   289, 1186, 1546,  448,  118,  118,  118,  117,  113,  444,
-
 /*   180 */   125, 1186, 1187, 1188,  144,  465,  334,  566,  150,  127,
-
 /*   190 */   444,  122,  122,  122,  122,  115,  120,  120,  120,  120,
-
 /*   200 */   119,  119,  118,  118,  118,  117,  113,  444,  454,  419,
-
 /*   210 */    13,   13,  215,  120,  120,  120,  120,  119,  119,  118,
-
 /*   220 */   118,  118,  117,  113,  444,  422,  308,  557, 1186, 1187,
-
 /*   230 */  1188,  441,  440,  409, 1271,  122,  122,  122,  122,  120,
-
 /*   240 */   120,  120,  120,  119,  119,  118,  118,  118,  117,  113,
-
 /*   250 */   444, 1543,   98, 1033, 1033, 1045, 1048,  123,  124,  114,
-
 /*   260 */  1210, 1210, 1044, 1047, 1036, 1036,  121,  121,  122,  122,
-
 /*   270 */   122,  122,  566,  406,  405, 1186,  566,  409, 1217,  319,
-
 /*   280 */  1217,   80,   81,  120,  120,  120,  120,  119,  119,  118,
-
 /*   290 */   118,  118,  117,  113,  444,   70,   70, 1186, 1604,   71,
-
 /*   300 */    71,  123,  124,  114, 1210, 1210, 1044, 1047, 1036, 1036,
-
 /*   310 */   121,  121,  122,  122,  122,  122,  120,  120,  120,  120,
-
 /*   320 */   119,  119,  118,  118,  118,  117,  113,  444, 1037,  210,
-
 /*   330 */  1186,  365, 1186, 1187, 1188,  245,  548,  399,  504,  501,
-
 /*   340 */   500,  108,  558,  138,    4,  516,  933,  433,  499,  217,
-
 /*   350 */   514,  522,  352,  879, 1186, 1187, 1188,  383,  561,  566,
-
 /*   360 */   120,  120,  120,  120,  119,  119,  118,  118,  118,  117,
-
 /*   370 */   113,  444,  277,  277,   16,   16, 1598,  441,  440,  153,
-
 /*   380 */   409,  445,   13,   13, 1279,  563, 1214, 1186, 1187, 1188,
-
 /*   390 */  1003, 1216,  264,  555, 1574,  186,  566,  427,  138, 1215,
-
 /*   400 */   308,  557,  472,  138,  123,  124,  114, 1210, 1210, 1044,
-
 /*   410 */  1047, 1036, 1036,  121,  121,  122,  122,  122,  122,   55,
-
 /*   420 */    55,  413, 1023,  507, 1217, 1186, 1217,  474,  106,  106,
-
 /*   430 */  1312, 1312, 1186,  171,  566,  384,  107,  380,  445,  568,
-
 /*   440 */   567,  430, 1543, 1013,  332,  549,  565,  263,  280,  360,
-
 /*   450 */   510,  355,  509,  250,  491,  308,  557,   71,   71,  351,
-
 /*   460 */   308,  557,  374,  120,  120,  120,  120,  119,  119,  118,
-
 /*   470 */   118,  118,  117,  113,  444, 1013, 1013, 1015, 1016,   27,
-
 /*   480 */   277,  277, 1186, 1187, 1188, 1152,  566,  528,  409, 1186,
-
 /*   490 */  1187, 1188,  348,  563,  548, 1260,  533,  517, 1152, 1516,
-
 /*   500 */   317, 1152,  285,  550,  485,  569,  566,  569,  482,   51,
-
 /*   510 */    51,  207,  123,  124,  114, 1210, 1210, 1044, 1047, 1036,
-
 /*   520 */  1036,  121,  121,  122,  122,  122,  122,  171, 1412,   13,
-
 /*   530 */    13,  409,  277,  277, 1186,  505,  119,  119,  118,  118,
-
 /*   540 */   118,  117,  113,  444,  429,  563,  518,  220,  515, 1552,
-
 /*   550 */   365,  546, 1186,    6,  532,  123,  124,  114, 1210, 1210,
-
 /*   560 */  1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,  122,
-
 /*   570 */   145,  120,  120,  120,  120,  119,  119,  118,  118,  118,
-
 /*   580 */   117,  113,  444,  245,  566,  474,  504,  501,  500,  566,
-
 /*   590 */  1481, 1186, 1187, 1188, 1310, 1310,  499, 1186,  149,  425,
-
 /*   600 */  1186,  480,  409,  274,  365,  952,  872,   56,   56, 1186,
-
 /*   610 */  1187, 1188,   71,   71,  120,  120,  120,  120,  119,  119,
-
 /*   620 */   118,  118,  118,  117,  113,  444,  123,  124,  114, 1210,
-
 /*   630 */  1210, 1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,
-
 /*   640 */   122,  409,  541, 1552,   83,  865,   98,    6,  928,  529,
-
 /*   650 */   848,  543,  151,  927, 1186, 1187, 1188, 1186, 1187, 1188,
-
 /*   660 */   290, 1543,  187, 1633,  395,  123,  124,  114, 1210, 1210,
-
 /*   670 */  1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,  122,
-
 /*   680 */   566,  954,  566,  453,  953,  120,  120,  120,  120,  119,
-
 /*   690 */   119,  118,  118,  118,  117,  113,  444, 1152,  221, 1186,
-
 /*   700 */   331,  453,  452,   13,   13,   13,   13, 1003,  365,  463,
-
 /*   710 */  1152,  193,  409, 1152,  382, 1543, 1170,   32,  297,  474,
-
 /*   720 */   195, 1527,    5,  952,  120,  120,  120,  120,  119,  119,
-
 /*   730 */   118,  118,  118,  117,  113,  444,  123,  124,  114, 1210,
-
 /*   740 */  1210, 1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,
-
 /*   750 */   122,  409, 1067,  419, 1186, 1024, 1186, 1187, 1188, 1186,
-
 /*   760 */   419,  332,  460,  320,  544, 1545,  442,  442,  442,  566,
-
 /*   770 */     3,  117,  113,  444,  453,  123,  124,  114, 1210, 1210,
-
 /*   780 */  1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,  122,
-
 /*   790 */  1473,  566,   15,   15,  293,  120,  120,  120,  120,  119,
-
 /*   800 */   119,  118,  118,  118,  117,  113,  444, 1186,  566, 1486,
-
 /*   810 */  1412, 1186, 1187, 1188,   13,   13, 1186, 1187, 1188, 1544,
-
 /*   820 */   271,  271,  409,  286,  308,  557, 1008, 1486, 1488,  196,
-
 /*   830 */   288,   71,   71,  563,  120,  120,  120,  120,  119,  119,
-
 /*   840 */   118,  118,  118,  117,  113,  444,  123,  124,  114, 1210,
-
 /*   850 */  1210, 1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,
-
 /*   860 */   122,  409,  201, 1087, 1186, 1187, 1188, 1324,  304, 1529,
-
 /*   870 */   388,  278,  278,  450,  564,  402,  922,  922,  566,  563,
-
 /*   880 */   566,  426,  491,  480,  563,  123,  124,  114, 1210, 1210,
-
 /*   890 */  1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,  122,
-
 /*   900 */  1486,   71,   71,   13,   13,  120,  120,  120,  120,  119,
-
 /*   910 */   119,  118,  118,  118,  117,  113,  444,  566,  545,  566,
-
 /*   920 */  1577,  573,    2, 1238, 1092, 1092,  488, 1480,  309, 1525,
-
 /*   930 */   142,  324,  409,  836,  837,  838,  312, 1320,  305,  363,
-
 /*   940 */    43,   43,   57,   57,  120,  120,  120,  120,  119,  119,
-
 /*   950 */   118,  118,  118,  117,  113,  444,  123,  124,  114, 1210,
-
 /*   960 */  1210, 1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,
-
 /*   970 */   122,   12,  277,  277,  566, 1152,  409,  572,  428, 1238,
-
 /*   980 */   465,  334,  296,  474,  309,  563,  142,  249, 1152,  308,
-
 /*   990 */   557, 1152,  321, 1320,  323,  491,  455,   71,   71,  233,
-
 /*  1000 */   283,  101,  114, 1210, 1210, 1044, 1047, 1036, 1036,  121,
-
 /*  1010 */   121,  122,  122,  122,  122,  120,  120,  120,  120,  119,
-
 /*  1020 */   119,  118,  118,  118,  117,  113,  444, 1108,  277,  277,
-
 /*  1030 */  1412,  448,  394, 1230,  439,  277,  277,  248,  247,  246,
-
 /*  1040 */  1319,  563, 1109,  313,  198,  294,  491, 1318,  563,  464,
-
 /*  1050 */   566, 1427,  394, 1130, 1023,  233,  414, 1110,  295,  120,
-
 /*  1060 */   120,  120,  120,  119,  119,  118,  118,  118,  117,  113,
-
 /*  1070 */   444, 1014,  104,   71,   71, 1013,  322,  496,  908,  566,
-
 /*  1080 */   277,  277,  277,  277, 1108, 1261,  415,  448,  909,  361,
-
 /*  1090 */  1571, 1315,  409,  563,  952,  563,    9,  202,  255, 1109,
-
 /*  1100 */   316,  487,   44,   44,  249,  559,  415, 1013, 1013, 1015,
-
 /*  1110 */   443, 1231,  409, 1603, 1110,  897,  123,  124,  114, 1210,
-
 /*  1120 */  1210, 1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,
-
 /*  1130 */   122, 1231,  409, 1207,  215,  554,  123,  124,  114, 1210,
-
 /*  1140 */  1210, 1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,
-
 /*  1150 */   122, 1131, 1631,  470, 1631,  255,  123,  111,  114, 1210,
-
 /*  1160 */  1210, 1044, 1047, 1036, 1036,  121,  121,  122,  122,  122,
-
 /*  1170 */   122, 1131, 1632,  414, 1632,  120,  120,  120,  120,  119,
-
 /*  1180 */   119,  118,  118,  118,  117,  113,  444,  221,  209,  351,
-
 /*  1190 */  1207, 1207,  147, 1426,  491,  120,  120,  120,  120,  119,
-
 /*  1200 */   119,  118,  118,  118,  117,  113,  444, 1256,  539,  519,
-
 /*  1210 */   888,  551,  952,   12,  566,  120,  120,  120,  120,  119,
-
 /*  1220 */   119,  118,  118,  118,  117,  113,  444,  538,  566,  860,
-
 /*  1230 */  1129,  361, 1571,  346, 1356,  409, 1163,   58,   58,  339,
-
 /*  1240 */  1355,  508,  277,  277,  277,  277,  277,  277, 1207,  889,
-
 /*  1250 */  1129,   59,   59,  459,  363,  563,  566,  563,   96,  563,
-
 /*  1260 */   124,  114, 1210, 1210, 1044, 1047, 1036, 1036,  121,  121,
-
 /*  1270 */   122,  122,  122,  122,  566, 1412,  566,  281, 1186,   60,
-
 /*  1280 */    60,  110,  392,  392,  391,  266,  389,  860, 1163,  845,
-
 /*  1290 */   566,  481,  566,  436,  341, 1152,  344,   61,   61,   62,
-
 /*  1300 */    62,  967,  227, 1550,  315,  431,  540,    6, 1152,  968,
-
 /*  1310 */   566, 1152,  314,   45,   45,   46,   46,  512,  120,  120,
-
 /*  1320 */   120,  120,  119,  119,  118,  118,  118,  117,  113,  444,
-
 /*  1330 */   416,  173, 1532,   47,   47, 1186, 1187, 1188,  108,  558,
-
 /*  1340 */   325,    4,  229, 1551,  928,  566,  437,    6,  566,  927,
-
 /*  1350 */   164,  566, 1290,  137, 1190,  561,  566, 1549,  566, 1089,
-
 /*  1360 */   566,    6,  566, 1089,  531,  566,  868,    8,   49,   49,
-
 /*  1370 */   228,   50,   50,  566,   63,   63,  566,  457,  445,   64,
-
 /*  1380 */    64,   65,   65,   14,   14,   66,   66,  407,  129,  129,
-
 /*  1390 */   555,  566,  458,  566, 1505,  486,   67,   67,  566,   52,
-
 /*  1400 */    52,  546,  407,  467,  535,  410,  226, 1023,  566,  534,
-
 /*  1410 */   308,  557, 1190,  407,   68,   68,   69,   69,  566, 1023,
-
 /*  1420 */   566,   53,   53,  868, 1014,  106,  106,  525, 1013,  566,
-
 /*  1430 */  1504,  159,  159,  107,  451,  445,  568,  567,  471,  307,
-
 /*  1440 */  1013,  160,  160,   76,   76,  566, 1548,  466,  407,  407,
-
 /*  1450 */     6, 1225,   54,   54,  478,  276,  219,  566,  887,  886,
-
 /*  1460 */  1013, 1013, 1015,   84,  206, 1206,  230,  282,   72,   72,
-
 /*  1470 */   329,  483, 1013, 1013, 1015, 1016,   27, 1576, 1174,  447,
-
 /*  1480 */   130,  130,  281,  148,  105,   38,  103,  392,  392,  391,
-
 /*  1490 */   266,  389,  566, 1126,  845,  396,  566,  108,  558,  566,
-
 /*  1500 */     4,  311,  566,   30,   17,  566,  279,  227,  566,  315,
-
 /*  1510 */   108,  558,  468,    4,  561,   73,   73,  314,  566,  157,
-
 /*  1520 */   157,  566,  131,  131,  526,  132,  132,  561,  128,  128,
-
 /*  1530 */   566,  158,  158,  566,   31,  291,  566,  445,  330,  521,
-
 /*  1540 */    98,  152,  152,  420,  136,  136, 1005,  229,  254,  555,
-
 /*  1550 */   445,  479,  336,  135,  135,  164,  133,  133,  137,  134,
-
 /*  1560 */   134,  875,  555,  535,  566,  473,  566,  254,  536,  475,
-
 /*  1570 */   335,  254,   98,  894,  895,  228,  535,  566, 1023,  566,
-
 /*  1580 */  1074,  534,  210,  232,  106,  106, 1352,   75,   75,   77,
-
 /*  1590 */    77, 1023,  107,  340,  445,  568,  567,  106,  106, 1013,
-
 /*  1600 */    74,   74,   42,   42,  566,  107,  343,  445,  568,  567,
-
 /*  1610 */   410,  497, 1013,  251,  359,  308,  557, 1135,  349,  875,
-
 /*  1620 */    98, 1070,  345,  251,  358, 1591,  347,   48,   48, 1017,
-
 /*  1630 */  1303, 1013, 1013, 1015, 1016,   27, 1289, 1287, 1074,  451,
-
 /*  1640 */   961,  925,  254,  110, 1013, 1013, 1015, 1016,   27, 1174,
-
 /*  1650 */   447,  970,  971,  281,  108,  558, 1288,    4,  392,  392,
-
 /*  1660 */   391,  266,  389, 1343, 1086,  845, 1086, 1085,  858, 1085,
-
 /*  1670 */   146,  561,  926,  354,  110,  303,  364,  553,  227, 1364,
-
 /*  1680 */   315,  108,  558, 1411,    4, 1339,  492, 1017,  314, 1350,
-
 /*  1690 */  1565,  552, 1417, 1268,  445,  204, 1259, 1247,  561, 1246,
-
 /*  1700 */  1248, 1584,  269, 1336,  367,  369,  555,  371,   11,  212,
-
 /*  1710 */   393,  225, 1393,  284, 1398,  456,  287,  327,  229,  328,
-
 /*  1720 */   292,  445, 1386,  216,  333, 1403,  164,  477,  373,  137,
-
 /*  1730 */  1402,  400,  502,  555, 1286, 1023,  357, 1477,  199, 1587,
-
 /*  1740 */   211,  106,  106,  932, 1476, 1225,  228,  556,  175,  107,
-
 /*  1750 */   200,  445,  568,  567,  258,  387, 1013, 1524, 1522,  223,
-
 /*  1760 */  1222,  418, 1023,   83,  208,   79,   82,  184,  106,  106,
-
 /*  1770 */  1482,  169,  177,  461,  179,  462,  107, 1399,  445,  568,
-
 /*  1780 */   567,  410,  180, 1013,  495,  181,  308,  557, 1013, 1013,
-
 /*  1790 */  1015, 1016,   27,  182,   35,  235,  100,  558,  398,    4,
-
 /*  1800 */    96, 1405, 1404,   36,  484,  469, 1407,  188,  401, 1471,
-
 /*  1810 */   451,   89, 1493,  561,  239, 1013, 1013, 1015, 1016,   27,
-
 /*  1820 */   490,  338,  270,  241,  192,  342,  493,  242,  403, 1249,
-
 /*  1830 */   243,  511,  432, 1297, 1306,   91,  445, 1305, 1304,  879,
-
 /*  1840 */   217,  434,  435, 1570, 1276, 1602,  520, 1601,  555,  301,
-
 /*  1850 */   527,  404, 1275,  302,  356, 1274, 1600,   95, 1347,  366,
-
 /*  1860 */  1296,  362, 1348,  368,  256,  257, 1556, 1555,  438, 1346,
-
 /*  1870 */   370,  126, 1345,   10, 1371,  546,  381, 1023,  102, 1457,
-
 /*  1880 */    97,  530,   34,  106,  106,  570, 1180,  372,  265, 1329,
-
 /*  1890 */   379,  107,  203,  445,  568,  567, 1328,  385, 1013, 1370,
-
 /*  1900 */   386,  267,  268,  571, 1244,  161, 1239,  162, 1509, 1510,
-
 /*  1910 */  1508,  143, 1507,  299,  832,  213,  214,   78,  446,  205,
-
 /*  1920 */   310,  306,  163,  224, 1084,  140, 1082,  318,  165,  176,
-
 /*  1930 */  1013, 1013, 1015, 1016,   27,  178, 1206,  231,  911,  234,
-
 /*  1940 */   326, 1098,  183,  421,  166,  167,  411,  185,   85,  423,
-
 /*  1950 */   412,   86,  174,   87,  168,   88, 1101,  236, 1097,  237,
-
 /*  1960 */   154,   18,  238,  254,  337, 1219,  489, 1090,  240,  190,
-
 /*  1970 */    37,  847,  189,  494,  358,  244,  350,  506,  191,  877,
-
 /*  1980 */    90,  498,   19,   20,  503,   92,  353,  890,  300,  170,
-
 /*  1990 */   155,   93,  513,   94, 1168,  156, 1050, 1137,   39,  218,
-
 /*  2000 */   273,  275, 1136,  960,  194,  955,  110, 1154, 1158,  253,
-
 /*  2010 */     7, 1162, 1156,   21,   22, 1161, 1142,   23,   24,   25,
-
 /*  2020 */    33,  542,   26,  260,  197,   98, 1065, 1051, 1049, 1053,
-
 /*  2030 */  1107, 1054, 1106,  259,   28,   40,  562, 1018,  859,  109,
-
 /*  2040 */    29,  921,  390, 1176,  172,  139, 1175, 1235,  261, 1235,
-
 /*  2050 */  1235, 1235, 1235, 1235, 1235, 1235, 1235,  262, 1235, 1235,
-
 /*  2060 */  1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1593, 1592,
+
 /*     0 */   568,  208,  568,  118,  115,  229,  568,  118,  115,  229,
+
 /*    10 */   568, 1314,  377, 1293,  408,  562,  562,  562,  568,  409,
+
 /*    20 */   378, 1314, 1276,   41,   41,   41,   41,  208, 1526,   71,
+
 /*    30 */    71,  971,  419,   41,   41,  491,  303,  279,  303,  972,
+
 /*    40 */   397,   71,   71,  125,  126,   80, 1217, 1217, 1050, 1053,
+
 /*    50 */  1040, 1040,  123,  123,  124,  124,  124,  124,  476,  409,
+
 /*    60 */  1241,    1,    1,  575,    2, 1245,  550,  118,  115,  229,
+
 /*    70 */   317,  480,  146,  480,  524,  118,  115,  229,  529, 1327,
+
 /*    80 */   417,  523,  142,  125,  126,   80, 1217, 1217, 1050, 1053,
+
 /*    90 */  1040, 1040,  123,  123,  124,  124,  124,  124,  118,  115,
+
 /*   100 */   229,  327,  122,  122,  122,  122,  121,  121,  120,  120,
+
 /*   110 */   120,  119,  116,  444,  284,  284,  284,  284,  442,  442,
+
 /*   120 */   442, 1567,  376, 1569, 1192,  375, 1163,  565, 1163,  565,
+
 /*   130 */   409, 1567,  537,  259,  226,  444,  101,  145,  449,  316,
+
 /*   140 */   559,  240,  122,  122,  122,  122,  121,  121,  120,  120,
+
 /*   150 */   120,  119,  116,  444,  125,  126,   80, 1217, 1217, 1050,
+
 /*   160 */  1053, 1040, 1040,  123,  123,  124,  124,  124,  124,  142,
+
 /*   170 */   294, 1192,  339,  448,  120,  120,  120,  119,  116,  444,
+
 /*   180 */   127, 1192, 1193, 1194,  148,  441,  440,  568,  119,  116,
+
 /*   190 */   444,  124,  124,  124,  124,  117,  122,  122,  122,  122,
+
 /*   200 */   121,  121,  120,  120,  120,  119,  116,  444,  454,  113,
+
 /*   210 */    13,   13,  546,  122,  122,  122,  122,  121,  121,  120,
+
 /*   220 */   120,  120,  119,  116,  444,  422,  316,  559, 1192, 1193,
+
 /*   230 */  1194,  149, 1224,  409, 1224,  124,  124,  124,  124,  122,
+
 /*   240 */   122,  122,  122,  121,  121,  120,  120,  120,  119,  116,
+
 /*   250 */   444,  465,  342, 1037, 1037, 1051, 1054,  125,  126,   80,
+
 /*   260 */  1217, 1217, 1050, 1053, 1040, 1040,  123,  123,  124,  124,
+
 /*   270 */   124,  124, 1279,  522,  222, 1192,  568,  409,  224,  514,
+
 /*   280 */   175,   82,   83,  122,  122,  122,  122,  121,  121,  120,
+
 /*   290 */   120,  120,  119,  116,  444, 1007,   16,   16, 1192,  133,
+
 /*   300 */   133,  125,  126,   80, 1217, 1217, 1050, 1053, 1040, 1040,
+
 /*   310 */   123,  123,  124,  124,  124,  124,  122,  122,  122,  122,
+
 /*   320 */   121,  121,  120,  120,  120,  119,  116,  444, 1041,  546,
+
 /*   330 */  1192,  373, 1192, 1193, 1194,  252, 1434,  399,  504,  501,
+
 /*   340 */   500,  111,  560,  566,    4,  926,  926,  433,  499,  340,
+
 /*   350 */   460,  328,  360,  394, 1237, 1192, 1193, 1194,  563,  568,
+
 /*   360 */   122,  122,  122,  122,  121,  121,  120,  120,  120,  119,
+
 /*   370 */   116,  444,  284,  284,  369, 1580, 1607,  441,  440,  154,
+
 /*   380 */   409,  445,   71,   71, 1286,  565, 1221, 1192, 1193, 1194,
+
 /*   390 */    85, 1223,  271,  557,  543,  515, 1561,  568,   98, 1222,
+
 /*   400 */     6, 1278,  472,  142,  125,  126,   80, 1217, 1217, 1050,
+
 /*   410 */  1053, 1040, 1040,  123,  123,  124,  124,  124,  124,  550,
+
 /*   420 */    13,   13, 1027,  507, 1224, 1192, 1224,  549,  109,  109,
+
 /*   430 */   222,  568, 1238,  175,  568,  427,  110,  197,  445,  570,
+
 /*   440 */   569,  430, 1552, 1017,  325,  551, 1192,  270,  287,  368,
+
 /*   450 */   510,  363,  509,  257,   71,   71,  543,   71,   71,  359,
+
 /*   460 */   316,  559, 1613,  122,  122,  122,  122,  121,  121,  120,
+
 /*   470 */   120,  120,  119,  116,  444, 1017, 1017, 1019, 1020,   27,
+
 /*   480 */   284,  284, 1192, 1193, 1194, 1158,  568, 1612,  409,  901,
+
 /*   490 */   190,  550,  356,  565,  550,  937,  533,  517, 1158,  516,
+
 /*   500 */   413, 1158,  552, 1192, 1193, 1194,  568,  544, 1554,   51,
+
 /*   510 */    51,  214,  125,  126,   80, 1217, 1217, 1050, 1053, 1040,
+
 /*   520 */  1040,  123,  123,  124,  124,  124,  124, 1192,  474,  135,
+
 /*   530 */   135,  409,  284,  284, 1490,  505,  121,  121,  120,  120,
+
 /*   540 */   120,  119,  116,  444, 1007,  565,  518,  217,  541, 1561,
+
 /*   550 */   316,  559,  142,    6,  532,  125,  126,   80, 1217, 1217,
+
 /*   560 */  1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,  124,
+
 /*   570 */  1555,  122,  122,  122,  122,  121,  121,  120,  120,  120,
+
 /*   580 */   119,  116,  444,  485, 1192, 1193, 1194,  482,  281, 1267,
+
 /*   590 */   957,  252, 1192,  373,  504,  501,  500, 1192,  340,  571,
+
 /*   600 */  1192,  571,  409,  292,  499,  957,  876,  191,  480,  316,
+
 /*   610 */   559,  384,  290,  380,  122,  122,  122,  122,  121,  121,
+
 /*   620 */   120,  120,  120,  119,  116,  444,  125,  126,   80, 1217,
+
 /*   630 */  1217, 1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,
+
 /*   640 */   124,  409,  394, 1136, 1192,  869,  100,  284,  284, 1192,
+
 /*   650 */  1193, 1194,  373, 1093, 1192, 1193, 1194, 1192, 1193, 1194,
+
 /*   660 */   565,  455,   32,  373,  233,  125,  126,   80, 1217, 1217,
+
 /*   670 */  1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,  124,
+
 /*   680 */  1433,  959,  568,  228,  958,  122,  122,  122,  122,  121,
+
 /*   690 */   121,  120,  120,  120,  119,  116,  444, 1158,  228, 1192,
+
 /*   700 */   157, 1192, 1193, 1194, 1553,   13,   13,  301,  957, 1232,
+
 /*   710 */  1158,  153,  409, 1158,  373, 1583, 1176,    5,  369, 1580,
+
 /*   720 */   429, 1238,    3,  957,  122,  122,  122,  122,  121,  121,
+
 /*   730 */   120,  120,  120,  119,  116,  444,  125,  126,   80, 1217,
+
 /*   740 */  1217, 1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,
+
 /*   750 */   124,  409,  208,  567, 1192, 1028, 1192, 1193, 1194, 1192,
+
 /*   760 */   388,  852,  155, 1552,  286,  402, 1098, 1098,  488,  568,
+
 /*   770 */   465,  342, 1319, 1319, 1552,  125,  126,   80, 1217, 1217,
+
 /*   780 */  1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,  124,
+
 /*   790 */   129,  568,   13,   13,  374,  122,  122,  122,  122,  121,
+
 /*   800 */   121,  120,  120,  120,  119,  116,  444,  302,  568,  453,
+
 /*   810 */   528, 1192, 1193, 1194,   13,   13, 1192, 1193, 1194, 1297,
+
 /*   820 */   463, 1267,  409, 1317, 1317, 1552, 1012,  453,  452,  200,
+
 /*   830 */   299,   71,   71, 1265,  122,  122,  122,  122,  121,  121,
+
 /*   840 */   120,  120,  120,  119,  116,  444,  125,  126,   80, 1217,
+
 /*   850 */  1217, 1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,
+
 /*   860 */   124,  409,  227, 1073, 1158,  284,  284,  419,  312,  278,
+
 /*   870 */   278,  285,  285, 1419,  406,  405,  382, 1158,  565,  568,
+
 /*   880 */  1158, 1196,  565, 1600,  565,  125,  126,   80, 1217, 1217,
+
 /*   890 */  1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,  124,
+
 /*   900 */   453, 1482,   13,   13, 1536,  122,  122,  122,  122,  121,
+
 /*   910 */   121,  120,  120,  120,  119,  116,  444,  201,  568,  354,
+
 /*   920 */  1586,  575,    2, 1245,  840,  841,  842, 1562,  317, 1212,
+
 /*   930 */   146,    6,  409,  255,  254,  253,  206, 1327,    9, 1196,
+
 /*   940 */   262,   71,   71,  424,  122,  122,  122,  122,  121,  121,
+
 /*   950 */   120,  120,  120,  119,  116,  444,  125,  126,   80, 1217,
+
 /*   960 */  1217, 1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,
+
 /*   970 */   124,  568,  284,  284,  568, 1213,  409,  574,  313, 1245,
+
 /*   980 */   349, 1296,  352,  419,  317,  565,  146,  491,  525, 1643,
+
 /*   990 */   395,  371,  491, 1327,   70,   70, 1295,   71,   71,  240,
+
 /*  1000 */  1325,  104,   80, 1217, 1217, 1050, 1053, 1040, 1040,  123,
+
 /*  1010 */   123,  124,  124,  124,  124,  122,  122,  122,  122,  121,
+
 /*  1020 */   121,  120,  120,  120,  119,  116,  444, 1114,  284,  284,
+
 /*  1030 */   428,  448, 1525, 1213,  439,  284,  284, 1489, 1352,  311,
+
 /*  1040 */   474,  565, 1115,  971,  491,  491,  217, 1263,  565, 1538,
+
 /*  1050 */   568,  972,  207,  568, 1027,  240,  383, 1116,  519,  122,
+
 /*  1060 */   122,  122,  122,  121,  121,  120,  120,  120,  119,  116,
+
 /*  1070 */   444, 1018,  107,   71,   71, 1017,   13,   13,  912,  568,
+
 /*  1080 */  1495,  568,  284,  284,   97,  526,  491,  448,  913, 1326,
+
 /*  1090 */  1322,  545,  409,  284,  284,  565,  151,  209, 1495, 1497,
+
 /*  1100 */   262,  450,   55,   55,   56,   56,  565, 1017, 1017, 1019,
+
 /*  1110 */   443,  332,  409,  527,   12,  295,  125,  126,   80, 1217,
+
 /*  1120 */  1217, 1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,
+
 /*  1130 */   124,  347,  409,  864, 1534, 1213,  125,  126,   80, 1217,
+
 /*  1140 */  1217, 1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,
+
 /*  1150 */   124, 1137, 1641,  474, 1641,  371,  125,  114,   80, 1217,
+
 /*  1160 */  1217, 1050, 1053, 1040, 1040,  123,  123,  124,  124,  124,
+
 /*  1170 */   124, 1495,  329,  474,  331,  122,  122,  122,  122,  121,
+
 /*  1180 */   121,  120,  120,  120,  119,  116,  444,  203, 1419,  568,
+
 /*  1190 */  1294,  864,  464, 1213,  436,  122,  122,  122,  122,  121,
+
 /*  1200 */   121,  120,  120,  120,  119,  116,  444,  553, 1137, 1642,
+
 /*  1210 */   539, 1642,   15,   15,  892,  122,  122,  122,  122,  121,
+
 /*  1220 */   121,  120,  120,  120,  119,  116,  444,  568,  298,  538,
+
 /*  1230 */  1135, 1419, 1559, 1560, 1331,  409,    6,    6, 1169, 1268,
+
 /*  1240 */   415,  320,  284,  284, 1419,  508,  565,  525,  300,  457,
+
 /*  1250 */    43,   43,  568,  893,   12,  565,  330,  478,  425,  407,
+
 /*  1260 */   126,   80, 1217, 1217, 1050, 1053, 1040, 1040,  123,  123,
+
 /*  1270 */   124,  124,  124,  124,  568,   57,   57,  288, 1192, 1419,
+
 /*  1280 */   496,  458,  392,  392,  391,  273,  389, 1135, 1558,  849,
+
 /*  1290 */  1169,  407,    6,  568,  321, 1158,  470,   44,   44, 1557,
+
 /*  1300 */  1114,  426,  234,    6,  323,  256,  540,  256, 1158,  431,
+
 /*  1310 */   568, 1158,  322,   17,  487, 1115,   58,   58,  122,  122,
+
 /*  1320 */   122,  122,  121,  121,  120,  120,  120,  119,  116,  444,
+
 /*  1330 */  1116,  216,  481,   59,   59, 1192, 1193, 1194,  111,  560,
+
 /*  1340 */   324,    4,  236,  456,  526,  568,  237,  456,  568,  437,
+
 /*  1350 */   168,  556,  420,  141,  479,  563,  568,  293,  568, 1095,
+
 /*  1360 */   568,  293,  568, 1095,  531,  568,  872,    8,   60,   60,
+
 /*  1370 */   235,   61,   61,  568,  414,  568,  414,  568,  445,   62,
+
 /*  1380 */    62,   45,   45,   46,   46,   47,   47,  199,   49,   49,
+
 /*  1390 */   557,  568,  359,  568,  100,  486,   50,   50,   63,   63,
+
 /*  1400 */    64,   64,  561,  415,  535,  410,  568, 1027,  568,  534,
+
 /*  1410 */   316,  559,  316,  559,   65,   65,   14,   14,  568, 1027,
+
 /*  1420 */   568,  512,  932,  872, 1018,  109,  109,  931, 1017,   66,
+
 /*  1430 */    66,  131,  131,  110,  451,  445,  570,  569,  416,  177,
+
 /*  1440 */  1017,  132,  132,   67,   67,  568,  467,  568,  932,  471,
+
 /*  1450 */  1364,  283,  226,  931,  315, 1363,  407,  568,  459,  407,
+
 /*  1460 */  1017, 1017, 1019,  239,  407,   86,  213, 1350,   52,   52,
+
 /*  1470 */    68,   68, 1017, 1017, 1019, 1020,   27, 1585, 1180,  447,
+
 /*  1480 */    69,   69,  288,   97,  108, 1541,  106,  392,  392,  391,
+
 /*  1490 */   273,  389,  568,  879,  849,  883,  568,  111,  560,  466,
+
 /*  1500 */     4,  568,  152,   30,   38,  568, 1132,  234,  396,  323,
+
 /*  1510 */   111,  560,  527,    4,  563,   53,   53,  322,  568,  163,
+
 /*  1520 */   163,  568,  337,  468,  164,  164,  333,  563,   76,   76,
+
 /*  1530 */   568,  289, 1514,  568,   31, 1513,  568,  445,  338,  483,
+
 /*  1540 */   100,   54,   54,  344,   72,   72,  296,  236, 1080,  557,
+
 /*  1550 */   445,  879, 1360,  134,  134,  168,   73,   73,  141,  161,
+
 /*  1560 */   161, 1574,  557,  535,  568,  319,  568,  348,  536, 1009,
+
 /*  1570 */   473,  261,  261,  891,  890,  235,  535,  568, 1027,  568,
+
 /*  1580 */   475,  534,  261,  367,  109,  109,  521,  136,  136,  130,
+
 /*  1590 */   130, 1027,  110,  366,  445,  570,  569,  109,  109, 1017,
+
 /*  1600 */   162,  162,  156,  156,  568,  110, 1080,  445,  570,  569,
+
 /*  1610 */   410,  351, 1017,  568,  353,  316,  559,  568,  343,  568,
+
 /*  1620 */   100,  497,  357,  258,  100,  898,  899,  140,  140,  355,
+
 /*  1630 */  1310, 1017, 1017, 1019, 1020,   27,  139,  139,  362,  451,
+
 /*  1640 */   137,  137,  138,  138, 1017, 1017, 1019, 1020,   27, 1180,
+
 /*  1650 */   447,  568,  372,  288,  111,  560, 1021,    4,  392,  392,
+
 /*  1660 */   391,  273,  389,  568, 1141,  849,  568, 1076,  568,  258,
+
 /*  1670 */   492,  563,  568,  211,   75,   75,  555,  962,  234,  261,
+
 /*  1680 */   323,  111,  560,  929,    4,  113,   77,   77,  322,   74,
+
 /*  1690 */    74,   42,   42, 1373,  445,   48,   48, 1418,  563,  974,
+
 /*  1700 */   975, 1092, 1091, 1092, 1091,  862,  557,  150,  930, 1346,
+
 /*  1710 */   113, 1358,  554, 1424, 1021, 1275, 1266, 1254,  236, 1253,
+
 /*  1720 */  1255,  445, 1593, 1343,  308,  276,  168,  309,   11,  141,
+
 /*  1730 */   393,  310,  232,  557, 1405, 1027,  335,  291, 1400,  219,
+
 /*  1740 */   336,  109,  109,  936,  297, 1410,  235,  341,  477,  110,
+
 /*  1750 */   502,  445,  570,  569, 1393, 1409, 1017,  400, 1293,  365,
+
 /*  1760 */   223, 1486, 1027, 1485, 1355, 1356, 1354, 1353,  109,  109,
+
 /*  1770 */   204, 1596, 1232,  558,  265,  218,  110,  205,  445,  570,
+
 /*  1780 */   569,  410,  387, 1017, 1533,  179,  316,  559, 1017, 1017,
+
 /*  1790 */  1019, 1020,   27,  230, 1531, 1229,   79,  560,   85,    4,
+
 /*  1800 */   418,  215,  548,   81,   84,  188, 1406,  173,  181,  461,
+
 /*  1810 */   451,   35,  462,  563,  183, 1017, 1017, 1019, 1020,   27,
+
 /*  1820 */   184, 1491,  185,  186,  495,  242,   98,  398, 1412,   36,
+
 /*  1830 */  1411,  484,   91,  469,  401, 1414,  445,  192, 1480,  246,
+
 /*  1840 */  1502,  490,  346,  277,  248,  196,  493,  511,  557,  350,
+
 /*  1850 */  1256,  249,  250,  403, 1313, 1312,  111,  560,  432,    4,
+
 /*  1860 */  1311, 1304,   93, 1611,  883, 1610,  224,  404,  434,  520,
+
 /*  1870 */   263,  435, 1579,  563, 1283, 1282,  364, 1027,  306, 1281,
+
 /*  1880 */   264, 1609, 1565,  109,  109,  370, 1303,  307, 1564,  438,
+
 /*  1890 */   128,  110, 1378,  445,  570,  569,  445,  546, 1017,   10,
+
 /*  1900 */  1466,  105,  381, 1377,   34,  572,   99, 1336,  557,  314,
+
 /*  1910 */  1186,  530,  272,  274,  379,  210, 1335,  547,  385,  386,
+
 /*  1920 */   275,  573, 1251, 1246,  411,  412, 1518,  165,  178, 1519,
+
 /*  1930 */  1017, 1017, 1019, 1020,   27, 1517, 1516, 1027,   78,  147,
+
 /*  1940 */   166,  220,  221,  109,  109,  836,  304,  167,  446,  212,
+
 /*  1950 */   318,  110,  231,  445,  570,  569,  144, 1090, 1017, 1088,
+
 /*  1960 */   326,  180,  169, 1212,  182,  334,  238,  915,  241, 1104,
+
 /*  1970 */   187,  170,  171,  421,   87,   88,  423,  189,   89,   90,
+
 /*  1980 */   172, 1107,  243, 1103,  244,  158,   18,  245,  345,  247,
+
 /*  1990 */  1017, 1017, 1019, 1020,   27,  261, 1096,  193, 1226,  489,
+
 /*  2000 */   194,   37,  366,  851,  494,  251,  195,  506,   92,   19,
+
 /*  2010 */   498,  358,   20,  503,  881,  361,   94,  894,  305,  159,
+
 /*  2020 */   513,   39,   95, 1174,  160, 1056,  966, 1143,   96,  174,
+
 /*  2030 */  1142,  225,  280,  282,  198,  960,  113, 1164, 1160,  260,
+
 /*  2040 */    21,   22,   23, 1162, 1168, 1167, 1148,   24,   33,   25,
+
 /*  2050 */   202,  542,   26,  100, 1071,  102, 1057,  103,    7, 1055,
+
 /*  2060 */  1059, 1113, 1060, 1112,  266,  267,   28,   40,  390, 1022,
+
 /*  2070 */   863,  112,   29,  564, 1182, 1181,  268,  176,  143,  925,
+
 /*  2080 */  1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242, 1242,
+
 /*  2090 */  1242, 1242, 1242, 1242,  269, 1602, 1242, 1601,
};
static const YYCODETYPE yy_lookahead[] = {
-
 /*     0 */   193,  223,  193,  225,  193,  193,  193,  274,  275,  276,
-
 /*    10 */   193,  233,  219,  193,  274,  275,  276,  206,  206,   19,
-
 /*    20 */   193,  219,  216,  216,  217,  216,  217,  193,  295,  216,
-
 /*    30 */   217,   31,  205,  216,  217,  193,  216,  217,  213,   39,
-
 /*    40 */   228,  193,  230,   43,   44,   45,   46,   47,   48,   49,
+
 /*     0 */   193,  193,  193,  274,  275,  276,  193,  274,  275,  276,
+
 /*    10 */   193,  223,  219,  225,  206,  210,  211,  212,  193,   19,
+
 /*    20 */   219,  233,  216,  216,  217,  216,  217,  193,  295,  216,
+
 /*    30 */   217,   31,  193,  216,  217,  193,  228,  213,  230,   39,
+
 /*    40 */   206,  216,  217,   43,   44,   45,   46,   47,   48,   49,
 /*    50 */    50,   51,   52,   53,   54,   55,   56,   57,  193,   19,
 /*    60 */   185,  186,  187,  188,  189,  190,  253,  274,  275,  276,
-
 /*    70 */   195,  193,  197,  253,  216,  262,  274,  275,  276,  204,
-
 /*    80 */   238,  204,  262,   43,   44,   45,   46,   47,   48,   49,
-
 /*    90 */    50,   51,   52,   53,   54,   55,   56,   57,  264,  274,
-
 /*   100 */   275,  276,  102,  103,  104,  105,  106,  107,  108,  109,
+
 /*    70 */   195,  193,  197,  193,  261,  274,  275,  276,  253,  204,
+
 /*    80 */   238,  204,   81,   43,   44,   45,   46,   47,   48,   49,
+
 /*    90 */    50,   51,   52,   53,   54,   55,   56,   57,  274,  275,
+
 /*   100 */   276,  262,  102,  103,  104,  105,  106,  107,  108,  109,
 /*   110 */   110,  111,  112,  113,  239,  240,  239,  240,  210,  211,
 /*   120 */   212,  314,  315,  314,   59,  316,   86,  252,   88,  252,
-
 /*   130 */    19,  314,  315,  256,  257,  309,   25,   72,  296,  313,
-
 /*   140 */   193,  266,  102,  103,  104,  105,  106,  107,  108,  109,
+
 /*   130 */    19,  314,  315,  256,  257,  113,   25,   72,  296,  138,
+
 /*   140 */   139,  266,  102,  103,  104,  105,  106,  107,  108,  109,
 /*   150 */   110,  111,  112,  113,   43,   44,   45,   46,   47,   48,
 /*   160 */    49,   50,   51,   52,   53,   54,   55,   56,   57,   81,
-
 /*   170 */   292,   59,  307,  298,  108,  109,  110,  111,  112,  113,
-
 /*   180 */    69,  116,  117,  118,   72,  128,  129,  193,  241,   22,
+
 /*   170 */   292,   59,  292,  298,  108,  109,  110,  111,  112,  113,
+
 /*   180 */    69,  116,  117,  118,   72,  106,  107,  193,  111,  112,
 /*   190 */   113,   54,   55,   56,   57,   58,  102,  103,  104,  105,
-
 /*   200 */   106,  107,  108,  109,  110,  111,  112,  113,  120,  193,
-
 /*   210 */   216,  217,   25,  102,  103,  104,  105,  106,  107,  108,
+
 /*   200 */   106,  107,  108,  109,  110,  111,  112,  113,  120,   25,
+
 /*   210 */   216,  217,  145,  102,  103,  104,  105,  106,  107,  108,
 /*   220 */   109,  110,  111,  112,  113,  231,  138,  139,  116,  117,
-
 /*   230 */   118,  106,  107,   19,  216,   54,   55,   56,   57,  102,
+
 /*   230 */   118,  164,  153,   19,  155,   54,   55,   56,   57,  102,
 /*   240 */   103,  104,  105,  106,  107,  108,  109,  110,  111,  112,
-
 /*   250 */   113,  304,   25,   46,   47,   48,   49,   43,   44,   45,
+
 /*   250 */   113,  128,  129,   46,   47,   48,   49,   43,   44,   45,
 /*   260 */    46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
-
 /*   270 */    56,   57,  193,  106,  107,   59,  193,   19,  153,  263,
-
 /*   280 */   155,   67,   24,  102,  103,  104,  105,  106,  107,  108,
-
 /*   290 */   109,  110,  111,  112,  113,  216,  217,   59,  230,  216,
+
 /*   270 */    56,   57,  216,  193,   25,   59,  193,   19,  165,  166,
+
 /*   280 */   193,   67,   24,  102,  103,  104,  105,  106,  107,  108,
+
 /*   290 */   109,  110,  111,  112,  113,   73,  216,  217,   59,  216,
 /*   300 */   217,   43,   44,   45,   46,   47,   48,   49,   50,   51,
 /*   310 */    52,   53,   54,   55,   56,   57,  102,  103,  104,  105,
-
 /*   320 */   106,  107,  108,  109,  110,  111,  112,  113,  121,  142,
-
 /*   330 */    59,  193,  116,  117,  118,  119,  253,  204,  122,  123,
-
 /*   340 */   124,   19,   20,   81,   22,  262,  108,   19,  132,  165,
-
 /*   350 */   166,  193,   24,  126,  116,  117,  118,  278,   36,  193,
+
 /*   320 */   106,  107,  108,  109,  110,  111,  112,  113,  121,  145,
+
 /*   330 */    59,  193,  116,  117,  118,  119,  273,  204,  122,  123,
+
 /*   340 */   124,   19,   20,  134,   22,  136,  137,   19,  132,  127,
+
 /*   350 */   128,  129,   24,   22,   23,  116,  117,  118,   36,  193,
 /*   360 */   102,  103,  104,  105,  106,  107,  108,  109,  110,  111,
-
 /*   370 */   112,  113,  239,  240,  216,  217,  215,  106,  107,  241,
+
 /*   370 */   112,  113,  239,  240,  311,  312,  215,  106,  107,  241,
 /*   380 */    19,   59,  216,  217,  223,  252,  115,  116,  117,  118,
-
 /*   390 */    73,  120,   26,   71,  193,   22,  193,  231,   81,  128,
-
 /*   400 */   138,  139,  269,   81,   43,   44,   45,   46,   47,   48,
-
 /*   410 */    49,   50,   51,   52,   53,   54,   55,   56,   57,  216,
-
 /*   420 */   217,  198,  100,   95,  153,   59,  155,  193,  106,  107,
-
 /*   430 */   235,  236,   59,  193,  193,  249,  114,  251,  116,  117,
-
 /*   440 */   118,  113,  304,  121,  127,  204,  193,  119,  120,  121,
-
 /*   450 */   122,  123,  124,  125,  193,  138,  139,  216,  217,  131,
-
 /*   460 */   138,  139,  193,  102,  103,  104,  105,  106,  107,  108,
+
 /*   390 */   151,  120,   26,   71,  193,  308,  309,  193,  149,  128,
+
 /*   400 */   313,  216,  269,   81,   43,   44,   45,   46,   47,   48,
+
 /*   410 */    49,   50,   51,   52,   53,   54,   55,   56,   57,  253,
+
 /*   420 */   216,  217,  100,   95,  153,   59,  155,  261,  106,  107,
+
 /*   430 */    25,  193,  101,  193,  193,  231,  114,   25,  116,  117,
+
 /*   440 */   118,  113,  304,  121,  193,  204,   59,  119,  120,  121,
+
 /*   450 */   122,  123,  124,  125,  216,  217,  193,  216,  217,  131,
+
 /*   460 */   138,  139,  230,  102,  103,  104,  105,  106,  107,  108,
 /*   470 */   109,  110,  111,  112,  113,  153,  154,  155,  156,  157,
-
 /*   480 */   239,  240,  116,  117,  118,   76,  193,  193,   19,  116,
-
 /*   490 */   117,  118,   23,  252,  253,  193,   87,  204,   89,  238,
-
 /*   500 */   193,   92,  268,  262,  281,  203,  193,  205,  285,  216,
+
 /*   480 */   239,  240,  116,  117,  118,   76,  193,   23,   19,   25,
+
 /*   490 */    22,  253,   23,  252,  253,  108,   87,  204,   89,  261,
+
 /*   500 */   198,   92,  261,  116,  117,  118,  193,  306,  307,  216,
 /*   510 */   217,  150,   43,   44,   45,   46,   47,   48,   49,   50,
-
 /*   520 */    51,   52,   53,   54,   55,   56,   57,  193,  193,  216,
-
 /*   530 */   217,   19,  239,  240,   59,   23,  106,  107,  108,  109,
-
 /*   540 */   110,  111,  112,  113,  231,  252,  253,  193,  308,  309,
-
 /*   550 */   193,  145,   59,  313,  145,   43,   44,   45,   46,   47,
+
 /*   520 */    51,   52,   53,   54,   55,   56,   57,   59,  193,  216,
+
 /*   530 */   217,   19,  239,  240,  283,   23,  106,  107,  108,  109,
+
 /*   540 */   110,  111,  112,  113,   73,  252,  253,  142,  308,  309,
+
 /*   550 */   138,  139,   81,  313,  145,   43,   44,   45,   46,   47,
 /*   560 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
-
 /*   570 */   164,  102,  103,  104,  105,  106,  107,  108,  109,  110,
-
 /*   580 */   111,  112,  113,  119,  193,  193,  122,  123,  124,  193,
-
 /*   590 */   283,  116,  117,  118,  235,  236,  132,   59,  241,  264,
-
 /*   600 */    59,  193,   19,   23,  193,   25,   23,  216,  217,  116,
-
 /*   610 */   117,  118,  216,  217,  102,  103,  104,  105,  106,  107,
+
 /*   570 */   307,  102,  103,  104,  105,  106,  107,  108,  109,  110,
+
 /*   580 */   111,  112,  113,  281,  116,  117,  118,  285,   23,  193,
+
 /*   590 */    25,  119,   59,  193,  122,  123,  124,   59,  127,  203,
+
 /*   600 */    59,  205,   19,  268,  132,   25,   23,   22,  193,  138,
+
 /*   610 */   139,  249,  204,  251,  102,  103,  104,  105,  106,  107,
 /*   620 */   108,  109,  110,  111,  112,  113,   43,   44,   45,   46,
 /*   630 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
-
 /*   640 */    57,   19,  308,  309,  151,   23,   25,  313,  135,  253,
-
 /*   650 */    21,  193,  241,  140,  116,  117,  118,  116,  117,  118,
-
 /*   660 */   268,  304,   22,  301,  302,   43,   44,   45,   46,   47,
+
 /*   640 */    57,   19,   22,   23,   59,   23,   25,  239,  240,  116,
+
 /*   650 */   117,  118,  193,   11,  116,  117,  118,  116,  117,  118,
+
 /*   660 */   252,  269,   22,  193,   15,   43,   44,   45,   46,   47,
 /*   670 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
-
 /*   680 */   193,  143,  193,  193,  143,  102,  103,  104,  105,  106,
+
 /*   680 */   273,  143,  193,  118,  143,  102,  103,  104,  105,  106,
 /*   690 */   107,  108,  109,  110,  111,  112,  113,   76,  118,   59,
-
 /*   700 */   292,  211,  212,  216,  217,  216,  217,   73,  193,   80,
-
 /*   710 */    89,   25,   19,   92,  193,  304,   23,   22,  231,  193,
-
 /*   720 */   231,  193,   22,  143,  102,  103,  104,  105,  106,  107,
+
 /*   700 */   241,  116,  117,  118,  304,  216,  217,  292,  143,   60,
+
 /*   710 */    89,  241,   19,   92,  193,  193,   23,   22,  311,  312,
+
 /*   720 */   231,  101,   22,  143,  102,  103,  104,  105,  106,  107,
 /*   730 */   108,  109,  110,  111,  112,  113,   43,   44,   45,   46,
 /*   740 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
-
 /*   750 */    57,   19,  123,  193,   59,   23,  116,  117,  118,   59,
-
 /*   760 */   193,  127,  128,  129,  306,  307,  210,  211,  212,  193,
-
 /*   770 */    22,  111,  112,  113,  284,   43,   44,   45,   46,   47,
+
 /*   750 */    57,   19,  193,  193,   59,   23,  116,  117,  118,   59,
+
 /*   760 */   201,   21,  241,  304,   22,  206,  127,  128,  129,  193,
+
 /*   770 */   128,  129,  235,  236,  304,   43,   44,   45,   46,   47,
 /*   780 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
-
 /*   790 */   161,  193,  216,  217,  268,  102,  103,  104,  105,  106,
-
 /*   800 */   107,  108,  109,  110,  111,  112,  113,   59,  193,  193,
-
 /*   810 */   193,  116,  117,  118,  216,  217,  116,  117,  118,  304,
-
 /*   820 */   239,  240,   19,  263,  138,  139,   23,  211,  212,  231,
-
 /*   830 */   263,  216,  217,  252,  102,  103,  104,  105,  106,  107,
+
 /*   790 */    22,  193,  216,  217,  193,  102,  103,  104,  105,  106,
+
 /*   800 */   107,  108,  109,  110,  111,  112,  113,  231,  193,  193,
+
 /*   810 */   193,  116,  117,  118,  216,  217,  116,  117,  118,  226,
+
 /*   820 */    80,  193,   19,  235,  236,  304,   23,  211,  212,  231,
+
 /*   830 */   204,  216,  217,  205,  102,  103,  104,  105,  106,  107,
 /*   840 */   108,  109,  110,  111,  112,  113,   43,   44,   45,   46,
 /*   850 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
-
 /*   860 */    57,   19,  193,   11,  116,  117,  118,  240,  253,  193,
-
 /*   870 */   201,  239,  240,  193,  134,  206,  136,  137,  193,  252,
-
 /*   880 */   193,  264,  193,  193,  252,   43,   44,   45,   46,   47,
+
 /*   860 */    57,   19,  193,  123,   76,  239,  240,  193,  253,  239,
+
 /*   870 */   240,  239,  240,  193,  106,  107,  193,   89,  252,  193,
+
 /*   880 */    92,   59,  252,  141,  252,   43,   44,   45,   46,   47,
 /*   890 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
-
 /*   900 */   284,  216,  217,  216,  217,  102,  103,  104,  105,  106,
-
 /*   910 */   107,  108,  109,  110,  111,  112,  113,  193,  231,  193,
-
 /*   920 */   187,  188,  189,  190,  127,  128,  129,  238,  195,  193,
-
 /*   930 */   197,   16,   19,    7,    8,    9,  193,  204,  253,  193,
-
 /*   940 */   216,  217,  216,  217,  102,  103,  104,  105,  106,  107,
+
 /*   900 */   284,  161,  216,  217,  193,  102,  103,  104,  105,  106,
+
 /*   910 */   107,  108,  109,  110,  111,  112,  113,  231,  193,   16,
+
 /*   920 */   187,  188,  189,  190,    7,    8,    9,  309,  195,   25,
+
 /*   930 */   197,  313,   19,  127,  128,  129,  262,  204,   22,  117,
+
 /*   940 */    24,  216,  217,  263,  102,  103,  104,  105,  106,  107,
 /*   950 */   108,  109,  110,  111,  112,  113,   43,   44,   45,   46,
 /*   960 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
-
 /*   970 */    57,  213,  239,  240,  193,   76,   19,  188,  232,  190,
-
 /*   980 */   128,  129,  292,  193,  195,  252,  197,   46,   89,  138,
-
 /*   990 */   139,   92,   77,  204,   79,  193,  269,  216,  217,  266,
+
 /*   970 */    57,  193,  239,  240,  193,   59,   19,  188,  253,  190,
+
 /*   980 */    77,  226,   79,  193,  195,  252,  197,  193,   19,  301,
+
 /*   990 */   302,  193,  193,  204,  216,  217,  226,  216,  217,  266,
 /*  1000 */   204,  159,   45,   46,   47,   48,   49,   50,   51,   52,
 /*  1010 */    53,   54,   55,   56,   57,  102,  103,  104,  105,  106,
 /*  1020 */   107,  108,  109,  110,  111,  112,  113,   12,  239,  240,
-
 /*  1030 */   193,  298,   22,   23,  253,  239,  240,  127,  128,  129,
-
 /*  1040 */   238,  252,   27,  193,  286,  204,  193,  204,  252,  291,
-
 /*  1050 */   193,  273,   22,   23,  100,  266,  115,   42,  268,  102,
+
 /*  1030 */   232,  298,  238,  117,  253,  239,  240,  238,  259,  260,
+
 /*  1040 */   193,  252,   27,   31,  193,  193,  142,  204,  252,  193,
+
 /*  1050 */   193,   39,  262,  193,  100,  266,  278,   42,  204,  102,
 /*  1060 */   103,  104,  105,  106,  107,  108,  109,  110,  111,  112,
-
 /*  1070 */   113,  117,  159,  216,  217,  121,  161,   19,   63,  193,
-
 /*  1080 */   239,  240,  239,  240,   12,  208,  209,  298,   73,  311,
-
 /*  1090 */   312,  238,   19,  252,   25,  252,   22,   24,   24,   27,
-
 /*  1100 */   193,  264,  216,  217,   46,  208,  209,  153,  154,  155,
-
 /*  1110 */   253,  101,   19,   23,   42,   25,   43,   44,   45,   46,
+
 /*  1070 */   113,  117,  159,  216,  217,  121,  216,  217,   63,  193,
+
 /*  1080 */   193,  193,  239,  240,  115,  116,  193,  298,   73,  238,
+
 /*  1090 */   238,  231,   19,  239,  240,  252,   22,   24,  211,  212,
+
 /*  1100 */    24,  193,  216,  217,  216,  217,  252,  153,  154,  155,
+
 /*  1110 */   253,   16,   19,  144,  213,  268,   43,   44,   45,   46,
 /*  1120 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
-
 /*  1130 */    57,  101,   19,   59,   25,   63,   43,   44,   45,   46,
+
 /*  1130 */    57,  238,   19,   59,  193,   59,   43,   44,   45,   46,
 /*  1140 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
-
 /*  1150 */    57,   22,   23,  115,   25,   24,   43,   44,   45,   46,
+
 /*  1150 */    57,   22,   23,  193,   25,  193,   43,   44,   45,   46,
 /*  1160 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
-
 /*  1170 */    57,   22,   23,  115,   25,  102,  103,  104,  105,  106,
-
 /*  1180 */   107,  108,  109,  110,  111,  112,  113,  118,  150,  131,
-
 /*  1190 */    59,  117,   22,  273,  193,  102,  103,  104,  105,  106,
-
 /*  1200 */   107,  108,  109,  110,  111,  112,  113,  204,   66,  204,
-
 /*  1210 */    35,  204,  143,  213,  193,  102,  103,  104,  105,  106,
-
 /*  1220 */   107,  108,  109,  110,  111,  112,  113,   85,  193,   59,
-
 /*  1230 */   101,  311,  312,   16,  193,   19,   94,  216,  217,  238,
-
 /*  1240 */   193,   66,  239,  240,  239,  240,  239,  240,  117,   74,
-
 /*  1250 */   101,  216,  217,  193,  193,  252,  193,  252,  149,  252,
+
 /*  1170 */    57,  284,   77,  193,   79,  102,  103,  104,  105,  106,
+
 /*  1180 */   107,  108,  109,  110,  111,  112,  113,  286,  193,  193,
+
 /*  1190 */   193,  117,  291,  117,  232,  102,  103,  104,  105,  106,
+
 /*  1200 */   107,  108,  109,  110,  111,  112,  113,  204,   22,   23,
+
 /*  1210 */    66,   25,  216,  217,   35,  102,  103,  104,  105,  106,
+
 /*  1220 */   107,  108,  109,  110,  111,  112,  113,  193,  268,   85,
+
 /*  1230 */   101,  193,  309,  309,  240,   19,  313,  313,   94,  208,
+
 /*  1240 */   209,  193,  239,  240,  193,   66,  252,   19,  268,  244,
+
 /*  1250 */   216,  217,  193,   74,  213,  252,  161,   19,  263,  254,
 /*  1260 */    44,   45,   46,   47,   48,   49,   50,   51,   52,   53,
-
 /*  1270 */    54,   55,   56,   57,  193,  193,  193,    5,   59,  216,
-
 /*  1280 */   217,   25,   10,   11,   12,   13,   14,  117,  146,   17,
-
 /*  1290 */   193,  291,  193,  232,   77,   76,   79,  216,  217,  216,
-
 /*  1300 */   217,   31,   30,  309,   32,  130,   87,  313,   89,   39,
-
 /*  1310 */   193,   92,   40,  216,  217,  216,  217,  108,  102,  103,
+
 /*  1270 */    54,   55,   56,   57,  193,  216,  217,    5,   59,  193,
+
 /*  1280 */    19,  244,   10,   11,   12,   13,   14,  101,  309,   17,
+
 /*  1290 */   146,  254,  313,  193,  193,   76,  115,  216,  217,  309,
+
 /*  1300 */    12,  263,   30,  313,   32,   46,   87,   46,   89,  130,
+
 /*  1310 */   193,   92,   40,   22,  263,   27,  216,  217,  102,  103,
 /*  1320 */   104,  105,  106,  107,  108,  109,  110,  111,  112,  113,
-
 /*  1330 */   299,  300,  193,  216,  217,  116,  117,  118,   19,   20,
-
 /*  1340 */   193,   22,   70,  309,  135,  193,  264,  313,  193,  140,
-
 /*  1350 */    78,  193,  226,   81,   59,   36,  193,  309,  193,   29,
-
 /*  1360 */   193,  313,  193,   33,  145,  193,   59,   48,  216,  217,
-
 /*  1370 */    98,  216,  217,  193,  216,  217,  193,  244,   59,  216,
-
 /*  1380 */   217,  216,  217,  216,  217,  216,  217,  254,  216,  217,
-
 /*  1390 */    71,  193,  244,  193,  193,   65,  216,  217,  193,  216,
-
 /*  1400 */   217,  145,  254,  244,   85,  133,   15,  100,  193,   90,
-
 /*  1410 */   138,  139,  117,  254,  216,  217,  216,  217,  193,  100,
-
 /*  1420 */   193,  216,  217,  116,  117,  106,  107,   19,  121,  193,
-
 /*  1430 */   193,  216,  217,  114,  162,  116,  117,  118,  244,  244,
-
 /*  1440 */   121,  216,  217,  216,  217,  193,  309,  129,  254,  254,
-
 /*  1450 */   313,   60,  216,  217,   19,  256,  257,  193,  120,  121,
-
 /*  1460 */   153,  154,  155,  149,  150,   25,   24,   99,  216,  217,
-
 /*  1470 */   152,  193,  153,  154,  155,  156,  157,    0,    1,    2,
-
 /*  1480 */   216,  217,    5,   22,  158,   24,  160,   10,   11,   12,
-
 /*  1490 */    13,   14,  193,   23,   17,   25,  193,   19,   20,  193,
-
 /*  1500 */    22,  133,  193,   22,   22,  193,   22,   30,  193,   32,
-
 /*  1510 */    19,   20,  129,   22,   36,  216,  217,   40,  193,  216,
-
 /*  1520 */   217,  193,  216,  217,  116,  216,  217,   36,  216,  217,
-
 /*  1530 */   193,  216,  217,  193,   53,  152,  193,   59,   23,   19,
-
 /*  1540 */    25,  216,  217,   61,  216,  217,   23,   70,   25,   71,
-
 /*  1550 */    59,  116,  193,  216,  217,   78,  216,  217,   81,  216,
-
 /*  1560 */   217,   59,   71,   85,  193,   23,  193,   25,   90,   23,
-
 /*  1570 */    23,   25,   25,    7,    8,   98,   85,  193,  100,  193,
-
 /*  1580 */    59,   90,  142,  141,  106,  107,  193,  216,  217,  216,
-
 /*  1590 */   217,  100,  114,  193,  116,  117,  118,  106,  107,  121,
-
 /*  1600 */   216,  217,  216,  217,  193,  114,  193,  116,  117,  118,
-
 /*  1610 */   133,   23,  121,   25,  121,  138,  139,   97,   23,  117,
-
 /*  1620 */    25,   23,  193,   25,  131,  141,  193,  216,  217,   59,
-
 /*  1630 */   193,  153,  154,  155,  156,  157,  226,  193,  117,  162,
-
 /*  1640 */    23,   23,   25,   25,  153,  154,  155,  156,  157,    1,
-
 /*  1650 */     2,   83,   84,    5,   19,   20,  226,   22,   10,   11,
-
 /*  1660 */    12,   13,   14,  258,  153,   17,  155,  153,   23,  155,
-
 /*  1670 */    25,   36,   23,  193,   25,  255,  193,  236,   30,  193,
-
 /*  1680 */    32,   19,   20,  193,   22,  193,  288,  117,   40,  193,
-
 /*  1690 */   318,  193,  193,  193,   59,  242,  193,  193,   36,  193,
-
 /*  1700 */   193,  193,  287,  255,  255,  255,   71,  255,  243,  214,
-
 /*  1710 */   191,  297,  267,  245,  271,  259,  259,  293,   70,  246,
-
 /*  1720 */   246,   59,  267,  229,  245,  271,   78,  293,  259,   81,
-
 /*  1730 */   271,  271,  220,   71,  225,  100,  219,  219,  249,  196,
-
 /*  1740 */   243,  106,  107,  108,  219,   60,   98,  280,  297,  114,
-
 /*  1750 */   249,  116,  117,  118,  141,  245,  121,  200,  200,  297,
-
 /*  1760 */    38,  200,  100,  151,  150,  294,  294,   22,  106,  107,
-
 /*  1770 */   283,   43,  234,   18,  237,  200,  114,  272,  116,  117,
-
 /*  1780 */   118,  133,  237,  121,   18,  237,  138,  139,  153,  154,
-
 /*  1790 */   155,  156,  157,  237,  270,  199,   19,   20,  246,   22,
-
 /*  1800 */   149,  272,  272,  270,  200,  246,  234,  234,  246,  246,
-
 /*  1810 */   162,  158,  290,   36,  199,  153,  154,  155,  156,  157,
-
 /*  1820 */    62,  289,  200,  199,   22,  200,  221,  199,  221,  200,
-
 /*  1830 */   199,  115,   64,  227,  218,   22,   59,  218,  218,  126,
-
 /*  1840 */   165,   24,  113,  312,  218,  224,  305,  224,   71,  282,
-
 /*  1850 */   144,  221,  220,  282,  218,  218,  218,  115,  261,  260,
-
 /*  1860 */   227,  221,  261,  260,  200,   91,  317,  317,   82,  261,
-
 /*  1870 */   260,  148,  261,   22,  265,  145,  200,  100,  158,  277,
-
 /*  1880 */   147,  146,   25,  106,  107,  202,   13,  260,  194,  250,
-
 /*  1890 */   249,  114,  248,  116,  117,  118,  250,  247,  121,  265,
-
 /*  1900 */   246,  194,    6,  192,  192,  207,  192,  207,  213,  213,
-
 /*  1910 */   213,  222,  213,  222,    4,  214,  214,  213,    3,   22,
-
 /*  1920 */   163,  279,  207,   15,   23,   16,   23,  139,  130,  151,
-
 /*  1930 */   153,  154,  155,  156,  157,  142,   25,   24,   20,  144,
-
 /*  1940 */    16,    1,  142,   61,  130,  130,  303,  151,   53,   37,
-
 /*  1950 */   303,   53,  300,   53,  130,   53,  116,   34,    1,  141,
-
 /*  1960 */     5,   22,  115,   25,  161,   75,   41,   68,  141,  115,
-
 /*  1970 */    24,   20,   68,   19,  131,  125,   23,   96,   22,   59,
-
 /*  1980 */    22,   67,   22,   22,   67,   22,   24,   28,   67,   37,
-
 /*  1990 */    23,  149,   22,   25,   23,   23,   23,   23,   22,  141,
-
 /*  2000 */    23,   23,   97,  116,   22,  143,   25,   88,   75,   34,
-
 /*  2010 */    44,   75,   86,   34,   34,   93,   23,   34,   34,   34,
-
 /*  2020 */    22,   24,   34,   22,   25,   25,   23,   23,   23,   23,
-
 /*  2030 */    23,   11,   23,   25,   22,   22,   25,   23,   23,   22,
-
 /*  2040 */    22,  135,   15,    1,   25,   23,    1,  319,  141,  319,
-
 /*  2050 */   319,  319,  319,  319,  319,  319,  319,  141,  319,  319,
-
 /*  2060 */   319,  319,  319,  319,  319,  319,  319,  319,  141,  141,
-
 /*  2070 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
+
 /*  1330 */    42,  150,  291,  216,  217,  116,  117,  118,   19,   20,
+
 /*  1340 */   193,   22,   70,  260,  116,  193,   24,  264,  193,  263,
+
 /*  1350 */    78,   63,   61,   81,  116,   36,  193,  260,  193,   29,
+
 /*  1360 */   193,  264,  193,   33,  145,  193,   59,   48,  216,  217,
+
 /*  1370 */    98,  216,  217,  193,  115,  193,  115,  193,   59,  216,
+
 /*  1380 */   217,  216,  217,  216,  217,  216,  217,  255,  216,  217,
+
 /*  1390 */    71,  193,  131,  193,   25,   65,  216,  217,  216,  217,
+
 /*  1400 */   216,  217,  208,  209,   85,  133,  193,  100,  193,   90,
+
 /*  1410 */   138,  139,  138,  139,  216,  217,  216,  217,  193,  100,
+
 /*  1420 */   193,  108,  135,  116,  117,  106,  107,  140,  121,  216,
+
 /*  1430 */   217,  216,  217,  114,  162,  116,  117,  118,  299,  300,
+
 /*  1440 */   121,  216,  217,  216,  217,  193,  244,  193,  135,  244,
+
 /*  1450 */   193,  256,  257,  140,  244,  193,  254,  193,  193,  254,
+
 /*  1460 */   153,  154,  155,  141,  254,  149,  150,  258,  216,  217,
+
 /*  1470 */   216,  217,  153,  154,  155,  156,  157,    0,    1,    2,
+
 /*  1480 */   216,  217,    5,  115,  158,  193,  160,   10,   11,   12,
+
 /*  1490 */    13,   14,  193,   59,   17,  126,  193,   19,   20,  129,
+
 /*  1500 */    22,  193,   22,   22,   24,  193,   23,   30,   25,   32,
+
 /*  1510 */    19,   20,  144,   22,   36,  216,  217,   40,  193,  216,
+
 /*  1520 */   217,  193,  152,  129,  216,  217,  193,   36,  216,  217,
+
 /*  1530 */   193,   99,  193,  193,   53,  193,  193,   59,   23,  193,
+
 /*  1540 */    25,  216,  217,  193,  216,  217,  152,   70,   59,   71,
+
 /*  1550 */    59,  117,  193,  216,  217,   78,  216,  217,   81,  216,
+
 /*  1560 */   217,  318,   71,   85,  193,  133,  193,  193,   90,   23,
+
 /*  1570 */    23,   25,   25,  120,  121,   98,   85,  193,  100,  193,
+
 /*  1580 */    23,   90,   25,  121,  106,  107,   19,  216,  217,  216,
+
 /*  1590 */   217,  100,  114,  131,  116,  117,  118,  106,  107,  121,
+
 /*  1600 */   216,  217,  216,  217,  193,  114,  117,  116,  117,  118,
+
 /*  1610 */   133,  193,  121,  193,  193,  138,  139,  193,   23,  193,
+
 /*  1620 */    25,   23,   23,   25,   25,    7,    8,  216,  217,  193,
+
 /*  1630 */   193,  153,  154,  155,  156,  157,  216,  217,  193,  162,
+
 /*  1640 */   216,  217,  216,  217,  153,  154,  155,  156,  157,    1,
+
 /*  1650 */     2,  193,  193,    5,   19,   20,   59,   22,   10,   11,
+
 /*  1660 */    12,   13,   14,  193,   97,   17,  193,   23,  193,   25,
+
 /*  1670 */   288,   36,  193,  242,  216,  217,  236,   23,   30,   25,
+
 /*  1680 */    32,   19,   20,   23,   22,   25,  216,  217,   40,  216,
+
 /*  1690 */   217,  216,  217,  193,   59,  216,  217,  193,   36,   83,
+
 /*  1700 */    84,  153,  153,  155,  155,   23,   71,   25,   23,  193,
+
 /*  1710 */    25,  193,  193,  193,  117,  193,  193,  193,   70,  193,
+
 /*  1720 */   193,   59,  193,  255,  255,  287,   78,  255,  243,   81,
+
 /*  1730 */   191,  255,  297,   71,  271,  100,  293,  245,  267,  214,
+
 /*  1740 */   246,  106,  107,  108,  246,  271,   98,  245,  293,  114,
+
 /*  1750 */   220,  116,  117,  118,  267,  271,  121,  271,  225,  219,
+
 /*  1760 */   229,  219,  100,  219,  259,  259,  259,  259,  106,  107,
+
 /*  1770 */   249,  196,   60,  280,  141,  243,  114,  249,  116,  117,
+
 /*  1780 */   118,  133,  245,  121,  200,  297,  138,  139,  153,  154,
+
 /*  1790 */   155,  156,  157,  297,  200,   38,   19,   20,  151,   22,
+
 /*  1800 */   200,  150,  140,  294,  294,   22,  272,   43,  234,   18,
+
 /*  1810 */   162,  270,  200,   36,  237,  153,  154,  155,  156,  157,
+
 /*  1820 */   237,  283,  237,  237,   18,  199,  149,  246,  272,  270,
+
 /*  1830 */   272,  200,  158,  246,  246,  234,   59,  234,  246,  199,
+
 /*  1840 */   290,   62,  289,  200,  199,   22,  221,  115,   71,  200,
+
 /*  1850 */   200,  199,  199,  221,  218,  218,   19,   20,   64,   22,
+
 /*  1860 */   218,  227,   22,  224,  126,  224,  165,  221,   24,  305,
+
 /*  1870 */   200,  113,  312,   36,  218,  220,  218,  100,  282,  218,
+
 /*  1880 */    91,  218,  317,  106,  107,  221,  227,  282,  317,   82,
+
 /*  1890 */   148,  114,  265,  116,  117,  118,   59,  145,  121,   22,
+
 /*  1900 */   277,  158,  200,  265,   25,  202,  147,  250,   71,  279,
+
 /*  1910 */    13,  146,  194,  194,  249,  248,  250,  140,  247,  246,
+
 /*  1920 */     6,  192,  192,  192,  303,  303,  213,  207,  300,  213,
+
 /*  1930 */   153,  154,  155,  156,  157,  213,  213,  100,  213,  222,
+
 /*  1940 */   207,  214,  214,  106,  107,    4,  222,  207,    3,   22,
+
 /*  1950 */   163,  114,   15,  116,  117,  118,   16,   23,  121,   23,
+
 /*  1960 */   139,  151,  130,   25,  142,   16,   24,   20,  144,    1,
+
 /*  1970 */   142,  130,  130,   61,   53,   53,   37,  151,   53,   53,
+
 /*  1980 */   130,  116,   34,    1,  141,    5,   22,  115,  161,  141,
+
 /*  1990 */   153,  154,  155,  156,  157,   25,   68,   68,   75,   41,
+
 /*  2000 */   115,   24,  131,   20,   19,  125,   22,   96,   22,   22,
+
 /*  2010 */    67,   23,   22,   67,   59,   24,   22,   28,   67,   23,
+
 /*  2020 */    22,   22,  149,   23,   23,   23,  116,   23,   25,   37,
+
 /*  2030 */    97,  141,   23,   23,   22,  143,   25,   75,   88,   34,
+
 /*  2040 */    34,   34,   34,   86,   75,   93,   23,   34,   22,   34,
+
 /*  2050 */    25,   24,   34,   25,   23,  142,   23,  142,   44,   23,
+
 /*  2060 */    23,   23,   11,   23,   25,   22,   22,   22,   15,   23,
+
 /*  2070 */    23,   22,   22,   25,    1,    1,  141,   25,   23,  135,
 /*  2080 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
-
 /*  2090 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
+
 /*  2090 */   319,  319,  319,  319,  141,  141,  319,  141,  319,  319,
 /*  2100 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
 /*  2110 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
 /*  2120 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
@@ -162426,176 +164454,179 @@ static const YYCODETYPE yy_lookahead[] = {
 /*  2220 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
 /*  2230 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
 /*  2240 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
-
 /*  2250 */   319,  319,  319,  319,  319,
+
 /*  2250 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
+
 /*  2260 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
+
 /*  2270 */   319,  319,  319,  319,  319,  319,  319,  319,  319,  319,
+
 /*  2280 */   319,  319,  319,
};
-
#define YY_SHIFT_COUNT    (573)
+
#define YY_SHIFT_COUNT    (575)
#define YY_SHIFT_MIN      (0)
-
#define YY_SHIFT_MAX      (2045)
+
#define YY_SHIFT_MAX      (2074)
static const unsigned short int yy_shift_ofst[] = {
-
 /*     0 */  1648, 1477, 1272,  322,  322,  262, 1319, 1478, 1491, 1662,
-
 /*    10 */  1662, 1662,  317,    0,    0,  214, 1093, 1662, 1662, 1662,
-
 /*    20 */  1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
-
 /*    30 */   271,  271, 1219, 1219,  216,   88,  262,  262,  262,  262,
-
 /*    40 */   262,   40,  111,  258,  361,  469,  512,  583,  622,  693,
+
 /*     0 */  1648, 1477, 1272,  322,  322,    1, 1319, 1478, 1491, 1837,
+
 /*    10 */  1837, 1837,  471,    0,    0,  214, 1093, 1837, 1837, 1837,
+
 /*    20 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
+
 /*    30 */   271,  271, 1219, 1219,  216,   88,    1,    1,    1,    1,
+
 /*    40 */     1,   40,  111,  258,  361,  469,  512,  583,  622,  693,
 /*    50 */   732,  803,  842,  913, 1073, 1093, 1093, 1093, 1093, 1093,
 /*    60 */  1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
 /*    70 */  1093, 1093, 1093, 1113, 1093, 1216,  957,  957, 1635, 1662,
-
 /*    80 */  1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
-
 /*    90 */  1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
-
 /*   100 */  1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,
-
 /*   110 */  1662, 1662, 1662, 1662, 1777, 1662, 1662, 1662, 1662, 1662,
-
 /*   120 */  1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662,  137,  181,
-
 /*   130 */   181,  181,  181,  181,   94,  430,   66,   65,  112,  366,
-
 /*   140 */   475,  475,  629, 1058,  475,  475,  125,  125,  475,  686,
-
 /*   150 */   686,  686,  660,  686,   57,  184,  184,   77,   77, 2070,
-
 /*   160 */  2070,  328,  328,  328,  493,  373,  373,  373,  373, 1015,
-
 /*   170 */  1015,  409,  366, 1129, 1149,  475,  475,  475,  475,  475,
-
 /*   180 */   475,  475,  475,  475,  475,  475,  475,  475,  475,  475,
-
 /*   190 */   475,  475,  475,  475,  475,  621,  621,  475,  852,  899,
-
 /*   200 */   899, 1295, 1295,  406,  851, 2070, 2070, 2070, 2070, 2070,
-
 /*   210 */  2070, 2070, 1307,  954,  954,  640,  464,  695,  238,  700,
-
 /*   220 */   538,  541,  748,  475,  475,  475,  475,  475,  475,  475,
-
 /*   230 */   475,  475,  475,  634,  475,  475,  475,  475,  475,  475,
-
 /*   240 */   475,  475,  475,  475,  475,  475, 1175, 1175, 1175,  475,
-
 /*   250 */   475,  475,  580,  475,  475,  475, 1074, 1142,  475,  475,
-
 /*   260 */  1072,  475,  475,  475,  475,  475,  475,  475,  475,  797,
-
 /*   270 */  1330,  740, 1131, 1131, 1131, 1131, 1069,  740,  740, 1209,
-
 /*   280 */   167,  926, 1391, 1038, 1314,  187, 1408, 1314, 1408, 1435,
-
 /*   290 */  1109, 1038, 1038, 1109, 1038,  187, 1435,  227, 1090,  941,
-
 /*   300 */  1270, 1270, 1270, 1408, 1256, 1256, 1326, 1440,  513, 1461,
-
 /*   310 */  1685, 1685, 1613, 1613, 1722, 1722, 1613, 1612, 1614, 1745,
-
 /*   320 */  1728, 1755, 1755, 1755, 1755, 1613, 1766, 1651, 1614, 1614,
-
 /*   330 */  1651, 1745, 1728, 1651, 1728, 1651, 1613, 1766, 1653, 1758,
-
 /*   340 */  1613, 1766, 1802, 1613, 1766, 1613, 1766, 1802, 1716, 1716,
-
 /*   350 */  1716, 1768, 1813, 1813, 1802, 1716, 1713, 1716, 1768, 1716,
-
 /*   360 */  1716, 1675, 1817, 1729, 1729, 1802, 1706, 1742, 1706, 1742,
-
 /*   370 */  1706, 1742, 1706, 1742, 1613, 1774, 1774, 1786, 1786, 1723,
-
 /*   380 */  1730, 1851, 1613, 1720, 1723, 1733, 1735, 1651, 1857, 1873,
-
 /*   390 */  1873, 1896, 1896, 1896, 2070, 2070, 2070, 2070, 2070, 2070,
-
 /*   400 */  2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070,  207,
-
 /*   410 */   915, 1010, 1030, 1217,  910, 1170, 1470, 1368, 1481, 1442,
-
 /*   420 */  1318, 1383, 1515, 1482, 1523, 1542, 1546, 1547, 1588, 1595,
-
 /*   430 */  1502, 1338, 1566, 1493, 1520, 1521, 1598, 1617, 1568, 1618,
-
 /*   440 */  1511, 1514, 1645, 1649, 1570, 1484, 1910, 1915, 1897, 1757,
-
 /*   450 */  1908, 1909, 1901, 1903, 1788, 1778, 1798, 1911, 1911, 1913,
-
 /*   460 */  1793, 1918, 1795, 1924, 1940, 1800, 1814, 1911, 1815, 1882,
-
 /*   470 */  1912, 1911, 1796, 1895, 1898, 1900, 1902, 1824, 1840, 1923,
-
 /*   480 */  1818, 1957, 1955, 1939, 1847, 1803, 1899, 1938, 1904, 1890,
-
 /*   490 */  1925, 1827, 1854, 1946, 1951, 1954, 1843, 1850, 1956, 1914,
-
 /*   500 */  1958, 1960, 1953, 1961, 1917, 1920, 1962, 1881, 1959, 1963,
-
 /*   510 */  1921, 1952, 1967, 1842, 1970, 1971, 1972, 1973, 1968, 1974,
-
 /*   520 */  1976, 1905, 1858, 1977, 1978, 1887, 1975, 1982, 1862, 1981,
-
 /*   530 */  1979, 1980, 1983, 1984, 1919, 1933, 1926, 1966, 1936, 1922,
-
 /*   540 */  1985, 1993, 1998, 1997, 1999, 2000, 1988, 2003, 1981, 2004,
-
 /*   550 */  2005, 2006, 2007, 2008, 2009, 2001, 2020, 2012, 2013, 2014,
-
 /*   560 */  2015, 2017, 2018, 2011, 1906, 1907, 1916, 1927, 1928, 2019,
-
 /*   570 */  2022, 2027, 2042, 2045,
+
 /*    80 */  1777, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
+
 /*    90 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
+
 /*   100 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
+
 /*   110 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
+
 /*   120 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
+
 /*   130 */   137,  181,  181,  181,  181,  181,  181,  181,   94,  430,
+
 /*   140 */    66,   65,  112,  366,  533,  533,  740, 1261,  533,  533,
+
 /*   150 */    79,   79,  533,  412,  412,  412,   77,  412,  123,  113,
+
 /*   160 */   113,   22,   22, 2098, 2098,  328,  328,  328,  239,  468,
+
 /*   170 */   468,  468,  468, 1015, 1015,  409,  366, 1129, 1186,  533,
+
 /*   180 */   533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+
 /*   190 */   533,  533,  533,  533,  533,  533,  533,  533,  533,  969,
+
 /*   200 */   621,  621,  533,  642,  788,  788, 1228, 1228,  822,  822,
+
 /*   210 */    67, 1274, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 1307,
+
 /*   220 */   954,  954,  585,  472,  640,  387,  695,  538,  541,  700,
+
 /*   230 */   533,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+
 /*   240 */   222,  533,  533,  533,  533,  533,  533,  533,  533,  533,
+
 /*   250 */   533,  533,  533, 1179, 1179, 1179,  533,  533,  533,  565,
+
 /*   260 */   533,  533,  533,  916, 1144,  533,  533, 1288,  533,  533,
+
 /*   270 */   533,  533,  533,  533,  533,  533,  639, 1330,  209, 1076,
+
 /*   280 */  1076, 1076, 1076,  580,  209,  209, 1313,  768,  917,  649,
+
 /*   290 */  1181, 1316,  405, 1316, 1238,  249, 1181, 1181,  249, 1181,
+
 /*   300 */   405, 1238, 1369,  464, 1259, 1012, 1012, 1012, 1368, 1368,
+
 /*   310 */  1368, 1368,  184,  184, 1326,  904, 1287, 1480, 1712, 1712,
+
 /*   320 */  1633, 1633, 1757, 1757, 1633, 1647, 1651, 1783, 1764, 1791,
+
 /*   330 */  1791, 1791, 1791, 1633, 1806, 1677, 1651, 1651, 1677, 1783,
+
 /*   340 */  1764, 1677, 1764, 1677, 1633, 1806, 1674, 1779, 1633, 1806,
+
 /*   350 */  1823, 1633, 1806, 1633, 1806, 1823, 1732, 1732, 1732, 1794,
+
 /*   360 */  1840, 1840, 1823, 1732, 1738, 1732, 1794, 1732, 1732, 1701,
+
 /*   370 */  1844, 1758, 1758, 1823, 1633, 1789, 1789, 1807, 1807, 1742,
+
 /*   380 */  1752, 1877, 1633, 1743, 1742, 1759, 1765, 1677, 1879, 1897,
+
 /*   390 */  1897, 1914, 1914, 1914, 2098, 2098, 2098, 2098, 2098, 2098,
+
 /*   400 */  2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098, 2098,  207,
+
 /*   410 */  1095,  331,  620,  903,  806, 1074, 1483, 1432, 1481, 1322,
+
 /*   420 */  1370, 1394, 1515, 1291, 1546, 1547, 1557, 1595, 1598, 1599,
+
 /*   430 */  1434, 1453, 1618, 1462, 1567, 1489, 1644, 1654, 1616, 1660,
+
 /*   440 */  1548, 1549, 1682, 1685, 1597,  742, 1941, 1945, 1927, 1787,
+
 /*   450 */  1937, 1940, 1934, 1936, 1821, 1810, 1832, 1938, 1938, 1942,
+
 /*   460 */  1822, 1947, 1824, 1949, 1968, 1828, 1841, 1938, 1842, 1912,
+
 /*   470 */  1939, 1938, 1826, 1921, 1922, 1925, 1926, 1850, 1865, 1948,
+
 /*   480 */  1843, 1982, 1980, 1964, 1872, 1827, 1928, 1970, 1929, 1923,
+
 /*   490 */  1958, 1848, 1885, 1977, 1983, 1985, 1871, 1880, 1984, 1943,
+
 /*   500 */  1986, 1987, 1988, 1990, 1946, 1955, 1991, 1911, 1989, 1994,
+
 /*   510 */  1951, 1992, 1996, 1873, 1998, 2000, 2001, 2002, 2003, 2004,
+
 /*   520 */  1999, 1933, 1890, 2009, 2010, 1910, 2005, 2012, 1892, 2011,
+
 /*   530 */  2006, 2007, 2008, 2013, 1950, 1962, 1957, 2014, 1969, 1952,
+
 /*   540 */  2015, 2023, 2026, 2027, 2025, 2028, 2018, 1913, 1915, 2031,
+
 /*   550 */  2011, 2033, 2036, 2037, 2038, 2039, 2040, 2043, 2051, 2044,
+
 /*   560 */  2045, 2046, 2047, 2049, 2050, 2048, 1944, 1935, 1953, 1954,
+
 /*   570 */  1956, 2052, 2055, 2053, 2073, 2074,
};
#define YY_REDUCE_COUNT (408)
-
#define YY_REDUCE_MIN   (-267)
-
#define YY_REDUCE_MAX   (1715)
+
#define YY_REDUCE_MIN   (-271)
+
#define YY_REDUCE_MAX   (1740)
static const short yy_reduce_ofst[] = {
 /*     0 */  -125,  733,  789,  241,  293, -123, -193, -191, -183, -187,
-
 /*    10 */  -180,   83,  133, -207, -198, -267, -175,   -6,  166,  313,
-
 /*    20 */   487,  396,  489,  598,  615,  685,  687,   79,  781,  857,
-
 /*    30 */   490,  616,  240,  334, -188,  796,  841,  843, 1003, 1005,
-
 /*    40 */  1007, -260, -260, -260, -260, -260, -260, -260, -260, -260,
-
 /*    50 */  -260, -260, -260, -260, -260, -260, -260, -260, -260, -260,
-
 /*    60 */  -260, -260, -260, -260, -260, -260, -260, -260, -260, -260,
-
 /*    70 */  -260, -260, -260, -260, -260, -260, -260, -260,  158,  203,
-
 /*    80 */   391,  576,  724,  726,  886, 1021, 1035, 1063, 1081, 1083,
-
 /*    90 */  1097, 1099, 1117, 1152, 1155, 1158, 1163, 1165, 1167, 1169,
-
 /*   100 */  1172, 1180, 1183, 1198, 1200, 1205, 1215, 1225, 1227, 1236,
-
 /*   110 */  1252, 1264, 1299, 1303, 1306, 1309, 1312, 1315, 1325, 1328,
-
 /*   120 */  1337, 1340, 1343, 1371, 1373, 1384, 1386, 1411, -260, -260,
-
 /*   130 */  -260, -260, -260, -260, -260, -260, -260,  -53,  138,  302,
-
 /*   140 */  -158,  357,  223, -222,  411,  458,  -92,  556,  669,  581,
-
 /*   150 */   632,  581, -260,  632,  758,  778,  920, -260, -260, -260,
-
 /*   160 */  -260,  161,  161,  161,  307,  234,  392,  526,  790,  195,
-
 /*   170 */   359, -174, -173,  362,  362, -189,   16,  560,  567,  261,
-
 /*   180 */   689,  802,  853, -122, -166,  408,  335,  617,  690,  837,
-
 /*   190 */  1001,  746, 1061,  515, 1082,  994, 1034, -135, 1000, 1048,
-
 /*   200 */  1137,  877,  897,  186,  627, 1031, 1133, 1148, 1159, 1194,
-
 /*   210 */  1199, 1195, -194, -142,   18, -152,   68,  201,  253,  269,
-
 /*   220 */   294,  354,  521,  528,  676,  680,  736,  743,  850,  907,
-
 /*   230 */  1041, 1047, 1060,  727, 1139, 1147, 1201, 1237, 1278, 1359,
-
 /*   240 */  1393, 1400, 1413, 1429, 1433, 1437, 1126, 1410, 1430, 1444,
-
 /*   250 */  1480, 1483, 1405, 1486, 1490, 1492, 1420, 1372, 1496, 1498,
-
 /*   260 */  1441, 1499,  253, 1500, 1503, 1504, 1506, 1507, 1508, 1398,
-
 /*   270 */  1415, 1453, 1448, 1449, 1450, 1452, 1405, 1453, 1453, 1465,
-
 /*   280 */  1495, 1519, 1414, 1443, 1445, 1468, 1456, 1455, 1457, 1424,
-
 /*   290 */  1473, 1454, 1459, 1474, 1460, 1479, 1434, 1512, 1494, 1509,
-
 /*   300 */  1517, 1518, 1525, 1469, 1489, 1501, 1467, 1510, 1497, 1543,
-
 /*   310 */  1451, 1462, 1557, 1558, 1471, 1472, 1561, 1487, 1505, 1524,
-
 /*   320 */  1538, 1537, 1545, 1548, 1556, 1575, 1596, 1552, 1529, 1530,
-
 /*   330 */  1559, 1533, 1572, 1562, 1573, 1563, 1604, 1615, 1522, 1532,
-
 /*   340 */  1622, 1624, 1605, 1625, 1628, 1629, 1631, 1607, 1616, 1619,
-
 /*   350 */  1620, 1606, 1621, 1623, 1630, 1626, 1632, 1636, 1633, 1637,
-
 /*   360 */  1638, 1531, 1541, 1567, 1571, 1640, 1597, 1599, 1601, 1603,
-
 /*   370 */  1608, 1610, 1611, 1627, 1664, 1549, 1550, 1609, 1634, 1639,
-
 /*   380 */  1641, 1602, 1676, 1642, 1646, 1644, 1650, 1654, 1683, 1694,
-
 /*   390 */  1707, 1711, 1712, 1714, 1643, 1647, 1652, 1698, 1695, 1696,
-
 /*   400 */  1697, 1699, 1700, 1689, 1691, 1701, 1702, 1704, 1715,
+
 /*    10 */   166,  238,  133, -207, -199, -267, -176,   -6,  204,  489,
+
 /*    20 */   576, -175,  598,  686,  615,  725,  860,  778,  781,  857,
+
 /*    30 */   616,  887,   87,  240, -192,  408,  626,  796,  843,  854,
+
 /*    40 */  1003, -271, -271, -271, -271, -271, -271, -271, -271, -271,
+
 /*    50 */  -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
+
 /*    60 */  -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
+
 /*    70 */  -271, -271, -271, -271, -271, -271, -271, -271,   80,   83,
+
 /*    80 */   313,  886,  888,  996, 1034, 1059, 1081, 1100, 1117, 1152,
+
 /*    90 */  1155, 1163, 1165, 1167, 1169, 1172, 1180, 1182, 1184, 1198,
+
 /*   100 */  1200, 1213, 1215, 1225, 1227, 1252, 1254, 1264, 1299, 1303,
+
 /*   110 */  1308, 1312, 1325, 1328, 1337, 1340, 1343, 1371, 1373, 1384,
+
 /*   120 */  1386, 1411, 1420, 1424, 1426, 1458, 1470, 1473, 1475, 1479,
+
 /*   130 */  -271, -271, -271, -271, -271, -271, -271, -271, -271, -271,
+
 /*   140 */  -271,  138,  459,  396, -158,  470,  302, -212,  521,  201,
+
 /*   150 */  -195,  -92,  559,  630,  632,  630, -271,  632,  901,   63,
+
 /*   160 */   407, -271, -271, -271, -271,  161,  161,  161,  251,  335,
+
 /*   170 */   847,  960,  980,  537,  588,  618,  628,  688,  688, -166,
+
 /*   180 */  -161,  674,  790,  794,  799,  851,  852, -122,  680, -120,
+
 /*   190 */   995, 1038,  415, 1051,  893,  798,  962,  400, 1086,  779,
+
 /*   200 */   923,  924,  263, 1041,  979,  990, 1083, 1097, 1031, 1194,
+
 /*   210 */   362,  994, 1139, 1005, 1037, 1202, 1205, 1195, 1210, -194,
+
 /*   220 */    56,  185, -135,  232,  522,  560,  601,  617,  669,  683,
+
 /*   230 */   711,  856,  908,  941, 1048, 1101, 1147, 1257, 1262, 1265,
+
 /*   240 */   392, 1292, 1333, 1339, 1342, 1346, 1350, 1359, 1374, 1418,
+
 /*   250 */  1421, 1436, 1437,  593,  755,  770,  997, 1445, 1459, 1209,
+
 /*   260 */  1500, 1504, 1516, 1132, 1243, 1518, 1519, 1440, 1520,  560,
+
 /*   270 */  1522, 1523, 1524, 1526, 1527, 1529, 1382, 1438, 1431, 1468,
+
 /*   280 */  1469, 1472, 1476, 1209, 1431, 1431, 1485, 1525, 1539, 1435,
+
 /*   290 */  1463, 1471, 1492, 1487, 1443, 1494, 1474, 1484, 1498, 1486,
+
 /*   300 */  1502, 1455, 1530, 1531, 1533, 1540, 1542, 1544, 1505, 1506,
+
 /*   310 */  1507, 1508, 1521, 1528, 1493, 1537, 1532, 1575, 1488, 1496,
+
 /*   320 */  1584, 1594, 1509, 1510, 1600, 1538, 1534, 1541, 1574, 1577,
+
 /*   330 */  1583, 1585, 1586, 1612, 1626, 1581, 1556, 1558, 1587, 1559,
+
 /*   340 */  1601, 1588, 1603, 1592, 1631, 1640, 1550, 1553, 1643, 1645,
+
 /*   350 */  1625, 1649, 1652, 1650, 1653, 1632, 1636, 1637, 1642, 1634,
+
 /*   360 */  1639, 1641, 1646, 1656, 1655, 1658, 1659, 1661, 1663, 1560,
+
 /*   370 */  1564, 1596, 1605, 1664, 1670, 1565, 1571, 1627, 1638, 1657,
+
 /*   380 */  1665, 1623, 1702, 1630, 1666, 1667, 1671, 1673, 1703, 1718,
+
 /*   390 */  1719, 1729, 1730, 1731, 1621, 1622, 1628, 1720, 1713, 1716,
+
 /*   400 */  1722, 1723, 1733, 1717, 1724, 1727, 1728, 1725, 1740,
};
static const YYACTIONTYPE yy_default[] = {
-
 /*     0 */  1637, 1637, 1637, 1466, 1233, 1344, 1233, 1233, 1233, 1466,
-
 /*    10 */  1466, 1466, 1233, 1374, 1374, 1519, 1266, 1233, 1233, 1233,
-
 /*    20 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1465, 1233, 1233,
-
 /*    30 */  1233, 1233, 1554, 1554, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*    40 */  1233, 1233, 1383, 1233, 1390, 1233, 1233, 1233, 1233, 1233,
-
 /*    50 */  1467, 1468, 1233, 1233, 1233, 1518, 1520, 1483, 1397, 1396,
-
 /*    60 */  1395, 1394, 1501, 1361, 1388, 1381, 1385, 1461, 1462, 1460,
-
 /*    70 */  1464, 1468, 1467, 1233, 1384, 1431, 1445, 1430, 1233, 1233,
-
 /*    80 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*    90 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   100 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   110 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   120 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1439, 1444,
-
 /*   130 */  1451, 1443, 1440, 1433, 1432, 1434, 1435, 1233, 1233, 1257,
-
 /*   140 */  1233, 1233, 1254, 1308, 1233, 1233, 1233, 1233, 1233, 1538,
-
 /*   150 */  1537, 1233, 1436, 1233, 1266, 1425, 1424, 1448, 1437, 1447,
-
 /*   160 */  1446, 1526, 1590, 1589, 1484, 1233, 1233, 1233, 1233, 1233,
-
 /*   170 */  1233, 1554, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   180 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   190 */  1233, 1233, 1233, 1233, 1233, 1554, 1554, 1233, 1266, 1554,
-
 /*   200 */  1554, 1262, 1262, 1368, 1233, 1533, 1335, 1335, 1335, 1335,
-
 /*   210 */  1344, 1335, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   220 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1523, 1521, 1233,
-
 /*   230 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   240 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   250 */  1233, 1233, 1233, 1233, 1233, 1233, 1340, 1233, 1233, 1233,
-
 /*   260 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1583, 1233,
-
 /*   270 */  1496, 1322, 1340, 1340, 1340, 1340, 1342, 1323, 1321, 1334,
-
 /*   280 */  1267, 1240, 1629, 1400, 1389, 1341, 1363, 1389, 1363, 1626,
-
 /*   290 */  1387, 1400, 1400, 1387, 1400, 1341, 1626, 1283, 1606, 1278,
-
 /*   300 */  1374, 1374, 1374, 1363, 1368, 1368, 1463, 1341, 1334, 1233,
-
 /*   310 */  1629, 1629, 1349, 1349, 1628, 1628, 1349, 1484, 1613, 1409,
-
 /*   320 */  1311, 1317, 1317, 1317, 1317, 1349, 1251, 1387, 1613, 1613,
-
 /*   330 */  1387, 1409, 1311, 1387, 1311, 1387, 1349, 1251, 1500, 1623,
-
 /*   340 */  1349, 1251, 1474, 1349, 1251, 1349, 1251, 1474, 1309, 1309,
-
 /*   350 */  1309, 1298, 1233, 1233, 1474, 1309, 1283, 1309, 1298, 1309,
-
 /*   360 */  1309, 1572, 1233, 1478, 1478, 1474, 1367, 1362, 1367, 1362,
-
 /*   370 */  1367, 1362, 1367, 1362, 1349, 1564, 1564, 1377, 1377, 1382,
-
 /*   380 */  1368, 1469, 1349, 1233, 1382, 1380, 1378, 1387, 1301, 1586,
-
 /*   390 */  1586, 1582, 1582, 1582, 1634, 1634, 1533, 1599, 1266, 1266,
-
 /*   400 */  1266, 1266, 1599, 1285, 1285, 1267, 1267, 1266, 1599, 1233,
-
 /*   410 */  1233, 1233, 1233, 1233, 1233, 1594, 1233, 1528, 1485, 1353,
-
 /*   420 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   430 */  1233, 1233, 1233, 1233, 1539, 1233, 1233, 1233, 1233, 1233,
-
 /*   440 */  1233, 1233, 1233, 1233, 1233, 1414, 1233, 1236, 1530, 1233,
-
 /*   450 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1391, 1392, 1354,
-
 /*   460 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1406, 1233, 1233,
-
 /*   470 */  1233, 1401, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   480 */  1625, 1233, 1233, 1233, 1233, 1233, 1233, 1499, 1498, 1233,
-
 /*   490 */  1233, 1351, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   500 */  1233, 1233, 1233, 1233, 1233, 1281, 1233, 1233, 1233, 1233,
-
 /*   510 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   520 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1379,
-
 /*   530 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   540 */  1233, 1233, 1233, 1233, 1569, 1369, 1233, 1233, 1616, 1233,
-
 /*   550 */  1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233,
-
 /*   560 */  1233, 1233, 1233, 1610, 1325, 1416, 1233, 1415, 1419, 1255,
-
 /*   570 */  1233, 1245, 1233, 1233,
+
 /*     0 */  1647, 1647, 1647, 1475, 1240, 1351, 1240, 1240, 1240, 1475,
+
 /*    10 */  1475, 1475, 1240, 1381, 1381, 1528, 1273, 1240, 1240, 1240,
+
 /*    20 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1474, 1240, 1240,
+
 /*    30 */  1240, 1240, 1563, 1563, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*    40 */  1240, 1240, 1390, 1240, 1397, 1240, 1240, 1240, 1240, 1240,
+
 /*    50 */  1476, 1477, 1240, 1240, 1240, 1527, 1529, 1492, 1404, 1403,
+
 /*    60 */  1402, 1401, 1510, 1369, 1395, 1388, 1392, 1470, 1471, 1469,
+
 /*    70 */  1473, 1477, 1476, 1240, 1391, 1438, 1454, 1437, 1240, 1240,
+
 /*    80 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*    90 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   100 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   110 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   120 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   130 */  1446, 1453, 1452, 1451, 1460, 1450, 1447, 1440, 1439, 1441,
+
 /*   140 */  1442, 1240, 1240, 1264, 1240, 1240, 1261, 1315, 1240, 1240,
+
 /*   150 */  1240, 1240, 1240, 1547, 1546, 1240, 1443, 1240, 1273, 1432,
+
 /*   160 */  1431, 1457, 1444, 1456, 1455, 1535, 1599, 1598, 1493, 1240,
+
 /*   170 */  1240, 1240, 1240, 1240, 1240, 1563, 1240, 1240, 1240, 1240,
+
 /*   180 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   190 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1371,
+
 /*   200 */  1563, 1563, 1240, 1273, 1563, 1563, 1372, 1372, 1269, 1269,
+
 /*   210 */  1375, 1240, 1542, 1342, 1342, 1342, 1342, 1351, 1342, 1240,
+
 /*   220 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   230 */  1240, 1240, 1240, 1240, 1532, 1530, 1240, 1240, 1240, 1240,
+
 /*   240 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   250 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   260 */  1240, 1240, 1240, 1347, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   270 */  1240, 1240, 1240, 1240, 1240, 1592, 1240, 1505, 1329, 1347,
+
 /*   280 */  1347, 1347, 1347, 1349, 1330, 1328, 1341, 1274, 1247, 1639,
+
 /*   290 */  1407, 1396, 1348, 1396, 1636, 1394, 1407, 1407, 1394, 1407,
+
 /*   300 */  1348, 1636, 1290, 1615, 1285, 1381, 1381, 1381, 1371, 1371,
+
 /*   310 */  1371, 1371, 1375, 1375, 1472, 1348, 1341, 1240, 1639, 1639,
+
 /*   320 */  1357, 1357, 1638, 1638, 1357, 1493, 1623, 1416, 1318, 1324,
+
 /*   330 */  1324, 1324, 1324, 1357, 1258, 1394, 1623, 1623, 1394, 1416,
+
 /*   340 */  1318, 1394, 1318, 1394, 1357, 1258, 1509, 1633, 1357, 1258,
+
 /*   350 */  1483, 1357, 1258, 1357, 1258, 1483, 1316, 1316, 1316, 1305,
+
 /*   360 */  1240, 1240, 1483, 1316, 1290, 1316, 1305, 1316, 1316, 1581,
+
 /*   370 */  1240, 1487, 1487, 1483, 1357, 1573, 1573, 1384, 1384, 1389,
+
 /*   380 */  1375, 1478, 1357, 1240, 1389, 1387, 1385, 1394, 1308, 1595,
+
 /*   390 */  1595, 1591, 1591, 1591, 1644, 1644, 1542, 1608, 1273, 1273,
+
 /*   400 */  1273, 1273, 1608, 1292, 1292, 1274, 1274, 1273, 1608, 1240,
+
 /*   410 */  1240, 1240, 1240, 1240, 1240, 1603, 1240, 1537, 1494, 1361,
+
 /*   420 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   430 */  1240, 1240, 1240, 1240, 1548, 1240, 1240, 1240, 1240, 1240,
+
 /*   440 */  1240, 1240, 1240, 1240, 1240, 1421, 1240, 1243, 1539, 1240,
+
 /*   450 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1398, 1399, 1362,
+
 /*   460 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1413, 1240, 1240,
+
 /*   470 */  1240, 1408, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   480 */  1635, 1240, 1240, 1240, 1240, 1240, 1240, 1508, 1507, 1240,
+
 /*   490 */  1240, 1359, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   500 */  1240, 1240, 1240, 1240, 1240, 1288, 1240, 1240, 1240, 1240,
+
 /*   510 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   520 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1386,
+
 /*   530 */  1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   540 */  1240, 1240, 1240, 1240, 1578, 1376, 1240, 1240, 1240, 1240,
+
 /*   550 */  1626, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240, 1240,
+
 /*   560 */  1240, 1240, 1240, 1240, 1240, 1619, 1332, 1423, 1240, 1422,
+
 /*   570 */  1426, 1262, 1240, 1252, 1240, 1240,
};
/********** End of lemon-generated parsing tables *****************************/

@@ -163147,12 +165178,12 @@ static const char *const yyTokenName[] = {
  /*  256 */ "seltablist",
  /*  257 */ "stl_prefix",
  /*  258 */ "joinop",
-
  /*  259 */ "indexed_opt",
-
  /*  260 */ "on_opt",
-
  /*  261 */ "using_opt",
-
  /*  262 */ "exprlist",
-
  /*  263 */ "xfullname",
-
  /*  264 */ "idlist",
+
  /*  259 */ "on_using",
+
  /*  260 */ "indexed_by",
+
  /*  261 */ "exprlist",
+
  /*  262 */ "xfullname",
+
  /*  263 */ "idlist",
+
  /*  264 */ "indexed_opt",
  /*  265 */ "nulls",
  /*  266 */ "with",
  /*  267 */ "where_opt_ret",
@@ -163323,29 +165354,29 @@ static const char *const yyRuleName[] = {
 /* 106 */ "from ::= FROM seltablist",
 /* 107 */ "stl_prefix ::= seltablist joinop",
 /* 108 */ "stl_prefix ::=",
-
 /* 109 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
-
 /* 110 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt",
-
 /* 111 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
-
 /* 112 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
-
 /* 113 */ "dbnm ::=",
-
 /* 114 */ "dbnm ::= DOT nm",
-
 /* 115 */ "fullname ::= nm",
-
 /* 116 */ "fullname ::= nm DOT nm",
-
 /* 117 */ "xfullname ::= nm",
-
 /* 118 */ "xfullname ::= nm DOT nm",
-
 /* 119 */ "xfullname ::= nm DOT nm AS nm",
-
 /* 120 */ "xfullname ::= nm AS nm",
-
 /* 121 */ "joinop ::= COMMA|JOIN",
-
 /* 122 */ "joinop ::= JOIN_KW JOIN",
-
 /* 123 */ "joinop ::= JOIN_KW nm JOIN",
-
 /* 124 */ "joinop ::= JOIN_KW nm nm JOIN",
-
 /* 125 */ "on_opt ::= ON expr",
-
 /* 126 */ "on_opt ::=",
-
 /* 127 */ "indexed_opt ::=",
-
 /* 128 */ "indexed_opt ::= INDEXED BY nm",
-
 /* 129 */ "indexed_opt ::= NOT INDEXED",
-
 /* 130 */ "using_opt ::= USING LP idlist RP",
-
 /* 131 */ "using_opt ::=",
+
 /* 109 */ "seltablist ::= stl_prefix nm dbnm as on_using",
+
 /* 110 */ "seltablist ::= stl_prefix nm dbnm as indexed_by on_using",
+
 /* 111 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using",
+
 /* 112 */ "seltablist ::= stl_prefix LP select RP as on_using",
+
 /* 113 */ "seltablist ::= stl_prefix LP seltablist RP as on_using",
+
 /* 114 */ "dbnm ::=",
+
 /* 115 */ "dbnm ::= DOT nm",
+
 /* 116 */ "fullname ::= nm",
+
 /* 117 */ "fullname ::= nm DOT nm",
+
 /* 118 */ "xfullname ::= nm",
+
 /* 119 */ "xfullname ::= nm DOT nm",
+
 /* 120 */ "xfullname ::= nm DOT nm AS nm",
+
 /* 121 */ "xfullname ::= nm AS nm",
+
 /* 122 */ "joinop ::= COMMA|JOIN",
+
 /* 123 */ "joinop ::= JOIN_KW JOIN",
+
 /* 124 */ "joinop ::= JOIN_KW nm JOIN",
+
 /* 125 */ "joinop ::= JOIN_KW nm nm JOIN",
+
 /* 126 */ "on_using ::= ON expr",
+
 /* 127 */ "on_using ::= USING LP idlist RP",
+
 /* 128 */ "on_using ::=",
+
 /* 129 */ "indexed_opt ::=",
+
 /* 130 */ "indexed_by ::= INDEXED BY nm",
+
 /* 131 */ "indexed_by ::= NOT INDEXED",
 /* 132 */ "orderby_opt ::=",
 /* 133 */ "orderby_opt ::= ORDER BY sortlist",
 /* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls",
@@ -163423,199 +165454,202 @@ static const char *const yyRuleName[] = {
 /* 206 */ "expr ::= expr NOT NULL",
 /* 207 */ "expr ::= expr IS expr",
 /* 208 */ "expr ::= expr IS NOT expr",
-
 /* 209 */ "expr ::= NOT expr",
-
 /* 210 */ "expr ::= BITNOT expr",
-
 /* 211 */ "expr ::= PLUS|MINUS expr",
-
 /* 212 */ "expr ::= expr PTR expr",
-
 /* 213 */ "between_op ::= BETWEEN",
-
 /* 214 */ "between_op ::= NOT BETWEEN",
-
 /* 215 */ "expr ::= expr between_op expr AND expr",
-
 /* 216 */ "in_op ::= IN",
-
 /* 217 */ "in_op ::= NOT IN",
-
 /* 218 */ "expr ::= expr in_op LP exprlist RP",
-
 /* 219 */ "expr ::= LP select RP",
-
 /* 220 */ "expr ::= expr in_op LP select RP",
-
 /* 221 */ "expr ::= expr in_op nm dbnm paren_exprlist",
-
 /* 222 */ "expr ::= EXISTS LP select RP",
-
 /* 223 */ "expr ::= CASE case_operand case_exprlist case_else END",
-
 /* 224 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
-
 /* 225 */ "case_exprlist ::= WHEN expr THEN expr",
-
 /* 226 */ "case_else ::= ELSE expr",
-
 /* 227 */ "case_else ::=",
-
 /* 228 */ "case_operand ::= expr",
-
 /* 229 */ "case_operand ::=",
-
 /* 230 */ "exprlist ::=",
-
 /* 231 */ "nexprlist ::= nexprlist COMMA expr",
-
 /* 232 */ "nexprlist ::= expr",
-
 /* 233 */ "paren_exprlist ::=",
-
 /* 234 */ "paren_exprlist ::= LP exprlist RP",
-
 /* 235 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
-
 /* 236 */ "uniqueflag ::= UNIQUE",
-
 /* 237 */ "uniqueflag ::=",
-
 /* 238 */ "eidlist_opt ::=",
-
 /* 239 */ "eidlist_opt ::= LP eidlist RP",
-
 /* 240 */ "eidlist ::= eidlist COMMA nm collate sortorder",
-
 /* 241 */ "eidlist ::= nm collate sortorder",
-
 /* 242 */ "collate ::=",
-
 /* 243 */ "collate ::= COLLATE ID|STRING",
-
 /* 244 */ "cmd ::= DROP INDEX ifexists fullname",
-
 /* 245 */ "cmd ::= VACUUM vinto",
-
 /* 246 */ "cmd ::= VACUUM nm vinto",
-
 /* 247 */ "vinto ::= INTO expr",
-
 /* 248 */ "vinto ::=",
-
 /* 249 */ "cmd ::= PRAGMA nm dbnm",
-
 /* 250 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
-
 /* 251 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
-
 /* 252 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
-
 /* 253 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
-
 /* 254 */ "plus_num ::= PLUS INTEGER|FLOAT",
-
 /* 255 */ "minus_num ::= MINUS INTEGER|FLOAT",
-
 /* 256 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
-
 /* 257 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
-
 /* 258 */ "trigger_time ::= BEFORE|AFTER",
-
 /* 259 */ "trigger_time ::= INSTEAD OF",
-
 /* 260 */ "trigger_time ::=",
-
 /* 261 */ "trigger_event ::= DELETE|INSERT",
-
 /* 262 */ "trigger_event ::= UPDATE",
-
 /* 263 */ "trigger_event ::= UPDATE OF idlist",
-
 /* 264 */ "when_clause ::=",
-
 /* 265 */ "when_clause ::= WHEN expr",
-
 /* 266 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
-
 /* 267 */ "trigger_cmd_list ::= trigger_cmd SEMI",
-
 /* 268 */ "trnm ::= nm DOT nm",
-
 /* 269 */ "tridxby ::= INDEXED BY nm",
-
 /* 270 */ "tridxby ::= NOT INDEXED",
-
 /* 271 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt",
-
 /* 272 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
-
 /* 273 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
-
 /* 274 */ "trigger_cmd ::= scanpt select scanpt",
-
 /* 275 */ "expr ::= RAISE LP IGNORE RP",
-
 /* 276 */ "expr ::= RAISE LP raisetype COMMA nm RP",
-
 /* 277 */ "raisetype ::= ROLLBACK",
-
 /* 278 */ "raisetype ::= ABORT",
-
 /* 279 */ "raisetype ::= FAIL",
-
 /* 280 */ "cmd ::= DROP TRIGGER ifexists fullname",
-
 /* 281 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
-
 /* 282 */ "cmd ::= DETACH database_kw_opt expr",
-
 /* 283 */ "key_opt ::=",
-
 /* 284 */ "key_opt ::= KEY expr",
-
 /* 285 */ "cmd ::= REINDEX",
-
 /* 286 */ "cmd ::= REINDEX nm dbnm",
-
 /* 287 */ "cmd ::= ANALYZE",
-
 /* 288 */ "cmd ::= ANALYZE nm dbnm",
-
 /* 289 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
-
 /* 290 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
-
 /* 291 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
-
 /* 292 */ "add_column_fullname ::= fullname",
-
 /* 293 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
-
 /* 294 */ "cmd ::= create_vtab",
-
 /* 295 */ "cmd ::= create_vtab LP vtabarglist RP",
-
 /* 296 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
-
 /* 297 */ "vtabarg ::=",
-
 /* 298 */ "vtabargtoken ::= ANY",
-
 /* 299 */ "vtabargtoken ::= lp anylist RP",
-
 /* 300 */ "lp ::= LP",
-
 /* 301 */ "with ::= WITH wqlist",
-
 /* 302 */ "with ::= WITH RECURSIVE wqlist",
-
 /* 303 */ "wqas ::= AS",
-
 /* 304 */ "wqas ::= AS MATERIALIZED",
-
 /* 305 */ "wqas ::= AS NOT MATERIALIZED",
-
 /* 306 */ "wqitem ::= nm eidlist_opt wqas LP select RP",
-
 /* 307 */ "wqlist ::= wqitem",
-
 /* 308 */ "wqlist ::= wqlist COMMA wqitem",
-
 /* 309 */ "windowdefn_list ::= windowdefn",
-
 /* 310 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
-
 /* 311 */ "windowdefn ::= nm AS LP window RP",
-
 /* 312 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
-
 /* 313 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
-
 /* 314 */ "window ::= ORDER BY sortlist frame_opt",
-
 /* 315 */ "window ::= nm ORDER BY sortlist frame_opt",
-
 /* 316 */ "window ::= frame_opt",
-
 /* 317 */ "window ::= nm frame_opt",
-
 /* 318 */ "frame_opt ::=",
-
 /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
-
 /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
-
 /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
-
 /* 322 */ "frame_bound_s ::= frame_bound",
-
 /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
-
 /* 324 */ "frame_bound_e ::= frame_bound",
-
 /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
-
 /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
-
 /* 327 */ "frame_bound ::= CURRENT ROW",
-
 /* 328 */ "frame_exclude_opt ::=",
-
 /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
-
 /* 330 */ "frame_exclude ::= NO OTHERS",
-
 /* 331 */ "frame_exclude ::= CURRENT ROW",
-
 /* 332 */ "frame_exclude ::= GROUP|TIES",
-
 /* 333 */ "window_clause ::= WINDOW windowdefn_list",
-
 /* 334 */ "filter_over ::= filter_clause over_clause",
-
 /* 335 */ "filter_over ::= over_clause",
-
 /* 336 */ "filter_over ::= filter_clause",
-
 /* 337 */ "over_clause ::= OVER LP window RP",
-
 /* 338 */ "over_clause ::= OVER nm",
-
 /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP",
-
 /* 340 */ "input ::= cmdlist",
-
 /* 341 */ "cmdlist ::= cmdlist ecmd",
-
 /* 342 */ "cmdlist ::= ecmd",
-
 /* 343 */ "ecmd ::= SEMI",
-
 /* 344 */ "ecmd ::= cmdx SEMI",
-
 /* 345 */ "ecmd ::= explain cmdx SEMI",
-
 /* 346 */ "trans_opt ::=",
-
 /* 347 */ "trans_opt ::= TRANSACTION",
-
 /* 348 */ "trans_opt ::= TRANSACTION nm",
-
 /* 349 */ "savepoint_opt ::= SAVEPOINT",
-
 /* 350 */ "savepoint_opt ::=",
-
 /* 351 */ "cmd ::= create_table create_table_args",
-
 /* 352 */ "table_option_set ::= table_option",
-
 /* 353 */ "columnlist ::= columnlist COMMA columnname carglist",
-
 /* 354 */ "columnlist ::= columnname carglist",
-
 /* 355 */ "nm ::= ID|INDEXED",
-
 /* 356 */ "nm ::= STRING",
-
 /* 357 */ "nm ::= JOIN_KW",
-
 /* 358 */ "typetoken ::= typename",
-
 /* 359 */ "typename ::= ID|STRING",
-
 /* 360 */ "signed ::= plus_num",
-
 /* 361 */ "signed ::= minus_num",
-
 /* 362 */ "carglist ::= carglist ccons",
-
 /* 363 */ "carglist ::=",
-
 /* 364 */ "ccons ::= NULL onconf",
-
 /* 365 */ "ccons ::= GENERATED ALWAYS AS generated",
-
 /* 366 */ "ccons ::= AS generated",
-
 /* 367 */ "conslist_opt ::= COMMA conslist",
-
 /* 368 */ "conslist ::= conslist tconscomma tcons",
-
 /* 369 */ "conslist ::= tcons",
-
 /* 370 */ "tconscomma ::=",
-
 /* 371 */ "defer_subclause_opt ::= defer_subclause",
-
 /* 372 */ "resolvetype ::= raisetype",
-
 /* 373 */ "selectnowith ::= oneselect",
-
 /* 374 */ "oneselect ::= values",
-
 /* 375 */ "sclp ::= selcollist COMMA",
-
 /* 376 */ "as ::= ID|STRING",
-
 /* 377 */ "returning ::=",
-
 /* 378 */ "expr ::= term",
-
 /* 379 */ "likeop ::= LIKE_KW|MATCH",
-
 /* 380 */ "exprlist ::= nexprlist",
-
 /* 381 */ "nmnum ::= plus_num",
-
 /* 382 */ "nmnum ::= nm",
-
 /* 383 */ "nmnum ::= ON",
-
 /* 384 */ "nmnum ::= DELETE",
-
 /* 385 */ "nmnum ::= DEFAULT",
-
 /* 386 */ "plus_num ::= INTEGER|FLOAT",
-
 /* 387 */ "foreach_clause ::=",
-
 /* 388 */ "foreach_clause ::= FOR EACH ROW",
-
 /* 389 */ "trnm ::= nm",
-
 /* 390 */ "tridxby ::=",
-
 /* 391 */ "database_kw_opt ::= DATABASE",
-
 /* 392 */ "database_kw_opt ::=",
-
 /* 393 */ "kwcolumn_opt ::=",
-
 /* 394 */ "kwcolumn_opt ::= COLUMNKW",
-
 /* 395 */ "vtabarglist ::= vtabarg",
-
 /* 396 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
-
 /* 397 */ "vtabarg ::= vtabarg vtabargtoken",
-
 /* 398 */ "anylist ::=",
-
 /* 399 */ "anylist ::= anylist LP anylist RP",
-
 /* 400 */ "anylist ::= anylist ANY",
-
 /* 401 */ "with ::=",
+
 /* 209 */ "expr ::= expr IS NOT DISTINCT FROM expr",
+
 /* 210 */ "expr ::= expr IS DISTINCT FROM expr",
+
 /* 211 */ "expr ::= NOT expr",
+
 /* 212 */ "expr ::= BITNOT expr",
+
 /* 213 */ "expr ::= PLUS|MINUS expr",
+
 /* 214 */ "expr ::= expr PTR expr",
+
 /* 215 */ "between_op ::= BETWEEN",
+
 /* 216 */ "between_op ::= NOT BETWEEN",
+
 /* 217 */ "expr ::= expr between_op expr AND expr",
+
 /* 218 */ "in_op ::= IN",
+
 /* 219 */ "in_op ::= NOT IN",
+
 /* 220 */ "expr ::= expr in_op LP exprlist RP",
+
 /* 221 */ "expr ::= LP select RP",
+
 /* 222 */ "expr ::= expr in_op LP select RP",
+
 /* 223 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+
 /* 224 */ "expr ::= EXISTS LP select RP",
+
 /* 225 */ "expr ::= CASE case_operand case_exprlist case_else END",
+
 /* 226 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+
 /* 227 */ "case_exprlist ::= WHEN expr THEN expr",
+
 /* 228 */ "case_else ::= ELSE expr",
+
 /* 229 */ "case_else ::=",
+
 /* 230 */ "case_operand ::= expr",
+
 /* 231 */ "case_operand ::=",
+
 /* 232 */ "exprlist ::=",
+
 /* 233 */ "nexprlist ::= nexprlist COMMA expr",
+
 /* 234 */ "nexprlist ::= expr",
+
 /* 235 */ "paren_exprlist ::=",
+
 /* 236 */ "paren_exprlist ::= LP exprlist RP",
+
 /* 237 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt",
+
 /* 238 */ "uniqueflag ::= UNIQUE",
+
 /* 239 */ "uniqueflag ::=",
+
 /* 240 */ "eidlist_opt ::=",
+
 /* 241 */ "eidlist_opt ::= LP eidlist RP",
+
 /* 242 */ "eidlist ::= eidlist COMMA nm collate sortorder",
+
 /* 243 */ "eidlist ::= nm collate sortorder",
+
 /* 244 */ "collate ::=",
+
 /* 245 */ "collate ::= COLLATE ID|STRING",
+
 /* 246 */ "cmd ::= DROP INDEX ifexists fullname",
+
 /* 247 */ "cmd ::= VACUUM vinto",
+
 /* 248 */ "cmd ::= VACUUM nm vinto",
+
 /* 249 */ "vinto ::= INTO expr",
+
 /* 250 */ "vinto ::=",
+
 /* 251 */ "cmd ::= PRAGMA nm dbnm",
+
 /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+
 /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+
 /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+
 /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+
 /* 256 */ "plus_num ::= PLUS INTEGER|FLOAT",
+
 /* 257 */ "minus_num ::= MINUS INTEGER|FLOAT",
+
 /* 258 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+
 /* 259 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+
 /* 260 */ "trigger_time ::= BEFORE|AFTER",
+
 /* 261 */ "trigger_time ::= INSTEAD OF",
+
 /* 262 */ "trigger_time ::=",
+
 /* 263 */ "trigger_event ::= DELETE|INSERT",
+
 /* 264 */ "trigger_event ::= UPDATE",
+
 /* 265 */ "trigger_event ::= UPDATE OF idlist",
+
 /* 266 */ "when_clause ::=",
+
 /* 267 */ "when_clause ::= WHEN expr",
+
 /* 268 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+
 /* 269 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+
 /* 270 */ "trnm ::= nm DOT nm",
+
 /* 271 */ "tridxby ::= INDEXED BY nm",
+
 /* 272 */ "tridxby ::= NOT INDEXED",
+
 /* 273 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt",
+
 /* 274 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt",
+
 /* 275 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt",
+
 /* 276 */ "trigger_cmd ::= scanpt select scanpt",
+
 /* 277 */ "expr ::= RAISE LP IGNORE RP",
+
 /* 278 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+
 /* 279 */ "raisetype ::= ROLLBACK",
+
 /* 280 */ "raisetype ::= ABORT",
+
 /* 281 */ "raisetype ::= FAIL",
+
 /* 282 */ "cmd ::= DROP TRIGGER ifexists fullname",
+
 /* 283 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+
 /* 284 */ "cmd ::= DETACH database_kw_opt expr",
+
 /* 285 */ "key_opt ::=",
+
 /* 286 */ "key_opt ::= KEY expr",
+
 /* 287 */ "cmd ::= REINDEX",
+
 /* 288 */ "cmd ::= REINDEX nm dbnm",
+
 /* 289 */ "cmd ::= ANALYZE",
+
 /* 290 */ "cmd ::= ANALYZE nm dbnm",
+
 /* 291 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+
 /* 292 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist",
+
 /* 293 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
+
 /* 294 */ "add_column_fullname ::= fullname",
+
 /* 295 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
+
 /* 296 */ "cmd ::= create_vtab",
+
 /* 297 */ "cmd ::= create_vtab LP vtabarglist RP",
+
 /* 298 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+
 /* 299 */ "vtabarg ::=",
+
 /* 300 */ "vtabargtoken ::= ANY",
+
 /* 301 */ "vtabargtoken ::= lp anylist RP",
+
 /* 302 */ "lp ::= LP",
+
 /* 303 */ "with ::= WITH wqlist",
+
 /* 304 */ "with ::= WITH RECURSIVE wqlist",
+
 /* 305 */ "wqas ::= AS",
+
 /* 306 */ "wqas ::= AS MATERIALIZED",
+
 /* 307 */ "wqas ::= AS NOT MATERIALIZED",
+
 /* 308 */ "wqitem ::= nm eidlist_opt wqas LP select RP",
+
 /* 309 */ "wqlist ::= wqitem",
+
 /* 310 */ "wqlist ::= wqlist COMMA wqitem",
+
 /* 311 */ "windowdefn_list ::= windowdefn",
+
 /* 312 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
+
 /* 313 */ "windowdefn ::= nm AS LP window RP",
+
 /* 314 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
+
 /* 315 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
+
 /* 316 */ "window ::= ORDER BY sortlist frame_opt",
+
 /* 317 */ "window ::= nm ORDER BY sortlist frame_opt",
+
 /* 318 */ "window ::= frame_opt",
+
 /* 319 */ "window ::= nm frame_opt",
+
 /* 320 */ "frame_opt ::=",
+
 /* 321 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
+
 /* 322 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
+
 /* 323 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
+
 /* 324 */ "frame_bound_s ::= frame_bound",
+
 /* 325 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
+
 /* 326 */ "frame_bound_e ::= frame_bound",
+
 /* 327 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
+
 /* 328 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
+
 /* 329 */ "frame_bound ::= CURRENT ROW",
+
 /* 330 */ "frame_exclude_opt ::=",
+
 /* 331 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
+
 /* 332 */ "frame_exclude ::= NO OTHERS",
+
 /* 333 */ "frame_exclude ::= CURRENT ROW",
+
 /* 334 */ "frame_exclude ::= GROUP|TIES",
+
 /* 335 */ "window_clause ::= WINDOW windowdefn_list",
+
 /* 336 */ "filter_over ::= filter_clause over_clause",
+
 /* 337 */ "filter_over ::= over_clause",
+
 /* 338 */ "filter_over ::= filter_clause",
+
 /* 339 */ "over_clause ::= OVER LP window RP",
+
 /* 340 */ "over_clause ::= OVER nm",
+
 /* 341 */ "filter_clause ::= FILTER LP WHERE expr RP",
+
 /* 342 */ "input ::= cmdlist",
+
 /* 343 */ "cmdlist ::= cmdlist ecmd",
+
 /* 344 */ "cmdlist ::= ecmd",
+
 /* 345 */ "ecmd ::= SEMI",
+
 /* 346 */ "ecmd ::= cmdx SEMI",
+
 /* 347 */ "ecmd ::= explain cmdx SEMI",
+
 /* 348 */ "trans_opt ::=",
+
 /* 349 */ "trans_opt ::= TRANSACTION",
+
 /* 350 */ "trans_opt ::= TRANSACTION nm",
+
 /* 351 */ "savepoint_opt ::= SAVEPOINT",
+
 /* 352 */ "savepoint_opt ::=",
+
 /* 353 */ "cmd ::= create_table create_table_args",
+
 /* 354 */ "table_option_set ::= table_option",
+
 /* 355 */ "columnlist ::= columnlist COMMA columnname carglist",
+
 /* 356 */ "columnlist ::= columnname carglist",
+
 /* 357 */ "nm ::= ID|INDEXED",
+
 /* 358 */ "nm ::= STRING",
+
 /* 359 */ "nm ::= JOIN_KW",
+
 /* 360 */ "typetoken ::= typename",
+
 /* 361 */ "typename ::= ID|STRING",
+
 /* 362 */ "signed ::= plus_num",
+
 /* 363 */ "signed ::= minus_num",
+
 /* 364 */ "carglist ::= carglist ccons",
+
 /* 365 */ "carglist ::=",
+
 /* 366 */ "ccons ::= NULL onconf",
+
 /* 367 */ "ccons ::= GENERATED ALWAYS AS generated",
+
 /* 368 */ "ccons ::= AS generated",
+
 /* 369 */ "conslist_opt ::= COMMA conslist",
+
 /* 370 */ "conslist ::= conslist tconscomma tcons",
+
 /* 371 */ "conslist ::= tcons",
+
 /* 372 */ "tconscomma ::=",
+
 /* 373 */ "defer_subclause_opt ::= defer_subclause",
+
 /* 374 */ "resolvetype ::= raisetype",
+
 /* 375 */ "selectnowith ::= oneselect",
+
 /* 376 */ "oneselect ::= values",
+
 /* 377 */ "sclp ::= selcollist COMMA",
+
 /* 378 */ "as ::= ID|STRING",
+
 /* 379 */ "indexed_opt ::= indexed_by",
+
 /* 380 */ "returning ::=",
+
 /* 381 */ "expr ::= term",
+
 /* 382 */ "likeop ::= LIKE_KW|MATCH",
+
 /* 383 */ "exprlist ::= nexprlist",
+
 /* 384 */ "nmnum ::= plus_num",
+
 /* 385 */ "nmnum ::= nm",
+
 /* 386 */ "nmnum ::= ON",
+
 /* 387 */ "nmnum ::= DELETE",
+
 /* 388 */ "nmnum ::= DEFAULT",
+
 /* 389 */ "plus_num ::= INTEGER|FLOAT",
+
 /* 390 */ "foreach_clause ::=",
+
 /* 391 */ "foreach_clause ::= FOR EACH ROW",
+
 /* 392 */ "trnm ::= nm",
+
 /* 393 */ "tridxby ::=",
+
 /* 394 */ "database_kw_opt ::= DATABASE",
+
 /* 395 */ "database_kw_opt ::=",
+
 /* 396 */ "kwcolumn_opt ::=",
+
 /* 397 */ "kwcolumn_opt ::= COLUMNKW",
+
 /* 398 */ "vtabarglist ::= vtabarg",
+
 /* 399 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+
 /* 400 */ "vtabarg ::= vtabarg vtabargtoken",
+
 /* 401 */ "anylist ::=",
+
 /* 402 */ "anylist ::= anylist LP anylist RP",
+
 /* 403 */ "anylist ::= anylist ANY",
+
 /* 404 */ "with ::=",
};
#endif /* NDEBUG */

@@ -163753,7 +165787,6 @@ sqlite3SelectDelete(pParse->db, (yypminor->yy47));
    case 217: /* expr */
    case 246: /* where_opt */
    case 248: /* having_opt */
-
    case 260: /* on_opt */
    case 267: /* where_opt_ret */
    case 278: /* case_operand */
    case 280: /* case_else */
@@ -163773,7 +165806,7 @@ sqlite3ExprDelete(pParse->db, (yypminor->yy528));
    case 249: /* orderby_opt */
    case 253: /* nexprlist */
    case 254: /* sclp */
-
    case 262: /* exprlist */
+
    case 261: /* exprlist */
    case 268: /* setlist */
    case 277: /* paren_exprlist */
    case 279: /* case_exprlist */
@@ -163786,7 +165819,7 @@ sqlite3ExprListDelete(pParse->db, (yypminor->yy322));
    case 245: /* from */
    case 256: /* seltablist */
    case 257: /* stl_prefix */
-
    case 263: /* xfullname */
+
    case 262: /* xfullname */
{
sqlite3SrcListDelete(pParse->db, (yypminor->yy131));
}
@@ -163802,8 +165835,7 @@ sqlite3WithDelete(pParse->db, (yypminor->yy521));
sqlite3WindowListDelete(pParse->db, (yypminor->yy41));
}
      break;
-
    case 261: /* using_opt */
-
    case 264: /* idlist */
+
    case 263: /* idlist */
    case 270: /* idlist_opt */
{
sqlite3IdListDelete(pParse->db, (yypminor->yy254));
@@ -164233,29 +166265,29 @@ static const YYCODETYPE yyRuleInfoLhs[] = {
   245,  /* (106) from ::= FROM seltablist */
   257,  /* (107) stl_prefix ::= seltablist joinop */
   257,  /* (108) stl_prefix ::= */
-
   256,  /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
-
   256,  /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
-
   256,  /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
-
   256,  /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
-
   200,  /* (113) dbnm ::= */
-
   200,  /* (114) dbnm ::= DOT nm */
-
   238,  /* (115) fullname ::= nm */
-
   238,  /* (116) fullname ::= nm DOT nm */
-
   263,  /* (117) xfullname ::= nm */
-
   263,  /* (118) xfullname ::= nm DOT nm */
-
   263,  /* (119) xfullname ::= nm DOT nm AS nm */
-
   263,  /* (120) xfullname ::= nm AS nm */
-
   258,  /* (121) joinop ::= COMMA|JOIN */
-
   258,  /* (122) joinop ::= JOIN_KW JOIN */
-
   258,  /* (123) joinop ::= JOIN_KW nm JOIN */
-
   258,  /* (124) joinop ::= JOIN_KW nm nm JOIN */
-
   260,  /* (125) on_opt ::= ON expr */
-
   260,  /* (126) on_opt ::= */
-
   259,  /* (127) indexed_opt ::= */
-
   259,  /* (128) indexed_opt ::= INDEXED BY nm */
-
   259,  /* (129) indexed_opt ::= NOT INDEXED */
-
   261,  /* (130) using_opt ::= USING LP idlist RP */
-
   261,  /* (131) using_opt ::= */
+
   256,  /* (109) seltablist ::= stl_prefix nm dbnm as on_using */
+
   256,  /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
+
   256,  /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
+
   256,  /* (112) seltablist ::= stl_prefix LP select RP as on_using */
+
   256,  /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */
+
   200,  /* (114) dbnm ::= */
+
   200,  /* (115) dbnm ::= DOT nm */
+
   238,  /* (116) fullname ::= nm */
+
   238,  /* (117) fullname ::= nm DOT nm */
+
   262,  /* (118) xfullname ::= nm */
+
   262,  /* (119) xfullname ::= nm DOT nm */
+
   262,  /* (120) xfullname ::= nm DOT nm AS nm */
+
   262,  /* (121) xfullname ::= nm AS nm */
+
   258,  /* (122) joinop ::= COMMA|JOIN */
+
   258,  /* (123) joinop ::= JOIN_KW JOIN */
+
   258,  /* (124) joinop ::= JOIN_KW nm JOIN */
+
   258,  /* (125) joinop ::= JOIN_KW nm nm JOIN */
+
   259,  /* (126) on_using ::= ON expr */
+
   259,  /* (127) on_using ::= USING LP idlist RP */
+
   259,  /* (128) on_using ::= */
+
   264,  /* (129) indexed_opt ::= */
+
   260,  /* (130) indexed_by ::= INDEXED BY nm */
+
   260,  /* (131) indexed_by ::= NOT INDEXED */
   249,  /* (132) orderby_opt ::= */
   249,  /* (133) orderby_opt ::= ORDER BY sortlist */
   231,  /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */
@@ -164299,8 +166331,8 @@ static const YYCODETYPE yyRuleInfoLhs[] = {
   269,  /* (172) insert_cmd ::= REPLACE */
   270,  /* (173) idlist_opt ::= */
   270,  /* (174) idlist_opt ::= LP idlist RP */
-
   264,  /* (175) idlist ::= idlist COMMA nm */
-
   264,  /* (176) idlist ::= nm */
+
   263,  /* (175) idlist ::= idlist COMMA nm */
+
   263,  /* (176) idlist ::= nm */
   217,  /* (177) expr ::= LP expr RP */
   217,  /* (178) expr ::= ID|INDEXED */
   217,  /* (179) expr ::= JOIN_KW */
@@ -164333,199 +166365,202 @@ static const YYCODETYPE yyRuleInfoLhs[] = {
   217,  /* (206) expr ::= expr NOT NULL */
   217,  /* (207) expr ::= expr IS expr */
   217,  /* (208) expr ::= expr IS NOT expr */
-
   217,  /* (209) expr ::= NOT expr */
-
   217,  /* (210) expr ::= BITNOT expr */
-
   217,  /* (211) expr ::= PLUS|MINUS expr */
-
   217,  /* (212) expr ::= expr PTR expr */
-
   275,  /* (213) between_op ::= BETWEEN */
-
   275,  /* (214) between_op ::= NOT BETWEEN */
-
   217,  /* (215) expr ::= expr between_op expr AND expr */
-
   276,  /* (216) in_op ::= IN */
-
   276,  /* (217) in_op ::= NOT IN */
-
   217,  /* (218) expr ::= expr in_op LP exprlist RP */
-
   217,  /* (219) expr ::= LP select RP */
-
   217,  /* (220) expr ::= expr in_op LP select RP */
-
   217,  /* (221) expr ::= expr in_op nm dbnm paren_exprlist */
-
   217,  /* (222) expr ::= EXISTS LP select RP */
-
   217,  /* (223) expr ::= CASE case_operand case_exprlist case_else END */
-
   279,  /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */
-
   279,  /* (225) case_exprlist ::= WHEN expr THEN expr */
-
   280,  /* (226) case_else ::= ELSE expr */
-
   280,  /* (227) case_else ::= */
-
   278,  /* (228) case_operand ::= expr */
-
   278,  /* (229) case_operand ::= */
-
   262,  /* (230) exprlist ::= */
-
   253,  /* (231) nexprlist ::= nexprlist COMMA expr */
-
   253,  /* (232) nexprlist ::= expr */
-
   277,  /* (233) paren_exprlist ::= */
-
   277,  /* (234) paren_exprlist ::= LP exprlist RP */
-
   190,  /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
-
   281,  /* (236) uniqueflag ::= UNIQUE */
-
   281,  /* (237) uniqueflag ::= */
-
   221,  /* (238) eidlist_opt ::= */
-
   221,  /* (239) eidlist_opt ::= LP eidlist RP */
-
   232,  /* (240) eidlist ::= eidlist COMMA nm collate sortorder */
-
   232,  /* (241) eidlist ::= nm collate sortorder */
-
   282,  /* (242) collate ::= */
-
   282,  /* (243) collate ::= COLLATE ID|STRING */
-
   190,  /* (244) cmd ::= DROP INDEX ifexists fullname */
-
   190,  /* (245) cmd ::= VACUUM vinto */
-
   190,  /* (246) cmd ::= VACUUM nm vinto */
-
   283,  /* (247) vinto ::= INTO expr */
-
   283,  /* (248) vinto ::= */
-
   190,  /* (249) cmd ::= PRAGMA nm dbnm */
-
   190,  /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */
-
   190,  /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */
-
   190,  /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */
-
   190,  /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */
-
   211,  /* (254) plus_num ::= PLUS INTEGER|FLOAT */
-
   212,  /* (255) minus_num ::= MINUS INTEGER|FLOAT */
-
   190,  /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
-
   285,  /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
-
   287,  /* (258) trigger_time ::= BEFORE|AFTER */
-
   287,  /* (259) trigger_time ::= INSTEAD OF */
-
   287,  /* (260) trigger_time ::= */
-
   288,  /* (261) trigger_event ::= DELETE|INSERT */
-
   288,  /* (262) trigger_event ::= UPDATE */
-
   288,  /* (263) trigger_event ::= UPDATE OF idlist */
-
   290,  /* (264) when_clause ::= */
-
   290,  /* (265) when_clause ::= WHEN expr */
-
   286,  /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
-
   286,  /* (267) trigger_cmd_list ::= trigger_cmd SEMI */
-
   292,  /* (268) trnm ::= nm DOT nm */
-
   293,  /* (269) tridxby ::= INDEXED BY nm */
-
   293,  /* (270) tridxby ::= NOT INDEXED */
-
   291,  /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
-
   291,  /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
-
   291,  /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
-
   291,  /* (274) trigger_cmd ::= scanpt select scanpt */
-
   217,  /* (275) expr ::= RAISE LP IGNORE RP */
-
   217,  /* (276) expr ::= RAISE LP raisetype COMMA nm RP */
-
   236,  /* (277) raisetype ::= ROLLBACK */
-
   236,  /* (278) raisetype ::= ABORT */
-
   236,  /* (279) raisetype ::= FAIL */
-
   190,  /* (280) cmd ::= DROP TRIGGER ifexists fullname */
-
   190,  /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
-
   190,  /* (282) cmd ::= DETACH database_kw_opt expr */
-
   295,  /* (283) key_opt ::= */
-
   295,  /* (284) key_opt ::= KEY expr */
-
   190,  /* (285) cmd ::= REINDEX */
-
   190,  /* (286) cmd ::= REINDEX nm dbnm */
-
   190,  /* (287) cmd ::= ANALYZE */
-
   190,  /* (288) cmd ::= ANALYZE nm dbnm */
-
   190,  /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */
-
   190,  /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
-
   190,  /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
-
   296,  /* (292) add_column_fullname ::= fullname */
-
   190,  /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
-
   190,  /* (294) cmd ::= create_vtab */
-
   190,  /* (295) cmd ::= create_vtab LP vtabarglist RP */
-
   298,  /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
-
   300,  /* (297) vtabarg ::= */
-
   301,  /* (298) vtabargtoken ::= ANY */
-
   301,  /* (299) vtabargtoken ::= lp anylist RP */
-
   302,  /* (300) lp ::= LP */
-
   266,  /* (301) with ::= WITH wqlist */
-
   266,  /* (302) with ::= WITH RECURSIVE wqlist */
-
   305,  /* (303) wqas ::= AS */
-
   305,  /* (304) wqas ::= AS MATERIALIZED */
-
   305,  /* (305) wqas ::= AS NOT MATERIALIZED */
-
   304,  /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */
-
   241,  /* (307) wqlist ::= wqitem */
-
   241,  /* (308) wqlist ::= wqlist COMMA wqitem */
-
   306,  /* (309) windowdefn_list ::= windowdefn */
-
   306,  /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */
-
   307,  /* (311) windowdefn ::= nm AS LP window RP */
-
   308,  /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
-
   308,  /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
-
   308,  /* (314) window ::= ORDER BY sortlist frame_opt */
-
   308,  /* (315) window ::= nm ORDER BY sortlist frame_opt */
-
   308,  /* (316) window ::= frame_opt */
-
   308,  /* (317) window ::= nm frame_opt */
-
   309,  /* (318) frame_opt ::= */
-
   309,  /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
-
   309,  /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
-
   313,  /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */
-
   315,  /* (322) frame_bound_s ::= frame_bound */
-
   315,  /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */
-
   316,  /* (324) frame_bound_e ::= frame_bound */
-
   316,  /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */
-
   314,  /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */
-
   314,  /* (327) frame_bound ::= CURRENT ROW */
-
   317,  /* (328) frame_exclude_opt ::= */
-
   317,  /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */
-
   318,  /* (330) frame_exclude ::= NO OTHERS */
-
   318,  /* (331) frame_exclude ::= CURRENT ROW */
-
   318,  /* (332) frame_exclude ::= GROUP|TIES */
-
   251,  /* (333) window_clause ::= WINDOW windowdefn_list */
-
   273,  /* (334) filter_over ::= filter_clause over_clause */
-
   273,  /* (335) filter_over ::= over_clause */
-
   273,  /* (336) filter_over ::= filter_clause */
-
   312,  /* (337) over_clause ::= OVER LP window RP */
-
   312,  /* (338) over_clause ::= OVER nm */
-
   311,  /* (339) filter_clause ::= FILTER LP WHERE expr RP */
-
   185,  /* (340) input ::= cmdlist */
-
   186,  /* (341) cmdlist ::= cmdlist ecmd */
-
   186,  /* (342) cmdlist ::= ecmd */
-
   187,  /* (343) ecmd ::= SEMI */
-
   187,  /* (344) ecmd ::= cmdx SEMI */
-
   187,  /* (345) ecmd ::= explain cmdx SEMI */
-
   192,  /* (346) trans_opt ::= */
-
   192,  /* (347) trans_opt ::= TRANSACTION */
-
   192,  /* (348) trans_opt ::= TRANSACTION nm */
-
   194,  /* (349) savepoint_opt ::= SAVEPOINT */
-
   194,  /* (350) savepoint_opt ::= */
-
   190,  /* (351) cmd ::= create_table create_table_args */
-
   203,  /* (352) table_option_set ::= table_option */
-
   201,  /* (353) columnlist ::= columnlist COMMA columnname carglist */
-
   201,  /* (354) columnlist ::= columnname carglist */
-
   193,  /* (355) nm ::= ID|INDEXED */
-
   193,  /* (356) nm ::= STRING */
-
   193,  /* (357) nm ::= JOIN_KW */
-
   208,  /* (358) typetoken ::= typename */
-
   209,  /* (359) typename ::= ID|STRING */
-
   210,  /* (360) signed ::= plus_num */
-
   210,  /* (361) signed ::= minus_num */
-
   207,  /* (362) carglist ::= carglist ccons */
-
   207,  /* (363) carglist ::= */
-
   215,  /* (364) ccons ::= NULL onconf */
-
   215,  /* (365) ccons ::= GENERATED ALWAYS AS generated */
-
   215,  /* (366) ccons ::= AS generated */
-
   202,  /* (367) conslist_opt ::= COMMA conslist */
-
   228,  /* (368) conslist ::= conslist tconscomma tcons */
-
   228,  /* (369) conslist ::= tcons */
-
   229,  /* (370) tconscomma ::= */
-
   233,  /* (371) defer_subclause_opt ::= defer_subclause */
-
   235,  /* (372) resolvetype ::= raisetype */
-
   239,  /* (373) selectnowith ::= oneselect */
-
   240,  /* (374) oneselect ::= values */
-
   254,  /* (375) sclp ::= selcollist COMMA */
-
   255,  /* (376) as ::= ID|STRING */
-
   272,  /* (377) returning ::= */
-
   217,  /* (378) expr ::= term */
-
   274,  /* (379) likeop ::= LIKE_KW|MATCH */
-
   262,  /* (380) exprlist ::= nexprlist */
-
   284,  /* (381) nmnum ::= plus_num */
-
   284,  /* (382) nmnum ::= nm */
-
   284,  /* (383) nmnum ::= ON */
-
   284,  /* (384) nmnum ::= DELETE */
-
   284,  /* (385) nmnum ::= DEFAULT */
-
   211,  /* (386) plus_num ::= INTEGER|FLOAT */
-
   289,  /* (387) foreach_clause ::= */
-
   289,  /* (388) foreach_clause ::= FOR EACH ROW */
-
   292,  /* (389) trnm ::= nm */
-
   293,  /* (390) tridxby ::= */
-
   294,  /* (391) database_kw_opt ::= DATABASE */
-
   294,  /* (392) database_kw_opt ::= */
-
   297,  /* (393) kwcolumn_opt ::= */
-
   297,  /* (394) kwcolumn_opt ::= COLUMNKW */
-
   299,  /* (395) vtabarglist ::= vtabarg */
-
   299,  /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */
-
   300,  /* (397) vtabarg ::= vtabarg vtabargtoken */
-
   303,  /* (398) anylist ::= */
-
   303,  /* (399) anylist ::= anylist LP anylist RP */
-
   303,  /* (400) anylist ::= anylist ANY */
-
   266,  /* (401) with ::= */
+
   217,  /* (209) expr ::= expr IS NOT DISTINCT FROM expr */
+
   217,  /* (210) expr ::= expr IS DISTINCT FROM expr */
+
   217,  /* (211) expr ::= NOT expr */
+
   217,  /* (212) expr ::= BITNOT expr */
+
   217,  /* (213) expr ::= PLUS|MINUS expr */
+
   217,  /* (214) expr ::= expr PTR expr */
+
   275,  /* (215) between_op ::= BETWEEN */
+
   275,  /* (216) between_op ::= NOT BETWEEN */
+
   217,  /* (217) expr ::= expr between_op expr AND expr */
+
   276,  /* (218) in_op ::= IN */
+
   276,  /* (219) in_op ::= NOT IN */
+
   217,  /* (220) expr ::= expr in_op LP exprlist RP */
+
   217,  /* (221) expr ::= LP select RP */
+
   217,  /* (222) expr ::= expr in_op LP select RP */
+
   217,  /* (223) expr ::= expr in_op nm dbnm paren_exprlist */
+
   217,  /* (224) expr ::= EXISTS LP select RP */
+
   217,  /* (225) expr ::= CASE case_operand case_exprlist case_else END */
+
   279,  /* (226) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+
   279,  /* (227) case_exprlist ::= WHEN expr THEN expr */
+
   280,  /* (228) case_else ::= ELSE expr */
+
   280,  /* (229) case_else ::= */
+
   278,  /* (230) case_operand ::= expr */
+
   278,  /* (231) case_operand ::= */
+
   261,  /* (232) exprlist ::= */
+
   253,  /* (233) nexprlist ::= nexprlist COMMA expr */
+
   253,  /* (234) nexprlist ::= expr */
+
   277,  /* (235) paren_exprlist ::= */
+
   277,  /* (236) paren_exprlist ::= LP exprlist RP */
+
   190,  /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+
   281,  /* (238) uniqueflag ::= UNIQUE */
+
   281,  /* (239) uniqueflag ::= */
+
   221,  /* (240) eidlist_opt ::= */
+
   221,  /* (241) eidlist_opt ::= LP eidlist RP */
+
   232,  /* (242) eidlist ::= eidlist COMMA nm collate sortorder */
+
   232,  /* (243) eidlist ::= nm collate sortorder */
+
   282,  /* (244) collate ::= */
+
   282,  /* (245) collate ::= COLLATE ID|STRING */
+
   190,  /* (246) cmd ::= DROP INDEX ifexists fullname */
+
   190,  /* (247) cmd ::= VACUUM vinto */
+
   190,  /* (248) cmd ::= VACUUM nm vinto */
+
   283,  /* (249) vinto ::= INTO expr */
+
   283,  /* (250) vinto ::= */
+
   190,  /* (251) cmd ::= PRAGMA nm dbnm */
+
   190,  /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */
+
   190,  /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+
   190,  /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */
+
   190,  /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+
   211,  /* (256) plus_num ::= PLUS INTEGER|FLOAT */
+
   212,  /* (257) minus_num ::= MINUS INTEGER|FLOAT */
+
   190,  /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+
   285,  /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+
   287,  /* (260) trigger_time ::= BEFORE|AFTER */
+
   287,  /* (261) trigger_time ::= INSTEAD OF */
+
   287,  /* (262) trigger_time ::= */
+
   288,  /* (263) trigger_event ::= DELETE|INSERT */
+
   288,  /* (264) trigger_event ::= UPDATE */
+
   288,  /* (265) trigger_event ::= UPDATE OF idlist */
+
   290,  /* (266) when_clause ::= */
+
   290,  /* (267) when_clause ::= WHEN expr */
+
   286,  /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+
   286,  /* (269) trigger_cmd_list ::= trigger_cmd SEMI */
+
   292,  /* (270) trnm ::= nm DOT nm */
+
   293,  /* (271) tridxby ::= INDEXED BY nm */
+
   293,  /* (272) tridxby ::= NOT INDEXED */
+
   291,  /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
+
   291,  /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+
   291,  /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+
   291,  /* (276) trigger_cmd ::= scanpt select scanpt */
+
   217,  /* (277) expr ::= RAISE LP IGNORE RP */
+
   217,  /* (278) expr ::= RAISE LP raisetype COMMA nm RP */
+
   236,  /* (279) raisetype ::= ROLLBACK */
+
   236,  /* (280) raisetype ::= ABORT */
+
   236,  /* (281) raisetype ::= FAIL */
+
   190,  /* (282) cmd ::= DROP TRIGGER ifexists fullname */
+
   190,  /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+
   190,  /* (284) cmd ::= DETACH database_kw_opt expr */
+
   295,  /* (285) key_opt ::= */
+
   295,  /* (286) key_opt ::= KEY expr */
+
   190,  /* (287) cmd ::= REINDEX */
+
   190,  /* (288) cmd ::= REINDEX nm dbnm */
+
   190,  /* (289) cmd ::= ANALYZE */
+
   190,  /* (290) cmd ::= ANALYZE nm dbnm */
+
   190,  /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */
+
   190,  /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+
   190,  /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
+
   296,  /* (294) add_column_fullname ::= fullname */
+
   190,  /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+
   190,  /* (296) cmd ::= create_vtab */
+
   190,  /* (297) cmd ::= create_vtab LP vtabarglist RP */
+
   298,  /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+
   300,  /* (299) vtabarg ::= */
+
   301,  /* (300) vtabargtoken ::= ANY */
+
   301,  /* (301) vtabargtoken ::= lp anylist RP */
+
   302,  /* (302) lp ::= LP */
+
   266,  /* (303) with ::= WITH wqlist */
+
   266,  /* (304) with ::= WITH RECURSIVE wqlist */
+
   305,  /* (305) wqas ::= AS */
+
   305,  /* (306) wqas ::= AS MATERIALIZED */
+
   305,  /* (307) wqas ::= AS NOT MATERIALIZED */
+
   304,  /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */
+
   241,  /* (309) wqlist ::= wqitem */
+
   241,  /* (310) wqlist ::= wqlist COMMA wqitem */
+
   306,  /* (311) windowdefn_list ::= windowdefn */
+
   306,  /* (312) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+
   307,  /* (313) windowdefn ::= nm AS LP window RP */
+
   308,  /* (314) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+
   308,  /* (315) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+
   308,  /* (316) window ::= ORDER BY sortlist frame_opt */
+
   308,  /* (317) window ::= nm ORDER BY sortlist frame_opt */
+
   308,  /* (318) window ::= frame_opt */
+
   308,  /* (319) window ::= nm frame_opt */
+
   309,  /* (320) frame_opt ::= */
+
   309,  /* (321) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+
   309,  /* (322) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+
   313,  /* (323) range_or_rows ::= RANGE|ROWS|GROUPS */
+
   315,  /* (324) frame_bound_s ::= frame_bound */
+
   315,  /* (325) frame_bound_s ::= UNBOUNDED PRECEDING */
+
   316,  /* (326) frame_bound_e ::= frame_bound */
+
   316,  /* (327) frame_bound_e ::= UNBOUNDED FOLLOWING */
+
   314,  /* (328) frame_bound ::= expr PRECEDING|FOLLOWING */
+
   314,  /* (329) frame_bound ::= CURRENT ROW */
+
   317,  /* (330) frame_exclude_opt ::= */
+
   317,  /* (331) frame_exclude_opt ::= EXCLUDE frame_exclude */
+
   318,  /* (332) frame_exclude ::= NO OTHERS */
+
   318,  /* (333) frame_exclude ::= CURRENT ROW */
+
   318,  /* (334) frame_exclude ::= GROUP|TIES */
+
   251,  /* (335) window_clause ::= WINDOW windowdefn_list */
+
   273,  /* (336) filter_over ::= filter_clause over_clause */
+
   273,  /* (337) filter_over ::= over_clause */
+
   273,  /* (338) filter_over ::= filter_clause */
+
   312,  /* (339) over_clause ::= OVER LP window RP */
+
   312,  /* (340) over_clause ::= OVER nm */
+
   311,  /* (341) filter_clause ::= FILTER LP WHERE expr RP */
+
   185,  /* (342) input ::= cmdlist */
+
   186,  /* (343) cmdlist ::= cmdlist ecmd */
+
   186,  /* (344) cmdlist ::= ecmd */
+
   187,  /* (345) ecmd ::= SEMI */
+
   187,  /* (346) ecmd ::= cmdx SEMI */
+
   187,  /* (347) ecmd ::= explain cmdx SEMI */
+
   192,  /* (348) trans_opt ::= */
+
   192,  /* (349) trans_opt ::= TRANSACTION */
+
   192,  /* (350) trans_opt ::= TRANSACTION nm */
+
   194,  /* (351) savepoint_opt ::= SAVEPOINT */
+
   194,  /* (352) savepoint_opt ::= */
+
   190,  /* (353) cmd ::= create_table create_table_args */
+
   203,  /* (354) table_option_set ::= table_option */
+
   201,  /* (355) columnlist ::= columnlist COMMA columnname carglist */
+
   201,  /* (356) columnlist ::= columnname carglist */
+
   193,  /* (357) nm ::= ID|INDEXED */
+
   193,  /* (358) nm ::= STRING */
+
   193,  /* (359) nm ::= JOIN_KW */
+
   208,  /* (360) typetoken ::= typename */
+
   209,  /* (361) typename ::= ID|STRING */
+
   210,  /* (362) signed ::= plus_num */
+
   210,  /* (363) signed ::= minus_num */
+
   207,  /* (364) carglist ::= carglist ccons */
+
   207,  /* (365) carglist ::= */
+
   215,  /* (366) ccons ::= NULL onconf */
+
   215,  /* (367) ccons ::= GENERATED ALWAYS AS generated */
+
   215,  /* (368) ccons ::= AS generated */
+
   202,  /* (369) conslist_opt ::= COMMA conslist */
+
   228,  /* (370) conslist ::= conslist tconscomma tcons */
+
   228,  /* (371) conslist ::= tcons */
+
   229,  /* (372) tconscomma ::= */
+
   233,  /* (373) defer_subclause_opt ::= defer_subclause */
+
   235,  /* (374) resolvetype ::= raisetype */
+
   239,  /* (375) selectnowith ::= oneselect */
+
   240,  /* (376) oneselect ::= values */
+
   254,  /* (377) sclp ::= selcollist COMMA */
+
   255,  /* (378) as ::= ID|STRING */
+
   264,  /* (379) indexed_opt ::= indexed_by */
+
   272,  /* (380) returning ::= */
+
   217,  /* (381) expr ::= term */
+
   274,  /* (382) likeop ::= LIKE_KW|MATCH */
+
   261,  /* (383) exprlist ::= nexprlist */
+
   284,  /* (384) nmnum ::= plus_num */
+
   284,  /* (385) nmnum ::= nm */
+
   284,  /* (386) nmnum ::= ON */
+
   284,  /* (387) nmnum ::= DELETE */
+
   284,  /* (388) nmnum ::= DEFAULT */
+
   211,  /* (389) plus_num ::= INTEGER|FLOAT */
+
   289,  /* (390) foreach_clause ::= */
+
   289,  /* (391) foreach_clause ::= FOR EACH ROW */
+
   292,  /* (392) trnm ::= nm */
+
   293,  /* (393) tridxby ::= */
+
   294,  /* (394) database_kw_opt ::= DATABASE */
+
   294,  /* (395) database_kw_opt ::= */
+
   297,  /* (396) kwcolumn_opt ::= */
+
   297,  /* (397) kwcolumn_opt ::= COLUMNKW */
+
   299,  /* (398) vtabarglist ::= vtabarg */
+
   299,  /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */
+
   300,  /* (400) vtabarg ::= vtabarg vtabargtoken */
+
   303,  /* (401) anylist ::= */
+
   303,  /* (402) anylist ::= anylist LP anylist RP */
+
   303,  /* (403) anylist ::= anylist ANY */
+
   266,  /* (404) with ::= */
};

/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
@@ -164640,29 +166675,29 @@ static const signed char yyRuleInfoNRhs[] = {
   -2,  /* (106) from ::= FROM seltablist */
   -2,  /* (107) stl_prefix ::= seltablist joinop */
    0,  /* (108) stl_prefix ::= */
-
   -7,  /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
-
   -9,  /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
-
   -7,  /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */
-
   -7,  /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
-
    0,  /* (113) dbnm ::= */
-
   -2,  /* (114) dbnm ::= DOT nm */
-
   -1,  /* (115) fullname ::= nm */
-
   -3,  /* (116) fullname ::= nm DOT nm */
-
   -1,  /* (117) xfullname ::= nm */
-
   -3,  /* (118) xfullname ::= nm DOT nm */
-
   -5,  /* (119) xfullname ::= nm DOT nm AS nm */
-
   -3,  /* (120) xfullname ::= nm AS nm */
-
   -1,  /* (121) joinop ::= COMMA|JOIN */
-
   -2,  /* (122) joinop ::= JOIN_KW JOIN */
-
   -3,  /* (123) joinop ::= JOIN_KW nm JOIN */
-
   -4,  /* (124) joinop ::= JOIN_KW nm nm JOIN */
-
   -2,  /* (125) on_opt ::= ON expr */
-
    0,  /* (126) on_opt ::= */
-
    0,  /* (127) indexed_opt ::= */
-
   -3,  /* (128) indexed_opt ::= INDEXED BY nm */
-
   -2,  /* (129) indexed_opt ::= NOT INDEXED */
-
   -4,  /* (130) using_opt ::= USING LP idlist RP */
-
    0,  /* (131) using_opt ::= */
+
   -5,  /* (109) seltablist ::= stl_prefix nm dbnm as on_using */
+
   -6,  /* (110) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
+
   -8,  /* (111) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
+
   -6,  /* (112) seltablist ::= stl_prefix LP select RP as on_using */
+
   -6,  /* (113) seltablist ::= stl_prefix LP seltablist RP as on_using */
+
    0,  /* (114) dbnm ::= */
+
   -2,  /* (115) dbnm ::= DOT nm */
+
   -1,  /* (116) fullname ::= nm */
+
   -3,  /* (117) fullname ::= nm DOT nm */
+
   -1,  /* (118) xfullname ::= nm */
+
   -3,  /* (119) xfullname ::= nm DOT nm */
+
   -5,  /* (120) xfullname ::= nm DOT nm AS nm */
+
   -3,  /* (121) xfullname ::= nm AS nm */
+
   -1,  /* (122) joinop ::= COMMA|JOIN */
+
   -2,  /* (123) joinop ::= JOIN_KW JOIN */
+
   -3,  /* (124) joinop ::= JOIN_KW nm JOIN */
+
   -4,  /* (125) joinop ::= JOIN_KW nm nm JOIN */
+
   -2,  /* (126) on_using ::= ON expr */
+
   -4,  /* (127) on_using ::= USING LP idlist RP */
+
    0,  /* (128) on_using ::= */
+
    0,  /* (129) indexed_opt ::= */
+
   -3,  /* (130) indexed_by ::= INDEXED BY nm */
+
   -2,  /* (131) indexed_by ::= NOT INDEXED */
    0,  /* (132) orderby_opt ::= */
   -3,  /* (133) orderby_opt ::= ORDER BY sortlist */
   -5,  /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */
@@ -164740,199 +166775,202 @@ static const signed char yyRuleInfoNRhs[] = {
   -3,  /* (206) expr ::= expr NOT NULL */
   -3,  /* (207) expr ::= expr IS expr */
   -4,  /* (208) expr ::= expr IS NOT expr */
-
   -2,  /* (209) expr ::= NOT expr */
-
   -2,  /* (210) expr ::= BITNOT expr */
-
   -2,  /* (211) expr ::= PLUS|MINUS expr */
-
   -3,  /* (212) expr ::= expr PTR expr */
-
   -1,  /* (213) between_op ::= BETWEEN */
-
   -2,  /* (214) between_op ::= NOT BETWEEN */
-
   -5,  /* (215) expr ::= expr between_op expr AND expr */
-
   -1,  /* (216) in_op ::= IN */
-
   -2,  /* (217) in_op ::= NOT IN */
-
   -5,  /* (218) expr ::= expr in_op LP exprlist RP */
-
   -3,  /* (219) expr ::= LP select RP */
-
   -5,  /* (220) expr ::= expr in_op LP select RP */
-
   -5,  /* (221) expr ::= expr in_op nm dbnm paren_exprlist */
-
   -4,  /* (222) expr ::= EXISTS LP select RP */
-
   -5,  /* (223) expr ::= CASE case_operand case_exprlist case_else END */
-
   -5,  /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */
-
   -4,  /* (225) case_exprlist ::= WHEN expr THEN expr */
-
   -2,  /* (226) case_else ::= ELSE expr */
-
    0,  /* (227) case_else ::= */
-
   -1,  /* (228) case_operand ::= expr */
-
    0,  /* (229) case_operand ::= */
-
    0,  /* (230) exprlist ::= */
-
   -3,  /* (231) nexprlist ::= nexprlist COMMA expr */
-
   -1,  /* (232) nexprlist ::= expr */
-
    0,  /* (233) paren_exprlist ::= */
-
   -3,  /* (234) paren_exprlist ::= LP exprlist RP */
-
  -12,  /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
-
   -1,  /* (236) uniqueflag ::= UNIQUE */
-
    0,  /* (237) uniqueflag ::= */
-
    0,  /* (238) eidlist_opt ::= */
-
   -3,  /* (239) eidlist_opt ::= LP eidlist RP */
-
   -5,  /* (240) eidlist ::= eidlist COMMA nm collate sortorder */
-
   -3,  /* (241) eidlist ::= nm collate sortorder */
-
    0,  /* (242) collate ::= */
-
   -2,  /* (243) collate ::= COLLATE ID|STRING */
-
   -4,  /* (244) cmd ::= DROP INDEX ifexists fullname */
-
   -2,  /* (245) cmd ::= VACUUM vinto */
-
   -3,  /* (246) cmd ::= VACUUM nm vinto */
-
   -2,  /* (247) vinto ::= INTO expr */
-
    0,  /* (248) vinto ::= */
-
   -3,  /* (249) cmd ::= PRAGMA nm dbnm */
-
   -5,  /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */
-
   -6,  /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */
-
   -5,  /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */
-
   -6,  /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */
-
   -2,  /* (254) plus_num ::= PLUS INTEGER|FLOAT */
-
   -2,  /* (255) minus_num ::= MINUS INTEGER|FLOAT */
-
   -5,  /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
-
  -11,  /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
-
   -1,  /* (258) trigger_time ::= BEFORE|AFTER */
-
   -2,  /* (259) trigger_time ::= INSTEAD OF */
-
    0,  /* (260) trigger_time ::= */
-
   -1,  /* (261) trigger_event ::= DELETE|INSERT */
-
   -1,  /* (262) trigger_event ::= UPDATE */
-
   -3,  /* (263) trigger_event ::= UPDATE OF idlist */
-
    0,  /* (264) when_clause ::= */
-
   -2,  /* (265) when_clause ::= WHEN expr */
-
   -3,  /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
-
   -2,  /* (267) trigger_cmd_list ::= trigger_cmd SEMI */
-
   -3,  /* (268) trnm ::= nm DOT nm */
-
   -3,  /* (269) tridxby ::= INDEXED BY nm */
-
   -2,  /* (270) tridxby ::= NOT INDEXED */
-
   -9,  /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
-
   -8,  /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
-
   -6,  /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
-
   -3,  /* (274) trigger_cmd ::= scanpt select scanpt */
-
   -4,  /* (275) expr ::= RAISE LP IGNORE RP */
-
   -6,  /* (276) expr ::= RAISE LP raisetype COMMA nm RP */
-
   -1,  /* (277) raisetype ::= ROLLBACK */
-
   -1,  /* (278) raisetype ::= ABORT */
-
   -1,  /* (279) raisetype ::= FAIL */
-
   -4,  /* (280) cmd ::= DROP TRIGGER ifexists fullname */
-
   -6,  /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
-
   -3,  /* (282) cmd ::= DETACH database_kw_opt expr */
-
    0,  /* (283) key_opt ::= */
-
   -2,  /* (284) key_opt ::= KEY expr */
-
   -1,  /* (285) cmd ::= REINDEX */
-
   -3,  /* (286) cmd ::= REINDEX nm dbnm */
-
   -1,  /* (287) cmd ::= ANALYZE */
-
   -3,  /* (288) cmd ::= ANALYZE nm dbnm */
-
   -6,  /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */
-
   -7,  /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
-
   -6,  /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
-
   -1,  /* (292) add_column_fullname ::= fullname */
-
   -8,  /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
-
   -1,  /* (294) cmd ::= create_vtab */
-
   -4,  /* (295) cmd ::= create_vtab LP vtabarglist RP */
-
   -8,  /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
-
    0,  /* (297) vtabarg ::= */
-
   -1,  /* (298) vtabargtoken ::= ANY */
-
   -3,  /* (299) vtabargtoken ::= lp anylist RP */
-
   -1,  /* (300) lp ::= LP */
-
   -2,  /* (301) with ::= WITH wqlist */
-
   -3,  /* (302) with ::= WITH RECURSIVE wqlist */
-
   -1,  /* (303) wqas ::= AS */
-
   -2,  /* (304) wqas ::= AS MATERIALIZED */
-
   -3,  /* (305) wqas ::= AS NOT MATERIALIZED */
-
   -6,  /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */
-
   -1,  /* (307) wqlist ::= wqitem */
-
   -3,  /* (308) wqlist ::= wqlist COMMA wqitem */
-
   -1,  /* (309) windowdefn_list ::= windowdefn */
-
   -3,  /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */
-
   -5,  /* (311) windowdefn ::= nm AS LP window RP */
-
   -5,  /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
-
   -6,  /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
-
   -4,  /* (314) window ::= ORDER BY sortlist frame_opt */
-
   -5,  /* (315) window ::= nm ORDER BY sortlist frame_opt */
-
   -1,  /* (316) window ::= frame_opt */
-
   -2,  /* (317) window ::= nm frame_opt */
-
    0,  /* (318) frame_opt ::= */
-
   -3,  /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
-
   -6,  /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
-
   -1,  /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */
-
   -1,  /* (322) frame_bound_s ::= frame_bound */
-
   -2,  /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */
-
   -1,  /* (324) frame_bound_e ::= frame_bound */
-
   -2,  /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */
-
   -2,  /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */
-
   -2,  /* (327) frame_bound ::= CURRENT ROW */
-
    0,  /* (328) frame_exclude_opt ::= */
-
   -2,  /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */
-
   -2,  /* (330) frame_exclude ::= NO OTHERS */
-
   -2,  /* (331) frame_exclude ::= CURRENT ROW */
-
   -1,  /* (332) frame_exclude ::= GROUP|TIES */
-
   -2,  /* (333) window_clause ::= WINDOW windowdefn_list */
-
   -2,  /* (334) filter_over ::= filter_clause over_clause */
-
   -1,  /* (335) filter_over ::= over_clause */
-
   -1,  /* (336) filter_over ::= filter_clause */
-
   -4,  /* (337) over_clause ::= OVER LP window RP */
-
   -2,  /* (338) over_clause ::= OVER nm */
-
   -5,  /* (339) filter_clause ::= FILTER LP WHERE expr RP */
-
   -1,  /* (340) input ::= cmdlist */
-
   -2,  /* (341) cmdlist ::= cmdlist ecmd */
-
   -1,  /* (342) cmdlist ::= ecmd */
-
   -1,  /* (343) ecmd ::= SEMI */
-
   -2,  /* (344) ecmd ::= cmdx SEMI */
-
   -3,  /* (345) ecmd ::= explain cmdx SEMI */
-
    0,  /* (346) trans_opt ::= */
-
   -1,  /* (347) trans_opt ::= TRANSACTION */
-
   -2,  /* (348) trans_opt ::= TRANSACTION nm */
-
   -1,  /* (349) savepoint_opt ::= SAVEPOINT */
-
    0,  /* (350) savepoint_opt ::= */
-
   -2,  /* (351) cmd ::= create_table create_table_args */
-
   -1,  /* (352) table_option_set ::= table_option */
-
   -4,  /* (353) columnlist ::= columnlist COMMA columnname carglist */
-
   -2,  /* (354) columnlist ::= columnname carglist */
-
   -1,  /* (355) nm ::= ID|INDEXED */
-
   -1,  /* (356) nm ::= STRING */
-
   -1,  /* (357) nm ::= JOIN_KW */
-
   -1,  /* (358) typetoken ::= typename */
-
   -1,  /* (359) typename ::= ID|STRING */
-
   -1,  /* (360) signed ::= plus_num */
-
   -1,  /* (361) signed ::= minus_num */
-
   -2,  /* (362) carglist ::= carglist ccons */
-
    0,  /* (363) carglist ::= */
-
   -2,  /* (364) ccons ::= NULL onconf */
-
   -4,  /* (365) ccons ::= GENERATED ALWAYS AS generated */
-
   -2,  /* (366) ccons ::= AS generated */
-
   -2,  /* (367) conslist_opt ::= COMMA conslist */
-
   -3,  /* (368) conslist ::= conslist tconscomma tcons */
-
   -1,  /* (369) conslist ::= tcons */
-
    0,  /* (370) tconscomma ::= */
-
   -1,  /* (371) defer_subclause_opt ::= defer_subclause */
-
   -1,  /* (372) resolvetype ::= raisetype */
-
   -1,  /* (373) selectnowith ::= oneselect */
-
   -1,  /* (374) oneselect ::= values */
-
   -2,  /* (375) sclp ::= selcollist COMMA */
-
   -1,  /* (376) as ::= ID|STRING */
-
    0,  /* (377) returning ::= */
-
   -1,  /* (378) expr ::= term */
-
   -1,  /* (379) likeop ::= LIKE_KW|MATCH */
-
   -1,  /* (380) exprlist ::= nexprlist */
-
   -1,  /* (381) nmnum ::= plus_num */
-
   -1,  /* (382) nmnum ::= nm */
-
   -1,  /* (383) nmnum ::= ON */
-
   -1,  /* (384) nmnum ::= DELETE */
-
   -1,  /* (385) nmnum ::= DEFAULT */
-
   -1,  /* (386) plus_num ::= INTEGER|FLOAT */
-
    0,  /* (387) foreach_clause ::= */
-
   -3,  /* (388) foreach_clause ::= FOR EACH ROW */
-
   -1,  /* (389) trnm ::= nm */
-
    0,  /* (390) tridxby ::= */
-
   -1,  /* (391) database_kw_opt ::= DATABASE */
-
    0,  /* (392) database_kw_opt ::= */
-
    0,  /* (393) kwcolumn_opt ::= */
-
   -1,  /* (394) kwcolumn_opt ::= COLUMNKW */
-
   -1,  /* (395) vtabarglist ::= vtabarg */
-
   -3,  /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */
-
   -2,  /* (397) vtabarg ::= vtabarg vtabargtoken */
-
    0,  /* (398) anylist ::= */
-
   -4,  /* (399) anylist ::= anylist LP anylist RP */
-
   -2,  /* (400) anylist ::= anylist ANY */
-
    0,  /* (401) with ::= */
+
   -6,  /* (209) expr ::= expr IS NOT DISTINCT FROM expr */
+
   -5,  /* (210) expr ::= expr IS DISTINCT FROM expr */
+
   -2,  /* (211) expr ::= NOT expr */
+
   -2,  /* (212) expr ::= BITNOT expr */
+
   -2,  /* (213) expr ::= PLUS|MINUS expr */
+
   -3,  /* (214) expr ::= expr PTR expr */
+
   -1,  /* (215) between_op ::= BETWEEN */
+
   -2,  /* (216) between_op ::= NOT BETWEEN */
+
   -5,  /* (217) expr ::= expr between_op expr AND expr */
+
   -1,  /* (218) in_op ::= IN */
+
   -2,  /* (219) in_op ::= NOT IN */
+
   -5,  /* (220) expr ::= expr in_op LP exprlist RP */
+
   -3,  /* (221) expr ::= LP select RP */
+
   -5,  /* (222) expr ::= expr in_op LP select RP */
+
   -5,  /* (223) expr ::= expr in_op nm dbnm paren_exprlist */
+
   -4,  /* (224) expr ::= EXISTS LP select RP */
+
   -5,  /* (225) expr ::= CASE case_operand case_exprlist case_else END */
+
   -5,  /* (226) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+
   -4,  /* (227) case_exprlist ::= WHEN expr THEN expr */
+
   -2,  /* (228) case_else ::= ELSE expr */
+
    0,  /* (229) case_else ::= */
+
   -1,  /* (230) case_operand ::= expr */
+
    0,  /* (231) case_operand ::= */
+
    0,  /* (232) exprlist ::= */
+
   -3,  /* (233) nexprlist ::= nexprlist COMMA expr */
+
   -1,  /* (234) nexprlist ::= expr */
+
    0,  /* (235) paren_exprlist ::= */
+
   -3,  /* (236) paren_exprlist ::= LP exprlist RP */
+
  -12,  /* (237) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+
   -1,  /* (238) uniqueflag ::= UNIQUE */
+
    0,  /* (239) uniqueflag ::= */
+
    0,  /* (240) eidlist_opt ::= */
+
   -3,  /* (241) eidlist_opt ::= LP eidlist RP */
+
   -5,  /* (242) eidlist ::= eidlist COMMA nm collate sortorder */
+
   -3,  /* (243) eidlist ::= nm collate sortorder */
+
    0,  /* (244) collate ::= */
+
   -2,  /* (245) collate ::= COLLATE ID|STRING */
+
   -4,  /* (246) cmd ::= DROP INDEX ifexists fullname */
+
   -2,  /* (247) cmd ::= VACUUM vinto */
+
   -3,  /* (248) cmd ::= VACUUM nm vinto */
+
   -2,  /* (249) vinto ::= INTO expr */
+
    0,  /* (250) vinto ::= */
+
   -3,  /* (251) cmd ::= PRAGMA nm dbnm */
+
   -5,  /* (252) cmd ::= PRAGMA nm dbnm EQ nmnum */
+
   -6,  /* (253) cmd ::= PRAGMA nm dbnm LP nmnum RP */
+
   -5,  /* (254) cmd ::= PRAGMA nm dbnm EQ minus_num */
+
   -6,  /* (255) cmd ::= PRAGMA nm dbnm LP minus_num RP */
+
   -2,  /* (256) plus_num ::= PLUS INTEGER|FLOAT */
+
   -2,  /* (257) minus_num ::= MINUS INTEGER|FLOAT */
+
   -5,  /* (258) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+
  -11,  /* (259) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+
   -1,  /* (260) trigger_time ::= BEFORE|AFTER */
+
   -2,  /* (261) trigger_time ::= INSTEAD OF */
+
    0,  /* (262) trigger_time ::= */
+
   -1,  /* (263) trigger_event ::= DELETE|INSERT */
+
   -1,  /* (264) trigger_event ::= UPDATE */
+
   -3,  /* (265) trigger_event ::= UPDATE OF idlist */
+
    0,  /* (266) when_clause ::= */
+
   -2,  /* (267) when_clause ::= WHEN expr */
+
   -3,  /* (268) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+
   -2,  /* (269) trigger_cmd_list ::= trigger_cmd SEMI */
+
   -3,  /* (270) trnm ::= nm DOT nm */
+
   -3,  /* (271) tridxby ::= INDEXED BY nm */
+
   -2,  /* (272) tridxby ::= NOT INDEXED */
+
   -9,  /* (273) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
+
   -8,  /* (274) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+
   -6,  /* (275) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+
   -3,  /* (276) trigger_cmd ::= scanpt select scanpt */
+
   -4,  /* (277) expr ::= RAISE LP IGNORE RP */
+
   -6,  /* (278) expr ::= RAISE LP raisetype COMMA nm RP */
+
   -1,  /* (279) raisetype ::= ROLLBACK */
+
   -1,  /* (280) raisetype ::= ABORT */
+
   -1,  /* (281) raisetype ::= FAIL */
+
   -4,  /* (282) cmd ::= DROP TRIGGER ifexists fullname */
+
   -6,  /* (283) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+
   -3,  /* (284) cmd ::= DETACH database_kw_opt expr */
+
    0,  /* (285) key_opt ::= */
+
   -2,  /* (286) key_opt ::= KEY expr */
+
   -1,  /* (287) cmd ::= REINDEX */
+
   -3,  /* (288) cmd ::= REINDEX nm dbnm */
+
   -1,  /* (289) cmd ::= ANALYZE */
+
   -3,  /* (290) cmd ::= ANALYZE nm dbnm */
+
   -6,  /* (291) cmd ::= ALTER TABLE fullname RENAME TO nm */
+
   -7,  /* (292) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+
   -6,  /* (293) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
+
   -1,  /* (294) add_column_fullname ::= fullname */
+
   -8,  /* (295) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+
   -1,  /* (296) cmd ::= create_vtab */
+
   -4,  /* (297) cmd ::= create_vtab LP vtabarglist RP */
+
   -8,  /* (298) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+
    0,  /* (299) vtabarg ::= */
+
   -1,  /* (300) vtabargtoken ::= ANY */
+
   -3,  /* (301) vtabargtoken ::= lp anylist RP */
+
   -1,  /* (302) lp ::= LP */
+
   -2,  /* (303) with ::= WITH wqlist */
+
   -3,  /* (304) with ::= WITH RECURSIVE wqlist */
+
   -1,  /* (305) wqas ::= AS */
+
   -2,  /* (306) wqas ::= AS MATERIALIZED */
+
   -3,  /* (307) wqas ::= AS NOT MATERIALIZED */
+
   -6,  /* (308) wqitem ::= nm eidlist_opt wqas LP select RP */
+
   -1,  /* (309) wqlist ::= wqitem */
+
   -3,  /* (310) wqlist ::= wqlist COMMA wqitem */
+
   -1,  /* (311) windowdefn_list ::= windowdefn */
+
   -3,  /* (312) windowdefn_list ::= windowdefn_list COMMA windowdefn */
+
   -5,  /* (313) windowdefn ::= nm AS LP window RP */
+
   -5,  /* (314) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+
   -6,  /* (315) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+
   -4,  /* (316) window ::= ORDER BY sortlist frame_opt */
+
   -5,  /* (317) window ::= nm ORDER BY sortlist frame_opt */
+
   -1,  /* (318) window ::= frame_opt */
+
   -2,  /* (319) window ::= nm frame_opt */
+
    0,  /* (320) frame_opt ::= */
+
   -3,  /* (321) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+
   -6,  /* (322) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+
   -1,  /* (323) range_or_rows ::= RANGE|ROWS|GROUPS */
+
   -1,  /* (324) frame_bound_s ::= frame_bound */
+
   -2,  /* (325) frame_bound_s ::= UNBOUNDED PRECEDING */
+
   -1,  /* (326) frame_bound_e ::= frame_bound */
+
   -2,  /* (327) frame_bound_e ::= UNBOUNDED FOLLOWING */
+
   -2,  /* (328) frame_bound ::= expr PRECEDING|FOLLOWING */
+
   -2,  /* (329) frame_bound ::= CURRENT ROW */
+
    0,  /* (330) frame_exclude_opt ::= */
+
   -2,  /* (331) frame_exclude_opt ::= EXCLUDE frame_exclude */
+
   -2,  /* (332) frame_exclude ::= NO OTHERS */
+
   -2,  /* (333) frame_exclude ::= CURRENT ROW */
+
   -1,  /* (334) frame_exclude ::= GROUP|TIES */
+
   -2,  /* (335) window_clause ::= WINDOW windowdefn_list */
+
   -2,  /* (336) filter_over ::= filter_clause over_clause */
+
   -1,  /* (337) filter_over ::= over_clause */
+
   -1,  /* (338) filter_over ::= filter_clause */
+
   -4,  /* (339) over_clause ::= OVER LP window RP */
+
   -2,  /* (340) over_clause ::= OVER nm */
+
   -5,  /* (341) filter_clause ::= FILTER LP WHERE expr RP */
+
   -1,  /* (342) input ::= cmdlist */
+
   -2,  /* (343) cmdlist ::= cmdlist ecmd */
+
   -1,  /* (344) cmdlist ::= ecmd */
+
   -1,  /* (345) ecmd ::= SEMI */
+
   -2,  /* (346) ecmd ::= cmdx SEMI */
+
   -3,  /* (347) ecmd ::= explain cmdx SEMI */
+
    0,  /* (348) trans_opt ::= */
+
   -1,  /* (349) trans_opt ::= TRANSACTION */
+
   -2,  /* (350) trans_opt ::= TRANSACTION nm */
+
   -1,  /* (351) savepoint_opt ::= SAVEPOINT */
+
    0,  /* (352) savepoint_opt ::= */
+
   -2,  /* (353) cmd ::= create_table create_table_args */
+
   -1,  /* (354) table_option_set ::= table_option */
+
   -4,  /* (355) columnlist ::= columnlist COMMA columnname carglist */
+
   -2,  /* (356) columnlist ::= columnname carglist */
+
   -1,  /* (357) nm ::= ID|INDEXED */
+
   -1,  /* (358) nm ::= STRING */
+
   -1,  /* (359) nm ::= JOIN_KW */
+
   -1,  /* (360) typetoken ::= typename */
+
   -1,  /* (361) typename ::= ID|STRING */
+
   -1,  /* (362) signed ::= plus_num */
+
   -1,  /* (363) signed ::= minus_num */
+
   -2,  /* (364) carglist ::= carglist ccons */
+
    0,  /* (365) carglist ::= */
+
   -2,  /* (366) ccons ::= NULL onconf */
+
   -4,  /* (367) ccons ::= GENERATED ALWAYS AS generated */
+
   -2,  /* (368) ccons ::= AS generated */
+
   -2,  /* (369) conslist_opt ::= COMMA conslist */
+
   -3,  /* (370) conslist ::= conslist tconscomma tcons */
+
   -1,  /* (371) conslist ::= tcons */
+
    0,  /* (372) tconscomma ::= */
+
   -1,  /* (373) defer_subclause_opt ::= defer_subclause */
+
   -1,  /* (374) resolvetype ::= raisetype */
+
   -1,  /* (375) selectnowith ::= oneselect */
+
   -1,  /* (376) oneselect ::= values */
+
   -2,  /* (377) sclp ::= selcollist COMMA */
+
   -1,  /* (378) as ::= ID|STRING */
+
   -1,  /* (379) indexed_opt ::= indexed_by */
+
    0,  /* (380) returning ::= */
+
   -1,  /* (381) expr ::= term */
+
   -1,  /* (382) likeop ::= LIKE_KW|MATCH */
+
   -1,  /* (383) exprlist ::= nexprlist */
+
   -1,  /* (384) nmnum ::= plus_num */
+
   -1,  /* (385) nmnum ::= nm */
+
   -1,  /* (386) nmnum ::= ON */
+
   -1,  /* (387) nmnum ::= DELETE */
+
   -1,  /* (388) nmnum ::= DEFAULT */
+
   -1,  /* (389) plus_num ::= INTEGER|FLOAT */
+
    0,  /* (390) foreach_clause ::= */
+
   -3,  /* (391) foreach_clause ::= FOR EACH ROW */
+
   -1,  /* (392) trnm ::= nm */
+
    0,  /* (393) tridxby ::= */
+
   -1,  /* (394) database_kw_opt ::= DATABASE */
+
    0,  /* (395) database_kw_opt ::= */
+
    0,  /* (396) kwcolumn_opt ::= */
+
   -1,  /* (397) kwcolumn_opt ::= COLUMNKW */
+
   -1,  /* (398) vtabarglist ::= vtabarg */
+
   -3,  /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */
+
   -2,  /* (400) vtabarg ::= vtabarg vtabargtoken */
+
    0,  /* (401) anylist ::= */
+
   -4,  /* (402) anylist ::= anylist LP anylist RP */
+
   -2,  /* (403) anylist ::= anylist ANY */
+
    0,  /* (404) with ::= */
};

static void yy_accept(yyParser*);  /* Forward Declaration */
@@ -164992,7 +167030,7 @@ static YYACTIONTYPE yy_reduce(
      case 5: /* transtype ::= DEFERRED */
      case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
      case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
-
      case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321);
+
      case 323: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==323);
{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/}
        break;
      case 8: /* cmd ::= COMMIT|END trans_opt */
@@ -165029,7 +167067,7 @@ static YYACTIONTYPE yy_reduce(
      case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72);
      case 81: /* ifexists ::= */ yytestcase(yyruleno==81);
      case 98: /* distinct ::= */ yytestcase(yyruleno==98);
-
      case 242: /* collate ::= */ yytestcase(yyruleno==242);
+
      case 244: /* collate ::= */ yytestcase(yyruleno==244);
{yymsp[1].minor.yy394 = 0;}
        break;
      case 16: /* ifnotexists ::= IF NOT EXISTS */
@@ -165213,9 +167251,9 @@ static YYACTIONTYPE yy_reduce(
        break;
      case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
      case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80);
-
      case 214: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==214);
-
      case 217: /* in_op ::= NOT IN */ yytestcase(yyruleno==217);
-
      case 243: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==243);
+
      case 216: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==216);
+
      case 219: /* in_op ::= NOT IN */ yytestcase(yyruleno==219);
+
      case 245: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==245);
{yymsp[-1].minor.yy394 = 1;}
        break;
      case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
@@ -165300,7 +167338,7 @@ static YYACTIONTYPE yy_reduce(
    Token x;
    x.n = 0;
    parserDoubleLinkSelect(pParse, pRhs);
-
    pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
+
    pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0);
    pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
  }
  if( pRhs ){
@@ -165365,9 +167403,9 @@ static YYACTIONTYPE yy_reduce(
      case 99: /* sclp ::= */
      case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132);
      case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142);
-
      case 230: /* exprlist ::= */ yytestcase(yyruleno==230);
-
      case 233: /* paren_exprlist ::= */ yytestcase(yyruleno==233);
-
      case 238: /* eidlist_opt ::= */ yytestcase(yyruleno==238);
+
      case 232: /* exprlist ::= */ yytestcase(yyruleno==232);
+
      case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235);
+
      case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240);
{yymsp[1].minor.yy322 = 0;}
        break;
      case 100: /* selcollist ::= sclp scanpt expr scanpt as */
@@ -165392,9 +167430,9 @@ static YYACTIONTYPE yy_reduce(
}
        break;
      case 103: /* as ::= AS nm */
-
      case 114: /* dbnm ::= DOT nm */ yytestcase(yyruleno==114);
-
      case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254);
-
      case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255);
+
      case 115: /* dbnm ::= DOT nm */ yytestcase(yyruleno==115);
+
      case 256: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==256);
+
      case 257: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==257);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
        break;
      case 105: /* from ::= */
@@ -165404,7 +167442,7 @@ static YYACTIONTYPE yy_reduce(
      case 106: /* from ::= FROM seltablist */
{
  yymsp[-1].minor.yy131 = yymsp[0].minor.yy131;
-
  sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy131);
+
  sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy131);
}
        break;
      case 107: /* stl_prefix ::= seltablist joinop */
@@ -165412,35 +167450,43 @@ static YYACTIONTYPE yy_reduce(
   if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394;
}
        break;
-
      case 109: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+
      case 109: /* seltablist ::= stl_prefix nm dbnm as on_using */
{
-
  yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
-
  sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy131, &yymsp[-2].minor.yy0);
+
  yymsp[-4].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy131,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
}
        break;
-
      case 110: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */
+
      case 110: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
{
-
  yymsp[-8].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy131,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
-
  sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy131, yymsp[-4].minor.yy322);
+
  yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy561);
+
  sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-1].minor.yy0);
}
        break;
-
      case 111: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+
      case 111: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
{
-
    yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy47,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
+
  yymsp[-7].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy131,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
+
  sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy131, yymsp[-3].minor.yy322);
+
}
+
        break;
+
      case 112: /* seltablist ::= stl_prefix LP select RP as on_using */
+
{
+
    yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy47,&yymsp[0].minor.yy561);
  }
        break;
-
      case 112: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+
      case 113: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
{
-
    if( yymsp[-6].minor.yy131==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy528==0 && yymsp[0].minor.yy254==0 ){
-
      yymsp[-6].minor.yy131 = yymsp[-4].minor.yy131;
-
    }else if( yymsp[-4].minor.yy131->nSrc==1 ){
-
      yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
-
      if( yymsp[-6].minor.yy131 ){
-
        SrcItem *pNew = &yymsp[-6].minor.yy131->a[yymsp[-6].minor.yy131->nSrc-1];
-
        SrcItem *pOld = yymsp[-4].minor.yy131->a;
+
    if( yymsp[-5].minor.yy131==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy561.pOn==0 && yymsp[0].minor.yy561.pUsing==0 ){
+
      yymsp[-5].minor.yy131 = yymsp[-3].minor.yy131;
+
    }else if( yymsp[-3].minor.yy131->nSrc==1 ){
+
      yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy561);
+
      if( yymsp[-5].minor.yy131 ){
+
        SrcItem *pNew = &yymsp[-5].minor.yy131->a[yymsp[-5].minor.yy131->nSrc-1];
+
        SrcItem *pOld = yymsp[-3].minor.yy131->a;
        pNew->zName = pOld->zName;
        pNew->zDatabase = pOld->zDatabase;
        pNew->pSelect = pOld->pSelect;
+
        if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){
+
          pNew->fg.isNestedFrom = 1;
+
        }
        if( pOld->fg.isTabFunc ){
          pNew->u1.pFuncArg = pOld->u1.pFuncArg;
          pOld->u1.pFuncArg = 0;
@@ -165450,94 +167496,78 @@ static YYACTIONTYPE yy_reduce(
        pOld->zName = pOld->zDatabase = 0;
        pOld->pSelect = 0;
      }
-
      sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy131);
+
      sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy131);
    }else{
      Select *pSubquery;
-
      sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy131);
-
      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy131,0,0,0,0,SF_NestedFrom,0);
-
      yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy528,yymsp[0].minor.yy254);
+
      sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy131);
+
      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy131,0,0,0,0,SF_NestedFrom,0);
+
      yymsp[-5].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy131,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy561);
    }
  }
        break;
-
      case 113: /* dbnm ::= */
-
      case 127: /* indexed_opt ::= */ yytestcase(yyruleno==127);
+
      case 114: /* dbnm ::= */
+
      case 129: /* indexed_opt ::= */ yytestcase(yyruleno==129);
{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
        break;
-
      case 115: /* fullname ::= nm */
+
      case 116: /* fullname ::= nm */
{
  yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
  if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0);
}
  yymsp[0].minor.yy131 = yylhsminor.yy131;
        break;
-
      case 116: /* fullname ::= nm DOT nm */
+
      case 117: /* fullname ::= nm DOT nm */
{
  yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
  if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0);
}
  yymsp[-2].minor.yy131 = yylhsminor.yy131;
        break;
-
      case 117: /* xfullname ::= nm */
+
      case 118: /* xfullname ::= nm */
{yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
        break;
-
      case 118: /* xfullname ::= nm DOT nm */
+
      case 119: /* xfullname ::= nm DOT nm */
{yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
        break;
-
      case 119: /* xfullname ::= nm DOT nm AS nm */
+
      case 120: /* xfullname ::= nm DOT nm AS nm */
{
   yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
   if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
        break;
-
      case 120: /* xfullname ::= nm AS nm */
+
      case 121: /* xfullname ::= nm AS nm */
{
   yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
   if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
        break;
-
      case 121: /* joinop ::= COMMA|JOIN */
+
      case 122: /* joinop ::= COMMA|JOIN */
{ yymsp[0].minor.yy394 = JT_INNER; }
        break;
-
      case 122: /* joinop ::= JOIN_KW JOIN */
+
      case 123: /* joinop ::= JOIN_KW JOIN */
{yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0);  /*X-overwrites-A*/}
        break;
-
      case 123: /* joinop ::= JOIN_KW nm JOIN */
+
      case 124: /* joinop ::= JOIN_KW nm JOIN */
{yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
        break;
-
      case 124: /* joinop ::= JOIN_KW nm nm JOIN */
+
      case 125: /* joinop ::= JOIN_KW nm nm JOIN */
{yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
        break;
-
      case 125: /* on_opt ::= ON expr */
-
      case 145: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==145);
-
      case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152);
-
      case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154);
-
      case 226: /* case_else ::= ELSE expr */ yytestcase(yyruleno==226);
-
      case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247);
-
{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
+
      case 126: /* on_using ::= ON expr */
+
{yymsp[-1].minor.yy561.pOn = yymsp[0].minor.yy528; yymsp[-1].minor.yy561.pUsing = 0;}
        break;
-
      case 126: /* on_opt ::= */
-
      case 144: /* having_opt ::= */ yytestcase(yyruleno==144);
-
      case 146: /* limit_opt ::= */ yytestcase(yyruleno==146);
-
      case 151: /* where_opt ::= */ yytestcase(yyruleno==151);
-
      case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153);
-
      case 227: /* case_else ::= */ yytestcase(yyruleno==227);
-
      case 229: /* case_operand ::= */ yytestcase(yyruleno==229);
-
      case 248: /* vinto ::= */ yytestcase(yyruleno==248);
-
{yymsp[1].minor.yy528 = 0;}
+
      case 127: /* on_using ::= USING LP idlist RP */
+
{yymsp[-3].minor.yy561.pOn = 0; yymsp[-3].minor.yy561.pUsing = yymsp[-1].minor.yy254;}
+
        break;
+
      case 128: /* on_using ::= */
+
{yymsp[1].minor.yy561.pOn = 0; yymsp[1].minor.yy561.pUsing = 0;}
        break;
-
      case 128: /* indexed_opt ::= INDEXED BY nm */
+
      case 130: /* indexed_by ::= INDEXED BY nm */
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
        break;
-
      case 129: /* indexed_opt ::= NOT INDEXED */
+
      case 131: /* indexed_by ::= NOT INDEXED */
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
        break;
-
      case 130: /* using_opt ::= USING LP idlist RP */
-
{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;}
-
        break;
-
      case 131: /* using_opt ::= */
-
      case 173: /* idlist_opt ::= */ yytestcase(yyruleno==173);
-
{yymsp[1].minor.yy254 = 0;}
-
        break;
      case 133: /* orderby_opt ::= ORDER BY sortlist */
      case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143);
{yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;}
@@ -165570,6 +167600,22 @@ static YYACTIONTYPE yy_reduce(
      case 140: /* nulls ::= NULLS LAST */
{yymsp[-1].minor.yy394 = SQLITE_SO_DESC;}
        break;
+
      case 144: /* having_opt ::= */
+
      case 146: /* limit_opt ::= */ yytestcase(yyruleno==146);
+
      case 151: /* where_opt ::= */ yytestcase(yyruleno==151);
+
      case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153);
+
      case 229: /* case_else ::= */ yytestcase(yyruleno==229);
+
      case 231: /* case_operand ::= */ yytestcase(yyruleno==231);
+
      case 250: /* vinto ::= */ yytestcase(yyruleno==250);
+
{yymsp[1].minor.yy528 = 0;}
+
        break;
+
      case 145: /* having_opt ::= HAVING expr */
+
      case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152);
+
      case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154);
+
      case 228: /* case_else ::= ELSE expr */ yytestcase(yyruleno==228);
+
      case 249: /* vinto ::= INTO expr */ yytestcase(yyruleno==249);
+
{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
+
        break;
      case 147: /* limit_opt ::= LIMIT expr */
{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);}
        break;
@@ -165595,7 +167641,18 @@ static YYACTIONTYPE yy_reduce(
{
  sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0);
  sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list");
-
  yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, yymsp[-1].minor.yy131);
+
  if( yymsp[-1].minor.yy131 ){
+
    SrcList *pFromClause = yymsp[-1].minor.yy131;
+
    if( pFromClause->nSrc>1 ){
+
      Select *pSubquery;
+
      Token as;
+
      pSubquery = sqlite3SelectNew(pParse,0,pFromClause,0,0,0,0,SF_NestedFrom,0);
+
      as.n = 0;
+
      as.z = 0;
+
      pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
+
    }
+
    yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, pFromClause);
+
  }
  sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0);
}
        break;
@@ -165653,6 +167710,9 @@ static YYACTIONTYPE yy_reduce(
      case 170: /* returning ::= RETURNING selcollist */
{sqlite3AddReturning(pParse,yymsp[0].minor.yy322);}
        break;
+
      case 173: /* idlist_opt ::= */
+
{yymsp[1].minor.yy254 = 0;}
+
        break;
      case 174: /* idlist_opt ::= LP idlist RP */
{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;}
        break;
@@ -165838,17 +167898,29 @@ static YYACTIONTYPE yy_reduce(
  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL);
}
        break;
-
      case 209: /* expr ::= NOT expr */
-
      case 210: /* expr ::= BITNOT expr */ yytestcase(yyruleno==210);
+
      case 209: /* expr ::= expr IS NOT DISTINCT FROM expr */
+
{
+
  yymsp[-5].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy528,yymsp[0].minor.yy528);
+
  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-5].minor.yy528, TK_ISNULL);
+
}
+
        break;
+
      case 210: /* expr ::= expr IS DISTINCT FROM expr */
+
{
+
  yymsp[-4].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy528,yymsp[0].minor.yy528);
+
  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-4].minor.yy528, TK_NOTNULL);
+
}
+
        break;
+
      case 211: /* expr ::= NOT expr */
+
      case 212: /* expr ::= BITNOT expr */ yytestcase(yyruleno==212);
{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/}
        break;
-
      case 211: /* expr ::= PLUS|MINUS expr */
+
      case 213: /* expr ::= PLUS|MINUS expr */
{
  yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0);
  /*A-overwrites-B*/
}
        break;
-
      case 212: /* expr ::= expr PTR expr */
+
      case 214: /* expr ::= expr PTR expr */
{
  ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528);
  pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528);
@@ -165856,11 +167928,11 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[-2].minor.yy528 = yylhsminor.yy528;
        break;
-
      case 213: /* between_op ::= BETWEEN */
-
      case 216: /* in_op ::= IN */ yytestcase(yyruleno==216);
+
      case 215: /* between_op ::= BETWEEN */
+
      case 218: /* in_op ::= IN */ yytestcase(yyruleno==218);
{yymsp[0].minor.yy394 = 0;}
        break;
-
      case 215: /* expr ::= expr between_op expr AND expr */
+
      case 217: /* expr ::= expr between_op expr AND expr */
{
  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528);
@@ -165873,7 +167945,7 @@ static YYACTIONTYPE yy_reduce(
  if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
}
        break;
-
      case 218: /* expr ::= expr in_op LP exprlist RP */
+
      case 220: /* expr ::= expr in_op LP exprlist RP */
{
    if( yymsp[-1].minor.yy322==0 ){
      /* Expressions of the form
@@ -165885,7 +167957,8 @@ static YYACTIONTYPE yy_reduce(
      ** regardless of the value of expr1.
      */
      sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528);
-
      yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy394 ? "1" : "0");
+
      yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy394 ? "true" : "false");
+
      if( yymsp[-4].minor.yy528 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy528);
    }else{
      Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr;
      if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){
@@ -165913,20 +167986,20 @@ static YYACTIONTYPE yy_reduce(
    }
  }
        break;
-
      case 219: /* expr ::= LP select RP */
+
      case 221: /* expr ::= LP select RP */
{
    yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
    sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47);
  }
        break;
-
      case 220: /* expr ::= expr in_op LP select RP */
+
      case 222: /* expr ::= expr in_op LP select RP */
{
    yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47);
    if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
  }
        break;
-
      case 221: /* expr ::= expr in_op nm dbnm paren_exprlist */
+
      case 223: /* expr ::= expr in_op nm dbnm paren_exprlist */
{
    SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
    Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
@@ -165936,14 +168009,14 @@ static YYACTIONTYPE yy_reduce(
    if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0);
  }
        break;
-
      case 222: /* expr ::= EXISTS LP select RP */
+
      case 224: /* expr ::= EXISTS LP select RP */
{
    Expr *p;
    p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
    sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47);
  }
        break;
-
      case 223: /* expr ::= CASE case_operand case_exprlist case_else END */
+
      case 225: /* expr ::= CASE case_operand case_exprlist case_else END */
{
  yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0);
  if( yymsp[-4].minor.yy528 ){
@@ -165955,32 +168028,32 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 224: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+
      case 226: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
  yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528);
  yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528);
}
        break;
-
      case 225: /* case_exprlist ::= WHEN expr THEN expr */
+
      case 227: /* case_exprlist ::= WHEN expr THEN expr */
{
  yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
  yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528);
}
        break;
-
      case 228: /* case_operand ::= expr */
+
      case 230: /* case_operand ::= expr */
{yymsp[0].minor.yy528 = yymsp[0].minor.yy528; /*A-overwrites-X*/}
        break;
-
      case 231: /* nexprlist ::= nexprlist COMMA expr */
+
      case 233: /* nexprlist ::= nexprlist COMMA expr */
{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);}
        break;
-
      case 232: /* nexprlist ::= expr */
+
      case 234: /* nexprlist ::= expr */
{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/}
        break;
-
      case 234: /* paren_exprlist ::= LP exprlist RP */
-
      case 239: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==239);
+
      case 236: /* paren_exprlist ::= LP exprlist RP */
+
      case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241);
{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;}
        break;
-
      case 235: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+
      case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
  sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
                     sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394,
@@ -165990,48 +168063,48 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 236: /* uniqueflag ::= UNIQUE */
-
      case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278);
+
      case 238: /* uniqueflag ::= UNIQUE */
+
      case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280);
{yymsp[0].minor.yy394 = OE_Abort;}
        break;
-
      case 237: /* uniqueflag ::= */
+
      case 239: /* uniqueflag ::= */
{yymsp[1].minor.yy394 = OE_None;}
        break;
-
      case 240: /* eidlist ::= eidlist COMMA nm collate sortorder */
+
      case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
  yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394);
}
        break;
-
      case 241: /* eidlist ::= nm collate sortorder */
+
      case 243: /* eidlist ::= nm collate sortorder */
{
  yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/
}
        break;
-
      case 244: /* cmd ::= DROP INDEX ifexists fullname */
+
      case 246: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);}
        break;
-
      case 245: /* cmd ::= VACUUM vinto */
+
      case 247: /* cmd ::= VACUUM vinto */
{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);}
        break;
-
      case 246: /* cmd ::= VACUUM nm vinto */
+
      case 248: /* cmd ::= VACUUM nm vinto */
{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);}
        break;
-
      case 249: /* cmd ::= PRAGMA nm dbnm */
+
      case 251: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
        break;
-
      case 250: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+
      case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
        break;
-
      case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+
      case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
        break;
-
      case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+
      case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
        break;
-
      case 253: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+
      case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
        break;
-
      case 256: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+
      case 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
  Token all;
  all.z = yymsp[-3].minor.yy0.z;
@@ -166039,50 +168112,50 @@ static YYACTIONTYPE yy_reduce(
  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all);
}
        break;
-
      case 257: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+
      case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394);
  yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
}
        break;
-
      case 258: /* trigger_time ::= BEFORE|AFTER */
+
      case 260: /* trigger_time ::= BEFORE|AFTER */
{ yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ }
        break;
-
      case 259: /* trigger_time ::= INSTEAD OF */
+
      case 261: /* trigger_time ::= INSTEAD OF */
{ yymsp[-1].minor.yy394 = TK_INSTEAD;}
        break;
-
      case 260: /* trigger_time ::= */
+
      case 262: /* trigger_time ::= */
{ yymsp[1].minor.yy394 = TK_BEFORE; }
        break;
-
      case 261: /* trigger_event ::= DELETE|INSERT */
-
      case 262: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==262);
+
      case 263: /* trigger_event ::= DELETE|INSERT */
+
      case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264);
{yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;}
        break;
-
      case 263: /* trigger_event ::= UPDATE OF idlist */
+
      case 265: /* trigger_event ::= UPDATE OF idlist */
{yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;}
        break;
-
      case 264: /* when_clause ::= */
-
      case 283: /* key_opt ::= */ yytestcase(yyruleno==283);
+
      case 266: /* when_clause ::= */
+
      case 285: /* key_opt ::= */ yytestcase(yyruleno==285);
{ yymsp[1].minor.yy528 = 0; }
        break;
-
      case 265: /* when_clause ::= WHEN expr */
-
      case 284: /* key_opt ::= KEY expr */ yytestcase(yyruleno==284);
+
      case 267: /* when_clause ::= WHEN expr */
+
      case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286);
{ yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; }
        break;
-
      case 266: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+
      case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
  assert( yymsp[-2].minor.yy33!=0 );
  yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33;
  yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33;
}
        break;
-
      case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */
+
      case 269: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
  assert( yymsp[-1].minor.yy33!=0 );
  yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33;
}
        break;
-
      case 268: /* trnm ::= nm DOT nm */
+
      case 270: /* trnm ::= nm DOT nm */
{
  yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
  sqlite3ErrorMsg(pParse,
@@ -166090,39 +168163,39 @@ static YYACTIONTYPE yy_reduce(
        "statements within triggers");
}
        break;
-
      case 269: /* tridxby ::= INDEXED BY nm */
+
      case 271: /* tridxby ::= INDEXED BY nm */
{
  sqlite3ErrorMsg(pParse,
        "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
        "within triggers");
}
        break;
-
      case 270: /* tridxby ::= NOT INDEXED */
+
      case 272: /* tridxby ::= NOT INDEXED */
{
  sqlite3ErrorMsg(pParse,
        "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
        "within triggers");
}
        break;
-
      case 271: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
+
      case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
{yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);}
  yymsp[-8].minor.yy33 = yylhsminor.yy33;
        break;
-
      case 272: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+
      case 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
{
   yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/
}
  yymsp[-7].minor.yy33 = yylhsminor.yy33;
        break;
-
      case 273: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+
      case 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
{yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);}
  yymsp[-5].minor.yy33 = yylhsminor.yy33;
        break;
-
      case 274: /* trigger_cmd ::= scanpt select scanpt */
+
      case 276: /* trigger_cmd ::= scanpt select scanpt */
{yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/}
  yymsp[-2].minor.yy33 = yylhsminor.yy33;
        break;
-
      case 275: /* expr ::= RAISE LP IGNORE RP */
+
      case 277: /* expr ::= RAISE LP IGNORE RP */
{
  yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
  if( yymsp[-3].minor.yy528 ){
@@ -166130,7 +168203,7 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 276: /* expr ::= RAISE LP raisetype COMMA nm RP */
+
      case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
  yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1);
  if( yymsp[-5].minor.yy528 ) {
@@ -166138,118 +168211,118 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 277: /* raisetype ::= ROLLBACK */
+
      case 279: /* raisetype ::= ROLLBACK */
{yymsp[0].minor.yy394 = OE_Rollback;}
        break;
-
      case 279: /* raisetype ::= FAIL */
+
      case 281: /* raisetype ::= FAIL */
{yymsp[0].minor.yy394 = OE_Fail;}
        break;
-
      case 280: /* cmd ::= DROP TRIGGER ifexists fullname */
+
      case 282: /* cmd ::= DROP TRIGGER ifexists fullname */
{
  sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394);
}
        break;
-
      case 281: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+
      case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
  sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528);
}
        break;
-
      case 282: /* cmd ::= DETACH database_kw_opt expr */
+
      case 284: /* cmd ::= DETACH database_kw_opt expr */
{
  sqlite3Detach(pParse, yymsp[0].minor.yy528);
}
        break;
-
      case 285: /* cmd ::= REINDEX */
+
      case 287: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
        break;
-
      case 286: /* cmd ::= REINDEX nm dbnm */
+
      case 288: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
        break;
-
      case 287: /* cmd ::= ANALYZE */
+
      case 289: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
        break;
-
      case 288: /* cmd ::= ANALYZE nm dbnm */
+
      case 290: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
        break;
-
      case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+
      case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0);
}
        break;
-
      case 290: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+
      case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
{
  yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
  sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
}
        break;
-
      case 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
+
      case 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
{
  sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0);
}
        break;
-
      case 292: /* add_column_fullname ::= fullname */
+
      case 294: /* add_column_fullname ::= fullname */
{
  disableLookaside(pParse);
  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131);
}
        break;
-
      case 293: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+
      case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
{
  sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
}
        break;
-
      case 294: /* cmd ::= create_vtab */
+
      case 296: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
        break;
-
      case 295: /* cmd ::= create_vtab LP vtabarglist RP */
+
      case 297: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
        break;
-
      case 296: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+
      case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394);
}
        break;
-
      case 297: /* vtabarg ::= */
+
      case 299: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
        break;
-
      case 298: /* vtabargtoken ::= ANY */
-
      case 299: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==299);
-
      case 300: /* lp ::= LP */ yytestcase(yyruleno==300);
+
      case 300: /* vtabargtoken ::= ANY */
+
      case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301);
+
      case 302: /* lp ::= LP */ yytestcase(yyruleno==302);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
        break;
-
      case 301: /* with ::= WITH wqlist */
-
      case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302);
+
      case 303: /* with ::= WITH wqlist */
+
      case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304);
{ sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); }
        break;
-
      case 303: /* wqas ::= AS */
+
      case 305: /* wqas ::= AS */
{yymsp[0].minor.yy516 = M10d_Any;}
        break;
-
      case 304: /* wqas ::= AS MATERIALIZED */
+
      case 306: /* wqas ::= AS MATERIALIZED */
{yymsp[-1].minor.yy516 = M10d_Yes;}
        break;
-
      case 305: /* wqas ::= AS NOT MATERIALIZED */
+
      case 307: /* wqas ::= AS NOT MATERIALIZED */
{yymsp[-2].minor.yy516 = M10d_No;}
        break;
-
      case 306: /* wqitem ::= nm eidlist_opt wqas LP select RP */
+
      case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */
{
  yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/
}
        break;
-
      case 307: /* wqlist ::= wqitem */
+
      case 309: /* wqlist ::= wqitem */
{
  yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/
}
        break;
-
      case 308: /* wqlist ::= wqlist COMMA wqitem */
+
      case 310: /* wqlist ::= wqlist COMMA wqitem */
{
  yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385);
}
        break;
-
      case 309: /* windowdefn_list ::= windowdefn */
+
      case 311: /* windowdefn_list ::= windowdefn */
{ yylhsminor.yy41 = yymsp[0].minor.yy41; }
  yymsp[0].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 310: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
+
      case 312: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
{
  assert( yymsp[0].minor.yy41!=0 );
  sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41);
@@ -166258,7 +168331,7 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[-2].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 311: /* windowdefn ::= nm AS LP window RP */
+
      case 313: /* windowdefn ::= nm AS LP window RP */
{
  if( ALWAYS(yymsp[-1].minor.yy41) ){
    yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
@@ -166267,90 +168340,90 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[-4].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 312: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+
      case 314: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
{
  yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0);
}
        break;
-
      case 313: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+
      case 315: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
{
  yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0);
}
  yymsp[-5].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 314: /* window ::= ORDER BY sortlist frame_opt */
+
      case 316: /* window ::= ORDER BY sortlist frame_opt */
{
  yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0);
}
        break;
-
      case 315: /* window ::= nm ORDER BY sortlist frame_opt */
+
      case 317: /* window ::= nm ORDER BY sortlist frame_opt */
{
  yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
}
  yymsp[-4].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 316: /* window ::= frame_opt */
-
      case 335: /* filter_over ::= over_clause */ yytestcase(yyruleno==335);
+
      case 318: /* window ::= frame_opt */
+
      case 337: /* filter_over ::= over_clause */ yytestcase(yyruleno==337);
{
  yylhsminor.yy41 = yymsp[0].minor.yy41;
}
  yymsp[0].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 317: /* window ::= nm frame_opt */
+
      case 319: /* window ::= nm frame_opt */
{
  yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0);
}
  yymsp[-1].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 318: /* frame_opt ::= */
+
      case 320: /* frame_opt ::= */
{
  yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
}
        break;
-
      case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+
      case 321: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
{
  yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516);
}
  yymsp[-2].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+
      case 322: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
{
  yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516);
}
  yymsp[-5].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 322: /* frame_bound_s ::= frame_bound */
-
      case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324);
+
      case 324: /* frame_bound_s ::= frame_bound */
+
      case 326: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==326);
{yylhsminor.yy595 = yymsp[0].minor.yy595;}
  yymsp[0].minor.yy595 = yylhsminor.yy595;
        break;
-
      case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */
-
      case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325);
-
      case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327);
+
      case 325: /* frame_bound_s ::= UNBOUNDED PRECEDING */
+
      case 327: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==327);
+
      case 329: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==329);
{yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;}
  yymsp[-1].minor.yy595 = yylhsminor.yy595;
        break;
-
      case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */
+
      case 328: /* frame_bound ::= expr PRECEDING|FOLLOWING */
{yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;}
  yymsp[-1].minor.yy595 = yylhsminor.yy595;
        break;
-
      case 328: /* frame_exclude_opt ::= */
+
      case 330: /* frame_exclude_opt ::= */
{yymsp[1].minor.yy516 = 0;}
        break;
-
      case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
+
      case 331: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
{yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;}
        break;
-
      case 330: /* frame_exclude ::= NO OTHERS */
-
      case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331);
+
      case 332: /* frame_exclude ::= NO OTHERS */
+
      case 333: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==333);
{yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/}
        break;
-
      case 332: /* frame_exclude ::= GROUP|TIES */
+
      case 334: /* frame_exclude ::= GROUP|TIES */
{yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/}
        break;
-
      case 333: /* window_clause ::= WINDOW windowdefn_list */
+
      case 335: /* window_clause ::= WINDOW windowdefn_list */
{ yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; }
        break;
-
      case 334: /* filter_over ::= filter_clause over_clause */
+
      case 336: /* filter_over ::= filter_clause over_clause */
{
  if( yymsp[0].minor.yy41 ){
    yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528;
@@ -166361,7 +168434,7 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[-1].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 336: /* filter_over ::= filter_clause */
+
      case 338: /* filter_over ::= filter_clause */
{
  yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  if( yylhsminor.yy41 ){
@@ -166373,13 +168446,13 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[0].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 337: /* over_clause ::= OVER LP window RP */
+
      case 339: /* over_clause ::= OVER LP window RP */
{
  yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41;
  assert( yymsp[-3].minor.yy41!=0 );
}
        break;
-
      case 338: /* over_clause ::= OVER nm */
+
      case 340: /* over_clause ::= OVER nm */
{
  yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  if( yymsp[-1].minor.yy41 ){
@@ -166387,72 +168460,73 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 339: /* filter_clause ::= FILTER LP WHERE expr RP */
+
      case 341: /* filter_clause ::= FILTER LP WHERE expr RP */
{ yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; }
        break;
      default:
-
      /* (340) input ::= cmdlist */ yytestcase(yyruleno==340);
-
      /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341);
-
      /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342);
-
      /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343);
-
      /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344);
-
      /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345);
-
      /* (346) trans_opt ::= */ yytestcase(yyruleno==346);
-
      /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347);
-
      /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348);
-
      /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349);
-
      /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350);
-
      /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351);
-
      /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352);
-
      /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353);
-
      /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354);
-
      /* (355) nm ::= ID|INDEXED */ yytestcase(yyruleno==355);
-
      /* (356) nm ::= STRING */ yytestcase(yyruleno==356);
-
      /* (357) nm ::= JOIN_KW */ yytestcase(yyruleno==357);
-
      /* (358) typetoken ::= typename */ yytestcase(yyruleno==358);
-
      /* (359) typename ::= ID|STRING */ yytestcase(yyruleno==359);
-
      /* (360) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=360);
-
      /* (361) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=361);
-
      /* (362) carglist ::= carglist ccons */ yytestcase(yyruleno==362);
-
      /* (363) carglist ::= */ yytestcase(yyruleno==363);
-
      /* (364) ccons ::= NULL onconf */ yytestcase(yyruleno==364);
-
      /* (365) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==365);
-
      /* (366) ccons ::= AS generated */ yytestcase(yyruleno==366);
-
      /* (367) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==367);
-
      /* (368) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==368);
-
      /* (369) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=369);
-
      /* (370) tconscomma ::= */ yytestcase(yyruleno==370);
-
      /* (371) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=371);
-
      /* (372) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=372);
-
      /* (373) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=373);
-
      /* (374) oneselect ::= values */ yytestcase(yyruleno==374);
-
      /* (375) sclp ::= selcollist COMMA */ yytestcase(yyruleno==375);
-
      /* (376) as ::= ID|STRING */ yytestcase(yyruleno==376);
-
      /* (377) returning ::= */ yytestcase(yyruleno==377);
-
      /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378);
-
      /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379);
-
      /* (380) exprlist ::= nexprlist */ yytestcase(yyruleno==380);
-
      /* (381) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=381);
-
      /* (382) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=382);
-
      /* (383) nmnum ::= ON */ yytestcase(yyruleno==383);
-
      /* (384) nmnum ::= DELETE */ yytestcase(yyruleno==384);
-
      /* (385) nmnum ::= DEFAULT */ yytestcase(yyruleno==385);
-
      /* (386) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==386);
-
      /* (387) foreach_clause ::= */ yytestcase(yyruleno==387);
-
      /* (388) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==388);
-
      /* (389) trnm ::= nm */ yytestcase(yyruleno==389);
-
      /* (390) tridxby ::= */ yytestcase(yyruleno==390);
-
      /* (391) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==391);
-
      /* (392) database_kw_opt ::= */ yytestcase(yyruleno==392);
-
      /* (393) kwcolumn_opt ::= */ yytestcase(yyruleno==393);
-
      /* (394) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==394);
-
      /* (395) vtabarglist ::= vtabarg */ yytestcase(yyruleno==395);
-
      /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==396);
-
      /* (397) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==397);
-
      /* (398) anylist ::= */ yytestcase(yyruleno==398);
-
      /* (399) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==399);
-
      /* (400) anylist ::= anylist ANY */ yytestcase(yyruleno==400);
-
      /* (401) with ::= */ yytestcase(yyruleno==401);
+
      /* (342) input ::= cmdlist */ yytestcase(yyruleno==342);
+
      /* (343) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==343);
+
      /* (344) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=344);
+
      /* (345) ecmd ::= SEMI */ yytestcase(yyruleno==345);
+
      /* (346) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==346);
+
      /* (347) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=347);
+
      /* (348) trans_opt ::= */ yytestcase(yyruleno==348);
+
      /* (349) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==349);
+
      /* (350) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==350);
+
      /* (351) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==351);
+
      /* (352) savepoint_opt ::= */ yytestcase(yyruleno==352);
+
      /* (353) cmd ::= create_table create_table_args */ yytestcase(yyruleno==353);
+
      /* (354) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=354);
+
      /* (355) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==355);
+
      /* (356) columnlist ::= columnname carglist */ yytestcase(yyruleno==356);
+
      /* (357) nm ::= ID|INDEXED */ yytestcase(yyruleno==357);
+
      /* (358) nm ::= STRING */ yytestcase(yyruleno==358);
+
      /* (359) nm ::= JOIN_KW */ yytestcase(yyruleno==359);
+
      /* (360) typetoken ::= typename */ yytestcase(yyruleno==360);
+
      /* (361) typename ::= ID|STRING */ yytestcase(yyruleno==361);
+
      /* (362) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=362);
+
      /* (363) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=363);
+
      /* (364) carglist ::= carglist ccons */ yytestcase(yyruleno==364);
+
      /* (365) carglist ::= */ yytestcase(yyruleno==365);
+
      /* (366) ccons ::= NULL onconf */ yytestcase(yyruleno==366);
+
      /* (367) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==367);
+
      /* (368) ccons ::= AS generated */ yytestcase(yyruleno==368);
+
      /* (369) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==369);
+
      /* (370) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==370);
+
      /* (371) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=371);
+
      /* (372) tconscomma ::= */ yytestcase(yyruleno==372);
+
      /* (373) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=373);
+
      /* (374) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=374);
+
      /* (375) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=375);
+
      /* (376) oneselect ::= values */ yytestcase(yyruleno==376);
+
      /* (377) sclp ::= selcollist COMMA */ yytestcase(yyruleno==377);
+
      /* (378) as ::= ID|STRING */ yytestcase(yyruleno==378);
+
      /* (379) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=379);
+
      /* (380) returning ::= */ yytestcase(yyruleno==380);
+
      /* (381) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=381);
+
      /* (382) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==382);
+
      /* (383) exprlist ::= nexprlist */ yytestcase(yyruleno==383);
+
      /* (384) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=384);
+
      /* (385) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=385);
+
      /* (386) nmnum ::= ON */ yytestcase(yyruleno==386);
+
      /* (387) nmnum ::= DELETE */ yytestcase(yyruleno==387);
+
      /* (388) nmnum ::= DEFAULT */ yytestcase(yyruleno==388);
+
      /* (389) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==389);
+
      /* (390) foreach_clause ::= */ yytestcase(yyruleno==390);
+
      /* (391) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==391);
+
      /* (392) trnm ::= nm */ yytestcase(yyruleno==392);
+
      /* (393) tridxby ::= */ yytestcase(yyruleno==393);
+
      /* (394) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==394);
+
      /* (395) database_kw_opt ::= */ yytestcase(yyruleno==395);
+
      /* (396) kwcolumn_opt ::= */ yytestcase(yyruleno==396);
+
      /* (397) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==397);
+
      /* (398) vtabarglist ::= vtabarg */ yytestcase(yyruleno==398);
+
      /* (399) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==399);
+
      /* (400) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==400);
+
      /* (401) anylist ::= */ yytestcase(yyruleno==401);
+
      /* (402) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==402);
+
      /* (403) anylist ::= anylist ANY */ yytestcase(yyruleno==403);
+
      /* (404) with ::= */ yytestcase(yyruleno==404);
        break;
/********** End reduce actions ************************************************/
  };
@@ -167899,6 +169973,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){
    mxSqlLen -= n;
    if( mxSqlLen<0 ){
      pParse->rc = SQLITE_TOOBIG;
+
      pParse->nErr++;
      break;
    }
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -167995,7 +170070,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){
  if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){
    sqlite3DeleteTrigger(db, pParse->pNewTrigger);
  }
-
  sqlite3DbFree(db, pParse->pVList);
+
  if( pParse->pVList ) sqlite3DbFreeNN(db, pParse->pVList);
  db->pParse = pParentParse;
  assert( nErr==0 || pParse->rc!=SQLITE_OK );
  return nErr;
@@ -172624,6 +174699,28 @@ SQLITE_API int sqlite3_test_control(int op, ...){
      volatile int x = 0;
      assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
      rc = x;
+
#if defined(SQLITE_DEBUG)
+
      /* Invoke these debugging routines so that the compiler does not
+
      ** issue "defined but not used" warnings. */
+
      if( x==9999 ){
+
        sqlite3ShowExpr(0);
+
        sqlite3ShowExpr(0);
+
        sqlite3ShowExprList(0);
+
        sqlite3ShowIdList(0);
+
        sqlite3ShowSrcList(0);
+
        sqlite3ShowWith(0);
+
        sqlite3ShowUpsert(0);
+
        sqlite3ShowTriggerStep(0);
+
        sqlite3ShowTriggerStepList(0);
+
        sqlite3ShowTrigger(0);
+
        sqlite3ShowTriggerList(0);
+
#ifndef SQLITE_OMIT_WINDOWFUNC
+
        sqlite3ShowWindow(0);
+
        sqlite3ShowWinFunc(0);
+
#endif
+
        sqlite3ShowSelect(0);
+
      }
+
#endif
      break;
    }

@@ -172885,8 +174982,8 @@ SQLITE_API int sqlite3_test_control(int op, ...){
    **
    **  "ptr" is a pointer to a u32.
    **
-
    **   op==0       Store the current sqlite3SelectTrace in *ptr
-
    **   op==1       Set sqlite3SelectTrace to the value *ptr
+
    **   op==0       Store the current sqlite3TreeTrace in *ptr
+
    **   op==1       Set sqlite3TreeTrace to the value *ptr
    **   op==3       Store the current sqlite3WhereTrace in *ptr
    **   op==3       Set sqlite3WhereTrace to the value *ptr
    */
@@ -172894,10 +174991,10 @@ SQLITE_API int sqlite3_test_control(int op, ...){
       int opTrace = va_arg(ap, int);
       u32 *ptr = va_arg(ap, u32*);
       switch( opTrace ){
-
         case 0:   *ptr = sqlite3SelectTrace;      break;
-
         case 1:   sqlite3SelectTrace = *ptr;      break;
-
         case 2:   *ptr = sqlite3WhereTrace;       break;
-
         case 3:   sqlite3WhereTrace = *ptr;       break;
+
         case 0:   *ptr = sqlite3TreeTrace;      break;
+
         case 1:   sqlite3TreeTrace = *ptr;      break;
+
         case 2:   *ptr = sqlite3WhereTrace;     break;
+
         case 3:   sqlite3WhereTrace = *ptr;     break;
       }
       break;
    }
@@ -172914,10 +175011,12 @@ SQLITE_API int sqlite3_test_control(int op, ...){
    case SQLITE_TESTCTRL_LOGEST: {
      double rIn = va_arg(ap, double);
      LogEst rLogEst = sqlite3LogEstFromDouble(rIn);
-
      u64 iInt = sqlite3LogEstToInt(rLogEst);
-
      va_arg(ap, int*)[0] = rLogEst;
-
      va_arg(ap, u64*)[0] = iInt;
-
      va_arg(ap, int*)[0] = sqlite3LogEst(iInt);
+
      int *pI1 = va_arg(ap,int*);
+
      u64 *pU64 = va_arg(ap,u64*);
+
      int *pI2 = va_arg(ap,int*);
+
      *pI1 = rLogEst;
+
      *pU64 = sqlite3LogEstToInt(rLogEst);
+
      *pI2 = sqlite3LogEst(*pU64);
      break;
    }

@@ -173133,6 +175232,24 @@ SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
}

/*
+
** Return the name of the N-th database schema.  Return NULL if N is out
+
** of range.
+
*/
+
SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N){
+
#ifdef SQLITE_ENABLE_API_ARMOR
+
  if( !sqlite3SafetyCheckOk(db) ){
+
    (void)SQLITE_MISUSE_BKPT;
+
    return 0;
+
  }
+
#endif
+
  if( N<0 || N>=db->nDb ){
+
    return 0;
+
  }else{
+
    return db->aDb[N].zDbSName;
+
  }
+
}
+

+
/*
** Return the filename of the database associated with a database
** connection.
*/
@@ -178935,8 +181052,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
  char *aPoslist = 0;             /* Position list for deferred tokens */
  int nPoslist = 0;               /* Number of bytes in aPoslist */
  int iPrev = -1;                 /* Token number of previous deferred token */
-

-
  assert( pPhrase->doclist.bFreeList==0 );
+
  char *aFree = (pPhrase->doclist.bFreeList ? pPhrase->doclist.pList : 0);

  for(iToken=0; iToken<pPhrase->nToken; iToken++){
    Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
@@ -178950,6 +181066,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){

      if( pList==0 ){
        sqlite3_free(aPoslist);
+
        sqlite3_free(aFree);
        pPhrase->doclist.pList = 0;
        pPhrase->doclist.nList = 0;
        return SQLITE_OK;
@@ -178970,6 +181087,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
        nPoslist = (int)(aOut - aPoslist);
        if( nPoslist==0 ){
          sqlite3_free(aPoslist);
+
          sqlite3_free(aFree);
          pPhrase->doclist.pList = 0;
          pPhrase->doclist.nList = 0;
          return SQLITE_OK;
@@ -179009,6 +181127,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
      }

      pPhrase->doclist.pList = aOut;
+
      assert( p1 && p2 );
      if( fts3PoslistPhraseMerge(&aOut, nDistance, 0, 1, &p1, &p2) ){
        pPhrase->doclist.bFreeList = 1;
        pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList);
@@ -179021,6 +181140,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
    }
  }

+
  if( pPhrase->doclist.pList!=aFree ) sqlite3_free(aFree);
  return SQLITE_OK;
}
#endif /* SQLITE_DISABLE_FTS4_DEFERRED */
@@ -180195,11 +182315,10 @@ static int fts3EvalTestExpr(

      default: {
#ifndef SQLITE_DISABLE_FTS4_DEFERRED
-
        if( pCsr->pDeferred
-
         && (pExpr->iDocid==pCsr->iPrevId || pExpr->bDeferred)
-
        ){
+
        if( pCsr->pDeferred && (pExpr->bDeferred || (
+
            pExpr->iDocid==pCsr->iPrevId && pExpr->pPhrase->doclist.pList
+
        ))){
          Fts3Phrase *pPhrase = pExpr->pPhrase;
-
          assert( pExpr->bDeferred || pPhrase->doclist.bFreeList==0 );
          if( pExpr->bDeferred ){
            fts3EvalInvalidatePoslist(pPhrase);
          }
@@ -188770,6 +190889,8 @@ static int fts3IncrmergePush(
          pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix);
        }
        pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix);
+
        assert( nPrefix+nSuffix<=nTerm );
+
        assert( nPrefix>=0 );
        memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix);
        pBlk->n += nSuffix;

@@ -188892,6 +191013,7 @@ static int fts3IncrmergeAppend(
  pLeaf = &pWriter->aNodeWriter[0];
  nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm);
  nSuffix = nTerm - nPrefix;
+
  if(nSuffix<=0 ) return FTS_CORRUPT_VTAB;

  nSpace  = sqlite3Fts3VarintLen(nPrefix);
  nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix;
@@ -194849,7 +196971,7 @@ static JsonNode *jsonMergePatch(
  if( pPatch->eType!=JSON_OBJECT ){
    return pPatch;
  }
-
  assert( iTarget>=0 && iTarget<pParse->nNode );
+
  assert( iTarget<pParse->nNode );
  pTarget = &pParse->aNode[iTarget];
  assert( (pPatch->jnFlags & JNODE_APPEND)==0 );
  if( pTarget->eType!=JSON_OBJECT ){
@@ -210167,7 +212289,7 @@ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  ){
    pIdxInfo->orderByConsumed = 1;
  }
-
  sqlite3VtabWriteAll(pIdxInfo);
+
  sqlite3VtabUsesAllSchemas(pIdxInfo);
  return SQLITE_OK;
}

@@ -210345,7 +212467,7 @@ static int dbpageUpdate(
    goto update_fail;
  }
  pBt = pTab->db->aDb[iDb].pBt;
-
  if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){
+
  if( pgno<1 || pBt==0 || pgno>sqlite3BtreeLastPage(pBt) ){
    zErr = "bad page number";
    goto update_fail;
  }
@@ -222895,6 +225017,9 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset(
  }else{
    if( pRet->nPhrase>0 ){
      Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1];
+
      assert( pParse!=0 );
+
      assert( pParse->apPhrase!=0 );
+
      assert( pParse->nPhrase>=2 );
      assert( pLast==pParse->apPhrase[pParse->nPhrase-2] );
      if( pPhrase->nTerm==0 ){
        fts5ExprPhraseFree(pPhrase);
@@ -225194,7 +227319,7 @@ struct Fts5Index {
  sqlite3_stmt *pWriter;          /* "INSERT ... %_data VALUES(?,?)" */
  sqlite3_stmt *pDeleter;         /* "DELETE FROM %_data ... id>=? AND id<=?" */
  sqlite3_stmt *pIdxWriter;       /* "INSERT ... %_idx VALUES(?,?,?,?)" */
-
  sqlite3_stmt *pIdxDeleter;      /* "DELETE FROM %_idx WHERE segid=? */
+
  sqlite3_stmt *pIdxDeleter;      /* "DELETE FROM %_idx WHERE segid=?" */
  sqlite3_stmt *pIdxSelect;
  int nRead;                      /* Total number of blocks read */

@@ -234511,7 +236636,7 @@ static void fts5SourceIdFunc(
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
-
  sqlite3_result_text(pCtx, "fts5: 2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe", -1, SQLITE_TRANSIENT);
+
  sqlite3_result_text(pCtx, "fts5: 2022-07-21 15:24:47 698edb77537b67c41adc68f9b892db56bcf9a55e00371a61420f3ddd668e6603", -1, SQLITE_TRANSIENT);
}

/*
@@ -239182,6 +241307,16 @@ SQLITE_EXTENSION_INIT1

#ifndef SQLITE_OMIT_VIRTUALTABLE

+

+
#define STMT_NUM_INTEGER_COLUMN 10
+
typedef struct StmtRow StmtRow;
+
struct StmtRow {
+
  sqlite3_int64 iRowid;                /* Rowid value */
+
  char *zSql;                          /* column "sql" */
+
  int aCol[STMT_NUM_INTEGER_COLUMN+1]; /* all other column values */
+
  StmtRow *pNext;                      /* Next row to return */
+
};
+

/* stmt_vtab is a subclass of sqlite3_vtab which will
** serve as the underlying representation of a stmt virtual table
*/
@@ -239199,8 +241334,7 @@ typedef struct stmt_cursor stmt_cursor;
struct stmt_cursor {
  sqlite3_vtab_cursor base;  /* Base class - must be first */
  sqlite3 *db;               /* Database connection for this cursor */
-
  sqlite3_stmt *pStmt;       /* Statement cursor is currently pointing at */
-
  sqlite3_int64 iRowid;      /* The rowid */
+
  StmtRow *pRow;             /* Current row */
};

/*
@@ -239244,7 +241378,7 @@ static int stmtConnect(
     "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
                    "reprep,run,mem)");
  if( rc==SQLITE_OK ){
-
    pNew = sqlite3_malloc( sizeof(*pNew) );
+
    pNew = sqlite3_malloc64( sizeof(*pNew) );
    *ppVtab = (sqlite3_vtab*)pNew;
    if( pNew==0 ) return SQLITE_NOMEM;
    memset(pNew, 0, sizeof(*pNew));
@@ -239266,7 +241400,7 @@ static int stmtDisconnect(sqlite3_vtab *pVtab){
*/
static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
  stmt_cursor *pCur;
-
  pCur = sqlite3_malloc( sizeof(*pCur) );
+
  pCur = sqlite3_malloc64( sizeof(*pCur) );
  if( pCur==0 ) return SQLITE_NOMEM;
  memset(pCur, 0, sizeof(*pCur));
  pCur->db = ((stmt_vtab*)p)->db;
@@ -239274,10 +241408,21 @@ static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
  return SQLITE_OK;
}

+
static void stmtCsrReset(stmt_cursor *pCur){
+
  StmtRow *pRow = 0;
+
  StmtRow *pNext = 0;
+
  for(pRow=pCur->pRow; pRow; pRow=pNext){
+
    pNext = pRow->pNext;
+
    sqlite3_free(pRow);
+
  }
+
  pCur->pRow = 0;
+
}
+

/*
** Destructor for a stmt_cursor.
*/
static int stmtClose(sqlite3_vtab_cursor *cur){
+
  stmtCsrReset((stmt_cursor*)cur);
  sqlite3_free(cur);
  return SQLITE_OK;
}
@@ -239288,8 +241433,9 @@ static int stmtClose(sqlite3_vtab_cursor *cur){
*/
static int stmtNext(sqlite3_vtab_cursor *cur){
  stmt_cursor *pCur = (stmt_cursor*)cur;
-
  pCur->iRowid++;
-
  pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt);
+
  StmtRow *pNext = pCur->pRow->pNext;
+
  sqlite3_free(pCur->pRow);
+
  pCur->pRow = pNext;
  return SQLITE_OK;
}

@@ -239303,39 +241449,11 @@ static int stmtColumn(
  int i                       /* Which column to return */
){
  stmt_cursor *pCur = (stmt_cursor*)cur;
-
  switch( i ){
-
    case STMT_COLUMN_SQL: {
-
      sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT);
-
      break;
-
    }
-
    case STMT_COLUMN_NCOL: {
-
      sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt));
-
      break;
-
    }
-
    case STMT_COLUMN_RO: {
-
      sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt));
-
      break;
-
    }
-
    case STMT_COLUMN_BUSY: {
-
      sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt));
-
      break;
-
    }
-
    default: {
-
      assert( i==STMT_COLUMN_MEM );
-
      i = SQLITE_STMTSTATUS_MEMUSED +
-
            STMT_COLUMN_NSCAN - SQLITE_STMTSTATUS_FULLSCAN_STEP;
-
      /* Fall thru */
-
    }
-
    case STMT_COLUMN_NSCAN:
-
    case STMT_COLUMN_NSORT:
-
    case STMT_COLUMN_NAIDX:
-
    case STMT_COLUMN_NSTEP:
-
    case STMT_COLUMN_REPREP:
-
    case STMT_COLUMN_RUN: {
-
      sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt,
-
                      i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0));
-
      break;
-
    }
+
  StmtRow *pRow = pCur->pRow;
+
  if( i==STMT_COLUMN_SQL ){
+
    sqlite3_result_text(ctx, pRow->zSql, -1, SQLITE_TRANSIENT);
+
  }else{
+
    sqlite3_result_int(ctx, pRow->aCol[i]);
  }
  return SQLITE_OK;
}
@@ -239346,7 +241464,7 @@ static int stmtColumn(
*/
static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
  stmt_cursor *pCur = (stmt_cursor*)cur;
-
  *pRowid = pCur->iRowid;
+
  *pRowid = pCur->pRow->iRowid;
  return SQLITE_OK;
}

@@ -239356,7 +241474,7 @@ static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
*/
static int stmtEof(sqlite3_vtab_cursor *cur){
  stmt_cursor *pCur = (stmt_cursor*)cur;
-
  return pCur->pStmt==0;
+
  return pCur->pRow==0;
}

/*
@@ -239371,9 +241489,53 @@ static int stmtFilter(
  int argc, sqlite3_value **argv
){
  stmt_cursor *pCur = (stmt_cursor *)pVtabCursor;
-
  pCur->pStmt = 0;
-
  pCur->iRowid = 0;
-
  return stmtNext(pVtabCursor);
+
  sqlite3_stmt *p = 0;
+
  sqlite3_int64 iRowid = 1;
+
  StmtRow **ppRow = 0;
+

+
  stmtCsrReset(pCur);
+
  ppRow = &pCur->pRow;
+
  for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){
+
    const char *zSql = sqlite3_sql(p);
+
    sqlite3_int64 nSql = zSql ? strlen(zSql)+1 : 0;
+
    StmtRow *pNew = (StmtRow*)sqlite3_malloc64(sizeof(StmtRow) + nSql);
+

+
    if( pNew==0 ) return SQLITE_NOMEM;
+
    memset(pNew, 0, sizeof(StmtRow));
+
    if( zSql ){
+
      pNew->zSql = (char*)&pNew[1];
+
      memcpy(pNew->zSql, zSql, nSql);
+
    }
+
    pNew->aCol[STMT_COLUMN_NCOL] = sqlite3_column_count(p);
+
    pNew->aCol[STMT_COLUMN_RO] = sqlite3_stmt_readonly(p);
+
    pNew->aCol[STMT_COLUMN_BUSY] = sqlite3_stmt_busy(p);
+
    pNew->aCol[STMT_COLUMN_NSCAN] = sqlite3_stmt_status(
+
        p, SQLITE_STMTSTATUS_FULLSCAN_STEP, 0
+
    );
+
    pNew->aCol[STMT_COLUMN_NSORT] = sqlite3_stmt_status(
+
        p, SQLITE_STMTSTATUS_SORT, 0
+
    );
+
    pNew->aCol[STMT_COLUMN_NAIDX] = sqlite3_stmt_status(
+
        p, SQLITE_STMTSTATUS_AUTOINDEX, 0
+
    );
+
    pNew->aCol[STMT_COLUMN_NSTEP] = sqlite3_stmt_status(
+
        p, SQLITE_STMTSTATUS_VM_STEP, 0
+
    );
+
    pNew->aCol[STMT_COLUMN_REPREP] = sqlite3_stmt_status(
+
        p, SQLITE_STMTSTATUS_REPREPARE, 0
+
    );
+
    pNew->aCol[STMT_COLUMN_RUN] = sqlite3_stmt_status(
+
        p, SQLITE_STMTSTATUS_RUN, 0
+
    );
+
    pNew->aCol[STMT_COLUMN_MEM] = sqlite3_stmt_status(
+
        p, SQLITE_STMTSTATUS_MEMUSED, 0
+
    );
+
    pNew->iRowid = iRowid++;
+
    *ppRow = pNew;
+
    ppRow = &pNew->pNext;
+
  }
+

+
  return SQLITE_OK;
}

/*
modified external/sqlite/sqlite3.h
@@ -146,9 +146,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-
#define SQLITE_VERSION        "3.38.5"
-
#define SQLITE_VERSION_NUMBER 3038005
-
#define SQLITE_SOURCE_ID      "2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe"
+
#define SQLITE_VERSION        "3.39.2"
+
#define SQLITE_VERSION_NUMBER 3039002
+
#define SQLITE_SOURCE_ID      "2022-07-21 15:24:47 698edb77537b67c41adc68f9b892db56bcf9a55e00371a61420f3ddd668e6603"

/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -5593,7 +5593,8 @@ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*);
** object D and returns a pointer to that copy.  ^The [sqlite3_value] returned
** is a [protected sqlite3_value] object even if the input is not.
** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
-
** memory allocation fails.
+
** memory allocation fails. ^If V is a [pointer value], then the result
+
** of sqlite3_value_dup(V) is a NULL value.
**
** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
** previously obtained from [sqlite3_value_dup()].  ^If V is a NULL pointer
@@ -6276,6 +6277,28 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*);
SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);

/*
+
** CAPI3REF: Return The Schema Name For A Database Connection
+
** METHOD: sqlite3
+
**
+
** ^The sqlite3_db_name(D,N) interface returns a pointer to the schema name
+
** for the N-th database on database connection D, or a NULL pointer of N is
+
** out of range.  An N value of 0 means the main database file.  An N of 1 is
+
** the "temp" schema.  Larger values of N correspond to various ATTACH-ed
+
** databases.
+
**
+
** Space to hold the string that is returned by sqlite3_db_name() is managed
+
** by SQLite itself.  The string might be deallocated by any operation that
+
** changes the schema, including [ATTACH] or [DETACH] or calls to
+
** [sqlite3_serialize()] or [sqlite3_deserialize()], even operations that
+
** occur on a different thread.  Applications that need to
+
** remember the string long-term should make their own copy.  Applications that
+
** are accessing the same database connection simultaneously on multiple
+
** threads should mutex-protect calls to this API and should make their own
+
** private copy of the result prior to releasing the mutex.
+
*/
+
SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N);
+

+
/*
** CAPI3REF: Return The Filename For A Database Connection
** METHOD: sqlite3
**
@@ -9554,8 +9577,8 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_
** of a [virtual table] implementation. The result of calling this
** interface from outside of xBestIndex() is undefined and probably harmful.
**
-
** ^The sqlite3_vtab_distinct() interface returns an integer that is
-
** either 0, 1, or 2.  The integer returned by sqlite3_vtab_distinct()
+
** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and
+
** 3.  The integer returned by sqlite3_vtab_distinct()
** gives the virtual table additional information about how the query
** planner wants the output to be ordered. As long as the virtual table
** can meet the ordering requirements of the query planner, it may set
@@ -9587,6 +9610,13 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_
** that have the same value for all columns identified by "aOrderBy".
** ^However omitting the extra rows is optional.
** This mode is used for a DISTINCT query.
+
** <li value="3"><p>
+
** ^(If the sqlite3_vtab_distinct() interface returns 3, that means
+
** that the query planner needs only distinct rows but it does need the
+
** rows to be sorted.)^ ^The virtual table implementation is free to omit
+
** rows that are identical in all aOrderBy columns, if it wants to, but
+
** it is not required to omit any rows.  This mode is used for queries
+
** that have both DISTINCT and ORDER BY clauses.
** </ol>
**
** ^For the purposes of comparing virtual table output values to see if the