Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
sqlite: update to latest version
Baptiste Daroussin committed 2 years ago
commit f269873e6cc6a44c29b02aa6f21f1faf4bd57089
parent e686c3f
3 files changed +10897 -5238
modified external/sqlite/shell.c
@@ -39,7 +39,7 @@ typedef unsigned short int u16;

/*
** Optionally #include a user-defined header, whereby compilation options
-
** may be set prior to where they take effect, but after platform setup. 
+
** may be set prior to where they take effect, but after platform setup.
** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include
** file. Note that this macro has a like effect on sqlite3.c compilation.
*/
@@ -117,6 +117,7 @@ typedef unsigned short int u16;
#include <string.h>
#include <stdio.h>
#include <assert.h>
+
#include <math.h>
#include "sqlite3.h"
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
@@ -129,7 +130,7 @@ typedef unsigned char u8;

#if !defined(_WIN32) && !defined(WIN32)
# include <signal.h>
-
# if !defined(__RTP__) && !defined(_WRS_KERNEL)
+
# if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI)
#  include <pwd.h>
# endif
#endif
@@ -184,6 +185,14 @@ typedef unsigned char u8;
# define SHELL_USE_LOCAL_GETLINE 1
#endif

+
#ifndef deliberate_fall_through
+
/* Quiet some compilers about some of our intentional code. */
+
# if defined(GCC_VERSION) && GCC_VERSION>=7000000
+
#  define deliberate_fall_through __attribute__((fallthrough));
+
# else
+
#  define deliberate_fall_through
+
# endif
+
#endif

#if defined(_WIN32) || defined(WIN32)
# if SQLITE_OS_WINRT
@@ -210,7 +219,7 @@ typedef unsigned char u8;
 /* Make sure isatty() has a prototype. */
 extern int isatty(int);

-
# if !defined(__RTP__) && !defined(_WRS_KERNEL)
+
# if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI)
  /* popen and pclose are not C89 functions and so are
  ** sometimes omitted from the <stdio.h> header */
   extern FILE *popen(const char*,const char*);
@@ -237,6 +246,7 @@ typedef unsigned char u8;
#if SQLITE_OS_WINRT
#include <intrin.h>
#endif
+
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

/* string conversion routines only needed on Win32 */
@@ -451,11 +461,25 @@ static void endTimer(void){
static int bail_on_error = 0;

/*
-
** Threat stdin as an interactive input if the following variable
+
** Treat stdin as an interactive input if the following variable
** is true.  Otherwise, assume stdin is connected to a file or pipe.
*/
static int stdin_is_interactive = 1;

+
#if (defined(_WIN32) || defined(WIN32)) && SHELL_USE_LOCAL_GETLINE \
+
  && !defined(SHELL_OMIT_WIN_UTF8)
+
# define SHELL_WIN_UTF8_OPT 1
+
#else
+
# define SHELL_WIN_UTF8_OPT 0
+
#endif
+

+
#if SHELL_WIN_UTF8_OPT
+
/*
+
** Setup console for UTF-8 input/output when following variable true.
+
*/
+
static int console_utf8 = 0;
+
#endif
+

/*
** On Windows systems we have to know if standard output is a console
** in order to translate UTF-8 into MBCS.  The following variable is
@@ -485,19 +509,253 @@ static char *Argv0;
** Prompt strings. Initialized in main. Settable with
**   .prompt main continue
*/
-
static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
-
static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */
+
#define PROMPT_LEN_MAX 20
+
/* First line prompt.   default: "sqlite> " */
+
static char mainPrompt[PROMPT_LEN_MAX];
+
/* Continuation prompt. default: "   ...> " */
+
static char continuePrompt[PROMPT_LEN_MAX];
+

+
/* This is variant of the standard-library strncpy() routine with the
+
** one change that the destination string is always zero-terminated, even
+
** if there is no zero-terminator in the first n-1 characters of the source
+
** string.
+
*/
+
static char *shell_strncpy(char *dest, const char *src, size_t n){
+
  size_t i;
+
  for(i=0; i<n-1 && src[i]!=0; i++) dest[i] = src[i];
+
  dest[i] = 0;
+
  return dest;
+
}
+

+
/*
+
** Optionally disable dynamic continuation prompt.
+
** Unless disabled, the continuation prompt shows open SQL lexemes if any,
+
** or open parentheses level if non-zero, or continuation prompt as set.
+
** This facility interacts with the scanner and process_input() where the
+
** below 5 macros are used.
+
*/
+
#ifdef SQLITE_OMIT_DYNAPROMPT
+
# define CONTINUATION_PROMPT continuePrompt
+
# define CONTINUE_PROMPT_RESET
+
# define CONTINUE_PROMPT_AWAITS(p,s)
+
# define CONTINUE_PROMPT_AWAITC(p,c)
+
# define CONTINUE_PAREN_INCR(p,n)
+
# define CONTINUE_PROMPT_PSTATE 0
+
typedef void *t_NoDynaPrompt;
+
# define SCAN_TRACKER_REFTYPE t_NoDynaPrompt
+
#else
+
# define CONTINUATION_PROMPT dynamicContinuePrompt()
+
# define CONTINUE_PROMPT_RESET \
+
  do {setLexemeOpen(&dynPrompt,0,0); trackParenLevel(&dynPrompt,0);} while(0)
+
# define CONTINUE_PROMPT_AWAITS(p,s) \
+
  if(p && stdin_is_interactive) setLexemeOpen(p, s, 0)
+
# define CONTINUE_PROMPT_AWAITC(p,c) \
+
  if(p && stdin_is_interactive) setLexemeOpen(p, 0, c)
+
# define CONTINUE_PAREN_INCR(p,n) \
+
  if(p && stdin_is_interactive) (trackParenLevel(p,n))
+
# define CONTINUE_PROMPT_PSTATE (&dynPrompt)
+
typedef struct DynaPrompt *t_DynaPromptRef;
+
# define SCAN_TRACKER_REFTYPE t_DynaPromptRef
+

+
static struct DynaPrompt {
+
  char dynamicPrompt[PROMPT_LEN_MAX];
+
  char acAwait[2];
+
  int inParenLevel;
+
  char *zScannerAwaits;
+
} dynPrompt = { {0}, {0}, 0, 0 };
+

+
/* Record parenthesis nesting level change, or force level to 0. */
+
static void trackParenLevel(struct DynaPrompt *p, int ni){
+
  p->inParenLevel += ni;
+
  if( ni==0 ) p->inParenLevel = 0;
+
  p->zScannerAwaits = 0;
+
}
+

+
/* Record that a lexeme is opened, or closed with args==0. */
+
static void setLexemeOpen(struct DynaPrompt *p, char *s, char c){
+
  if( s!=0 || c==0 ){
+
    p->zScannerAwaits = s;
+
    p->acAwait[0] = 0;
+
  }else{
+
    p->acAwait[0] = c;
+
    p->zScannerAwaits = p->acAwait;
+
  }
+
}
+

+
/* Upon demand, derive the continuation prompt to display. */
+
static char *dynamicContinuePrompt(void){
+
  if( continuePrompt[0]==0
+
      || (dynPrompt.zScannerAwaits==0 && dynPrompt.inParenLevel == 0) ){
+
    return continuePrompt;
+
  }else{
+
    if( dynPrompt.zScannerAwaits ){
+
      size_t ncp = strlen(continuePrompt);
+
      size_t ndp = strlen(dynPrompt.zScannerAwaits);
+
      if( ndp > ncp-3 ) return continuePrompt;
+
      strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits);
+
      while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' ';
+
      shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
+
              PROMPT_LEN_MAX-4);
+
    }else{
+
      if( dynPrompt.inParenLevel>9 ){
+
        shell_strncpy(dynPrompt.dynamicPrompt, "(..", 4);
+
      }else if( dynPrompt.inParenLevel<0 ){
+
        shell_strncpy(dynPrompt.dynamicPrompt, ")x!", 4);
+
      }else{
+
        shell_strncpy(dynPrompt.dynamicPrompt, "(x.", 4);
+
        dynPrompt.dynamicPrompt[2] = (char)('0'+dynPrompt.inParenLevel);
+
      }
+
      shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3, PROMPT_LEN_MAX-4);
+
    }
+
  }
+
  return dynPrompt.dynamicPrompt;
+
}
+
#endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */
+

+
#if SHELL_WIN_UTF8_OPT
+
/* Following struct is used for -utf8 operation. */
+
static struct ConsoleState {
+
  int stdinEof;      /* EOF has been seen on console input */
+
  int infsMode;      /* Input file stream mode upon shell start */
+
  UINT inCodePage;   /* Input code page upon shell start */
+
  UINT outCodePage;  /* Output code page upon shell start */
+
  HANDLE hConsoleIn; /* Console input handle */
+
  DWORD consoleMode; /* Console mode upon shell start */
+
} conState = { 0, 0, 0, 0, INVALID_HANDLE_VALUE, 0 };
+

+
#ifndef _O_U16TEXT /* For build environments lacking this constant: */
+
# define _O_U16TEXT 0x20000
+
#endif
+

+
/*
+
** Prepare console, (if known to be a WIN32 console), for UTF-8
+
** input (from either typing or suitable paste operations) and for
+
** UTF-8 rendering. This may "fail" with a message to stderr, where
+
** the preparation is not done and common "code page" issues occur.
+
*/
+
static void console_prepare(void){
+
  HANDLE hCI = GetStdHandle(STD_INPUT_HANDLE);
+
  DWORD consoleMode = 0;
+
  if( isatty(0) && GetFileType(hCI)==FILE_TYPE_CHAR
+
      && GetConsoleMode( hCI, &consoleMode) ){
+
    if( !IsValidCodePage(CP_UTF8) ){
+
      fprintf(stderr, "Cannot use UTF-8 code page.\n");
+
      console_utf8 = 0;
+
      return;
+
    }
+
    conState.hConsoleIn = hCI;
+
    conState.consoleMode = consoleMode;
+
    conState.inCodePage = GetConsoleCP();
+
    conState.outCodePage = GetConsoleOutputCP();
+
    SetConsoleCP(CP_UTF8);
+
    SetConsoleOutputCP(CP_UTF8);
+
    consoleMode |= ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT;
+
    SetConsoleMode(conState.hConsoleIn, consoleMode);
+
    conState.infsMode = _setmode(_fileno(stdin), _O_U16TEXT);
+
    console_utf8 = 1;
+
  }else{
+
    console_utf8 = 0;
+
  }
+
}
+

+
/*
+
** Undo the effects of console_prepare(), if any.
+
*/
+
static void SQLITE_CDECL console_restore(void){
+
  if( console_utf8 && conState.inCodePage!=0
+
      && conState.hConsoleIn!=INVALID_HANDLE_VALUE ){
+
    _setmode(_fileno(stdin), conState.infsMode);
+
    SetConsoleCP(conState.inCodePage);
+
    SetConsoleOutputCP(conState.outCodePage);
+
    SetConsoleMode(conState.hConsoleIn, conState.consoleMode);
+
    /* Avoid multiple calls. */
+
    conState.hConsoleIn = INVALID_HANDLE_VALUE;
+
    conState.consoleMode = 0;
+
    console_utf8 = 0;
+
  }
+
}
+

+
/*
+
** Collect input like fgets(...) with special provisions for input
+
** from the Windows console to get around its strange coding issues.
+
** Defers to plain fgets() when input is not interactive or when the
+
** startup option, -utf8, has not been provided or taken effect.
+
*/
+
static char* utf8_fgets(char *buf, int ncmax, FILE *fin){
+
  if( fin==0 ) fin = stdin;
+
  if( fin==stdin && stdin_is_interactive && console_utf8 ){
+
# define SQLITE_IALIM 150
+
    wchar_t wbuf[SQLITE_IALIM];
+
    int lend = 0;
+
    int noc = 0;
+
    if( ncmax==0 || conState.stdinEof ) return 0;
+
    buf[0] = 0;
+
    while( noc<ncmax-7-1 && !lend ){
+
      /* There is room for at least 2 more characters and a 0-terminator. */
+
      int na = (ncmax > SQLITE_IALIM*4+1 + noc)
+
        ? SQLITE_IALIM : (ncmax-1 - noc)/4;
+
# undef SQLITE_IALIM
+
      DWORD nbr = 0;
+
      BOOL bRC = ReadConsoleW(conState.hConsoleIn, wbuf, na, &nbr, 0);
+
      if( !bRC || (noc==0 && nbr==0) ) return 0;
+
      if( nbr > 0 ){
+
        int nmb = WideCharToMultiByte(CP_UTF8,WC_COMPOSITECHECK|WC_DEFAULTCHAR,
+
                                      wbuf,nbr,0,0,0,0);
+
        if( nmb !=0 && noc+nmb <= ncmax ){
+
          int iseg = noc;
+
          nmb = WideCharToMultiByte(CP_UTF8,WC_COMPOSITECHECK|WC_DEFAULTCHAR,
+
                                    wbuf,nbr,buf+noc,nmb,0,0);
+
          noc += nmb;
+
          /* Fixup line-ends as coded by Windows for CR (or "Enter".)*/
+
          if( noc > 0 ){
+
            if( buf[noc-1]=='\n' ){
+
              lend = 1;
+
              if( noc > 1 && buf[noc-2]=='\r' ){
+
                buf[noc-2] = '\n';
+
                --noc;
+
              }
+
            }
+
          }
+
          /* Check for ^Z (anywhere in line) too. */
+
          while( iseg < noc ){
+
            if( buf[iseg]==0x1a ){
+
              conState.stdinEof = 1;
+
              noc = iseg; /* Chop ^Z and anything following. */
+
              break;
+
            }
+
            ++iseg;
+
          }
+
        }else break; /* Drop apparent garbage in. (Could assert.) */
+
      }else break;
+
    }
+
    /* If got nothing, (after ^Z chop), must be at end-of-file. */
+
    if( noc == 0 ) return 0;
+
    buf[noc] = 0;
+
    return buf;
+
  }else{
+
    return fgets(buf, ncmax, fin);
+
  }
+
}
+

+
# define fgets(b,n,f) utf8_fgets(b,n,f)
+
#endif /* SHELL_WIN_UTF8_OPT */

/*
** Render output like fprintf().  Except, if the output is going to the
-
** console and if this is running on a Windows machine, translate the
-
** output from UTF-8 into MBCS.
+
** console and if this is running on a Windows machine, and if the -utf8
+
** option is unavailable or (available and inactive), translate the
+
** output from UTF-8 into MBCS for output through 8-bit stdout stream.
+
** (With -utf8 active, no translation is needed and must not be done.)
*/
#if defined(_WIN32) || defined(WIN32)
void utf8_printf(FILE *out, const char *zFormat, ...){
  va_list ap;
  va_start(ap, zFormat);
-
  if( stdout_is_console && (out==stdout || out==stderr) ){
+
  if( stdout_is_console && (out==stdout || out==stderr)
+
# if SHELL_WIN_UTF8_OPT
+
      && !console_utf8
+
# endif
+
  ){
    char *z1 = sqlite3_vmprintf(zFormat, ap);
    char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
    sqlite3_free(z1);
@@ -529,7 +787,7 @@ static void shell_out_of_memory(void){
/* Check a pointer to see if it is NULL.  If it is NULL, exit with an
** out-of-memory error.
*/
-
static void shell_check_oom(void *p){
+
static void shell_check_oom(const void *p){
  if( p==0 ) shell_out_of_memory();
}

@@ -708,9 +966,14 @@ static char *local_getline(char *zLine, FILE *in){
    }
  }
#if defined(_WIN32) || defined(WIN32)
-
  /* For interactive input on Windows systems, translate the
-
  ** multi-byte characterset characters into UTF-8. */
-
  if( stdin_is_interactive && in==stdin ){
+
  /* For interactive input on Windows systems, without -utf8,
+
  ** translate the multi-byte characterset characters into UTF-8.
+
  ** This is the translation that predates the -utf8 option. */
+
  if( stdin_is_interactive && in==stdin
+
# if SHELL_WIN_UTF8_OPT
+
      && !console_utf8
+
# endif /* SHELL_WIN_UTF8_OPT */
+
  ){
    char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
    if( zTrans ){
      i64 nTrans = strlen(zTrans)+1;
@@ -747,14 +1010,25 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
  if( in!=0 ){
    zResult = local_getline(zPrior, in);
  }else{
-
    zPrompt = isContinuation ? continuePrompt : mainPrompt;
+
    zPrompt = isContinuation ? CONTINUATION_PROMPT : mainPrompt;
#if SHELL_USE_LOCAL_GETLINE
    printf("%s", zPrompt);
    fflush(stdout);
-
    zResult = local_getline(zPrior, stdin);
+
    do{
+
      zResult = local_getline(zPrior, stdin);
+
      zPrior = 0;
+
      /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
+
      if( zResult==0 ) sqlite3_sleep(50);
+
    }while( zResult==0 && seenInterrupt>0 );
#else
    free(zPrior);
    zResult = shell_readline(zPrompt);
+
    while( zResult==0 ){
+
      /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
+
      sqlite3_sleep(50);
+
      if( seenInterrupt==0 ) break;
+
      zResult = shell_readline("");
+
    }
    if( zResult && *zResult ) shell_add_history(zResult);
#endif
  }
@@ -894,6 +1168,7 @@ static void appendText(ShellText *p, const char *zAppend, char quote){
*/
static char quoteChar(const char *zName){
  int i;
+
  if( zName==0 ) return '"';
  if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
  for(i=0; zName[i]; i++){
    if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
@@ -964,7 +1239,7 @@ static void shellModuleSchema(
  char *zFake;
  UNUSED_PARAMETER(nVal);
  zName = (const char*)sqlite3_value_text(apVal[0]);
-
  zFake = zName ? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0;
+
  zFake = zName? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0;
  if( zFake ){
    sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
                        -1, sqlite3_free);
@@ -1537,7 +1812,8 @@ int sqlite3MemTraceDeactivate(void){
**
******************************************************************************
**
-
** This SQLite extension implements functions that compute SHA3 hashes.
+
** This SQLite extension implements functions that compute SHA3 hashes
+
** in the way described by the (U.S.) NIST FIPS 202 SHA-3 Standard.
** Two SQL functions are implemented:
**
**     sha3(X,SIZE)
@@ -2058,7 +2334,7 @@ static void sha3Func(
/* Compute a string using sqlite3_vsnprintf() with a maximum length
** of 50 bytes and add it to the hash.
*/
-
static void hash_step_vformat(
+
static void sha3_step_vformat(
  SHA3Context *p,                 /* Add content to this context */
  const char *zFormat,
  ...
@@ -2154,7 +2430,7 @@ static void sha3QueryFunc(
    z = sqlite3_sql(pStmt);
    if( z ){
      n = (int)strlen(z);
-
      hash_step_vformat(&cx,"S%d:",n);
+
      sha3_step_vformat(&cx,"S%d:",n);
      SHA3Update(&cx,(unsigned char*)z,n);
    }

@@ -2198,14 +2474,14 @@ static void sha3QueryFunc(
          case SQLITE_TEXT: {
            int n2 = sqlite3_column_bytes(pStmt, i);
            const unsigned char *z2 = sqlite3_column_text(pStmt, i);
-
            hash_step_vformat(&cx,"T%d:",n2);
+
            sha3_step_vformat(&cx,"T%d:",n2);
            SHA3Update(&cx, z2, n2);
            break;
          }
          case SQLITE_BLOB: {
            int n2 = sqlite3_column_bytes(pStmt, i);
            const unsigned char *z2 = sqlite3_column_blob(pStmt, i);
-
            hash_step_vformat(&cx,"B%d:",n2);
+
            sha3_step_vformat(&cx,"B%d:",n2);
            SHA3Update(&cx, z2, n2);
            break;
          }
@@ -2965,7 +3241,7 @@ int sqlite3_decimal_init(

  SQLITE_EXTENSION_INIT2(pApi);

-
  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
+
  for(i=0; i<(int)(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);
@@ -2984,9 +3260,11 @@ int sqlite3_decimal_init(
}

/************************* End ../ext/misc/decimal.c ********************/
-
/************************* Begin ../ext/misc/ieee754.c ******************/
+
#undef sqlite3_base_init
+
#define sqlite3_base_init sqlite3_base64_init
+
/************************* Begin ../ext/misc/base64.c ******************/
/*
-
** 2013-04-17
+
** 2022-11-18
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
@@ -2995,294 +3273,749 @@ int sqlite3_decimal_init(
**    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 is a SQLite extension for converting in either direction
+
** between a (binary) blob and base64 text. Base64 can transit a
+
** sane USASCII channel unmolested. It also plays nicely in CSV or
+
** written as TCL brace-enclosed literals or SQL string literals,
+
** and can be used unmodified in XML-like documents.
+
**
+
** This is an independent implementation of conversions specified in
+
** RFC 4648, done on the above date by the author (Larry Brasfield)
+
** who thereby has the right to put this into the public domain.
+
**
+
** The conversions meet RFC 4648 requirements, provided that this
+
** C source specifies that line-feeds are included in the encoded
+
** data to limit visible line lengths to 72 characters and to
+
** terminate any encoded blob having non-zero length.
+
**
+
** Length limitations are not imposed except that the runtime
+
** SQLite string or blob length limits are respected. Otherwise,
+
** any length binary sequence can be represented and recovered.
+
** Generated base64 sequences, with their line-feeds included,
+
** can be concatenated; the result converted back to binary will
+
** be the concatenation of the represented binary sequences.
+
**
+
** This SQLite3 extension creates a function, base64(x), which
+
** either: converts text x containing base64 to a returned blob;
+
** or converts a blob x to returned text containing base64. An
+
** error will be thrown for other input argument types.
+
**
+
** This code relies on UTF-8 encoding only with respect to the
+
** meaning of the first 128 (7-bit) codes matching that of USASCII.
+
** It will fail miserably if somehow made to try to convert EBCDIC.
+
** Because it is table-driven, it could be enhanced to handle that,
+
** but the world and SQLite have moved on from that anachronism.
+
**
+
** To build the extension:
+
** Set shell variable SQDIR=<your favorite SQLite checkout directory>
+
** *Nix: gcc -O2 -shared -I$SQDIR -fPIC -o base64.so base64.c
+
** OSX: gcc -O2 -dynamiclib -fPIC -I$SQDIR -o base64.dylib base64.c
+
** Win32: gcc -O2 -shared -I%SQDIR% -o base64.dll base64.c
+
** Win32: cl /Os -I%SQDIR% base64.c -link -dll -out:base64.dll
*/
-
/* #include "sqlite3ext.h" */
-
SQLITE_EXTENSION_INIT1
+

#include <assert.h>
-
#include <string.h>

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

+
#ifndef deliberate_fall_through
+
/* Quiet some compilers about some of our intentional code. */
+
# if GCC_VERSION>=7000000
+
#  define deliberate_fall_through __attribute__((fallthrough));
+
# else
+
#  define deliberate_fall_through
+
# endif
#endif

-
/*
-
** Implementation of the ieee754() function
+
SQLITE_EXTENSION_INIT1;
+

+
#define PC 0x80 /* pad character */
+
#define WS 0x81 /* whitespace */
+
#define ND 0x82 /* Not above or digit-value */
+
#define PAD_CHAR '='
+

+
#ifndef U8_TYPEDEF
+
/* typedef unsigned char u8; */
+
#define U8_TYPEDEF
+
#endif
+

+
/* Decoding table, ASCII (7-bit) value to base 64 digit value or other */
+
static const u8 b64DigitValues[128] = {
+
  /*                             HT LF VT  FF CR       */
+
    ND,ND,ND,ND, ND,ND,ND,ND, ND,WS,WS,WS, WS,WS,ND,ND,
+
  /*                                                US */
+
    ND,ND,ND,ND, ND,ND,ND,ND, ND,ND,ND,ND, ND,ND,ND,ND,
+
  /*sp                                  +            / */
+
    WS,ND,ND,ND, ND,ND,ND,ND, ND,ND,ND,62, ND,ND,ND,63,
+
  /* 0  1            5            9            =       */
+
    52,53,54,55, 56,57,58,59, 60,61,ND,ND, ND,PC,ND,ND,
+
  /*    A                                            O */
+
    ND, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
+
  /* P                               Z                 */
+
    15,16,17,18, 19,20,21,22, 23,24,25,ND, ND,ND,ND,ND,
+
  /*    a                                            o */
+
    ND,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+
  /* p                               z                 */
+
    41,42,43,44, 45,46,47,48, 49,50,51,ND, ND,ND,ND,ND
+
};
+

+
static const char b64Numerals[64+1]
+
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+

+
#define BX_DV_PROTO(c) \
+
  ((((u8)(c))<0x80)? (u8)(b64DigitValues[(u8)(c)]) : 0x80)
+
#define IS_BX_DIGIT(bdp) (((u8)(bdp))<0x80)
+
#define IS_BX_WS(bdp) ((bdp)==WS)
+
#define IS_BX_PAD(bdp) ((bdp)==PC)
+
#define BX_NUMERAL(dv) (b64Numerals[(u8)(dv)])
+
/* Width of base64 lines. Should be an integer multiple of 4. */
+
#define B64_DARK_MAX 72
+

+
/* Encode a byte buffer into base64 text with linefeeds appended to limit
+
** encoded group lengths to B64_DARK_MAX or to terminate the last group.
*/
-
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];
+
static char* toBase64( u8 *pIn, int nbIn, char *pOut ){
+
  int nCol = 0;
+
  while( nbIn >= 3 ){
+
    /* Do the bit-shuffle, exploiting unsigned input to avoid masking. */
+
    pOut[0] = BX_NUMERAL(pIn[0]>>2);
+
    pOut[1] = BX_NUMERAL(((pIn[0]<<4)|(pIn[1]>>4))&0x3f);
+
    pOut[2] = BX_NUMERAL(((pIn[1]&0xf)<<2)|(pIn[2]>>6));
+
    pOut[3] = BX_NUMERAL(pIn[2]&0x3f);
+
    pOut += 4;
+
    nbIn -= 3;
+
    pIn += 3;
+
    if( (nCol += 4)>=B64_DARK_MAX || nbIn<=0 ){
+
      *pOut++ = '\n';
+
      nCol = 0;
+
    }
+
  }
+
  if( nbIn > 0 ){
+
    signed char nco = nbIn+1;
+
    int nbe;
+
    unsigned long qv = *pIn++;
+
    for( nbe=1; nbe<3; ++nbe ){
+
      qv <<= 8;
+
      if( nbe<nbIn ) qv |= *pIn++;
+
    }
+
    for( nbe=3; nbe>=0; --nbe ){
+
      char ce = (nbe<nco)? BX_NUMERAL((u8)(qv & 0x3f)) : PAD_CHAR;
+
      qv >>= 6;
+
      pOut[nbe] = ce;
+
    }
+
    pOut += 4;
+
    *pOut++ = '\n';
+
  }
+
  *pOut = 0;
+
  return pOut;
+
}
+

+
/* Skip over text which is not base64 numeral(s). */
+
static char * skipNonB64( char *s, int nc ){
+
  char c;
+
  while( nc-- > 0 && (c = *s) && !IS_BX_DIGIT(BX_DV_PROTO(c)) ) ++s;
+
  return s;
+
}
+

+
/* Decode base64 text into a byte buffer. */
+
static u8* fromBase64( char *pIn, int ncIn, u8 *pOut ){
+
  if( ncIn>0 && pIn[ncIn-1]=='\n' ) --ncIn;
+
  while( ncIn>0 && *pIn!=PAD_CHAR ){
+
    static signed char nboi[] = { 0, 0, 1, 2, 3 };
+
    char *pUse = skipNonB64(pIn, ncIn);
+
    unsigned long qv = 0L;
+
    int nti, nbo, nac;
+
    ncIn -= (pUse - pIn);
+
    pIn = pUse;
+
    nti = (ncIn>4)? 4 : ncIn;
+
    ncIn -= nti;
+
    nbo = nboi[nti];
+
    if( nbo==0 ) break;
+
    for( nac=0; nac<4; ++nac ){
+
      char c = (nac<nti)? *pIn++ : b64Numerals[0];
+
      u8 bdp = BX_DV_PROTO(c);
+
      switch( bdp ){
+
      case ND:
+
        /*  Treat dark non-digits as pad, but they terminate decode too. */
+
        ncIn = 0;
+
        deliberate_fall_through;
+
      case WS:
+
        /* Treat whitespace as pad and terminate this group.*/
+
        nti = nac;
+
        deliberate_fall_through;
+
      case PC:
+
        bdp = 0;
+
        --nbo;
+
        deliberate_fall_through;
+
      default: /* bdp is the digit value. */
+
        qv = qv<<6 | bdp;
+
        break;
      }
-
      memcpy(&r, &v, sizeof(r));
-
    }else{
-
      r = sqlite3_value_double(argv[0]);
    }
-
    if( r<0.0 ){
-
      isNeg = 1;
-
      r = -r;
-
    }else{
-
      isNeg = 0;
+
    switch( nbo ){
+
    case 3:
+
      pOut[2] = (qv) & 0xff;
+
    case 2:
+
      pOut[1] = (qv>>8) & 0xff;
+
    case 1:
+
      pOut[0] = (qv>>16) & 0xff;
+
    }
+
    pOut += nbo;
+
  }
+
  return pOut;
+
}
+

+
/* This function does the work for the SQLite base64(x) UDF. */
+
static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){
+
  int nb, nc, nv = sqlite3_value_bytes(av[0]);
+
  int nvMax = sqlite3_limit(sqlite3_context_db_handle(context),
+
                            SQLITE_LIMIT_LENGTH, -1);
+
  char *cBuf;
+
  u8 *bBuf;
+
  assert(na==1);
+
  switch( sqlite3_value_type(av[0]) ){
+
  case SQLITE_BLOB:
+
    nb = nv;
+
    nc = 4*(nv+2/3); /* quads needed */
+
    nc += (nc+(B64_DARK_MAX-1))/B64_DARK_MAX + 1; /* LFs and a 0-terminator */
+
    if( nvMax < nc ){
+
      sqlite3_result_error(context, "blob expanded to base64 too big", -1);
+
      return;
    }
-
    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( e<1075 && m>0 && (m&1)==0 ){
-
        m >>= 1;
-
        e++;
+
    bBuf = (u8*)sqlite3_value_blob(av[0]);
+
    if( !bBuf ){
+
      if( SQLITE_NOMEM==sqlite3_errcode(sqlite3_context_db_handle(context)) ){
+
        goto memFail;
      }
-
      if( isNeg ) m = -m;
-
    }
-
    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]);
-

-
    /* Limit the range of e.  Ticket 22dea1cfdb9151e4 2021-03-02 */
-
    if( e>10000 ){
-
      e = 10000;
-
    }else if( e<-10000 ){
-
      e = -10000;
+
      sqlite3_result_text(context,"",-1,SQLITE_STATIC);
+
      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);
+
    cBuf = sqlite3_malloc(nc);
+
    if( !cBuf ) goto memFail;
+
    nc = (int)(toBase64(bBuf, nb, cBuf) - cBuf);
+
    sqlite3_result_text(context, cBuf, nc, sqlite3_free);
+
    break;
+
  case SQLITE_TEXT:
+
    nc = nv;
+
    nb = 3*((nv+3)/4); /* may overestimate due to LF and padding */
+
    if( nvMax < nb ){
+
      sqlite3_result_error(context, "blob from base64 may be too big", -1);
      return;
+
    }else if( nb<1 ){
+
      nb = 1;
    }
-
    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;
-
      }else{
-
        m >>= 1-e;
+
    cBuf = (char *)sqlite3_value_text(av[0]);
+
    if( !cBuf ){
+
      if( SQLITE_NOMEM==sqlite3_errcode(sqlite3_context_db_handle(context)) ){
+
        goto memFail;
      }
-
      e = 0;
-
    }else if( e>0x7ff ){
-
      e = 0x7ff;
+
      sqlite3_result_zeroblob(context, 0);
+
      break;
    }
-
    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);
+
    bBuf = sqlite3_malloc(nb);
+
    if( !bBuf ) goto memFail;
+
    nb = (int)(fromBase64(cBuf, nc, bBuf) - bBuf);
+
    sqlite3_result_blob(context, bBuf, nb, sqlite3_free);
+
    break;
+
  default:
+
    sqlite3_result_error(context, "base64 accepts only blob or text", -1);
+
    return;
  }
+
  return;
+
 memFail:
+
  sqlite3_result_error(context, "base64 OOM", -1);
}

/*
-
** Functions to convert between blobs and floats.
+
** Establish linkage to running SQLite library.
*/
-
static void ieee754func_from_blob(
-
  sqlite3_context *context,
-
  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];
+
#ifndef SQLITE_SHELL_EXTFUNCS
+
#ifdef _WIN32
+

+
#endif
+
int sqlite3_base_init
+
#else
+
static int sqlite3_base64_init
+
#endif
+
(sqlite3 *db, char **pzErr, const sqlite3_api_routines *pApi){
+
  SQLITE_EXTENSION_INIT2(pApi);
+
  (void)pzErr;
+
  return sqlite3_create_function
+
    (db, "base64", 1,
+
     SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|SQLITE_DIRECTONLY|SQLITE_UTF8,
+
     0, base64, 0, 0);
+
}
+

+
/*
+
** Define some macros to allow this extension to be built into the shell
+
** conveniently, in conjunction with use of SQLITE_SHELL_EXTFUNCS. This
+
** allows shell.c, as distributed, to have this extension built in.
+
*/
+
#define BASE64_INIT(db) sqlite3_base64_init(db, 0, 0)
+
#define BASE64_EXPOSE(db, pzErr) /* Not needed, ..._init() does this. */
+

+
/************************* End ../ext/misc/base64.c ********************/
+
#undef sqlite3_base_init
+
#define sqlite3_base_init sqlite3_base85_init
+
#define OMIT_BASE85_CHECKER
+
/************************* Begin ../ext/misc/base85.c ******************/
+
/*
+
** 2022-11-16
+
**
+
** The author disclaims copyright to this source code.  In place of
+
** a legal notice, here is a blessing:
+
**
+
**    May you do good and not evil.
+
**    May you find forgiveness for yourself and forgive others.
+
**    May you share freely, never taking more than you give.
+
**
+
*************************************************************************
+
**
+
** This is a utility for converting binary to base85 or vice-versa.
+
** It can be built as a standalone program or an SQLite3 extension.
+
**
+
** Much like base64 representations, base85 can be sent through a
+
** sane USASCII channel unmolested. It also plays nicely in CSV or
+
** written as TCL brace-enclosed literals or SQL string literals.
+
** It is not suited for unmodified use in XML-like documents.
+
**
+
** The encoding used resembles Ascii85, but was devised by the author
+
** (Larry Brasfield) before Mozilla, Adobe, ZMODEM or other Ascii85
+
** variant sources existed, in the 1984 timeframe on a VAX mainframe.
+
** Further, this is an independent implementation of a base85 system.
+
** Hence, the author has rightfully put this into the public domain.
+
**
+
** Base85 numerals are taken from the set of 7-bit USASCII codes,
+
** excluding control characters and Space ! " ' ( ) { | } ~ Del
+
** in code order representing digit values 0 to 84 (base 10.)
+
**
+
** Groups of 4 bytes, interpreted as big-endian 32-bit values,
+
** are represented as 5-digit base85 numbers with MS to LS digit
+
** order. Groups of 1-3 bytes are represented with 2-4 digits,
+
** still big-endian but 8-24 bit values. (Using big-endian yields
+
** the simplest transition to byte groups smaller than 4 bytes.
+
** These byte groups can also be considered base-256 numbers.)
+
** Groups of 0 bytes are represented with 0 digits and vice-versa.
+
** No pad characters are used; Encoded base85 numeral sequence
+
** (aka "group") length maps 1-to-1 to the decoded binary length.
+
**
+
** Any character not in the base85 numeral set delimits groups.
+
** When base85 is streamed or stored in containers of indefinite
+
** size, newline is used to separate it into sub-sequences of no
+
** more than 80 digits so that fgets() can be used to read it.
+
**
+
** Length limitations are not imposed except that the runtime
+
** SQLite string or blob length limits are respected. Otherwise,
+
** any length binary sequence can be represented and recovered.
+
** Base85 sequences can be concatenated by separating them with
+
** a non-base85 character; the conversion to binary will then
+
** be the concatenation of the represented binary sequences.
+

+
** The standalone program either converts base85 on stdin to create
+
** a binary file or converts a binary file to base85 on stdout.
+
** Read or make it blurt its help for invocation details.
+
**
+
** The SQLite3 extension creates a function, base85(x), which will
+
** either convert text base85 to a blob or a blob to text base85
+
** and return the result (or throw an error for other types.)
+
** Unless built with OMIT_BASE85_CHECKER defined, it also creates a
+
** function, is_base85(t), which returns 1 iff the text t contains
+
** nothing other than base85 numerals and whitespace, or 0 otherwise.
+
**
+
** To build the extension:
+
** Set shell variable SQDIR=<your favorite SQLite checkout directory>
+
** and variable OPTS to -DOMIT_BASE85_CHECKER if is_base85() unwanted.
+
** *Nix: gcc -O2 -shared -I$SQDIR $OPTS -fPIC -o base85.so base85.c
+
** OSX: gcc -O2 -dynamiclib -fPIC -I$SQDIR $OPTS -o base85.dylib base85.c
+
** Win32: gcc -O2 -shared -I%SQDIR% %OPTS% -o base85.dll base85.c
+
** Win32: cl /Os -I%SQDIR% %OPTS% base85.c -link -dll -out:base85.dll
+
**
+
** To build the standalone program, define PP symbol BASE85_STANDALONE. Eg.
+
** *Nix or OSX: gcc -O2 -DBASE85_STANDALONE base85.c -o base85
+
** Win32: gcc -O2 -DBASE85_STANDALONE -o base85.exe base85.c
+
** Win32: cl /Os /MD -DBASE85_STANDALONE base85.c
+
*/
+

+
#include <stdio.h>
+
#include <memory.h>
+
#include <string.h>
+
#include <assert.h>
+
#ifndef OMIT_BASE85_CHECKER
+
# include <ctype.h>
+
#endif
+

+
#ifndef BASE85_STANDALONE
+

+
/* # include "sqlite3ext.h" */
+

+
SQLITE_EXTENSION_INIT1;
+

+
#else
+

+
# ifdef _WIN32
+
#  include <io.h>
+
#  include <fcntl.h>
+
# else
+
#  define setmode(fd,m)
+
# endif
+

+
static char *zHelp =
+
  "Usage: base85 <dirFlag> <binFile>\n"
+
  " <dirFlag> is either -r to read or -w to write <binFile>,\n"
+
  "   content to be converted to/from base85 on stdout/stdin.\n"
+
  " <binFile> names a binary file to be rendered or created.\n"
+
  "   Or, the name '-' refers to the stdin or stdout stream.\n"
+
  ;
+

+
static void sayHelp(){
+
  printf("%s", zHelp);
+
}
+
#endif
+

+
#ifndef U8_TYPEDEF
+
/* typedef unsigned char u8; */
+
#define U8_TYPEDEF
+
#endif
+

+
/* Classify c according to interval within USASCII set w.r.t. base85
+
 * Values of 1 and 3 are base85 numerals. Values of 0, 2, or 4 are not.
+
 */
+
#define B85_CLASS( c ) (((c)>='#')+((c)>'&')+((c)>='*')+((c)>'z'))
+

+
/* Provide digitValue to b85Numeral offset as a function of above class. */
+
static u8 b85_cOffset[] = { 0, '#', 0, '*'-4, 0 };
+
#define B85_DNOS( c ) b85_cOffset[B85_CLASS(c)]
+

+
/* Say whether c is a base85 numeral. */
+
#define IS_B85( c ) (B85_CLASS(c) & 1)
+

+
#if 0 /* Not used, */
+
static u8 base85DigitValue( char c ){
+
  u8 dv = (u8)(c - '#');
+
  if( dv>87 ) return 0xff;
+
  return (dv > 3)? dv-3 : dv;
+
}
+
#endif
+

+
/* Width of base64 lines. Should be an integer multiple of 5. */
+
#define B85_DARK_MAX 80
+

+

+
static char * skipNonB85( char *s, int nc ){
+
  char c;
+
  while( nc-- > 0 && (c = *s) && !IS_B85(c) ) ++s;
+
  return s;
+
}
+

+
/* Convert small integer, known to be in 0..84 inclusive, to base85 numeral.
+
 * Do not use the macro form with argument expression having a side-effect.*/
+
#if 0
+
static char base85Numeral( u8 b ){
+
  return (b < 4)? (char)(b + '#') : (char)(b - 4 + '*');
+
}
+
#else
+
# define base85Numeral( dn )\
+
  ((char)(((dn) < 4)? (char)((dn) + '#') : (char)((dn) - 4 + '*')))
+
#endif
+

+
static char *putcs(char *pc, char *s){
+
  char c;
+
  while( (c = *s++)!=0 ) *pc++ = c;
+
  return pc;
+
}
+

+
/* Encode a byte buffer into base85 text. If pSep!=0, it's a C string
+
** to be appended to encoded groups to limit their length to B85_DARK_MAX
+
** or to terminate the last group (to aid concatenation.)
+
*/
+
static char* toBase85( u8 *pIn, int nbIn, char *pOut, char *pSep ){
+
  int nCol = 0;
+
  while( nbIn >= 4 ){
+
    int nco = 5;
+
    unsigned long qbv = (((unsigned long)pIn[0])<<24) |
+
                        (pIn[1]<<16) | (pIn[2]<<8) | pIn[3];
+
    while( nco > 0 ){
+
      unsigned nqv = (unsigned)(qbv/85UL);
+
      unsigned char dv = qbv - 85UL*nqv;
+
      qbv = nqv;
+
      pOut[--nco] = base85Numeral(dv);
+
    }
+
    nbIn -= 4;
+
    pIn += 4;
+
    pOut += 5;
+
    if( pSep && (nCol += 5)>=B85_DARK_MAX ){
+
      pOut = putcs(pOut, pSep);
+
      nCol = 0;
+
    }
+
  }
+
  if( nbIn > 0 ){
+
    int nco = nbIn + 1;
+
    unsigned long qv = *pIn++;
+
    int nbe = 1;
+
    while( nbe++ < nbIn ){
+
      qv = (qv<<8) | *pIn++;
+
    }
+
    nCol += nco;
+
    while( nco > 0 ){
+
      u8 dv = (u8)(qv % 85);
+
      qv /= 85;
+
      pOut[--nco] = base85Numeral(dv);
+
    }
+
    pOut += (nbIn+1);
+
  }
+
  if( pSep && nCol>0 ) pOut = putcs(pOut, pSep);
+
  *pOut = 0;
+
  return pOut;
+
}
+

+
/* Decode base85 text into a byte buffer. */
+
static u8* fromBase85( char *pIn, int ncIn, u8 *pOut ){
+
  if( ncIn>0 && pIn[ncIn-1]=='\n' ) --ncIn;
+
  while( ncIn>0 ){
+
    static signed char nboi[] = { 0, 0, 1, 2, 3, 4 };
+
    char *pUse = skipNonB85(pIn, ncIn);
+
    unsigned long qv = 0L;
+
    int nti, nbo;
+
    ncIn -= (pUse - pIn);
+
    pIn = pUse;
+
    nti = (ncIn>5)? 5 : ncIn;
+
    nbo = nboi[nti];
+
    if( nbo==0 ) break;
+
    while( nti>0 ){
+
      char c = *pIn++;
+
      u8 cdo = B85_DNOS(c);
+
      --ncIn;
+
      if( cdo==0 ) break;
+
      qv = 85 * qv + (c - cdo);
+
      --nti;
+
    }
+
    nbo -= nti; /* Adjust for early (non-digit) end of group. */
+
    switch( nbo ){
+
    case 4:
+
      *pOut++ = (qv >> 24)&0xff;
+
    case 3:
+
      *pOut++ = (qv >> 16)&0xff;
+
    case 2:
+
      *pOut++ = (qv >> 8)&0xff;
+
    case 1:
+
      *pOut++ = qv&0xff;
+
    case 0:
+
      break;
    }
-
    memcpy(&r, &v, sizeof(r));
-
    sqlite3_result_double(context, r);
  }
+
  return pOut;
}
-
static void ieee754func_to_blob(
-
  sqlite3_context *context,
-
  int argc,
-
  sqlite3_value **argv
-
){
-
  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;
+

+
#ifndef OMIT_BASE85_CHECKER
+
/* Say whether input char sequence is all (base85 and/or whitespace).*/
+
static int allBase85( char *p, int len ){
+
  char c;
+
  while( len-- > 0 && (c = *p++) != 0 ){
+
    if( !IS_B85(c) && !isspace(c) ) return 0;
+
  }
+
  return 1;
+
}
+
#endif
+

+
#ifndef BASE85_STANDALONE
+

+
# ifndef OMIT_BASE85_CHECKER
+
/* This function does the work for the SQLite is_base85(t) UDF. */
+
static void is_base85(sqlite3_context *context, int na, sqlite3_value *av[]){
+
  assert(na==1);
+
  switch( sqlite3_value_type(av[0]) ){
+
  case SQLITE_TEXT:
+
    {
+
      int rv = allBase85( (char *)sqlite3_value_text(av[0]),
+
                          sqlite3_value_bytes(av[0]) );
+
      sqlite3_result_int(context, rv);
    }
-
    sqlite3_result_blob(context, a, sizeof(r), SQLITE_TRANSIENT);
+
    break;
+
  case SQLITE_NULL:
+
    sqlite3_result_null(context);
+
    break;
+
  default:
+
    sqlite3_result_error(context, "is_base85 accepts only text or NULL", -1);
+
    return;
  }
}
+
# endif

+
/* This function does the work for the SQLite base85(x) UDF. */
+
static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){
+
  int nb, nc, nv = sqlite3_value_bytes(av[0]);
+
  int nvMax = sqlite3_limit(sqlite3_context_db_handle(context),
+
                            SQLITE_LIMIT_LENGTH, -1);
+
  char *cBuf;
+
  u8 *bBuf;
+
  assert(na==1);
+
  switch( sqlite3_value_type(av[0]) ){
+
  case SQLITE_BLOB:
+
    nb = nv;
+
    /*    ulongs    tail   newlines  tailenc+nul*/
+
    nc = 5*(nv/4) + nv%4 + nv/64+1 + 2;
+
    if( nvMax < nc ){
+
      sqlite3_result_error(context, "blob expanded to base85 too big", -1);
+
      return;
+
    }
+
    bBuf = (u8*)sqlite3_value_blob(av[0]);
+
    if( !bBuf ){
+
      if( SQLITE_NOMEM==sqlite3_errcode(sqlite3_context_db_handle(context)) ){
+
        goto memFail;
+
      }
+
      sqlite3_result_text(context,"",-1,SQLITE_STATIC);
+
      break;
+
    }
+
    cBuf = sqlite3_malloc(nc);
+
    if( !cBuf ) goto memFail;
+
    nc = (int)(toBase85(bBuf, nb, cBuf, "\n") - cBuf);
+
    sqlite3_result_text(context, cBuf, nc, sqlite3_free);
+
    break;
+
  case SQLITE_TEXT:
+
    nc = nv;
+
    nb = 4*(nv/5) + nv%5; /* may overestimate */
+
    if( nvMax < nb ){
+
      sqlite3_result_error(context, "blob from base85 may be too big", -1);
+
      return;
+
    }else if( nb<1 ){
+
      nb = 1;
+
    }
+
    cBuf = (char *)sqlite3_value_text(av[0]);
+
    if( !cBuf ){
+
      if( SQLITE_NOMEM==sqlite3_errcode(sqlite3_context_db_handle(context)) ){
+
        goto memFail;
+
      }
+
      sqlite3_result_zeroblob(context, 0);
+
      break;
+
    }
+
    bBuf = sqlite3_malloc(nb);
+
    if( !bBuf ) goto memFail;
+
    nb = (int)(fromBase85(cBuf, nc, bBuf) - bBuf);
+
    sqlite3_result_blob(context, bBuf, nb, sqlite3_free);
+
    break;
+
  default:
+
    sqlite3_result_error(context, "base85 accepts only blob or text.", -1);
+
    return;
+
  }
+
  return;
+
 memFail:
+
  sqlite3_result_error(context, "base85 OOM", -1);
+
}

+
/*
+
** Establish linkage to running SQLite library.
+
*/
+
#ifndef SQLITE_SHELL_EXTFUNCS
#ifdef _WIN32

#endif
-
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;
+
int sqlite3_base_init
+
#else
+
static int sqlite3_base85_init
+
#endif
+
(sqlite3 *db, char **pzErr, const sqlite3_api_routines *pApi){
  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);
+
  (void)pzErr;
+
# ifndef OMIT_BASE85_CHECKER
+
  {
+
    int rc = sqlite3_create_function
+
      (db, "is_base85", 1,
+
       SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|SQLITE_UTF8,
+
       0, is_base85, 0, 0);
+
    if( rc!=SQLITE_OK ) return rc;
+
  }
+
# endif
+
  return sqlite3_create_function
+
    (db, "base85", 1,
+
     SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|SQLITE_DIRECTONLY|SQLITE_UTF8,
+
     0, base85, 0, 0);
+
}
+

+
/*
+
** Define some macros to allow this extension to be built into the shell
+
** conveniently, in conjunction with use of SQLITE_SHELL_EXTFUNCS. This
+
** allows shell.c, as distributed, to have this extension built in.
+
*/
+
# define BASE85_INIT(db) sqlite3_base85_init(db, 0, 0)
+
# define BASE85_EXPOSE(db, pzErr) /* Not needed, ..._init() does this. */
+

+
#else /* standalone program */
+

+
int main(int na, char *av[]){
+
  int cin;
+
  int rc = 0;
+
  u8 bBuf[4*(B85_DARK_MAX/5)];
+
  char cBuf[5*(sizeof(bBuf)/4)+2];
+
  size_t nio;
+
# ifndef OMIT_BASE85_CHECKER
+
  int b85Clean = 1;
+
# endif
+
  char rw;
+
  FILE *fb = 0, *foc = 0;
+
  char fmode[3] = "xb";
+
  if( na < 3 || av[1][0]!='-' || (rw = av[1][1])==0 || (rw!='r' && rw!='w') ){
+
    sayHelp();
+
    return 0;
+
  }
+
  fmode[0] = rw;
+
  if( av[2][0]=='-' && av[2][1]==0 ){
+
    switch( rw ){
+
    case 'r':
+
      fb = stdin;
+
      setmode(fileno(stdin), O_BINARY);
+
      break;
+
    case 'w':
+
      fb = stdout;
+
      setmode(fileno(stdout), O_BINARY);
+
      break;
+
    }
+
  }else{
+
    fb = fopen(av[2], fmode);
+
    foc = fb;
+
  }
+
  if( !fb ){
+
    fprintf(stderr, "Cannot open %s for %c\n", av[2], rw);
+
    rc = 1;
+
  }else{
+
    switch( rw ){
+
    case 'r':
+
      while( (nio = fread( bBuf, 1, sizeof(bBuf), fb))>0 ){
+
        toBase85( bBuf, (int)nio, cBuf, 0 );
+
        fprintf(stdout, "%s\n", cBuf);
+
      }
+
      break;
+
    case 'w':
+
      while( 0 != fgets(cBuf, sizeof(cBuf), stdin) ){
+
        int nc = strlen(cBuf);
+
        size_t nbo = fromBase85( cBuf, nc, bBuf ) - bBuf;
+
        if( 1 != fwrite(bBuf, nbo, 1, fb) ) rc = 1;
+
# ifndef OMIT_BASE85_CHECKER
+
        b85Clean &= allBase85( cBuf, nc );
+
# endif
+
      }
+
      break;
+
    default:
+
      sayHelp();
+
      rc = 1;
+
    }
+
    if( foc ) fclose(foc);
  }
+
# ifndef OMIT_BASE85_CHECKER
+
  if( !b85Clean ){
+
    fprintf(stderr, "Base85 input had non-base85 dark or control content.\n");
+
  }
+
# endif
  return rc;
}

-
/************************* End ../ext/misc/ieee754.c ********************/
-
/************************* Begin ../ext/misc/series.c ******************/
+
#endif
+

+
/************************* End ../ext/misc/base85.c ********************/
+
/************************* Begin ../ext/misc/ieee754.c ******************/
/*
-
** 2015-08-18
+
** 2013-04-17
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
@@ -3291,154 +4024,585 @@ int sqlite3_ieee_init(
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
-
*************************************************************************
+
******************************************************************************
**
-
** 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:
+
** This SQLite extension implements functions for the exact display
+
** and input of IEEE754 Binary64 floating-point numbers.
**
-
**      SELECT * FROM generate_series(0,100,5);
+
**   ieee754(X)
+
**   ieee754(Y,Z)
**
-
** The query above returns integers from 0 through 100 counting by steps
-
** of 5.
+
** 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).
**
-
**      SELECT * FROM generate_series(0,100);
+
** 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).
**
-
** Integers from 0 through 100 with a step size of 1.
+
** Examples:
**
-
**      SELECT * FROM generate_series(20) LIMIT 10;
+
**     ieee754(2.0)             ->     'ieee754(2,0)'
+
**     ieee754(45.25)           ->     'ieee754(181,-2)'
+
**     ieee754(2, 0)            ->     2.0
+
**     ieee754(181, -2)         ->     45.25
**
-
** Integers 20 through 29.
+
** Two additional functions break apart the one-argument ieee754()
+
** result into separate integer values:
**
-
** HOW IT WORKS
+
**     ieee754_mantissa(45.25)  ->     181
+
**     ieee754_exponent(45.25)  ->     -2
**
-
** The generate_series "function" is really a virtual table with the
-
** following schema:
+
** These functions convert binary64 numbers into blobs and back again.
**
-
**     CREATE TABLE generate_series(
-
**       value,
-
**       start HIDDEN,
-
**       stop HIDDEN,
-
**       step HIDDEN
-
**     );
+
**     ieee754_from_blob(x'3ff0000000000000')  ->  1.0
+
**     ieee754_to_blob(1.0)                    ->  x'3ff0000000000000'
**
-
** 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:
+
** In all single-argument functions, if the argument is an 8-byte blob
+
** then that blob is interpreted as a big-endian binary64 value.
**
-
**    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;
+
** EXACT DECIMAL REPRESENTATION OF BINARY64 VALUES
+
** -----------------------------------------------
**
-
**    SELECT * FROM generate_series(20) LIMIT 10;
-
**    SELECT * FROM generate_series WHERE start=20 LIMIT 10;
+
** 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:
**
-
** 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.
+
**    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);
**
-
** 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>

-
#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") */
-
};
+
/* Mark a function parameter as unused, to suppress nuisance compiler
+
** warnings. */
+
#ifndef UNUSED_PARAMETER
+
# define UNUSED_PARAMETER(X)  (void)(X)
+
#endif

/*
-
** 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.
+
** Implementation of the ieee754() function
*/
-
static int seriesConnect(
-
  sqlite3 *db,
-
  void *pUnused,
-
  int argcUnused, const char *const*argvUnused,
-
  sqlite3_vtab **ppVtab,
-
  char **pzErrUnused
+
static void ieee754func(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
){
-
  sqlite3_vtab *pNew;
-
  int rc;
+
  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( r<0.0 ){
+
      isNeg = 1;
+
      r = -r;
+
    }else{
+
      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{
+
        m |= ((sqlite3_int64)1)<<52;
+
      }
+
      while( e<1075 && m>0 && (m&1)==0 ){
+
        m >>= 1;
+
        e++;
+
      }
+
      if( isNeg ) m = -m;
+
    }
+
    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]);

-
/* Column numbers */
-
#define SERIES_COLUMN_VALUE 0
-
#define SERIES_COLUMN_START 1
-
#define SERIES_COLUMN_STOP  2
-
#define SERIES_COLUMN_STEP  3
+
    /* Limit the range of e.  Ticket 22dea1cfdb9151e4 2021-03-02 */
+
    if( e>10000 ){
+
      e = 10000;
+
    }else if( e<-10000 ){
+
      e = -10000;
+
    }

-
  (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);
+
    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;
+
      }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 rc;
-
}
-

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

/*
-
** Constructor for a new series_cursor object.
+
** Functions to convert between blobs and floats.
*/
-
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;
+
static void ieee754func_from_blob(
+
  sqlite3_context *context,
+
  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);
+
  }
}
-

+
static void ieee754func_to_blob(
+
  sqlite3_context *context,
+
  int argc,
+
  sqlite3_value **argv
+
){
+
  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);
+
  }
+
}
+

+

+
#ifdef _WIN32
+

+
#endif
+
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 */
+
  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/ieee754.c ********************/
+
/************************* Begin ../ext/misc/series.c ******************/
+
/*
+
** 2015-08-18, 2023-04-28
+
**
+
** The author disclaims copyright to this source code.  In place of
+
** a legal notice, here is a blessing:
+
**
+
**    May you do good and not evil.
+
**    May you find forgiveness for yourself and forgive others.
+
**    May you share freely, never taking more than you give.
+
**
+
*************************************************************************
+
**
+
** This file demonstrates how to create a table-valued-function using
+
** a virtual table.  This demo implements the generate_series() function
+
** which gives the same results as the eponymous function in PostgreSQL,
+
** within the limitation that its arguments are signed 64-bit integers.
+
**
+
** Considering its equivalents to generate_series(start,stop,step): A
+
** value V[n] sequence is produced for integer n ascending from 0 where
+
**  ( V[n] == start + n * step  &&  sgn(V[n] - stop) * sgn(step) >= 0 )
+
** for each produced value (independent of production time ordering.)
+
**
+
** All parameters must be either integer or convertable to integer.
+
** The start parameter is required.
+
** The stop parameter defaults to (1<<32)-1 (aka 4294967295 or 0xffffffff)
+
** The step parameter defaults to 1 and 0 is treated as 1.
+
**
+
** 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.
+
**
+
**      SELECT * FROM generate_series(0,-100,-5);
+
**
+
** Integers 0 -5 -10 ... -100.
+
**
+
**      SELECT * FROM generate_series(0,-1);
+
**
+
** Empty sequence.
+
**
+
** 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
+
**     );
+
**
+
** The virtual table also has a rowid, logically equivalent to n+1 where
+
** "n" is the ascending integer in the aforesaid production definition.
+
**
+
** 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.
+
*/
+
/* #include "sqlite3ext.h" */
+
SQLITE_EXTENSION_INIT1
+
#include <assert.h>
+
#include <string.h>
+
#include <limits.h>
+

+
#ifndef SQLITE_OMIT_VIRTUALTABLE
+
/*
+
** Return that member of a generate_series(...) sequence whose 0-based
+
** index is ix. The 0th member is given by smBase. The sequence members
+
** progress per ix increment by smStep.
+
*/
+
static sqlite3_int64 genSeqMember(sqlite3_int64 smBase,
+
                                  sqlite3_int64 smStep,
+
                                  sqlite3_uint64 ix){
+
  if( ix>=(sqlite3_uint64)LLONG_MAX ){
+
    /* Get ix into signed i64 range. */
+
    ix -= (sqlite3_uint64)LLONG_MAX;
+
    /* With 2's complement ALU, this next can be 1 step, but is split into
+
     * 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */
+
    smBase += (LLONG_MAX/2) * smStep;
+
    smBase += (LLONG_MAX - LLONG_MAX/2) * smStep;
+
  }
+
  /* Under UBSAN (or on 1's complement machines), must do this last term
+
   * in steps to avoid the dreaded (and harmless) signed multiply overlow. */
+
  if( ix>=2 ){
+
    sqlite3_int64 ix2 = (sqlite3_int64)ix/2;
+
    smBase += ix2*smStep;
+
    ix -= ix2;
+
  }
+
  return smBase + ((sqlite3_int64)ix)*smStep;
+
}
+

+
/* typedef unsigned char u8; */
+

+
typedef struct SequenceSpec {
+
  sqlite3_int64 iBase;         /* Starting value ("start") */
+
  sqlite3_int64 iTerm;         /* Given terminal value ("stop") */
+
  sqlite3_int64 iStep;         /* Increment ("step") */
+
  sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */
+
  sqlite3_uint64 uSeqIndexNow; /* Current index during generation */
+
  sqlite3_int64 iValueNow;     /* Current value during generation */
+
  u8 isNotEOF;                 /* Sequence generation not exhausted */
+
  u8 isReversing;              /* Sequence is being reverse generated */
+
} SequenceSpec;
+

+
/*
+
** Prepare a SequenceSpec for use in generating an integer series
+
** given initialized iBase, iTerm and iStep values. Sequence is
+
** initialized per given isReversing. Other members are computed.
+
*/
+
static void setupSequence( SequenceSpec *pss ){
+
  int bSameSigns;
+
  pss->uSeqIndexMax = 0;
+
  pss->isNotEOF = 0;
+
  bSameSigns = (pss->iBase < 0)==(pss->iTerm < 0);
+
  if( pss->iTerm < pss->iBase ){
+
    sqlite3_uint64 nuspan = 0;
+
    if( bSameSigns ){
+
      nuspan = (sqlite3_uint64)(pss->iBase - pss->iTerm);
+
    }else{
+
      /* Under UBSAN (or on 1's complement machines), must do this in steps.
+
       * In this clause, iBase>=0 and iTerm<0 . */
+
      nuspan = 1;
+
      nuspan += pss->iBase;
+
      nuspan += -(pss->iTerm+1);
+
    }
+
    if( pss->iStep<0 ){
+
      pss->isNotEOF = 1;
+
      if( nuspan==ULONG_MAX ){
+
        pss->uSeqIndexMax = ( pss->iStep>LLONG_MIN )? nuspan/-pss->iStep : 1;
+
      }else if( pss->iStep>LLONG_MIN ){
+
        pss->uSeqIndexMax = nuspan/-pss->iStep;
+
      }
+
    }
+
  }else if( pss->iTerm > pss->iBase ){
+
    sqlite3_uint64 puspan = 0;
+
    if( bSameSigns ){
+
      puspan = (sqlite3_uint64)(pss->iTerm - pss->iBase);
+
    }else{
+
      /* Under UBSAN (or on 1's complement machines), must do this in steps.
+
       * In this clause, iTerm>=0 and iBase<0 . */
+
      puspan = 1;
+
      puspan += pss->iTerm;
+
      puspan += -(pss->iBase+1);
+
    }
+
    if( pss->iStep>0 ){
+
      pss->isNotEOF = 1;
+
      pss->uSeqIndexMax = puspan/pss->iStep;
+
    }
+
  }else if( pss->iTerm == pss->iBase ){
+
      pss->isNotEOF = 1;
+
      pss->uSeqIndexMax = 0;
+
  }
+
  pss->uSeqIndexNow = (pss->isReversing)? pss->uSeqIndexMax : 0;
+
  pss->iValueNow = (pss->isReversing)
+
    ? genSeqMember(pss->iBase, pss->iStep, pss->uSeqIndexMax)
+
    : pss->iBase;
+
}
+

+
/*
+
** Progress sequence generator to yield next value, if any.
+
** Leave its state to either yield next value or be at EOF.
+
** Return whether there is a next value, or 0 at EOF.
+
*/
+
static int progressSequence( SequenceSpec *pss ){
+
  if( !pss->isNotEOF ) return 0;
+
  if( pss->isReversing ){
+
    if( pss->uSeqIndexNow > 0 ){
+
      pss->uSeqIndexNow--;
+
      pss->iValueNow -= pss->iStep;
+
    }else{
+
      pss->isNotEOF = 0;
+
    }
+
  }else{
+
    if( pss->uSeqIndexNow < pss->uSeqIndexMax ){
+
      pss->uSeqIndexNow++;
+
      pss->iValueNow += pss->iStep;
+
    }else{
+
      pss->isNotEOF = 0;
+
    }
+
  }
+
  return pss->isNotEOF;
+
}
+

+
/* 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 */
+
  SequenceSpec ss;           /* (this) Derived class data */
+
};
+

+
/*
+
** 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.
+
*/
+
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;
+
}
+

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

+
/*
+
** Constructor for a new series_cursor object.
+
*/
+
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;
+
}
+

/*
** Destructor for a series_cursor.
*/
@@ -3453,12 +4617,7 @@ static int seriesClose(sqlite3_vtab_cursor *cur){
*/
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++;
+
  progressSequence( & pCur->ss );
  return SQLITE_OK;
}

@@ -3474,23 +4633,23 @@ static int seriesColumn(
  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;
+
    case SERIES_COLUMN_START:  x = pCur->ss.iBase; break;
+
    case SERIES_COLUMN_STOP:   x = pCur->ss.iTerm; break;
+
    case SERIES_COLUMN_STEP:   x = pCur->ss.iStep;   break;
+
    default:                   x = pCur->ss.iValueNow;  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, logically equivalent to n+1 where
+
** "n" is the ascending integer in the aforesaid production definition.
*/
static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
  series_cursor *pCur = (series_cursor*)cur;
-
  *pRowid = pCur->iRowid;
+
  sqlite3_uint64 n = pCur->ss.uSeqIndexNow;
+
  *pRowid = (sqlite3_int64)((n<0xffffffffffffffff)? n+1 : 0);
  return SQLITE_OK;
}

@@ -3500,14 +4659,10 @@ static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
*/
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;
-
  }
+
  return !pCur->ss.isNotEOF;
}

-
/* True to cause run-time checking of the start=, stop=, and/or step= 
+
/* 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.
*/
@@ -3518,7 +4673,7 @@ static int seriesEof(sqlite3_vtab_cursor *cur){
/*
** 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 
+
** once prior to any call to seriesColumn() or seriesRowid() or
** seriesEof().
**
** The query plan selected by seriesBestIndex is passed in the idxNum
@@ -3538,7 +4693,7 @@ static int seriesEof(sqlite3_vtab_cursor *cur){
** (so that seriesEof() will return true) if the table is empty.
*/
static int seriesFilter(
-
  sqlite3_vtab_cursor *pVtabCursor, 
+
  sqlite3_vtab_cursor *pVtabCursor,
  int idxNum, const char *idxStrUnused,
  int argc, sqlite3_value **argv
){
@@ -3546,46 +4701,41 @@ static int seriesFilter(
  int i = 0;
  (void)idxStrUnused;
  if( idxNum & 1 ){
-
    pCur->mnValue = sqlite3_value_int64(argv[i++]);
+
    pCur->ss.iBase = sqlite3_value_int64(argv[i++]);
  }else{
-
    pCur->mnValue = 0;
+
    pCur->ss.iBase = 0;
  }
  if( idxNum & 2 ){
-
    pCur->mxValue = sqlite3_value_int64(argv[i++]);
+
    pCur->ss.iTerm = sqlite3_value_int64(argv[i++]);
  }else{
-
    pCur->mxValue = 0xffffffff;
+
    pCur->ss.iTerm = 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;
+
    pCur->ss.iStep = sqlite3_value_int64(argv[i++]);
+
    if( pCur->ss.iStep==0 ){
+
      pCur->ss.iStep = 1;
+
    }else if( pCur->ss.iStep<0 ){
      if( (idxNum & 16)==0 ) idxNum |= 8;
    }
  }else{
-
    pCur->iStep = 1;
+
    pCur->ss.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;
+
      pCur->ss.iBase = 1;
+
      pCur->ss.iTerm = 0;
+
      pCur->ss.iStep = 1;
      break;
    }
  }
  if( idxNum & 8 ){
-
    pCur->isDesc = 1;
-
    pCur->iValue = pCur->mxValue;
-
    if( pCur->iStep>0 ){
-
      pCur->iValue -= (pCur->mxValue - pCur->mnValue)%pCur->iStep;
-
    }
+
    pCur->ss.isReversing = pCur->ss.iStep > 0;
  }else{
-
    pCur->isDesc = 0;
-
    pCur->iValue = pCur->mnValue;
+
    pCur->ss.isReversing = pCur->ss.iStep < 0;
  }
-
  pCur->iRowid = 1;
+
  setupSequence( &pCur->ss );
  return SQLITE_OK;
}

@@ -3930,7 +5080,7 @@ static unsigned re_next_char(ReInput *p){
      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
+
    }else if( (c&0xf8)==0xf0 && p->i+2<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);
@@ -4340,7 +5490,7 @@ static const char *re_subcompile_string(ReCompiled *p){
        break;
      }
      case '[': {
-
        int iFirst = p->nState;
+
        unsigned int iFirst = p->nState;
        if( rePeek(p)=='^' ){
          re_append(p, RE_OP_CC_EXC, 0);
          p->sIn.i++;
@@ -4364,7 +5514,7 @@ static const char *re_subcompile_string(ReCompiled *p){
          if( rePeek(p)==']' ){ p->sIn.i++; break; }
        }
        if( c==0 ) return "unclosed '['";
-
        p->aArg[iFirst] = p->nState - iFirst;
+
        if( p->nState>iFirst ) p->aArg[iFirst] = p->nState - iFirst;
        break;
      }
      case '\\': {
@@ -4457,15 +5607,15 @@ static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
  ** 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
+
  ** regex engine over the string.  Do not worry about 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 ){
+
      if( x<=0x7f ){
        pRe->zInit[j++] = (unsigned char)x;
-
      }else if( x<=0xfff ){
+
      }else if( x<=0x7ff ){
        pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
        pRe->zInit[j++] = 0x80 | (x&0x3f);
      }else if( x<=0xffff ){
@@ -4548,6 +5698,7 @@ static void re_bytecode_func(
  int i;
  int n;
  char *z;
+
  (void)argc;

  zPattern = (const char*)sqlite3_value_text(argv[0]);
  if( zPattern==0 ) return;
@@ -7195,6 +8346,7 @@ static int zipfileConnect(
  const char *zFile = 0;
  ZipfileTab *pNew = 0;
  int rc;
+
  (void)pAux;

  /* If the table name is not "zipfile", require that the argument be
  ** specified. This stops zipfile tables from being created as:
@@ -7651,6 +8803,7 @@ static int zipfileGetEntry(
  u8 *aRead;
  char **pzErr = &pTab->base.zErrMsg;
  int rc = SQLITE_OK;
+
  (void)nBlob;

  if( aBlob==0 ){
    aRead = pTab->aBuffer;
@@ -7938,7 +9091,10 @@ static int zipfileColumn(
          ** it to be a directory either if the mode suggests so, or if
          ** the final character in the name is '/'.  */
          u32 mode = pCDS->iExternalAttr >> 16;
-
          if( !(mode & S_IFDIR) && pCDS->zFile[pCDS->nFile-1]!='/' ){
+
          if( !(mode & S_IFDIR)
+
           && pCDS->nFile>=1
+
           && pCDS->zFile[pCDS->nFile-1]!='/'
+
          ){
            sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC);
          }
        }
@@ -8097,6 +9253,9 @@ static int zipfileFilter(
  int rc = SQLITE_OK;             /* Return Code */
  int bInMemory = 0;              /* True for an in-memory zipfile */

+
  (void)idxStr;
+
  (void)argc;
+

  zipfileResetCursor(pCsr);

  if( pTab->zFile ){
@@ -8123,7 +9282,7 @@ static int zipfileFilter(
  }

  if( 0==pTab->pWriteFd && 0==bInMemory ){
-
    pCsr->pFile = fopen(zFile, "rb");
+
    pCsr->pFile = zFile ? fopen(zFile, "rb") : 0;
    if( pCsr->pFile==0 ){
      zipfileCursorErr(pCsr, "cannot open file: %s", zFile);
      rc = SQLITE_ERROR;
@@ -8157,6 +9316,7 @@ static int zipfileBestIndex(
  int i;
  int idx = -1;
  int unusable = 0;
+
  (void)tab;

  for(i=0; i<pIdxInfo->nConstraint; i++){
    const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
@@ -8371,9 +9531,19 @@ static u32 zipfileGetTime(sqlite3_value *pVal){
*/
static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){
  if( pOld ){
-
    ZipfileEntry **pp;
-
    for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext));
-
    *pp = (*pp)->pNext;
+
    if( pTab->pFirstEntry==pOld ){
+
      pTab->pFirstEntry = pOld->pNext;
+
      if( pTab->pLastEntry==pOld ) pTab->pLastEntry = 0;
+
    }else{
+
      ZipfileEntry *p;
+
      for(p=pTab->pFirstEntry; p; p=p->pNext){
+
        if( p->pNext==pOld ){
+
          p->pNext = pOld->pNext;
+
          if( pTab->pLastEntry==pOld ) pTab->pLastEntry = p;
+
          break;
+
        }
+
      }
+
    }
    zipfileEntryFree(pOld);
  }
}
@@ -8407,6 +9577,8 @@ static int zipfileUpdate(
  int bIsDir = 0;
  u32 iCrc32 = 0;

+
  (void)pRowid;
+

  if( pTab->pWriteFd==0 ){
    rc = zipfileBegin(pVtab);
    if( rc!=SQLITE_OK ) return rc;
@@ -8741,6 +9913,7 @@ static int zipfileFindFunction(
  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
  void **ppArg                    /* OUT: User data for *pxFunc */
){
+
  (void)nArg;
  if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
    *pxFunc = zipfileFunctionCds;
    *ppArg = (void*)pVtab;
@@ -9149,7 +10322,9 @@ static void sqlarUncompressFunc(
  }else{
    const Bytef *pData= sqlite3_value_blob(argv[0]);
    Bytef *pOut = sqlite3_malloc(sz);
-
    if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){
+
    if( pOut==0 ){
+
      sqlite3_result_error_nomem(context);
+
    }else if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){
      sqlite3_result_error(context, "error in uncompress()", -1);
    }else{
      sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT);
@@ -9158,7 +10333,6 @@ static void sqlarUncompressFunc(
  }
}

-

#ifdef _WIN32

#endif
@@ -11412,9 +12586,9 @@ void sqlite3_expert_destroy(sqlite3expert *p){
#define SQLITE_SHELL_HAVE_RECOVER 0
#endif
#if SQLITE_SHELL_HAVE_RECOVER
-
/************************* Begin ../ext/recover/dbdata.c ******************/
+
/************************* Begin ../ext/recover/sqlite3recover.h ******************/
/*
-
** 2019-04-17
+
** 2022-08-27
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
@@ -11423,402 +12597,659 @@ void sqlite3_expert_destroy(sqlite3expert *p){
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
-
******************************************************************************
-
**
-
** This file contains an implementation of two eponymous virtual tables,
-
** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the
-
** "sqlite_dbpage" eponymous virtual table be available.
-
**
-
** SQLITE_DBDATA:
-
**   sqlite_dbdata is used to extract data directly from a database b-tree
-
**   page and its associated overflow pages, bypassing the b-tree layer.
-
**   The table schema is equivalent to:
-
**
-
**     CREATE TABLE sqlite_dbdata(
-
**       pgno INTEGER,
-
**       cell INTEGER,
-
**       field INTEGER,
-
**       value ANY,
-
**       schema TEXT HIDDEN
-
**     );
-
**
-
**   IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE
-
**   FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND
-
**   "schema".
-
**
-
**   Each page of the database is inspected. If it cannot be interpreted as
-
**   a b-tree page, or if it is a b-tree page containing 0 entries, the
-
**   sqlite_dbdata table contains no rows for that page.  Otherwise, the
-
**   table contains one row for each field in the record associated with
-
**   each cell on the page. For intkey b-trees, the key value is stored in
-
**   field -1.
+
*************************************************************************
**
-
**   For example, for the database:
+
** This file contains the public interface to the "recover" extension -
+
** an SQLite extension designed to recover data from corrupted database
+
** files.
+
*/
+

+
/*
+
** OVERVIEW:
**
-
**     CREATE TABLE t1(a, b);     -- root page is page 2
-
**     INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five');
-
**     INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
+
** To use the API to recover data from a corrupted database, an
+
** application:
**
-
**   the sqlite_dbdata table contains, as well as from entries related to 
-
**   page 1, content equivalent to:
+
**   1) Creates an sqlite3_recover handle by calling either
+
**      sqlite3_recover_init() or sqlite3_recover_init_sql().
**
-
**     INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES
-
**         (2, 0, -1, 5     ),
-
**         (2, 0,  0, 'v'   ),
-
**         (2, 0,  1, 'five'),
-
**         (2, 1, -1, 10    ),
-
**         (2, 1,  0, 'x'   ),
-
**         (2, 1,  1, 'ten' );
+
**   2) Configures the new handle using one or more calls to
+
**      sqlite3_recover_config().
**
-
**   If database corruption is encountered, this module does not report an
-
**   error. Instead, it attempts to extract as much data as possible and
-
**   ignores the corruption.
+
**   3) Executes the recovery by repeatedly calling sqlite3_recover_step() on
+
**      the handle until it returns something other than SQLITE_OK. If it
+
**      returns SQLITE_DONE, then the recovery operation completed without 
+
**      error. If it returns some other non-SQLITE_OK value, then an error 
+
**      has occurred.
**
-
** SQLITE_DBPTR:
-
**   The sqlite_dbptr table has the following schema:
+
**   4) Retrieves any error code and English language error message using the
+
**      sqlite3_recover_errcode() and sqlite3_recover_errmsg() APIs,
+
**      respectively.
**
-
**     CREATE TABLE sqlite_dbptr(
-
**       pgno INTEGER,
-
**       child INTEGER,
-
**       schema TEXT HIDDEN
-
**     );
+
**   5) Destroys the sqlite3_recover handle and frees all resources
+
**      using sqlite3_recover_finish().
**
-
**   It contains one entry for each b-tree pointer between a parent and
-
**   child page in the database.
+
** The application may abandon the recovery operation at any point 
+
** before it is finished by passing the sqlite3_recover handle to
+
** sqlite3_recover_finish(). This is not an error, but the final state
+
** of the output database, or the results of running the partial script
+
** delivered to the SQL callback, are undefined.
*/

-
#if !defined(SQLITEINT_H) 
-
/* #include "sqlite3ext.h" */
+
#ifndef _SQLITE_RECOVER_H
+
#define _SQLITE_RECOVER_H

-
/* typedef unsigned char u8; */
-
/* typedef unsigned int u32; */
+
/* #include "sqlite3.h" */

+
#ifdef __cplusplus
+
extern "C" {
#endif
-
SQLITE_EXTENSION_INIT1
-
#include <string.h>
-
#include <assert.h>
-

-
#ifndef SQLITE_OMIT_VIRTUALTABLE
-

-
#define DBDATA_PADDING_BYTES 100 
-

-
typedef struct DbdataTable DbdataTable;
-
typedef struct DbdataCursor DbdataCursor;
-

-
/* Cursor object */
-
struct DbdataCursor {
-
  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
-
  sqlite3_stmt *pStmt;            /* For fetching database pages */
-

-
  int iPgno;                      /* Current page number */
-
  u8 *aPage;                      /* Buffer containing page */
-
  int nPage;                      /* Size of aPage[] in bytes */
-
  int nCell;                      /* Number of cells on aPage[] */
-
  int iCell;                      /* Current cell number */
-
  int bOnePage;                   /* True to stop after one page */
-
  int szDb;
-
  sqlite3_int64 iRowid;
-

-
  /* Only for the sqlite_dbdata table */
-
  u8 *pRec;                       /* Buffer containing current record */
-
  sqlite3_int64 nRec;             /* Size of pRec[] in bytes */
-
  sqlite3_int64 nHdr;             /* Size of header in bytes */
-
  int iField;                     /* Current field number */
-
  u8 *pHdrPtr;
-
  u8 *pPtr;
-
  u32 enc;                        /* Text encoding */
-
  
-
  sqlite3_int64 iIntkey;          /* Integer key value */
-
};
-

-
/* Table object */
-
struct DbdataTable {
-
  sqlite3_vtab base;              /* Base class.  Must be first */
-
  sqlite3 *db;                    /* The database connection */
-
  sqlite3_stmt *pStmt;            /* For fetching database pages */
-
  int bPtr;                       /* True for sqlite3_dbptr table */
-
};
-

-
/* Column and schema definitions for sqlite_dbdata */
-
#define DBDATA_COLUMN_PGNO        0
-
#define DBDATA_COLUMN_CELL        1
-
#define DBDATA_COLUMN_FIELD       2
-
#define DBDATA_COLUMN_VALUE       3
-
#define DBDATA_COLUMN_SCHEMA      4
-
#define DBDATA_SCHEMA             \
-
      "CREATE TABLE x("           \
-
      "  pgno INTEGER,"           \
-
      "  cell INTEGER,"           \
-
      "  field INTEGER,"          \
-
      "  value ANY,"              \
-
      "  schema TEXT HIDDEN"      \
-
      ")"
-

-
/* Column and schema definitions for sqlite_dbptr */
-
#define DBPTR_COLUMN_PGNO         0
-
#define DBPTR_COLUMN_CHILD        1
-
#define DBPTR_COLUMN_SCHEMA       2
-
#define DBPTR_SCHEMA              \
-
      "CREATE TABLE x("           \
-
      "  pgno INTEGER,"           \
-
      "  child INTEGER,"          \
-
      "  schema TEXT HIDDEN"      \
-
      ")"
-

-
/*
-
** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual 
-
** table.
-
*/
-
static int dbdataConnect(
-
  sqlite3 *db,
-
  void *pAux,
-
  int argc, const char *const*argv,
-
  sqlite3_vtab **ppVtab,
-
  char **pzErr
-
){
-
  DbdataTable *pTab = 0;
-
  int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);
-

-
  if( rc==SQLITE_OK ){
-
    pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable));
-
    if( pTab==0 ){
-
      rc = SQLITE_NOMEM;
-
    }else{
-
      memset(pTab, 0, sizeof(DbdataTable));
-
      pTab->db = db;
-
      pTab->bPtr = (pAux!=0);
-
    }
-
  }
-

-
  *ppVtab = (sqlite3_vtab*)pTab;
-
  return rc;
-
}
-

-
/*
-
** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table.
-
*/
-
static int dbdataDisconnect(sqlite3_vtab *pVtab){
-
  DbdataTable *pTab = (DbdataTable*)pVtab;
-
  if( pTab ){
-
    sqlite3_finalize(pTab->pStmt);
-
    sqlite3_free(pVtab);
-
  }
-
  return SQLITE_OK;
-
}

/*
-
** This function interprets two types of constraints:
+
** An instance of the sqlite3_recover object represents a recovery
+
** operation in progress.
**
-
**       schema=?
-
**       pgno=?
+
** Constructors:
**
-
** If neither are present, idxNum is set to 0. If schema=? is present,
-
** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit
-
** in idxNum is set.
+
**    sqlite3_recover_init()
+
**    sqlite3_recover_init_sql()
**
-
** If both parameters are present, schema is in position 0 and pgno in
-
** position 1.
+
** Destructor:
+
**
+
**    sqlite3_recover_finish()
+
**
+
** Methods:
+
**
+
**    sqlite3_recover_config()
+
**    sqlite3_recover_errcode()
+
**    sqlite3_recover_errmsg()
+
**    sqlite3_recover_run()
+
**    sqlite3_recover_step()
*/
-
static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){
-
  DbdataTable *pTab = (DbdataTable*)tab;
-
  int i;
-
  int iSchema = -1;
-
  int iPgno = -1;
-
  int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA);
+
typedef struct sqlite3_recover sqlite3_recover;

-
  for(i=0; i<pIdx->nConstraint; i++){
-
    struct sqlite3_index_constraint *p = &pIdx->aConstraint[i];
-
    if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
-
      if( p->iColumn==colSchema ){
-
        if( p->usable==0 ) return SQLITE_CONSTRAINT;
-
        iSchema = i;
-
      }
-
      if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){
-
        iPgno = i;
-
      }
-
    }
-
  }
-

-
  if( iSchema>=0 ){
-
    pIdx->aConstraintUsage[iSchema].argvIndex = 1;
-
    pIdx->aConstraintUsage[iSchema].omit = 1;
-
  }
-
  if( iPgno>=0 ){
-
    pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0);
-
    pIdx->aConstraintUsage[iPgno].omit = 1;
-
    pIdx->estimatedCost = 100;
-
    pIdx->estimatedRows =  50;
-

-
    if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){
-
      int iCol = pIdx->aOrderBy[0].iColumn;
-
      if( pIdx->nOrderBy==1 ){
-
        pIdx->orderByConsumed = (iCol==0 || iCol==1);
-
      }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){
-
        pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1);
-
      }
-
    }
+
/* 
+
** These two APIs attempt to create and return a new sqlite3_recover object.
+
** In both cases the first two arguments identify the (possibly
+
** corrupt) database to recover data from. The first argument is an open
+
** database handle and the second the name of a database attached to that
+
** handle (i.e. "main", "temp" or the name of an attached database).
+
**
+
** If sqlite3_recover_init() is used to create the new sqlite3_recover
+
** handle, then data is recovered into a new database, identified by
+
** string parameter zUri. zUri may be an absolute or relative file path,
+
** or may be an SQLite URI. If the identified database file already exists,
+
** it is overwritten.
+
**
+
** If sqlite3_recover_init_sql() is invoked, then any recovered data will
+
** be returned to the user as a series of SQL statements. Executing these
+
** SQL statements results in the same database as would have been created
+
** had sqlite3_recover_init() been used. For each SQL statement in the
+
** output, the callback function passed as the third argument (xSql) is 
+
** invoked once. The first parameter is a passed a copy of the fourth argument
+
** to this function (pCtx) as its first parameter, and a pointer to a
+
** nul-terminated buffer containing the SQL statement formated as UTF-8 as 
+
** the second. If the xSql callback returns any value other than SQLITE_OK,
+
** then processing is immediately abandoned and the value returned used as
+
** the recover handle error code (see below).
+
**
+
** If an out-of-memory error occurs, NULL may be returned instead of
+
** a valid handle. In all other cases, it is the responsibility of the
+
** application to avoid resource leaks by ensuring that
+
** sqlite3_recover_finish() is called on all allocated handles.
+
*/
+
sqlite3_recover *sqlite3_recover_init(
+
  sqlite3* db, 
+
  const char *zDb, 
+
  const char *zUri
+
);
+
sqlite3_recover *sqlite3_recover_init_sql(
+
  sqlite3* db, 
+
  const char *zDb, 
+
  int (*xSql)(void*, const char*),
+
  void *pCtx
+
);

-
  }else{
-
    pIdx->estimatedCost = 100000000;
-
    pIdx->estimatedRows = 1000000000;
-
  }
-
  pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00);
-
  return SQLITE_OK;
-
}
+
/*
+
** Configure an sqlite3_recover object that has just been created using
+
** sqlite3_recover_init() or sqlite3_recover_init_sql(). This function
+
** may only be called before the first call to sqlite3_recover_step()
+
** or sqlite3_recover_run() on the object.
+
**
+
** The second argument passed to this function must be one of the
+
** SQLITE_RECOVER_* symbols defined below. Valid values for the third argument
+
** depend on the specific SQLITE_RECOVER_* symbol in use.
+
**
+
** SQLITE_OK is returned if the configuration operation was successful,
+
** or an SQLite error code otherwise.
+
*/
+
int sqlite3_recover_config(sqlite3_recover*, int op, void *pArg);

/*
-
** Open a new sqlite_dbdata or sqlite_dbptr cursor.
+
** SQLITE_RECOVER_LOST_AND_FOUND:
+
**   The pArg argument points to a string buffer containing the name
+
**   of a "lost-and-found" table in the output database, or NULL. If
+
**   the argument is non-NULL and the database contains seemingly
+
**   valid pages that cannot be associated with any table in the
+
**   recovered part of the schema, data is extracted from these
+
**   pages to add to the lost-and-found table.
+
**
+
** SQLITE_RECOVER_FREELIST_CORRUPT:
+
**   The pArg value must actually be a pointer to a value of type
+
**   int containing value 0 or 1 cast as a (void*). If this option is set
+
**   (argument is 1) and a lost-and-found table has been configured using
+
**   SQLITE_RECOVER_LOST_AND_FOUND, then is assumed that the freelist is 
+
**   corrupt and an attempt is made to recover records from pages that
+
**   appear to be linked into the freelist. Otherwise, pages on the freelist
+
**   are ignored. Setting this option can recover more data from the
+
**   database, but often ends up "recovering" deleted records. The default 
+
**   value is 0 (clear).
+
**
+
** SQLITE_RECOVER_ROWIDS:
+
**   The pArg value must actually be a pointer to a value of type
+
**   int containing value 0 or 1 cast as a (void*). If this option is set
+
**   (argument is 1), then an attempt is made to recover rowid values
+
**   that are not also INTEGER PRIMARY KEY values. If this option is
+
**   clear, then new rowids are assigned to all recovered rows. The
+
**   default value is 1 (set).
+
**
+
** SQLITE_RECOVER_SLOWINDEXES:
+
**   The pArg value must actually be a pointer to a value of type
+
**   int containing value 0 or 1 cast as a (void*). If this option is clear
+
**   (argument is 0), then when creating an output database, the recover 
+
**   module creates and populates non-UNIQUE indexes right at the end of the
+
**   recovery operation - after all recoverable data has been inserted
+
**   into the new database. This is faster overall, but means that the
+
**   final call to sqlite3_recover_step() for a recovery operation may
+
**   be need to create a large number of indexes, which may be very slow.
+
**
+
**   Or, if this option is set (argument is 1), then non-UNIQUE indexes
+
**   are created in the output database before it is populated with 
+
**   recovered data. This is slower overall, but avoids the slow call
+
**   to sqlite3_recover_step() at the end of the recovery operation.
+
**
+
**   The default option value is 0.
*/
-
static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
-
  DbdataCursor *pCsr;
+
#define SQLITE_RECOVER_LOST_AND_FOUND   1
+
#define SQLITE_RECOVER_FREELIST_CORRUPT 2
+
#define SQLITE_RECOVER_ROWIDS           3
+
#define SQLITE_RECOVER_SLOWINDEXES      4

-
  pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor));
-
  if( pCsr==0 ){
-
    return SQLITE_NOMEM;
-
  }else{
-
    memset(pCsr, 0, sizeof(DbdataCursor));
-
    pCsr->base.pVtab = pVTab;
-
  }
+
/*
+
** Perform a unit of work towards the recovery operation. This function 
+
** must normally be called multiple times to complete database recovery.
+
**
+
** If no error occurs but the recovery operation is not completed, this
+
** function returns SQLITE_OK. If recovery has been completed successfully
+
** then SQLITE_DONE is returned. If an error has occurred, then an SQLite
+
** error code (e.g. SQLITE_IOERR or SQLITE_NOMEM) is returned. It is not
+
** considered an error if some or all of the data cannot be recovered
+
** due to database corruption.
+
**
+
** Once sqlite3_recover_step() has returned a value other than SQLITE_OK,
+
** all further such calls on the same recover handle are no-ops that return
+
** the same non-SQLITE_OK value.
+
*/
+
int sqlite3_recover_step(sqlite3_recover*);

-
  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
-
  return SQLITE_OK;
-
}
+
/* 
+
** Run the recovery operation to completion. Return SQLITE_OK if successful,
+
** or an SQLite error code otherwise. Calling this function is the same
+
** as executing:
+
**
+
**     while( SQLITE_OK==sqlite3_recover_step(p) );
+
**     return sqlite3_recover_errcode(p);
+
*/
+
int sqlite3_recover_run(sqlite3_recover*);

/*
-
** Restore a cursor object to the state it was in when first allocated 
-
** by dbdataOpen().
+
** If an error has been encountered during a prior call to
+
** sqlite3_recover_step(), then this function attempts to return a 
+
** pointer to a buffer containing an English language explanation of 
+
** the error. If no error message is available, or if an out-of memory 
+
** error occurs while attempting to allocate a buffer in which to format
+
** the error message, NULL is returned.
+
**
+
** The returned buffer remains valid until the sqlite3_recover handle is
+
** destroyed using sqlite3_recover_finish().
*/
-
static void dbdataResetCursor(DbdataCursor *pCsr){
-
  DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab);
-
  if( pTab->pStmt==0 ){
-
    pTab->pStmt = pCsr->pStmt;
-
  }else{
-
    sqlite3_finalize(pCsr->pStmt);
-
  }
-
  pCsr->pStmt = 0;
-
  pCsr->iPgno = 1;
-
  pCsr->iCell = 0;
-
  pCsr->iField = 0;
-
  pCsr->bOnePage = 0;
-
  sqlite3_free(pCsr->aPage);
-
  sqlite3_free(pCsr->pRec);
-
  pCsr->pRec = 0;
-
  pCsr->aPage = 0;
-
}
+
const char *sqlite3_recover_errmsg(sqlite3_recover*);

/*
-
** Close an sqlite_dbdata or sqlite_dbptr cursor.
+
** If this function is called on an sqlite3_recover handle after
+
** an error occurs, an SQLite error code is returned. Otherwise, SQLITE_OK.
*/
-
static int dbdataClose(sqlite3_vtab_cursor *pCursor){
-
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
-
  dbdataResetCursor(pCsr);
-
  sqlite3_free(pCsr);
-
  return SQLITE_OK;
-
}
+
int sqlite3_recover_errcode(sqlite3_recover*);

/* 
-
** Utility methods to decode 16 and 32-bit big-endian unsigned integers. 
+
** Clean up a recovery object created by a call to sqlite3_recover_init().
+
** The results of using a recovery object with any API after it has been
+
** passed to this function are undefined.
+
**
+
** This function returns the same value as sqlite3_recover_errcode().
*/
-
static u32 get_uint16(unsigned char *a){
-
  return (a[0]<<8)|a[1];
-
}
-
static u32 get_uint32(unsigned char *a){
-
  return ((u32)a[0]<<24)
-
       | ((u32)a[1]<<16)
-
       | ((u32)a[2]<<8)
-
       | ((u32)a[3]);
-
}
+
int sqlite3_recover_finish(sqlite3_recover*);
+

+

+
#ifdef __cplusplus
+
}  /* end of the 'extern "C"' block */
+
#endif
+

+
#endif /* ifndef _SQLITE_RECOVER_H */

+
/************************* End ../ext/recover/sqlite3recover.h ********************/
+
# ifndef SQLITE_HAVE_SQLITE3R
+
/************************* Begin ../ext/recover/dbdata.c ******************/
/*
-
** Load page pgno from the database via the sqlite_dbpage virtual table.
-
** If successful, set (*ppPage) to point to a buffer containing the page
-
** data, (*pnPage) to the size of that buffer in bytes and return
-
** SQLITE_OK. In this case it is the responsibility of the caller to
-
** eventually free the buffer using sqlite3_free().
+
** 2019-04-17
**
-
** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and
-
** return an SQLite error code.
-
*/
-
static int dbdataLoadPage(
-
  DbdataCursor *pCsr,             /* Cursor object */
-
  u32 pgno,                       /* Page number of page to load */
-
  u8 **ppPage,                    /* OUT: pointer to page buffer */
-
  int *pnPage                     /* OUT: Size of (*ppPage) in bytes */
+
** The author disclaims copyright to this source code.  In place of
+
** a legal notice, here is a blessing:
+
**
+
**    May you do good and not evil.
+
**    May you find forgiveness for yourself and forgive others.
+
**    May you share freely, never taking more than you give.
+
**
+
******************************************************************************
+
**
+
** This file contains an implementation of two eponymous virtual tables,
+
** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the
+
** "sqlite_dbpage" eponymous virtual table be available.
+
**
+
** SQLITE_DBDATA:
+
**   sqlite_dbdata is used to extract data directly from a database b-tree
+
**   page and its associated overflow pages, bypassing the b-tree layer.
+
**   The table schema is equivalent to:
+
**
+
**     CREATE TABLE sqlite_dbdata(
+
**       pgno INTEGER,
+
**       cell INTEGER,
+
**       field INTEGER,
+
**       value ANY,
+
**       schema TEXT HIDDEN
+
**     );
+
**
+
**   IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE
+
**   FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND
+
**   "schema".
+
**
+
**   Each page of the database is inspected. If it cannot be interpreted as
+
**   a b-tree page, or if it is a b-tree page containing 0 entries, the
+
**   sqlite_dbdata table contains no rows for that page.  Otherwise, the
+
**   table contains one row for each field in the record associated with
+
**   each cell on the page. For intkey b-trees, the key value is stored in
+
**   field -1.
+
**
+
**   For example, for the database:
+
**
+
**     CREATE TABLE t1(a, b);     -- root page is page 2
+
**     INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five');
+
**     INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten');
+
**
+
**   the sqlite_dbdata table contains, as well as from entries related to 
+
**   page 1, content equivalent to:
+
**
+
**     INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES
+
**         (2, 0, -1, 5     ),
+
**         (2, 0,  0, 'v'   ),
+
**         (2, 0,  1, 'five'),
+
**         (2, 1, -1, 10    ),
+
**         (2, 1,  0, 'x'   ),
+
**         (2, 1,  1, 'ten' );
+
**
+
**   If database corruption is encountered, this module does not report an
+
**   error. Instead, it attempts to extract as much data as possible and
+
**   ignores the corruption.
+
**
+
** SQLITE_DBPTR:
+
**   The sqlite_dbptr table has the following schema:
+
**
+
**     CREATE TABLE sqlite_dbptr(
+
**       pgno INTEGER,
+
**       child INTEGER,
+
**       schema TEXT HIDDEN
+
**     );
+
**
+
**   It contains one entry for each b-tree pointer between a parent and
+
**   child page in the database.
+
*/
+

+
#if !defined(SQLITEINT_H) 
+
/* #include "sqlite3ext.h" */
+

+
/* typedef unsigned char u8; */
+
/* typedef unsigned int u32; */
+

+
#endif
+
SQLITE_EXTENSION_INIT1
+
#include <string.h>
+
#include <assert.h>
+

+
#ifndef SQLITE_OMIT_VIRTUALTABLE
+

+
#define DBDATA_PADDING_BYTES 100 
+

+
typedef struct DbdataTable DbdataTable;
+
typedef struct DbdataCursor DbdataCursor;
+

+
/* Cursor object */
+
struct DbdataCursor {
+
  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
+
  sqlite3_stmt *pStmt;            /* For fetching database pages */
+

+
  int iPgno;                      /* Current page number */
+
  u8 *aPage;                      /* Buffer containing page */
+
  int nPage;                      /* Size of aPage[] in bytes */
+
  int nCell;                      /* Number of cells on aPage[] */
+
  int iCell;                      /* Current cell number */
+
  int bOnePage;                   /* True to stop after one page */
+
  int szDb;
+
  sqlite3_int64 iRowid;
+

+
  /* Only for the sqlite_dbdata table */
+
  u8 *pRec;                       /* Buffer containing current record */
+
  sqlite3_int64 nRec;             /* Size of pRec[] in bytes */
+
  sqlite3_int64 nHdr;             /* Size of header in bytes */
+
  int iField;                     /* Current field number */
+
  u8 *pHdrPtr;
+
  u8 *pPtr;
+
  u32 enc;                        /* Text encoding */
+
  
+
  sqlite3_int64 iIntkey;          /* Integer key value */
+
};
+

+
/* Table object */
+
struct DbdataTable {
+
  sqlite3_vtab base;              /* Base class.  Must be first */
+
  sqlite3 *db;                    /* The database connection */
+
  sqlite3_stmt *pStmt;            /* For fetching database pages */
+
  int bPtr;                       /* True for sqlite3_dbptr table */
+
};
+

+
/* Column and schema definitions for sqlite_dbdata */
+
#define DBDATA_COLUMN_PGNO        0
+
#define DBDATA_COLUMN_CELL        1
+
#define DBDATA_COLUMN_FIELD       2
+
#define DBDATA_COLUMN_VALUE       3
+
#define DBDATA_COLUMN_SCHEMA      4
+
#define DBDATA_SCHEMA             \
+
      "CREATE TABLE x("           \
+
      "  pgno INTEGER,"           \
+
      "  cell INTEGER,"           \
+
      "  field INTEGER,"          \
+
      "  value ANY,"              \
+
      "  schema TEXT HIDDEN"      \
+
      ")"
+

+
/* Column and schema definitions for sqlite_dbptr */
+
#define DBPTR_COLUMN_PGNO         0
+
#define DBPTR_COLUMN_CHILD        1
+
#define DBPTR_COLUMN_SCHEMA       2
+
#define DBPTR_SCHEMA              \
+
      "CREATE TABLE x("           \
+
      "  pgno INTEGER,"           \
+
      "  child INTEGER,"          \
+
      "  schema TEXT HIDDEN"      \
+
      ")"
+

+
/*
+
** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual 
+
** table.
+
*/
+
static int dbdataConnect(
+
  sqlite3 *db,
+
  void *pAux,
+
  int argc, const char *const*argv,
+
  sqlite3_vtab **ppVtab,
+
  char **pzErr
){
-
  int rc2;
-
  int rc = SQLITE_OK;
-
  sqlite3_stmt *pStmt = pCsr->pStmt;
+
  DbdataTable *pTab = 0;
+
  int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);

-
  *ppPage = 0;
-
  *pnPage = 0;
-
  if( pgno>0 ){
-
    sqlite3_bind_int64(pStmt, 2, pgno);
-
    if( SQLITE_ROW==sqlite3_step(pStmt) ){
-
      int nCopy = sqlite3_column_bytes(pStmt, 0);
-
      if( nCopy>0 ){
-
        u8 *pPage;
-
        pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
-
        if( pPage==0 ){
-
          rc = SQLITE_NOMEM;
-
        }else{
-
          const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
-
          memcpy(pPage, pCopy, nCopy);
-
          memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
-
        }
-
        *ppPage = pPage;
-
        *pnPage = nCopy;
-
      }
+
  (void)argc;
+
  (void)argv;
+
  (void)pzErr;
+
  sqlite3_vtab_config(db, SQLITE_VTAB_USES_ALL_SCHEMAS);
+
  if( rc==SQLITE_OK ){
+
    pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable));
+
    if( pTab==0 ){
+
      rc = SQLITE_NOMEM;
+
    }else{
+
      memset(pTab, 0, sizeof(DbdataTable));
+
      pTab->db = db;
+
      pTab->bPtr = (pAux!=0);
    }
-
    rc2 = sqlite3_reset(pStmt);
-
    if( rc==SQLITE_OK ) rc = rc2;
  }

+
  *ppVtab = (sqlite3_vtab*)pTab;
  return rc;
}

/*
-
** Read a varint.  Put the value in *pVal and return the number of bytes.
+
** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table.
*/
-
static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
-
  sqlite3_uint64 u = 0;
-
  int i;
-
  for(i=0; i<8; i++){
-
    u = (u<<7) + (z[i]&0x7f);
-
    if( (z[i]&0x80)==0 ){ *pVal = (sqlite3_int64)u; return i+1; }
+
static int dbdataDisconnect(sqlite3_vtab *pVtab){
+
  DbdataTable *pTab = (DbdataTable*)pVtab;
+
  if( pTab ){
+
    sqlite3_finalize(pTab->pStmt);
+
    sqlite3_free(pVtab);
  }
-
  u = (u<<8) + (z[i]&0xff);
-
  *pVal = (sqlite3_int64)u;
-
  return 9;
+
  return SQLITE_OK;
}

/*
-
** Like dbdataGetVarint(), but set the output to 0 if it is less than 0
-
** or greater than 0xFFFFFFFF. This can be used for all varints in an
-
** SQLite database except for key values in intkey tables.
+
** This function interprets two types of constraints:
+
**
+
**       schema=?
+
**       pgno=?
+
**
+
** If neither are present, idxNum is set to 0. If schema=? is present,
+
** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit
+
** in idxNum is set.
+
**
+
** If both parameters are present, schema is in position 0 and pgno in
+
** position 1.
*/
-
static int dbdataGetVarintU32(const u8 *z, sqlite3_int64 *pVal){
-
  sqlite3_int64 val;
-
  int nRet = dbdataGetVarint(z, &val);
-
  if( val<0 || val>0xFFFFFFFF ) val = 0;
-
  *pVal = val;
-
  return nRet;
-
}
+
static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){
+
  DbdataTable *pTab = (DbdataTable*)tab;
+
  int i;
+
  int iSchema = -1;
+
  int iPgno = -1;
+
  int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA);

-
/*
-
** Return the number of bytes of space used by an SQLite value of type
-
** eType.
-
*/
-
static int dbdataValueBytes(int eType){
-
  switch( eType ){
-
    case 0: case 8: case 9:
-
    case 10: case 11:
-
      return 0;
-
    case 1:
-
      return 1;
-
    case 2:
-
      return 2;
-
    case 3:
-
      return 3;
+
  for(i=0; i<pIdx->nConstraint; i++){
+
    struct sqlite3_index_constraint *p = &pIdx->aConstraint[i];
+
    if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+
      if( p->iColumn==colSchema ){
+
        if( p->usable==0 ) return SQLITE_CONSTRAINT;
+
        iSchema = i;
+
      }
+
      if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){
+
        iPgno = i;
+
      }
+
    }
+
  }
+

+
  if( iSchema>=0 ){
+
    pIdx->aConstraintUsage[iSchema].argvIndex = 1;
+
    pIdx->aConstraintUsage[iSchema].omit = 1;
+
  }
+
  if( iPgno>=0 ){
+
    pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0);
+
    pIdx->aConstraintUsage[iPgno].omit = 1;
+
    pIdx->estimatedCost = 100;
+
    pIdx->estimatedRows =  50;
+

+
    if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){
+
      int iCol = pIdx->aOrderBy[0].iColumn;
+
      if( pIdx->nOrderBy==1 ){
+
        pIdx->orderByConsumed = (iCol==0 || iCol==1);
+
      }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){
+
        pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1);
+
      }
+
    }
+

+
  }else{
+
    pIdx->estimatedCost = 100000000;
+
    pIdx->estimatedRows = 1000000000;
+
  }
+
  pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00);
+
  return SQLITE_OK;
+
}
+

+
/*
+
** Open a new sqlite_dbdata or sqlite_dbptr cursor.
+
*/
+
static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
+
  DbdataCursor *pCsr;
+

+
  pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor));
+
  if( pCsr==0 ){
+
    return SQLITE_NOMEM;
+
  }else{
+
    memset(pCsr, 0, sizeof(DbdataCursor));
+
    pCsr->base.pVtab = pVTab;
+
  }
+

+
  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
+
  return SQLITE_OK;
+
}
+

+
/*
+
** Restore a cursor object to the state it was in when first allocated 
+
** by dbdataOpen().
+
*/
+
static void dbdataResetCursor(DbdataCursor *pCsr){
+
  DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab);
+
  if( pTab->pStmt==0 ){
+
    pTab->pStmt = pCsr->pStmt;
+
  }else{
+
    sqlite3_finalize(pCsr->pStmt);
+
  }
+
  pCsr->pStmt = 0;
+
  pCsr->iPgno = 1;
+
  pCsr->iCell = 0;
+
  pCsr->iField = 0;
+
  pCsr->bOnePage = 0;
+
  sqlite3_free(pCsr->aPage);
+
  sqlite3_free(pCsr->pRec);
+
  pCsr->pRec = 0;
+
  pCsr->aPage = 0;
+
}
+

+
/*
+
** Close an sqlite_dbdata or sqlite_dbptr cursor.
+
*/
+
static int dbdataClose(sqlite3_vtab_cursor *pCursor){
+
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
+
  dbdataResetCursor(pCsr);
+
  sqlite3_free(pCsr);
+
  return SQLITE_OK;
+
}
+

+
/* 
+
** Utility methods to decode 16 and 32-bit big-endian unsigned integers. 
+
*/
+
static u32 get_uint16(unsigned char *a){
+
  return (a[0]<<8)|a[1];
+
}
+
static u32 get_uint32(unsigned char *a){
+
  return ((u32)a[0]<<24)
+
       | ((u32)a[1]<<16)
+
       | ((u32)a[2]<<8)
+
       | ((u32)a[3]);
+
}
+

+
/*
+
** Load page pgno from the database via the sqlite_dbpage virtual table.
+
** If successful, set (*ppPage) to point to a buffer containing the page
+
** data, (*pnPage) to the size of that buffer in bytes and return
+
** SQLITE_OK. In this case it is the responsibility of the caller to
+
** eventually free the buffer using sqlite3_free().
+
**
+
** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and
+
** return an SQLite error code.
+
*/
+
static int dbdataLoadPage(
+
  DbdataCursor *pCsr,             /* Cursor object */
+
  u32 pgno,                       /* Page number of page to load */
+
  u8 **ppPage,                    /* OUT: pointer to page buffer */
+
  int *pnPage                     /* OUT: Size of (*ppPage) in bytes */
+
){
+
  int rc2;
+
  int rc = SQLITE_OK;
+
  sqlite3_stmt *pStmt = pCsr->pStmt;
+

+
  *ppPage = 0;
+
  *pnPage = 0;
+
  if( pgno>0 ){
+
    sqlite3_bind_int64(pStmt, 2, pgno);
+
    if( SQLITE_ROW==sqlite3_step(pStmt) ){
+
      int nCopy = sqlite3_column_bytes(pStmt, 0);
+
      if( nCopy>0 ){
+
        u8 *pPage;
+
        pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES);
+
        if( pPage==0 ){
+
          rc = SQLITE_NOMEM;
+
        }else{
+
          const u8 *pCopy = sqlite3_column_blob(pStmt, 0);
+
          memcpy(pPage, pCopy, nCopy);
+
          memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES);
+
        }
+
        *ppPage = pPage;
+
        *pnPage = nCopy;
+
      }
+
    }
+
    rc2 = sqlite3_reset(pStmt);
+
    if( rc==SQLITE_OK ) rc = rc2;
+
  }
+

+
  return rc;
+
}
+

+
/*
+
** Read a varint.  Put the value in *pVal and return the number of bytes.
+
*/
+
static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){
+
  sqlite3_uint64 u = 0;
+
  int i;
+
  for(i=0; i<8; i++){
+
    u = (u<<7) + (z[i]&0x7f);
+
    if( (z[i]&0x80)==0 ){ *pVal = (sqlite3_int64)u; return i+1; }
+
  }
+
  u = (u<<8) + (z[i]&0xff);
+
  *pVal = (sqlite3_int64)u;
+
  return 9;
+
}
+

+
/*
+
** Like dbdataGetVarint(), but set the output to 0 if it is less than 0
+
** or greater than 0xFFFFFFFF. This can be used for all varints in an
+
** SQLite database except for key values in intkey tables.
+
*/
+
static int dbdataGetVarintU32(const u8 *z, sqlite3_int64 *pVal){
+
  sqlite3_int64 val;
+
  int nRet = dbdataGetVarint(z, &val);
+
  if( val<0 || val>0xFFFFFFFF ) val = 0;
+
  *pVal = val;
+
  return nRet;
+
}
+

+
/*
+
** Return the number of bytes of space used by an SQLite value of type
+
** eType.
+
*/
+
static int dbdataValueBytes(int eType){
+
  switch( eType ){
+
    case 0: case 8: case 9:
+
    case 10: case 11:
+
      return 0;
+
    case 1:
+
      return 1;
+
    case 2:
+
      return 2;
+
    case 3:
+
      return 3;
    case 4:
      return 4;
    case 5:
@@ -11924,10 +13355,14 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
        if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK;
        rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage);
        if( rc!=SQLITE_OK ) return rc;
-
        if( pCsr->aPage ) break;
+
        if( pCsr->aPage && pCsr->nPage>=256 ) break;
+
        sqlite3_free(pCsr->aPage);
+
        pCsr->aPage = 0;
        if( pCsr->bOnePage ) return SQLITE_OK;
        pCsr->iPgno++;
      }
+

+
      assert( iOff+3+2<=pCsr->nPage );
      pCsr->iCell = pTab->bPtr ? -2 : 0;
      pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]);
    }
@@ -12091,524 +13526,276 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){

        /* Advance to the next cell. The next iteration of the loop will load
        ** the record and so on. */
-
        sqlite3_free(pCsr->pRec);
-
        pCsr->pRec = 0;
-
        pCsr->iCell++;
-
      }
-
    }
-
  }
-

-
  assert( !"can't get here" );
-
  return SQLITE_OK;
-
}
-

-
/* 
-
** Return true if the cursor is at EOF.
-
*/
-
static int dbdataEof(sqlite3_vtab_cursor *pCursor){
-
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
-
  return pCsr->aPage==0;
-
}
-

-
/*
-
** Return true if nul-terminated string zSchema ends in "()". Or false
-
** otherwise.
-
*/
-
static int dbdataIsFunction(const char *zSchema){
-
  size_t n = strlen(zSchema);
-
  if( n>2 && zSchema[n-2]=='(' && zSchema[n-1]==')' ){
-
    return (int)n-2;
-
  }
-
  return 0;
-
}
-

-
/* 
-
** Determine the size in pages of database zSchema (where zSchema is
-
** "main", "temp" or the name of an attached database) and set 
-
** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise,
-
** an SQLite error code.
-
*/
-
static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
-
  DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
-
  char *zSql = 0;
-
  int rc, rc2;
-
  int nFunc = 0;
-
  sqlite3_stmt *pStmt = 0;
-

-
  if( (nFunc = dbdataIsFunction(zSchema))>0 ){
-
    zSql = sqlite3_mprintf("SELECT %.*s(0)", nFunc, zSchema);
-
  }else{
-
    zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
-
  }
-
  if( zSql==0 ) return SQLITE_NOMEM;
-

-
  rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
-
  sqlite3_free(zSql);
-
  if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
-
    pCsr->szDb = sqlite3_column_int(pStmt, 0);
-
  }
-
  rc2 = sqlite3_finalize(pStmt);
-
  if( rc==SQLITE_OK ) rc = rc2;
-
  return rc;
-
}
-

-
/*
-
** Attempt to figure out the encoding of the database by retrieving page 1
-
** and inspecting the header field. If successful, set the pCsr->enc variable
-
** and return SQLITE_OK. Otherwise, return an SQLite error code.
-
*/
-
static int dbdataGetEncoding(DbdataCursor *pCsr){
-
  int rc = SQLITE_OK;
-
  int nPg1 = 0;
-
  u8 *aPg1 = 0;
-
  rc = dbdataLoadPage(pCsr, 1, &aPg1, &nPg1);
-
  assert( rc!=SQLITE_OK || nPg1==0 || nPg1>=512 );
-
  if( rc==SQLITE_OK && nPg1>0 ){
-
    pCsr->enc = get_uint32(&aPg1[56]);
-
  }
-
  sqlite3_free(aPg1);
-
  return rc;
-
}
-

-

-
/* 
-
** xFilter method for sqlite_dbdata and sqlite_dbptr.
-
*/
-
static int dbdataFilter(
-
  sqlite3_vtab_cursor *pCursor, 
-
  int idxNum, const char *idxStr,
-
  int argc, sqlite3_value **argv
-
){
-
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
-
  DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
-
  int rc = SQLITE_OK;
-
  const char *zSchema = "main";
-

-
  dbdataResetCursor(pCsr);
-
  assert( pCsr->iPgno==1 );
-
  if( idxNum & 0x01 ){
-
    zSchema = (const char*)sqlite3_value_text(argv[0]);
-
    if( zSchema==0 ) zSchema = "";
-
  }
-
  if( idxNum & 0x02 ){
-
    pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
-
    pCsr->bOnePage = 1;
-
  }else{
-
    rc = dbdataDbsize(pCsr, zSchema);
-
  }
-

-
  if( rc==SQLITE_OK ){
-
    int nFunc = 0;
-
    if( pTab->pStmt ){
-
      pCsr->pStmt = pTab->pStmt;
-
      pTab->pStmt = 0;
-
    }else if( (nFunc = dbdataIsFunction(zSchema))>0 ){
-
      char *zSql = sqlite3_mprintf("SELECT %.*s(?2)", nFunc, zSchema);
-
      if( zSql==0 ){
-
        rc = SQLITE_NOMEM;
-
      }else{
-
        rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
-
        sqlite3_free(zSql);
-
      }
-
    }else{
-
      rc = sqlite3_prepare_v2(pTab->db, 
-
          "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
-
          &pCsr->pStmt, 0
-
      );
-
    }
-
  }
-
  if( rc==SQLITE_OK ){
-
    rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT);
-
  }else{
-
    pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
-
  }
-

-
  /* Try to determine the encoding of the db by inspecting the header
-
  ** field on page 1. */
-
  if( rc==SQLITE_OK ){
-
    rc = dbdataGetEncoding(pCsr);
-
  }
-

-
  if( rc==SQLITE_OK ){
-
    rc = dbdataNext(pCursor);
-
  }
-
  return rc;
-
}
-

-
/*
-
** Return a column for the sqlite_dbdata or sqlite_dbptr table.
-
*/
-
static int dbdataColumn(
-
  sqlite3_vtab_cursor *pCursor, 
-
  sqlite3_context *ctx, 
-
  int i
-
){
-
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
-
  DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
-
  if( pTab->bPtr ){
-
    switch( i ){
-
      case DBPTR_COLUMN_PGNO:
-
        sqlite3_result_int64(ctx, pCsr->iPgno);
-
        break;
-
      case DBPTR_COLUMN_CHILD: {
-
        int iOff = pCsr->iPgno==1 ? 100 : 0;
-
        if( pCsr->iCell<0 ){
-
          iOff += 8;
-
        }else{
-
          iOff += 12 + pCsr->iCell*2;
-
          if( iOff>pCsr->nPage ) return SQLITE_OK;
-
          iOff = get_uint16(&pCsr->aPage[iOff]);
-
        }
-
        if( iOff<=pCsr->nPage ){
-
          sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
-
        }
-
        break;
-
      }
-
    }
-
  }else{
-
    switch( i ){
-
      case DBDATA_COLUMN_PGNO:
-
        sqlite3_result_int64(ctx, pCsr->iPgno);
-
        break;
-
      case DBDATA_COLUMN_CELL:
-
        sqlite3_result_int(ctx, pCsr->iCell);
-
        break;
-
      case DBDATA_COLUMN_FIELD:
-
        sqlite3_result_int(ctx, pCsr->iField);
-
        break;
-
      case DBDATA_COLUMN_VALUE: {
-
        if( pCsr->iField<0 ){
-
          sqlite3_result_int64(ctx, pCsr->iIntkey);
-
        }else if( &pCsr->pRec[pCsr->nRec] >= pCsr->pPtr ){
-
          sqlite3_int64 iType;
-
          dbdataGetVarintU32(pCsr->pHdrPtr, &iType);
-
          dbdataValue(
-
              ctx, pCsr->enc, iType, pCsr->pPtr, 
-
              &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
-
          );
-
        }
-
        break;
-
      }
-
    }
-
  }
-
  return SQLITE_OK;
-
}
-

-
/* 
-
** Return the rowid for an sqlite_dbdata or sqlite_dptr table.
-
*/
-
static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
-
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
-
  *pRowid = pCsr->iRowid;
-
  return SQLITE_OK;
-
}
-

-

-
/*
-
** Invoke this routine to register the "sqlite_dbdata" virtual table module
-
*/
-
static int sqlite3DbdataRegister(sqlite3 *db){
-
  static sqlite3_module dbdata_module = {
-
    0,                            /* iVersion */
-
    0,                            /* xCreate */
-
    dbdataConnect,                /* xConnect */
-
    dbdataBestIndex,              /* xBestIndex */
-
    dbdataDisconnect,             /* xDisconnect */
-
    0,                            /* xDestroy */
-
    dbdataOpen,                   /* xOpen - open a cursor */
-
    dbdataClose,                  /* xClose - close a cursor */
-
    dbdataFilter,                 /* xFilter - configure scan constraints */
-
    dbdataNext,                   /* xNext - advance a cursor */
-
    dbdataEof,                    /* xEof - check for end of scan */
-
    dbdataColumn,                 /* xColumn - read data */
-
    dbdataRowid,                  /* 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, "sqlite_dbdata", &dbdata_module, 0);
-
  if( rc==SQLITE_OK ){
-
    rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
-
  }
-
  return rc;
-
}
-

-
#ifdef _WIN32
-

-
#endif
-
int sqlite3_dbdata_init(
-
  sqlite3 *db, 
-
  char **pzErrMsg, 
-
  const sqlite3_api_routines *pApi
-
){
-
  SQLITE_EXTENSION_INIT2(pApi);
-
  return sqlite3DbdataRegister(db);
-
}
+
        sqlite3_free(pCsr->pRec);
+
        pCsr->pRec = 0;
+
        pCsr->iCell++;
+
      }
+
    }
+
  }

-
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
+
  assert( !"can't get here" );
+
  return SQLITE_OK;
+
}

-
/************************* End ../ext/recover/dbdata.c ********************/
-
/************************* Begin ../ext/recover/sqlite3recover.h ******************/
-
/*
-
** 2022-08-27
-
**
-
** The author disclaims copyright to this source code.  In place of
-
** a legal notice, here is a blessing:
-
**
-
**    May you do good and not evil.
-
**    May you find forgiveness for yourself and forgive others.
-
**    May you share freely, never taking more than you give.
-
**
-
*************************************************************************
-
**
-
** This file contains the public interface to the "recover" extension -
-
** an SQLite extension designed to recover data from corrupted database
-
** files.
+
/* 
+
** Return true if the cursor is at EOF.
*/
+
static int dbdataEof(sqlite3_vtab_cursor *pCursor){
+
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
+
  return pCsr->aPage==0;
+
}

/*
-
** OVERVIEW:
-
**
-
** To use the API to recover data from a corrupted database, an
-
** application:
-
**
-
**   1) Creates an sqlite3_recover handle by calling either
-
**      sqlite3_recover_init() or sqlite3_recover_init_sql().
-
**
-
**   2) Configures the new handle using one or more calls to
-
**      sqlite3_recover_config().
-
**
-
**   3) Executes the recovery by repeatedly calling sqlite3_recover_step() on
-
**      the handle until it returns something other than SQLITE_OK. If it
-
**      returns SQLITE_DONE, then the recovery operation completed without 
-
**      error. If it returns some other non-SQLITE_OK value, then an error 
-
**      has occurred.
-
**
-
**   4) Retrieves any error code and English language error message using the
-
**      sqlite3_recover_errcode() and sqlite3_recover_errmsg() APIs,
-
**      respectively.
-
**
-
**   5) Destroys the sqlite3_recover handle and frees all resources
-
**      using sqlite3_recover_finish().
-
**
-
** The application may abandon the recovery operation at any point 
-
** before it is finished by passing the sqlite3_recover handle to
-
** sqlite3_recover_finish(). This is not an error, but the final state
-
** of the output database, or the results of running the partial script
-
** delivered to the SQL callback, are undefined.
+
** Return true if nul-terminated string zSchema ends in "()". Or false
+
** otherwise.
*/
+
static int dbdataIsFunction(const char *zSchema){
+
  size_t n = strlen(zSchema);
+
  if( n>2 && zSchema[n-2]=='(' && zSchema[n-1]==')' ){
+
    return (int)n-2;
+
  }
+
  return 0;
+
}

-
#ifndef _SQLITE_RECOVER_H
-
#define _SQLITE_RECOVER_H
+
/* 
+
** Determine the size in pages of database zSchema (where zSchema is
+
** "main", "temp" or the name of an attached database) and set 
+
** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise,
+
** an SQLite error code.
+
*/
+
static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){
+
  DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab;
+
  char *zSql = 0;
+
  int rc, rc2;
+
  int nFunc = 0;
+
  sqlite3_stmt *pStmt = 0;

-
/* #include "sqlite3.h" */
+
  if( (nFunc = dbdataIsFunction(zSchema))>0 ){
+
    zSql = sqlite3_mprintf("SELECT %.*s(0)", nFunc, zSchema);
+
  }else{
+
    zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema);
+
  }
+
  if( zSql==0 ) return SQLITE_NOMEM;

-
#ifdef __cplusplus
-
extern "C" {
-
#endif
+
  rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0);
+
  sqlite3_free(zSql);
+
  if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
+
    pCsr->szDb = sqlite3_column_int(pStmt, 0);
+
  }
+
  rc2 = sqlite3_finalize(pStmt);
+
  if( rc==SQLITE_OK ) rc = rc2;
+
  return rc;
+
}

/*
-
** An instance of the sqlite3_recover object represents a recovery
-
** operation in progress.
-
**
-
** Constructors:
-
**
-
**    sqlite3_recover_init()
-
**    sqlite3_recover_init_sql()
-
**
-
** Destructor:
-
**
-
**    sqlite3_recover_finish()
-
**
-
** Methods:
-
**
-
**    sqlite3_recover_config()
-
**    sqlite3_recover_errcode()
-
**    sqlite3_recover_errmsg()
-
**    sqlite3_recover_run()
-
**    sqlite3_recover_step()
+
** Attempt to figure out the encoding of the database by retrieving page 1
+
** and inspecting the header field. If successful, set the pCsr->enc variable
+
** and return SQLITE_OK. Otherwise, return an SQLite error code.
*/
-
typedef struct sqlite3_recover sqlite3_recover;
+
static int dbdataGetEncoding(DbdataCursor *pCsr){
+
  int rc = SQLITE_OK;
+
  int nPg1 = 0;
+
  u8 *aPg1 = 0;
+
  rc = dbdataLoadPage(pCsr, 1, &aPg1, &nPg1);
+
  if( rc==SQLITE_OK && nPg1>=(56+4) ){
+
    pCsr->enc = get_uint32(&aPg1[56]);
+
  }
+
  sqlite3_free(aPg1);
+
  return rc;
+
}

-
/* 
-
** These two APIs attempt to create and return a new sqlite3_recover object.
-
** In both cases the first two arguments identify the (possibly
-
** corrupt) database to recover data from. The first argument is an open
-
** database handle and the second the name of a database attached to that
-
** handle (i.e. "main", "temp" or the name of an attached database).
-
**
-
** If sqlite3_recover_init() is used to create the new sqlite3_recover
-
** handle, then data is recovered into a new database, identified by
-
** string parameter zUri. zUri may be an absolute or relative file path,
-
** or may be an SQLite URI. If the identified database file already exists,
-
** it is overwritten.
-
**
-
** If sqlite3_recover_init_sql() is invoked, then any recovered data will
-
** be returned to the user as a series of SQL statements. Executing these
-
** SQL statements results in the same database as would have been created
-
** had sqlite3_recover_init() been used. For each SQL statement in the
-
** output, the callback function passed as the third argument (xSql) is 
-
** invoked once. The first parameter is a passed a copy of the fourth argument
-
** to this function (pCtx) as its first parameter, and a pointer to a
-
** nul-terminated buffer containing the SQL statement formated as UTF-8 as 
-
** the second. If the xSql callback returns any value other than SQLITE_OK,
-
** then processing is immediately abandoned and the value returned used as
-
** the recover handle error code (see below).
-
**
-
** If an out-of-memory error occurs, NULL may be returned instead of
-
** a valid handle. In all other cases, it is the responsibility of the
-
** application to avoid resource leaks by ensuring that
-
** sqlite3_recover_finish() is called on all allocated handles.
-
*/
-
sqlite3_recover *sqlite3_recover_init(
-
  sqlite3* db, 
-
  const char *zDb, 
-
  const char *zUri
-
);
-
sqlite3_recover *sqlite3_recover_init_sql(
-
  sqlite3* db, 
-
  const char *zDb, 
-
  int (*xSql)(void*, const char*),
-
  void *pCtx
-
);

-
/*
-
** Configure an sqlite3_recover object that has just been created using
-
** sqlite3_recover_init() or sqlite3_recover_init_sql(). This function
-
** may only be called before the first call to sqlite3_recover_step()
-
** or sqlite3_recover_run() on the object.
-
**
-
** The second argument passed to this function must be one of the
-
** SQLITE_RECOVER_* symbols defined below. Valid values for the third argument
-
** depend on the specific SQLITE_RECOVER_* symbol in use.
-
**
-
** SQLITE_OK is returned if the configuration operation was successful,
-
** or an SQLite error code otherwise.
+
/* 
+
** xFilter method for sqlite_dbdata and sqlite_dbptr.
*/
-
int sqlite3_recover_config(sqlite3_recover*, int op, void *pArg);
+
static int dbdataFilter(
+
  sqlite3_vtab_cursor *pCursor, 
+
  int idxNum, const char *idxStr,
+
  int argc, sqlite3_value **argv
+
){
+
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
+
  DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
+
  int rc = SQLITE_OK;
+
  const char *zSchema = "main";
+
  (void)idxStr;
+
  (void)argc;

-
/*
-
** SQLITE_RECOVER_LOST_AND_FOUND:
-
**   The pArg argument points to a string buffer containing the name
-
**   of a "lost-and-found" table in the output database, or NULL. If
-
**   the argument is non-NULL and the database contains seemingly
-
**   valid pages that cannot be associated with any table in the
-
**   recovered part of the schema, data is extracted from these
-
**   pages to add to the lost-and-found table.
-
**
-
** SQLITE_RECOVER_FREELIST_CORRUPT:
-
**   The pArg value must actually be a pointer to a value of type
-
**   int containing value 0 or 1 cast as a (void*). If this option is set
-
**   (argument is 1) and a lost-and-found table has been configured using
-
**   SQLITE_RECOVER_LOST_AND_FOUND, then is assumed that the freelist is 
-
**   corrupt and an attempt is made to recover records from pages that
-
**   appear to be linked into the freelist. Otherwise, pages on the freelist
-
**   are ignored. Setting this option can recover more data from the
-
**   database, but often ends up "recovering" deleted records. The default 
-
**   value is 0 (clear).
-
**
-
** SQLITE_RECOVER_ROWIDS:
-
**   The pArg value must actually be a pointer to a value of type
-
**   int containing value 0 or 1 cast as a (void*). If this option is set
-
**   (argument is 1), then an attempt is made to recover rowid values
-
**   that are not also INTEGER PRIMARY KEY values. If this option is
-
**   clear, then new rowids are assigned to all recovered rows. The
-
**   default value is 1 (set).
-
**
-
** SQLITE_RECOVER_SLOWINDEXES:
-
**   The pArg value must actually be a pointer to a value of type
-
**   int containing value 0 or 1 cast as a (void*). If this option is clear
-
**   (argument is 0), then when creating an output database, the recover 
-
**   module creates and populates non-UNIQUE indexes right at the end of the
-
**   recovery operation - after all recoverable data has been inserted
-
**   into the new database. This is faster overall, but means that the
-
**   final call to sqlite3_recover_step() for a recovery operation may
-
**   be need to create a large number of indexes, which may be very slow.
-
**
-
**   Or, if this option is set (argument is 1), then non-UNIQUE indexes
-
**   are created in the output database before it is populated with 
-
**   recovered data. This is slower overall, but avoids the slow call
-
**   to sqlite3_recover_step() at the end of the recovery operation.
-
**
-
**   The default option value is 0.
-
*/
-
#define SQLITE_RECOVER_LOST_AND_FOUND   1
-
#define SQLITE_RECOVER_FREELIST_CORRUPT 2
-
#define SQLITE_RECOVER_ROWIDS           3
-
#define SQLITE_RECOVER_SLOWINDEXES      4
+
  dbdataResetCursor(pCsr);
+
  assert( pCsr->iPgno==1 );
+
  if( idxNum & 0x01 ){
+
    zSchema = (const char*)sqlite3_value_text(argv[0]);
+
    if( zSchema==0 ) zSchema = "";
+
  }
+
  if( idxNum & 0x02 ){
+
    pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]);
+
    pCsr->bOnePage = 1;
+
  }else{
+
    rc = dbdataDbsize(pCsr, zSchema);
+
  }
+

+
  if( rc==SQLITE_OK ){
+
    int nFunc = 0;
+
    if( pTab->pStmt ){
+
      pCsr->pStmt = pTab->pStmt;
+
      pTab->pStmt = 0;
+
    }else if( (nFunc = dbdataIsFunction(zSchema))>0 ){
+
      char *zSql = sqlite3_mprintf("SELECT %.*s(?2)", nFunc, zSchema);
+
      if( zSql==0 ){
+
        rc = SQLITE_NOMEM;
+
      }else{
+
        rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
+
        sqlite3_free(zSql);
+
      }
+
    }else{
+
      rc = sqlite3_prepare_v2(pTab->db, 
+
          "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1,
+
          &pCsr->pStmt, 0
+
      );
+
    }
+
  }
+
  if( rc==SQLITE_OK ){
+
    rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT);
+
  }
+

+
  /* Try to determine the encoding of the db by inspecting the header
+
  ** field on page 1. */
+
  if( rc==SQLITE_OK ){
+
    rc = dbdataGetEncoding(pCsr);
+
  }
+

+
  if( rc!=SQLITE_OK ){
+
    pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db));
+
  }
+

+
  if( rc==SQLITE_OK ){
+
    rc = dbdataNext(pCursor);
+
  }
+
  return rc;
+
}

/*
-
** Perform a unit of work towards the recovery operation. This function 
-
** must normally be called multiple times to complete database recovery.
-
**
-
** If no error occurs but the recovery operation is not completed, this
-
** function returns SQLITE_OK. If recovery has been completed successfully
-
** then SQLITE_DONE is returned. If an error has occurred, then an SQLite
-
** error code (e.g. SQLITE_IOERR or SQLITE_NOMEM) is returned. It is not
-
** considered an error if some or all of the data cannot be recovered
-
** due to database corruption.
-
**
-
** Once sqlite3_recover_step() has returned a value other than SQLITE_OK,
-
** all further such calls on the same recover handle are no-ops that return
-
** the same non-SQLITE_OK value.
+
** Return a column for the sqlite_dbdata or sqlite_dbptr table.
*/
-
int sqlite3_recover_step(sqlite3_recover*);
+
static int dbdataColumn(
+
  sqlite3_vtab_cursor *pCursor, 
+
  sqlite3_context *ctx, 
+
  int i
+
){
+
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
+
  DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
+
  if( pTab->bPtr ){
+
    switch( i ){
+
      case DBPTR_COLUMN_PGNO:
+
        sqlite3_result_int64(ctx, pCsr->iPgno);
+
        break;
+
      case DBPTR_COLUMN_CHILD: {
+
        int iOff = pCsr->iPgno==1 ? 100 : 0;
+
        if( pCsr->iCell<0 ){
+
          iOff += 8;
+
        }else{
+
          iOff += 12 + pCsr->iCell*2;
+
          if( iOff>pCsr->nPage ) return SQLITE_OK;
+
          iOff = get_uint16(&pCsr->aPage[iOff]);
+
        }
+
        if( iOff<=pCsr->nPage ){
+
          sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff]));
+
        }
+
        break;
+
      }
+
    }
+
  }else{
+
    switch( i ){
+
      case DBDATA_COLUMN_PGNO:
+
        sqlite3_result_int64(ctx, pCsr->iPgno);
+
        break;
+
      case DBDATA_COLUMN_CELL:
+
        sqlite3_result_int(ctx, pCsr->iCell);
+
        break;
+
      case DBDATA_COLUMN_FIELD:
+
        sqlite3_result_int(ctx, pCsr->iField);
+
        break;
+
      case DBDATA_COLUMN_VALUE: {
+
        if( pCsr->iField<0 ){
+
          sqlite3_result_int64(ctx, pCsr->iIntkey);
+
        }else if( &pCsr->pRec[pCsr->nRec] >= pCsr->pPtr ){
+
          sqlite3_int64 iType;
+
          dbdataGetVarintU32(pCsr->pHdrPtr, &iType);
+
          dbdataValue(
+
              ctx, pCsr->enc, iType, pCsr->pPtr, 
+
              &pCsr->pRec[pCsr->nRec] - pCsr->pPtr
+
          );
+
        }
+
        break;
+
      }
+
    }
+
  }
+
  return SQLITE_OK;
+
}

/* 
-
** Run the recovery operation to completion. Return SQLITE_OK if successful,
-
** or an SQLite error code otherwise. Calling this function is the same
-
** as executing:
-
**
-
**     while( SQLITE_OK==sqlite3_recover_step(p) );
-
**     return sqlite3_recover_errcode(p);
+
** Return the rowid for an sqlite_dbdata or sqlite_dptr table.
*/
-
int sqlite3_recover_run(sqlite3_recover*);
+
static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
+
  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
+
  *pRowid = pCsr->iRowid;
+
  return SQLITE_OK;
+
}

-
/*
-
** If an error has been encountered during a prior call to
-
** sqlite3_recover_step(), then this function attempts to return a 
-
** pointer to a buffer containing an English language explanation of 
-
** the error. If no error message is available, or if an out-of memory 
-
** error occurs while attempting to allocate a buffer in which to format
-
** the error message, NULL is returned.
-
**
-
** The returned buffer remains valid until the sqlite3_recover handle is
-
** destroyed using sqlite3_recover_finish().
-
*/
-
const char *sqlite3_recover_errmsg(sqlite3_recover*);

/*
-
** If this function is called on an sqlite3_recover handle after
-
** an error occurs, an SQLite error code is returned. Otherwise, SQLITE_OK.
+
** Invoke this routine to register the "sqlite_dbdata" virtual table module
*/
-
int sqlite3_recover_errcode(sqlite3_recover*);
+
static int sqlite3DbdataRegister(sqlite3 *db){
+
  static sqlite3_module dbdata_module = {
+
    0,                            /* iVersion */
+
    0,                            /* xCreate */
+
    dbdataConnect,                /* xConnect */
+
    dbdataBestIndex,              /* xBestIndex */
+
    dbdataDisconnect,             /* xDisconnect */
+
    0,                            /* xDestroy */
+
    dbdataOpen,                   /* xOpen - open a cursor */
+
    dbdataClose,                  /* xClose - close a cursor */
+
    dbdataFilter,                 /* xFilter - configure scan constraints */
+
    dbdataNext,                   /* xNext - advance a cursor */
+
    dbdataEof,                    /* xEof - check for end of scan */
+
    dbdataColumn,                 /* xColumn - read data */
+
    dbdataRowid,                  /* 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 */
+
  };

-
/* 
-
** Clean up a recovery object created by a call to sqlite3_recover_init().
-
** The results of using a recovery object with any API after it has been
-
** passed to this function are undefined.
-
**
-
** This function returns the same value as sqlite3_recover_errcode().
-
*/
-
int sqlite3_recover_finish(sqlite3_recover*);
+
  int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0);
+
  if( rc==SQLITE_OK ){
+
    rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1);
+
  }
+
  return rc;
+
}

+
#ifdef _WIN32

-
#ifdef __cplusplus
-
}  /* end of the 'extern "C"' block */
#endif
+
int sqlite3_dbdata_init(
+
  sqlite3 *db, 
+
  char **pzErrMsg, 
+
  const sqlite3_api_routines *pApi
+
){
+
  SQLITE_EXTENSION_INIT2(pApi);
+
  (void)pzErrMsg;
+
  return sqlite3DbdataRegister(db);
+
}

-
#endif /* ifndef _SQLITE_RECOVER_H */
+
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */

-
/************************* End ../ext/recover/sqlite3recover.h ********************/
+
/************************* End ../ext/recover/dbdata.c ********************/
/************************* Begin ../ext/recover/sqlite3recover.c ******************/
/*
** 2022-08-27
@@ -13373,6 +14560,7 @@ static void recoverEscapeCrnl(
  sqlite3_value **argv
){
  const char *zText = (const char*)sqlite3_value_text(argv[0]);
+
  (void)argc;
  if( zText && zText[0]=='\'' ){
    int nText = sqlite3_value_bytes(argv[0]);
    int i;
@@ -13525,7 +14713,7 @@ static void recoverTransferSettings(sqlite3_recover *p){
      return;
    }

-
    for(ii=0; ii<sizeof(aPragma)/sizeof(aPragma[0]); ii++){
+
    for(ii=0; ii<(int)(sizeof(aPragma)/sizeof(aPragma[0])); ii++){
      const char *zPrag = aPragma[ii];
      sqlite3_stmt *p1 = 0;
      p1 = recoverPreparePrintf(p, p->dbIn, "PRAGMA %Q.%s", p->zDb, zPrag);
@@ -13603,7 +14791,9 @@ static int recoverOpenOutput(sqlite3_recover *p){
  }

  /* Register the custom user-functions with the output handle. */
-
  for(ii=0; p->errCode==SQLITE_OK && ii<sizeof(aFunc)/sizeof(aFunc[0]); ii++){
+
  for(ii=0;
+
      p->errCode==SQLITE_OK && ii<(int)(sizeof(aFunc)/sizeof(aFunc[0]));
+
      ii++){
    p->errCode = sqlite3_create_function(db, aFunc[ii].zName, 
        aFunc[ii].nArg, SQLITE_UTF8, (void*)p, aFunc[ii].xFunc, 0, 0
    );
@@ -13715,7 +14905,7 @@ static void recoverAddTable(
      int iField = sqlite3_column_int(pStmt, 0);
      int iCol = sqlite3_column_int(pStmt, 1);

-
      assert( iField<pNew->nCol && iCol<pNew->nCol );
+
      assert( iCol<pNew->nCol );
      pNew->aCol[iCol].iField = iField;

      pNew->bIntkey = 0;
@@ -14629,6 +15819,7 @@ static void recoverFinalCleanup(sqlite3_recover *p){
  p->pTblList = 0;
  sqlite3_finalize(p->pGetPage);
  p->pGetPage = 0;
+
  sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0);

  {
#ifndef NDEBUG
@@ -14927,6 +16118,7 @@ static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){
      **
      **   + first freelist page (32-bits at offset 32)
      **   + size of freelist (32-bits at offset 36)
+
      **   + the wal-mode flags (16-bits at offset 18)
      **
      ** We also try to preserve the auto-vacuum, incr-value, user-version
      ** and application-id fields - all 32 bit quantities at offsets 
@@ -14990,14 +16182,15 @@ static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){
      if( p->pPage1Cache ){
        p->pPage1Disk = &p->pPage1Cache[nByte];
        memcpy(p->pPage1Disk, aBuf, nByte);
-

+
        aHdr[18] = a[18];
+
        aHdr[19] = a[19];
        recoverPutU32(&aHdr[28], dbsz);
        recoverPutU32(&aHdr[56], enc);
        recoverPutU16(&aHdr[105], pgsz-nReserve);
        if( pgsz==65536 ) pgsz = 1;
        recoverPutU16(&aHdr[16], pgsz);
        aHdr[20] = nReserve;
-
        for(ii=0; ii<sizeof(aPreserve)/sizeof(aPreserve[0]); ii++){
+
        for(ii=0; ii<(int)(sizeof(aPreserve)/sizeof(aPreserve[0])); ii++){
          memcpy(&aHdr[aPreserve[ii]], &a[aPreserve[ii]], 4);
        }
        memcpy(aBuf, aHdr, sizeof(aHdr));
@@ -15121,10 +16314,16 @@ static int recoverVfsFetch(
  int iAmt, 
  void **pp
){
+
  (void)pFd;
+
  (void)iOff;
+
  (void)iAmt;
  *pp = 0;
  return SQLITE_OK;
}
static int recoverVfsUnfetch(sqlite3_file *pFd, sqlite3_int64 iOff, void *p){
+
  (void)pFd;
+
  (void)iOff;
+
  (void)p;
  return SQLITE_OK;
}

@@ -15186,6 +16385,7 @@ static void recoverStep(sqlite3_recover *p){
      recoverOpenOutput(p);

      /* Open transactions on both the input and output databases. */
+
      sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0);
      recoverExec(p, p->dbIn, "PRAGMA writable_schema = on");
      recoverExec(p, p->dbIn, "BEGIN");
      if( p->errCode==SQLITE_OK ) p->bCloseTransaction = 1;
@@ -15469,6 +16669,10 @@ int sqlite3_recover_finish(sqlite3_recover *p){
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */

/************************* End ../ext/recover/sqlite3recover.c ********************/
+
# endif /* SQLITE_HAVE_SQLITE3R */
+
#endif
+
#ifdef SQLITE_SHELL_EXTSRC
+
# include SHELL_STRINGIFY(SQLITE_SHELL_EXTSRC)
#endif

#if defined(SQLITE_ENABLE_SESSION)
@@ -15647,6 +16851,7 @@ static ShellState shellState;
#define SHFLG_HeaderSet      0x00000080 /* showHeader has been specified */
#define SHFLG_DumpDataOnly   0x00000100 /* .dump show data only */
#define SHFLG_DumpNoSys      0x00000200 /* .dump omits system tables */
+
#define SHFLG_TestingMode    0x00000400 /* allow unsafe testing features */

/*
** Macros for testing and setting shellFlgs
@@ -15890,13 +17095,14 @@ static void editFunc(
    }else{
      /* If the file did not originally contain \r\n then convert any new
      ** \r\n back into \n */
+
      p[sz] = 0;
      for(i=j=0; i<sz; i++){
        if( p[i]=='\r' && p[i+1]=='\n' ) i++;
        p[j++] = p[i];
      }
      sz = j;
      p[sz] = 0;
-
    } 
+
    }
    sqlite3_result_text64(context, (const char*)p, sz,
                          sqlite3_free, SQLITE_UTF8);
  }
@@ -15980,6 +17186,7 @@ static void output_quoted_string(FILE *out, const char *z){
  int i;
  char c;
  setBinaryMode(out, 1);
+
  if( z==0 ) return;
  for(i=0; (c = z[i])!=0 && c!='\''; i++){}
  if( c==0 ){
    utf8_printf(out,"'%s'",z);
@@ -16109,6 +17316,7 @@ static void output_c_string(FILE *out, const char *z){
*/
static void output_json_string(FILE *out, const char *z, i64 n){
  unsigned int c;
+
  if( z==0 ) z = "";
  if( n<0 ) n = strlen(z);
  fputc('"', out);
  while( n-- ){
@@ -16233,8 +17441,7 @@ static void output_csv(ShellState *p, const char *z, int bSep){
*/
static void interrupt_handler(int NotUsed){
  UNUSED_PARAMETER(NotUsed);
-
  seenInterrupt++;
-
  if( seenInterrupt>2 ) exit(1);
+
  if( ++seenInterrupt>1 ) exit(1);
  if( globalDb ) sqlite3_interrupt(globalDb);
}

@@ -16275,7 +17482,7 @@ static int safeModeAuth(
    "zipfile",
    "zipfile_cds",
  };
-
  UNUSED_PARAMETER(zA2);
+
  UNUSED_PARAMETER(zA1);
  UNUSED_PARAMETER(zA3);
  UNUSED_PARAMETER(zA4);
  switch( op ){
@@ -16290,7 +17497,7 @@ static int safeModeAuth(
    case SQLITE_FUNCTION: {
      int i;
      for(i=0; i<ArraySize(azProhibitedFunctions); i++){
-
        if( sqlite3_stricmp(zA1, azProhibitedFunctions[i])==0 ){
+
        if( sqlite3_stricmp(zA2, azProhibitedFunctions[i])==0 ){
          failIfSafeMode(p, "cannot use the %s() function in safe mode",
                         azProhibitedFunctions[i]);
        }
@@ -16368,6 +17575,7 @@ static void printSchemaLine(FILE *out, const char *z, const char *zTail){
    int i;
    for(i=0; i<ArraySize(azTerm); i++){
      char *zNew = sqlite3_mprintf("%s%s;", zOrig, azTerm[i]);
+
      shell_check_oom(zNew);
      if( sqlite3_complete(zNew) ){
        size_t n = strlen(zNew);
        zNew[n-1] = 0;
@@ -16477,7 +17685,7 @@ static void eqp_render_level(ShellState *p, int iEqpId){
/*
** Display and reset the EXPLAIN QUERY PLAN data
*/
-
static void eqp_render(ShellState *p){
+
static void eqp_render(ShellState *p, i64 nCycle){
  EQPGraphRow *pRow = p->sGraph.pRow;
  if( pRow ){
    if( pRow->zText[0]=='-' ){
@@ -16488,6 +17696,8 @@ static void eqp_render(ShellState *p){
      utf8_printf(p->out, "%s\n", pRow->zText+3);
      p->sGraph.pRow = pRow->pNext;
      sqlite3_free(pRow);
+
    }else if( nCycle>0 ){
+
      utf8_printf(p->out, "QUERY PLAN (cycles=%lld [100%%])\n", nCycle);
    }else{
      utf8_printf(p->out, "QUERY PLAN\n");
    }
@@ -16800,9 +18010,9 @@ static int shell_callback(
          sqlite3_uint64 ur;
          memcpy(&ur,&r,sizeof(r));
          if( ur==0x7ff0000000000000LL ){
-
            raw_printf(p->out, "1e999");
+
            raw_printf(p->out, "9.0e+999");
          }else if( ur==0xfff0000000000000LL ){
-
            raw_printf(p->out, "-1e999");
+
            raw_printf(p->out, "-9.0e+999");
          }else{
            sqlite3_int64 ir = (sqlite3_int64)r;
            if( r==(double)ir ){
@@ -16846,9 +18056,9 @@ static int shell_callback(
          sqlite3_uint64 ur;
          memcpy(&ur,&r,sizeof(r));
          if( ur==0x7ff0000000000000LL ){
-
            raw_printf(p->out, "1e999");
+
            raw_printf(p->out, "9.0e+999");
          }else if( ur==0xfff0000000000000LL ){
-
            raw_printf(p->out, "-1e999");
+
            raw_printf(p->out, "-9.0e+999");
          }else{
            sqlite3_snprintf(50,z,"%!.20g", r);
            raw_printf(p->out, "%s", z);
@@ -17052,6 +18262,7 @@ static char *shell_error_context(const char *zSql, sqlite3 *db){
  if( db==0
   || zSql==0
   || (iOffset = sqlite3_error_offset(db))<0
+
   || iOffset>=(int)strlen(zSql)
  ){
    return sqlite3_mprintf("");
  }
@@ -17063,15 +18274,15 @@ static char *shell_error_context(const char *zSql, sqlite3 *db){
  len = strlen(zSql);
  if( len>78 ){
    len = 78;
-
    while( (zSql[len]&0xc0)==0x80 ) len--;
+
    while( len>0 && (zSql[len]&0xc0)==0x80 ) len--;
  }
  zCode = sqlite3_mprintf("%.*s", len, zSql);
  shell_check_oom(zCode);
  for(i=0; zCode[i]; i++){ if( IsSpace(zSql[i]) ) zCode[i] = ' '; }
  if( iOffset<25 ){
-
    zMsg = sqlite3_mprintf("\n  %z\n  %*s^--- error here", zCode, iOffset, "");
+
    zMsg = sqlite3_mprintf("\n  %z\n  %*s^--- error here", zCode,iOffset,"");
  }else{
-
    zMsg = sqlite3_mprintf("\n  %z\n  %*serror here ---^", zCode, iOffset-14, "");
+
    zMsg = sqlite3_mprintf("\n  %z\n  %*serror here ---^", zCode,iOffset-14,"");
  }
  return zMsg;
}
@@ -17259,7 +18470,7 @@ static int display_stats(

  if( pArg->statsOn==3 ){
    if( pArg->pStmt ){
-
      iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
+
      iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset);
      raw_printf(pArg->out, "VM-steps: %d\n", iCur);
    }
    return 0;
@@ -17340,8 +18551,10 @@ static int display_stats(
    raw_printf(pArg->out, "Sort Operations:                     %d\n", iCur);
    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
    raw_printf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
-
    iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, bReset);
-
    iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, bReset);
+
    iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT,
+
                               bReset);
+
    iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS,
+
                                bReset);
    if( iHit || iMiss ){
      raw_printf(pArg->out, "Bloom filter bypass taken:           %d/%d\n",
            iHit, iHit+iMiss);
@@ -17365,6 +18578,35 @@ static int display_stats(
  return 0;
}

+

+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
static int scanStatsHeight(sqlite3_stmt *p, int iEntry){
+
  int iPid = 0;
+
  int ret = 1;
+
  sqlite3_stmt_scanstatus_v2(p, iEntry,
+
      SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
+
  );
+
  while( iPid!=0 ){
+
    int ii;
+
    for(ii=0; 1; ii++){
+
      int iId;
+
      int res;
+
      res = sqlite3_stmt_scanstatus_v2(p, ii,
+
          SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iId
+
      );
+
      if( res ) break;
+
      if( iId==iPid ){
+
        sqlite3_stmt_scanstatus_v2(p, ii,
+
            SQLITE_SCANSTAT_PARENTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid
+
        );
+
      }
+
    }
+
    ret++;
+
  }
+
  return ret;
+
}
+
#endif
+

/*
** Display scan stats.
*/
@@ -17376,40 +18618,77 @@ static void display_scanstats(
  UNUSED_PARAMETER(db);
  UNUSED_PARAMETER(pArg);
#else
-
  int i, k, n, mx;
-
  raw_printf(pArg->out, "-------- scanstats --------\n");
-
  mx = 0;
-
  for(k=0; k<=mx; k++){
-
    double rEstLoop = 1.0;
-
    for(i=n=0; 1; i++){
-
      sqlite3_stmt *p = pArg->pStmt;
-
      sqlite3_int64 nLoop, nVisit;
-
      double rEst;
-
      int iSid;
-
      const char *zExplain;
-
      if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
-
        break;
+
  static const int f = SQLITE_SCANSTAT_COMPLEX;
+
  sqlite3_stmt *p = pArg->pStmt;
+
  int ii = 0;
+
  i64 nTotal = 0;
+
  int nWidth = 0;
+
  eqp_reset(pArg);
+

+
  for(ii=0; 1; ii++){
+
    const char *z = 0;
+
    int n = 0;
+
    if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&z) ){
+
      break;
+
    }
+
    n = strlen(z) + scanStatsHeight(p, ii)*3;
+
    if( n>nWidth ) nWidth = n;
+
  }
+
  nWidth += 4;
+

+
  sqlite3_stmt_scanstatus_v2(p, -1, SQLITE_SCANSTAT_NCYCLE, f, (void*)&nTotal);
+
  for(ii=0; 1; ii++){
+
    i64 nLoop = 0;
+
    i64 nRow = 0;
+
    i64 nCycle = 0;
+
    int iId = 0;
+
    int iPid = 0;
+
    const char *z = 0;
+
    const char *zName = 0;
+
    char *zText = 0;
+
    double rEst = 0.0;
+

+
    if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&z) ){
+
      break;
+
    }
+
    sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_EST,f,(void*)&rEst);
+
    sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NLOOP,f,(void*)&nLoop);
+
    sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NVISIT,f,(void*)&nRow);
+
    sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NCYCLE,f,(void*)&nCycle);
+
    sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_SELECTID,f,(void*)&iId);
+
    sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_PARENTID,f,(void*)&iPid);
+
    sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NAME,f,(void*)&zName);
+

+
    zText = sqlite3_mprintf("%s", z);
+
    if( nCycle>=0 || nLoop>=0 || nRow>=0 ){
+
      char *z = 0;
+
      if( nCycle>=0 && nTotal>0 ){
+
        z = sqlite3_mprintf("%zcycles=%lld [%d%%]", z,
+
            nCycle, ((nCycle*100)+nTotal/2) / nTotal
+
        );
      }
-
      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
-
      if( iSid>mx ) mx = iSid;
-
      if( iSid!=k ) continue;
-
      if( n==0 ){
-
        rEstLoop = (double)nLoop;
-
        if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
+
      if( nLoop>=0 ){
+
        z = sqlite3_mprintf("%z%sloops=%lld", z, z ? " " : "", nLoop);
      }
-
      n++;
-
      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
-
      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
-
      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
-
      utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
-
      rEstLoop *= rEst;
-
      raw_printf(pArg->out,
-
          "         nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
-
          nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
+
      if( nRow>=0 ){
+
        z = sqlite3_mprintf("%z%srows=%lld", z, z ? " " : "", nRow);
+
      }
+

+
      if( zName && pArg->scanstatsOn>1 ){
+
        double rpl = (double)nRow / (double)nLoop;
+
        z = sqlite3_mprintf("%z rpl=%.1f est=%.1f", z, rpl, rEst);
+
      }
+

+
      zText = sqlite3_mprintf(
+
          "% *z (%z)", -1*(nWidth-scanStatsHeight(p, ii)*3), zText, z
      );
    }
+

+
    eqp_append(pArg, iId, iPid, zText);
+
    sqlite3_free(zText);
  }
-
  raw_printf(pArg->out, "---------------------------\n");
+

+
  eqp_render(pArg, nTotal);
#endif
}

@@ -17596,12 +18875,13 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
  if( nVar==0 ) return;  /* Nothing to do */
  if( sqlite3_table_column_metadata(pArg->db, "TEMP", "sqlite_parameters",
                                    "key", 0, 0, 0, 0, 0)!=SQLITE_OK ){
-
    return; /* Parameter table does not exist */
+
    rc = SQLITE_NOTFOUND;
+
    pQ = 0;
+
  }else{
+
    rc = sqlite3_prepare_v2(pArg->db,
+
            "SELECT value FROM temp.sqlite_parameters"
+
            " WHERE key=?1", -1, &pQ, 0);
  }
-
  rc = sqlite3_prepare_v2(pArg->db,
-
          "SELECT value FROM temp.sqlite_parameters"
-
          " WHERE key=?1", -1, &pQ, 0);
-
  if( rc || pQ==0 ) return;
  for(i=1; i<=nVar; i++){
    char zNum[30];
    const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
@@ -17610,8 +18890,16 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
      zVar = zNum;
    }
    sqlite3_bind_text(pQ, 1, zVar, -1, SQLITE_STATIC);
-
    if( sqlite3_step(pQ)==SQLITE_ROW ){
+
    if( rc==SQLITE_OK && pQ && sqlite3_step(pQ)==SQLITE_ROW ){
      sqlite3_bind_value(pStmt, i, sqlite3_column_value(pQ, 0));
+
#ifdef NAN
+
    }else if( sqlite3_strlike("_NAN", zVar, 0)==0 ){
+
      sqlite3_bind_double(pStmt, i, NAN);
+
#endif
+
#ifdef INFINITY
+
    }else if( sqlite3_strlike("_INF", zVar, 0)==0 ){
+
      sqlite3_bind_double(pStmt, i, INFINITY);
+
#endif
    }else{
      sqlite3_bind_null(pStmt, i);
    }
@@ -17649,7 +18937,7 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
** characters
*/
static void print_box_line(FILE *out, int N){
-
  const char zDash[] = 
+
  const char zDash[] =
      BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
      BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
  const int nDash = sizeof(zDash) - 1;
@@ -17778,7 +19066,7 @@ static char *translateForDisplayAndDup(
    break;
  }
  zOut[j] = 0;
-
  return (char*)zOut;  
+
  return (char*)zOut;
}

/* Extract the value of the i-th current column for pStmt as an SQL literal
@@ -17855,7 +19143,7 @@ static void exec_prepared_stmt_columnar(
  azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
  shell_check_oom(azData);
  azNextLine = sqlite3_malloc64( nColumn*sizeof(char*) );
-
  shell_check_oom((void*)azNextLine);
+
  shell_check_oom(azNextLine);
  memset((void*)azNextLine, 0, nColumn*sizeof(char*) );
  if( p->cmOpts.bQuote ){
    azQuoted = sqlite3_malloc64( nColumn*sizeof(char*) );
@@ -17885,6 +19173,7 @@ static void exec_prepared_stmt_columnar(
    }
    if( wx<0 ) wx = -wx;
    uz = (const unsigned char*)sqlite3_column_name(pStmt,i);
+
    if( uz==0 ) uz = (u8*)"";
    azData[i] = translateForDisplayAndDup(uz, &zNotUsed, wx, bw);
  }
  do{
@@ -18139,8 +19428,8 @@ static void exec_prepared_stmt(
** caller to eventually free this buffer using sqlite3_free().
*/
static int expertHandleSQL(
-
  ShellState *pState, 
-
  const char *zSql, 
+
  ShellState *pState,
+
  const char *zSql,
  char **pzErr
){
  assert( pState->expert.pExpert );
@@ -18150,7 +19439,7 @@ static int expertHandleSQL(

/*
** This function is called either to silently clean up the object
-
** created by the ".expert" command (if bCancel==1), or to generate a 
+
** created by the ".expert" command (if bCancel==1), or to generate a
** report from it and then clean it up (if bCancel==0).
**
** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
@@ -18245,7 +19534,8 @@ static int expertDotCommand(
  if( rc==SQLITE_OK ){
    pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
    if( pState->expert.pExpert==0 ){
-
      raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory");
+
      raw_printf(stderr, "sqlite3_expert_new: %s\n",
+
                 zErr ? zErr : "out of memory");
      rc = SQLITE_ERROR;
    }else{
      sqlite3_expert_config(
@@ -18333,10 +19623,10 @@ static int shell_exec(
            int iEqpId = sqlite3_column_int(pExplain, 0);
            int iParentId = sqlite3_column_int(pExplain, 1);
            if( zEQPLine==0 ) zEQPLine = "";
-
            if( zEQPLine[0]=='-' ) eqp_render(pArg);
+
            if( zEQPLine[0]=='-' ) eqp_render(pArg, 0);
            eqp_append(pArg, iEqpId, iParentId, zEQPLine);
          }
-
          eqp_render(pArg);
+
          eqp_render(pArg, 0);
        }
        sqlite3_finalize(pExplain);
        sqlite3_free(zEQP);
@@ -18385,7 +19675,7 @@ static int shell_exec(
      bind_prepared_stmt(pArg, pStmt);
      exec_prepared_stmt(pArg, pStmt);
      explain_data_delete(pArg);
-
      eqp_render(pArg);
+
      eqp_render(pArg, 0);

      /* print usage stats if stats on */
      if( pArg && pArg->statsOn ){
@@ -18817,13 +20107,13 @@ static const char *(azHelp[]) = {
  "        input text.",
#endif
#ifndef SQLITE_OMIT_TEST_CONTROL
-
  ".imposter INDEX TABLE    Create imposter table TABLE on index INDEX",
+
  ",imposter INDEX TABLE    Create imposter table TABLE on index INDEX",
#endif
  ".indexes ?TABLE?         Show names of indexes",
  "                           If TABLE is specified, only show indexes for",
  "                           tables matching TABLE using the LIKE operator.",
#ifdef SQLITE_ENABLE_IOTRACE
-
  ".iotrace FILE            Enable I/O diagnostic logging to FILE",
+
  ",iotrace FILE            Enable I/O diagnostic logging to FILE",
#endif
  ".limit ?LIMIT? ?VAL?     Display or change the value of an SQLITE_LIMIT",
  ".lint OPTIONS            Report potential schema issues.",
@@ -18832,8 +20122,10 @@ static const char *(azHelp[]) = {
#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_FIDDLE)
  ".load FILE ?ENTRY?       Load an extension library",
#endif
-
#ifndef SQLITE_SHELL_FIDDLE
-
  ".log FILE|off            Turn logging on or off.  FILE can be stderr/stdout",
+
#if !defined(SQLITE_SHELL_FIDDLE)
+
  ".log FILE|on|off         Turn logging on or off.  FILE can be stderr/stdout",
+
#else
+
  ".log on|off              Turn logging on or off.",
#endif
  ".mode MODE ?OPTIONS?     Set output mode",
  "   MODE is one of:",
@@ -18910,7 +20202,7 @@ static const char *(azHelp[]) = {
#endif
  ".prompt MAIN CONTINUE    Replace the standard prompts",
#ifndef SQLITE_SHELL_FIDDLE
-
  ".quit                    Exit this program",
+
  ".quit                    Stop interpreting input stream, exit if primary.",
  ".read FILE               Read input from FILE or command output",
  "    If FILE begins with \"|\", it is a command that generates the input.",
#endif
@@ -18925,12 +20217,12 @@ static const char *(azHelp[]) = {
  ".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",
+
  ".scanstats on|off|est    Turn sqlite3_stmt_scanstatus() metrics on or off",
  ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",
  "   Options:",
  "      --indent             Try to pretty-print the schema",
  "      --nosys              Omit objects whose names start with \"sqlite_\"",
-
  ".selftest ?OPTIONS?      Run tests defined in the SELFTEST table",
+
  ",selftest ?OPTIONS?      Run tests defined in the SELFTEST table",
  "    Options:",
  "       --init               Create a new SELFTEST table",
  "       -v                   Verbose output",
@@ -18972,9 +20264,9 @@ static const char *(azHelp[]) = {
#endif
  ".tables ?TABLE?          List names of tables matching LIKE pattern TABLE",
#ifndef SQLITE_SHELL_FIDDLE
-
  ".testcase NAME           Begin redirecting output to 'testcase-out.txt'",
+
  ",testcase NAME           Begin redirecting output to 'testcase-out.txt'",
#endif
-
  ".testctrl CMD ...        Run various sqlite3_test_control() operations",
+
  ",testctrl CMD ...        Run various sqlite3_test_control() operations",
  "                           Run \".testctrl\" with no arguments for details",
  ".timeout MS              Try opening locked tables for MS milliseconds",
  ".timer on|off            Turn SQL timer on or off",
@@ -18998,6 +20290,7 @@ static const char *(azHelp[]) = {
  ".unmodule NAME ...       Unregister virtual table modules",
  "    --allexcept             Unregister everything except those named",
#endif
+
  ".version                 Show source, library and compiler versions",
  ".vfsinfo ?AUX?           Information about the top-level VFS",
  ".vfslist                 List all available VFSes",
  ".vfsname ?AUX?           Print the name of the VFS stack",
@@ -19025,16 +20318,41 @@ static int showHelp(FILE *out, const char *zPattern){
   || cli_strcmp(zPattern,"-all")==0
   || cli_strcmp(zPattern,"--all")==0
  ){
-
    /* Show all commands, but only one line per command */
-
    if( zPattern==0 ) zPattern = "";
+
    enum HelpWanted { HW_NoCull = 0, HW_SummaryOnly = 1, HW_Undoc = 2 };
+
    enum HelpHave { HH_Undoc = 2, HH_Summary = 1, HH_More = 0 };
+
    /* Show all or most commands
+
    ** *zPattern==0   => summary of documented commands only
+
    ** *zPattern=='0' => whole help for undocumented commands
+
    ** Otherwise      => whole help for documented commands
+
    */
+
    enum HelpWanted hw = HW_SummaryOnly;
+
    enum HelpHave hh = HH_More;
+
    if( zPattern!=0 ){
+
      hw = (*zPattern=='0')? HW_NoCull|HW_Undoc : HW_NoCull;
+
    }
    for(i=0; i<ArraySize(azHelp); i++){
-
      if( azHelp[i][0]=='.' || zPattern[0] ){
-
        utf8_printf(out, "%s\n", azHelp[i]);
-
        n++;
+
      switch( azHelp[i][0] ){
+
      case ',':
+
        hh = HH_Summary|HH_Undoc;
+
        break;
+
      case '.':
+
        hh = HH_Summary;
+
        break;
+
      default:
+
        hh &= ~HH_Summary;
+
        break;
+
      }
+
      if( ((hw^hh)&HH_Undoc)==0 ){
+
        if( (hh&HH_Summary)!=0 ){
+
          utf8_printf(out, ".%s\n", azHelp[i]+1);
+
          ++n;
+
        }else if( (hw&HW_SummaryOnly)==0 ){
+
          utf8_printf(out, "%s\n", azHelp[i]);
+
        }
      }
    }
  }else{
-
    /* Look for commands that for which zPattern is an exact prefix */
+
    /* Seek documented commands for which zPattern is an exact prefix */
    zPat = sqlite3_mprintf(".%s*", zPattern);
    shell_check_oom(zPat);
    for(i=0; i<ArraySize(azHelp); i++){
@@ -19047,24 +20365,28 @@ static int showHelp(FILE *out, const char *zPattern){
    sqlite3_free(zPat);
    if( n ){
      if( n==1 ){
-
        /* when zPattern is a prefix of exactly one command, then include the
-
        ** details of that command, which should begin at offset j */
-
        while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
+
        /* when zPattern is a prefix of exactly one command, then include
+
        ** the details of that command, which should begin at offset j */
+
        while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){
          utf8_printf(out, "%s\n", azHelp[j]);
          j++;
        }
      }
      return n;
    }
-
    /* Look for commands that contain zPattern anywhere.  Show the complete
-
    ** text of all commands that match. */
+
    /* Look for documented commands that contain zPattern anywhere.
+
    ** Show complete text of all documented commands that match. */
    zPat = sqlite3_mprintf("%%%s%%", zPattern);
    shell_check_oom(zPat);
    for(i=0; i<ArraySize(azHelp); i++){
+
      if( azHelp[i][0]==',' ){
+
        while( i<ArraySize(azHelp)-1 && azHelp[i+1][0]==' ' ) ++i;
+
        continue;
+
      }
      if( azHelp[i][0]=='.' ) j = i;
      if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
        utf8_printf(out, "%s\n", azHelp[j]);
-
        while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
+
        while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]==' ' ){
          j++;
          utf8_printf(out, "%s\n", azHelp[j]);
        }
@@ -19100,16 +20422,27 @@ static char *readFile(const char *zName, int *pnByte){
  long nIn;
  size_t nRead;
  char *pBuf;
+
  int rc;
  if( in==0 ) return 0;
-
  fseek(in, 0, SEEK_END);
+
  rc = fseek(in, 0, SEEK_END);
+
  if( rc!=0 ){
+
    raw_printf(stderr, "Error: '%s' not seekable\n", zName);
+
    fclose(in);
+
    return 0;
+
  }
  nIn = ftell(in);
  rewind(in);
  pBuf = sqlite3_malloc64( nIn+1 );
-
  if( pBuf==0 ){ fclose(in); return 0; }
+
  if( pBuf==0 ){
+
    raw_printf(stderr, "Error: out of memory\n");
+
    fclose(in);
+
    return 0;
+
  }
  nRead = fread(pBuf, nIn, 1, in);
  fclose(in);
  if( nRead!=1 ){
    sqlite3_free(pBuf);
+
    raw_printf(stderr, "Error: cannot read '%s'\n", zName);
    return 0;
  }
  pBuf[nIn] = 0;
@@ -19206,7 +20539,7 @@ int deduceDatabaseType(const char *zName, int dfltZip){
    }
  }
  fclose(f);
-
  return rc;  
+
  return rc;
}

#ifndef SQLITE_OMIT_DESERIALIZE
@@ -19299,58 +20632,11 @@ readHexDb_error:
#endif /* SQLITE_OMIT_DESERIALIZE */

/*
-
** Scalar function "shell_int32". The first argument to this function
-
** must be a blob. The second a non-negative integer. This function
-
** reads and returns a 32-bit big-endian integer from byte
-
** offset (4*<arg2>) of the blob.
-
*/
-
static void shellInt32(
-
  sqlite3_context *context, 
-
  int argc, 
-
  sqlite3_value **argv
-
){
-
  const unsigned char *pBlob;
-
  int nBlob;
-
  int iInt;
-

-
  UNUSED_PARAMETER(argc);
-
  nBlob = sqlite3_value_bytes(argv[0]);
-
  pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
-
  iInt = sqlite3_value_int(argv[1]);
-

-
  if( iInt>=0 && (iInt+1)*4<=nBlob ){
-
    const unsigned char *a = &pBlob[iInt*4];
-
    sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24)
-
                       + ((sqlite3_int64)a[1]<<16)
-
                       + ((sqlite3_int64)a[2]<< 8)
-
                       + ((sqlite3_int64)a[3]<< 0);
-
    sqlite3_result_int64(context, iVal);
-
  }
-
}
-

-
/*
-
** Scalar function "shell_idquote(X)" returns string X quoted as an identifier,
-
** using "..." with internal double-quote characters doubled.
-
*/
-
static void shellIdQuote(
-
  sqlite3_context *context, 
-
  int argc, 
-
  sqlite3_value **argv
-
){
-
  const char *zName = (const char*)sqlite3_value_text(argv[0]);
-
  UNUSED_PARAMETER(argc);
-
  if( zName ){
-
    char *z = sqlite3_mprintf("\"%w\"", zName);
-
    sqlite3_result_text(context, z, -1, sqlite3_free);
-
  }
-
}
-

-
/*
** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X.
*/
static void shellUSleepFunc(
-
  sqlite3_context *context, 
-
  int argcUnused, 
+
  sqlite3_context *context,
+
  int argcUnused,
  sqlite3_value **argv
){
  int sleep = sqlite3_value_int(argv[0]);
@@ -19359,97 +20645,6 @@ static void shellUSleepFunc(
  sqlite3_result_int(context, sleep);
}

-
/*
-
** Scalar function "shell_escape_crnl" used by the .recover command.
-
** The argument passed to this function is the output of built-in
-
** function quote(). If the first character of the input is "'", 
-
** indicating that the value passed to quote() was a text value,
-
** then this function searches the input for "\n" and "\r" characters
-
** and adds a wrapper similar to the following:
-
**
-
**   replace(replace(<input>, '\n', char(10), '\r', char(13));
-
**
-
** Or, if the first character of the input is not "'", then a copy
-
** of the input is returned.
-
*/
-
static void shellEscapeCrnl(
-
  sqlite3_context *context, 
-
  int argc, 
-
  sqlite3_value **argv
-
){
-
  const char *zText = (const char*)sqlite3_value_text(argv[0]);
-
  UNUSED_PARAMETER(argc);
-
  if( zText && zText[0]=='\'' ){
-
    i64 nText = sqlite3_value_bytes(argv[0]);
-
    i64 i;
-
    char zBuf1[20];
-
    char zBuf2[20];
-
    const char *zNL = 0;
-
    const char *zCR = 0;
-
    i64 nCR = 0;
-
    i64 nNL = 0;
-

-
    for(i=0; zText[i]; i++){
-
      if( zNL==0 && zText[i]=='\n' ){
-
        zNL = unused_string(zText, "\\n", "\\012", zBuf1);
-
        nNL = strlen(zNL);
-
      }
-
      if( zCR==0 && zText[i]=='\r' ){
-
        zCR = unused_string(zText, "\\r", "\\015", zBuf2);
-
        nCR = strlen(zCR);
-
      }
-
    }
-

-
    if( zNL || zCR ){
-
      i64 iOut = 0;
-
      i64 nMax = (nNL > nCR) ? nNL : nCR;
-
      i64 nAlloc = nMax * nText + (nMax+64)*2;
-
      char *zOut = (char*)sqlite3_malloc64(nAlloc);
-
      if( zOut==0 ){
-
        sqlite3_result_error_nomem(context);
-
        return;
-
      }
-

-
      if( zNL && zCR ){
-
        memcpy(&zOut[iOut], "replace(replace(", 16);
-
        iOut += 16;
-
      }else{
-
        memcpy(&zOut[iOut], "replace(", 8);
-
        iOut += 8;
-
      }
-
      for(i=0; zText[i]; i++){
-
        if( zText[i]=='\n' ){
-
          memcpy(&zOut[iOut], zNL, nNL);
-
          iOut += nNL;
-
        }else if( zText[i]=='\r' ){
-
          memcpy(&zOut[iOut], zCR, nCR);
-
          iOut += nCR;
-
        }else{
-
          zOut[iOut] = zText[i];
-
          iOut++;
-
        }
-
      }
-

-
      if( zNL ){
-
        memcpy(&zOut[iOut], ",'", 2); iOut += 2;
-
        memcpy(&zOut[iOut], zNL, nNL); iOut += nNL;
-
        memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12;
-
      }
-
      if( zCR ){
-
        memcpy(&zOut[iOut], ",'", 2); iOut += 2;
-
        memcpy(&zOut[iOut], zCR, nCR); iOut += nCR;
-
        memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12;
-
      }
-

-
      sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT);
-
      sqlite3_free(zOut);
-
      return;
-
    }
-
  }
-

-
  sqlite3_result_value(context, argv[0]);
-
}
-

/* Flags for open_db().
**
** The default behavior of open_db() is to exit(1) if the database fails to
@@ -19474,13 +20669,13 @@ static void open_db(ShellState *p, int openFlags){
      if( zDbFilename==0 || zDbFilename[0]==0 ){
        p->openMode = SHELL_OPEN_NORMAL;
      }else{
-
        p->openMode = (u8)deduceDatabaseType(zDbFilename, 
+
        p->openMode = (u8)deduceDatabaseType(zDbFilename,
                             (openFlags & OPEN_DB_ZIPFILE)!=0);
      }
    }
    switch( p->openMode ){
      case SHELL_OPEN_APPENDVFS: {
-
        sqlite3_open_v2(zDbFilename, &p->db, 
+
        sqlite3_open_v2(zDbFilename, &p->db,
           SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs");
        break;
      }
@@ -19509,18 +20704,39 @@ static void open_db(ShellState *p, int openFlags){
    if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
      utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
          zDbFilename, sqlite3_errmsg(p->db));
-
      if( openFlags & OPEN_DB_KEEPALIVE ){
-
        sqlite3_open(":memory:", &p->db);
-
        return;
+
      if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
+
        exit(1);
+
      }
+
      sqlite3_close(p->db);
+
      sqlite3_open(":memory:", &p->db);
+
      if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
+
        utf8_printf(stderr,
+
          "Also: unable to open substitute in-memory database.\n"
+
        );
+
        exit(1);
+
      }else{
+
        utf8_printf(stderr,
+
          "Notice: using substitute in-memory database instead of \"%s\"\n",
+
          zDbFilename);
      }
-
      exit(1);
    }
+
    sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, (int)0, (int*)0);
+

+
    /* Reflect the use or absence of --unsafe-testing invocation. */
+
    {
+
      int testmode_on = ShellHasFlag(p,SHFLG_TestingMode);
+
      sqlite3_db_config(p->db, SQLITE_DBCONFIG_TRUSTED_SCHEMA, testmode_on,0);
+
      sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, !testmode_on,0);
+
    }
+

#ifndef SQLITE_OMIT_LOAD_EXTENSION
    sqlite3_enable_load_extension(p->db, 1);
#endif
    sqlite3_shathree_init(p->db, 0, 0);
    sqlite3_uint_init(p->db, 0, 0);
    sqlite3_decimal_init(p->db, 0, 0);
+
    sqlite3_base64_init(p->db, 0, 0);
+
    sqlite3_base85_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);
@@ -19528,27 +20744,46 @@ static void open_db(ShellState *p, int openFlags){
    sqlite3_fileio_init(p->db, 0, 0);
    sqlite3_completion_init(p->db, 0, 0);
#endif
-
#if SQLITE_SHELL_HAVE_RECOVER
-
    sqlite3_dbdata_init(p->db, 0, 0);
-
#endif
#ifdef SQLITE_HAVE_ZLIB
    if( !p->bSafeModePersist ){
      sqlite3_zipfile_init(p->db, 0, 0);
      sqlite3_sqlar_init(p->db, 0, 0);
    }
#endif
+
#ifdef SQLITE_SHELL_EXTFUNCS
+
    /* Create a preprocessing mechanism for extensions to make
+
     * their own provisions for being built into the shell.
+
     * This is a short-span macro. See further below for usage.
+
     */
+
#define SHELL_SUB_MACRO(base, variant) base ## _ ## variant
+
#define SHELL_SUBMACRO(base, variant) SHELL_SUB_MACRO(base, variant)
+
    /* Let custom-included extensions get their ..._init() called.
+
     * The WHATEVER_INIT( db, pzErrorMsg, pApi ) macro should cause
+
     * the extension's sqlite3_*_init( db, pzErrorMsg, pApi )
+
     * inititialization routine to be called.
+
     */
+
    {
+
      int irc = SHELL_SUBMACRO(SQLITE_SHELL_EXTFUNCS, INIT)(p->db);
+
    /* Let custom-included extensions expose their functionality.
+
     * The WHATEVER_EXPOSE( db, pzErrorMsg ) macro should cause
+
     * the SQL functions, virtual tables, collating sequences or
+
     * VFS's implemented by the extension to be registered.
+
     */
+
      if( irc==SQLITE_OK
+
          || irc==SQLITE_OK_LOAD_PERMANENTLY ){
+
        SHELL_SUBMACRO(SQLITE_SHELL_EXTFUNCS, EXPOSE)(p->db, 0);
+
      }
+
#undef SHELL_SUB_MACRO
+
#undef SHELL_SUBMACRO
+
    }
+
#endif
+

    sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
                            shellAddSchemaName, 0, 0);
    sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
                            shellModuleSchema, 0, 0);
    sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
                            shellPutsFunc, 0, 0);
-
    sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0,
-
                            shellEscapeCrnl, 0, 0);
-
    sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0,
-
                            shellInt32, 0, 0);
-
    sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,
-
                            shellIdQuote, 0, 0);
    sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
                            shellUSleepFunc, 0, 0);
#ifndef SQLITE_NOHAVE_SYSTEM
@@ -19557,6 +20792,7 @@ static void open_db(ShellState *p, int openFlags){
    sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
                            editFunc, 0, 0);
#endif
+

    if( p->openMode==SHELL_OPEN_ZIPFILE ){
      char *zSql = sqlite3_mprintf(
         "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", zDbFilename);
@@ -19574,9 +20810,9 @@ static void open_db(ShellState *p, int openFlags){
        aData = (unsigned char*)readFile(zDbFilename, &nData);
      }else{
        aData = readHexDb(p, &nData);
-
        if( aData==0 ){
-
          return;
-
        }
+
      }
+
      if( aData==0 ){
+
        return;
      }
      rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
                   SQLITE_DESERIALIZE_RESIZEABLE |
@@ -19590,8 +20826,13 @@ static void open_db(ShellState *p, int openFlags){
    }
#endif
  }
-
  if( p->bSafeModePersist && p->db!=0 ){
-
    sqlite3_set_authorizer(p->db, safeModeAuth, p);
+
  if( p->db!=0 ){
+
    if( p->bSafeModePersist ){
+
      sqlite3_set_authorizer(p->db, safeModeAuth, p);
+
    }
+
    sqlite3_db_config(
+
        p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0
+
    );
  }
}

@@ -19603,7 +20844,7 @@ void close_db(sqlite3 *db){
  if( rc ){
    utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n",
        rc, sqlite3_errmsg(db));
-
  } 
+
  }
}

#if HAVE_READLINE || HAVE_EDITLINE
@@ -19633,6 +20874,8 @@ static char *readline_completion_generator(const char *text, int state){
  return zRet;
}
static char **readline_completion(const char *zText, int iStart, int iEnd){
+
  (void)iStart;
+
  (void)iEnd;
  rl_attempted_completion_over = 1;
  return rl_completion_matches(zText, readline_completion_generator);
}
@@ -19648,7 +20891,7 @@ static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
  char *zSql;
  char zBuf[1000];

-
  if( nLine>sizeof(zBuf)-30 ) return;
+
  if( nLine>(i64)sizeof(zBuf)-30 ) return;
  if( zLine[0]=='.' || zLine[0]=='#') return;
  for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
  if( i==nLine-1 ) return;
@@ -19664,7 +20907,7 @@ static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
  while( sqlite3_step(pStmt)==SQLITE_ROW ){
    const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0);
    int nCompletion = sqlite3_column_bytes(pStmt, 0);
-
    if( iStart+nCompletion < sizeof(zBuf)-1 && zCompletion ){
+
    if( iStart+nCompletion < (i64)sizeof(zBuf)-1 && zCompletion ){
      memcpy(zBuf+iStart, zCompletion, nCompletion+1);
      linenoiseAddCompletion(lc, zBuf);
    }
@@ -19688,6 +20931,7 @@ static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
**    \'    -> '
**    \\    -> backslash
**    \NNN  -> ascii character NNN in octal
+
**    \xHH  -> ascii character HH in hexadecimal
*/
static void resolve_backslashes(char *z){
  int i, j;
@@ -19716,6 +20960,15 @@ static void resolve_backslashes(char *z){
        c = '\'';
      }else if( c=='\\' ){
        c = '\\';
+
      }else if( c=='x' ){
+
        int nhd = 0, hdv;
+
        u8 hv = 0;
+
        while( nhd<2 && (c=z[i+1+nhd])!=0 && (hdv=hexDigitValue(c))>=0 ){
+
          hv = (u8)((hv<<4)|hdv);
+
          ++nhd;
+
        }
+
        i += nhd;
+
        c = (u8)hv;
      }else if( c>='0' && c<='7' ){
        c -= '0';
        if( z[i+1]>='0' && z[i+1]<='7' ){
@@ -19815,7 +21068,7 @@ static int sql_trace_callback(
    utf8_printf(p->traceOut, "-- closing database connection\n");
    return 0;
  }
-
  if( mType!=SQLITE_TRACE_ROW && ((const char*)pX)[0]=='-' ){
+
  if( mType!=SQLITE_TRACE_ROW && pX!=0 && ((const char*)pX)[0]=='-' ){
    zSql = (const char*)pX;
  }else{
    pStmt = (sqlite3_stmt*)pP;
@@ -19847,7 +21100,7 @@ static int sql_trace_callback(
      break;
    }
    case SQLITE_TRACE_PROFILE: {
-
      sqlite3_int64 nNanosec = *(sqlite3_int64*)pX;
+
      sqlite3_int64 nNanosec = pX ? *(sqlite3_int64*)pX : 0;
      utf8_printf(p->traceOut, "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec);
      break;
    }
@@ -19859,10 +21112,13 @@ static int sql_trace_callback(
/*
** A no-op routine that runs with the ".breakpoint" doc-command.  This is
** a useful spot to set a debugger breakpoint.
+
**
+
** This routine does not do anything practical.  The code are there simply
+
** to prevent the compiler from optimizing this routine out.
*/
static void test_breakpoint(void){
-
  static int nCall = 0;
-
  nCall++;
+
  static unsigned int nCall = 0;
+
  if( (nCall++)==0xffffffff ) printf("Many .breakpoints have run\n");
}

/*
@@ -19920,8 +21176,8 @@ static void import_append_char(ImportCtx *p, int c){
*/
static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
  int c;
-
  int cSep = p->cColSep;
-
  int rSep = p->cRowSep;
+
  int cSep = (u8)p->cColSep;
+
  int rSep = (u8)p->cRowSep;
  p->n = 0;
  c = fgetc(p->in);
  if( c==EOF || seenInterrupt ){
@@ -20010,8 +21266,8 @@ static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
*/
static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
  int c;
-
  int cSep = p->cColSep;
-
  int rSep = p->cRowSep;
+
  int cSep = (u8)p->cColSep;
+
  int rSep = (u8)p->cRowSep;
  p->n = 0;
  c = fgetc(p->in);
  if( c==EOF || seenInterrupt ){
@@ -20161,7 +21417,7 @@ static void tryToCloneSchema(
  char *zErrMsg = 0;

  zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
-
                           " WHERE %s", zWhere);
+
                           " WHERE %s ORDER BY rowid ASC", zWhere);
  shell_check_oom(zQuery);
  rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
  if( rc ){
@@ -20174,12 +21430,14 @@ static void tryToCloneSchema(
    zName = sqlite3_column_text(pQuery, 0);
    zSql = sqlite3_column_text(pQuery, 1);
    if( zName==0 || zSql==0 ) continue;
-
    printf("%s... ", zName); fflush(stdout);
-
    sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
-
    if( zErrMsg ){
-
      utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
-
      sqlite3_free(zErrMsg);
-
      zErrMsg = 0;
+
    if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ){
+
      printf("%s... ", zName); fflush(stdout);
+
      sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
+
      if( zErrMsg ){
+
        utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
+
        sqlite3_free(zErrMsg);
+
        zErrMsg = 0;
+
      }
    }
    if( xForEach ){
      xForEach(p, newDb, (const char*)zName);
@@ -20203,6 +21461,7 @@ static void tryToCloneSchema(
      zName = sqlite3_column_text(pQuery, 0);
      zSql = sqlite3_column_text(pQuery, 1);
      if( zName==0 || zSql==0 ) continue;
+
      if( sqlite3_stricmp((char*)zName, "sqlite_sequence")==0 ) continue;
      printf("%s... ", zName); fflush(stdout);
      sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
      if( zErrMsg ){
@@ -20306,7 +21565,7 @@ static int db_int(sqlite3 *db, const char *zSql){
  return res;
}

-
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
+
#if SQLITE_SHELL_HAVE_RECOVER
/*
** Convert a 2-byte or 4-byte big-endian integer into a native integer
*/
@@ -20369,7 +21628,9 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
  if( sqlite3_step(pStmt)==SQLITE_ROW
   && sqlite3_column_bytes(pStmt,0)>100
  ){
-
    memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100);
+
    const u8 *pb = sqlite3_column_blob(pStmt,0);
+
    shell_check_oom(pb);
+
    memcpy(aHdr, pb, 100);
    sqlite3_finalize(pStmt);
  }else{
    raw_printf(stderr, "unable to read database header\n");
@@ -20844,16 +22105,16 @@ static int lintDotCommand(

#if !defined SQLITE_OMIT_VIRTUALTABLE
static void shellPrepare(
-
  sqlite3 *db, 
-
  int *pRc, 
-
  const char *zSql, 
+
  sqlite3 *db,
+
  int *pRc,
+
  const char *zSql,
  sqlite3_stmt **ppStmt
){
  *ppStmt = 0;
  if( *pRc==SQLITE_OK ){
    int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
    if( rc!=SQLITE_OK ){
-
      raw_printf(stderr, "sql error: %s (%d)\n", 
+
      raw_printf(stderr, "sql error: %s (%d)\n",
          sqlite3_errmsg(db), sqlite3_errcode(db)
      );
      *pRc = rc;
@@ -20869,10 +22130,10 @@ static void shellPrepare(
** nuisance compiler warnings about "defined but not used".
*/
void shellPreparePrintf(
-
  sqlite3 *db, 
-
  int *pRc, 
+
  sqlite3 *db,
+
  int *pRc,
  sqlite3_stmt **ppStmt,
-
  const char *zFmt, 
+
  const char *zFmt,
  ...
){
  *ppStmt = 0;
@@ -20898,7 +22159,7 @@ void shellPreparePrintf(
** nuisance compiler warnings about "defined but not used".
*/
void shellFinalize(
-
  int *pRc, 
+
  int *pRc,
  sqlite3_stmt *pStmt
){
  if( pStmt ){
@@ -20920,7 +22181,7 @@ void shellFinalize(
** nuisance compiler warnings about "defined but not used".
*/
void shellReset(
-
  int *pRc, 
+
  int *pRc,
  sqlite3_stmt *pStmt
){
  int rc = sqlite3_reset(pStmt);
@@ -20968,7 +22229,7 @@ static int arUsage(FILE *f){
}

/*
-
** Print an error message for the .ar command to stderr and return 
+
** Print an error message for the .ar command to stderr and return
** SQLITE_ERROR.
*/
static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
@@ -21034,7 +22295,7 @@ static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
      break;
    case AR_SWITCH_APPEND:
      pAr->bAppend = 1;
-
      /* Fall thru into --file */
+
      deliberate_fall_through;
    case AR_SWITCH_FILE:
      pAr->zFile = zArg;
      break;
@@ -21049,7 +22310,7 @@ static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
/*
** Parse the command line for an ".ar" command. The results are written into
** structure (*pAr). SQLITE_OK is returned if the command line is parsed
-
** successfully, otherwise an error message is written to stderr and 
+
** successfully, otherwise an error message is written to stderr and
** SQLITE_ERROR returned.
*/
static int arParseCommand(
@@ -21186,7 +22447,10 @@ static int arParseCommand(
      }
    }
  }
-

+
  if( pAr->eCmd==0 ){
+
    utf8_printf(stderr, "Required argument missing.  Usage:\n");
+
    return arUsage(stderr);
+
  }
  return SQLITE_OK;
}

@@ -21245,7 +22509,7 @@ static int arCheckEntries(ArCommand *pAr){
** when pAr->bGlob is false and GLOB match when pAr->bGlob is true.
*/
static void arWhereClause(
-
  int *pRc, 
+
  int *pRc,
  ArCommand *pAr,
  char **pzWhere                  /* OUT: New WHERE clause */
){
@@ -21260,7 +22524,7 @@ static void arWhereClause(
      for(i=0; i<pAr->nArg; i++){
        const char *z = pAr->azArg[i];
        zWhere = sqlite3_mprintf(
-
          "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'", 
+
          "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
          zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
        );
        if( zWhere==0 ){
@@ -21275,10 +22539,10 @@ static void arWhereClause(
}

/*
-
** Implementation of .ar "lisT" command. 
+
** Implementation of .ar "lisT" command.
*/
static int arListCommand(ArCommand *pAr){
-
  const char *zSql = "SELECT %s FROM %s WHERE %s"; 
+
  const char *zSql = "SELECT %s FROM %s WHERE %s";
  const char *azCols[] = {
    "name",
    "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name"
@@ -21300,7 +22564,7 @@ static int arListCommand(ArCommand *pAr){
      if( pAr->bVerbose ){
        utf8_printf(pAr->p->out, "%s % 10d  %s  %s\n",
            sqlite3_column_text(pSql, 0),
-
            sqlite3_column_int(pSql, 1), 
+
            sqlite3_column_int(pSql, 1),
            sqlite3_column_text(pSql, 2),
            sqlite3_column_text(pSql, 3)
        );
@@ -21357,17 +22621,17 @@ static int arRemoveCommand(ArCommand *pAr){
}

/*
-
** Implementation of .ar "eXtract" command. 
+
** Implementation of .ar "eXtract" command.
*/
static int arExtractCommand(ArCommand *pAr){
-
  const char *zSql1 = 
+
  const char *zSql1 =
    "SELECT "
    " ($dir || name),"
    " writefile(($dir || name), %s, mode, mtime) "
    "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)"
    " AND name NOT GLOB '*..[/\\]*'";

-
  const char *azExtraArg[] = { 
+
  const char *azExtraArg[] = {
    "sqlar_uncompress(data, sz)",
    "data"
  };
@@ -21393,7 +22657,7 @@ static int arExtractCommand(ArCommand *pAr){
    if( zDir==0 ) rc = SQLITE_NOMEM;
  }

-
  shellPreparePrintf(pAr->db, &rc, &pSql, zSql1, 
+
  shellPreparePrintf(pAr->db, &rc, &pSql, zSql1,
      azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere
  );

@@ -21471,7 +22735,7 @@ static int arCreateOrUpdateCommand(
  int bUpdate,                    /* true for a --create. */
  int bOnlyIfChanged              /* Only update if file has changed */
){
-
  const char *zCreate = 
+
  const char *zCreate =
      "CREATE TABLE IF NOT EXISTS sqlar(\n"
      "  name TEXT PRIMARY KEY,  -- name of the file\n"
      "  mode INT,               -- access permissions\n"
@@ -21513,7 +22777,7 @@ static int arCreateOrUpdateCommand(
  arExecSql(pAr, "PRAGMA page_size=512");
  rc = arExecSql(pAr, "SAVEPOINT ar;");
  if( rc!=SQLITE_OK ) return rc;
-
  zTemp[0] = 0; 
+
  zTemp[0] = 0;
  if( pAr->bZip ){
    /* Initialize the zipfile virtual table, if necessary */
    if( pAr->zFile ){
@@ -21607,7 +22871,7 @@ static int arDotCommand(
    }else if( cmd.zFile ){
      int flags;
      if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
-
      if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT 
+
      if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
           || cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){
        flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
      }else{
@@ -21618,10 +22882,10 @@ static int arDotCommand(
        utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile,
             eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
      }
-
      rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, 
+
      rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
             eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
      if( rc!=SQLITE_OK ){
-
        utf8_printf(stderr, "cannot open file: %s (%s)\n", 
+
        utf8_printf(stderr, "cannot open file: %s (%s)\n",
            cmd.zFile, sqlite3_errmsg(cmd.db)
        );
        goto end_ar_command;
@@ -21737,7 +23001,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
      bRowids = 0;
    }
    else{
-
      utf8_printf(stderr, "unexpected option: %s\n", azArg[i]); 
+
      utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
      showHelp(pState->out, azArg[0]);
      return 1;
    }
@@ -21952,7 +23216,7 @@ FROM (\
      sqlite3_bind_int(pStmt, 1, nDigits);
      rc = sqlite3_step(pStmt);
      sqlite3_finalize(pStmt);
-
      assert(rc==SQLITE_DONE);
+
      if( rc!=SQLITE_DONE ) rc_err_oom_die(SQLITE_NOMEM);
    }
    assert(db_int(*pDb, zHasDupes)==0); /* Consider: remove this */
    rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0);
@@ -22100,7 +23364,7 @@ static int do_meta_command(char *zLine, ShellState *p){
      return 1;
    }
    if( zDb==0 ) zDb = "main";
-
    rc = sqlite3_open_v2(zDestFile, &pDest, 
+
    rc = sqlite3_open_v2(zDestFile, &pDest,
                  SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
    if( rc!=SQLITE_OK ){
      utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
@@ -22202,7 +23466,6 @@ static int do_meta_command(char *zLine, ShellState *p){
      raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
      rc = 2;
    }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
-
      raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
      rc = 2;
    }else if( testcase_glob(azArg[1],zRes)==0 ){
      utf8_printf(stderr,
@@ -22332,6 +23595,8 @@ static int do_meta_command(char *zLine, ShellState *p){
        { "load_extension",     SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
        { "no_ckpt_on_close",   SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE      },
        { "reset_database",     SQLITE_DBCONFIG_RESET_DATABASE        },
+
        { "reverse_scanorder",  SQLITE_DBCONFIG_REVERSE_SCANORDER     },
+
        { "stmt_scanstatus",    SQLITE_DBCONFIG_STMT_SCANSTATUS       },
        { "trigger_eqp",        SQLITE_DBCONFIG_TRIGGER_EQP           },
        { "trusted_schema",     SQLITE_DBCONFIG_TRUSTED_SCHEMA        },
        { "writable_schema",    SQLITE_DBCONFIG_WRITABLE_SCHEMA       },
@@ -22350,7 +23615,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    if( nArg>1 && ii==ArraySize(aDbConfig) ){
      utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
      utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
-
    }   
+
    }
  }else

#if SQLITE_SHELL_HAVE_RECOVER
@@ -22417,7 +23682,7 @@ static int do_meta_command(char *zLine, ShellState *p){
            "    substr(o.name, 1, length(name)+1) == (name||'_')"
            ")", azArg[i], azArg[i]
        );
-
      
+

        if( zLike ){
          zLike = sqlite3_mprintf("%z OR %z", zLike, zExpr);
        }else{
@@ -22550,7 +23815,7 @@ static int do_meta_command(char *zLine, ShellState *p){
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){
    if( p->bSafeMode ){
-
      raw_printf(stderr, 
+
      raw_printf(stderr,
        "Cannot run experimental commands such as \"%s\" in safe mode\n",
        azArg[0]);
      rc = 1;
@@ -22569,7 +23834,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    } aCtrl[] = {
      { "chunk_size",     SQLITE_FCNTL_CHUNK_SIZE,      "SIZE"           },
      { "data_version",   SQLITE_FCNTL_DATA_VERSION,    ""               },
-
      { "has_moved",      SQLITE_FCNTL_HAS_MOVED,       ""               },  
+
      { "has_moved",      SQLITE_FCNTL_HAS_MOVED,       ""               },
      { "lock_timeout",   SQLITE_FCNTL_LOCK_TIMEOUT,    "MILLISEC"       },
      { "persist_wal",    SQLITE_FCNTL_PERSIST_WAL,     "[BOOLEAN]"      },
   /* { "pragma",         SQLITE_FCNTL_PRAGMA,          "NAME ARG"       },*/
@@ -22590,7 +23855,7 @@ static int do_meta_command(char *zLine, ShellState *p){
    open_db(p, 0);
    zCmd = nArg>=2 ? azArg[1] : "help";

-
    if( zCmd[0]=='-' 
+
    if( zCmd[0]=='-'
     && (cli_strcmp(zCmd,"--schema")==0 || cli_strcmp(zCmd,"-schema")==0)
     && nArg>=4
    ){
@@ -22883,8 +24148,8 @@ static int do_meta_command(char *zLine, ShellState *p){
                           " for import\n");
        goto meta_command_exit;
      }
-
      sCtx.cColSep = p->colSeparator[0];
-
      sCtx.cRowSep = p->rowSeparator[0];
+
      sCtx.cColSep = (u8)p->colSeparator[0];
+
      sCtx.cRowSep = (u8)p->rowSeparator[0];
    }
    sCtx.zFile = zFile;
    sCtx.nLine = 1;
@@ -23080,6 +24345,12 @@ static int do_meta_command(char *zLine, ShellState *p){
    int isWO = 0;  /* True if making an imposter of a WITHOUT ROWID table */
    int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
    int i;
+
    if( !ShellHasFlag(p,SHFLG_TestingMode) ){
+
      utf8_printf(stderr, ".%s unavailable without --unsafe-testing\n",
+
                  "imposter");
+
      rc = 1;
+
      goto meta_command_exit;
+
    }
    if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
      utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"
                          "       .imposter off\n");
@@ -23264,7 +24535,8 @@ static int do_meta_command(char *zLine, ShellState *p){
    const char *zFile, *zProc;
    char *zErrMsg = 0;
    failIfSafeMode(p, "cannot run .load in safe mode");
-
    if( nArg<2 ){
+
    if( nArg<2 || azArg[1][0]==0 ){
+
      /* Must have a non-empty FILE. (Will not load self.) */
      raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
      rc = 1;
      goto meta_command_exit;
@@ -23281,19 +24553,25 @@ static int do_meta_command(char *zLine, ShellState *p){
  }else
#endif

-
#ifndef SQLITE_SHELL_FIDDLE
  if( c=='l' && cli_strncmp(azArg[0], "log", n)==0 ){
-
    failIfSafeMode(p, "cannot run .log in safe mode");
    if( nArg!=2 ){
      raw_printf(stderr, "Usage: .log FILENAME\n");
      rc = 1;
    }else{
      const char *zFile = azArg[1];
+
      if( p->bSafeMode
+
       && cli_strcmp(zFile,"on")!=0
+
       && cli_strcmp(zFile,"off")!=0
+
      ){
+
        raw_printf(stdout, "cannot set .log to anything other "
+
                   "than \"on\" or \"off\"\n");
+
        zFile = "off";
+
      }
      output_file_close(p->pLog);
+
      if( cli_strcmp(zFile,"on")==0 ) zFile = "stdout";
      p->pLog = output_file_open(zFile, 0);
    }
  }else
-
#endif

  if( c=='m' && cli_strncmp(azArg[0], "mode", n)==0 ){
    const char *zMode = 0;
@@ -23818,10 +25096,10 @@ static int do_meta_command(char *zLine, ShellState *p){

  if( c=='p' && cli_strncmp(azArg[0], "prompt", n)==0 ){
    if( nArg >= 2) {
-
      strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
+
      shell_strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
    }
    if( nArg >= 3) {
-
      strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
+
      shell_strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
    }
  }else

@@ -23924,12 +25202,20 @@ static int do_meta_command(char *zLine, ShellState *p){

  if( c=='s' && cli_strncmp(azArg[0], "scanstats", n)==0 ){
    if( nArg==2 ){
-
      p->scanstatsOn = (u8)booleanValue(azArg[1]);
+
      if( cli_strcmp(azArg[1], "est")==0 ){
+
        p->scanstatsOn = 2;
+
      }else{
+
        p->scanstatsOn = (u8)booleanValue(azArg[1]);
+
      }
+
      open_db(p, 0);
+
      sqlite3_db_config(
+
          p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0
+
      );
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
      raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
#endif
    }else{
-
      raw_printf(stderr, "Usage: .scanstats on|off\n");
+
      raw_printf(stderr, "Usage: .scanstats on|off|est\n");
      rc = 1;
    }
  }else
@@ -23964,7 +25250,8 @@ static int do_meta_command(char *zLine, ShellState *p){
      }else if( zName==0 ){
        zName = azArg[ii];
      }else{
-
        raw_printf(stderr, "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
+
        raw_printf(stderr,
+
                   "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
        rc = 1;
        goto meta_command_exit;
      }
@@ -24080,7 +25367,7 @@ static int do_meta_command(char *zLine, ShellState *p){
  if( (c=='s' && n==11 && cli_strncmp(azArg[0], "selecttrace", n)==0)
   || (c=='t' && n==9  && cli_strncmp(azArg[0], "treetrace", n)==0)
  ){
-
    unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
+
    unsigned int x = nArg>=2? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
    sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
  }else

@@ -24265,7 +25552,8 @@ static int do_meta_command(char *zLine, ShellState *p){
        }
      }
      if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){
-
        raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession));
+
        raw_printf(stderr,
+
                   "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession));
        goto meta_command_exit;
      }
      pSession = &pAuxDb->aSession[pAuxDb->nSession];
@@ -24479,12 +25767,12 @@ static int do_meta_command(char *zLine, ShellState *p){
      }
    }
    if( bSchema ){
-
      zSql = "SELECT lower(name) FROM sqlite_schema"
+
      zSql = "SELECT lower(name) as tname FROM sqlite_schema"
             " WHERE type='table' AND coalesce(rootpage,0)>1"
             " UNION ALL SELECT 'sqlite_schema'"
             " ORDER BY 1 collate nocase";
    }else{
-
      zSql = "SELECT lower(name) FROM sqlite_schema"
+
      zSql = "SELECT lower(name) as tname FROM sqlite_schema"
             " WHERE type='table' AND coalesce(rootpage,0)>1"
             " AND name NOT LIKE 'sqlite_%'"
             " ORDER BY 1 collate nocase";
@@ -24545,6 +25833,66 @@ static int do_meta_command(char *zLine, ShellState *p){
    }else{
      shell_exec(p, zSql, 0);
    }
+
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && !defined(SQLITE_OMIT_VIRTUALTABLE)
+
    {
+
      int lrc;
+
      char *zRevText = /* Query for reversible to-blob-to-text check */
+
        "SELECT lower(name) as tname FROM sqlite_schema\n"
+
        "WHERE type='table' AND coalesce(rootpage,0)>1\n"
+
        "AND name NOT LIKE 'sqlite_%%'%s\n"
+
        "ORDER BY 1 collate nocase";
+
      zRevText = sqlite3_mprintf(zRevText, zLike? " AND name LIKE $tspec" : "");
+
      zRevText = sqlite3_mprintf(
+
          /* lower-case query is first run, producing upper-case query. */
+
          "with tabcols as materialized(\n"
+
          "select tname, cname\n"
+
          "from ("
+
          " select ss.tname as tname, ti.name as cname\n"
+
          " from (%z) ss\n inner join pragma_table_info(tname) ti))\n"
+
          "select 'SELECT total(bad_text_count) AS bad_text_count\n"
+
          "FROM ('||group_concat(query, ' UNION ALL ')||')' as btc_query\n"
+
          " from (select 'SELECT COUNT(*) AS bad_text_count\n"
+
          "FROM '||tname||' WHERE '\n"
+
          "||group_concat('CAST(CAST('||cname||' AS BLOB) AS TEXT)<>'||cname\n"
+
          "|| ' AND typeof('||cname||')=''text'' ',\n"
+
          "' OR ') as query, tname from tabcols group by tname)"
+
          , zRevText);
+
      shell_check_oom(zRevText);
+
      if( bDebug ) utf8_printf(p->out, "%s\n", zRevText);
+
      lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0);
+
      if( lrc!=SQLITE_OK ){
+
        /* assert(lrc==SQLITE_NOMEM); // might also be SQLITE_ERROR if the
+
        ** user does cruel and unnatural things like ".limit expr_depth 0". */
+
        rc = 1;
+
      }else{
+
        if( zLike ) sqlite3_bind_text(pStmt,1,zLike,-1,SQLITE_STATIC);
+
        lrc = SQLITE_ROW==sqlite3_step(pStmt);
+
        if( lrc ){
+
          const char *zGenQuery = (char*)sqlite3_column_text(pStmt,0);
+
          sqlite3_stmt *pCheckStmt;
+
          lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0);
+
          if( bDebug ) utf8_printf(p->out, "%s\n", zGenQuery);
+
          if( lrc!=SQLITE_OK ){
+
            rc = 1;
+
          }else{
+
            if( SQLITE_ROW==sqlite3_step(pCheckStmt) ){
+
              double countIrreversible = sqlite3_column_double(pCheckStmt, 0);
+
              if( countIrreversible>0 ){
+
                int sz = (int)(countIrreversible + 0.5);
+
                utf8_printf(stderr,
+
                     "Digest includes %d invalidly encoded text field%s.\n",
+
                            sz, (sz>1)? "s": "");
+
              }
+
            }
+
            sqlite3_finalize(pCheckStmt);
+
          }
+
          sqlite3_finalize(pStmt);
+
        }
+
      }
+
      if( rc ) utf8_printf(stderr, ".sha3sum failed.\n");
+
      sqlite3_free(zRevText);
+
    }
+
#endif /* !defined(*_OMIT_SCHEMA_PRAGMAS) && !defined(*_OMIT_VIRTUALTABLE) */
    sqlite3_free(zSql);
  }else

@@ -24774,28 +26122,28 @@ static int do_meta_command(char *zLine, ShellState *p){
       int unSafe;              /* Not valid for --safe mode */
       const char *zUsage;      /* Usage notes */
    } aCtrl[] = {
-
      { "always",             SQLITE_TESTCTRL_ALWAYS, 1,     "BOOLEAN"         },
-
      { "assert",             SQLITE_TESTCTRL_ASSERT, 1,     "BOOLEAN"         },
-
    /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, ""        },*/
-
    /*{ "bitvec_test",        SQLITE_TESTCTRL_BITVEC_TEST, 1,  ""              },*/
-
      { "byteorder",          SQLITE_TESTCTRL_BYTEORDER, 0,  ""                },
-
      { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN"  },
-
    /*{ "fault_install",      SQLITE_TESTCTRL_FAULT_INSTALL, 1,""              },*/
-
      { "imposter",         SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
-
      { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,""          },
-
      { "localtime_fault",    SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN"      },
-
      { "never_corrupt",      SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN"       },
-
      { "optimizations",      SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK"   },
+
    {"always",             SQLITE_TESTCTRL_ALWAYS, 1,     "BOOLEAN"         },
+
    {"assert",             SQLITE_TESTCTRL_ASSERT, 1,     "BOOLEAN"         },
+
  /*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, ""        },*/
+
  /*{"bitvec_test",        SQLITE_TESTCTRL_BITVEC_TEST, 1,  ""              },*/
+
    {"byteorder",          SQLITE_TESTCTRL_BYTEORDER, 0,  ""                },
+
    {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN"  },
+
  /*{"fault_install",      SQLITE_TESTCTRL_FAULT_INSTALL, 1,""              },*/
+
    {"imposter",         SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
+
    {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,""          },
+
    {"localtime_fault",    SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN"      },
+
    {"never_corrupt",      SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN"       },
+
    {"optimizations",      SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK"   },
#ifdef YYCOVERAGE
-
      { "parser_coverage",    SQLITE_TESTCTRL_PARSER_COVERAGE,0,""             },
-
#endif
-
      { "pending_byte",       SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET  "       },
-
      { "prng_restore",       SQLITE_TESTCTRL_PRNG_RESTORE,0, ""               },
-
      { "prng_save",          SQLITE_TESTCTRL_PRNG_SAVE,   0, ""               },
-
      { "prng_seed",          SQLITE_TESTCTRL_PRNG_SEED,   0, "SEED ?db?"      },
-
      { "seek_count",         SQLITE_TESTCTRL_SEEK_COUNT,  0, ""               },
-
      { "sorter_mmap",        SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX"           },
-
      { "tune",               SQLITE_TESTCTRL_TUNE,        1, "ID VALUE"       },
+
    {"parser_coverage",    SQLITE_TESTCTRL_PARSER_COVERAGE,0,""             },
+
#endif
+
    {"pending_byte",       SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET  "       },
+
    {"prng_restore",       SQLITE_TESTCTRL_PRNG_RESTORE,0, ""               },
+
    {"prng_save",          SQLITE_TESTCTRL_PRNG_SAVE,   0, ""               },
+
    {"prng_seed",          SQLITE_TESTCTRL_PRNG_SEED,   0, "SEED ?db?"      },
+
    {"seek_count",         SQLITE_TESTCTRL_SEEK_COUNT,  0, ""               },
+
    {"sorter_mmap",        SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX"           },
+
    {"tune",               SQLITE_TESTCTRL_TUNE,        1, "ID VALUE"       },
    };
    int testctrl = -1;
    int iCtrl = -1;
@@ -24804,6 +26152,12 @@ static int do_meta_command(char *zLine, ShellState *p){
    int i, n2;
    const char *zCmd = 0;

+
    if( !ShellHasFlag(p,SHFLG_TestingMode) ){
+
      utf8_printf(stderr, ".%s unavailable without --unsafe-testing\n",
+
                  "testctrl");
+
      rc = 1;
+
      goto meta_command_exit;
+
    }
    open_db(p, 0);
    zCmd = nArg>=2 ? azArg[1] : "help";

@@ -25056,7 +26410,7 @@ static int do_meta_command(char *zLine, ShellState *p){
        }
      }else{
        output_file_close(p->traceOut);
-
        p->traceOut = output_file_open(azArg[1], 0);
+
        p->traceOut = output_file_open(z, 0);
      }
    }
    if( p->traceOut==0 ){
@@ -25220,7 +26574,7 @@ static int do_meta_command(char *zLine, ShellState *p){
  }else

  if( c=='w' && cli_strncmp(azArg[0], "wheretrace", n)==0 ){
-
    unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
+
    unsigned int x = nArg>=2? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
    sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
  }else

@@ -25272,7 +26626,8 @@ typedef enum {
** The scan is resumable for subsequent lines when prior
** return values are passed as the 2nd argument.
*/
-
static QuickScanState quickscan(char *zLine, QuickScanState qss){
+
static QuickScanState quickscan(char *zLine, QuickScanState qss,
+
                                SCAN_TRACKER_REFTYPE pst){
  char cin;
  char cWait = (char)qss; /* intentional narrowing loss */
  if( cWait==0 ){
@@ -25296,17 +26651,25 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss){
        if( *zLine=='*' ){
          ++zLine;
          cWait = '*';
+
          CONTINUE_PROMPT_AWAITS(pst, "/*");
          qss = QSS_SETV(qss, cWait);
          goto TermScan;
        }
        break;
      case '[':
        cin = ']';
-
        /* fall thru */
+
        deliberate_fall_through;
      case '`': case '\'': case '"':
        cWait = cin;
        qss = QSS_HasDark | cWait;
+
        CONTINUE_PROMPT_AWAITC(pst, cin);
        goto TermScan;
+
      case '(':
+
        CONTINUE_PAREN_INCR(pst, 1);
+
        break;
+
      case ')':
+
        CONTINUE_PAREN_INCR(pst, -1);
+
        break;
      default:
        break;
      }
@@ -25322,16 +26685,19 @@ static QuickScanState quickscan(char *zLine, QuickScanState qss){
            continue;
          ++zLine;
          cWait = 0;
+
          CONTINUE_PROMPT_AWAITC(pst, 0);
          qss = QSS_SETV(qss, 0);
          goto PlainScan;
        case '`': case '\'': case '"':
          if(*zLine==cWait){
+
            /* Swallow doubled end-delimiter.*/
            ++zLine;
            continue;
          }
-
          /* fall thru */
+
          deliberate_fall_through;
        case ']':
          cWait = 0;
+
          CONTINUE_PROMPT_AWAITC(pst, 0);
          qss = QSS_SETV(qss, 0);
          goto PlainScan;
        default: assert(0);
@@ -25355,17 +26721,15 @@ 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, 0)==QSS_Start;
}

/*
-
** We need a default sqlite3_complete() implementation to use in case
-
** the shell is compiled with SQLITE_OMIT_COMPLETE.  The default assumes
-
** any arbitrary text is a complete SQL statement.  This is not very
-
** user-friendly, but it does seem to work.
+
** The CLI needs a working sqlite3_complete() to work properly.  So error
+
** out of the build if compiling with SQLITE_OMIT_COMPLETE.
*/
#ifdef SQLITE_OMIT_COMPLETE
-
#define sqlite3_complete(x) 1
+
# error the CLI application is imcompatable with SQLITE_OMIT_COMPLETE.
#endif

/*
@@ -25438,9 +26802,9 @@ static void echo_group_input(ShellState *p, const char *zDo){

#ifdef SQLITE_SHELL_FIDDLE
/*
-
** 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).
+
** 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. */
@@ -25497,6 +26861,7 @@ static int process_input(ShellState *p){
  }
  ++p->inputNesting;
  p->lineno = 0;
+
  CONTINUE_PROMPT_RESET;
  while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
    fflush(p->out);
    zLine = one_input_line(p->in, zLine, nSql>0);
@@ -25515,7 +26880,7 @@ static int process_input(ShellState *p){
        && line_is_complete(zSql, nSql) ){
      memcpy(zLine,";",2);
    }
-
    qss = quickscan(zLine, qss);
+
    qss = quickscan(zLine, qss, CONTINUE_PROMPT_PSTATE);
    if( QSS_PLAINWHITE(qss) && nSql==0 ){
      /* Just swallow single-line whitespace */
      echo_group_input(p, zLine);
@@ -25523,6 +26888,7 @@ static int process_input(ShellState *p){
      continue;
    }
    if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
+
      CONTINUE_PROMPT_RESET;
      echo_group_input(p, zLine);
      if( zLine[0]=='.' ){
        rc = do_meta_command(zLine, p);
@@ -25558,6 +26924,7 @@ static int process_input(ShellState *p){
    if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
      echo_group_input(p, zSql);
      errCnt += runOneSqlLine(p, zSql, p->in, startline);
+
      CONTINUE_PROMPT_RESET;
      nSql = 0;
      if( p->outCount ){
        output_reset(p);
@@ -25577,6 +26944,7 @@ static int process_input(ShellState *p){
    /* This may be incomplete. Let the SQL parser deal with that. */
    echo_group_input(p, zSql);
    errCnt += runOneSqlLine(p, zSql, p->in, startline);
+
    CONTINUE_PROMPT_RESET;
  }
  free(zSql);
  free(zLine);
@@ -25598,7 +26966,7 @@ static char *find_home_dir(int clearFlag){
  if( home_dir ) return home_dir;

#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
-
     && !defined(__RTP__) && !defined(_WRS_KERNEL)
+
     && !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI)
  {
    struct passwd *pwent;
    uid_t uid = getuid();
@@ -25654,8 +27022,42 @@ static char *find_home_dir(int clearFlag){
}

/*
+
** On non-Windows platforms, look for $XDG_CONFIG_HOME.
+
** If ${XDG_CONFIG_HOME}/sqlite3/sqliterc is found, return
+
** the path to it, else return 0. The result is cached for
+
** subsequent calls.
+
*/
+
static const char *find_xdg_config(void){
+
#if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \
+
     || defined(__RTP__) || defined(_WRS_KERNEL)
+
  return 0;
+
#else
+
  static int alreadyTried = 0;
+
  static char *zConfig = 0;
+
  const char *zXdgHome;
+

+
  if( alreadyTried!=0 ){
+
    return zConfig;
+
  }
+
  alreadyTried = 1;
+
  zXdgHome = getenv("XDG_CONFIG_HOME");
+
  if( zXdgHome==0 ){
+
    return 0;
+
  }
+
  zConfig = sqlite3_mprintf("%s/sqlite3/sqliterc", zXdgHome);
+
  shell_check_oom(zConfig);
+
  if( access(zConfig,0)!=0 ){
+
    sqlite3_free(zConfig);
+
    zConfig = 0;
+
  }
+
  return zConfig;
+
#endif
+
}
+

+
/*
** Read input from the file given by sqliterc_override.  Or if that
-
** parameter is NULL, take input from ~/.sqliterc
+
** parameter is NULL, take input from the first of find_xdg_config()
+
** or ~/.sqliterc which is found.
**
** Returns the number of errors.
*/
@@ -25669,7 +27071,10 @@ static void process_sqliterc(
  FILE *inSaved = p->in;
  int savedLineno = p->lineno;

-
  if (sqliterc == NULL) {
+
  if( sqliterc == NULL ){
+
    sqliterc = find_xdg_config();
+
  }
+
  if( sqliterc == NULL ){
    home_dir = find_home_dir(0);
    if( home_dir==0 ){
      raw_printf(stderr, "-- warning: cannot find home directory;"
@@ -25700,6 +27105,7 @@ static void process_sqliterc(
** Show available command line options
*/
static const char zOptions[] =
+
  "   --                   treat no subsequent arguments as options\n"
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
  "   -A ARGS...           run \".archive ARGS\" and exit\n"
#endif
@@ -25751,6 +27157,10 @@ static const char zOptions[] =
  "   -stats               print memory stats before each finalize\n"
  "   -table               set output mode to 'table'\n"
  "   -tabs                set output mode to 'tabs'\n"
+
  "   -unsafe-testing      allow unsafe commands and modes for testing\n"
+
#if SHELL_WIN_UTF8_OPT
+
  "   -utf8                setup interactive console code page for UTF-8\n"
+
#endif
  "   -version             show SQLite version\n"
  "   -vfs NAME            use NAME as the default VFS\n"
#ifdef SQLITE_ENABLE_VFSTRACE
@@ -25762,9 +27172,9 @@ static const char zOptions[] =
;
static void usage(int showDetail){
  utf8_printf(stderr,
-
      "Usage: %s [OPTIONS] FILENAME [SQL]\n"
+
      "Usage: %s [OPTIONS] [FILENAME [SQL]]\n"
      "FILENAME is the name of an SQLite database. A new database is created\n"
-
      "if the file does not previously exist.\n", Argv0);
+
      "if the file does not previously exist. Defaults to :memory:.\n", Argv0);
  if( showDetail ){
    utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
  }else{
@@ -25796,9 +27206,11 @@ static void main_init(ShellState *data) {
  memcpy(data->rowSeparator,SEP_Row, 2);
  data->showHeader = 0;
  data->shellFlgs = SHFLG_Lookaside;
+
  sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
+
#if !defined(SQLITE_SHELL_FIDDLE)
  verify_uninitialized();
+
#endif
  sqlite3_config(SQLITE_CONFIG_URI, 1);
-
  sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
  sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
  sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
  sqlite3_snprintf(sizeof(continuePrompt), continuePrompt,"   ...> ");
@@ -25841,6 +27253,10 @@ static char *cmdline_option_value(int argc, char **argv, int i){
  return argv[i];
}

+
static void sayAbnormalExit(void){
+
  if( seenInterrupt ) fprintf(stderr, "Program interrupted.\n");
+
}
+

#ifndef SQLITE_SHELL_IS_UTF8
#  if (defined(_WIN32) || defined(WIN32)) \
   && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__)))
@@ -25861,7 +27277,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
  char **argv;
#endif
#ifdef SQLITE_DEBUG
-
  sqlite3_int64 mem_main_enter = sqlite3_memory_used();
+
  sqlite3_int64 mem_main_enter = 0;
#endif
  char *zErrMsg = 0;
#ifdef SQLITE_SHELL_FIDDLE
@@ -25875,15 +27291,15 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
  int warnInmemoryDb = 0;
  int readStdin = 1;
  int nCmd = 0;
+
  int nOptsEnd = argc;
  char **azCmd = 0;
  const char *zVfs = 0;           /* Value of -vfs command-line option */
#if !SQLITE_SHELL_IS_UTF8
  char **argvToFree = 0;
  int argcToFree = 0;
#endif
-

-
  setBinaryMode(stdin, 0);
  setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
+

#ifdef SQLITE_SHELL_FIDDLE
  stdin_is_interactive = 0;
  stdout_is_console = 1;
@@ -25892,7 +27308,13 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
  stdin_is_interactive = isatty(0);
  stdout_is_console = isatty(1);
#endif
-

+
#if SHELL_WIN_UTF8_OPT
+
  atexit(console_restore); /* Needs revision for CLI as library call */
+
#endif
+
  atexit(sayAbnormalExit);
+
#ifdef SQLITE_DEBUG
+
  mem_main_enter = sqlite3_memory_used();
+
#endif
#if !defined(_WIN32_WCE)
  if( getenv("SQLITE_DEBUG_BREAK") ){
    if( isatty(0) && isatty(2) ){
@@ -25913,6 +27335,14 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
    }
  }
#endif
+
  /* Register a valid signal handler early, before much else is done. */
+
#ifdef SIGINT
+
  signal(SIGINT, interrupt_handler);
+
#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
+
  if( !SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE) ){
+
    fprintf(stderr, "No ^C handler.\n");
+
  }
+
#endif

#if USE_SYSTEM_SQLITE+0!=1
  if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
@@ -25952,15 +27382,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
  assert( argc>=1 && argv && argv[0] );
  Argv0 = argv[0];

-
  /* Make sure we have a valid signal handler early, before anything
-
  ** else is done.
-
  */
-
#ifdef SIGINT
-
  signal(SIGINT, interrupt_handler);
-
#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
-
  SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
-
#endif
-

#ifdef SQLITE_SHELL_DBNAME_PROC
  {
    /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
@@ -25978,11 +27399,13 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
  ** the size of the alternative malloc heap,
  ** and the first command to execute.
  */
+
#ifndef SQLITE_SHELL_FIDDLE
  verify_uninitialized();
+
#endif
  for(i=1; i<argc; i++){
    char *z;
    z = argv[i];
-
    if( z[0]!='-' ){
+
    if( z[0]!='-' || i>nOptsEnd ){
      if( data.aAuxDb->zDbFilename==0 ){
        data.aAuxDb->zDbFilename = z;
      }else{
@@ -25994,9 +27417,13 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
        shell_check_oom(azCmd);
        azCmd[nCmd-1] = z;
      }
+
      continue;
    }
    if( z[1]=='-' ) z++;
-
    if( cli_strcmp(z,"-separator")==0
+
    if( cli_strcmp(z, "-")==0 ){
+
      nOptsEnd = i;
+
      continue;
+
    }else if( cli_strcmp(z,"-separator")==0
     || cli_strcmp(z,"-nullvalue")==0
     || cli_strcmp(z,"-newline")==0
     || cli_strcmp(z,"-cmd")==0
@@ -26018,6 +27445,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
      zSize = cmdline_option_value(argc, argv, ++i);
      szHeap = integerValue(zSize);
      if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
+
      verify_uninitialized();
      sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
#else
      (void)cmdline_option_value(argc, argv, ++i);
@@ -26031,6 +27459,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
      if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){
        n = 0xffffffffffffLL/sz;
      }
+
      verify_uninitialized();
      sqlite3_config(SQLITE_CONFIG_PAGECACHE,
                    (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
      data.shellFlgs |= SHFLG_Pagecache;
@@ -26040,11 +27469,13 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
      if( sz<0 ) sz = 0;
      n = (int)integerValue(cmdline_option_value(argc,argv,++i));
      if( n<0 ) n = 0;
+
      verify_uninitialized();
      sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
      if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
    }else if( cli_strcmp(z,"-threadsafe")==0 ){
      int n;
      n = (int)integerValue(cmdline_option_value(argc,argv,++i));
+
      verify_uninitialized();
      switch( n ){
         case 0:  sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);  break;
         case 2:  sqlite3_config(SQLITE_CONFIG_MULTITHREAD);   break;
@@ -26068,10 +27499,12 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
    }else if( cli_strcmp(z,"-mmap")==0 ){
      sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
+
      verify_uninitialized();
      sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
-
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
+
#if defined(SQLITE_ENABLE_SORTER_REFERENCES)
    }else if( cli_strcmp(z,"-sorterref")==0 ){
      sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
+
      verify_uninitialized();
      sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz);
#endif
    }else if( cli_strcmp(z,"-vfs")==0 ){
@@ -26105,11 +27538,15 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
    }else if( cli_strcmp(z,"-nonce")==0 ){
      free(data.zNonce);
      data.zNonce = strdup(argv[++i]);
+
    }else if( cli_strcmp(z,"-unsafe-testing")==0 ){
+
      ShellSetFlag(&data,SHFLG_TestingMode);
    }else if( cli_strcmp(z,"-safe")==0 ){
      /* no-op - catch this on the second pass */
    }
  }
+
#ifndef SQLITE_SHELL_FIDDLE
  verify_uninitialized();
+
#endif


#ifdef SQLITE_SHELL_INIT_PROC
@@ -26132,7 +27569,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
    if( pVfs ){
      sqlite3_vfs_register(pVfs, 1);
    }else{
-
      utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
+
      utf8_printf(stderr, "no such VFS: \"%s\"\n", zVfs);
      exit(1);
    }
  }
@@ -26173,7 +27610,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
  */
  for(i=1; i<argc; i++){
    char *z = argv[i];
-
    if( z[0]!='-' ) continue;
+
    if( z[0]!='-' || i>=nOptsEnd ) continue;
    if( z[1]=='-' ){ z++; }
    if( cli_strcmp(z,"-init")==0 ){
      i++;
@@ -26218,12 +27655,12 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
      data.openFlags |= SQLITE_OPEN_NOFOLLOW;
    }else if( cli_strcmp(z,"-ascii")==0 ){
      data.mode = MODE_Ascii;
-
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Unit);
-
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Record);
+
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Unit);
+
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Record);
    }else if( cli_strcmp(z,"-tabs")==0 ){
      data.mode = MODE_List;
-
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Tab);
-
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
+
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Tab);
+
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Row);
    }else if( cli_strcmp(z,"-separator")==0 ){
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
                       "%s",cmdline_option_value(argc,argv,++i));
@@ -26265,6 +27702,10 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
      stdin_is_interactive = 1;
    }else if( cli_strcmp(z,"-batch")==0 ){
      stdin_is_interactive = 0;
+
    }else if( cli_strcmp(z,"-utf8")==0 ){
+
#if SHELL_WIN_UTF8_OPT
+
      console_utf8 = 1;
+
#endif /* SHELL_WIN_UTF8_OPT */
    }else if( cli_strcmp(z,"-heap")==0 ){
      i++;
    }else if( cli_strcmp(z,"-pagecache")==0 ){
@@ -26335,6 +27776,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
#endif
    }else if( cli_strcmp(z,"-safe")==0 ){
      data.bSafeMode = data.bSafeModePersist = 1;
+
    }else if( cli_strcmp(z,"-unsafe-testing")==0 ){
+
      /* Acted upon in first pass. */
    }else{
      utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
      raw_printf(stderr,"Use -help for a list of options.\n");
@@ -26342,6 +27785,14 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
    }
    data.cMode = data.mode;
  }
+
#if SHELL_WIN_UTF8_OPT
+
  if( console_utf8 && stdin_is_interactive ){
+
    console_prepare();
+
  }else{
+
    setBinaryMode(stdin, 0);
+
    console_utf8 = 0;
+
  }
+
#endif

  if( !readStdin ){
    /* Run all arguments that do not begin with '-' as if they were separate
@@ -26357,6 +27808,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
        }
      }else{
        open_db(&data, 0);
+
        echo_group_input(&data, azCmd[i]);
        rc = shell_exec(&data, azCmd[i], &zErrMsg);
        if( zErrMsg || rc ){
          if( zErrMsg!=0 ){
modified external/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-
** version 3.40.0.  By combining all the individual C code files into this
+
** version 3.42.0.  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
@@ -123,6 +123,10 @@
#define SQLITE_4_BYTE_ALIGNED_MALLOC
#endif /* defined(_MSC_VER) && !defined(_WIN64) */

+
#if !defined(HAVE_LOG2) && defined(_MSC_VER) && _MSC_VER<1800
+
#define HAVE_LOG2 0
+
#endif /* !defined(HAVE_LOG2) && defined(_MSC_VER) && _MSC_VER<1800 */
+

#endif /* SQLITE_MSVC_H */

/************** End of msvc.h ************************************************/
@@ -452,9 +456,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-
#define SQLITE_VERSION        "3.40.0"
-
#define SQLITE_VERSION_NUMBER 3040000
-
#define SQLITE_SOURCE_ID      "2022-11-16 12:10:08 89c459e766ea7e9165d0beeb124708b955a4950d0f4792f457465d71b158d318"
+
#define SQLITE_VERSION        "3.42.0"
+
#define SQLITE_VERSION_NUMBER 3042000
+
#define SQLITE_SOURCE_ID      "2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0"

/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -869,6 +873,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_CONSTRAINT_DATATYPE     (SQLITE_CONSTRAINT |(12<<8))
#define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
+
#define SQLITE_NOTICE_RBU              (SQLITE_NOTICE | (3<<8))
#define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
@@ -1481,7 +1486,6 @@ struct sqlite3_io_methods {
** in wal mode after the client has finished copying pages from the wal
** file to the database file, but before the *-shm file is updated to
** record the fact that the pages have been checkpointed.
-
** </ul>
**
** <li>[[SQLITE_FCNTL_EXTERNAL_READER]]
** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect
@@ -1494,10 +1498,16 @@ struct sqlite3_io_methods {
** the database is not a wal-mode db, or if there is no such connection in any
** other process. This opcode cannot be used to detect transactions opened
** by clients within the current process, only within other processes.
-
** </ul>
**
** <li>[[SQLITE_FCNTL_CKSM_FILE]]
-
** Used by the cksmvfs VFS module only.
+
** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use interally by the
+
** [checksum VFS shim] only.
+
**
+
** <li>[[SQLITE_FCNTL_RESET_CACHE]]
+
** If there is currently no transaction open on the database, and the
+
** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control
+
** purges the contents of the in-memory page cache. If there is an open
+
** transaction, or if the db is a temp-db, this opcode is a no-op, not an error.
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE               1
@@ -1540,6 +1550,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_CKPT_START             39
#define SQLITE_FCNTL_EXTERNAL_READER        40
#define SQLITE_FCNTL_CKSM_FILE              41
+
#define SQLITE_FCNTL_RESET_CACHE            42

/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
@@ -1954,20 +1965,23 @@ SQLITE_API int sqlite3_os_end(void);
** must ensure that no other SQLite interfaces are invoked by other
** threads while sqlite3_config() is running.</b>
**
-
** The sqlite3_config() interface
-
** may only be invoked prior to library initialization using
-
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
-
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
-
** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
-
** Note, however, that ^sqlite3_config() can be called as part of the
-
** implementation of an application-defined [sqlite3_os_init()].
-
**
** The first argument to sqlite3_config() is an integer
** [configuration option] that determines
** what property of SQLite is to be configured.  Subsequent arguments
** vary depending on the [configuration option]
** in the first argument.
**
+
** For most configuration options, the sqlite3_config() interface
+
** may only be invoked prior to library initialization using
+
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
+
** The exceptional configuration options that may be invoked at any time
+
** are called "anytime configuration options".
+
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
+
** [sqlite3_shutdown()] with a first argument that is not an anytime
+
** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE.
+
** Note, however, that ^sqlite3_config() can be called as part of the
+
** implementation of an application-defined [sqlite3_os_init()].
+
**
** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
** ^If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
@@ -2075,6 +2089,23 @@ struct sqlite3_mem_methods {
** These constants are the available integer configuration options that
** can be passed as the first argument to the [sqlite3_config()] interface.
**
+
** Most of the configuration options for sqlite3_config()
+
** will only work if invoked prior to [sqlite3_initialize()] or after
+
** [sqlite3_shutdown()].  The few exceptions to this rule are called
+
** "anytime configuration options".
+
** ^Calling [sqlite3_config()] with a first argument that is not an
+
** anytime configuration option in between calls to [sqlite3_initialize()] and
+
** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE.
+
**
+
** The set of anytime configuration options can change (by insertions
+
** and/or deletions) from one release of SQLite to the next.
+
** As of SQLite version 3.42.0, the complete set of anytime configuration
+
** options is:
+
** <ul>
+
** <li> SQLITE_CONFIG_LOG
+
** <li> SQLITE_CONFIG_PCACHE_HDRSZ
+
** </ul>
+
**
** New configuration options may be added in future releases of SQLite.
** Existing configuration options might be discontinued.  Applications
** should check the return code from [sqlite3_config()] to make sure that
@@ -2421,28 +2452,28 @@ struct sqlite3_mem_methods {
** compile-time option is not set, then the default maximum is 1073741824.
** </dl>
*/
-
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
-
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
-
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
-
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
-
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
-
#define SQLITE_CONFIG_SCRATCH       6  /* No longer used */
-
#define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */
-
#define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
-
#define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
-
#define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
-
#define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
-
/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
-
#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
-
#define SQLITE_CONFIG_PCACHE       14  /* no-op */
-
#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
-
#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
-
#define SQLITE_CONFIG_URI          17  /* int */
-
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
-
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
+
#define SQLITE_CONFIG_SINGLETHREAD         1  /* nil */
+
#define SQLITE_CONFIG_MULTITHREAD          2  /* nil */
+
#define SQLITE_CONFIG_SERIALIZED           3  /* nil */
+
#define SQLITE_CONFIG_MALLOC               4  /* sqlite3_mem_methods* */
+
#define SQLITE_CONFIG_GETMALLOC            5  /* sqlite3_mem_methods* */
+
#define SQLITE_CONFIG_SCRATCH              6  /* No longer used */
+
#define SQLITE_CONFIG_PAGECACHE            7  /* void*, int sz, int N */
+
#define SQLITE_CONFIG_HEAP                 8  /* void*, int nByte, int min */
+
#define SQLITE_CONFIG_MEMSTATUS            9  /* boolean */
+
#define SQLITE_CONFIG_MUTEX               10  /* sqlite3_mutex_methods* */
+
#define SQLITE_CONFIG_GETMUTEX            11  /* sqlite3_mutex_methods* */
+
/* previously SQLITE_CONFIG_CHUNKALLOC    12 which is now unused. */
+
#define SQLITE_CONFIG_LOOKASIDE           13  /* int int */
+
#define SQLITE_CONFIG_PCACHE              14  /* no-op */
+
#define SQLITE_CONFIG_GETPCACHE           15  /* no-op */
+
#define SQLITE_CONFIG_LOG                 16  /* xFunc, void* */
+
#define SQLITE_CONFIG_URI                 17  /* int */
+
#define SQLITE_CONFIG_PCACHE2             18  /* sqlite3_pcache_methods2* */
+
#define SQLITE_CONFIG_GETPCACHE2          19  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
-
#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
-
#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
+
#define SQLITE_CONFIG_SQLLOG              21  /* xSqllog, void* */
+
#define SQLITE_CONFIG_MMAP_SIZE           22  /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
#define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
#define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
@@ -2483,7 +2514,7 @@ struct sqlite3_mem_methods {
** configuration for a database connection can only be changed when that
** connection is not currently using lookaside memory, or in other words
** when the "current value" returned by
-
** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero.
+
** [sqlite3_db_status](D,[SQLITE_DBSTATUS_LOOKASIDE_USED],...) is zero.
** Any attempt to change the lookaside memory configuration when lookaside
** memory is in use leaves the configuration unchanged and returns
** [SQLITE_BUSY].)^</dd>
@@ -2633,8 +2664,12 @@ struct sqlite3_mem_methods {
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
** </ol>
** Because resetting a database is destructive and irreversible, the
-
** process requires the use of this obscure API and multiple steps to help
-
** ensure that it does not happen by accident.
+
** process requires the use of this obscure API and multiple steps to
+
** help ensure that it does not happen by accident. Because this
+
** feature must be capable of resetting corrupt databases, and
+
** shutting down virtual tables may require access to that corrupt
+
** storage, the library must abandon any installed virtual tables
+
** without calling their xDestroy() methods.
**
** [[SQLITE_DBCONFIG_DEFENSIVE]] <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
@@ -2673,7 +2708,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_DBCONFIG_DQS_DML]]
-
** <dt>SQLITE_DBCONFIG_DQS_DML</td>
+
** <dt>SQLITE_DBCONFIG_DQS_DML</dt>
** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
** the legacy [double-quoted string literal] misfeature for DML statements
** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
@@ -2682,7 +2717,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_DBCONFIG_DQS_DDL]]
-
** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
+
** <dt>SQLITE_DBCONFIG_DQS_DDL</dt>
** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
** the legacy [double-quoted string literal] misfeature for DDL statements,
** such as CREATE TABLE and CREATE INDEX. The
@@ -2691,7 +2726,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]]
-
** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td>
+
** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</dt>
** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to
** assume that database schemas are untainted by malicious content.
** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite
@@ -2711,7 +2746,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]]
-
** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</td>
+
** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</dt>
** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates
** the legacy file format flag.  When activated, this flag causes all newly
** created database file to have a schema format version number (the 4-byte
@@ -2720,7 +2755,7 @@ struct sqlite3_mem_methods {
** any SQLite version back to 3.0.0 ([dateof:3.0.0]).  Without this setting,
** newly created databases are generally not understandable by SQLite versions
** prior to 3.3.0 ([dateof:3.3.0]).  As these words are written, there
-
** is now scarcely any need to generated database files that are compatible
+
** is now scarcely any need to generate database files that are compatible
** all the way back to version 3.0.0, and so this setting is of little
** practical use, but is provided so that SQLite can continue to claim the
** ability to generate new database files that are compatible with  version
@@ -2731,6 +2766,38 @@ struct sqlite3_mem_methods {
** not considered a bug since SQLite versions 3.3.0 and earlier do not support
** either generated columns or decending indexes.
** </dd>
+
**
+
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
+
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
+
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
+
** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
+
** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
+
** statistics. For statistics to be collected, the flag must be set on
+
** the database handle both when the SQL statement is prepared and when it
+
** is stepped. The flag is set (collection of statistics is enabled)
+
** by default.  This option takes two arguments: an integer and a pointer to
+
** an integer..  The first argument is 1, 0, or -1 to enable, disable, or
+
** leave unchanged the statement scanstatus option.  If the second argument
+
** is not NULL, then the value of the statement scanstatus setting after
+
** processing the first argument is written into the integer that the second
+
** argument points to.
+
** </dd>
+
**
+
** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]]
+
** <dt>SQLITE_DBCONFIG_REVERSE_SCANORDER</dt>
+
** <dd>The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order
+
** in which tables and indexes are scanned so that the scans start at the end
+
** and work toward the beginning rather than starting at the beginning and
+
** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the
+
** same as setting [PRAGMA reverse_unordered_selects].  This option takes
+
** two arguments which are an integer and a pointer to an integer.  The first
+
** argument is 1, 0, or -1 to enable, disable, or leave unchanged the
+
** reverse scan order flag, respectively.  If the second argument is not NULL,
+
** then 0 or 1 is written into the integer that the second argument points to
+
** depending on if the reverse scan order flag is set after processing the
+
** first argument.
+
** </dd>
+
**
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
@@ -2751,7 +2818,9 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_ENABLE_VIEW           1015 /* int int* */
#define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT    1016 /* int int* */
#define SQLITE_DBCONFIG_TRUSTED_SCHEMA        1017 /* int int* */
-
#define SQLITE_DBCONFIG_MAX                   1017 /* Largest DBCONFIG */
+
#define SQLITE_DBCONFIG_STMT_SCANSTATUS       1018 /* int int* */
+
#define SQLITE_DBCONFIG_REVERSE_SCANORDER     1019 /* int int* */
+
#define SQLITE_DBCONFIG_MAX                   1019 /* Largest DBCONFIG */

/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -2973,8 +3042,12 @@ SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*);
** ^A call to sqlite3_interrupt(D) that occurs when there are no running
** SQL statements is a no-op and has no effect on SQL statements
** that are started after the sqlite3_interrupt() call returns.
+
**
+
** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether
+
** or not an interrupt is currently in effect for [database connection] D.
*/
SQLITE_API void sqlite3_interrupt(sqlite3*);
+
SQLITE_API int sqlite3_is_interrupted(sqlite3*);

/*
** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -3592,8 +3665,8 @@ SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
** information as is provided by the [sqlite3_profile()] callback.
** ^The P argument is a pointer to the [prepared statement] and the
-
** X argument points to a 64-bit integer which is the estimated of
-
** the number of nanosecond that the prepared statement took to run.
+
** X argument points to a 64-bit integer which is approximately
+
** the number of nanoseconds that the prepared statement took to run.
** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
**
** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
@@ -3656,7 +3729,7 @@ SQLITE_API int sqlite3_trace_v2(
**
** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
** function X to be invoked periodically during long running calls to
-
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
+
** [sqlite3_step()] and [sqlite3_prepare()] and similar for
** database connection D.  An example use for this
** interface is to keep a GUI updated during a large query.
**
@@ -3681,6 +3754,13 @@ SQLITE_API int sqlite3_trace_v2(
** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their
** database connections for the meaning of "modify" in this paragraph.
**
+
** The progress handler callback would originally only be invoked from the
+
** bytecode engine.  It still might be invoked during [sqlite3_prepare()]
+
** and similar because those routines might force a reparse of the schema
+
** which involves running the bytecode engine.  However, beginning with
+
** SQLite version 3.41.0, the progress handler callback might also be
+
** invoked directly from [sqlite3_prepare()] while analyzing and generating
+
** code for complex queries.
*/
SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);

@@ -3717,13 +3797,18 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
**
** <dl>
** ^(<dt>[SQLITE_OPEN_READONLY]</dt>
-
** <dd>The database is opened in read-only mode.  If the database does not
-
** already exist, an error is returned.</dd>)^
+
** <dd>The database is opened in read-only mode.  If the database does
+
** not already exist, an error is returned.</dd>)^
**
** ^(<dt>[SQLITE_OPEN_READWRITE]</dt>
-
** <dd>The database is opened for reading and writing if possible, or reading
-
** only if the file is write protected by the operating system.  In either
-
** case the database must already exist, otherwise an error is returned.</dd>)^
+
** <dd>The database is opened for reading and writing if possible, or
+
** reading only if the file is write protected by the operating
+
** system.  In either case the database must already exist, otherwise
+
** an error is returned.  For historical reasons, if opening in
+
** read-write mode fails due to OS-level permissions, an attempt is
+
** made to open it in read-only mode. [sqlite3_db_readonly()] can be
+
** used to determine whether the database is actually
+
** read-write.</dd>)^
**
** ^(<dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
** <dd>The database is opened for reading and writing, and is created if
@@ -5704,10 +5789,21 @@ SQLITE_API int sqlite3_create_window_function(
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in
** schema structures such as [CHECK constraints], [DEFAULT clauses],
** [expression indexes], [partial indexes], or [generated columns].
-
** The SQLITE_DIRECTONLY flags is a security feature which is recommended
-
** for all [application-defined SQL functions], and especially for functions
-
** that have side-effects or that could potentially leak sensitive
-
** information.
+
** <p>
+
** The SQLITE_DIRECTONLY flag is recommended for any
+
** [application-defined SQL function]
+
** that has side-effects or that could potentially leak sensitive information.
+
** This will prevent attacks in which an application is tricked
+
** into using a database file that has had its schema surreptiously
+
** modified to invoke the application-defined function in ways that are
+
** harmful.
+
** <p>
+
** Some people say it is good practice to set SQLITE_DIRECTONLY on all
+
** [application-defined SQL functions], regardless of whether or not they
+
** are security sensitive, as doing so prevents those functions from being used
+
** inside of the database schema, and thus ensures that the database
+
** can be inspected and modified using generic tools (such as the [CLI])
+
** that do not have access to the application-defined functions.
** </dd>
**
** [[SQLITE_INNOCUOUS]] <dt>SQLITE_INNOCUOUS</dt><dd>
@@ -5848,16 +5944,6 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
** then the conversion is performed.  Otherwise no conversion occurs.
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
**
-
** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8],
-
** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current encoding
-
** of the value X, assuming that X has type TEXT.)^  If sqlite3_value_type(X)
-
** returns something other than SQLITE_TEXT, then the return value from
-
** sqlite3_value_encoding(X) is meaningless.  ^Calls to
-
** sqlite3_value_text(X), sqlite3_value_text16(X), sqlite3_value_text16be(X),
-
** sqlite3_value_text16le(X), sqlite3_value_bytes(X), or
-
** sqlite3_value_bytes16(X) might change the encoding of the value X and
-
** thus change the return from subsequent calls to sqlite3_value_encoding(X).
-
**
** ^Within the [xUpdate] method of a [virtual table], the
** sqlite3_value_nochange(X) interface returns true if and only if
** the column corresponding to X is unchanged by the UPDATE operation
@@ -5922,6 +6008,27 @@ SQLITE_API int sqlite3_value_type(sqlite3_value*);
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
+

+
/*
+
** CAPI3REF: Report the internal text encoding state of an sqlite3_value object
+
** METHOD: sqlite3_value
+
**
+
** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8],
+
** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current text encoding
+
** of the value X, assuming that X has type TEXT.)^  If sqlite3_value_type(X)
+
** returns something other than SQLITE_TEXT, then the return value from
+
** sqlite3_value_encoding(X) is meaningless.  ^Calls to
+
** [sqlite3_value_text(X)], [sqlite3_value_text16(X)], [sqlite3_value_text16be(X)],
+
** [sqlite3_value_text16le(X)], [sqlite3_value_bytes(X)], or
+
** [sqlite3_value_bytes16(X)] might change the encoding of the value X and
+
** thus change the return from subsequent calls to sqlite3_value_encoding(X).
+
**
+
** This routine is intended for used by applications that test and validate
+
** the SQLite implementation.  This routine is inquiring about the opaque
+
** internal state of an [sqlite3_value] object.  Ordinary applications should
+
** not need to know what the internal state of an sqlite3_value object is and
+
** hence should not need to use this interface.
+
*/
SQLITE_API int sqlite3_value_encoding(sqlite3_value*);

/*
@@ -6458,6 +6565,13 @@ SQLITE_API void sqlite3_activate_cerod(
** of the default VFS is not implemented correctly, or not implemented at
** all, then the behavior of sqlite3_sleep() may deviate from the description
** in the previous paragraphs.
+
**
+
** If a negative argument is passed to sqlite3_sleep() the results vary by
+
** VFS and operating system.  Some system treat a negative argument as an
+
** instruction to sleep forever.  Others understand it to mean do not sleep
+
** at all. ^In SQLite version 3.42.0 and later, a negative
+
** argument passed into sqlite3_sleep() is changed to zero before it is relayed
+
** down into the xSleep method of the VFS.
*/
SQLITE_API int sqlite3_sleep(int);

@@ -7303,15 +7417,6 @@ SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void));
SQLITE_API void sqlite3_reset_auto_extension(void);

/*
-
** The interface to the virtual-table mechanism is currently considered
-
** to be experimental.  The interface might change in incompatible ways.
-
** If this is a problem for you, do not use the interface at this time.
-
**
-
** When the virtual-table mechanism stabilizes, we will declare the
-
** interface fixed, support it indefinitely, and remove this comment.
-
*/
-

-
/*
** Structures used by the virtual table interface
*/
typedef struct sqlite3_vtab sqlite3_vtab;
@@ -7429,10 +7534,10 @@ struct sqlite3_module {
** when the omit flag is true there is no guarantee that the constraint will
** not be checked again using byte code.)^
**
-
** ^The idxNum and idxPtr values are recorded and passed into the
+
** ^The idxNum and idxStr values are recorded and passed into the
** [xFilter] method.
-
** ^[sqlite3_free()] is used to free idxPtr if and only if
-
** needToFreeIdxPtr is true.
+
** ^[sqlite3_free()] is used to free idxStr if and only if
+
** needToFreeIdxStr is true.
**
** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in
** the correct order to satisfy the ORDER BY clause so that no separate
@@ -7552,7 +7657,7 @@ struct sqlite3_index_info {
** the [sqlite3_vtab_collation()] interface.  For most real-world virtual
** tables, the collating sequence of constraints does not matter (for example
** because the constraints are numeric) and so the sqlite3_vtab_collation()
-
** interface is no commonly needed.
+
** interface is not commonly needed.
*/
#define SQLITE_INDEX_CONSTRAINT_EQ          2
#define SQLITE_INDEX_CONSTRAINT_GT          4
@@ -7712,16 +7817,6 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);

/*
-
** The interface to the virtual-table mechanism defined above (back up
-
** to a comment remarkably similar to this one) is currently considered
-
** to be experimental.  The interface might change in incompatible ways.
-
** If this is a problem for you, do not use the interface at this time.
-
**
-
** When the virtual-table mechanism stabilizes, we will declare the
-
** interface fixed, support it indefinitely, and remove this comment.
-
*/
-

-
/*
** CAPI3REF: A Handle To An Open BLOB
** KEYWORDS: {BLOB handle} {BLOB handles}
**
@@ -8104,9 +8199,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** is undefined if the mutex is not currently entered by the
** calling thread or is not currently allocated.
**
-
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
-
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
-
** behave as no-ops.
+
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(),
+
** sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer,
+
** then any of the four routines behaves as a no-op.
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
@@ -9840,18 +9935,28 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt>
** <dd>Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the
-
** the [xConnect] or [xCreate] methods of a [virtual table] implmentation
+
** the [xConnect] or [xCreate] methods of a [virtual table] implementation
** identify that virtual table as being safe to use from within triggers
** and views.  Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the
** virtual table can do no serious harm even if it is controlled by a
** malicious hacker.  Developers should avoid setting the SQLITE_VTAB_INNOCUOUS
** flag unless absolutely necessary.
** </dd>
+
**
+
** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]<dt>SQLITE_VTAB_USES_ALL_SCHEMAS</dt>
+
** <dd>Calls of the form
+
** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the
+
** the [xConnect] or [xCreate] methods of a [virtual table] implementation
+
** instruct the query planner to begin at least a read transaction on
+
** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the
+
** virtual table is used.
+
** </dd>
** </dl>
*/
#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
#define SQLITE_VTAB_INNOCUOUS          2
#define SQLITE_VTAB_DIRECTONLY         3
+
#define SQLITE_VTAB_USES_ALL_SCHEMAS   4

/*
** CAPI3REF: Determine The Virtual Table Conflict Policy
@@ -9924,7 +10029,7 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*);
** <li><p> Otherwise, "BINARY" is returned.
** </ol>
*/
-
SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int);
+
SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info*,int);

/*
** CAPI3REF: Determine if a virtual table query is DISTINCT
@@ -10081,21 +10186,20 @@ SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
** is undefined and probably harmful.
**
** The X parameter in a call to sqlite3_vtab_in_first(X,P) or
-
** sqlite3_vtab_in_next(X,P) must be one of the parameters to the
+
** sqlite3_vtab_in_next(X,P) should be one of the parameters to the
** xFilter method which invokes these routines, and specifically
** a parameter that was previously selected for all-at-once IN constraint
** processing use the [sqlite3_vtab_in()] interface in the
** [xBestIndex|xBestIndex method].  ^(If the X parameter is not
** an xFilter argument that was selected for all-at-once IN constraint
-
** processing, then these routines return [SQLITE_MISUSE])^ or perhaps
-
** exhibit some other undefined or harmful behavior.
+
** processing, then these routines return [SQLITE_ERROR].)^
**
** ^(Use these routines to access all values on the right-hand side
** of the IN constraint using code like the following:
**
** <blockquote><pre>
** &nbsp;  for(rc=sqlite3_vtab_in_first(pList, &pVal);
-
** &nbsp;      rc==SQLITE_OK && pVal
+
** &nbsp;      rc==SQLITE_OK && pVal;
** &nbsp;      rc=sqlite3_vtab_in_next(pList, &pVal)
** &nbsp;  ){
** &nbsp;    // do something with pVal
@@ -10193,6 +10297,10 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
** managed by the prepared statement S and will be automatically freed when
** S is finalized.
**
+
** Not all values are available for all query elements. When a value is
+
** not available, the output variable is set to -1 if the value is numeric,
+
** or to NULL if it is a string (SQLITE_SCANSTAT_NAME).
+
**
** <dl>
** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
** <dd>^The [sqlite3_int64] variable pointed to by the V parameter will be
@@ -10220,12 +10328,24 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
** description for the X-th loop.
**
-
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
+
** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECTID</dt>
** <dd>^The "int" variable pointed to by the V parameter will be set to the
-
** "select-id" for the X-th loop.  The select-id identifies which query or
-
** subquery the loop is part of.  The main query has a select-id of zero.
-
** The select-id is the same value as is output in the first column
-
** of an [EXPLAIN QUERY PLAN] query.
+
** id for the X-th query plan element. The id value is unique within the
+
** statement. The select-id is the same value as is output in the first
+
** column of an [EXPLAIN QUERY PLAN] query.
+
**
+
** [[SQLITE_SCANSTAT_PARENTID]] <dt>SQLITE_SCANSTAT_PARENTID</dt>
+
** <dd>The "int" variable pointed to by the V parameter will be set to the
+
** the id of the parent of the current query element, if applicable, or
+
** to zero if the query element has no parent. This is the same value as
+
** returned in the second column of an [EXPLAIN QUERY PLAN] query.
+
**
+
** [[SQLITE_SCANSTAT_NCYCLE]] <dt>SQLITE_SCANSTAT_NCYCLE</dt>
+
** <dd>The sqlite3_int64 output value is set to the number of cycles,
+
** according to the processor time-stamp counter, that elapsed while the
+
** query element was being processed. This value is not available for
+
** all query elements - if it is unavailable the output variable is
+
** set to -1.
** </dl>
*/
#define SQLITE_SCANSTAT_NLOOP    0
@@ -10234,12 +10354,14 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
#define SQLITE_SCANSTAT_NAME     3
#define SQLITE_SCANSTAT_EXPLAIN  4
#define SQLITE_SCANSTAT_SELECTID 5
+
#define SQLITE_SCANSTAT_PARENTID 6
+
#define SQLITE_SCANSTAT_NCYCLE   7

/*
** CAPI3REF: Prepared Statement Scan Status
** METHOD: sqlite3_stmt
**
-
** This interface returns information about the predicted and measured
+
** These interfaces return information about the predicted and measured
** performance for pStmt.  Advanced applications can use this
** interface to compare the predicted and the measured performance and
** issue warnings and/or rerun [ANALYZE] if discrepancies are found.
@@ -10250,19 +10372,25 @@ SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **
**
** The "iScanStatusOp" parameter determines which status information to return.
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
-
** of this interface is undefined.
-
** ^The requested measurement is written into a variable pointed to by
-
** the "pOut" parameter.
-
** Parameter "idx" identifies the specific loop to retrieve statistics for.
-
** Loops are numbered starting from zero. ^If idx is out of range - less than
-
** zero or greater than or equal to the total number of loops used to implement
-
** the statement - a non-zero value is returned and the variable that pOut
-
** points to is unchanged.
-
**
-
** ^Statistics might not be available for all loops in all statements. ^In cases
-
** where there exist loops with no available statistics, this function behaves
-
** as if the loop did not exist - it returns non-zero and leave the variable
-
** that pOut points to unchanged.
+
** of this interface is undefined. ^The requested measurement is written into
+
** a variable pointed to by the "pOut" parameter.
+
**
+
** The "flags" parameter must be passed a mask of flags. At present only
+
** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX
+
** is specified, then status information is available for all elements
+
** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If
+
** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements
+
** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of
+
** the EXPLAIN QUERY PLAN output) are available. Invoking API
+
** sqlite3_stmt_scanstatus() is equivalent to calling
+
** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.
+
**
+
** Parameter "idx" identifies the specific query element to retrieve statistics
+
** for. Query elements are numbered starting from zero. A value of -1 may be
+
** to query for statistics regarding the entire query. ^If idx is out of range
+
** - less than -1 or greater than or equal to the total number of query
+
** elements used to implement the statement - a non-zero value is returned and
+
** the variable that pOut points to is unchanged.
**
** See also: [sqlite3_stmt_scanstatus_reset()]
*/
@@ -10272,6 +10400,19 @@ SQLITE_API int sqlite3_stmt_scanstatus(
  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
  void *pOut                /* Result written here */
);
+
SQLITE_API int sqlite3_stmt_scanstatus_v2(
+
  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
+
  int idx,                  /* Index of loop to report on */
+
  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
+
  int flags,                /* Mask of flags defined below */
+
  void *pOut                /* Result written here */
+
);
+

+
/*
+
** CAPI3REF: Prepared Statement Scan Status
+
** KEYWORDS: {scan status flags}
+
*/
+
#define SQLITE_SCANSTAT_COMPLEX 0x0001

/*
** CAPI3REF: Zero Scan-Status Counters
@@ -10362,6 +10503,10 @@ SQLITE_API int sqlite3_db_cacheflush(sqlite3*);
** function is not defined for operations on WITHOUT ROWID tables, or for
** DELETE operations on rowid tables.
**
+
** ^The sqlite3_preupdate_hook(D,C,P) function returns the P argument from
+
** the previous call on the same [database connection] D, or NULL for
+
** the first call on D.
+
**
** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()],
** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces
** provide additional information about a preupdate event. These routines
@@ -10767,6 +10912,19 @@ SQLITE_API int sqlite3_deserialize(
# undef double
#endif

+
#if defined(__wasi__)
+
# undef SQLITE_WASI
+
# define SQLITE_WASI 1
+
# undef SQLITE_OMIT_WAL
+
# define SQLITE_OMIT_WAL 1/* because it requires shared memory APIs */
+
# ifndef SQLITE_OMIT_LOAD_EXTENSION
+
#  define SQLITE_OMIT_LOAD_EXTENSION
+
# endif
+
# ifndef SQLITE_THREADSAFE
+
#  define SQLITE_THREADSAFE 0
+
# endif
+
#endif
+

#if 0
}  /* End of the 'extern "C"' block */
#endif
@@ -10973,16 +11131,20 @@ SQLITE_API int sqlite3session_create(
SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);

/*
-
** CAPIREF: Conigure a Session Object
+
** CAPI3REF: Configure a Session Object
** METHOD: sqlite3_session
**
** This method is used to configure a session object after it has been
-
** created. At present the only valid value for the second parameter is
-
** [SQLITE_SESSION_OBJCONFIG_SIZE].
+
** created. At present the only valid values for the second parameter are
+
** [SQLITE_SESSION_OBJCONFIG_SIZE] and [SQLITE_SESSION_OBJCONFIG_ROWID].
**
-
** Arguments for sqlite3session_object_config()
+
*/
+
SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
+

+
/*
+
** CAPI3REF: Options for sqlite3session_object_config
**
-
** The following values may passed as the the 4th parameter to
+
** The following values may passed as the the 2nd parameter to
** sqlite3session_object_config().
**
** <dt>SQLITE_SESSION_OBJCONFIG_SIZE <dd>
@@ -10998,12 +11160,21 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
**
**   It is an error (SQLITE_MISUSE) to attempt to modify this setting after
**   the first table has been attached to the session object.
+
**
+
** <dt>SQLITE_SESSION_OBJCONFIG_ROWID <dd>
+
**   This option is used to set, clear or query the flag that enables
+
**   collection of data for tables with no explicit PRIMARY KEY.
+
**
+
**   Normally, tables with no explicit PRIMARY KEY are simply ignored
+
**   by the sessions module. However, if this flag is set, it behaves
+
**   as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted
+
**   as their leftmost columns.
+
**
+
**   It is an error (SQLITE_MISUSE) to attempt to modify this setting after
+
**   the first table has been attached to the session object.
*/
-
SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
-

-
/*
-
*/
-
#define SQLITE_SESSION_OBJCONFIG_SIZE 1
+
#define SQLITE_SESSION_OBJCONFIG_SIZE  1
+
#define SQLITE_SESSION_OBJCONFIG_ROWID 2

/*
** CAPI3REF: Enable Or Disable A Session Object
@@ -12136,9 +12307,23 @@ SQLITE_API int sqlite3changeset_apply_v2(
**   Invert the changeset before applying it. This is equivalent to inverting
**   a changeset using sqlite3changeset_invert() before applying it. It is
**   an error to specify this flag with a patchset.
+
**
+
** <dt>SQLITE_CHANGESETAPPLY_IGNORENOOP <dd>
+
**   Do not invoke the conflict handler callback for any changes that
+
**   would not actually modify the database even if they were applied.
+
**   Specifically, this means that the conflict handler is not invoked
+
**   for:
+
**    <ul>
+
**    <li>a delete change if the row being deleted cannot be found,
+
**    <li>an update change if the modified fields are already set to
+
**        their new values in the conflicting row, or
+
**    <li>an insert change if all fields of the conflicting row match
+
**        the row being inserted.
+
**    </ul>
*/
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001
#define SQLITE_CHANGESETAPPLY_INVERT        0x0002
+
#define SQLITE_CHANGESETAPPLY_IGNORENOOP    0x0004

/*
** CAPI3REF: Constants Passed To The Conflict Handler
@@ -13435,8 +13620,8 @@ struct fts5_api {
#endif

/*
-
** WAL mode depends on atomic aligned 32-bit loads and stores in a few
-
** places.  The following macros try to make this explicit.
+
** A few places in the code require atomic load/store of aligned
+
** integer values.
*/
#ifndef __has_extension
# define __has_extension(x) 0     /* compatibility with non-clang compilers */
@@ -13492,15 +13677,22 @@ struct fts5_api {
#endif

/*
-
** A macro to hint to the compiler that a function should not be
+
** Macros to hint to the compiler that a function should or should not be
** inlined.
*/
#if defined(__GNUC__)
#  define SQLITE_NOINLINE  __attribute__((noinline))
+
#  define SQLITE_INLINE    __attribute__((always_inline)) inline
#elif defined(_MSC_VER) && _MSC_VER>=1310
#  define SQLITE_NOINLINE  __declspec(noinline)
+
#  define SQLITE_INLINE    __forceinline
#else
#  define SQLITE_NOINLINE
+
#  define SQLITE_INLINE
+
#endif
+
#if defined(SQLITE_COVERAGE_TEST) || defined(__STRICT_ANSI__)
+
# undef SQLITE_INLINE
+
# define SQLITE_INLINE
#endif

/*
@@ -14318,15 +14510,9 @@ typedef INT8_TYPE i8; /* 1-byte signed integer */

/*
** The datatype used to store estimates of the number of rows in a
-
** table or index.  This is an unsigned integer type.  For 99.9% of
-
** the world, a 32-bit integer is sufficient.  But a 64-bit integer
-
** can be used at compile-time if desired.
+
** table or index.
*/
-
#ifdef SQLITE_64BIT_STATS
-
 typedef u64 tRowcnt;    /* 64-bit only if requested at compile-time */
-
#else
-
 typedef u32 tRowcnt;    /* 32-bit is the default */
-
#endif
+
typedef u64 tRowcnt;

/*
** Estimated quantities used for query planning are stored as 16-bit
@@ -14472,9 +14658,9 @@ typedef INT16_TYPE LogEst;
** pointers.  In that case, only verify 4-byte alignment.
*/
#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
-
# define EIGHT_BYTE_ALIGNMENT(X)   ((((char*)(X) - (char*)0)&3)==0)
+
# define EIGHT_BYTE_ALIGNMENT(X)   ((((uptr)(X) - (uptr)0)&3)==0)
#else
-
# define EIGHT_BYTE_ALIGNMENT(X)   ((((char*)(X) - (char*)0)&7)==0)
+
# define EIGHT_BYTE_ALIGNMENT(X)   ((((uptr)(X) - (uptr)0)&7)==0)
#endif

/*
@@ -14528,15 +14714,38 @@ SQLITE_PRIVATE u32 sqlite3TreeTrace;
    && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE) \
                             || defined(SQLITE_ENABLE_TREETRACE))
# define TREETRACE_ENABLED 1
-
# define SELECTTRACE(K,P,S,X)  \
+
# define TREETRACE(K,P,S,X)  \
  if(sqlite3TreeTrace&(K))   \
    sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\
    sqlite3DebugPrintf X
#else
-
# define SELECTTRACE(K,P,S,X)
+
# define TREETRACE(K,P,S,X)
# define TREETRACE_ENABLED 0
#endif

+
/* TREETRACE flag meanings:
+
**
+
**   0x00000001     Beginning and end of SELECT processing
+
**   0x00000002     WHERE clause processing
+
**   0x00000004     Query flattener
+
**   0x00000008     Result-set wildcard expansion
+
**   0x00000010     Query name resolution
+
**   0x00000020     Aggregate analysis
+
**   0x00000040     Window functions
+
**   0x00000080     Generated column names
+
**   0x00000100     Move HAVING terms into WHERE
+
**   0x00000200     Count-of-view optimization
+
**   0x00000400     Compound SELECT processing
+
**   0x00000800     Drop superfluous ORDER BY
+
**   0x00001000     LEFT JOIN simplifies to JOIN
+
**   0x00002000     Constant propagation
+
**   0x00004000     Push-down optimization
+
**   0x00008000     After all FROM-clause analysis
+
**   0x00010000     Beginning of DELETE/INSERT/UPDATE processing
+
**   0x00020000     Transform DISTINCT into GROUP BY
+
**   0x00040000     SELECT tree dump after all code has been generated
+
*/
+

/*
** Macros for "wheretrace"
*/
@@ -14549,6 +14758,36 @@ SQLITE_PRIVATE u32 sqlite3WhereTrace;
# define WHERETRACE(K,X)
#endif

+
/*
+
** Bits for the sqlite3WhereTrace mask:
+
**
+
** (---any--)   Top-level block structure
+
** 0x-------F   High-level debug messages
+
** 0x----FFF-   More detail
+
** 0xFFFF----   Low-level debug messages
+
**
+
** 0x00000001   Code generation
+
** 0x00000002   Solver
+
** 0x00000004   Solver costs
+
** 0x00000008   WhereLoop inserts
+
**
+
** 0x00000010   Display sqlite3_index_info xBestIndex calls
+
** 0x00000020   Range an equality scan metrics
+
** 0x00000040   IN operator decisions
+
** 0x00000080   WhereLoop cost adjustements
+
** 0x00000100
+
** 0x00000200   Covering index decisions
+
** 0x00000400   OR optimization
+
** 0x00000800   Index scanner
+
** 0x00001000   More details associated with code generation
+
** 0x00002000
+
** 0x00004000   Show all WHERE terms at key points
+
** 0x00008000   Show the full SELECT statement at key places
+
**
+
** 0x00010000   Show more detail when printing WHERE terms
+
** 0x00020000   Show WHERE terms returned from whereScanNext()
+
*/
+


/*
** An instance of the following structure is used to store the busy-handler
@@ -15529,7 +15768,7 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
**     reduce network bandwidth.
**
** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by
-
** standard SQLite.  The other hints are provided for extentions that use
+
** standard SQLite.  The other hints are provided for extensions that use
** the SQLite parser and code generator but substitute their own storage
** engine.
*/
@@ -15675,7 +15914,15 @@ SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt);
SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*);
SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*);

-
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,Pgno*aRoot,int nRoot,int,int*);
+
SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck(
+
  sqlite3 *db,  /* Database connection that is running the check */
+
  Btree *p,     /* The btree to be checked */
+
  Pgno *aRoot,  /* An array of root pages numbers for individual trees */
+
  int nRoot,    /* Number of entries in aRoot[] */
+
  int mxErr,    /* Stop reporting errors after this many */
+
  int *pnErr,   /* OUT: Write number of errors seen to this variable */
+
  char **pzOut  /* OUT: Write the error message string here */
+
);
SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*);

@@ -15714,6 +15961,8 @@ SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *);

SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64);

+
SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree*);
+

/*
** If we are not using shared cache, then there is no need to
** use mutexes to access the BtShared structures.  So make the
@@ -15830,14 +16079,14 @@ struct VdbeOp {
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  char *zComment;          /* Comment to improve readability */
#endif
-
#ifdef VDBE_PROFILE
-
  u32 cnt;                 /* Number of times this instruction was executed */
-
  u64 cycles;              /* Total time spent executing this instruction */
-
#endif
#ifdef SQLITE_VDBE_COVERAGE
  u32 iSrcLine;            /* Source-code line that generated this opcode
                           ** with flags in the upper 8 bits */
#endif
+
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE)
+
  u64 nExec;
+
  u64 nCycle;
+
#endif
};
typedef struct VdbeOp VdbeOp;

@@ -16128,29 +16377,30 @@ typedef struct VdbeOpList VdbeOpList;
#define OPFLG_IN3         0x08  /* in3:   P3 is an input */
#define OPFLG_OUT2        0x10  /* out2:  P2 is an output */
#define OPFLG_OUT3        0x20  /* out3:  P3 is an output */
+
#define OPFLG_NCYCLE      0x40  /* ncycle:Cycles count against P1 */
#define OPFLG_INITIALIZER {\
-
/*   0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\
+
/*   0 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x41, 0x00,\
/*   8 */ 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x01, 0x01,\
-
/*  16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x09, 0x09, 0x09,\
-
/*  24 */ 0x09, 0x01, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,\
-
/*  32 */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
-
/*  40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x01, 0x23, 0x0b,\
+
/*  16 */ 0x03, 0x03, 0x01, 0x12, 0x01, 0x49, 0x49, 0x49,\
+
/*  24 */ 0x49, 0x01, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,\
+
/*  32 */ 0x41, 0x01, 0x01, 0x01, 0x41, 0x01, 0x41, 0x41,\
+
/*  40 */ 0x41, 0x41, 0x41, 0x26, 0x26, 0x41, 0x23, 0x0b,\
/*  48 */ 0x01, 0x01, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
-
/*  56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x01,\
+
/*  56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x03, 0x01, 0x41,\
/*  64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
/*  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,\
+
/*  88 */ 0x02, 0x00, 0x00, 0x12, 0x1e, 0x20, 0x40, 0x00,\
+
/*  96 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 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, 0x00, 0x10, 0x10,\
-
/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
-
/* 136 */ 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00,\
+
/* 112 */ 0x40, 0x00, 0x12, 0x40, 0x40, 0x10, 0x40, 0x00,\
+
/* 120 */ 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x10, 0x10,\
+
/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,\
+
/* 136 */ 0x00, 0x40, 0x04, 0x04, 0x00, 0x40, 0x50, 0x40,\
/* 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,\
+
/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x50, 0x40,\
/* 176 */ 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00, 0x00,\
/* 184 */ 0x00, 0x00, 0x00,}

@@ -16205,14 +16455,20 @@ SQLITE_PRIVATE void sqlite3VdbeNoJumpsOutsideSubrtn(Vdbe*,int,int,int);
#endif
SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno);
#ifndef SQLITE_OMIT_EXPLAIN
-
SQLITE_PRIVATE   void sqlite3VdbeExplain(Parse*,u8,const char*,...);
+
SQLITE_PRIVATE   int sqlite3VdbeExplain(Parse*,u8,const char*,...);
SQLITE_PRIVATE   void sqlite3VdbeExplainPop(Parse*);
SQLITE_PRIVATE   int sqlite3VdbeExplainParent(Parse*);
# define ExplainQueryPlan(P)        sqlite3VdbeExplain P
+
# ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
#  define ExplainQueryPlan2(V,P)     (V = sqlite3VdbeExplain P)
+
# else
+
#  define ExplainQueryPlan2(V,P)     ExplainQueryPlan(P)
+
# endif
# define ExplainQueryPlanPop(P)     sqlite3VdbeExplainPop(P)
# define ExplainQueryPlanParent(P)  sqlite3VdbeExplainParent(P)
#else
# define ExplainQueryPlan(P)
+
# define ExplainQueryPlan2(V,P)
# define ExplainQueryPlanPop(P)
# define ExplainQueryPlanParent(P) 0
# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
@@ -16385,14 +16641,22 @@ SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int);

#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*);
+
SQLITE_PRIVATE void sqlite3VdbeScanStatusRange(Vdbe*, int, int, int);
+
SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters(Vdbe*, int, int, int);
#else
-
# define sqlite3VdbeScanStatus(a,b,c,d,e)
+
# define sqlite3VdbeScanStatus(a,b,c,d,e,f)
+
# define sqlite3VdbeScanStatusRange(a,b,c,d)
+
# define sqlite3VdbeScanStatusCounters(a,b,c,d)
#endif

#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*);
#endif

+
#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG)
+
SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr);
+
#endif
+

#endif /* SQLITE_VDBE_H */

/************** End of vdbe.h ************************************************/
@@ -16441,7 +16705,7 @@ struct PgHdr {
  ** private to pcache.c and should not be accessed by other modules.
  ** pCache is grouped with the public elements for efficiency.
  */
-
  i16 nRef;                      /* Number of users of this page */
+
  i64 nRef;                      /* Number of users of this page */
  PgHdr *pDirtyNext;             /* Next element in list of dirty pages */
  PgHdr *pDirtyPrev;             /* Previous element in list of dirty pages */
                          /* NB: pDirtyNext and pDirtyPrev are undefined if the
@@ -16522,12 +16786,12 @@ SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *);
SQLITE_PRIVATE void sqlite3PcacheClear(PCache*);

/* Return the total number of outstanding page references */
-
SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*);
+
SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache*);

/* Increment the reference count of an existing page */
SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*);

-
SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*);
+
SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr*);

/* Return the total number of pages stored in the cache */
SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*);
@@ -17102,7 +17366,7 @@ struct sqlite3 {
#define SQLITE_NullCallback   0x00000100  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_IgnoreChecks   0x00000200  /* Do not enforce check constraints */
-
#define SQLITE_ReadUncommit   0x00000400  /* READ UNCOMMITTED in shared-cache */
+
#define SQLITE_StmtScanStatus 0x00000400  /* Enable stmt_scanstats() counters */
#define SQLITE_NoCkptOnClose  0x00000800  /* No checkpoint on close()/DETACH */
#define SQLITE_ReverseOrder   0x00001000  /* Reverse unordered SELECTs */
#define SQLITE_RecTriggers    0x00002000  /* Enable recursive triggers */
@@ -17128,6 +17392,7 @@ struct sqlite3 {
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_CorruptRdOnly  HI(0x00002) /* Prohibit writes due to error */
+
#define SQLITE_ReadUncommit   HI(0x00004) /* READ UNCOMMITTED in shared-cache */

/* Flags used only if debugging */
#ifdef SQLITE_DEBUG
@@ -17183,6 +17448,8 @@ struct sqlite3 {
#define SQLITE_FlttnUnionAll  0x00800000 /* Disable the UNION ALL flattener */
   /* TH3 expects this value  ^^^^^^^^^^ See flatten04.test */
#define SQLITE_IndexedExpr    0x01000000 /* Pull exprs from index when able */
+
#define SQLITE_Coroutines     0x02000000 /* Co-routines for subqueries */
+
#define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */
#define SQLITE_AllOpts        0xffffffff /* All optimizations */

/*
@@ -17267,8 +17534,14 @@ struct FuncDestructor {
**     SQLITE_FUNC_TYPEOF      ==  OPFLAG_TYPEOFARG
**     SQLITE_FUNC_CONSTANT    ==  SQLITE_DETERMINISTIC from the API
**     SQLITE_FUNC_DIRECT      ==  SQLITE_DIRECTONLY from the API
-
**     SQLITE_FUNC_UNSAFE      ==  SQLITE_INNOCUOUS
+
**     SQLITE_FUNC_UNSAFE      ==  SQLITE_INNOCUOUS  -- opposite meanings!!!
**     SQLITE_FUNC_ENCMASK   depends on SQLITE_UTF* macros in the API
+
**
+
** Note that even though SQLITE_FUNC_UNSAFE and SQLITE_INNOCUOUS have the
+
** same bit value, their meanings are inverted.  SQLITE_FUNC_UNSAFE is
+
** used internally and if set means tha the function has side effects.
+
** SQLITE_INNOCUOUS is used by application code and means "not unsafe".
+
** See multiple instances of tag-20230109-1.
*/
#define SQLITE_FUNC_ENCMASK  0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */
#define SQLITE_FUNC_LIKE     0x0004 /* Candidate for the LIKE optimization */
@@ -17385,7 +17658,7 @@ struct FuncDestructor {
  {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
   xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
#define JFUNCTION(zName, nArg, iArg, xFunc) \
-
  {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|\
+
  {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|\
   SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
   SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define INLINE_FUNC(zName, nArg, iArg, mFlags) \
@@ -17577,6 +17850,7 @@ struct CollSeq {
#define SQLITE_AFF_NUMERIC  0x43  /* 'C' */
#define SQLITE_AFF_INTEGER  0x44  /* 'D' */
#define SQLITE_AFF_REAL     0x45  /* 'E' */
+
#define SQLITE_AFF_FLEXNUM  0x46  /* 'F' */

#define sqlite3IsNumericAffinity(X)  ((X)>=SQLITE_AFF_NUMERIC)

@@ -17647,6 +17921,7 @@ struct VTable {
  sqlite3_vtab *pVtab;      /* Pointer to vtab instance */
  int nRef;                 /* Number of pointers to this structure */
  u8 bConstraint;           /* True if constraints are supported */
+
  u8 bAllSchemas;           /* True if might use any attached schema */
  u8 eVtabRisk;             /* Riskiness of allowing hacker access */
  int iSavepoint;           /* Depth of the SAVEPOINT stack */
  VTable *pNext;            /* Next in linked list (see above) */
@@ -18027,6 +18302,7 @@ struct Index {
                           ** expression, or a reference to a VIRTUAL column */
#ifdef SQLITE_ENABLE_STAT4
  int nSample;             /* Number of elements in aSample[] */
+
  int mxSample;            /* Number of slots allocated to aSample[] */
  int nSampleCol;          /* Size of IndexSample.anEq[] and so on */
  tRowcnt *aAvgEq;         /* Average nEq values for keys not in aSample */
  IndexSample *aSample;    /* Samples of the left-most key */
@@ -18108,16 +18384,15 @@ struct AggInfo {
                          ** from source tables rather than from accumulators */
  u8 useSortingIdx;       /* In direct mode, reference the sorting index rather
                          ** than the source table */
+
  u16 nSortingColumn;     /* Number of columns in the sorting index */
  int sortingIdx;         /* Cursor number of the sorting index */
  int sortingIdxPTab;     /* Cursor number of pseudo-table */
-
  int nSortingColumn;     /* Number of columns in the sorting index */
-
  int mnReg, mxReg;       /* Range of registers allocated for aCol and aFunc */
+
  int iFirstReg;          /* First register in range for aCol[] and aFunc[] */
  ExprList *pGroupBy;     /* The group by clause */
  struct AggInfo_col {    /* For each column used in source tables */
    Table *pTab;             /* Source table */
    Expr *pCExpr;            /* The original expression */
    int iTable;              /* Cursor number of the source table */
-
    int iMem;                /* Memory location that acts as accumulator */
    i16 iColumn;             /* Column number within the source table */
    i16 iSorterColumn;       /* Column number in the sorting index */
  } *aCol;
@@ -18128,15 +18403,28 @@ struct AggInfo {
  struct AggInfo_func {   /* For each aggregate function */
    Expr *pFExpr;            /* Expression encoding the function */
    FuncDef *pFunc;          /* The aggregate function implementation */
-
    int iMem;                /* Memory location that acts as accumulator */
    int iDistinct;           /* Ephemeral table used to enforce DISTINCT */
    int iDistAddr;           /* Address of OP_OpenEphemeral */
  } *aFunc;
  int nFunc;              /* Number of entries in aFunc[] */
  u32 selId;              /* Select to which this AggInfo belongs */
+
#ifdef SQLITE_DEBUG
+
  Select *pSelect;        /* SELECT statement that this AggInfo supports */
+
#endif
};

/*
+
** Macros to compute aCol[] and aFunc[] register numbers.
+
**
+
** These macros should not be used prior to the call to
+
** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg.
+
** The assert()s that are part of this macro verify that constraint.
+
*/
+
#define AggInfoColumnReg(A,I)  (assert((A)->iFirstReg),(A)->iFirstReg+(I))
+
#define AggInfoFuncReg(A,I)    \
+
                      (assert((A)->iFirstReg),(A)->iFirstReg+(A)->nColumn+(I))
+

+
/*
** The datatype ynVar is a signed integer, either 16-bit or 32-bit.
** Usually it is 16-bits.  But if SQLITE_MAX_VARIABLE_NUMBER is greater
** than 32767 we have to make it 32-bit.  16-bit is preferred because
@@ -18666,7 +18954,7 @@ struct NameContext {
#define NC_HasAgg    0x000010 /* One or more aggregate functions seen */
#define NC_IdxExpr   0x000020 /* True if resolving columns of CREATE INDEX */
#define NC_SelfRef   0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */
-
#define NC_VarSelect 0x000040 /* A correlated subquery has been seen */
+
#define NC_Subquery  0x000040 /* A subquery has been seen */
#define NC_UEList    0x000080 /* True if uNC.pEList is used */
#define NC_UAggInfo  0x000100 /* True if uNC.pAggInfo is used */
#define NC_UUpsert   0x000200 /* True if uNC.pUpsert is used */
@@ -18795,6 +19083,7 @@ struct Select {
#define SF_MultiPart     0x2000000 /* Has multiple incompatible PARTITIONs */
#define SF_CopyCte       0x4000000 /* SELECT statement is a copy of a CTE */
#define SF_OrderByReqd   0x8000000 /* The ORDER BY clause may not be omitted */
+
#define SF_UpdateFrom   0x10000000 /* Query originates with UPDATE FROM */

/* True if S exists and has SF_NestedFrom */
#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0)
@@ -18903,7 +19192,7 @@ struct SelectDest {
  int iSDParm2;        /* A second parameter for the eDest disposal method */
  int iSdst;           /* Base register where results are written */
  int nSdst;           /* Number of registers allocated */
-
  char *zAffSdst;      /* Affinity used for SRT_Set, SRT_Table, and similar */
+
  char *zAffSdst;      /* Affinity used for SRT_Set */
  ExprList *pOrderBy;  /* Key columns for SRT_Queue and SRT_DistQueue */
};

@@ -18962,10 +19251,10 @@ struct TriggerPrg {
#else
  typedef unsigned int yDbMask;
# define DbMaskTest(M,I)    (((M)&(((yDbMask)1)<<(I)))!=0)
-
# define DbMaskZero(M)      (M)=0
-
# define DbMaskSet(M,I)     (M)|=(((yDbMask)1)<<(I))
-
# define DbMaskAllZero(M)   (M)==0
-
# define DbMaskNonZero(M)   (M)!=0
+
# define DbMaskZero(M)      ((M)=0)
+
# define DbMaskSet(M,I)     ((M)|=(((yDbMask)1)<<(I)))
+
# define DbMaskAllZero(M)   ((M)==0)
+
# define DbMaskNonZero(M)   ((M)!=0)
#endif

/*
@@ -18984,6 +19273,7 @@ struct IndexedExpr {
  int iIdxCur;            /* The index cursor */
  int iIdxCol;            /* The index column that contains value of pExpr */
  u8 bMaybeNullRow;       /* True if we need an OP_IfNullRow check */
+
  u8 aff;                 /* Affinity of the pExpr expression */
  IndexedExpr *pIENext;   /* Next in a list of all indexed expressions */
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  const char *zIdxName;   /* Name of index, used only for bytecode comments */
@@ -19036,6 +19326,9 @@ struct Parse {
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
  u8 earlyCleanup;     /* OOM inside sqlite3ParserAddCleanup() */
#endif
+
#ifdef SQLITE_DEBUG
+
  u8 ifNotExists;      /* Might be true if IF NOT EXISTS.  Assert()s only */
+
#endif
  int nRangeReg;       /* Size of the temporary register block */
  int iRangeReg;       /* First register in temporary register block */
  int nErr;            /* Number of errors seen */
@@ -19048,7 +19341,7 @@ struct Parse {
  int nLabelAlloc;     /* Number of slots in aLabel */
  int *aLabel;         /* Space to hold the labels */
  ExprList *pConstExpr;/* Constant expressions */
-
  IndexedExpr *pIdxExpr;/* List of expressions used by active indexes */
+
  IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */
  Token constraintName;/* Name of the constraint currently being parsed */
  yDbMask writeMask;   /* Start a write transaction on these databases */
  yDbMask cookieMask;  /* Bitmask of schema verified databases */
@@ -19072,6 +19365,9 @@ struct Parse {
  u32 nQueryLoop;      /* Est number of iterations of a query (10*log2(N)) */
  u32 oldmask;         /* Mask of old.* columns referenced */
  u32 newmask;         /* Mask of new.* columns referenced */
+
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+
  u32 nProgressSteps;  /* xProgress steps taken during sqlite3_prepare() */
+
#endif
  u8 eTriggerOp;       /* TK_UPDATE, TK_INSERT or TK_DELETE */
  u8 bReturning;       /* Coding a RETURNING trigger */
  u8 eOrconf;          /* Default ON CONFLICT policy for trigger steps */
@@ -19493,6 +19789,7 @@ struct Walker {
    struct CoveringIndexCheck *pCovIdxCk;     /* Check for covering index */
    SrcItem *pSrcItem;                        /* A single FROM clause item */
    DbFixer *pFix;                            /* See sqlite3FixSelect() */
+
    Mem *aMem;                                /* See sqlite3BtreeCursorHint() */
  } u;
};

@@ -19762,6 +20059,8 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
# define sqlite3Isxdigit(x)  (sqlite3CtypeMap[(unsigned char)(x)]&0x08)
# define sqlite3Tolower(x)   (sqlite3UpperToLower[(unsigned char)(x)])
# define sqlite3Isquote(x)   (sqlite3CtypeMap[(unsigned char)(x)]&0x80)
+
# define sqlite3JsonId1(x)   (sqlite3CtypeMap[(unsigned char)(x)]&0x42)
+
# define sqlite3JsonId2(x)   (sqlite3CtypeMap[(unsigned char)(x)]&0x46)
#else
# define sqlite3Toupper(x)   toupper((unsigned char)(x))
# define sqlite3Isspace(x)   isspace((unsigned char)(x))
@@ -19771,6 +20070,8 @@ SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno);
# define sqlite3Isxdigit(x)  isxdigit((unsigned char)(x))
# define sqlite3Tolower(x)   tolower((unsigned char)(x))
# define sqlite3Isquote(x)   ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`')
+
# define sqlite3JsonId1(x)   (sqlite3IsIdChar(x)&&(x)<'0')
+
# define sqlite3JsonId2(x)   sqlite3IsIdChar(x)
#endif
SQLITE_PRIVATE int sqlite3IsIdChar(u8);

@@ -19820,13 +20121,11 @@ SQLITE_PRIVATE int sqlite3HeapNearlyFull(void);
#ifdef SQLITE_USE_ALLOCA
# define sqlite3StackAllocRaw(D,N)   alloca(N)
# define sqlite3StackAllocRawNN(D,N) alloca(N)
-
# define sqlite3StackAllocZero(D,N)  memset(alloca(N), 0, N)
# define sqlite3StackFree(D,P)
# define sqlite3StackFreeNN(D,P)
#else
# define sqlite3StackAllocRaw(D,N)   sqlite3DbMallocRaw(D,N)
# define sqlite3StackAllocRawNN(D,N) sqlite3DbMallocRawNN(D,N)
-
# define sqlite3StackAllocZero(D,N)  sqlite3DbMallocZero(D,N)
# define sqlite3StackFree(D,P)       sqlite3DbFree(D,P)
# define sqlite3StackFreeNN(D,P)     sqlite3DbFreeNN(D,P)
#endif
@@ -19951,6 +20250,7 @@ SQLITE_PRIVATE void sqlite3ShowWinFunc(const Window*);
#endif

SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
+
SQLITE_PRIVATE void sqlite3ProgressCheck(Parse*);
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int);
SQLITE_PRIVATE void sqlite3Dequote(char*);
@@ -19965,6 +20265,10 @@ SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int);
SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int);
SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int);
SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*);
+
SQLITE_PRIVATE void sqlite3TouchRegister(Parse*,int);
+
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG)
+
SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse*,int);
+
#endif
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int);
#endif
@@ -20008,7 +20312,7 @@ SQLITE_PRIVATE const char *sqlite3ColumnColl(Column*);
SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*);
SQLITE_PRIVATE void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect);
SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**);
-
SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char);
+
SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(Parse*,Table*,Select*,char);
SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char);
SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *, int);
SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*);
@@ -20115,7 +20419,7 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList
                         Expr*,ExprList*,u32,Expr*);
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*);
-
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
+
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*);
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
@@ -20204,7 +20508,7 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
-
SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr*,const SrcItem*);
+
SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*);
#endif
@@ -20328,7 +20632,7 @@ SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*);
SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64);
SQLITE_PRIVATE i64 sqlite3RealToI64(double);
-
SQLITE_PRIVATE void sqlite3Int64ToText(i64,char*);
+
SQLITE_PRIVATE int sqlite3Int64ToText(i64,char*);
SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8);
SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*);
SQLITE_PRIVATE int sqlite3GetUInt32(const char*, u32*);
@@ -20379,6 +20683,7 @@ SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2);
SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table*,int);
SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr);
+
SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr);
SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8);
SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*);
SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
@@ -20395,6 +20700,9 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int);

#ifndef SQLITE_OMIT_DESERIALIZE
SQLITE_PRIVATE int sqlite3MemdbInit(void);
+
SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs*);
+
#else
+
# define sqlite3IsMemdb(X) 0
#endif

SQLITE_PRIVATE const char *sqlite3ErrStr(int);
@@ -20534,7 +20842,7 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);

SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
-
SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, int);
+
SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
@@ -20648,10 +20956,7 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *);
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 sqlite3VtabUsesAllSchemas(sqlite3_index_info*);
-
#endif
+
SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse*);
SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*);
SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int);
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
@@ -20892,6 +21197,18 @@ SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt);
SQLITE_PRIVATE int sqlite3KvvfsInit(void);
#endif

+
#if defined(VDBE_PROFILE) \
+
 || defined(SQLITE_PERFORMANCE_TRACE) \
+
 || defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+
SQLITE_PRIVATE sqlite3_uint64 sqlite3Hwtime(void);
+
#endif
+

+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
# define IS_STMT_SCANSTATUS(db) (db->flags & SQLITE_StmtScanStatus)
+
#else
+
# define IS_STMT_SCANSTATUS(db) 0
+
#endif
+

#endif /* SQLITEINT_H */

/************** End of sqliteInt.h *******************************************/
@@ -20933,101 +21250,6 @@ SQLITE_PRIVATE int sqlite3KvvfsInit(void);
*/
#ifdef SQLITE_PERFORMANCE_TRACE

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

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

-
  #if defined(__GNUC__)
-

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

-
  #elif defined(_MSC_VER)
-

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

-
  #endif
-

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

-
  __inline__ sqlite_uint64 sqlite3Hwtime(void){
-
      unsigned long val;
-
      __asm__ __volatile__ ("rdtsc" : "=A" (val));
-
      return val;
-
  }
-

-
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
-

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

-
#else
-

-
  /*
-
  ** asm() is needed for hardware timing support.  Without asm(),
-
  ** disable the sqlite3Hwtime() routine.
-
  **
-
  ** sqlite3Hwtime() is only used for some obscure debugging
-
  ** and analysis configurations, not in any deliverable, so this
-
  ** should not be a great loss.
-
  */
-
SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
-

-
#endif
-

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

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

static sqlite_uint64 g_start;
static sqlite_uint64 g_elapsed;
#define TIMER_START       g_start=sqlite3Hwtime()
@@ -21982,7 +22204,7 @@ SQLITE_PRIVATE const unsigned char *sqlite3aGTb = &sqlite3UpperToLower[256+12-OP
**   isalnum()                        0x06
**   isxdigit()                       0x08
**   toupper()                        0x20
-
**   SQLite identifier character      0x40
+
**   SQLite identifier character      0x40   $, _, or non-ascii
**   Quote character                  0x80
**
** Bit 0x20 is set if the mapped character requires translation to upper
@@ -22176,7 +22398,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
   SQLITE_DEFAULT_SORTERREF_SIZE,   /* szSorterRef */
   0,                         /* iPrngSeed */
#ifdef SQLITE_DEBUG
-
   {0,0,0,0,0,0}              /* aTune */
+
   {0,0,0,0,0,0},             /* aTune */
#endif
};

@@ -22472,7 +22694,6 @@ struct VdbeFrame {
  Vdbe *v;                /* VM this frame belongs to */
  VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
  Op *aOp;                /* Program instructions for parent frame */
-
  i64 *anExec;            /* Event counters from parent frame */
  Mem *aMem;              /* Array of memory cells for parent frame */
  VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
  u8 *aOnce;              /* Bitmask used by OP_Once */
@@ -22688,10 +22909,19 @@ typedef unsigned bft; /* Bit Field Type */

/* The ScanStatus object holds a single value for the
** sqlite3_stmt_scanstatus() interface.
+
**
+
** aAddrRange[]:
+
**   This array is used by ScanStatus elements associated with EQP
+
**   notes that make an SQLITE_SCANSTAT_NCYCLE value available. It is
+
**   an array of up to 3 ranges of VM addresses for which the Vdbe.anCycle[]
+
**   values should be summed to calculate the NCYCLE value. Each pair of
+
**   integer addresses is a start and end address (both inclusive) for a range
+
**   instructions. A start value of 0 indicates an empty range.
*/
typedef struct ScanStatus ScanStatus;
struct ScanStatus {
  int addrExplain;                /* OP_Explain for loop */
+
  int aAddrRange[6];
  int addrLoop;                   /* Address of "loops" counter */
  int addrVisit;                  /* Address of "rows visited" counter */
  int iSelectID;                  /* The "Select-ID" for this loop */
@@ -22747,7 +22977,7 @@ struct Vdbe {
  int nOp;                /* Number of instructions in the program */
  int nOpAlloc;           /* Slots allocated for aOp[] */
  Mem *aColName;          /* Column names to return */
-
  Mem *pResultSet;        /* Pointer to an array of results */
+
  Mem *pResultRow;        /* Current output row */
  char *zErrMsg;          /* Error message written here */
  VList *pVList;          /* Name of variables */
#ifndef SQLITE_OMIT_TRACE
@@ -22784,7 +23014,6 @@ struct Vdbe {
  SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
  AuxData *pAuxData;      /* Linked list of auxdata allocations */
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-
  i64 *anExec;            /* Number of times each op has been executed */
  int nScan;              /* Entries in aScan[] */
  ScanStatus *aScan;      /* Scan definitions for sqlite3_stmt_scanstatus() */
#endif
@@ -22951,6 +23180,8 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);

+
SQLITE_PRIVATE void sqlite3VdbeValueListFree(void*);
+

#ifdef SQLITE_DEBUG
SQLITE_PRIVATE   void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*);
SQLITE_PRIVATE   void sqlite3VdbeAssertAbortable(Vdbe*);
@@ -23466,6 +23697,7 @@ struct DateTime {
  char validTZ;       /* True (1) if tz is valid */
  char tzSet;         /* Timezone was set explicitly */
  char isError;       /* An overflow has occurred */
+
  char useSubsec;     /* Display subsecond precision */
};


@@ -23780,6 +24012,11 @@ static int parseDateOrTime(
  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){
    setRawDateNumber(p, r);
    return 0;
+
  }else if( (sqlite3StrICmp(zDate,"subsec")==0
+
             || sqlite3StrICmp(zDate,"subsecond")==0)
+
           && sqlite3NotPureFunc(context) ){
+
    p->useSubsec = 1;
+
    return setDateTimeToCurrent(context, p);
  }
  return 1;
}
@@ -24138,7 +24375,7 @@ static int parseModifier(
          i64 iOrigJD;              /* Original localtime */
          i64 iGuess;               /* Guess at the corresponding utc time */
          int cnt = 0;              /* Safety to prevent infinite loop */
-
          int iErr;                 /* Guess is off by this much */
+
          i64 iErr;                 /* Guess is off by this much */

          computeJD(p);
          iGuess = iOrigJD = p->iJD;
@@ -24194,8 +24431,22 @@ static int parseModifier(
      **
      ** Move the date backwards to the beginning of the current day,
      ** or month or year.
+
      **
+
      **    subsecond
+
      **    subsec
+
      **
+
      ** Show subsecond precision in the output of datetime() and
+
      ** unixepoch() and strftime('%s').
      */
-
      if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break;
+
      if( sqlite3_strnicmp(z, "start of ", 9)!=0 ){
+
        if( sqlite3_stricmp(z, "subsec")==0
+
         || sqlite3_stricmp(z, "subsecond")==0
+
        ){
+
          p->useSubsec = 1;
+
          rc = 0;
+
        }
+
        break;
+
      }
      if( !p->validJD && !p->validYMD && !p->validHMS ) break;
      z += 9;
      computeYMD(p);
@@ -24393,7 +24644,11 @@ static void unixepochFunc(
  DateTime x;
  if( isDate(context, argc, argv, &x)==0 ){
    computeJD(&x);
-
    sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000);
+
    if( x.useSubsec ){
+
      sqlite3_result_double(context, (x.iJD - 21086676*(i64)10000000)/1000.0);
+
    }else{
+
      sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000);
+
    }
  }
}

@@ -24409,8 +24664,8 @@ static void datetimeFunc(
){
  DateTime x;
  if( isDate(context, argc, argv, &x)==0 ){
-
    int Y, s;
-
    char zBuf[24];
+
    int Y, s, n;
+
    char zBuf[32];
    computeYMD_HMS(&x);
    Y = x.Y;
    if( Y<0 ) Y = -Y;
@@ -24431,15 +24686,28 @@ static void datetimeFunc(
    zBuf[15] = '0' + (x.m/10)%10;
    zBuf[16] = '0' + (x.m)%10;
    zBuf[17] = ':';
-
    s = (int)x.s;
-
    zBuf[18] = '0' + (s/10)%10;
-
    zBuf[19] = '0' + (s)%10;
-
    zBuf[20] = 0;
+
    if( x.useSubsec ){
+
      s = (int)1000.0*x.s;
+
      zBuf[18] = '0' + (s/10000)%10;
+
      zBuf[19] = '0' + (s/1000)%10;
+
      zBuf[20] = '.';
+
      zBuf[21] = '0' + (s/100)%10;
+
      zBuf[22] = '0' + (s/10)%10;
+
      zBuf[23] = '0' + (s)%10;
+
      zBuf[24] = 0;
+
      n = 24;
+
    }else{
+
      s = (int)x.s;
+
      zBuf[18] = '0' + (s/10)%10;
+
      zBuf[19] = '0' + (s)%10;
+
      zBuf[20] = 0;
+
      n = 20;
+
    }
    if( x.Y<0 ){
      zBuf[0] = '-';
-
      sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT);
+
      sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT);
    }else{
-
      sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT);
+
      sqlite3_result_text(context, &zBuf[1], n-1, SQLITE_TRANSIENT);
    }
  }
}
@@ -24456,7 +24724,7 @@ static void timeFunc(
){
  DateTime x;
  if( isDate(context, argc, argv, &x)==0 ){
-
    int s;
+
    int s, n;
    char zBuf[16];
    computeHMS(&x);
    zBuf[0] = '0' + (x.h/10)%10;
@@ -24465,11 +24733,24 @@ static void timeFunc(
    zBuf[3] = '0' + (x.m/10)%10;
    zBuf[4] = '0' + (x.m)%10;
    zBuf[5] = ':';
-
    s = (int)x.s;
-
    zBuf[6] = '0' + (s/10)%10;
-
    zBuf[7] = '0' + (s)%10;
-
    zBuf[8] = 0;
-
    sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT);
+
    if( x.useSubsec ){
+
      s = (int)1000.0*x.s;
+
      zBuf[6] = '0' + (s/10000)%10;
+
      zBuf[7] = '0' + (s/1000)%10;
+
      zBuf[8] = '.';
+
      zBuf[9] = '0' + (s/100)%10;
+
      zBuf[10] = '0' + (s/10)%10;
+
      zBuf[11] = '0' + (s)%10;
+
      zBuf[12] = 0;
+
      n = 12;
+
    }else{
+
      s = (int)x.s;
+
      zBuf[6] = '0' + (s/10)%10;
+
      zBuf[7] = '0' + (s)%10;
+
      zBuf[8] = 0;
+
      n = 8;
+
    }
+
    sqlite3_result_text(context, zBuf, n, SQLITE_TRANSIENT);
  }
}

@@ -24600,8 +24881,13 @@ static void strftimeFunc(
        break;
      }
      case 's': {
-
        i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000);
-
        sqlite3_str_appendf(&sRes,"%lld",iS);
+
        if( x.useSubsec ){
+
          sqlite3_str_appendf(&sRes,"%.3f",
+
                (x.iJD - 21086676*(i64)10000000)/1000.0);
+
        }else{
+
          i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000);
+
          sqlite3_str_appendf(&sRes,"%lld",iS);
+
        }
        break;
      }
      case 'S': {
@@ -27290,9 +27576,13 @@ static int memsys5Roundup(int n){
    if( n<=mem5.szAtom ) return mem5.szAtom;
    return mem5.szAtom*2;
  }
-
  if( n>0x40000000 ) return 0;
+
  if( n>0x10000000 ){
+
    if( n>0x40000000 ) return 0;
+
    if( n>0x20000000 ) return 0x40000000;
+
    return 0x20000000;
+
  }
  for(iFullSz=mem5.szAtom*8; iFullSz<n; iFullSz *= 4);
-
  if( (iFullSz/2)>=n ) return iFullSz/2;
+
  if( (iFullSz/2)>=(i64)n ) return iFullSz/2;
  return iFullSz;
}

@@ -29202,7 +29492,7 @@ static void mallocWithAlarm(int n, void **pp){
** The upper bound is slightly less than 2GiB:  0x7ffffeff == 2,147,483,391
** This provides a 256-byte safety margin for defense against 32-bit
** signed integer overflow bugs when computing memory allocation sizes.
-
** Parnoid applications might want to reduce the maximum allocation size
+
** Paranoid applications might want to reduce the maximum allocation size
** further for an even larger safety margin.  0x3fffffff or 0x0fffffff
** or even smaller would be reasonable upper bounds on the size of a memory
** allocations for most applications.
@@ -29716,9 +30006,14 @@ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){
*/
SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
  int n;
+
#ifdef SQLITE_DEBUG
+
  /* Because of the way the parser works, the span is guaranteed to contain
+
  ** at least one non-space character */
+
  for(n=0; sqlite3Isspace(zStart[n]); n++){ assert( &zStart[n]<zEnd ); }
+
#endif
  while( sqlite3Isspace(zStart[0]) ) zStart++;
  n = (int)(zEnd - zStart);
-
  while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--;
+
  while( sqlite3Isspace(zStart[n-1]) ) n--;
  return sqlite3DbStrNDup(db, zStart, n);
}

@@ -29963,6 +30258,20 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
}
#endif /* SQLITE_OMIT_FLOATING_POINT */

+
#ifndef SQLITE_OMIT_FLOATING_POINT
+
/*
+
** "*val" is a u64.  *msd is a divisor used to extract the
+
** most significant digit of *val.  Extract that most significant
+
** digit and return it.
+
*/
+
static char et_getdigit_int(u64 *val, u64 *msd){
+
  u64 x = (*val)/(*msd);
+
  *val -= x*(*msd);
+
  if( *msd>=10 ) *msd /= 10;
+
  return '0' + (char)(x & 15);
+
}
+
#endif /* SQLITE_OMIT_FLOATING_POINT */
+

/*
** Set the StrAccum object to an error mode.
*/
@@ -30055,6 +30364,8 @@ SQLITE_API void sqlite3_str_vappendf(
  char prefix;               /* Prefix character.  "+" or "-" or " " or '\0'. */
  sqlite_uint64 longvalue;   /* Value for integer types */
  LONGDOUBLE_TYPE realvalue; /* Value for real types */
+
  sqlite_uint64 msd;         /* Divisor to get most-significant-digit
+
                             ** of longvalue */
  const et_info *infop;      /* Pointer to the appropriate info structure */
  char *zOut;                /* Rendering buffer */
  int nOut;                  /* Size of the rendering buffer */
@@ -30361,52 +30672,78 @@ SQLITE_API void sqlite3_str_vappendf(
        }else{
          prefix = flag_prefix;
        }
+
        exp = 0;
        if( xtype==etGENERIC && precision>0 ) precision--;
        testcase( precision>0xfff );
-
        idx = precision & 0xfff;
-
        rounder = arRound[idx%10];
-
        while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; }
-
        if( xtype==etFLOAT ){
-
          double rx = (double)realvalue;
-
          sqlite3_uint64 u;
-
          int ex;
-
          memcpy(&u, &rx, sizeof(u));
-
          ex = -1023 + (int)((u>>52)&0x7ff);
-
          if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16;
-
          realvalue += rounder;
-
        }
-
        /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
-
        exp = 0;
-
        if( sqlite3IsNaN((double)realvalue) ){
-
          bufpt = "NaN";
-
          length = 3;
-
          break;
-
        }
-
        if( realvalue>0.0 ){
-
          LONGDOUBLE_TYPE scale = 1.0;
-
          while( realvalue>=1e100*scale && exp<=350 ){ scale *= 1e100;exp+=100;}
-
          while( realvalue>=1e10*scale && exp<=350 ){ scale *= 1e10; exp+=10; }
-
          while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
-
          realvalue /= scale;
-
          while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
-
          while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
-
          if( exp>350 ){
-
            bufpt = buf;
-
            buf[0] = prefix;
-
            memcpy(buf+(prefix!=0),"Inf",4);
-
            length = 3+(prefix!=0);
+
        if( realvalue<1.0e+16
+
         && realvalue==(LONGDOUBLE_TYPE)(longvalue = (u64)realvalue)
+
        ){
+
          /* Number is a pure integer that can be represented as u64 */
+
          for(msd=1; msd*10<=longvalue; msd *= 10, exp++){}
+
          if( exp>precision && xtype!=etFLOAT ){
+
            u64 rnd = msd/2;
+
            int kk = precision;
+
            while( kk-- > 0 ){  rnd /= 10; }
+
            longvalue += rnd;
+
          }
+
        }else{
+
          msd = 0;
+
          longvalue = 0;  /* To prevent a compiler warning */
+
          idx = precision & 0xfff;
+
          rounder = arRound[idx%10];
+
          while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; }
+
          if( xtype==etFLOAT ){
+
            double rx = (double)realvalue;
+
            sqlite3_uint64 u;
+
            int ex;
+
            memcpy(&u, &rx, sizeof(u));
+
            ex = -1023 + (int)((u>>52)&0x7ff);
+
            if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16;
+
            realvalue += rounder;
+
          }
+
          if( sqlite3IsNaN((double)realvalue) ){
+
            if( flag_zeropad ){
+
              bufpt = "null";
+
              length = 4;
+
            }else{
+
              bufpt = "NaN";
+
              length = 3;
+
            }
            break;
          }
+

+
          /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
+
          if( ALWAYS(realvalue>0.0) ){
+
            LONGDOUBLE_TYPE scale = 1.0;
+
            while( realvalue>=1e100*scale && exp<=350){ scale*=1e100;exp+=100;}
+
            while( realvalue>=1e10*scale && exp<=350 ){ scale*=1e10; exp+=10; }
+
            while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; }
+
            realvalue /= scale;
+
            while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
+
            while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
+
            if( exp>350 ){
+
              if( flag_zeropad ){
+
                realvalue = 9.0;
+
                exp = 999;
+
              }else{
+
                bufpt = buf;
+
                buf[0] = prefix;
+
                memcpy(buf+(prefix!=0),"Inf",4);
+
                length = 3+(prefix!=0);
+
                break;
+
              }
+
            }
+
            if( xtype!=etFLOAT ){
+
              realvalue += rounder;
+
              if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
+
            }
+
          }
        }
-
        bufpt = buf;
+

        /*
        ** If the field type is etGENERIC, then convert to either etEXP
        ** or etFLOAT, as appropriate.
        */
-
        if( xtype!=etFLOAT ){
-
          realvalue += rounder;
-
          if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
-
        }
        if( xtype==etGENERIC ){
          flag_rtz = !flag_alternateform;
          if( exp<-4 || exp>precision ){
@@ -30423,16 +30760,18 @@ SQLITE_API void sqlite3_str_vappendf(
        }else{
          e2 = exp;
        }
+
        nsd = 16 + flag_altform2*10;
+
        bufpt = buf;
        {
          i64 szBufNeeded;           /* Size of a temporary buffer needed */
          szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15;
+
          if( cThousand && e2>0 ) szBufNeeded += (e2+2)/3;
          if( szBufNeeded > etBUFSIZE ){
            bufpt = zExtra = printfTempBuf(pAccum, szBufNeeded);
            if( bufpt==0 ) return;
          }
        }
        zOut = bufpt;
-
        nsd = 16 + flag_altform2*10;
        flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
        /* The sign in front of the number */
        if( prefix ){
@@ -30441,9 +30780,15 @@ SQLITE_API void sqlite3_str_vappendf(
        /* Digits prior to the decimal point */
        if( e2<0 ){
          *(bufpt++) = '0';
+
        }else if( msd>0 ){
+
          for(; e2>=0; e2--){
+
            *(bufpt++) = et_getdigit_int(&longvalue,&msd);
+
            if( cThousand && (e2%3)==0 && e2>1 ) *(bufpt++) = ',';
+
          }
        }else{
          for(; e2>=0; e2--){
            *(bufpt++) = et_getdigit(&realvalue,&nsd);
+
            if( cThousand && (e2%3)==0 && e2>1 ) *(bufpt++) = ',';
          }
        }
        /* The decimal point */
@@ -30457,8 +30802,14 @@ SQLITE_API void sqlite3_str_vappendf(
          *(bufpt++) = '0';
        }
        /* Significant digits after the decimal point */
-
        while( (precision--)>0 ){
-
          *(bufpt++) = et_getdigit(&realvalue,&nsd);
+
        if( msd>0 ){
+
          while( (precision--)>0 ){
+
            *(bufpt++) = et_getdigit_int(&longvalue,&msd);
+
          }
+
        }else{
+
          while( (precision--)>0 ){
+
            *(bufpt++) = et_getdigit(&realvalue,&nsd);
+
          }
        }
        /* Remove trailing zeros and the "." if no digits follow the "." */
        if( flag_rtz && flag_dp ){
@@ -30557,13 +30908,26 @@ SQLITE_API void sqlite3_str_vappendf(
          }
        }
        if( precision>1 ){
+
          i64 nPrior = 1;
          width -= precision-1;
          if( width>1 && !flag_leftjustify ){
            sqlite3_str_appendchar(pAccum, width-1, ' ');
            width = 0;
          }
-
          while( precision-- > 1 ){
-
            sqlite3_str_append(pAccum, buf, length);
+
          sqlite3_str_append(pAccum, buf, length);
+
          precision--;
+
          while( precision > 1 ){
+
            i64 nCopyBytes;
+
            if( nPrior > precision-1 ) nPrior = precision - 1;
+
            nCopyBytes = length*nPrior;
+
            if( nCopyBytes + pAccum->nChar >= pAccum->nAlloc ){
+
              sqlite3StrAccumEnlarge(pAccum, nCopyBytes);
+
            }
+
            if( pAccum->accError ) break;
+
            sqlite3_str_append(pAccum,
+
                 &pAccum->zText[pAccum->nChar-nCopyBytes], nCopyBytes);
+
            precision -= nPrior;
+
            nPrior *= 2;
          }
        }
        bufpt = buf;
@@ -30791,9 +31155,9 @@ SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExp
** Return the number of bytes of text that StrAccum is able to accept
** after the attempted enlargement.  The value returned might be zero.
*/
-
SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, int N){
+
SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, i64 N){
  char *zNew;
-
  assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
+
  assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */
  if( p->accError ){
    testcase(p->accError==SQLITE_TOOBIG);
    testcase(p->accError==SQLITE_NOMEM);
@@ -30804,8 +31168,7 @@ SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, int N){
    return p->nAlloc - p->nChar - 1;
  }else{
    char *zOld = isMalloced(p) ? p->zText : 0;
-
    i64 szNew = p->nChar;
-
    szNew += (sqlite3_int64)N + 1;
+
    i64 szNew = p->nChar + N + 1;
    if( szNew+p->nChar<=p->mxAlloc ){
      /* Force exponential buffer size growth as long as it does not overflow,
      ** to avoid having to call this routine too often */
@@ -30835,7 +31198,8 @@ SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, int N){
      return 0;
    }
  }
-
  return N;
+
  assert( N>=0 && N<=0x7fffffff );
+
  return (int)N;
}

/*
@@ -31126,12 +31490,22 @@ SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_li
  return zBuf;
}
SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
-
  char *z;
+
  StrAccum acc;
  va_list ap;
+
  if( n<=0 ) return zBuf;
+
#ifdef SQLITE_ENABLE_API_ARMOR
+
  if( zBuf==0 || zFormat==0 ) {
+
    (void)SQLITE_MISUSE_BKPT;
+
    if( zBuf ) zBuf[0] = 0;
+
    return zBuf;
+
  }
+
#endif
+
  sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
  va_start(ap,zFormat);
-
  z = sqlite3_vsnprintf(n, zBuf, zFormat, ap);
+
  sqlite3_str_vappendf(&acc, zFormat, ap);
  va_end(ap);
-
  return z;
+
  zBuf[acc.nChar] = 0;
+
  return zBuf;
}

/*
@@ -31431,6 +31805,13 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc)
    if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){
      sqlite3_str_appendf(&x, " ON");
    }
+
    if( pItem->fg.isTabFunc )      sqlite3_str_appendf(&x, " isTabFunc");
+
    if( pItem->fg.isCorrelated )   sqlite3_str_appendf(&x, " isCorrelated");
+
    if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized");
+
    if( pItem->fg.viaCoroutine )   sqlite3_str_appendf(&x, " viaCoroutine");
+
    if( pItem->fg.notCte )         sqlite3_str_appendf(&x, " notCte");
+
    if( pItem->fg.isNestedFrom )   sqlite3_str_appendf(&x, " isNestedFrom");
+

    sqlite3StrAccumFinish(&x);
    sqlite3TreeViewItem(pView, zLine, i<pSrc->nSrc-1);
    n = 0;
@@ -31700,7 +32081,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
    sqlite3TreeViewPop(&pView);
    return;
  }
-
  if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){
+
  if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags || pExpr->pAggInfo ){
    StrAccum x;
    sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0);
    sqlite3_str_appendf(&x, " fg.af=%x.%c",
@@ -31717,6 +32098,9 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m
    if( ExprHasVVAProperty(pExpr, EP_Immutable) ){
      sqlite3_str_appendf(&x, " IMMUTABLE");
    }
+
    if( pExpr->pAggInfo!=0 ){
+
      sqlite3_str_appendf(&x, " agg-column[%d]", pExpr->iAgg);
+
    }
    sqlite3StrAccumFinish(&x);
  }else{
    zFlgs[0] = 0;
@@ -33657,6 +34041,26 @@ SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *z
}

/*
+
** Check for interrupts and invoke progress callback.
+
*/
+
SQLITE_PRIVATE void sqlite3ProgressCheck(Parse *p){
+
  sqlite3 *db = p->db;
+
  if( AtomicLoad(&db->u1.isInterrupted) ){
+
    p->nErr++;
+
    p->rc = SQLITE_INTERRUPT;
+
  }
+
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+
  if( db->xProgress && (++p->nProgressSteps)>=db->nProgressOps ){
+
    if( db->xProgress(db->pProgressArg) ){
+
      p->nErr++;
+
      p->rc = SQLITE_INTERRUPT;
+
    }
+
    p->nProgressSteps = 0;
+
  }
+
#endif
+
}
+

+
/*
** Add an error message to pParse->zErrMsg and increment pParse->nErr.
**
** This function should be used to report any error that occurs while
@@ -34113,11 +34517,14 @@ do_atof_calc:
#endif

/*
-
** Render an signed 64-bit integer as text.  Store the result in zOut[].
+
** Render an signed 64-bit integer as text.  Store the result in zOut[] and
+
** return the length of the string that was stored, in bytes.  The value
+
** returned does not include the zero terminator at the end of the output
+
** string.
**
** The caller must ensure that zOut[] is at least 21 bytes in size.
*/
-
SQLITE_PRIVATE void sqlite3Int64ToText(i64 v, char *zOut){
+
SQLITE_PRIVATE int sqlite3Int64ToText(i64 v, char *zOut){
  int i;
  u64 x;
  char zTemp[22];
@@ -34128,12 +34535,15 @@ SQLITE_PRIVATE void sqlite3Int64ToText(i64 v, char *zOut){
  }
  i = sizeof(zTemp)-2;
  zTemp[sizeof(zTemp)-1] = 0;
-
  do{
-
    zTemp[i--] = (x%10) + '0';
+
  while( 1 /*exit-by-break*/ ){
+
    zTemp[i] = (x%10) + '0';
    x = x/10;
-
  }while( x );
-
  if( v<0 ) zTemp[i--] = '-';
-
  memcpy(zOut, &zTemp[i+1], sizeof(zTemp)-1-i);
+
    if( x==0 ) break;
+
    i--;
+
  };
+
  if( v<0 ) zTemp[--i] = '-';
+
  memcpy(zOut, &zTemp[i], sizeof(zTemp)-i);
+
  return sizeof(zTemp)-1-i;
}

/*
@@ -34298,7 +34708,9 @@ SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
      u = u*16 + sqlite3HexToInt(z[k]);
    }
    memcpy(pOut, &u, 8);
-
    return (z[k]==0 && k-i<=16) ? 0 : 2;
+
    if( k-i>16 ) return 2;
+
    if( z[k]!=0 ) return 1;
+
    return 0;
  }else
#endif /* SQLITE_OMIT_HEX_INTEGER */
  {
@@ -34334,7 +34746,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){
    u32 u = 0;
    zNum += 2;
    while( zNum[0]=='0' ) zNum++;
-
    for(i=0; sqlite3Isxdigit(zNum[i]) && i<8; i++){
+
    for(i=0; i<8 && sqlite3Isxdigit(zNum[i]); i++){
      u = u*16 + sqlite3HexToInt(zNum[i]);
    }
    if( (u&0x80000000)==0 && sqlite3Isxdigit(zNum[i])==0 ){
@@ -35195,6 +35607,104 @@ SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nNam
  return 0;
}

+
/*
+
** High-resolution hardware timer used for debugging and testing only.
+
*/
+
#if defined(VDBE_PROFILE)  \
+
 || defined(SQLITE_PERFORMANCE_TRACE) \
+
 || defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+
/************** Include hwtime.h in the middle of util.c *********************/
+
/************** Begin file hwtime.h ******************************************/
+
/*
+
** 2008 May 27
+
**
+
** The author disclaims copyright to this source code.  In place of
+
** a legal notice, here is a blessing:
+
**
+
**    May you do good and not evil.
+
**    May you find forgiveness for yourself and forgive others.
+
**    May you share freely, never taking more than you give.
+
**
+
******************************************************************************
+
**
+
** This file contains inline asm code for retrieving "high-performance"
+
** counters for x86 and x86_64 class CPUs.
+
*/
+
#ifndef SQLITE_HWTIME_H
+
#define SQLITE_HWTIME_H
+

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

+
  #if defined(__GNUC__)
+

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

+
  #elif defined(_MSC_VER)
+

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

+
  #endif
+

+
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
+

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

+
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
+

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

+
#else
+

+
  /*
+
  ** asm() is needed for hardware timing support.  Without asm(),
+
  ** disable the sqlite3Hwtime() routine.
+
  **
+
  ** sqlite3Hwtime() is only used for some obscure debugging
+
  ** and analysis configurations, not in any deliverable, so this
+
  ** should not be a great loss.
+
  */
+
SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
+

+
#endif
+

+
#endif /* !defined(SQLITE_HWTIME_H) */
+

+
/************** End of hwtime.h **********************************************/
+
/************** Continuing where we left off in util.c ***********************/
+
#endif
+

/************** End of util.c ************************************************/
/************** Begin file hash.c ********************************************/
/*
@@ -35365,12 +35875,13 @@ static HashElem *findElementWithHash(
    count = pH->count;
  }
  if( pHash ) *pHash = h;
-
  while( count-- ){
+
  while( count ){
    assert( elem!=0 );
    if( sqlite3StrICmp(elem->pKey,pKey)==0 ){
      return elem;
    }
    elem = elem->next;
+
    count--;
  }
  return &nullElement;
}
@@ -35729,7 +36240,9 @@ struct KVVfsFile {
  char *aJrnl;                    /* Journal content */
  int szPage;                     /* Last known page size */
  sqlite3_int64 szDb;             /* Database file size.  -1 means unknown */
+
  char *aData;                    /* Buffer to hold page data */
};
+
#define SQLITE_KVOS_SZ 133073

/*
** Methods for KVVfsFile
@@ -36092,8 +36605,7 @@ static int kvvfsDecode(const char *a, char *aOut, int nOut){
      if( j+n>nOut ) return -1;
      memset(&aOut[j], 0, n);
      j += n;
-
      c = aIn[i];
-
      if( c==0 ) break;
+
      if( c==0 || mult==1 ) break; /* progress stalled if mult==1 */
    }else{
      aOut[j] = c<<4;
      c = kvvfsHexValue[aIn[++i]];
@@ -36170,6 +36682,7 @@ static int kvvfsClose(sqlite3_file *pProtoFile){
  SQLITE_KV_LOG(("xClose %s %s\n", pFile->zClass,
             pFile->isJournal ? "journal" : "db"));
  sqlite3_free(pFile->aJrnl);
+
  sqlite3_free(pFile->aData);
  return SQLITE_OK;
}

@@ -36218,7 +36731,7 @@ static int kvvfsReadDb(
  unsigned int pgno;
  int got, n;
  char zKey[30];
-
  char aData[133073];
+
  char *aData = pFile->aData;
  assert( iOfst>=0 );
  assert( iAmt>=0 );
  SQLITE_KV_LOG(("xRead('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst));
@@ -36235,7 +36748,8 @@ static int kvvfsReadDb(
    pgno = 1;
  }
  sqlite3_snprintf(sizeof(zKey), zKey, "%u", pgno);
-
  got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey, aData, sizeof(aData)-1);
+
  got = sqlite3KvvfsMethods.xRead(pFile->zClass, zKey,
+
                                  aData, SQLITE_KVOS_SZ-1);
  if( got<0 ){
    n = 0;
  }else{
@@ -36243,7 +36757,7 @@ static int kvvfsReadDb(
    if( iOfst+iAmt<512 ){
      int k = iOfst+iAmt;
      aData[k*2] = 0;
-
      n = kvvfsDecode(aData, &aData[2000], sizeof(aData)-2000);
+
      n = kvvfsDecode(aData, &aData[2000], SQLITE_KVOS_SZ-2000);
      if( n>=iOfst+iAmt ){
        memcpy(zBuf, &aData[2000+iOfst], iAmt);
        n = iAmt;
@@ -36302,7 +36816,7 @@ static int kvvfsWriteDb(
  KVVfsFile *pFile = (KVVfsFile*)pProtoFile;
  unsigned int pgno;
  char zKey[30];
-
  char aData[131073];
+
  char *aData = pFile->aData;
  SQLITE_KV_LOG(("xWrite('%s-db',%d,%lld)\n", pFile->zClass, iAmt, iOfst));
  assert( iAmt>=512 && iAmt<=65536 );
  assert( (iAmt & (iAmt-1))==0 );
@@ -36511,6 +37025,10 @@ static int kvvfsOpen(
  }else{
    pFile->zClass = "local";
  }
+
  pFile->aData = sqlite3_malloc64(SQLITE_KVOS_SZ);
+
  if( pFile->aData==0 ){
+
    return SQLITE_NOMEM;
+
  }
  pFile->aJrnl = 0;
  pFile->nJrnl = 0;
  pFile->szPage = -1;
@@ -36724,7 +37242,7 @@ SQLITE_PRIVATE int sqlite3KvvfsInit(void){
#endif

/* Use pread() and pwrite() if they are available */
-
#if defined(__APPLE__)
+
#if defined(__APPLE__) || defined(__linux__)
# define HAVE_PREAD 1
# define HAVE_PWRITE 1
#endif
@@ -36747,7 +37265,8 @@ SQLITE_PRIVATE int sqlite3KvvfsInit(void){
/* #include <time.h> */
#include <sys/time.h>    /* amalgamator: keep */
#include <errno.h>
-
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+
#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \
+
  && !defined(SQLITE_WASI)
# include <sys/mman.h>
#endif

@@ -36835,9 +37354,46 @@ SQLITE_PRIVATE int sqlite3KvvfsInit(void){
*/
#define SQLITE_MAX_SYMLINKS 100

+
/*
+
** Remove and stub certain info for WASI (WebAssembly System
+
** Interface) builds.
+
*/
+
#ifdef SQLITE_WASI
+
# undef HAVE_FCHMOD
+
# undef HAVE_FCHOWN
+
# undef HAVE_MREMAP
+
# define HAVE_MREMAP 0
+
# ifndef SQLITE_DEFAULT_UNIX_VFS
+
#  define SQLITE_DEFAULT_UNIX_VFS "unix-dotfile"
+
   /* ^^^ should SQLITE_DEFAULT_UNIX_VFS be "unix-none"? */
+
# endif
+
# ifndef F_RDLCK
+
#  define F_RDLCK 0
+
#  define F_WRLCK 1
+
#  define F_UNLCK 2
+
#  if __LONG_MAX == 0x7fffffffL
+
#   define F_GETLK 12
+
#   define F_SETLK 13
+
#   define F_SETLKW 14
+
#  else
+
#   define F_GETLK 5
+
#   define F_SETLK 6
+
#   define F_SETLKW 7
+
#  endif
+
# endif
+
#else /* !SQLITE_WASI */
+
# ifndef HAVE_FCHMOD
+
#  define HAVE_FCHMOD
+
# endif
+
#endif /* SQLITE_WASI */
+

+
#ifdef SQLITE_WASI
+
# define osGetpid(X) (pid_t)1
+
#else
/* Always cast the getpid() return type for compatibility with
** kernel modules in VxWorks. */
-
#define osGetpid(X) (pid_t)getpid()
+
# define osGetpid(X) (pid_t)getpid()
+
#endif

/*
** Only set the lastErrno if the error code is a real error and not
@@ -37109,7 +37665,11 @@ static struct unix_syscall {
#define osPwrite64  ((ssize_t(*)(int,const void*,size_t,off64_t))\
                    aSyscall[13].pCurrent)

+
#if defined(HAVE_FCHMOD)
  { "fchmod",       (sqlite3_syscall_ptr)fchmod,          0  },
+
#else
+
  { "fchmod",       (sqlite3_syscall_ptr)0,               0  },
+
#endif
#define osFchmod    ((int(*)(int,mode_t))aSyscall[14].pCurrent)

#if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE
@@ -37145,14 +37705,16 @@ static struct unix_syscall {
#endif
#define osGeteuid   ((uid_t(*)(void))aSyscall[21].pCurrent)

-
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+
#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \
+
  && !defined(SQLITE_WASI)
  { "mmap",         (sqlite3_syscall_ptr)mmap,            0 },
#else
  { "mmap",         (sqlite3_syscall_ptr)0,               0 },
#endif
#define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent)

-
#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+
#if (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) \
+
  && !defined(SQLITE_WASI)
  { "munmap",       (sqlite3_syscall_ptr)munmap,          0 },
#else
  { "munmap",       (sqlite3_syscall_ptr)0,               0 },
@@ -37338,6 +37900,9 @@ static int robust_open(const char *z, int f, mode_t m){
      break;
    }
    if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break;
+
    if( (f & (O_EXCL|O_CREAT))==(O_EXCL|O_CREAT) ){
+
      (void)osUnlink(z);
+
    }
    osClose(fd);
    sqlite3_log(SQLITE_WARNING,
                "attempt to open \"%s\" as file descriptor %d", z, fd);
@@ -38300,7 +38865,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
**
**    UNLOCKED -> SHARED
**    SHARED -> RESERVED
-
**    SHARED -> (PENDING) -> EXCLUSIVE
+
**    SHARED -> EXCLUSIVE
**    RESERVED -> (PENDING) -> EXCLUSIVE
**    PENDING -> EXCLUSIVE
**
@@ -38333,19 +38898,20 @@ static int unixLock(sqlite3_file *id, int eFileLock){
  ** A RESERVED lock is implemented by grabbing a write-lock on the
  ** 'reserved byte'.
  **
-
  ** A process may only obtain a PENDING lock after it has obtained a
-
  ** SHARED lock. A PENDING lock is implemented by obtaining a write-lock
-
  ** on the 'pending byte'. This ensures that no new SHARED locks can be
-
  ** obtained, but existing SHARED locks are allowed to persist. A process
-
  ** does not have to obtain a RESERVED lock on the way to a PENDING lock.
-
  ** This property is used by the algorithm for rolling back a journal file
-
  ** after a crash.
+
  ** An EXCLUSIVE lock may only be requested after either a SHARED or
+
  ** RESERVED lock is held. An EXCLUSIVE lock is implemented by obtaining
+
  ** a write-lock on the entire 'shared byte range'. Since all other locks
+
  ** require a read-lock on one of the bytes within this range, this ensures
+
  ** that no other locks are held on the database.
  **
-
  ** An EXCLUSIVE lock, obtained after a PENDING lock is held, is
-
  ** implemented by obtaining a write-lock on the entire 'shared byte
-
  ** range'. Since all other locks require a read-lock on one of the bytes
-
  ** within this range, this ensures that no other locks are held on the
-
  ** database.
+
  ** If a process that holds a RESERVED lock requests an EXCLUSIVE, then
+
  ** a PENDING lock is obtained first. A PENDING lock is implemented by
+
  ** obtaining a write-lock on the 'pending byte'. This ensures that no new
+
  ** SHARED locks can be obtained, but existing SHARED locks are allowed to
+
  ** persist. If the call to this function fails to obtain the EXCLUSIVE
+
  ** lock in this case, it holds the PENDING lock intead. The client may
+
  ** then re-attempt the EXCLUSIVE lock later on, after existing SHARED
+
  ** locks have cleared.
  */
  int rc = SQLITE_OK;
  unixFile *pFile = (unixFile*)id;
@@ -38416,7 +38982,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
  lock.l_len = 1L;
  lock.l_whence = SEEK_SET;
  if( eFileLock==SHARED_LOCK
-
      || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock<PENDING_LOCK)
+
   || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock==RESERVED_LOCK)
  ){
    lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK);
    lock.l_start = PENDING_BYTE;
@@ -38427,6 +38993,9 @@ static int unixLock(sqlite3_file *id, int eFileLock){
        storeLastErrno(pFile, tErrno);
      }
      goto end_lock;
+
    }else if( eFileLock==EXCLUSIVE_LOCK ){
+
      pFile->eFileLock = PENDING_LOCK;
+
      pInode->eFileLock = PENDING_LOCK;
    }
  }

@@ -38514,13 +39083,9 @@ static int unixLock(sqlite3_file *id, int eFileLock){
  }
#endif

-

  if( rc==SQLITE_OK ){
    pFile->eFileLock = eFileLock;
    pInode->eFileLock = eFileLock;
-
  }else if( eFileLock==EXCLUSIVE_LOCK ){
-
    pFile->eFileLock = PENDING_LOCK;
-
    pInode->eFileLock = PENDING_LOCK;
  }

end_lock:
@@ -39927,12 +40492,6 @@ static int nfsUnlock(sqlite3_file *id, int eFileLock){
** Seek to the offset passed as the second argument, then read cnt
** bytes into pBuf. Return the number of bytes actually read.
**
-
** NB:  If you define USE_PREAD or USE_PREAD64, then it might also
-
** be necessary to define _XOPEN_SOURCE to be 500.  This varies from
-
** one system to another.  Since SQLite does not define USE_PREAD
-
** in any form by default, we will not attempt to define _XOPEN_SOURCE.
-
** See tickets #2741 and #2681.
-
**
** To avoid stomping the errno value on a failed read the lastErrno value
** is set before returning.
*/
@@ -43111,12 +43670,10 @@ static void appendOnePathElement(
  if( zName[0]=='.' ){
    if( nName==1 ) return;
    if( zName[1]=='.' && nName==2 ){
-
      if( pPath->nUsed<=1 ){
-
        pPath->rc = SQLITE_ERROR;
-
        return;
+
      if( pPath->nUsed>1 ){
+
        assert( pPath->zOut[0]=='/' );
+
        while( pPath->zOut[--pPath->nUsed]!='/' ){}
      }
-
      assert( pPath->zOut[0]=='/' );
-
      while( pPath->zOut[--pPath->nUsed]!='/' ){}
      return;
    }
  }
@@ -43328,7 +43885,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
** than the argument.
*/
static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){
-
#if OS_VXWORKS
+
#if OS_VXWORKS || _POSIX_C_SOURCE >= 199309L
  struct timespec sp;

  sp.tv_sec = microseconds / 1000000;
@@ -49961,7 +50518,7 @@ static int winOpen(
      if( isReadWrite ){
        int rc2, isRO = 0;
        sqlite3BeginBenignMalloc();
-
        rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+
        rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO);
        sqlite3EndBenignMalloc();
        if( rc2==SQLITE_OK && isRO ) break;
      }
@@ -49978,7 +50535,7 @@ static int winOpen(
      if( isReadWrite ){
        int rc2, isRO = 0;
        sqlite3BeginBenignMalloc();
-
        rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+
        rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO);
        sqlite3EndBenignMalloc();
        if( rc2==SQLITE_OK && isRO ) break;
      }
@@ -49998,7 +50555,7 @@ static int winOpen(
      if( isReadWrite ){
        int rc2, isRO = 0;
        sqlite3BeginBenignMalloc();
-
        rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
+
        rc2 = winAccess(pVfs, zUtf8Name, SQLITE_ACCESS_READ, &isRO);
        sqlite3EndBenignMalloc();
        if( rc2==SQLITE_OK && isRO ) break;
      }
@@ -50221,6 +50778,13 @@ static int winAccess(
  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
           zFilename, flags, pResOut));

+
  if( zFilename==0 ){
+
    *pResOut = 0;
+
    OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
+
             zFilename, pResOut, *pResOut));
+
    return SQLITE_OK;
+
  }
+

  zConverted = winConvertFromUtf8Filename(zFilename);
  if( zConverted==0 ){
    OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
@@ -51071,6 +51635,7 @@ static int memdbTruncate(sqlite3_file*, sqlite3_int64 size);
static int memdbSync(sqlite3_file*, int flags);
static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize);
static int memdbLock(sqlite3_file*, int);
+
static int memdbUnlock(sqlite3_file*, int);
/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */
static int memdbFileControl(sqlite3_file*, int op, void *pArg);
/* static int memdbSectorSize(sqlite3_file*); // not used */
@@ -51129,7 +51694,7 @@ static const sqlite3_io_methods memdb_io_methods = {
  memdbSync,                       /* xSync */
  memdbFileSize,                   /* xFileSize */
  memdbLock,                       /* xLock */
-
  memdbLock,                       /* xUnlock - same as xLock in this case */
+
  memdbUnlock,                     /* xUnlock */
  0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */
  memdbFileControl,                /* xFileControl */
  0, /* memdbSectorSize,*/         /* xSectorSize */
@@ -51330,39 +51895,81 @@ static int memdbLock(sqlite3_file *pFile, int eLock){
  MemFile *pThis = (MemFile*)pFile;
  MemStore *p = pThis->pStore;
  int rc = SQLITE_OK;
-
  if( eLock==pThis->eLock ) return SQLITE_OK;
+
  if( eLock<=pThis->eLock ) return SQLITE_OK;
  memdbEnter(p);
-
  if( eLock>SQLITE_LOCK_SHARED ){
-
    if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){
-
      rc = SQLITE_READONLY;
-
    }else if( pThis->eLock<=SQLITE_LOCK_SHARED ){
-
      if( p->nWrLock ){
-
        rc = SQLITE_BUSY;
-
      }else{
-
        p->nWrLock = 1;
+

+
  assert( p->nWrLock==0 || p->nWrLock==1 );
+
  assert( pThis->eLock<=SQLITE_LOCK_SHARED || p->nWrLock==1 );
+
  assert( pThis->eLock==SQLITE_LOCK_NONE || p->nRdLock>=1 );
+

+
  if( eLock>SQLITE_LOCK_SHARED && (p->mFlags & SQLITE_DESERIALIZE_READONLY) ){
+
    rc = SQLITE_READONLY;
+
  }else{
+
    switch( eLock ){
+
      case SQLITE_LOCK_SHARED: {
+
        assert( pThis->eLock==SQLITE_LOCK_NONE );
+
        if( p->nWrLock>0 ){
+
          rc = SQLITE_BUSY;
+
        }else{
+
          p->nRdLock++;
+
        }
+
        break;
+
      };
+

+
      case SQLITE_LOCK_RESERVED:
+
      case SQLITE_LOCK_PENDING: {
+
        assert( pThis->eLock>=SQLITE_LOCK_SHARED );
+
        if( ALWAYS(pThis->eLock==SQLITE_LOCK_SHARED) ){
+
          if( p->nWrLock>0 ){
+
            rc = SQLITE_BUSY;
+
          }else{
+
            p->nWrLock = 1;
+
          }
+
        }
+
        break;
+
      }
+

+
      default: {
+
        assert(  eLock==SQLITE_LOCK_EXCLUSIVE );
+
        assert( pThis->eLock>=SQLITE_LOCK_SHARED );
+
        if( p->nRdLock>1 ){
+
          rc = SQLITE_BUSY;
+
        }else if( pThis->eLock==SQLITE_LOCK_SHARED ){
+
          p->nWrLock = 1;
+
        }
+
        break;
      }
    }
-
  }else if( eLock==SQLITE_LOCK_SHARED ){
-
    if( pThis->eLock > SQLITE_LOCK_SHARED ){
-
      assert( p->nWrLock==1 );
-
      p->nWrLock = 0;
-
    }else if( p->nWrLock ){
-
      rc = SQLITE_BUSY;
-
    }else{
-
      p->nRdLock++;
+
  }
+
  if( rc==SQLITE_OK ) pThis->eLock = eLock;
+
  memdbLeave(p);
+
  return rc;
+
}
+

+
/*
+
** Unlock an memdb-file.
+
*/
+
static int memdbUnlock(sqlite3_file *pFile, int eLock){
+
  MemFile *pThis = (MemFile*)pFile;
+
  MemStore *p = pThis->pStore;
+
  if( eLock>=pThis->eLock ) return SQLITE_OK;
+
  memdbEnter(p);
+

+
  assert( eLock==SQLITE_LOCK_SHARED || eLock==SQLITE_LOCK_NONE );
+
  if( eLock==SQLITE_LOCK_SHARED ){
+
    if( ALWAYS(pThis->eLock>SQLITE_LOCK_SHARED) ){
+
      p->nWrLock--;
    }
  }else{
-
    assert( eLock==SQLITE_LOCK_NONE );
    if( pThis->eLock>SQLITE_LOCK_SHARED ){
-
      assert( p->nWrLock==1 );
-
      p->nWrLock = 0;
+
      p->nWrLock--;
    }
-
    assert( p->nRdLock>0 );
    p->nRdLock--;
  }
-
  if( rc==SQLITE_OK ) pThis->eLock = eLock;
+

+
  pThis->eLock = eLock;
  memdbLeave(p);
-
  return rc;
+
  return SQLITE_OK;
}

#if 0
@@ -51472,7 +52079,7 @@ static int memdbOpen(

  memset(pFile, 0, sizeof(*pFile));
  szName = sqlite3Strlen30(zName);
-
  if( szName>1 && zName[0]=='/' ){
+
  if( szName>1 && (zName[0]=='/' || zName[0]=='\\') ){
    int i;
#ifndef SQLITE_MUTEX_OMIT
    sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
@@ -51820,6 +52427,13 @@ end_deserialize:
}

/*
+
** Return true if the VFS is the memvfs.
+
*/
+
SQLITE_PRIVATE int sqlite3IsMemdb(const sqlite3_vfs *pVfs){
+
  return pVfs==&memdb_vfs;
+
}
+

+
/*
** This routine is called when the extension is loaded.
** Register the new VFS.
*/
@@ -52298,7 +52912,7 @@ bitvec_end:
struct PCache {
  PgHdr *pDirty, *pDirtyTail;         /* List of dirty pages in LRU order */
  PgHdr *pSynced;                     /* Last synced page in dirty page list */
-
  int nRefSum;                        /* Sum of ref counts over all pages */
+
  i64 nRefSum;                        /* Sum of ref counts over all pages */
  int szCache;                        /* Configured cache size */
  int szSpill;                        /* Size before spilling occurs */
  int szPage;                         /* Size of every page in this cache */
@@ -52327,11 +52941,15 @@ struct PCache {
    PgHdr *pPg;
    unsigned char *a;
    int j;
-
    pPg = (PgHdr*)pLower->pExtra;
-
    printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags);
-
    a = (unsigned char *)pLower->pBuf;
-
    for(j=0; j<12; j++) printf("%02x", a[j]);
-
    printf(" ptr %p\n", pPg);
+
    if( pLower==0 ){
+
      printf("%3d: NULL\n", i);
+
    }else{
+
      pPg = (PgHdr*)pLower->pExtra;
+
      printf("%3d: nRef %2lld flgs %02x data ", i, pPg->nRef, pPg->flags);
+
      a = (unsigned char *)pLower->pBuf;
+
      for(j=0; j<12; j++) printf("%02x", a[j]);
+
      printf(" ptr %p\n", pPg);
+
    }
  }
  static void pcacheDump(PCache *pCache){
    int N;
@@ -52344,9 +52962,8 @@ struct PCache {
    if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump;
    for(i=1; i<=N; i++){
       pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0);
-
       if( pLower==0 ) continue;
       pcachePageTrace(i, pLower);
-
       if( ((PgHdr*)pLower)->pPage==0 ){
+
       if( pLower && ((PgHdr*)pLower)->pPage==0 ){
         sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0);
       }
    }
@@ -53072,14 +53689,14 @@ SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
** This is not the total number of pages referenced, but the sum of the
** reference count for all pages.
*/
-
SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
+
SQLITE_PRIVATE i64 sqlite3PcacheRefCount(PCache *pCache){
  return pCache->nRefSum;
}

/*
** Return the number of references to the page supplied as an argument.
*/
-
SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
+
SQLITE_PRIVATE i64 sqlite3PcachePageRefcount(PgHdr *p){
  return p->nRef;
}

@@ -57734,6 +58351,8 @@ static int pager_truncate(Pager *pPager, Pgno nPage){
  int rc = SQLITE_OK;
  assert( pPager->eState!=PAGER_ERROR );
  assert( pPager->eState!=PAGER_READER );
+
  PAGERTRACE(("Truncate %d npage %u\n", PAGERID(pPager), nPage));
+


  if( isOpen(pPager->fd)
   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
@@ -58064,7 +58683,7 @@ end_playback:
    ** see if it is possible to delete the super-journal.
    */
    assert( zSuper==&pPager->pTmpSpace[4] );
-
    memset(&zSuper[-4], 0, 4);
+
    memset(pPager->pTmpSpace, 0, 4);
    rc = pager_delsuper(pPager, zSuper);
    testcase( rc!=SQLITE_OK );
  }
@@ -58685,7 +59304,6 @@ SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
** Numeric values associated with these states are OFF==1, NORMAL=2,
** and FULL=3.
*/
-
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
SQLITE_PRIVATE void sqlite3PagerSetFlags(
  Pager *pPager,        /* The pager to set safety level for */
  unsigned pgFlags      /* Various flags */
@@ -58720,7 +59338,6 @@ SQLITE_PRIVATE void sqlite3PagerSetFlags(
    pPager->doNotSpill |= SPILLFLAG_OFF;
  }
}
-
#endif

/*
** The following global variable is incremented whenever the library
@@ -59822,7 +60439,6 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
  u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
  const char *zUri = 0;    /* URI args to copy */
  int nUriByte = 1;        /* Number of bytes of URI args at *zUri */
-
  int nUri = 0;            /* Number of URI parameters */

  /* Figure out how much space is required for each journal file-handle
  ** (there are two of them, the main journal and the sub-journal).  */
@@ -59870,7 +60486,6 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
    while( *z ){
      z += strlen(z)+1;
      z += strlen(z)+1;
-
      nUri++;
    }
    nUriByte = (int)(&z[1] - zUri);
    assert( nUriByte>=1 );
@@ -60126,18 +60741,7 @@ act_like_temp_file:
  pPager->memDb = (u8)memDb;
  pPager->readOnly = (u8)readOnly;
  assert( useJournal || pPager->tempFile );
-
  pPager->noSync = pPager->tempFile;
-
  if( pPager->noSync ){
-
    assert( pPager->fullSync==0 );
-
    assert( pPager->extraSync==0 );
-
    assert( pPager->syncFlags==0 );
-
    assert( pPager->walSyncFlags==0 );
-
  }else{
-
    pPager->fullSync = 1;
-
    pPager->extraSync = 0;
-
    pPager->syncFlags = SQLITE_SYNC_NORMAL;
-
    pPager->walSyncFlags = SQLITE_SYNC_NORMAL | (SQLITE_SYNC_NORMAL<<2);
-
  }
+
  sqlite3PagerSetFlags(pPager, (SQLITE_DEFAULT_SYNCHRONOUS+1)|PAGER_CACHESPILL);
  /* pPager->pFirst = 0; */
  /* pPager->pFirstSynced = 0; */
  /* pPager->pLast = 0; */
@@ -60666,6 +61270,10 @@ static int getPageNormal(
    if( !isOpen(pPager->fd) || pPager->dbSize<pgno || noContent ){
      if( pgno>pPager->mxPgno ){
        rc = SQLITE_FULL;
+
        if( pgno<=pPager->dbSize ){
+
          sqlite3PcacheRelease(pPg);
+
          pPg = 0;
+
        }
        goto pager_acquire_err;
      }
      if( noContent ){
@@ -60830,10 +61438,12 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
/*
** Release a page reference.
**
-
** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be
-
** used if we know that the page being released is not the last page.
+
** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be used
+
** if we know that the page being released is not the last reference to page1.
** The btree layer always holds page1 open until the end, so these first
-
** to routines can be used to release any page other than BtShared.pPage1.
+
** two routines can be used to release any page other than BtShared.pPage1.
+
** The assert() at tag-20230419-2 proves that this constraint is always
+
** honored.
**
** Use sqlite3PagerUnrefPageOne() to release page1.  This latter routine
** checks the total number of outstanding pages and if the number of
@@ -60849,7 +61459,7 @@ SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){
    sqlite3PcacheRelease(pPg);
  }
  /* Do not use this routine to release the last reference to page1 */
-
  assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
+
  assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); /* tag-20230419-2 */
}
SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
  if( pPg ) sqlite3PagerUnrefNotNull(pPg);
@@ -61398,7 +62008,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
# define DIRECT_MODE isDirectMode
#endif

-
  if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
+
  if( !pPager->changeCountDone && pPager->dbSize>0 ){
    PgHdr *pPgHdr;                /* Reference to page 1 */

    assert( !pPager->tempFile && isOpen(pPager->fd) );
@@ -62138,7 +62748,11 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
*/
SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){
  static const char zFake[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-
  return (nullIfMemDb && pPager->memDb) ? &zFake[4] : pPager->zFilename;
+
  if( nullIfMemDb && (pPager->memDb || sqlite3IsMemdb(pPager->pVfs)) ){
+
    return &zFake[4];
+
  }else{
+
    return pPager->zFilename;
+
  }
}

/*
@@ -62605,13 +63219,15 @@ SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){
*/
static int pagerExclusiveLock(Pager *pPager){
  int rc;                         /* Return code */
+
  u8 eOrigLock;                   /* Original lock */

-
  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
+
  assert( pPager->eLock>=SHARED_LOCK );
+
  eOrigLock = pPager->eLock;
  rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
  if( rc!=SQLITE_OK ){
    /* If the attempt to grab the exclusive lock failed, release the
    ** pending lock that may have been obtained instead.  */
-
    pagerUnlockDb(pPager, SHARED_LOCK);
+
    pagerUnlockDb(pPager, eOrigLock);
  }

  return rc;
@@ -63616,19 +64232,40 @@ static void walChecksumBytes(
  assert( nByte>=8 );
  assert( (nByte&0x00000007)==0 );
  assert( nByte<=65536 );
+
  assert( nByte%4==0 );

-
  if( nativeCksum ){
+
  if( !nativeCksum ){
+
    do {
+
      s1 += BYTESWAP32(aData[0]) + s2;
+
      s2 += BYTESWAP32(aData[1]) + s1;
+
      aData += 2;
+
    }while( aData<aEnd );
+
  }else if( nByte%64==0 ){
    do {
      s1 += *aData++ + s2;
      s2 += *aData++ + s1;
+
      s1 += *aData++ + s2;
+
      s2 += *aData++ + s1;
+
      s1 += *aData++ + s2;
+
      s2 += *aData++ + s1;
+
      s1 += *aData++ + s2;
+
      s2 += *aData++ + s1;
+
      s1 += *aData++ + s2;
+
      s2 += *aData++ + s1;
+
      s1 += *aData++ + s2;
+
      s2 += *aData++ + s1;
+
      s1 += *aData++ + s2;
+
      s2 += *aData++ + s1;
+
      s1 += *aData++ + s2;
+
      s2 += *aData++ + s1;
    }while( aData<aEnd );
  }else{
    do {
-
      s1 += BYTESWAP32(aData[0]) + s2;
-
      s2 += BYTESWAP32(aData[1]) + s1;
-
      aData += 2;
+
      s1 += *aData++ + s2;
+
      s2 += *aData++ + s1;
    }while( aData<aEnd );
  }
+
  assert( aData==aEnd );

  aOut[0] = s1;
  aOut[1] = s2;
@@ -66559,7 +67196,9 @@ SQLITE_PRIVATE int sqlite3WalFrames(
      if( rc ) return rc;
    }
  }
-
  assert( (int)pWal->szPage==szPage );
+
  if( (int)pWal->szPage!=szPage ){
+
    return SQLITE_CORRUPT_BKPT;  /* TH3 test case: cov1/corrupt155.test */
+
  }

  /* Setup information needed to write frames into the WAL */
  w.pWal = pWal;
@@ -67219,7 +67858,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){
** byte are used.  The integer consists of all bytes that have bit 8 set and
** the first byte with bit 8 clear.  The most significant byte of the integer
** appears first.  A variable-length integer may not be more than 9 bytes long.
-
** As a special case, all 8 bytes of the 9th byte are used as data.  This
+
** As a special case, all 8 bits of the 9th byte are used as data.  This
** allows a 64-bit integer to be encoded in 9 bytes.
**
**    0x00                      becomes  0x00000000
@@ -67603,7 +68242,7 @@ struct BtCursor {
#define BTCF_WriteFlag    0x01   /* True if a write cursor */
#define BTCF_ValidNKey    0x02   /* True if info.nKey is valid */
#define BTCF_ValidOvfl    0x04   /* True if aOverflow is valid */
-
#define BTCF_AtLast       0x08   /* Cursor is pointing ot the last entry */
+
#define BTCF_AtLast       0x08   /* Cursor is pointing to the last entry */
#define BTCF_Incrblob     0x10   /* True if an incremental I/O handle */
#define BTCF_Multiple     0x20   /* Maybe another cursor on the same btree */
#define BTCF_Pinned       0x40   /* Cursor is busy and cannot be moved */
@@ -67721,15 +68360,15 @@ struct BtCursor {
** So, this macro is defined instead.
*/
#ifndef SQLITE_OMIT_AUTOVACUUM
-
#define ISAUTOVACUUM (pBt->autoVacuum)
+
#define ISAUTOVACUUM(pBt) (pBt->autoVacuum)
#else
-
#define ISAUTOVACUUM 0
+
#define ISAUTOVACUUM(pBt) 0
#endif


/*
-
** This structure is passed around through all the sanity checking routines
-
** in order to keep track of some global state information.
+
** This structure is passed around through all the PRAGMA integrity_check
+
** checking routines in order to keep track of some global state information.
**
** The aRef[] array is allocated so that there is 1 bit for each page in
** the database. As the integrity-check proceeds, for each page used in
@@ -67745,10 +68384,12 @@ struct IntegrityCk {
  Pgno nPage;       /* Number of pages in the database */
  int mxErr;        /* Stop accumulating errors when this reaches zero */
  int nErr;         /* Number of messages written to zErrMsg so far */
-
  int bOomFault;    /* A memory allocation error has occurred */
+
  int rc;           /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */
+
  u32 nStep;        /* Number of steps into the integrity_check process */
  const char *zPfx; /* Error message prefix */
-
  Pgno v1;          /* Value for first %u substitution in zPfx */
-
  int v2;           /* Value for second %d substitution in zPfx */
+
  Pgno v0;          /* Value for first %u substitution in zPfx (root page) */
+
  Pgno v1;          /* Value for second %u substitution in zPfx (current pg) */
+
  int v2;           /* Value for third %d substitution in zPfx */
  StrAccum errMsg;  /* Accumulate the error message text here */
  u32 *heap;        /* Min-heap used for analyzing cell coverage */
  sqlite3 *db;      /* Database connection running the check */
@@ -68211,8 +68852,8 @@ SQLITE_PRIVATE sqlite3_uint64 sqlite3BtreeSeekCount(Btree *pBt){
int corruptPageError(int lineno, MemPage *p){
  char *zMsg;
  sqlite3BeginBenignMalloc();
-
  zMsg = sqlite3_mprintf("database corruption page %d of %s",
-
      (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
+
  zMsg = sqlite3_mprintf("database corruption page %u of %s",
+
             p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
  );
  sqlite3EndBenignMalloc();
  if( zMsg ){
@@ -69021,8 +69662,25 @@ SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow)
*/
SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){
  /* Used only by system that substitute their own storage engine */
+
#ifdef SQLITE_DEBUG
+
  if( ALWAYS(eHintType==BTREE_HINT_RANGE) ){
+
    va_list ap;
+
    Expr *pExpr;
+
    Walker w;
+
    memset(&w, 0, sizeof(w));
+
    w.xExprCallback = sqlite3CursorRangeHintExprCheck;
+
    va_start(ap, eHintType);
+
    pExpr = va_arg(ap, Expr*);
+
    w.u.aMem = va_arg(ap, Mem*);
+
    va_end(ap);
+
    assert( pExpr!=0 );
+
    assert( w.u.aMem!=0 );
+
    sqlite3WalkExpr(&w, pExpr);
+
  }
+
#endif /* SQLITE_DEBUG */
}
-
#endif
+
#endif /* SQLITE_ENABLE_CURSOR_HINTS */
+


/*
** Provide flag hints to the cursor.
@@ -69107,7 +69765,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){
  pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage);

  if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){
-
    TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent));
+
    TRACE(("PTRMAP_UPDATE: %u->(%u,%u)\n", key, eType, parent));
    *pRC= rc = sqlite3PagerWrite(pDbPage);
    if( rc==SQLITE_OK ){
      pPtrmap[offset] = eType;
@@ -69306,27 +69964,31 @@ static void btreeParseCellPtr(
  iKey = *pIter;
  if( iKey>=0x80 ){
    u8 x;
-
    iKey = ((iKey&0x7f)<<7) | ((x = *++pIter) & 0x7f);
+
    iKey = (iKey<<7) ^ (x = *++pIter);
    if( x>=0x80 ){
-
      iKey = (iKey<<7) | ((x =*++pIter) & 0x7f);
+
      iKey = (iKey<<7) ^ (x = *++pIter);
      if( x>=0x80 ){
-
        iKey = (iKey<<7) | ((x = *++pIter) & 0x7f);
+
        iKey = (iKey<<7) ^ 0x10204000 ^ (x = *++pIter);
        if( x>=0x80 ){
-
          iKey = (iKey<<7) | ((x = *++pIter) & 0x7f);
+
          iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter);
          if( x>=0x80 ){
-
            iKey = (iKey<<7) | ((x = *++pIter) & 0x7f);
+
            iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter);
            if( x>=0x80 ){
-
              iKey = (iKey<<7) | ((x = *++pIter) & 0x7f);
+
              iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter);
              if( x>=0x80 ){
-
                iKey = (iKey<<7) | ((x = *++pIter) & 0x7f);
+
                iKey = (iKey<<7) ^ 0x4000 ^ (x = *++pIter);
                if( x>=0x80 ){
-
                  iKey = (iKey<<8) | (*++pIter);
+
                  iKey = (iKey<<8) ^ 0x8000 ^ (*++pIter);
                }
              }
            }
          }
        }
+
      }else{
+
        iKey ^= 0x204000;
      }
+
    }else{
+
      iKey ^= 0x4000;
    }
  }
  pIter++;
@@ -69403,10 +70065,11 @@ static void btreeParseCell(
**
** cellSizePtrNoPayload()    =>   table internal nodes
** cellSizePtrTableLeaf()    =>   table leaf nodes
-
** cellSizePtr()             =>   all index nodes & table leaf nodes
+
** cellSizePtr()             =>   index internal nodes
+
** cellSizeIdxLeaf()         =>   index leaf nodes
*/
static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
-
  u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
+
  u8 *pIter = pCell + 4;                   /* For looping over bytes of pCell */
  u8 *pEnd;                                /* End mark for a varint */
  u32 nSize;                               /* Size value to return */

@@ -69419,6 +70082,49 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
  pPage->xParseCell(pPage, pCell, &debuginfo);
#endif

+
  assert( pPage->childPtrSize==4 );
+
  nSize = *pIter;
+
  if( nSize>=0x80 ){
+
    pEnd = &pIter[8];
+
    nSize &= 0x7f;
+
    do{
+
      nSize = (nSize<<7) | (*++pIter & 0x7f);
+
    }while( *(pIter)>=0x80 && pIter<pEnd );
+
  }
+
  pIter++;
+
  testcase( nSize==pPage->maxLocal );
+
  testcase( nSize==(u32)pPage->maxLocal+1 );
+
  if( nSize<=pPage->maxLocal ){
+
    nSize += (u32)(pIter - pCell);
+
    assert( 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;
+
}
+
static u16 cellSizePtrIdxLeaf(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
+

+
  assert( pPage->childPtrSize==0 );
  nSize = *pIter;
  if( nSize>=0x80 ){
    pEnd = &pIter[8];
@@ -69655,10 +70361,10 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){
      /* These conditions have already been verified in btreeInitPage()
      ** if PRAGMA cell_size_check=ON.
      */
-
      if( pc<iCellStart || pc>iCellLast ){
+
      if( pc>iCellLast ){
        return SQLITE_CORRUPT_PAGE(pPage);
      }
-
      assert( pc>=iCellStart && pc<=iCellLast );
+
      assert( pc>=0 && pc<=iCellLast );
      size = pPage->xCellSize(pPage, &src[pc]);
      cbrk -= size;
      if( cbrk<iCellStart || pc+size>usableSize ){
@@ -69773,7 +70479,7 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){
** allocation is being made in order to insert a new cell, so we will
** also end up needing a new cell pointer.
*/
-
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
+
static SQLITE_INLINE int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
  const int hdr = pPage->hdrOffset;    /* Local cache of pPage->hdrOffset */
  u8 * const data = pPage->aData;      /* Local cache of pPage->aData */
  int top;                             /* First byte of cell content area */
@@ -69799,13 +70505,14 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
  ** integer, so a value of 0 is used in its place. */
  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 ){
      top = 65536;
    }else{
      return SQLITE_CORRUPT_PAGE(pPage);
    }
+
  }else if( top>(int)pPage->pBt->usableSize ){
+
    return SQLITE_CORRUPT_PAGE(pPage);
  }

  /* If there is enough space between gap and top for one more cell pointer,
@@ -69888,7 +70595,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
  assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( iSize>=4 );   /* Minimum cell size is 4 */
-
  assert( iStart<=pPage->pBt->usableSize-4 );
+
  assert( CORRUPT_DB || iStart<=pPage->pBt->usableSize-4 );

  /* The list of freeblocks must be in ascending order.  Find the
  ** spot on the list where iStart should be inserted.
@@ -69945,6 +70652,11 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
  }
  pTmp = &data[hdr+5];
  x = get2byte(pTmp);
+
  if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
+
    /* Overwrite deleted information with zeros when the secure_delete
+
    ** option is enabled */
+
    memset(&data[iStart], 0, iSize);
+
  }
  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
@@ -69956,14 +70668,9 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
  }else{
    /* Insert the new freeblock into the freelist */
    put2byte(&data[iPtr], iStart);
+
    put2byte(&data[iStart], iFreeBlk);
+
    put2byte(&data[iStart+2], iSize);
  }
-
  if( pPage->pBt->btsFlags & BTS_FAST_SECURE ){
-
    /* Overwrite deleted information with zeros when the secure_delete
-
    ** option is enabled */
-
    memset(&data[iStart], 0, iSize);
-
  }
-
  put2byte(&data[iStart], iFreeBlk);
-
  put2byte(&data[iStart+2], iSize);
  pPage->nFree += iOrigSize;
  return SQLITE_OK;
}
@@ -69975,62 +70682,67 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
** Only the following combinations are supported.  Anything different
** indicates a corrupt database files:
**
-
**         PTF_ZERODATA
-
**         PTF_ZERODATA | PTF_LEAF
-
**         PTF_LEAFDATA | PTF_INTKEY
-
**         PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF
+
**         PTF_ZERODATA                             (0x02,  2)
+
**         PTF_LEAFDATA | PTF_INTKEY                (0x05,  5)
+
**         PTF_ZERODATA | PTF_LEAF                  (0x0a, 10)
+
**         PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF     (0x0d, 13)
*/
static int decodeFlags(MemPage *pPage, int flagByte){
  BtShared *pBt;     /* A copy of pPage->pBt */

  assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-
  pPage->leaf = (u8)(flagByte>>3);  assert( PTF_LEAF == 1<<3 );
-
  flagByte &= ~PTF_LEAF;
-
  pPage->childPtrSize = 4-4*pPage->leaf;
  pBt = pPage->pBt;
-
  if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
-
    /* EVIDENCE-OF: R-07291-35328 A value of 5 (0x05) means the page is an
-
    ** interior table b-tree page. */
-
    assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
-
    /* EVIDENCE-OF: R-26900-09176 A value of 13 (0x0d) means the page is a
-
    ** leaf table b-tree page. */
-
    assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
-
    pPage->intKey = 1;
-
    if( pPage->leaf ){
+
  pPage->max1bytePayload = pBt->max1bytePayload;
+
  if( flagByte>=(PTF_ZERODATA | PTF_LEAF) ){
+
    pPage->childPtrSize = 0;
+
    pPage->leaf = 1;
+
    if( flagByte==(PTF_LEAFDATA | PTF_INTKEY | PTF_LEAF) ){
      pPage->intKeyLeaf = 1;
      pPage->xCellSize = cellSizePtrTableLeaf;
      pPage->xParseCell = btreeParseCellPtr;
+
      pPage->intKey = 1;
+
      pPage->maxLocal = pBt->maxLeaf;
+
      pPage->minLocal = pBt->minLeaf;
+
    }else if( flagByte==(PTF_ZERODATA | PTF_LEAF) ){
+
      pPage->intKey = 0;
+
      pPage->intKeyLeaf = 0;
+
      pPage->xCellSize = cellSizePtrIdxLeaf;
+
      pPage->xParseCell = btreeParseCellPtrIndex;
+
      pPage->maxLocal = pBt->maxLocal;
+
      pPage->minLocal = pBt->minLocal;
    }else{
+
      pPage->intKey = 0;
+
      pPage->intKeyLeaf = 0;
+
      pPage->xCellSize = cellSizePtrIdxLeaf;
+
      pPage->xParseCell = btreeParseCellPtrIndex;
+
      return SQLITE_CORRUPT_PAGE(pPage);
+
    }
+
  }else{
+
    pPage->childPtrSize = 4;
+
    pPage->leaf = 0;
+
    if( flagByte==(PTF_ZERODATA) ){
+
      pPage->intKey = 0;
+
      pPage->intKeyLeaf = 0;
+
      pPage->xCellSize = cellSizePtr;
+
      pPage->xParseCell = btreeParseCellPtrIndex;
+
      pPage->maxLocal = pBt->maxLocal;
+
      pPage->minLocal = pBt->minLocal;
+
    }else if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
      pPage->intKeyLeaf = 0;
      pPage->xCellSize = cellSizePtrNoPayload;
      pPage->xParseCell = btreeParseCellPtrNoPayload;
+
      pPage->intKey = 1;
+
      pPage->maxLocal = pBt->maxLeaf;
+
      pPage->minLocal = pBt->minLeaf;
+
    }else{
+
      pPage->intKey = 0;
+
      pPage->intKeyLeaf = 0;
+
      pPage->xCellSize = cellSizePtr;
+
      pPage->xParseCell = btreeParseCellPtrIndex;
+
      return SQLITE_CORRUPT_PAGE(pPage);
    }
-
    pPage->maxLocal = pBt->maxLeaf;
-
    pPage->minLocal = pBt->minLeaf;
-
  }else if( flagByte==PTF_ZERODATA ){
-
    /* EVIDENCE-OF: R-43316-37308 A value of 2 (0x02) means the page is an
-
    ** interior index b-tree page. */
-
    assert( (PTF_ZERODATA)==2 );
-
    /* EVIDENCE-OF: R-59615-42828 A value of 10 (0x0a) means the page is a
-
    ** leaf index b-tree page. */
-
    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;
  return SQLITE_OK;
}

@@ -71868,7 +72580,7 @@ static int relocatePage(
  if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT;

  /* Move page iDbPage from its current location to page number iFreePage */
-
  TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n",
+
  TRACE(("AUTOVACUUM: Moving %u to free page %u (ptr page %u type %u)\n",
      iDbPage, iFreePage, iPtrPage, eType));
  rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit);
  if( rc!=SQLITE_OK ){
@@ -73570,9 +74282,25 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
** on success.  Set *pRes to 0 if the cursor actually points to something
** or set *pRes to 1 if the table is empty.
*/
+
static SQLITE_NOINLINE int btreeLast(BtCursor *pCur, int *pRes){
+
  int rc = moveToRoot(pCur);
+
  if( rc==SQLITE_OK ){
+
    assert( pCur->eState==CURSOR_VALID );
+
    *pRes = 0;
+
    rc = moveToRightmost(pCur);
+
    if( rc==SQLITE_OK ){
+
      pCur->curFlags |= BTCF_AtLast;
+
    }else{
+
      pCur->curFlags &= ~BTCF_AtLast;
+
    }
+
  }else if( rc==SQLITE_EMPTY ){
+
    assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
+
    *pRes = 1;
+
    rc = SQLITE_OK;
+
  }
+
  return rc;
+
}
SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
-
  int rc;
-

  assert( cursorOwnsBtShared(pCur) );
  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );

@@ -73593,23 +74321,7 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
    *pRes = 0;
    return SQLITE_OK;
  }
-

-
  rc = moveToRoot(pCur);
-
  if( rc==SQLITE_OK ){
-
    assert( pCur->eState==CURSOR_VALID );
-
    *pRes = 0;
-
    rc = moveToRightmost(pCur);
-
    if( rc==SQLITE_OK ){
-
      pCur->curFlags |= BTCF_AtLast;
-
    }else{
-
      pCur->curFlags &= ~BTCF_AtLast;
-
    }
-
  }else if( rc==SQLITE_EMPTY ){
-
    assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
-
    *pRes = 1;
-
    rc = SQLITE_OK;
-
  }
-
  return rc;
+
  return btreeLast(pCur, pRes);
}

/* Move the cursor so that it points to an entry in a table (a.k.a INTKEY)
@@ -74154,7 +74866,8 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){

  pPage = pCur->pPage;
  idx = ++pCur->ix;
-
  if( NEVER(!pPage->isInit) || sqlite3FaultSim(412) ){
+
  if( sqlite3FaultSim(412) ) pPage->isInit = 0;
+
  if( !pPage->isInit ){
    return SQLITE_CORRUPT_BKPT;
  }

@@ -74417,7 +75130,7 @@ static int allocateBtreePage(
        memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4);
        *ppPage = pTrunk;
        pTrunk = 0;
-
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
+
        TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1));
      }else if( k>(u32)(pBt->usableSize/4 - 2) ){
        /* Value of k is out of range.  Database corruption */
        rc = SQLITE_CORRUPT_PGNO(iTrunk);
@@ -74483,7 +75196,7 @@ static int allocateBtreePage(
          }
        }
        pTrunk = 0;
-
        TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
+
        TRACE(("ALLOCATE: %u trunk - %u free pages left\n", *pPgno, n-1));
#endif
      }else if( k>0 ){
        /* Extract a leaf from the trunk */
@@ -74528,8 +75241,8 @@ static int allocateBtreePage(
        ){
          int noContent;
          *pPgno = iPage;
-
          TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d"
-
                 ": %d more free pages\n",
+
          TRACE(("ALLOCATE: %u was leaf %u of %u on trunk %u"
+
                 ": %u more free pages\n",
                 *pPgno, closest+1, k, pTrunk->pgno, n-1));
          rc = sqlite3PagerWrite(pTrunk->pDbPage);
          if( rc ) goto end_allocate_page;
@@ -74585,7 +75298,7 @@ static int allocateBtreePage(
      ** becomes a new pointer-map page, the second is used by the caller.
      */
      MemPage *pPg = 0;
-
      TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
+
      TRACE(("ALLOCATE: %u from end of file (pointer-map page)\n", pBt->nPage));
      assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
      rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent);
      if( rc==SQLITE_OK ){
@@ -74608,7 +75321,7 @@ static int allocateBtreePage(
      releasePage(*ppPage);
      *ppPage = 0;
    }
-
    TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
+
    TRACE(("ALLOCATE: %u from end of file\n", *pPgno));
  }

  assert( CORRUPT_DB || *pPgno!=PENDING_BYTE_PAGE(pBt) );
@@ -74676,7 +75389,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
  /* If the database supports auto-vacuum, write an entry in the pointer-map
  ** to indicate that the page is free.
  */
-
  if( ISAUTOVACUUM ){
+
  if( ISAUTOVACUUM(pBt) ){
    ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc);
    if( rc ) goto freepage_out;
  }
@@ -74736,7 +75449,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
        }
        rc = btreeSetHasContent(pBt, iPage);
      }
-
      TRACE(("FREE-PAGE: %d leaf on trunk page %d\n",pPage->pgno,pTrunk->pgno));
+
      TRACE(("FREE-PAGE: %u leaf on trunk page %u\n",pPage->pgno,pTrunk->pgno));
      goto freepage_out;
    }
  }
@@ -74757,7 +75470,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
  put4byte(pPage->aData, iTrunk);
  put4byte(&pPage->aData[4], 0);
  put4byte(&pPage1->aData[32], iPage);
-
  TRACE(("FREE-PAGE: %d new trunk page replacing %d\n", pPage->pgno, iTrunk));
+
  TRACE(("FREE-PAGE: %u new trunk page replacing %u\n", pPage->pgno, iTrunk));

freepage_out:
  if( pPage ){
@@ -75117,23 +75830,27 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
** Allocating a new entry in pPage->aCell[] implies that
** pPage->nOverflow is incremented.
**
-
** *pRC must be SQLITE_OK when this routine is called.
+
** The insertCellFast() routine below works exactly the same as
+
** insertCell() except that it lacks the pTemp and iChild parameters
+
** which are assumed zero.  Other than that, the two routines are the
+
** same.
+
**
+
** Fixes or enhancements to this routine should be reflected in
+
** insertCellFast()!
*/
-
static void insertCell(
+
static int insertCell(
  MemPage *pPage,   /* Page into which we are copying */
  int i,            /* New cell becomes the i-th cell of the page */
  u8 *pCell,        /* Content of the new cell */
  int sz,           /* Bytes of content in pCell */
  u8 *pTemp,        /* Temp storage space for pCell, if needed */
-
  Pgno iChild,      /* If non-zero, replace first 4 bytes with this value */
-
  int *pRC          /* Read and write return code from here */
+
  Pgno iChild       /* If non-zero, replace first 4 bytes with this value */
){
  int idx = 0;      /* Where to write new cell content in data[] */
  int j;            /* Loop counter */
  u8 *data;         /* The content of the whole page */
  u8 *pIns;         /* The point in pPage->aCellIdx[] where no cell inserted */

-
  assert( *pRC==SQLITE_OK );
  assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
  assert( MX_CELL(pPage->pBt)<=10921 );
  assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB );
@@ -75142,14 +75859,103 @@ static void insertCell(
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB );
  assert( pPage->nFree>=0 );
+
  assert( iChild>0 );
  if( pPage->nOverflow || sz+2>pPage->nFree ){
    if( pTemp ){
      memcpy(pTemp, pCell, sz);
      pCell = pTemp;
    }
-
    if( iChild ){
-
      put4byte(pCell, iChild);
+
    put4byte(pCell, iChild);
+
    j = pPage->nOverflow++;
+
    /* Comparison against ArraySize-1 since we hold back one extra slot
+
    ** as a contingency.  In other words, never need more than 3 overflow
+
    ** slots but 4 are allocated, just to be safe. */
+
    assert( j < ArraySize(pPage->apOvfl)-1 );
+
    pPage->apOvfl[j] = pCell;
+
    pPage->aiOvfl[j] = (u16)i;
+

+
    /* When multiple overflows occur, they are always sequential and in
+
    ** sorted order.  This invariants arise because multiple overflows can
+
    ** only occur when inserting divider cells into the parent page during
+
    ** balancing, and the dividers are adjacent and sorted.
+
    */
+
    assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */
+
    assert( j==0 || i==pPage->aiOvfl[j-1]+1 );   /* Overflows are sequential */
+
  }else{
+
    int rc = sqlite3PagerWrite(pPage->pDbPage);
+
    if( NEVER(rc!=SQLITE_OK) ){
+
      return rc;
    }
+
    assert( sqlite3PagerIswriteable(pPage->pDbPage) );
+
    data = pPage->aData;
+
    assert( &data[pPage->cellOffset]==pPage->aCellIdx );
+
    rc = allocateSpace(pPage, sz, &idx);
+
    if( rc ){ return rc; }
+
    /* The allocateSpace() routine guarantees the following properties
+
    ** if it returns successfully */
+
    assert( idx >= 0 );
+
    assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB );
+
    assert( idx+sz <= (int)pPage->pBt->usableSize );
+
    pPage->nFree -= (u16)(2 + sz);
+
    /* In a corrupt database where an entry in the cell index section of
+
    ** a btree page has a value of 3 or less, the pCell value might point
+
    ** as many as 4 bytes in front of the start of the aData buffer for
+
    ** the source page.  Make sure this does not cause problems by not
+
    ** reading the first 4 bytes */
+
    memcpy(&data[idx+4], pCell+4, sz-4);
+
    put4byte(&data[idx], iChild);
+
    pIns = pPage->aCellIdx + i*2;
+
    memmove(pIns+2, pIns, 2*(pPage->nCell - i));
+
    put2byte(pIns, idx);
+
    pPage->nCell++;
+
    /* increment the cell count */
+
    if( (++data[pPage->hdrOffset+4])==0 ) data[pPage->hdrOffset+3]++;
+
    assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB );
+
#ifndef SQLITE_OMIT_AUTOVACUUM
+
    if( pPage->pBt->autoVacuum ){
+
      int rc2 = SQLITE_OK;
+
      /* The cell may contain a pointer to an overflow page. If so, write
+
      ** the entry for the overflow page into the pointer map.
+
      */
+
      ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2);
+
      if( rc2 ) return rc2;
+
    }
+
#endif
+
  }
+
  return SQLITE_OK;
+
}
+

+
/*
+
** This variant of insertCell() assumes that the pTemp and iChild
+
** parameters are both zero.  Use this variant in sqlite3BtreeInsert()
+
** for performance improvement, and also so that this variant is only
+
** called from that one place, and is thus inlined, and thus runs must
+
** faster.
+
**
+
** Fixes or enhancements to this routine should be reflected into
+
** the insertCell() routine.
+
*/
+
static int insertCellFast(
+
  MemPage *pPage,   /* Page into which we are copying */
+
  int i,            /* New cell becomes the i-th cell of the page */
+
  u8 *pCell,        /* Content of the new cell */
+
  int sz            /* Bytes of content in pCell */
+
){
+
  int idx = 0;      /* Where to write new cell content in data[] */
+
  int j;            /* Loop counter */
+
  u8 *data;         /* The content of the whole page */
+
  u8 *pIns;         /* The point in pPage->aCellIdx[] where no cell inserted */
+

+
  assert( i>=0 && i<=pPage->nCell+pPage->nOverflow );
+
  assert( MX_CELL(pPage->pBt)<=10921 );
+
  assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB );
+
  assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) );
+
  assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) );
+
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
+
  assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB );
+
  assert( pPage->nFree>=0 );
+
  assert( pPage->nOverflow==0 );
+
  if( sz+2>pPage->nFree ){
    j = pPage->nOverflow++;
    /* Comparison against ArraySize-1 since we hold back one extra slot
    ** as a contingency.  In other words, never need more than 3 overflow
@@ -75168,31 +75974,20 @@ static void insertCell(
  }else{
    int rc = sqlite3PagerWrite(pPage->pDbPage);
    if( rc!=SQLITE_OK ){
-
      *pRC = rc;
-
      return;
+
      return rc;
    }
    assert( sqlite3PagerIswriteable(pPage->pDbPage) );
    data = pPage->aData;
    assert( &data[pPage->cellOffset]==pPage->aCellIdx );
    rc = allocateSpace(pPage, sz, &idx);
-
    if( rc ){ *pRC = rc; return; }
+
    if( rc ){ return rc; }
    /* The allocateSpace() routine guarantees the following properties
    ** if it returns successfully */
    assert( idx >= 0 );
    assert( idx >= pPage->cellOffset+2*pPage->nCell+2 || CORRUPT_DB );
    assert( idx+sz <= (int)pPage->pBt->usableSize );
    pPage->nFree -= (u16)(2 + sz);
-
    if( iChild ){
-
      /* In a corrupt database where an entry in the cell index section of
-
      ** a btree page has a value of 3 or less, the pCell value might point
-
      ** as many as 4 bytes in front of the start of the aData buffer for
-
      ** the source page.  Make sure this does not cause problems by not
-
      ** reading the first 4 bytes */
-
      memcpy(&data[idx+4], pCell+4, sz-4);
-
      put4byte(&data[idx], iChild);
-
    }else{
-
      memcpy(&data[idx], pCell, sz);
-
    }
+
    memcpy(&data[idx], pCell, sz);
    pIns = pPage->aCellIdx + i*2;
    memmove(pIns+2, pIns, 2*(pPage->nCell - i));
    put2byte(pIns, idx);
@@ -75202,13 +75997,16 @@ static void insertCell(
    assert( get2byte(&data[pPage->hdrOffset+3])==pPage->nCell || CORRUPT_DB );
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pPage->pBt->autoVacuum ){
+
      int rc2 = SQLITE_OK;
      /* The cell may contain a pointer to an overflow page. If so, write
      ** the entry for the overflow page into the pointer map.
      */
-
      ptrmapPutOvflPtr(pPage, pPage, pCell, pRC);
+
      ptrmapPutOvflPtr(pPage, pPage, pCell, &rc2);
+
      if( rc2 ) return rc2;
    }
#endif
  }
+
  return SQLITE_OK;
}

/*
@@ -75309,14 +76107,16 @@ struct CellArray {
** computed.
*/
static void populateCellCache(CellArray *p, int idx, int N){
+
  MemPage *pRef = p->pRef;
+
  u16 *szCell = p->szCell;
  assert( idx>=0 && idx+N<=p->nCell );
  while( N>0 ){
    assert( p->apCell[idx]!=0 );
-
    if( p->szCell[idx]==0 ){
-
      p->szCell[idx] = p->pRef->xCellSize(p->pRef, p->apCell[idx]);
+
    if( szCell[idx]==0 ){
+
      szCell[idx] = pRef->xCellSize(pRef, p->apCell[idx]);
    }else{
      assert( CORRUPT_DB ||
-
              p->szCell[idx]==p->pRef->xCellSize(p->pRef, p->apCell[idx]) );
+
              szCell[idx]==pRef->xCellSize(pRef, p->apCell[idx]) );
    }
    idx++;
    N--;
@@ -75372,7 +76172,7 @@ static int rebuildPage(

  assert( i<iEnd );
  j = get2byte(&aData[hdr+5]);
-
  if( j>(u32)usableSize ){ j = 0; }
+
  if( NEVER(j>(u32)usableSize) ){ j = 0; }
  memcpy(&pTmp[j], &aData[j], usableSize - j);

  for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
@@ -75516,39 +76316,50 @@ static int pageFreeArray(
  u8 * const pEnd = &aData[pPg->pBt->usableSize];
  u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
  int nRet = 0;
-
  int i;
+
  int i, j;
  int iEnd = iFirst + nCell;
-
  u8 *pFree = 0;
-
  int szFree = 0;
+
  int nFree = 0;
+
  int aOfst[10];
+
  int aAfter[10];

  for(i=iFirst; i<iEnd; i++){
    u8 *pCell = pCArray->apCell[i];
    if( SQLITE_WITHIN(pCell, pStart, pEnd) ){
      int sz;
+
      int iAfter;
+
      int iOfst;
      /* No need to use cachedCellSize() here.  The sizes of all cells that
      ** are to be freed have already been computing while deciding which
      ** cells need freeing */
      sz = pCArray->szCell[i];  assert( sz>0 );
-
      if( pFree!=(pCell + sz) ){
-
        if( pFree ){
-
          assert( pFree>aData && (pFree - aData)<65536 );
-
          freeSpace(pPg, (u16)(pFree - aData), szFree);
-
        }
-
        pFree = pCell;
-
        szFree = sz;
-
        if( pFree+sz>pEnd ){
-
          return 0;
+
      iOfst = (u16)(pCell - aData);
+
      iAfter = iOfst+sz;
+
      for(j=0; j<nFree; j++){
+
        if( aOfst[j]==iAfter ){
+
          aOfst[j] = iOfst;
+
          break;
+
        }else if( aAfter[j]==iOfst ){
+
          aAfter[j] = iAfter;
+
          break;
        }
-
      }else{
-
        pFree = pCell;
-
        szFree += sz;
+
      }
+
      if( j>=nFree ){
+
        if( nFree>=(int)(sizeof(aOfst)/sizeof(aOfst[0])) ){
+
          for(j=0; j<nFree; j++){
+
            freeSpace(pPg, aOfst[j], aAfter[j]-aOfst[j]);
+
          }
+
          nFree = 0;
+
        }
+
        aOfst[nFree] = iOfst;
+
        aAfter[nFree] = iAfter;
+
        if( &aData[iAfter]>pEnd ) return 0;
+
        nFree++;
      }
      nRet++;
    }
  }
-
  if( pFree ){
-
    assert( pFree>aData && (pFree - aData)<65536 );
-
    freeSpace(pPg, (u16)(pFree - aData), szFree);
+
  for(j=0; j<nFree; j++){
+
    freeSpace(pPg, aOfst[j], aAfter[j]-aOfst[j]);
  }
  return nRet;
}
@@ -75601,9 +76412,9 @@ static int editPage(
    nCell -= nTail;
  }

-
  pData = &aData[get2byteNotZero(&aData[hdr+5])];
+
  pData = &aData[get2byte(&aData[hdr+5])];
  if( pData<pBegin ) goto editpage_fail;
-
  if( pData>pPg->aDataEnd ) goto editpage_fail;
+
  if( NEVER(pData>pPg->aDataEnd) ) goto editpage_fail;

  /* Add cells to the start of the page */
  if( iNew<iOld ){
@@ -75747,7 +76558,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
    ** be marked as dirty. Returning an error code will cause a
    ** rollback, undoing any changes made to the parent page.
    */
-
    if( ISAUTOVACUUM ){
+
    if( ISAUTOVACUUM(pBt) ){
      ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc);
      if( szCell>pNew->minLocal ){
        ptrmapPutOvflPtr(pNew, pNew, pCell, &rc);
@@ -75775,8 +76586,8 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){

    /* Insert the new divider cell into pParent. */
    if( rc==SQLITE_OK ){
-
      insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace),
-
                   0, pPage->pgno, &rc);
+
      rc = insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace),
+
                      0, pPage->pgno);
    }

    /* Set the right-child pointer of pParent to point to the new page. */
@@ -75885,7 +76696,7 @@ static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){
    /* If this is an auto-vacuum database, update the pointer-map entries
    ** for any b-tree or overflow pages that pTo now contains the pointers to.
    */
-
    if( ISAUTOVACUUM ){
+
    if( ISAUTOVACUUM(pBt) ){
      *pRC = setChildPtrmaps(pTo);
    }
  }
@@ -76309,15 +77120,17 @@ static int balance_nonroot(
    d = r + 1 - leafData;
    (void)cachedCellSize(&b, d);
    do{
+
      int szR, szD;
      assert( d<nMaxCells );
      assert( r<nMaxCells );
-
      (void)cachedCellSize(&b, r);
+
      szR = cachedCellSize(&b, r);
+
      szD = b.szCell[d];
      if( szRight!=0
-
       && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){
+
       && (bBulk || szRight+szD+2 > szLeft-(szR+(i==k-1?0:2)))){
        break;
      }
-
      szRight += b.szCell[d] + 2;
-
      szLeft -= b.szCell[r] + 2;
+
      szRight += szD + 2;
+
      szLeft -= szR + 2;
      cntNew[i-1] = r;
      r--;
      d--;
@@ -76338,7 +77151,7 @@ static int balance_nonroot(
  **        that page.
  */
  assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB);
-
  TRACE(("BALANCE: old: %d(nc=%d) %d(nc=%d) %d(nc=%d)\n",
+
  TRACE(("BALANCE: old: %u(nc=%u) %u(nc=%u) %u(nc=%u)\n",
    apOld[0]->pgno, apOld[0]->nCell,
    nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0,
    nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0
@@ -76371,7 +77184,7 @@ static int balance_nonroot(
      cntOld[i] = b.nCell;

      /* Set the pointer-map entry for the new sibling page. */
-
      if( ISAUTOVACUUM ){
+
      if( ISAUTOVACUUM(pBt) ){
        ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc);
        if( rc!=SQLITE_OK ){
          goto balance_cleanup;
@@ -76422,8 +77235,8 @@ static int balance_nonroot(
    }
  }

-
  TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) "
-
         "%d(%d nc=%d) %d(%d nc=%d)\n",
+
  TRACE(("BALANCE: new: %u(%u nc=%u) %u(%u nc=%u) %u(%u nc=%u) "
+
         "%u(%u nc=%u) %u(%u nc=%u)\n",
    apNew[0]->pgno, szNew[0], cntNew[0],
    nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0,
    nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0,
@@ -76464,7 +77277,7 @@ static int balance_nonroot(
  ** updated. This happens below, after the sibling pages have been
  ** populated, not here.
  */
-
  if( ISAUTOVACUUM ){
+
  if( ISAUTOVACUUM(pBt) ){
    MemPage *pOld;
    MemPage *pNew = pOld = apNew[0];
    int cntOldNext = pNew->nCell + pNew->nOverflow;
@@ -76561,7 +77374,7 @@ static int balance_nonroot(
      rc = SQLITE_CORRUPT_BKPT;
      goto balance_cleanup;
    }
-
    insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc);
+
    rc = insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno);
    if( rc!=SQLITE_OK ) goto balance_cleanup;
    assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  }
@@ -76657,7 +77470,7 @@ static int balance_nonroot(
    );
    copyNodeContent(apNew[0], pParent, &rc);
    freePage(apNew[0], &rc);
-
  }else if( ISAUTOVACUUM && !leafCorrection ){
+
  }else if( ISAUTOVACUUM(pBt) && !leafCorrection ){
    /* Fix the pointer map entries associated with the right-child of each
    ** sibling page. All other pointer map entries have already been taken
    ** care of.  */
@@ -76668,7 +77481,7 @@ static int balance_nonroot(
  }

  assert( pParent->isInit );
-
  TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n",
+
  TRACE(("BALANCE: finished: old=%u new=%u cells=%u\n",
          nOld, nNew, b.nCell));

  /* Free any old pages that were not reused as new pages.
@@ -76678,7 +77491,7 @@ static int balance_nonroot(
  }

#if 0
-
  if( ISAUTOVACUUM && rc==SQLITE_OK && apNew[0]->isInit ){
+
  if( ISAUTOVACUUM(pBt) && rc==SQLITE_OK && apNew[0]->isInit ){
    /* The ptrmapCheckPages() contains assert() statements that verify that
    ** all pointer map pages are set correctly. This is helpful while
    ** debugging. This is usually disabled because a corrupt database may
@@ -76740,7 +77553,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
  if( rc==SQLITE_OK ){
    rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0);
    copyNodeContent(pRoot, pChild, &rc);
-
    if( ISAUTOVACUUM ){
+
    if( ISAUTOVACUUM(pBt) ){
      ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc);
    }
  }
@@ -76753,7 +77566,7 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){
  assert( sqlite3PagerIswriteable(pRoot->pDbPage) );
  assert( pChild->nCell==pRoot->nCell || CORRUPT_DB );

-
  TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno));
+
  TRACE(("BALANCE: copy root %u into %u\n", pRoot->pgno, pChild->pgno));

  /* Copy the overflow cells from pRoot to pChild */
  memcpy(pChild->aiOvfl, pRoot->aiOvfl,
@@ -76979,9 +77792,13 @@ static int btreeOverwriteContent(

/*
** Overwrite the cell that cursor pCur is pointing to with fresh content
-
** contained in pX.
+
** contained in pX.  In this variant, pCur is pointing to an overflow
+
** cell.
*/
-
static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
+
static SQLITE_NOINLINE int btreeOverwriteOverflowCell(
+
  BtCursor *pCur,                     /* Cursor pointing to cell to ovewrite */
+
  const BtreePayload *pX              /* Content to write into the cell */
+
){
  int iOffset;                        /* Next byte of pX->pData to write */
  int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */
  int rc;                             /* Return code */
@@ -76990,16 +77807,12 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
  Pgno ovflPgno;                      /* Next overflow page to write */
  u32 ovflPageSize;                   /* Size to write on overflow page */

-
  if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd
-
   || pCur->info.pPayload < pPage->aData + pPage->cellOffset
-
  ){
-
    return SQLITE_CORRUPT_BKPT;
-
  }
+
  assert( pCur->info.nLocal<nTotal );  /* pCur is an overflow cell */
+

  /* Overwrite the local portion first */
  rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX,
                             0, pCur->info.nLocal);
  if( rc ) return rc;
-
  if( pCur->info.nLocal==nTotal ) return SQLITE_OK;

  /* Now overwrite the overflow pages */
  iOffset = pCur->info.nLocal;
@@ -77029,6 +77842,29 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
  return SQLITE_OK;
}

+
/*
+
** Overwrite the cell that cursor pCur is pointing to with fresh content
+
** contained in pX.
+
*/
+
static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){
+
  int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */
+
  MemPage *pPage = pCur->pPage;       /* Page being written */
+

+
  if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd
+
   || pCur->info.pPayload < pPage->aData + pPage->cellOffset
+
  ){
+
    return SQLITE_CORRUPT_BKPT;
+
  }
+
  if( pCur->info.nLocal==nTotal ){
+
    /* The entire cell is local */
+
    return btreeOverwriteContent(pPage, pCur->info.pPayload, pX,
+
                                 0, pCur->info.nLocal);
+
  }else{
+
    /* The cell contains overflow content */
+
    return btreeOverwriteOverflowCell(pCur, pX);
+
  }
+
}
+


/*
** Insert a new record into the BTree.  The content of the new record
@@ -77072,7 +77908,6 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
  int idx;
  MemPage *pPage;
  Btree *p = pCur->pBtree;
-
  BtShared *pBt = p->pBt;
  unsigned char *oldCell;
  unsigned char *newCell = 0;

@@ -77091,7 +77926,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
  ** not to clear the cursor here.
  */
  if( pCur->curFlags & BTCF_Multiple ){
-
    rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
+
    rc = saveAllCursors(p->pBt, pCur->pgnoRoot, pCur);
    if( rc ) return rc;
    if( loc && pCur->iPage<0 ){
      /* This can only happen if the schema is corrupt such that there is more
@@ -77115,8 +77950,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(

  assert( cursorOwnsBtShared(pCur) );
  assert( (pCur->curFlags & BTCF_WriteFlag)!=0
-
              && pBt->inTransaction==TRANS_WRITE
-
              && (pBt->btsFlags & BTS_READ_ONLY)==0 );
+
              && p->pBt->inTransaction==TRANS_WRITE
+
              && (p->pBt->btsFlags & BTS_READ_ONLY)==0 );
  assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );

  /* Assert that the caller has been consistent. If this cursor was opened
@@ -77214,7 +78049,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
    }
  }
  assert( pCur->eState==CURSOR_VALID
-
       || (pCur->eState==CURSOR_INVALID && loc) );
+
       || (pCur->eState==CURSOR_INVALID && loc) || CORRUPT_DB );

  pPage = pCur->pPage;
  assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
@@ -77229,31 +78064,34 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
    if( rc ) return rc;
  }

-
  TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n",
+
  TRACE(("INSERT: table=%u nkey=%lld ndata=%u page=%u %s\n",
          pCur->pgnoRoot, pX->nKey, pX->nData, pPage->pgno,
          loc==0 ? "overwrite" : "new entry"));
  assert( pPage->isInit || CORRUPT_DB );
-
  newCell = pBt->pTmpSpace;
+
  newCell = p->pBt->pTmpSpace;
  assert( newCell!=0 );
+
  assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT );
  if( flags & BTREE_PREFORMAT ){
    rc = SQLITE_OK;
-
    szNew = pBt->nPreformatSize;
+
    szNew = p->pBt->nPreformatSize;
    if( szNew<4 ) szNew = 4;
-
    if( ISAUTOVACUUM && szNew>pPage->maxLocal ){
+
    if( ISAUTOVACUUM(p->pBt) && szNew>pPage->maxLocal ){
      CellInfo info;
      pPage->xParseCell(pPage, newCell, &info);
      if( info.nPayload!=info.nLocal ){
        Pgno ovfl = get4byte(&newCell[szNew-4]);
-
        ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc);
+
        ptrmapPut(p->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc);
+
        if( NEVER(rc) ) goto end_insert;
      }
    }
  }else{
    rc = fillInCell(pPage, newCell, pX, &szNew);
+
    if( rc ) goto end_insert;
  }
-
  if( rc ) goto end_insert;
  assert( szNew==pPage->xCellSize(pPage, newCell) );
-
  assert( szNew <= MX_CELL_SIZE(pBt) );
+
  assert( szNew <= MX_CELL_SIZE(p->pBt) );
  idx = pCur->ix;
+
  pCur->info.nSize = 0;
  if( loc==0 ){
    CellInfo info;
    assert( idx>=0 );
@@ -77272,7 +78110,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
    testcase( pCur->curFlags & BTCF_ValidOvfl );
    invalidateOverflowCache(pCur);
    if( info.nSize==szNew && info.nLocal==info.nPayload
-
     && (!ISAUTOVACUUM || szNew<pPage->minLocal)
+
     && (!ISAUTOVACUUM(p->pBt) || szNew<pPage->minLocal)
    ){
      /* Overwrite the old cell with the new if they are the same size.
      ** We could also try to do this if the old cell is smaller, then add
@@ -77302,7 +78140,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
  }else{
    assert( pPage->leaf );
  }
-
  insertCell(pPage, idx, newCell, szNew, 0, 0, &rc);
+
  rc = insertCellFast(pPage, idx, newCell, szNew);
  assert( pPage->nOverflow==0 || rc==SQLITE_OK );
  assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 );

@@ -77326,7 +78164,6 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
  ** larger than the largest existing key, it is possible to insert the
  ** row without seeking the cursor. This can be a big performance boost.
  */
-
  pCur->info.nSize = 0;
  if( pPage->nOverflow ){
    assert( rc==SQLITE_OK );
    pCur->curFlags &= ~(BTCF_ValidNKey);
@@ -77375,7 +78212,6 @@ end_insert:
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
*/
SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){
-
  int rc = SQLITE_OK;
  BtShared *pBt = pDest->pBt;
  u8 *aOut = pBt->pTmpSpace;    /* Pointer to next output buffer */
  const u8 *aIn;                /* Pointer to next input buffer */
@@ -77398,7 +78234,9 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64
  if( nIn==nRem && nIn<pDest->pPage->maxLocal ){
    memcpy(aOut, aIn, nIn);
    pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace);
+
    return SQLITE_OK;
  }else{
+
    int rc = SQLITE_OK;
    Pager *pSrcPager = pSrc->pBt->pPager;
    u8 *pPgnoOut = 0;
    Pgno ovflIn = 0;
@@ -77450,7 +78288,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64
        MemPage *pNew = 0;
        rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
        put4byte(pPgnoOut, pgnoNew);
-
        if( ISAUTOVACUUM && pPageOut ){
+
        if( ISAUTOVACUUM(pBt) && pPageOut ){
          ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc);
        }
        releasePage(pPageOut);
@@ -77466,9 +78304,8 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64

    releasePage(pPageOut);
    sqlite3PagerUnref(pPageIn);
+
    return rc;
  }
-

-
  return rc;
}

/*
@@ -77527,6 +78364,9 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
  if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){
    return SQLITE_CORRUPT_BKPT;
  }
+
  if( pCell<&pPage->aCellIdx[pPage->nCell] ){
+
    return SQLITE_CORRUPT_BKPT;
+
  }

  /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must
  ** be preserved following this delete operation. If the current delete
@@ -77623,7 +78463,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
    assert( pTmp!=0 );
    rc = sqlite3PagerWrite(pLeaf->pDbPage);
    if( rc==SQLITE_OK ){
-
      insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
+
      rc = insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n);
    }
    dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
    if( rc ) return rc;
@@ -78223,6 +79063,41 @@ SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){

#ifndef SQLITE_OMIT_INTEGRITY_CHECK
/*
+
** Record an OOM error during integrity_check
+
*/
+
static void checkOom(IntegrityCk *pCheck){
+
  pCheck->rc = SQLITE_NOMEM;
+
  pCheck->mxErr = 0;  /* Causes integrity_check processing to stop */
+
  if( pCheck->nErr==0 ) pCheck->nErr++;
+
}
+

+
/*
+
** Invoke the progress handler, if appropriate.  Also check for an
+
** interrupt.
+
*/
+
static void checkProgress(IntegrityCk *pCheck){
+
  sqlite3 *db = pCheck->db;
+
  if( AtomicLoad(&db->u1.isInterrupted) ){
+
    pCheck->rc = SQLITE_INTERRUPT;
+
    pCheck->nErr++;
+
    pCheck->mxErr = 0;
+
  }
+
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
+
  if( db->xProgress ){
+
    assert( db->nProgressOps>0 );
+
    pCheck->nStep++;
+
    if( (pCheck->nStep % db->nProgressOps)==0
+
     && db->xProgress(db->pProgressArg)
+
    ){
+
      pCheck->rc = SQLITE_INTERRUPT;
+
      pCheck->nErr++;
+
      pCheck->mxErr = 0;
+
    }
+
  }
+
#endif
+
}
+

+
/*
** Append a message to the error message string.
*/
static void checkAppendMsg(
@@ -78231,6 +79106,7 @@ static void checkAppendMsg(
  ...
){
  va_list ap;
+
  checkProgress(pCheck);
  if( !pCheck->mxErr ) return;
  pCheck->mxErr--;
  pCheck->nErr++;
@@ -78239,12 +79115,13 @@ static void checkAppendMsg(
    sqlite3_str_append(&pCheck->errMsg, "\n", 1);
  }
  if( pCheck->zPfx ){
-
    sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
+
    sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx,
+
                        pCheck->v0, pCheck->v1, pCheck->v2);
  }
  sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap);
  va_end(ap);
  if( pCheck->errMsg.accError==SQLITE_NOMEM ){
-
    pCheck->bOomFault = 1;
+
    checkOom(pCheck);
  }
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -78279,14 +79156,13 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){
*/
static int checkRef(IntegrityCk *pCheck, Pgno iPage){
  if( iPage>pCheck->nPage || iPage==0 ){
-
    checkAppendMsg(pCheck, "invalid page number %d", iPage);
+
    checkAppendMsg(pCheck, "invalid page number %u", iPage);
    return 1;
  }
  if( getPageReferenced(pCheck, iPage) ){
-
    checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
+
    checkAppendMsg(pCheck, "2nd reference to page %u", iPage);
    return 1;
  }
-
  if( AtomicLoad(&pCheck->db->u1.isInterrupted) ) return 1;
  setPageReferenced(pCheck, iPage);
  return 0;
}
@@ -78309,14 +79185,14 @@ static void checkPtrmap(

  rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
  if( rc!=SQLITE_OK ){
-
    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->bOomFault = 1;
-
    checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild);
+
    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) checkOom(pCheck);
+
    checkAppendMsg(pCheck, "Failed to read ptrmap key=%u", iChild);
    return;
  }

  if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
    checkAppendMsg(pCheck,
-
      "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)",
+
      "Bad ptr map entry key=%u expected=(%u,%u) got=(%u,%u)",
      iChild, eType, iParent, ePtrmapType, iPtrmapParent);
  }
}
@@ -78341,7 +79217,7 @@ static void checkList(
    if( checkRef(pCheck, iPage) ) break;
    N--;
    if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
-
      checkAppendMsg(pCheck, "failed to get page %d", iPage);
+
      checkAppendMsg(pCheck, "failed to get page %u", iPage);
      break;
    }
    pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
@@ -78354,7 +79230,7 @@ static void checkList(
#endif
      if( n>pCheck->pBt->usableSize/4-2 ){
        checkAppendMsg(pCheck,
-
           "freelist leaf count too big on page %d", iPage);
+
           "freelist leaf count too big on page %u", iPage);
        N--;
      }else{
        for(i=0; i<(int)n; i++){
@@ -78386,7 +79262,7 @@ static void checkList(
  }
  if( N && nErrAtStart==pCheck->nErr ){
    checkAppendMsg(pCheck,
-
      "%s is %d but should be %d",
+
      "%s is %u but should be %u",
      isFreeList ? "size" : "overflow list length",
      expected-N, expected);
  }
@@ -78416,7 +79292,9 @@ static void checkList(
** lower 16 bits are the index of the last byte of that range.
*/
static void btreeHeapInsert(u32 *aHeap, u32 x){
-
  u32 j, i = ++aHeap[0];
+
  u32 j, i;
+
  assert( aHeap!=0 );
+
  i = ++aHeap[0];
  aHeap[i] = x;
  while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){
    x = aHeap[j];
@@ -78493,12 +79371,14 @@ static int checkTreePage(

  /* Check that the page exists
  */
+
  checkProgress(pCheck);
+
  if( pCheck->mxErr==0 ) goto end_of_check;
  pBt = pCheck->pBt;
  usableSize = pBt->usableSize;
  if( iPage==0 ) return 0;
  if( checkRef(pCheck, iPage) ) return 0;
-
  pCheck->zPfx = "Page %u: ";
-
  pCheck->v1 = iPage;
+
  pCheck->zPfx = "Tree %u page %u: ";
+
  pCheck->v0 = pCheck->v1 = iPage;
  if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){
    checkAppendMsg(pCheck,
       "unable to get the page. error code=%d", rc);
@@ -78524,7 +79404,7 @@ static int checkTreePage(
  hdr = pPage->hdrOffset;

  /* Set up for cell analysis */
-
  pCheck->zPfx = "On tree page %u cell %d: ";
+
  pCheck->zPfx = "Tree %u page %u cell %u: ";
  contentOffset = get2byteNotZero(&data[hdr+5]);
  assert( contentOffset<=usableSize );  /* Enforced by btreeInitPage() */

@@ -78544,7 +79424,7 @@ static int checkTreePage(
    pgno = get4byte(&data[hdr+8]);
#ifndef SQLITE_OMIT_AUTOVACUUM
    if( pBt->autoVacuum ){
-
      pCheck->zPfx = "On page %u at right child: ";
+
      pCheck->zPfx = "Tree %u page %u right child: ";
      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
    }
#endif
@@ -78568,7 +79448,7 @@ static int checkTreePage(
    pc = get2byteAligned(pCellIdx);
    pCellIdx -= 2;
    if( pc<contentOffset || pc>usableSize-4 ){
-
      checkAppendMsg(pCheck, "Offset %d out of range %d..%d",
+
      checkAppendMsg(pCheck, "Offset %u out of range %u..%u",
                             pc, contentOffset, usableSize-4);
      doCoverageCheck = 0;
      continue;
@@ -78700,7 +79580,7 @@ static int checkTreePage(
    */
    if( heap[0]==0 && nFrag!=data[hdr+7] ){
      checkAppendMsg(pCheck,
-
          "Fragmentation of %d bytes reported as %d on page %u",
+
          "Fragmentation of %u bytes reported as %u on page %u",
          nFrag, data[hdr+7], iPage);
    }
  }
@@ -78738,13 +79618,14 @@ end_of_check:
** the unverified btrees.  Except, if aRoot[1] is 1, then the freelist
** checks are still performed.
*/
-
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
+
SQLITE_PRIVATE int sqlite3BtreeIntegrityCheck(
  sqlite3 *db,  /* Database connection that is running the check */
  Btree *p,     /* The btree to be checked */
  Pgno *aRoot,  /* An array of root pages numbers for individual trees */
  int nRoot,    /* Number of entries in aRoot[] */
  int mxErr,    /* Stop reporting errors after this many */
-
  int *pnErr    /* Write number of errors seen to this variable */
+
  int *pnErr,   /* OUT: Write number of errors seen to this variable */
+
  char **pzOut  /* OUT: Write the error message string here */
){
  Pgno i;
  IntegrityCk sCheck;
@@ -78767,18 +79648,12 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
  assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE );
  VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) );
  assert( nRef>=0 );
+
  memset(&sCheck, 0, sizeof(sCheck));
  sCheck.db = db;
  sCheck.pBt = pBt;
  sCheck.pPager = pBt->pPager;
  sCheck.nPage = btreePagecount(sCheck.pBt);
  sCheck.mxErr = mxErr;
-
  sCheck.nErr = 0;
-
  sCheck.bOomFault = 0;
-
  sCheck.zPfx = 0;
-
  sCheck.v1 = 0;
-
  sCheck.v2 = 0;
-
  sCheck.aPgRef = 0;
-
  sCheck.heap = 0;
  sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
  sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL;
  if( sCheck.nPage==0 ){
@@ -78787,12 +79662,12 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(

  sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
  if( !sCheck.aPgRef ){
-
    sCheck.bOomFault = 1;
+
    checkOom(&sCheck);
    goto integrity_ck_cleanup;
  }
  sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
  if( sCheck.heap==0 ){
-
    sCheck.bOomFault = 1;
+
    checkOom(&sCheck);
    goto integrity_ck_cleanup;
  }

@@ -78802,7 +79677,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
  /* Check the integrity of the freelist
  */
  if( bCkFreelist ){
-
    sCheck.zPfx = "Main freelist: ";
+
    sCheck.zPfx = "Freelist: ";
    checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
              get4byte(&pBt->pPage1->aData[36]));
    sCheck.zPfx = 0;
@@ -78819,7 +79694,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
      mxInHdr = get4byte(&pBt->pPage1->aData[52]);
      if( mx!=mxInHdr ){
        checkAppendMsg(&sCheck,
-
          "max rootpage (%d) disagrees with header (%d)",
+
          "max rootpage (%u) disagrees with header (%u)",
          mx, mxInHdr
        );
      }
@@ -78850,7 +79725,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
    for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
#ifdef SQLITE_OMIT_AUTOVACUUM
      if( getPageReferenced(&sCheck, i)==0 ){
-
        checkAppendMsg(&sCheck, "Page %d is never used", i);
+
        checkAppendMsg(&sCheck, "Page %u: never used", i);
      }
#else
      /* If the database supports auto-vacuum, make sure no tables contain
@@ -78858,11 +79733,11 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
      */
      if( getPageReferenced(&sCheck, i)==0 &&
         (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
-
        checkAppendMsg(&sCheck, "Page %d is never used", i);
+
        checkAppendMsg(&sCheck, "Page %u: never used", i);
      }
      if( getPageReferenced(&sCheck, i)!=0 &&
         (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
-
        checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i);
+
        checkAppendMsg(&sCheck, "Page %u: pointer map referenced", i);
      }
#endif
    }
@@ -78873,16 +79748,17 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
integrity_ck_cleanup:
  sqlite3PageFree(sCheck.heap);
  sqlite3_free(sCheck.aPgRef);
-
  if( sCheck.bOomFault ){
+
  *pnErr = sCheck.nErr;
+
  if( sCheck.nErr==0 ){
    sqlite3_str_reset(&sCheck.errMsg);
-
    sCheck.nErr++;
+
    *pzOut = 0;
+
  }else{
+
    *pzOut = sqlite3StrAccumFinish(&sCheck.errMsg);
  }
-
  *pnErr = sCheck.nErr;
-
  if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg);
  /* Make sure this analysis did not leave any unref() pages. */
  assert( nRef==sqlite3PagerRefcount(pBt->pPager) );
  sqlite3BtreeLeave(p);
-
  return sqlite3StrAccumFinish(&sCheck.errMsg);
+
  return sCheck.rc;
}
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */

@@ -79147,6 +80023,17 @@ SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){
*/
SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }

+
/*
+
** If no transaction is active and the database is not a temp-db, clear
+
** the in-memory pager cache.
+
*/
+
SQLITE_PRIVATE void sqlite3BtreeClearCache(Btree *p){
+
  BtShared *pBt = p->pBt;
+
  if( pBt->inTransaction==TRANS_NONE ){
+
    sqlite3PagerClearCache(pBt->pPager);
+
  }
+
}
+

#if !defined(SQLITE_OMIT_SHARED_CACHE)
/*
** Return true if the Btree passed as the only argument is sharable.
@@ -79412,13 +80299,7 @@ static int backupOnePage(
  assert( !isFatalError(p->rc) );
  assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) );
  assert( zSrcData );
-

-
  /* Catch the case where the destination is an in-memory database and the
-
  ** page sizes of the source and destination differ.
-
  */
-
  if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){
-
    rc = SQLITE_READONLY;
-
  }
+
  assert( nSrcPgsz==nDestPgsz || sqlite3PagerIsMemdb(pDestPager)==0 );

  /* This loop runs once for each destination page spanned by the source
  ** page. For each iteration, variable iOff is set to the byte offset
@@ -79551,7 +80432,10 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
    pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
    pgszDest = sqlite3BtreeGetPageSize(p->pDest);
    destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest));
-
    if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){
+
    if( SQLITE_OK==rc
+
     && (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager))
+
     && pgszSrc!=pgszDest
+
    ){
      rc = SQLITE_READONLY;
    }

@@ -80057,9 +80941,9 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
    i64 x;
    assert( (p->flags&MEM_Int)*2==sizeof(x) );
    memcpy(&x, (char*)&p->u, (p->flags&MEM_Int)*2);
-
    sqlite3Int64ToText(x, zBuf);
+
    p->n = sqlite3Int64ToText(x, zBuf);
#else
-
    sqlite3Int64ToText(p->u.i, zBuf);
+
    p->n = sqlite3Int64ToText(p->u.i, zBuf);
#endif
  }else{
    sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0);
@@ -80067,6 +80951,7 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
         (p->flags & MEM_IntReal)!=0 ? (double)p->u.i : p->u.r);
    assert( acc.zText==zBuf && acc.mxAlloc<=0 );
    zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */
+
    p->n = acc.nChar;
  }
}

@@ -80094,10 +80979,12 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){
** This routine is for use inside of assert() statements only.
*/
SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){
+
  Mem tmp;
  char zBuf[100];
  char *z;
  int i, j, incr;
  if( (p->flags & MEM_Str)==0 ) return 1;
+
  if( p->db && p->db->mallocFailed ) return 1;
  if( p->flags & MEM_Term ){
    /* Insure that the string is properly zero-terminated.  Pay particular
    ** attention to the case where p->n is odd */
@@ -80110,7 +80997,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){
    assert( p->enc==SQLITE_UTF8 || p->z[((p->n+1)&~1)+1]==0 );
  }
  if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1;
-
  vdbeMemRenderNum(sizeof(zBuf), zBuf, p);
+
  memcpy(&tmp, p, sizeof(tmp));
+
  vdbeMemRenderNum(sizeof(zBuf), zBuf, &tmp);
  z = p->z;
  i = j = 0;
  incr = 1;
@@ -80379,7 +81267,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){

  vdbeMemRenderNum(nByte, pMem->z, pMem);
  assert( pMem->z!=0 );
-
  pMem->n = sqlite3Strlen30NN(pMem->z);
+
  assert( pMem->n==(int)sqlite3Strlen30NN(pMem->z) );
  pMem->enc = SQLITE_UTF8;
  pMem->flags |= MEM_Str|MEM_Term;
  if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal);
@@ -80619,32 +81507,35 @@ SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){
}

/*
-
** The MEM structure is already a MEM_Real.  Try to also make it a
-
** MEM_Int if we can.
+
** The MEM structure is already a MEM_Real or MEM_IntReal. Try to
+
** make it a MEM_Int if we can.
*/
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
-
  i64 ix;
  assert( pMem!=0 );
-
  assert( pMem->flags & MEM_Real );
+
  assert( pMem->flags & (MEM_Real|MEM_IntReal) );
  assert( !sqlite3VdbeMemIsRowSet(pMem) );
  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
  assert( EIGHT_BYTE_ALIGNMENT(pMem) );

-
  ix = doubleToInt64(pMem->u.r);
-

-
  /* Only mark the value as an integer if
-
  **
-
  **    (1) the round-trip conversion real->int->real is a no-op, and
-
  **    (2) The integer is neither the largest nor the smallest
-
  **        possible integer (ticket #3922)
-
  **
-
  ** The second and third terms in the following conditional enforces
-
  ** the second condition under the assumption that addition overflow causes
-
  ** values to wrap around.
-
  */
-
  if( pMem->u.r==ix && ix>SMALLEST_INT64 && ix<LARGEST_INT64 ){
-
    pMem->u.i = ix;
+
  if( pMem->flags & MEM_IntReal ){
    MemSetTypeFlag(pMem, MEM_Int);
+
  }else{
+
    i64 ix = doubleToInt64(pMem->u.r);
+

+
    /* Only mark the value as an integer if
+
    **
+
    **    (1) the round-trip conversion real->int->real is a no-op, and
+
    **    (2) The integer is neither the largest nor the smallest
+
    **        possible integer (ticket #3922)
+
    **
+
    ** The second and third terms in the following conditional enforces
+
    ** the second condition under the assumption that addition overflow causes
+
    ** values to wrap around.
+
    */
+
    if( pMem->u.r==ix && ix>SMALLEST_INT64 && ix<LARGEST_INT64 ){
+
      pMem->u.i = ix;
+
      MemSetTypeFlag(pMem, MEM_Int);
+
    }
  }
}

@@ -81420,6 +82311,9 @@ static int valueFromFunction(
  if( pList ) nVal = pList->nExpr;
  assert( !ExprHasProperty(p, EP_IntValue) );
  pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
+
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
+
  if( pFunc==0 ) return SQLITE_OK;
+
#endif
  assert( pFunc );
  if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
   || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
@@ -81445,8 +82339,6 @@ static int valueFromFunction(
    goto value_from_function_out;
  }

-
  testcase( pCtx->pParse->rc==SQLITE_ERROR );
-
  testcase( pCtx->pParse->rc==SQLITE_OK );
  memset(&ctx, 0, sizeof(ctx));
  ctx.pOut = pVal;
  ctx.pFunc = pFunc;
@@ -81459,16 +82351,16 @@ static int valueFromFunction(
    sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8);
    assert( rc==SQLITE_OK );
    rc = sqlite3VdbeChangeEncoding(pVal, enc);
-
    if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){
+
    if( NEVER(rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal)) ){
      rc = SQLITE_TOOBIG;
      pCtx->pParse->nErr++;
    }
  }
-
  pCtx->pParse->rc = rc;

 value_from_function_out:
  if( rc!=SQLITE_OK ){
    pVal = 0;
+
    pCtx->pParse->rc = rc;
  }
  if( apVal ){
    for(i=0; i<nVal; i++){
@@ -81526,6 +82418,13 @@ static int valueFromExpr(
    rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
    testcase( rc!=SQLITE_OK );
    if( *ppVal ){
+
#ifdef SQLITE_ENABLE_STAT4
+
      rc = ExpandBlob(*ppVal);
+
#else
+
      /* zero-blobs only come from functions, not literal values.  And
+
      ** functions are only processed under STAT4 */
+
      assert( (ppVal[0][0].flags & MEM_Zero)==0 );
+
#endif
      sqlite3VdbeMemCast(*ppVal, aff, enc);
      sqlite3ValueApplyAffinity(*ppVal, affinity, enc);
    }
@@ -82141,6 +83040,8 @@ static int growOpArray(Vdbe *v, int nOp){
*/
static void test_addop_breakpoint(int pc, Op *pOp){
  static int n = 0;
+
  (void)pc;
+
  (void)pOp;
  n++;
}
#endif
@@ -82191,16 +83092,16 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  pOp->zComment = 0;
#endif
+
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE)
+
  pOp->nExec = 0;
+
  pOp->nCycle = 0;
+
#endif
#ifdef SQLITE_DEBUG
  if( p->db->flags & SQLITE_VdbeAddopTrace ){
    sqlite3VdbePrintOp(0, i, &p->aOp[i]);
    test_addop_breakpoint(i, &p->aOp[i]);
  }
#endif
-
#ifdef VDBE_PROFILE
-
  pOp->cycles = 0;
-
  pOp->cnt = 0;
-
#endif
#ifdef SQLITE_VDBE_COVERAGE
  pOp->iSrcLine = 0;
#endif
@@ -82368,11 +83269,12 @@ SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){
** If the bPush flag is true, then make this opcode the parent for
** subsequent Explains until sqlite3VdbeExplainPop() is called.
*/
-
SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
-
#ifndef SQLITE_DEBUG
+
SQLITE_PRIVATE int sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
+
  int addr = 0;
+
#if !defined(SQLITE_DEBUG)
  /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined.
  ** But omit them (for performance) during production builds */
-
  if( pParse->explain==2 )
+
  if( pParse->explain==2 || IS_STMT_SCANSTATUS(pParse->db) )
#endif
  {
    char *zMsg;
@@ -82384,13 +83286,15 @@ SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt
    va_end(ap);
    v = pParse->pVdbe;
    iThis = v->nOp;
-
    sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
+
    addr = sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
                      zMsg, P4_DYNAMIC);
    sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetLastOp(v)->p4.z);
    if( bPush){
      pParse->addrExplain = iThis;
    }
+
    sqlite3VdbeScanStatus(v, iThis, 0, 0, 0, 0);
  }
+
  return addr;
}

/*
@@ -82498,6 +83402,9 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){
    int i;
    for(i=p->nLabelAlloc; i<nNewSize; i++) p->aLabel[i] = -1;
#endif
+
    if( nNewSize>=100 && (nNewSize/100)>(p->nLabelAlloc/100) ){
+
      sqlite3ProgressCheck(p);
+
    }
    p->nLabelAlloc = nNewSize;
    p->aLabel[j] = v->nOp;
  }
@@ -82741,6 +83648,8 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
  Op *pOp;
  Parse *pParse = p->pParse;
  int *aLabel = pParse->aLabel;
+

+
  assert( pParse->db->mallocFailed==0 ); /* tag-20230419-1 */
  p->readOnly = 1;
  p->bIsReader = 0;
  pOp = &p->aOp[p->nOp-1];
@@ -82800,6 +83709,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
            ** have non-negative values for P2. */
            assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 );
            assert( ADDR(pOp->p2)<-pParse->nLabel );
+
            assert( aLabel!=0 );  /* True because of tag-20230419-1 */
            pOp->p2 = aLabel[ADDR(pOp->p2)];
          }
          break;
@@ -83043,20 +83953,83 @@ SQLITE_PRIVATE void sqlite3VdbeScanStatus(
  LogEst nEst,                    /* Estimated number of output rows */
  const char *zName               /* Name of table or index being scanned */
){
-
  sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus);
-
  ScanStatus *aNew;
-
  aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
-
  if( aNew ){
-
    ScanStatus *pNew = &aNew[p->nScan++];
-
    pNew->addrExplain = addrExplain;
-
    pNew->addrLoop = addrLoop;
-
    pNew->addrVisit = addrVisit;
-
    pNew->nEst = nEst;
-
    pNew->zName = sqlite3DbStrDup(p->db, zName);
-
    p->aScan = aNew;
+
  if( IS_STMT_SCANSTATUS(p->db) ){
+
    sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus);
+
    ScanStatus *aNew;
+
    aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
+
    if( aNew ){
+
      ScanStatus *pNew = &aNew[p->nScan++];
+
      memset(pNew, 0, sizeof(ScanStatus));
+
      pNew->addrExplain = addrExplain;
+
      pNew->addrLoop = addrLoop;
+
      pNew->addrVisit = addrVisit;
+
      pNew->nEst = nEst;
+
      pNew->zName = sqlite3DbStrDup(p->db, zName);
+
      p->aScan = aNew;
+
    }
  }
}
-
#endif
+

+
/*
+
** Add the range of instructions from addrStart to addrEnd (inclusive) to
+
** the set of those corresponding to the sqlite3_stmt_scanstatus() counters
+
** associated with the OP_Explain instruction at addrExplain. The
+
** sum of the sqlite3Hwtime() values for each of these instructions
+
** will be returned for SQLITE_SCANSTAT_NCYCLE requests.
+
*/
+
SQLITE_PRIVATE void sqlite3VdbeScanStatusRange(
+
  Vdbe *p,
+
  int addrExplain,
+
  int addrStart,
+
  int addrEnd
+
){
+
  if( IS_STMT_SCANSTATUS(p->db) ){
+
    ScanStatus *pScan = 0;
+
    int ii;
+
    for(ii=p->nScan-1; ii>=0; ii--){
+
      pScan = &p->aScan[ii];
+
      if( pScan->addrExplain==addrExplain ) break;
+
      pScan = 0;
+
    }
+
    if( pScan ){
+
      if( addrEnd<0 ) addrEnd = sqlite3VdbeCurrentAddr(p)-1;
+
      for(ii=0; ii<ArraySize(pScan->aAddrRange); ii+=2){
+
        if( pScan->aAddrRange[ii]==0 ){
+
          pScan->aAddrRange[ii] = addrStart;
+
          pScan->aAddrRange[ii+1] = addrEnd;
+
          break;
+
        }
+
      }
+
    }
+
  }
+
}
+

+
/*
+
** Set the addresses for the SQLITE_SCANSTAT_NLOOP and SQLITE_SCANSTAT_NROW
+
** counters for the query element associated with the OP_Explain at
+
** addrExplain.
+
*/
+
SQLITE_PRIVATE void sqlite3VdbeScanStatusCounters(
+
  Vdbe *p,
+
  int addrExplain,
+
  int addrLoop,
+
  int addrVisit
+
){
+
  if( IS_STMT_SCANSTATUS(p->db) ){
+
    ScanStatus *pScan = 0;
+
    int ii;
+
    for(ii=p->nScan-1; ii>=0; ii--){
+
      pScan = &p->aScan[ii];
+
      if( pScan->addrExplain==addrExplain ) break;
+
      pScan = 0;
+
    }
+
    if( pScan ){
+
      pScan->addrLoop = addrLoop;
+
      pScan->addrVisit = addrVisit;
+
    }
+
  }
+
}
+
#endif /* defined(SQLITE_ENABLE_STMT_SCANSTATUS) */


/*
@@ -83386,7 +84359,7 @@ SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){
  if( p->db->mallocFailed ){
    freeP4(p->db, n, pP4);
  }else{
-
    assert( pP4!=0 );
+
    assert( pP4!=0 || n==P4_DYNAMIC );
    assert( p->nOp>0 );
    pOp = &p->aOp[p->nOp-1];
    assert( pOp->p4type==P4_NOTUSED );
@@ -83480,7 +84453,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){

/* Return the most recently added opcode
*/
-
VdbeOp * sqlite3VdbeGetLastOp(Vdbe *p){
+
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetLastOp(Vdbe *p){
  return sqlite3VdbeGetOp(p, p->nOp - 1);
}

@@ -84185,7 +85158,6 @@ SQLITE_PRIVATE int sqlite3VdbeList(
  ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
  */
  releaseMemArray(pMem, 8);
-
  p->pResultSet = 0;

  if( p->rc==SQLITE_NOMEM ){
    /* This happens if a malloc() inside a call to sqlite3_column_text() or
@@ -84242,7 +85214,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
        sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free);
        p->nResColumn = 8;
      }
-
      p->pResultSet = pMem;
+
      p->pResultRow = pMem;
      if( db->mallocFailed ){
        p->rc = SQLITE_NOMEM;
        rc = SQLITE_ERROR;
@@ -84353,7 +85325,7 @@ static void *allocSpace(
** running it.
*/
SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
-
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+
#if defined(SQLITE_DEBUG)
  int i;
#endif
  assert( p!=0 );
@@ -84382,8 +85354,8 @@ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
  p->nFkConstraint = 0;
#ifdef VDBE_PROFILE
  for(i=0; i<p->nOp; i++){
-
    p->aOp[i].cnt = 0;
-
    p->aOp[i].cycles = 0;
+
    p->aOp[i].nExec = 0;
+
    p->aOp[i].nCycle = 0;
  }
#endif
}
@@ -84492,9 +85464,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
  p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem));
  p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*));
  p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*));
-
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-
  p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64));
-
#endif
  if( x.nNeeded ){
    x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
    x.nFree = x.nNeeded;
@@ -84503,9 +85472,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
      p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
      p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
      p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
-
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-
      p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
-
#endif
    }
  }

@@ -84520,9 +85486,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
    p->nMem = nMem;
    initMemArray(p->aMem, nMem, db, MEM_Undefined);
    memset(p->apCsr, 0, nCursor*sizeof(VdbeCursor*));
-
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-
    memset(p->anExec, 0, p->nOp*sizeof(i64));
-
#endif
  }
  sqlite3VdbeRewind(p);
}
@@ -84580,9 +85543,6 @@ static void closeCursorsInFrame(Vdbe *p){
SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
  Vdbe *v = pFrame->v;
  closeCursorsInFrame(v);
-
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-
  v->anExec = pFrame->anExec;
-
#endif
  v->aOp = pFrame->aOp;
  v->nOp = pFrame->nOp;
  v->aMem = pFrame->aMem;
@@ -85197,6 +86157,8 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
          db->flags &= ~(u64)SQLITE_DeferFKs;
          sqlite3CommitInternalChanges(db);
        }
+
      }else if( p->rc==SQLITE_SCHEMA && db->nVdbeActive>1 ){
+
        p->nChange = 0;
      }else{
        sqlite3RollbackAll(db, SQLITE_OK);
        p->nChange = 0;
@@ -85386,7 +86348,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
    sqlite3DbFree(db, p->zErrMsg);
    p->zErrMsg = 0;
  }
-
  p->pResultSet = 0;
+
  p->pResultRow = 0;
#ifdef SQLITE_DEBUG
  p->nWrite = 0;
#endif
@@ -85414,10 +86376,12 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
      }
      for(i=0; i<p->nOp; i++){
        char zHdr[100];
+
        i64 cnt = p->aOp[i].nExec;
+
        i64 cycles = p->aOp[i].nCycle;
        sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ",
-
           p->aOp[i].cnt,
-
           p->aOp[i].cycles,
-
           p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
+
           cnt,
+
           cycles,
+
           cnt>0 ? cycles/cnt : 0
        );
        fprintf(out, "%s", zHdr);
        sqlite3VdbePrintOp(out, i, &p->aOp[i]);
@@ -85513,9 +86477,9 @@ static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
#ifdef SQLITE_ENABLE_NORMALIZE
  sqlite3DbFree(db, p->zNormSql);
  {
-
    DblquoteStr *pThis, *pNext;
-
    for(pThis=p->pDblStr; pThis; pThis=pNext){
-
      pNext = pThis->pNextStr;
+
    DblquoteStr *pThis, *pNxt;
+
    for(pThis=p->pDblStr; pThis; pThis=pNxt){
+
      pNxt = pThis->pNextStr;
      sqlite3DbFree(db, pThis);
    }
  }
@@ -87142,6 +88106,20 @@ SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){
  return 1;
}

+
#if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG)
+
/*
+
** This Walker callback is used to help verify that calls to
+
** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have
+
** byte-code register values correctly initialized.
+
*/
+
SQLITE_PRIVATE int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr){
+
  if( pExpr->op==TK_REGISTER ){
+
    assert( (pWalker->u.aMem[pExpr->iTable].flags & MEM_Undefined)==0 );
+
  }
+
  return WRC_Continue;
+
}
+
#endif /* SQLITE_ENABLE_CURSOR_HINTS && SQLITE_DEBUG */
+

#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored
@@ -87204,6 +88182,16 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
  PreUpdate preupdate;
  const char *zTbl = pTab->zName;
  static const u8 fakeSortOrder = 0;
+
#ifdef SQLITE_DEBUG
+
  int nRealCol;
+
  if( pTab->tabFlags & TF_WithoutRowid ){
+
    nRealCol = sqlite3PrimaryKeyIndex(pTab)->nColumn;
+
  }else if( pTab->tabFlags & TF_HasVirtual ){
+
    nRealCol = pTab->nNVCol;
+
  }else{
+
    nRealCol = pTab->nCol;
+
  }
+
#endif

  assert( db->pPreUpdate==0 );
  memset(&preupdate, 0, sizeof(PreUpdate));
@@ -87220,8 +88208,8 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(

  assert( pCsr!=0 );
  assert( pCsr->eCurType==CURTYPE_BTREE );
-
  assert( pCsr->nField==pTab->nCol
-
       || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
+
  assert( pCsr->nField==nRealCol
+
       || (pCsr->nField==nRealCol+1 && op==SQLITE_DELETE && iReg==-1)
  );

  preupdate.v = v;
@@ -87272,6 +88260,7 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(
*/
/* #include "sqliteInt.h" */
/* #include "vdbeInt.h" */
+
/* #include "opcodes.h" */

#ifndef SQLITE_OMIT_DEPRECATED
/*
@@ -87527,7 +88516,7 @@ SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
     SQLITE_NULL,     /* 0x1f (not possible) */
     SQLITE_FLOAT,    /* 0x20 INTREAL */
     SQLITE_NULL,     /* 0x21 (not possible) */
-
     SQLITE_TEXT,     /* 0x22 INTREAL + TEXT */
+
     SQLITE_FLOAT,    /* 0x22 INTREAL + TEXT */
     SQLITE_NULL,     /* 0x23 (not possible) */
     SQLITE_FLOAT,    /* 0x24 (not possible) */
     SQLITE_NULL,     /* 0x25 (not possible) */
@@ -87762,7 +88751,10 @@ SQLITE_API void sqlite3_result_text64(
){
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
  assert( xDel!=SQLITE_DYNAMIC );
-
  if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
+
  if( enc!=SQLITE_UTF8 ){
+
    if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
+
    n &= ~(u64)1;
+
  }
  if( n>0x7fffffff ){
    (void)invokeValueDestructor(z, xDel, pCtx);
  }else{
@@ -87777,7 +88769,7 @@ SQLITE_API void sqlite3_result_text16(
  void (*xDel)(void *)
){
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
-
  setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
+
  setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16NATIVE, xDel);
}
SQLITE_API void sqlite3_result_text16be(
  sqlite3_context *pCtx,
@@ -87786,7 +88778,7 @@ SQLITE_API void sqlite3_result_text16be(
  void (*xDel)(void *)
){
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
-
  setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
+
  setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16BE, xDel);
}
SQLITE_API void sqlite3_result_text16le(
  sqlite3_context *pCtx,
@@ -87795,7 +88787,7 @@ SQLITE_API void sqlite3_result_text16le(
  void (*xDel)(void *)
){
  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
-
  setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
+
  setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16LE, xDel);
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
@@ -88006,7 +88998,7 @@ static int sqlite3Step(Vdbe *p){
    /* If the statement completed successfully, invoke the profile callback */
    checkProfileCallback(db, p);
#endif
-

+
    p->pResultRow = 0;
    if( rc==SQLITE_DONE && db->autoCommit ){
      assert( p->rc==SQLITE_OK );
      p->rc = doWalCallbacks(db);
@@ -88136,6 +89128,17 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){
}

/*
+
** The destructor function for a ValueList object.  This needs to be
+
** a separate function, unknowable to the application, to ensure that
+
** calls to sqlite3_vtab_in_first()/sqlite3_vtab_in_next() that are not
+
** preceeded by activation of IN processing via sqlite3_vtab_int() do not
+
** try to access a fake ValueList object inserted by a hostile extension.
+
*/
+
SQLITE_PRIVATE void sqlite3VdbeValueListFree(void *pToDelete){
+
  sqlite3_free(pToDelete);
+
}
+

+
/*
** Implementation of sqlite3_vtab_in_first() (if bNext==0) and
** sqlite3_vtab_in_next() (if bNext!=0).
*/
@@ -88149,8 +89152,15 @@ static int valueFromValueList(

  *ppOut = 0;
  if( pVal==0 ) return SQLITE_MISUSE;
-
  pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList");
-
  if( pRhs==0 ) return SQLITE_MISUSE;
+
  if( (pVal->flags & MEM_Dyn)==0 || pVal->xDel!=sqlite3VdbeValueListFree ){
+
    return SQLITE_ERROR;
+
  }else{
+
    assert( (pVal->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) ==
+
                 (MEM_Null|MEM_Term|MEM_Subtype) );
+
    assert( pVal->eSubtype=='p' );
+
    assert( pVal->u.zPType!=0 && strcmp(pVal->u.zPType,"ValueList")==0 );
+
    pRhs = (ValueList*)pVal->z;
+
  }
  if( bNext ){
    rc = sqlite3BtreeNext(pRhs->pCsr, 0);
  }else{
@@ -88370,7 +89380,7 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
*/
SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){
  Vdbe *pVm = (Vdbe *)pStmt;
-
  if( pVm==0 || pVm->pResultSet==0 ) return 0;
+
  if( pVm==0 || pVm->pResultRow==0 ) return 0;
  return pVm->nResColumn;
}

@@ -88425,8 +89435,8 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
  if( pVm==0 ) return (Mem*)columnNullValue();
  assert( pVm->db );
  sqlite3_mutex_enter(pVm->db->mutex);
-
  if( pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
-
    pOut = &pVm->pResultSet[i];
+
  if( pVm->pResultRow!=0 && i<pVm->nResColumn && i>=0 ){
+
    pOut = &pVm->pResultRow[i];
  }else{
    sqlite3Error(pVm->db, SQLITE_RANGE);
    pOut = (Mem*)columnNullValue();
@@ -88572,9 +89582,9 @@ static const void *columnName(
  assert( db!=0 );
  n = sqlite3_column_count(pStmt);
  if( N<n && N>=0 ){
+
    u8 prior_mallocFailed = db->mallocFailed;
    N += useType*n;
    sqlite3_mutex_enter(db->mutex);
-
    assert( db->mallocFailed==0 );
#ifndef SQLITE_OMIT_UTF16
    if( useUtf16 ){
      ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]);
@@ -88586,7 +89596,8 @@ static const void *columnName(
    /* A malloc may have failed inside of the _text() call. If this
    ** is the case, clear the mallocFailed flag and return NULL.
    */
-
    if( db->mallocFailed ){
+
    assert( db->mallocFailed==0 || db->mallocFailed==1 );
+
    if( db->mallocFailed > prior_mallocFailed ){
      sqlite3OomClear(db);
      ret = 0;
    }
@@ -88860,7 +89871,10 @@ SQLITE_API int sqlite3_bind_text64(
  unsigned char enc
){
  assert( xDel!=SQLITE_DYNAMIC );
-
  if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
+
  if( enc!=SQLITE_UTF8 ){
+
    if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
+
    nData &= ~(u16)1;
+
  }
  return bindText(pStmt, i, zData, nData, xDel, enc);
}
#ifndef SQLITE_OMIT_UTF16
@@ -88868,10 +89882,10 @@ SQLITE_API int sqlite3_bind_text16(
  sqlite3_stmt *pStmt,
  int i,
  const void *zData,
-
  int nData,
+
  int n,
  void (*xDel)(void*)
){
-
  return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
+
  return bindText(pStmt, i, zData, n & ~(u64)1, xDel, SQLITE_UTF16NATIVE);
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
@@ -89362,23 +90376,69 @@ SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppVa
/*
** Return status data for a single loop within query pStmt.
*/
-
SQLITE_API int sqlite3_stmt_scanstatus(
+
SQLITE_API int sqlite3_stmt_scanstatus_v2(
  sqlite3_stmt *pStmt,            /* Prepared statement being queried */
-
  int idx,                        /* Index of loop to report on */
+
  int iScan,                      /* Index of loop to report on */
  int iScanStatusOp,              /* Which metric to return */
+
  int flags,
  void *pOut                      /* OUT: Write the answer here */
){
  Vdbe *p = (Vdbe*)pStmt;
-
  ScanStatus *pScan;
-
  if( idx<0 || idx>=p->nScan ) return 1;
-
  pScan = &p->aScan[idx];
+
  VdbeOp *aOp = p->aOp;
+
  int nOp = p->nOp;
+
  ScanStatus *pScan = 0;
+
  int idx;
+

+
  if( p->pFrame ){
+
    VdbeFrame *pFrame;
+
    for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
+
    aOp = pFrame->aOp;
+
    nOp = pFrame->nOp;
+
  }
+

+
  if( iScan<0 ){
+
    int ii;
+
    if( iScanStatusOp==SQLITE_SCANSTAT_NCYCLE ){
+
      i64 res = 0;
+
      for(ii=0; ii<nOp; ii++){
+
        res += aOp[ii].nCycle;
+
      }
+
      *(i64*)pOut = res;
+
      return 0;
+
    }
+
    return 1;
+
  }
+
  if( flags & SQLITE_SCANSTAT_COMPLEX ){
+
    idx = iScan;
+
    pScan = &p->aScan[idx];
+
  }else{
+
    /* If the COMPLEX flag is clear, then this function must ignore any
+
    ** ScanStatus structures with ScanStatus.addrLoop set to 0. */
+
    for(idx=0; idx<p->nScan; idx++){
+
      pScan = &p->aScan[idx];
+
      if( pScan->zName ){
+
        iScan--;
+
        if( iScan<0 ) break;
+
      }
+
    }
+
  }
+
  if( idx>=p->nScan ) return 1;
+

  switch( iScanStatusOp ){
    case SQLITE_SCANSTAT_NLOOP: {
-
      *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop];
+
      if( pScan->addrLoop>0 ){
+
        *(sqlite3_int64*)pOut = aOp[pScan->addrLoop].nExec;
+
      }else{
+
        *(sqlite3_int64*)pOut = -1;
+
      }
      break;
    }
    case SQLITE_SCANSTAT_NVISIT: {
-
      *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit];
+
      if( pScan->addrVisit>0 ){
+
        *(sqlite3_int64*)pOut = aOp[pScan->addrVisit].nExec;
+
      }else{
+
        *(sqlite3_int64*)pOut = -1;
+
      }
      break;
    }
    case SQLITE_SCANSTAT_EST: {
@@ -89397,7 +90457,7 @@ SQLITE_API int sqlite3_stmt_scanstatus(
    }
    case SQLITE_SCANSTAT_EXPLAIN: {
      if( pScan->addrExplain ){
-
        *(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z;
+
        *(const char**)pOut = aOp[ pScan->addrExplain ].p4.z;
      }else{
        *(const char**)pOut = 0;
      }
@@ -89405,12 +90465,51 @@ SQLITE_API int sqlite3_stmt_scanstatus(
    }
    case SQLITE_SCANSTAT_SELECTID: {
      if( pScan->addrExplain ){
-
        *(int*)pOut = p->aOp[ pScan->addrExplain ].p1;
+
        *(int*)pOut = aOp[ pScan->addrExplain ].p1;
+
      }else{
+
        *(int*)pOut = -1;
+
      }
+
      break;
+
    }
+
    case SQLITE_SCANSTAT_PARENTID: {
+
      if( pScan->addrExplain ){
+
        *(int*)pOut = aOp[ pScan->addrExplain ].p2;
      }else{
        *(int*)pOut = -1;
      }
      break;
    }
+
    case SQLITE_SCANSTAT_NCYCLE: {
+
      i64 res = 0;
+
      if( pScan->aAddrRange[0]==0 ){
+
        res = -1;
+
      }else{
+
        int ii;
+
        for(ii=0; ii<ArraySize(pScan->aAddrRange); ii+=2){
+
          int iIns = pScan->aAddrRange[ii];
+
          int iEnd = pScan->aAddrRange[ii+1];
+
          if( iIns==0 ) break;
+
          if( iIns>0 ){
+
            while( iIns<=iEnd ){
+
              res += aOp[iIns].nCycle;
+
              iIns++;
+
            }
+
          }else{
+
            int iOp;
+
            for(iOp=0; iOp<nOp; iOp++){
+
              Op *pOp = &aOp[iOp];
+
              if( pOp->p1!=iEnd ) continue;
+
              if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_NCYCLE)==0 ){
+
                continue;
+
              }
+
              res += aOp[iOp].nCycle;
+
            }
+
          }
+
        }
+
      }
+
      *(i64*)pOut = res;
+
      break;
+
    }
    default: {
      return 1;
    }
@@ -89419,11 +90518,28 @@ SQLITE_API int sqlite3_stmt_scanstatus(
}

/*
+
** Return status data for a single loop within query pStmt.
+
*/
+
SQLITE_API int sqlite3_stmt_scanstatus(
+
  sqlite3_stmt *pStmt,            /* Prepared statement being queried */
+
  int iScan,                      /* Index of loop to report on */
+
  int iScanStatusOp,              /* Which metric to return */
+
  void *pOut                      /* OUT: Write the answer here */
+
){
+
  return sqlite3_stmt_scanstatus_v2(pStmt, iScan, iScanStatusOp, 0, pOut);
+
}
+

+
/*
** Zero all counters associated with the sqlite3_stmt_scanstatus() data.
*/
SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
  Vdbe *p = (Vdbe*)pStmt;
-
  memset(p->anExec, 0, p->nOp * sizeof(i64));
+
  int ii;
+
  for(ii=0; ii<p->nOp; ii++){
+
    Op *pOp = &p->aOp[ii];
+
    pOp->nExec = 0;
+
    pOp->nCycle = 0;
+
  }
}
#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */

@@ -89759,6 +90875,9 @@ SQLITE_API int sqlite3_found_count = 0;
*/
static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){
  static int n = 0;
+
  (void)pc;
+
  (void)pOp;
+
  (void)v;
  n++;
}
#endif
@@ -89997,6 +91116,10 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){
**    always preferred, even if the affinity is REAL, because
**    an integer representation is more space efficient on disk.
**
+
** SQLITE_AFF_FLEXNUM:
+
**    If the value is text, then try to convert it into a number of
+
**    some kind (integer or real) but do not make any other changes.
+
**
** SQLITE_AFF_TEXT:
**    Convert pRec to a text representation.
**
@@ -90011,11 +91134,11 @@ static void applyAffinity(
){
  if( affinity>=SQLITE_AFF_NUMERIC ){
    assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
-
             || affinity==SQLITE_AFF_NUMERIC );
+
             || affinity==SQLITE_AFF_NUMERIC || affinity==SQLITE_AFF_FLEXNUM );
    if( (pRec->flags & MEM_Int)==0 ){ /*OPTIMIZATION-IF-FALSE*/
-
      if( (pRec->flags & MEM_Real)==0 ){
+
      if( (pRec->flags & (MEM_Real|MEM_IntReal))==0 ){
        if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1);
-
      }else{
+
      }else if( affinity<=SQLITE_AFF_REAL ){
        sqlite3VdbeIntegerAffinity(pRec);
      }
    }
@@ -90243,17 +91366,6 @@ SQLITE_PRIVATE void sqlite3VdbeRegisterDump(Vdbe *v){
#  define REGISTER_TRACE(R,M)
#endif

-

-
#ifdef VDBE_PROFILE
-

-
/*
-
** hwtime.h contains inline assembler code for implementing
-
** high-performance timing routines.
-
*/
-
/* #include "hwtime.h" */
-

-
#endif
-

#ifndef NDEBUG
/*
** This function is only called from within an assert() expression. It
@@ -90313,8 +91425,10 @@ static u64 filterHash(const Mem *aMem, const Op *pOp){
    }else if( p->flags & MEM_Real ){
      h += sqlite3VdbeIntValue(p);
    }else if( p->flags & (MEM_Str|MEM_Blob) ){
-
      h += p->n;
-
      if( p->flags & MEM_Zero ) h += p->u.nZero;
+
      /* All strings have the same hash and all blobs have the same hash,
+
      ** though, at least, those hashes are different from each other and
+
      ** from NULL. */
+
      h += 4093 + (p->flags & (MEM_Str|MEM_Blob));
    }
  }
  return h;
@@ -90343,11 +91457,10 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
){
  Op *aOp = p->aOp;          /* Copy of p->aOp */
  Op *pOp = aOp;             /* Current operation */
-
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
-
  Op *pOrigOp;               /* Value of pOp at the top of the loop */
-
#endif
#ifdef SQLITE_DEBUG
+
  Op *pOrigOp;               /* Value of pOp at the top of the loop */
  int nExtraDelete = 0;      /* Verifies FORDELETE and AUXDELETE flags */
+
  u8 iCompareIsInit = 0;     /* iCompare is initialized */
#endif
  int rc = SQLITE_OK;        /* Value to return */
  sqlite3 *db = p->db;       /* The database */
@@ -90363,13 +91476,16 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
  Mem *pIn2 = 0;             /* 2nd input operand */
  Mem *pIn3 = 0;             /* 3rd input operand */
  Mem *pOut = 0;             /* Output operand */
-
#ifdef VDBE_PROFILE
-
  u64 start;                 /* CPU clock count at start of opcode */
+
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE)
+
  u64 *pnCycle = 0;
+
  int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0;
#endif
  /*** INSERT STACK UNION HERE ***/

  assert( p->eVdbeState==VDBE_RUN_STATE );  /* sqlite3_step() verifies this */
-
  sqlite3VdbeEnter(p);
+
  if( DbMaskNonZero(p->lockMask) ){
+
    sqlite3VdbeEnter(p);
+
  }
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  if( db->xProgress ){
    u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP];
@@ -90390,7 +91506,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
  assert( p->bIsReader || p->readOnly!=0 );
  p->iCurrentTime = 0;
  assert( p->explain==0 );
-
  p->pResultSet = 0;
  db->busyHandler.nBusy = 0;
  if( AtomicLoad(&db->u1.isInterrupted) ) goto abort_due_to_interrupt;
  sqlite3VdbeIOTraceSql(p);
@@ -90427,12 +91542,18 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
    assert( rc==SQLITE_OK );

    assert( pOp>=aOp && pOp<&aOp[p->nOp]);
-
#ifdef VDBE_PROFILE
-
    start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
-
#endif
    nVmStep++;
-
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-
    if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
+

+
#if defined(VDBE_PROFILE)
+
    pOp->nExec++;
+
    pnCycle = &pOp->nCycle;
+
    if( sqlite3NProfileCnt==0 ) *pnCycle -= sqlite3Hwtime();
+
#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+
    if( bStmtScanStatus ){
+
      pOp->nExec++;
+
      pnCycle = &pOp->nCycle;
+
      *pnCycle -= sqlite3Hwtime();
+
    }
#endif

    /* Only allow tracing if SQLITE_DEBUG is defined.
@@ -90494,7 +91615,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
      }
    }
#endif
-
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+
#ifdef SQLITE_DEBUG
    pOrigOp = pOp;
#endif

@@ -90778,6 +91899,12 @@ case OP_Halt: {
#ifdef SQLITE_DEBUG
  if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
#endif
+

+
  /* A deliberately coded "OP_Halt SQLITE_INTERNAL * * * *" opcode indicates
+
  ** something is wrong with the code generator.  Raise an assertion in order
+
  ** to bring this to the attention of fuzzers and other testing tools. */
+
  assert( pOp->p1!=SQLITE_INTERNAL );
+

  if( p->pFrame && pOp->p1==SQLITE_OK ){
    /* Halt the sub-program. Return control to the parent frame. */
    pFrame = p->pFrame;
@@ -91219,10 +92346,10 @@ case OP_ResultRow: {
  assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 );

  p->cacheCtr = (p->cacheCtr + 2)|1;
-
  p->pResultSet = &aMem[pOp->p1];
+
  p->pResultRow = &aMem[pOp->p1];
#ifdef SQLITE_DEBUG
  {
-
    Mem *pMem = p->pResultSet;
+
    Mem *pMem = p->pResultRow;
    int i;
    for(i=0; i<pOp->p2; i++){
      assert( memIsValid(&pMem[i]) );
@@ -91752,7 +92879,6 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
  flags1 = pIn1->flags;
  flags3 = pIn3->flags;
  if( (flags1 & flags3 & MEM_Int)!=0 ){
-
    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 ){
      if( sqlite3aGTb[pOp->opcode] ){
@@ -91760,18 +92886,21 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
        goto jump_to_p2;
      }
      iCompare = +1;
+
      VVA_ONLY( iCompareIsInit = 1; )
    }else if( pIn3->u.i < pIn1->u.i ){
      if( sqlite3aLTb[pOp->opcode] ){
        VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
        goto jump_to_p2;
      }
      iCompare = -1;
+
      VVA_ONLY( iCompareIsInit = 1; )
    }else{
      if( sqlite3aEQb[pOp->opcode] ){
        VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3);
        goto jump_to_p2;
      }
      iCompare = 0;
+
      VVA_ONLY( iCompareIsInit = 1; )
    }
    VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
    break;
@@ -91803,6 +92932,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
        goto jump_to_p2;
      }
      iCompare = 1;    /* Operands are not equal */
+
      VVA_ONLY( iCompareIsInit = 1; )
      break;
    }
  }else{
@@ -91813,14 +92943,14 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
      if( (flags1 | flags3)&MEM_Str ){
        if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
          applyNumericAffinity(pIn1,0);
-
          testcase( flags3==pIn3->flags );
+
          assert( flags3==pIn3->flags || CORRUPT_DB );
          flags3 = pIn3->flags;
        }
        if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
          applyNumericAffinity(pIn3,0);
        }
      }
-
    }else if( affinity==SQLITE_AFF_TEXT ){
+
    }else if( affinity==SQLITE_AFF_TEXT && ((flags1 | flags3) & MEM_Str)!=0 ){
      if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
        testcase( pIn1->flags & MEM_Int );
        testcase( pIn1->flags & MEM_Real );
@@ -91828,7 +92958,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
        sqlite3VdbeMemStringify(pIn1, encoding, 1);
        testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
        flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
-
        if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str;
+
        if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str;
      }
      if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){
        testcase( pIn3->flags & MEM_Int );
@@ -91859,6 +92989,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
    res2 = sqlite3aGTb[pOp->opcode];
  }
  iCompare = res;
+
  VVA_ONLY( iCompareIsInit = 1; )

  /* Undo any changes made by applyAffinity() to the input registers. */
  assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
@@ -91897,6 +93028,7 @@ case OP_ElseEq: { /* same as TK_ESCAPE, jump */
    break;
  }
#endif /* SQLITE_DEBUG */
+
  assert( iCompareIsInit );
  VdbeBranchTaken(iCompare==0, 2);
  if( iCompare==0 ) goto jump_to_p2;
  break;
@@ -91991,6 +93123,7 @@ case OP_Compare: {
    pColl = pKeyInfo->aColl[i];
    bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC);
    iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
+
    VVA_ONLY( iCompareIsInit = 1; )
    if( iCompare ){
      if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL)
       && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null))
@@ -92008,13 +93141,14 @@ case OP_Compare: {
/* Opcode: Jump P1 P2 P3 * *
**
** 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
+
** 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 );
+
  assert( iCompareIsInit );
  if( iCompare<0 ){
    VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1];
  }else if( iCompare==0 ){
@@ -92234,6 +93368,12 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
** (0x01) bit. SQLITE_FLOAT is the 0x02 bit. SQLITE_TEXT is 0x04.
** SQLITE_BLOB is 0x08.  SQLITE_NULL is 0x10.
**
+
** WARNING: This opcode does not reliably distinguish between NULL and REAL
+
** when P1>=0.  If the database contains a NaN value, this opcode will think
+
** that the datatype is REAL when it should be NULL.  When P1<0 and the value
+
** is already stored in register P3, then this opcode does reliably
+
** distinguish between NULL and REAL.  The problem only arises then P1>=0.
+
**
** Take the jump to address P2 if and only if the datatype of the
** value determined by P1 and P3 corresponds to one of the bits in the
** P5 bitmask.
@@ -92347,7 +93487,7 @@ case OP_IfNullRow: { /* jump */
  VdbeCursor *pC;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
-
  if( ALWAYS(pC) && pC->nullRow ){
+
  if( pC && pC->nullRow ){
    sqlite3VdbeMemSetNull(aMem + pOp->p3);
    goto jump_to_p2;
  }
@@ -92414,7 +93554,7 @@ case OP_Offset: { /* out3 */
** typeof() function or the IS NULL or IS NOT NULL operators or the
** equivalent.  In this case, all content loading can be omitted.
*/
-
case OP_Column: {
+
case OP_Column: {            /* ncycle */
  u32 p2;            /* column number to retrieve */
  VdbeCursor *pC;    /* The VDBE cursor */
  BtCursor *pCrsr;   /* The B-Tree cursor corresponding to pC */
@@ -92763,7 +93903,7 @@ case OP_TypeCheck: {
        }
        case COLTYPE_REAL: {
          testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real );
-
          testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_IntReal );
+
          assert( (pIn1->flags & MEM_IntReal)==0 );
          if( pIn1->flags & MEM_Int ){
            /* When applying REAL affinity, if the result is still an MEM_Int
            ** that will fit in 6 bytes, then change the type to MEM_IntReal
@@ -92842,7 +93982,7 @@ case OP_Affinity: {
      }else{
        pIn1->u.r = (double)pIn1->u.i;
        pIn1->flags |= MEM_Real;
-
        pIn1->flags &= ~MEM_Int;
+
        pIn1->flags &= ~(MEM_Int|MEM_Str);
      }
    }
    REGISTER_TRACE((int)(pIn1-aMem), pIn1);
@@ -93766,7 +94906,7 @@ case OP_SetCookie: {
**
** See also: OP_OpenRead, OP_ReopenIdx
*/
-
case OP_ReopenIdx: {
+
case OP_ReopenIdx: {         /* ncycle */
  int nField;
  KeyInfo *pKeyInfo;
  u32 p2;
@@ -93787,7 +94927,7 @@ case OP_ReopenIdx: {
  }
  /* If the cursor is not currently open or is open on a different
  ** index, then fall through into OP_OpenRead to force a reopen */
-
case OP_OpenRead:
+
case OP_OpenRead:            /* ncycle */
case OP_OpenWrite:

  assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
@@ -93881,7 +95021,7 @@ open_cursor_set_hints:
**
** Duplicate ephemeral cursors are used for self-joins of materialized views.
*/
-
case OP_OpenDup: {
+
case OP_OpenDup: {           /* ncycle */
  VdbeCursor *pOrig;    /* The original cursor to be duplicated */
  VdbeCursor *pCx;      /* The new cursor */

@@ -93943,8 +95083,8 @@ case OP_OpenDup: {
** by this opcode will be used for automatically created transient
** indices in joins.
*/
-
case OP_OpenAutoindex:
-
case OP_OpenEphemeral: {
+
case OP_OpenAutoindex:       /* ncycle */
+
case OP_OpenEphemeral: {     /* ncycle */
  VdbeCursor *pCx;
  KeyInfo *pKeyInfo;

@@ -94102,7 +95242,7 @@ case OP_OpenPseudo: {
** Close a cursor previously opened as P1.  If P1 is not
** currently open, this instruction is a no-op.
*/
-
case OP_Close: {
+
case OP_Close: {             /* ncycle */
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]);
  p->apCsr[pOp->p1] = 0;
@@ -94219,10 +95359,10 @@ case OP_ColumnsUsed: {
**
** See also: Found, NotFound, SeekGt, SeekGe, SeekLt
*/
-
case OP_SeekLT:         /* jump, in3, group */
-
case OP_SeekLE:         /* jump, in3, group */
-
case OP_SeekGE:         /* jump, in3, group */
-
case OP_SeekGT: {       /* jump, in3, group */
+
case OP_SeekLT:         /* jump, in3, group, ncycle */
+
case OP_SeekLE:         /* jump, in3, group, ncycle */
+
case OP_SeekGE:         /* jump, in3, group, ncycle */
+
case OP_SeekGT: {       /* jump, in3, group, ncycle */
  int res;           /* Comparison result */
  int oc;            /* Opcode */
  VdbeCursor *pC;    /* The cursor to seek */
@@ -94488,7 +95628,7 @@ seek_not_found:
**      jump to SeekOP.P2 if This.P5==0 or to This.P2 if This.P5>0.
** </ol>
*/
-
case OP_SeekScan: {
+
case OP_SeekScan: {          /* ncycle */
  VdbeCursor *pC;
  int res;
  int nStep;
@@ -94581,6 +95721,7 @@ case OP_SeekScan: {
      break;
    }
    nStep--;
+
    pC->cacheStatus = CACHE_STALE;
    rc = sqlite3BtreeNext(pC->uc.pCursor, 0);
    if( rc ){
      if( rc==SQLITE_DONE ){
@@ -94610,7 +95751,7 @@ case OP_SeekScan: {
**
** P1 must be a valid b-tree cursor.
*/
-
case OP_SeekHit: {
+
case OP_SeekHit: {           /* ncycle */
  VdbeCursor *pC;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
@@ -94742,7 +95883,7 @@ case OP_IfNotOpen: { /* jump */
**
** See also: NotFound, Found, NotExists
*/
-
case OP_IfNoHope: {     /* jump, in3 */
+
case OP_IfNoHope: {     /* jump, in3, ncycle */
  VdbeCursor *pC;
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
@@ -94756,9 +95897,9 @@ case OP_IfNoHope: { /* jump, in3 */
  /* Fall through into OP_NotFound */
  /* no break */ deliberate_fall_through
}
-
case OP_NoConflict:     /* jump, in3 */
-
case OP_NotFound:       /* jump, in3 */
-
case OP_Found: {        /* jump, in3 */
+
case OP_NoConflict:     /* jump, in3, ncycle */
+
case OP_NotFound:       /* jump, in3, ncycle */
+
case OP_Found: {        /* jump, in3, ncycle */
  int alreadyExists;
  int ii;
  VdbeCursor *pC;
@@ -94888,7 +96029,7 @@ case OP_Found: { /* jump, in3 */
**
** See also: Found, NotFound, NoConflict, SeekRowid
*/
-
case OP_SeekRowid: {        /* jump, in3 */
+
case OP_SeekRowid: {        /* jump, in3, ncycle */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
@@ -94913,7 +96054,7 @@ case OP_SeekRowid: { /* jump, in3 */
  }
  /* Fall through into OP_NotExists */
  /* no break */ deliberate_fall_through
-
case OP_NotExists:          /* jump, in3 */
+
case OP_NotExists:          /* jump, in3, ncycle */
  pIn3 = &aMem[pOp->p3];
  assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
@@ -95193,8 +96334,11 @@ case OP_Insert: {
  if( pOp->p5 & OPFLAG_ISNOOP ) break;
#endif

-
  if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
-
  if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
+
  assert( (pOp->p5 & OPFLAG_LASTROWID)==0 || (pOp->p5 & OPFLAG_NCHANGE)!=0 );
+
  if( pOp->p5 & OPFLAG_NCHANGE ){
+
    p->nChange++;
+
    if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
+
  }
  assert( (pData->flags & (MEM_Blob|MEM_Str))!=0 || pData->n==0 );
  x.pData = pData->z;
  x.nData = pData->n;
@@ -95205,6 +96349,7 @@ case OP_Insert: {
    x.nZero = 0;
  }
  x.pKey = 0;
+
  assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT );
  rc = sqlite3BtreeInsert(pC->uc.pCursor, &x,
      (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)),
      seekResult
@@ -95536,7 +96681,7 @@ case OP_RowData: {
** be a separate OP_VRowid opcode for use with virtual tables, but this
** one opcode now works for both table types.
*/
-
case OP_Rowid: {                 /* out2 */
+
case OP_Rowid: {                 /* out2, ncycle */
  VdbeCursor *pC;
  i64 v;
  sqlite3_vtab *pVtab;
@@ -95635,8 +96780,8 @@ case OP_NullRow: {
** from the end toward the beginning.  In other words, the cursor is
** configured to use Prev, not Next.
*/
-
case OP_SeekEnd:
-
case OP_Last: {        /* jump */
+
case OP_SeekEnd:             /* ncycle */
+
case OP_Last: {              /* jump, ncycle */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
@@ -95737,17 +96882,22 @@ case OP_Sort: { /* jump */
** If the table or index is not empty, fall through to the following
** instruction.
**
+
** If P2 is zero, that is an assertion that the P1 table is never
+
** empty and hence the jump will never be taken.
+
**
** This opcode leaves the cursor configured to move in forward order,
** from the beginning toward the end.  In other words, the cursor is
** configured to use Next, not Prev.
*/
-
case OP_Rewind: {        /* jump */
+
case OP_Rewind: {        /* jump, ncycle */
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p5==0 );
+
  assert( pOp->p2>=0 && pOp->p2<p->nOp );
+

  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
  assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
@@ -95767,9 +96917,10 @@ case OP_Rewind: { /* jump */
  }
  if( rc ) goto abort_due_to_error;
  pC->nullRow = (u8)res;
-
  assert( pOp->p2>0 && pOp->p2<p->nOp );
-
  VdbeBranchTaken(res!=0,2);
-
  if( res ) goto jump_to_p2;
+
  if( pOp->p2>0 ){
+
    VdbeBranchTaken(res!=0,2);
+
    if( res ) goto jump_to_p2;
+
  }
  break;
}

@@ -95835,7 +96986,7 @@ case OP_SorterNext: { /* jump */
  rc = sqlite3VdbeSorterNext(db, pC);
  goto next_tail;

-
case OP_Prev:          /* jump */
+
case OP_Prev:          /* jump, ncycle */
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p5==0
       || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP
@@ -95850,7 +97001,7 @@ case OP_Prev: /* jump */
  rc = sqlite3BtreePrevious(pC->uc.pCursor, pOp->p3);
  goto next_tail;

-
case OP_Next:          /* jump */
+
case OP_Next:          /* jump, ncycle */
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  assert( pOp->p5==0
       || pOp->p5==SQLITE_STMTSTATUS_FULLSCAN_STEP
@@ -96042,8 +97193,8 @@ case OP_IdxDelete: {
**
** See also: Rowid, MakeRecord.
*/
-
case OP_DeferredSeek:
-
case OP_IdxRowid: {           /* out2 */
+
case OP_DeferredSeek:         /* ncycle */
+
case OP_IdxRowid: {           /* out2, ncycle */
  VdbeCursor *pC;             /* The P1 index cursor */
  VdbeCursor *pTabCur;        /* The P2 table cursor (OP_DeferredSeek only) */
  i64 rowid;                  /* Rowid that P1 current points to */
@@ -96105,8 +97256,8 @@ case OP_IdxRowid: { /* out2 */
** seek operation now, without further delay.  If the cursor seek has
** already occurred, this instruction is a no-op.
*/
-
case OP_FinishSeek: {
-
  VdbeCursor *pC;             /* The P1 index cursor */
+
case OP_FinishSeek: {        /* ncycle */
+
  VdbeCursor *pC;            /* The P1 index cursor */

  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
@@ -96161,10 +97312,10 @@ case OP_FinishSeek: {
** If the P1 index entry is less than or equal to the key value then jump
** to P2. Otherwise fall through to the next instruction.
*/
-
case OP_IdxLE:          /* jump */
-
case OP_IdxGT:          /* jump */
-
case OP_IdxLT:          /* jump */
-
case OP_IdxGE:  {       /* jump */
+
case OP_IdxLE:          /* jump, ncycle */
+
case OP_IdxGT:          /* jump, ncycle */
+
case OP_IdxLT:          /* jump, ncycle */
+
case OP_IdxGE:  {       /* jump, ncycle */
  VdbeCursor *pC;
  int res;
  UnpackedRecord r;
@@ -96575,13 +97726,14 @@ case OP_IntegrityCk: {
  pIn1 = &aMem[pOp->p1];
  assert( pOp->p5<db->nDb );
  assert( DbMaskTest(p->btreeMask, pOp->p5) );
-
  z = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot,
-
                                 (int)pnErr->u.i+1, &nErr);
+
  rc = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot,
+
                                 (int)pnErr->u.i+1, &nErr, &z);
  sqlite3VdbeMemSetNull(pIn1);
  if( nErr==0 ){
    assert( z==0 );
-
  }else if( z==0 ){
-
    goto no_mem;
+
  }else if( rc ){
+
    sqlite3_free(z);
+
    goto abort_due_to_error;
  }else{
    pnErr->u.i -= nErr-1;
    sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
@@ -96785,9 +97937,6 @@ case OP_Program: { /* jump */
    pFrame->aOp = p->aOp;
    pFrame->nOp = p->nOp;
    pFrame->token = pProgram->token;
-
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-
    pFrame->anExec = p->anExec;
-
#endif
#ifdef SQLITE_DEBUG
    pFrame->iFrameMagic = SQLITE_FRAME_MAGIC;
#endif
@@ -96824,9 +97973,6 @@ case OP_Program: { /* jump */
  memset(pFrame->aOnce, 0, (pProgram->nOp + 7)/8);
  p->aOp = aOp = pProgram->aOp;
  p->nOp = pProgram->nOp;
-
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-
  p->anExec = 0;
-
#endif
#ifdef SQLITE_DEBUG
  /* Verify that second and subsequent executions of the same trigger do not
  ** try to reuse register values from the first use. */
@@ -97228,6 +98374,7 @@ case OP_AggFinal: {
  }
  sqlite3VdbeChangeEncoding(pMem, encoding);
  UPDATE_MAX_BLOBSIZE(pMem);
+
  REGISTER_TRACE((int)(pMem-aMem), pMem);
  break;
}

@@ -97583,7 +98730,7 @@ case OP_VDestroy: {
** P1 is a cursor number.  This opcode opens a cursor to the virtual
** table and stores that cursor in P1.
*/
-
case OP_VOpen: {
+
case OP_VOpen: {             /* ncycle */
  VdbeCursor *pCur;
  sqlite3_vtab_cursor *pVCur;
  sqlite3_vtab *pVtab;
@@ -97630,7 +98777,7 @@ case OP_VOpen: {
** cursor.  Register P3 is used to hold the values returned by
** sqlite3_vtab_in_first() and sqlite3_vtab_in_next().
*/
-
case OP_VInitIn: {        /* out2 */
+
case OP_VInitIn: {        /* out2, ncycle */
  VdbeCursor *pC;         /* The cursor containing the RHS values */
  ValueList *pRhs;        /* New ValueList object to put in reg[P2] */

@@ -97641,7 +98788,7 @@ case OP_VInitIn: { /* out2 */
  pRhs->pOut = &aMem[pOp->p3];
  pOut = out2Prerelease(p, pOp);
  pOut->flags = MEM_Null;
-
  sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free);
+
  sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3VdbeValueListFree);
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -97667,7 +98814,7 @@ case OP_VInitIn: { /* out2 */
**
** A jump is made to P2 if the result set after filtering would be empty.
*/
-
case OP_VFilter: {   /* jump */
+
case OP_VFilter: {   /* jump, ncycle */
  int nArg;
  int iQuery;
  const sqlite3_module *pModule;
@@ -97727,7 +98874,7 @@ case OP_VFilter: { /* jump */
** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are
** unused by OP_VColumn.
*/
-
case OP_VColumn: {
+
case OP_VColumn: {           /* ncycle */
  sqlite3_vtab *pVtab;
  const sqlite3_module *pModule;
  Mem *pDest;
@@ -97779,7 +98926,7 @@ case OP_VColumn: {
** jump to instruction P2.  Or, if the virtual table has reached
** the end of its result set, then fall through to the next instruction.
*/
-
case OP_VNext: {   /* jump */
+
case OP_VNext: {   /* jump, ncycle */
  sqlite3_vtab *pVtab;
  const sqlite3_module *pModule;
  int res;
@@ -98362,11 +99509,13 @@ default: { /* This is really OP_Noop, OP_Explain */
*****************************************************************************/
    }

-
#ifdef VDBE_PROFILE
-
    {
-
      u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
-
      if( endTime>start ) pOrigOp->cycles += endTime - start;
-
      pOrigOp->cnt++;
+
#if defined(VDBE_PROFILE)
+
    *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
+
    pnCycle = 0;
+
#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+
    if( pnCycle ){
+
      *pnCycle += sqlite3Hwtime();
+
      pnCycle = 0;
    }
#endif

@@ -98443,6 +99592,18 @@ abort_due_to_error:
  ** release the mutexes on btrees that were acquired at the
  ** top. */
vdbe_return:
+
#if defined(VDBE_PROFILE)
+
  if( pnCycle ){
+
    *pnCycle += sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
+
    pnCycle = 0;
+
  }
+
#elif defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+
  if( pnCycle ){
+
    *pnCycle += sqlite3Hwtime();
+
    pnCycle = 0;
+
  }
+
#endif
+

#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  while( nVmStep>=nProgressLimit && db->xProgress!=0 ){
    nProgressLimit += db->nProgressOps;
@@ -98454,7 +99615,9 @@ vdbe_return:
  }
#endif
  p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
-
  sqlite3VdbeLeave(p);
+
  if( DbMaskNonZero(p->lockMask) ){
+
    sqlite3VdbeLeave(p);
+
  }
  assert( rc!=SQLITE_OK || nExtraDelete==0
       || sqlite3_strlike("DELETE%",p->zSql,0)!=0
  );
@@ -98832,7 +99995,7 @@ blob_open_out:
    if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
    sqlite3DbFree(db, pBlob);
  }
-
  sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
+
  sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr);
  sqlite3DbFree(db, zErr);
  sqlite3ParseObjectReset(&sParse);
  rc = sqlite3ApiExit(db, rc);
@@ -98991,7 +100154,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
    ((Vdbe*)p->pStmt)->rc = SQLITE_OK;
    rc = blobSeekToRow(p, iRow, &zErr);
    if( rc!=SQLITE_OK ){
-
      sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
+
      sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : (char*)0), zErr);
      sqlite3DbFree(db, zErr);
    }
    assert( rc!=SQLITE_SCHEMA );
@@ -101861,6 +103024,9 @@ static int bytecodevtabConnect(
   ");"
  };

+
  (void)argc;
+
  (void)argv;
+
  (void)pzErr;
  rc = sqlite3_declare_vtab(db, azSchema[isTabUsed]);
  if( rc==SQLITE_OK ){
    pNew = sqlite3_malloc( sizeof(*pNew) );
@@ -102096,6 +103262,7 @@ static int bytecodevtabFilter(
  bytecodevtab_cursor *pCur = (bytecodevtab_cursor *)pVtabCursor;
  bytecodevtab *pVTab = (bytecodevtab *)pVtabCursor->pVtab;
  int rc = SQLITE_OK;
+
  (void)idxStr;

  bytecodevtabCursorClear(pCur);
  pCur->iRowid = 0;
@@ -103111,6 +104278,32 @@ static void extendFJMatch(
}

/*
+
** Return TRUE (non-zero) if zTab is a valid name for the schema table pTab.
+
*/
+
static SQLITE_NOINLINE int isValidSchemaTableName(
+
  const char *zTab,         /* Name as it appears in the SQL */
+
  Table *pTab,              /* The schema table we are trying to match */
+
  Schema *pSchema           /* non-NULL if a database qualifier is present */
+
){
+
  const char *zLegacy;
+
  assert( pTab!=0 );
+
  assert( pTab->tnum==1 );
+
  if( sqlite3StrNICmp(zTab, "sqlite_", 7)!=0 ) return 0;
+
  zLegacy = pTab->zName;
+
  if( strcmp(zLegacy+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){
+
    if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){
+
      return 1;
+
    }
+
    if( pSchema==0 ) return 0;
+
    if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1;
+
    if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1;
+
  }else{
+
    if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1;
+
  }
+
  return 0;
+
}
+

+
/*
** 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
@@ -103263,15 +104456,17 @@ static int lookupName(
        }
        assert( zDb==0 || zTab!=0 );
        if( zTab ){
-
          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;
+
          if( pItem->zAlias!=0 ){
+
            if( sqlite3StrICmp(zTab, pItem->zAlias)!=0 ){
+
              continue;
+
            }
+
          }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){
+
            if( pTab->tnum!=1 ) continue;
+
            if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue;
          }
          assert( ExprUseYTab(pExpr) );
          if( IN_RENAME_OBJECT && pItem->zAlias ){
@@ -103347,7 +104542,8 @@ static int lookupName(
        assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
        if( pParse->bReturning ){
          if( (pNC->ncFlags & NC_UBaseReg)!=0
-
           && (zTab==0 || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0)
+
           && ALWAYS(zTab==0
+
                     || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0)
          ){
            pExpr->iTable = op!=TK_DELETE;
            pTab = pParse->pTriggerTab;
@@ -103414,6 +104610,7 @@ static int lookupName(
            if( pParse->bReturning ){
              eNewExprOp = TK_REGISTER;
              pExpr->op2 = TK_COLUMN;
+
              pExpr->iColumn = iCol;
              pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable +
                 sqlite3TableColumnToStorage(pTab, iCol) + 1;
            }else{
@@ -103826,14 +105023,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
      if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
        testcase( ExprHasProperty(pExpr, EP_OuterON) );
        assert( !ExprHasProperty(pExpr, EP_IntValue) );
-
        if( pExpr->op==TK_NOTNULL ){
-
          pExpr->u.zToken = "true";
-
          ExprSetProperty(pExpr, EP_IsTrue);
-
        }else{
-
          pExpr->u.zToken = "false";
-
          ExprSetProperty(pExpr, EP_IsFalse);
-
        }
-
        pExpr->op = TK_TRUEFALSE;
+
        pExpr->u.iValue = (pExpr->op==TK_NOTNULL);
+
        pExpr->flags |= EP_IntValue;
+
        pExpr->op = TK_INTEGER;
+

        for(i=0, p=pNC; p && i<ArraySize(anRef); p=p->pNext, i++){
          p->nRef = anRef[i];
        }
@@ -104135,8 +105328,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
        assert( pNC->nRef>=nRef );
        if( nRef!=pNC->nRef ){
          ExprSetProperty(pExpr, EP_VarSelect);
-
          pNC->ncFlags |= NC_VarSelect;
        }
+
        pNC->ncFlags |= NC_Subquery;
      }
      break;
    }
@@ -105090,49 +106283,122 @@ SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
*/
SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){
  int op;
-
  while( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){
-
    assert( pExpr->op==TK_COLLATE
-
         || pExpr->op==TK_IF_NULL_ROW
-
         || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) );
-
    pExpr = pExpr->pLeft;
-
    assert( pExpr!=0 );
-
  }
  op = pExpr->op;
-
  if( op==TK_REGISTER ) op = pExpr->op2;
-
  if( op==TK_COLUMN || op==TK_AGG_COLUMN ){
-
    assert( ExprUseYTab(pExpr) );
-
    assert( pExpr->y.pTab!=0 );
-
    return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
-
  }
-
  if( op==TK_SELECT ){
-
    assert( ExprUseXSelect(pExpr) );
-
    assert( pExpr->x.pSelect!=0 );
-
    assert( pExpr->x.pSelect->pEList!=0 );
-
    assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 );
-
    return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
-
  }
+
  while( 1 /* exit-by-break */ ){
+
    if( op==TK_COLUMN || (op==TK_AGG_COLUMN && pExpr->y.pTab!=0) ){
+
      assert( ExprUseYTab(pExpr) );
+
      assert( pExpr->y.pTab!=0 );
+
      return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
+
    }
+
    if( op==TK_SELECT ){
+
      assert( ExprUseXSelect(pExpr) );
+
      assert( pExpr->x.pSelect!=0 );
+
      assert( pExpr->x.pSelect->pEList!=0 );
+
      assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 );
+
      return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
+
    }
#ifndef SQLITE_OMIT_CAST
-
  if( op==TK_CAST ){
-
    assert( !ExprHasProperty(pExpr, EP_IntValue) );
-
    return sqlite3AffinityType(pExpr->u.zToken, 0);
-
  }
+
    if( op==TK_CAST ){
+
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
+
      return sqlite3AffinityType(pExpr->u.zToken, 0);
+
    }
#endif
-
  if( op==TK_SELECT_COLUMN ){
-
    assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) );
-
    assert( pExpr->iColumn < pExpr->iTable );
-
    assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
-
    return sqlite3ExprAffinity(
-
        pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
-
    );
-
  }
-
  if( op==TK_VECTOR ){
-
    assert( ExprUseXList(pExpr) );
-
    return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
+
    if( op==TK_SELECT_COLUMN ){
+
      assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) );
+
      assert( pExpr->iColumn < pExpr->iTable );
+
      assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
+
      return sqlite3ExprAffinity(
+
          pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
+
      );
+
    }
+
    if( op==TK_VECTOR ){
+
      assert( ExprUseXList(pExpr) );
+
      return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
+
    }
+
    if( ExprHasProperty(pExpr, EP_Skip|EP_IfNullRow) ){
+
      assert( pExpr->op==TK_COLLATE
+
           || pExpr->op==TK_IF_NULL_ROW
+
           || (pExpr->op==TK_REGISTER && pExpr->op2==TK_IF_NULL_ROW) );
+
      pExpr = pExpr->pLeft;
+
      op = pExpr->op;
+
      continue;
+
    }
+
    if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break;
  }
  return pExpr->affExpr;
}

/*
+
** Make a guess at all the possible datatypes of the result that could
+
** be returned by an expression.  Return a bitmask indicating the answer:
+
**
+
**     0x01         Numeric
+
**     0x02         Text
+
**     0x04         Blob
+
**
+
** If the expression must return NULL, then 0x00 is returned.
+
*/
+
SQLITE_PRIVATE int sqlite3ExprDataType(const Expr *pExpr){
+
  while( pExpr ){
+
    switch( pExpr->op ){
+
      case TK_COLLATE:
+
      case TK_IF_NULL_ROW:
+
      case TK_UPLUS:  {
+
        pExpr = pExpr->pLeft;
+
        break;
+
      }
+
      case TK_NULL: {
+
        pExpr = 0;
+
        break;
+
      }
+
      case TK_STRING: {
+
        return 0x02;
+
      }
+
      case TK_BLOB: {
+
        return 0x04;
+
      }
+
      case TK_CONCAT: {
+
        return 0x06;
+
      }
+
      case TK_VARIABLE:
+
      case TK_AGG_FUNCTION:
+
      case TK_FUNCTION: {
+
        return 0x07;
+
      }
+
      case TK_COLUMN:
+
      case TK_AGG_COLUMN:
+
      case TK_SELECT:
+
      case TK_CAST:
+
      case TK_SELECT_COLUMN:
+
      case TK_VECTOR:  {
+
        int aff = sqlite3ExprAffinity(pExpr);
+
        if( aff>=SQLITE_AFF_NUMERIC ) return 0x05;
+
        if( aff==SQLITE_AFF_TEXT )    return 0x06;
+
        return 0x07;
+
      }
+
      case TK_CASE: {
+
        int res = 0;
+
        int ii;
+
        ExprList *pList = pExpr->x.pList;
+
        assert( ExprUseXList(pExpr) && pList!=0 );
+
        assert( pList->nExpr > 0);
+
        for(ii=1; ii<pList->nExpr; ii+=2){
+
          res |= sqlite3ExprDataType(pList->a[ii].pExpr);
+
        }
+
        if( pList->nExpr % 2 ){
+
          res |= sqlite3ExprDataType(pList->a[pList->nExpr-1].pExpr);
+
        }
+
        return res;
+
      }
+
      default: {
+
        return 0x01;
+
      }
+
    } /* End of switch(op) */
+
  } /* End of while(pExpr) */
+
  return 0x00;
+
}
+

+
/*
** Set the collating sequence for expression pExpr to be the collating
** sequence named by pToken.   Return a pointer to a new Expr node that
** implements the COLLATE operator.
@@ -105219,7 +106485,9 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
  while( p ){
    int op = p->op;
    if( op==TK_REGISTER ) op = p->op2;
-
    if( op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER ){
+
    if( (op==TK_AGG_COLUMN && p->y.pTab!=0)
+
     || op==TK_COLUMN || op==TK_TRIGGER
+
    ){
      int j;
      assert( ExprUseYTab(p) );
      assert( p->y.pTab!=0 );
@@ -105249,11 +106517,10 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
      }else{
        Expr *pNext  = p->pRight;
        /* The Expr.x union is never used at the same time as Expr.pRight */
-
        assert( ExprUseXList(p) );
-
        assert( p->x.pList==0 || p->pRight==0 );
-
        if( p->x.pList!=0 && !db->mallocFailed ){
+
        assert( !ExprUseXList(p) || p->x.pList==0 || p->pRight==0 );
+
        if( ExprUseXList(p) && p->x.pList!=0 && !db->mallocFailed ){
          int i;
-
          for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
+
          for(i=0; i<p->x.pList->nExpr; i++){
            if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
              pNext = p->x.pList->a[i].pExpr;
              break;
@@ -106085,9 +107352,9 @@ SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprLis
** Join two expressions using an AND operator.  If either expression is
** NULL, then just return the other expression.
**
-
** If one side or the other of the AND is known to be false, then instead
-
** of returning an AND expression, just return a constant expression with
-
** a value of false.
+
** If one side or the other of the AND is known to be false, and neither side
+
** is part of an ON clause, then instead of returning an AND expression,
+
** just return a constant expression with a value of false.
*/
SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
  sqlite3 *db = pParse->db;
@@ -106095,14 +107362,17 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){
    return pRight;
  }else if( pRight==0 ){
    return pLeft;
-
  }else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight))
-
         && !IN_RENAME_OBJECT
-
  ){
-
    sqlite3ExprDeferredDelete(pParse, pLeft);
-
    sqlite3ExprDeferredDelete(pParse, pRight);
-
    return sqlite3Expr(db, TK_INTEGER, "0");
  }else{
-
    return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
+
    u32 f = pLeft->flags | pRight->flags;
+
    if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse
+
     && !IN_RENAME_OBJECT
+
    ){
+
      sqlite3ExprDeferredDelete(pParse, pLeft);
+
      sqlite3ExprDeferredDelete(pParse, pRight);
+
      return sqlite3Expr(db, TK_INTEGER, "0");
+
    }else{
+
      return sqlite3PExpr(pParse, TK_AND, pLeft, pRight);
+
    }
  }
}

@@ -107347,12 +108617,17 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
}

/*
-
** Check pExpr to see if it is an invariant constraint on data source pSrc.
+
** Check pExpr to see if it is an constraint on the single data source
+
** pSrc = &pSrcList->a[iSrc].  In other words, check to see if pExpr
+
** constrains pSrc but does not depend on any other tables or data
+
** sources anywhere else in the query.  Return true (non-zero) if pExpr
+
** is a constraint on pSrc only.
+
**
** This is an optimization.  False negatives will perhaps cause slower
** queries, but false positives will yield incorrect answers.  So when in
** doubt, return 0.
**
-
** To be an invariant constraint, the following must be true:
+
** To be an single-source constraint, the following must be true:
**
**   (1)  pExpr cannot refer to any table other than pSrc->iCursor.
**
@@ -107363,13 +108638,31 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
**
**   (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.
+
**
+
**   (6) Either:
+
**
+
**       (6a) pExpr does not originate in an ON or USING clause, or
+
**
+
**       (6b) The ON or USING clause from which pExpr is derived is
+
**            not to the left of a RIGHT JOIN (or FULL JOIN).
+
**
+
**       Without this restriction, accepting pExpr as a single-table
+
**       constraint might move the the ON/USING filter expression
+
**       from the left side of a RIGHT JOIN over to the right side,
+
**       which leads to incorrect answers.  See also restriction (9)
+
**       on push-down.
*/
-
SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){
+
SQLITE_PRIVATE int sqlite3ExprIsSingleTableConstraint(
+
  Expr *pExpr,                 /* The constraint */
+
  const SrcList *pSrcList,     /* Complete FROM clause */
+
  int iSrc                     /* Which element of pSrcList to use */
+
){
+
  const SrcItem *pSrc = &pSrcList->a[iSrc];
  if( pSrc->fg.jointype & JT_LTORJ ){
    return 0;  /* rule (3) */
  }
@@ -107379,6 +108672,19 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc
  }else{
    if( ExprHasProperty(pExpr, EP_OuterON) ) return 0;    /* rule (5) */
  }
+
  if( ExprHasProperty(pExpr, EP_OuterON|EP_InnerON)  /* (6a) */
+
   && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0     /* Fast pre-test of (6b) */
+
  ){
+
    int jj;
+
    for(jj=0; jj<iSrc; jj++){
+
      if( pExpr->w.iJoin==pSrcList->a[jj].iCursor ){
+
        if( (pSrcList->a[jj].fg.jointype & JT_LTORJ)!=0 ){
+
          return 0;  /* restriction (6) */
+
        }
+
        break;
+
      }
+
    }
+
  }
  return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */
}

@@ -107621,7 +108927,7 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){
** pX is the RHS of an IN operator.  If pX is a SELECT statement
** that can be simplified to a direct table access, then return
** a pointer to the SELECT statement.  If pX is not a SELECT statement,
-
** or if the SELECT statement needs to be manifested into a transient
+
** or if the SELECT statement needs to be materialized into a transient
** table, then return NULL.
*/
#ifndef SQLITE_OMIT_SUBQUERY
@@ -107907,7 +109213,6 @@ SQLITE_PRIVATE int sqlite3FindInIndex(
            CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
            int j;

-
            assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
            for(j=0; j<nExpr; j++){
              if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
              assert( pIdx->azColl[j] );
@@ -108301,6 +109606,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
  SelectDest dest;            /* How to deal with SELECT result */
  int nReg;                   /* Registers to allocate */
  Expr *pLimit;               /* New limit expression */
+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
  int addrExplain;            /* Address of OP_Explain instruction */
+
#endif

  Vdbe *v = pParse->pVdbe;
  assert( v!=0 );
@@ -108353,8 +109661,9 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
  ** In both cases, the query is augmented with "LIMIT 1".  Any
  ** preexisting limit is discarded in place of the new LIMIT 1.
  */
-
  ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY %d",
+
  ExplainQueryPlan2(addrExplain, (pParse, 1, "%sSCALAR SUBQUERY %d",
        addrOnce?"":"CORRELATED ", pSel->selId));
+
  sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, -1);
  nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
  sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
  pParse->nMem += nReg;
@@ -108397,6 +109706,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
  if( addrOnce ){
    sqlite3VdbeJumpHere(v, addrOnce);
  }
+
  sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1);

  /* Subroutine return */
  assert( ExprUseYSub(pExpr) );
@@ -108805,6 +110115,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(
){
  int iAddr;
  Vdbe *v = pParse->pVdbe;
+
  int nErr = pParse->nErr;
  assert( v!=0 );
  assert( pParse->iSelfTab!=0 );
  if( pParse->iSelfTab>0 ){
@@ -108817,6 +110128,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(
    sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1);
  }
  if( iAddr ) sqlite3VdbeJumpHere(v, iAddr);
+
  if( pParse->nErr>nErr ) pParse->db->errByteOffset = -1;
}
#endif /* SQLITE_OMIT_GENERATED_COLUMNS */

@@ -108833,6 +110145,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(
  Column *pCol;
  assert( v!=0 );
  assert( pTab!=0 );
+
  assert( iCol!=XN_EXPR );
  if( iCol<0 || iCol==pTab->iPKey ){
    sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut);
    VdbeComment((v, "%s.rowid", pTab->zName));
@@ -109069,10 +110382,13 @@ static int exprCodeInlineFunction(
      ** the type affinity of the argument.  This is used for testing of
      ** the SQLite type logic.
      */
-
      const char *azAff[] = { "blob", "text", "numeric", "integer", "real" };
+
      const char *azAff[] = { "blob", "text", "numeric", "integer",
+
                              "real", "flexnum" };
      char aff;
      assert( nFarg==1 );
      aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
+
      assert( aff<=SQLITE_AFF_NONE
+
           || (aff>=SQLITE_AFF_BLOB && aff<=SQLITE_AFF_FLEXNUM) );
      sqlite3VdbeLoadString(v, target,
              (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]);
      break;
@@ -109083,7 +110399,7 @@ static int exprCodeInlineFunction(
}

/*
-
** Check to see if pExpr is one of the indexed expressions on pParse->pIdxExpr.
+
** Check to see if pExpr is one of the indexed expressions on pParse->pIdxEpr.
** If it is, then resolve the expression by reading from the index and
** return the register into which the value has been read.  If pExpr is
** not an indexed expression, then return negative.
@@ -109095,7 +110411,8 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
){
  IndexedExpr *p;
  Vdbe *v;
-
  for(p=pParse->pIdxExpr; p; p=p->pIENext){
+
  for(p=pParse->pIdxEpr; p; p=p->pIENext){
+
    u8 exprAff;
    int iDataCur = p->iDataCur;
    if( iDataCur<0 ) continue;
    if( pParse->iSelfTab ){
@@ -109103,6 +110420,16 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
      iDataCur = -1;
    }
    if( sqlite3ExprCompare(0, pExpr, p->pExpr, iDataCur)!=0 ) continue;
+
    assert( p->aff>=SQLITE_AFF_BLOB && p->aff<=SQLITE_AFF_NUMERIC );
+
    exprAff = sqlite3ExprAffinity(pExpr);
+
    if( (exprAff<=SQLITE_AFF_BLOB && p->aff!=SQLITE_AFF_BLOB)
+
     || (exprAff==SQLITE_AFF_TEXT && p->aff!=SQLITE_AFF_TEXT)
+
     || (exprAff>=SQLITE_AFF_NUMERIC && p->aff!=SQLITE_AFF_NUMERIC)
+
    ){
+
      /* Affinity mismatch on a generated column */
+
      continue;
+
    }
+

    v = pParse->pVdbe;
    assert( v!=0 );
    if( p->bMaybeNullRow ){
@@ -109115,10 +110442,10 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
      sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target);
      VdbeComment((v, "%s expr-column %d", p->zIdxName, p->iIdxCol));
      sqlite3VdbeGoto(v, 0);
-
      p = pParse->pIdxExpr;
-
      pParse->pIdxExpr = 0;
+
      p = pParse->pIdxEpr;
+
      pParse->pIdxEpr = 0;
      sqlite3ExprCode(pParse, pExpr, target);
-
      pParse->pIdxExpr = p;
+
      pParse->pIdxEpr = p;
      sqlite3VdbeJumpHere(v, addr+2);
    }else{
      sqlite3VdbeAddOp3(v, OP_Column, p->iIdxCur, p->iIdxCol, target);
@@ -109157,7 +110484,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
expr_code_doover:
  if( pExpr==0 ){
    op = TK_NULL;
-
  }else if( pParse->pIdxExpr!=0
+
  }else if( pParse->pIdxEpr!=0
   && !ExprHasProperty(pExpr, EP_Leaf)
   && (r1 = sqlite3IndexedExprLookup(pParse, pExpr, target))>=0
  ){
@@ -109171,18 +110498,31 @@ expr_code_doover:
      AggInfo *pAggInfo = pExpr->pAggInfo;
      struct AggInfo_col *pCol;
      assert( pAggInfo!=0 );
-
      assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
+
      assert( pExpr->iAgg>=0 );
+
      if( pExpr->iAgg>=pAggInfo->nColumn ){
+
        /* Happens when the left table of a RIGHT JOIN is null and
+
        ** is using an expression index */
+
        sqlite3VdbeAddOp2(v, OP_Null, 0, target);
+
#ifdef SQLITE_VDBE_COVERAGE
+
        /* Verify that the OP_Null above is exercised by tests
+
        ** tag-20230325-2 */
+
        sqlite3VdbeAddOp2(v, OP_NotNull, target, 1);
+
        VdbeCoverageNeverTaken(v);
+
#endif
+
        break;
+
      }
      pCol = &pAggInfo->aCol[pExpr->iAgg];
      if( !pAggInfo->directMode ){
-
        assert( pCol->iMem>0 );
-
        return pCol->iMem;
+
        return AggInfoColumnReg(pAggInfo, pExpr->iAgg);
      }else if( pAggInfo->useSortingIdx ){
        Table *pTab = pCol->pTab;
        sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab,
                              pCol->iSorterColumn, target);
-
        if( pCol->iColumn<0 ){
+
        if( pTab==0 ){
+
          /* No comment added */
+
        }else if( pCol->iColumn<0 ){
          VdbeComment((v,"%s.rowid",pTab->zName));
-
        }else if( ALWAYS(pTab!=0) ){
+
        }else{
          VdbeComment((v,"%s.%s",
              pTab->zName, pTab->aCol[pCol->iColumn].zCnName));
          if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){
@@ -109190,6 +110530,11 @@ expr_code_doover:
          }
        }
        return target;
+
      }else if( pExpr->y.pTab==0 ){
+
        /* This case happens when the argument to an aggregate function
+
        ** is rewritten by aggregateConvertIndexedExprRefToColumn() */
+
        sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, pExpr->iColumn, target);
+
        return target;
      }
      /* Otherwise, fall thru into the TK_COLUMN case */
      /* no break */ deliberate_fall_through
@@ -109210,7 +110555,7 @@ expr_code_doover:
        assert( pExpr->y.pTab!=0 );
        aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
        if( aff>SQLITE_AFF_BLOB ){
-
          static const char zAff[] = "B\000C\000D\000E";
+
          static const char zAff[] = "B\000C\000D\000E\000F";
          assert( SQLITE_AFF_BLOB=='A' );
          assert( SQLITE_AFF_TEXT=='B' );
          sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
@@ -109340,11 +110685,8 @@ expr_code_doover:
#ifndef SQLITE_OMIT_CAST
    case TK_CAST: {
      /* Expressions of the form:   CAST(pLeft AS token) */
-
      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
-
      if( inReg!=target ){
-
        sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
-
        inReg = target;
-
      }
+
      sqlite3ExprCode(pParse, pExpr->pLeft, target);
+
      assert( inReg==target );
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
      sqlite3VdbeAddOp2(v, OP_Cast, target,
                        sqlite3AffinityType(pExpr->u.zToken, 0));
@@ -109487,7 +110829,7 @@ expr_code_doover:
        assert( !ExprHasProperty(pExpr, EP_IntValue) );
        sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr);
      }else{
-
        return pInfo->aFunc[pExpr->iAgg].iMem;
+
        return AggInfoFuncReg(pInfo, pExpr->iAgg);
      }
      break;
    }
@@ -109676,17 +111018,16 @@ expr_code_doover:
      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;
+
      if( !ExprHasProperty(pExpr, EP_Collate) ){
+
        /* A TK_COLLATE Expr node without the EP_Collate tag is a so-called
+
        ** "SOFT-COLLATE" that is added to constraints that are pushed down
+
        ** from outer queries into sub-queries by the push-down optimization.
+
        ** Clear subtypes as subtypes may not cross a subquery boundary.
+
        */
+
        assert( pExpr->pLeft );
+
        sqlite3ExprCode(pParse, pExpr->pLeft, target);
+
        sqlite3VdbeAddOp1(v, OP_ClrSubtype, target);
+
        return target;
      }else{
        pExpr = pExpr->pLeft;
        goto expr_code_doover; /* 2018-04-28: Prevent deep recursion. */
@@ -109776,7 +111117,7 @@ expr_code_doover:
      if( pAggInfo ){
        assert( pExpr->iAgg>=0 && pExpr->iAgg<pAggInfo->nColumn );
        if( !pAggInfo->directMode ){
-
          inReg = pAggInfo->aCol[pExpr->iAgg].iMem;
+
          inReg = AggInfoColumnReg(pAggInfo, pExpr->iAgg);
          break;
        }
        if( pExpr->pAggInfo->useSortingIdx ){
@@ -109787,16 +111128,19 @@ expr_code_doover:
          break;
        }
      }
-
      addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable);
-
      /* Temporarily disable factoring of constant expressions, since
-
      ** even though expressions may appear to be constant, they are not
-
      ** really constant because they originate from the right-hand side
-
      ** of a LEFT JOIN. */
-
      pParse->okConstFactor = 0;
-
      inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
+
      addrINR = sqlite3VdbeAddOp3(v, OP_IfNullRow, pExpr->iTable, 0, target);
+
      /* The OP_IfNullRow opcode above can overwrite the result register with
+
      ** NULL.  So we have to ensure that the result register is not a value
+
      ** that is suppose to be a constant.  Two defenses are needed:
+
      **   (1)  Temporarily disable factoring of constant expressions
+
      **   (2)  Make sure the computed value really is stored in register
+
      **        "target" and not someplace else.
+
      */
+
      pParse->okConstFactor = 0;   /* note (1) above */
+
      sqlite3ExprCode(pParse, pExpr->pLeft, target);
+
      assert( target==inReg );
      pParse->okConstFactor = okConstFactor;
      sqlite3VdbeJumpHere(v, addrINR);
-
      sqlite3VdbeChangeP3(v, addrINR, inReg);
      break;
    }

@@ -110033,7 +111377,9 @@ SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
  inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
  if( inReg!=target ){
    u8 op;
-
    if( ALWAYS(pExpr) && ExprHasProperty(pExpr,EP_Subquery) ){
+
    if( ALWAYS(pExpr)
+
     && (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER)
+
    ){
      op = OP_Copy;
    }else{
      op = OP_SCopy;
@@ -111207,10 +112553,8 @@ SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList
** it does, make a copy.  This is done because the pExpr argument is
** subject to change.
**
-
** The copy is stored on pParse->pConstExpr with a register number of 0.
-
** This will cause the expression to be deleted automatically when the
-
** Parse object is destroyed, but the zero register number means that it
-
** will not generate any code in the preamble.
+
** The copy is scheduled for deletion using the sqlite3ExprDeferredDelete()
+
** which builds on the sqlite3ParserAddCleanup() mechanism.
*/
static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
  if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced))
@@ -111220,10 +112564,11 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
    int iAgg = pExpr->iAgg;
    Parse *pParse = pWalker->pParse;
    sqlite3 *db = pParse->db;
+
    assert( iAgg>=0 );
    if( pExpr->op!=TK_AGG_FUNCTION ){
-
      assert( pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_IF_NULL_ROW );
-
      assert( iAgg>=0 && iAgg<pAggInfo->nColumn );
-
      if( pAggInfo->aCol[iAgg].pCExpr==pExpr ){
+
      if( iAgg<pAggInfo->nColumn
+
       && pAggInfo->aCol[iAgg].pCExpr==pExpr
+
      ){
        pExpr = sqlite3ExprDup(db, pExpr, 0);
        if( pExpr ){
          pAggInfo->aCol[iAgg].pCExpr = pExpr;
@@ -111232,8 +112577,9 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
      }
    }else{
      assert( pExpr->op==TK_AGG_FUNCTION );
-
      assert( iAgg>=0 && iAgg<pAggInfo->nFunc );
-
      if( pAggInfo->aFunc[iAgg].pFExpr==pExpr ){
+
      if( ALWAYS(iAgg<pAggInfo->nFunc)
+
       && pAggInfo->aFunc[iAgg].pFExpr==pExpr
+
      ){
        pExpr = sqlite3ExprDup(db, pExpr, 0);
        if( pExpr ){
          pAggInfo->aFunc[iAgg].pFExpr = pExpr;
@@ -111289,6 +112635,73 @@ static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){
}

/*
+
** Search the AggInfo object for an aCol[] entry that has iTable and iColumn.
+
** Return the index in aCol[] of the entry that describes that column.
+
**
+
** If no prior entry is found, create a new one and return -1.  The
+
** new column will have an idex of pAggInfo->nColumn-1.
+
*/
+
static void findOrCreateAggInfoColumn(
+
  Parse *pParse,       /* Parsing context */
+
  AggInfo *pAggInfo,   /* The AggInfo object to search and/or modify */
+
  Expr *pExpr          /* Expr describing the column to find or insert */
+
){
+
  struct AggInfo_col *pCol;
+
  int k;
+

+
  assert( pAggInfo->iFirstReg==0 );
+
  pCol = pAggInfo->aCol;
+
  for(k=0; k<pAggInfo->nColumn; k++, pCol++){
+
    if( pCol->iTable==pExpr->iTable
+
     && pCol->iColumn==pExpr->iColumn
+
     && pExpr->op!=TK_IF_NULL_ROW
+
    ){
+
      goto fix_up_expr;
+
    }
+
  }
+
  k = addAggInfoColumn(pParse->db, pAggInfo);
+
  if( k<0 ){
+
    /* OOM on resize */
+
    assert( pParse->db->mallocFailed );
+
    return;
+
  }
+
  pCol = &pAggInfo->aCol[k];
+
  assert( ExprUseYTab(pExpr) );
+
  pCol->pTab = pExpr->y.pTab;
+
  pCol->iTable = pExpr->iTable;
+
  pCol->iColumn = pExpr->iColumn;
+
  pCol->iSorterColumn = -1;
+
  pCol->pCExpr = pExpr;
+
  if( pAggInfo->pGroupBy && pExpr->op!=TK_IF_NULL_ROW ){
+
    int j, n;
+
    ExprList *pGB = pAggInfo->pGroupBy;
+
    struct ExprList_item *pTerm = pGB->a;
+
    n = pGB->nExpr;
+
    for(j=0; j<n; j++, pTerm++){
+
      Expr *pE = pTerm->pExpr;
+
      if( pE->op==TK_COLUMN
+
       && pE->iTable==pExpr->iTable
+
       && pE->iColumn==pExpr->iColumn
+
      ){
+
        pCol->iSorterColumn = j;
+
        break;
+
      }
+
    }
+
  }
+
  if( pCol->iSorterColumn<0 ){
+
    pCol->iSorterColumn = pAggInfo->nSortingColumn++;
+
  }
+
fix_up_expr:
+
  ExprSetVVAProperty(pExpr, EP_NoReduce);
+
  assert( pExpr->pAggInfo==0 || pExpr->pAggInfo==pAggInfo );
+
  pExpr->pAggInfo = pAggInfo;
+
  if( pExpr->op==TK_COLUMN ){
+
    pExpr->op = TK_AGG_COLUMN;
+
  }
+
  pExpr->iAgg = (i16)k;
+
}
+

+
/*
** This is the xExprCallback for a tree walker.  It is used to
** implement sqlite3ExprAnalyzeAggregates().  See sqlite3ExprAnalyzeAggregates
** for additional information.
@@ -111301,7 +112714,45 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
  AggInfo *pAggInfo = pNC->uNC.pAggInfo;

  assert( pNC->ncFlags & NC_UAggInfo );
+
  assert( pAggInfo->iFirstReg==0 );
  switch( pExpr->op ){
+
    default: {
+
      IndexedExpr *pIEpr;
+
      Expr tmp;
+
      assert( pParse->iSelfTab==0 );
+
      if( (pNC->ncFlags & NC_InAggFunc)==0 ) break;
+
      if( pParse->pIdxEpr==0 ) break;
+
      for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){
+
        int iDataCur = pIEpr->iDataCur;
+
        if( iDataCur<0 ) continue;
+
        if( sqlite3ExprCompare(0, pExpr, pIEpr->pExpr, iDataCur)==0 ) break;
+
      }
+
      if( pIEpr==0 ) break;
+
      if( NEVER(!ExprUseYTab(pExpr)) ) break;
+
      for(i=0; i<pSrcList->nSrc; i++){
+
         if( pSrcList->a[0].iCursor==pIEpr->iDataCur ) break;
+
      }
+
      if( i>=pSrcList->nSrc ) break;
+
      if( NEVER(pExpr->pAggInfo!=0) ) break; /* Resolved by outer context */
+
      if( pParse->nErr ){ return WRC_Abort; }
+

+
      /* If we reach this point, it means that expression pExpr can be
+
      ** translated into a reference to an index column as described by
+
      ** pIEpr.
+
      */
+
      memset(&tmp, 0, sizeof(tmp));
+
      tmp.op = TK_AGG_COLUMN;
+
      tmp.iTable = pIEpr->iIdxCur;
+
      tmp.iColumn = pIEpr->iIdxCol;
+
      findOrCreateAggInfoColumn(pParse, pAggInfo, &tmp);
+
      if( pParse->nErr ){ return WRC_Abort; }
+
      assert( pAggInfo->aCol!=0 );
+
      assert( tmp.iAgg<pAggInfo->nColumn );
+
      pAggInfo->aCol[tmp.iAgg].pCExpr = pExpr;
+
      pExpr->pAggInfo = pAggInfo;
+
      pExpr->iAgg = tmp.iAgg;
+
      return WRC_Prune;
+
    }
    case TK_IF_NULL_ROW:
    case TK_AGG_COLUMN:
    case TK_COLUMN: {
@@ -111313,72 +112764,14 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
      if( ALWAYS(pSrcList!=0) ){
        SrcItem *pItem = pSrcList->a;
        for(i=0; i<pSrcList->nSrc; i++, pItem++){
-
          struct AggInfo_col *pCol;
          assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
          if( pExpr->iTable==pItem->iCursor ){
-
            /* If we reach this point, it means that pExpr refers to a table
-
            ** that is in the FROM clause of the aggregate query.
-
            **
-
            ** Make an entry for the column in pAggInfo->aCol[] if there
-
            ** is not an entry there already.
-
            */
-
            int k;
-
            pCol = pAggInfo->aCol;
-
            for(k=0; k<pAggInfo->nColumn; k++, pCol++){
-
              if( pCol->iTable==pExpr->iTable
-
               && pCol->iColumn==pExpr->iColumn
-
               && pExpr->op!=TK_IF_NULL_ROW
-
              ){
-
                break;
-
              }
-
            }
-
            if( (k>=pAggInfo->nColumn)
-
             && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
-
            ){
-
              pCol = &pAggInfo->aCol[k];
-
              assert( ExprUseYTab(pExpr) );
-
              pCol->pTab = pExpr->y.pTab;
-
              pCol->iTable = pExpr->iTable;
-
              pCol->iColumn = pExpr->iColumn;
-
              pCol->iMem = ++pParse->nMem;
-
              pCol->iSorterColumn = -1;
-
              pCol->pCExpr = pExpr;
-
              if( pAggInfo->pGroupBy && pExpr->op!=TK_IF_NULL_ROW ){
-
                int j, n;
-
                ExprList *pGB = pAggInfo->pGroupBy;
-
                struct ExprList_item *pTerm = pGB->a;
-
                n = pGB->nExpr;
-
                for(j=0; j<n; j++, pTerm++){
-
                  Expr *pE = pTerm->pExpr;
-
                  if( pE->op==TK_COLUMN
-
                   && pE->iTable==pExpr->iTable
-
                   && pE->iColumn==pExpr->iColumn
-
                  ){
-
                    pCol->iSorterColumn = j;
-
                    break;
-
                  }
-
                }
-
              }
-
              if( pCol->iSorterColumn<0 ){
-
                pCol->iSorterColumn = pAggInfo->nSortingColumn++;
-
              }
-
            }
-
            /* There is now an entry for pExpr in pAggInfo->aCol[] (either
-
            ** because it was there before or because we just created it).
-
            ** Convert the pExpr to be a TK_AGG_COLUMN referring to that
-
            ** pAggInfo->aCol[] entry.
-
            */
-
            ExprSetVVAProperty(pExpr, EP_NoReduce);
-
            pExpr->pAggInfo = pAggInfo;
-
            if( pExpr->op==TK_COLUMN ){
-
              pExpr->op = TK_AGG_COLUMN;
-
            }
-
            pExpr->iAgg = (i16)k;
+
            findOrCreateAggInfoColumn(pParse, pAggInfo, pExpr);
            break;
          } /* endif pExpr->iTable==pItem->iCursor */
        } /* end loop over pSrcList */
      }
-
      return WRC_Prune;
+
      return WRC_Continue;
    }
    case TK_AGG_FUNCTION: {
      if( (pNC->ncFlags & NC_InAggFunc)==0
@@ -111403,7 +112796,6 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
            assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
            pItem = &pAggInfo->aFunc[i];
            pItem->pFExpr = pExpr;
-
            pItem->iMem = ++pParse->nMem;
            assert( ExprUseUToken(pExpr) );
            pItem->pFunc = sqlite3FindFunction(pParse->db,
                   pExpr->u.zToken,
@@ -111533,6 +112925,37 @@ SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){
}

/*
+
** Make sure sufficient registers have been allocated so that
+
** iReg is a valid register number.
+
*/
+
SQLITE_PRIVATE void sqlite3TouchRegister(Parse *pParse, int iReg){
+
  if( pParse->nMem<iReg ) pParse->nMem = iReg;
+
}
+

+
#if defined(SQLITE_ENABLE_STAT4) || defined(SQLITE_DEBUG)
+
/*
+
** Return the latest reusable register in the set of all registers.
+
** The value returned is no less than iMin.  If any register iMin or
+
** greater is in permanent use, then return one more than that last
+
** permanent register.
+
*/
+
SQLITE_PRIVATE int sqlite3FirstAvailableRegister(Parse *pParse, int iMin){
+
  const ExprList *pList = pParse->pConstExpr;
+
  if( pList ){
+
    int i;
+
    for(i=0; i<pList->nExpr; i++){
+
      if( pList->a[i].u.iConstExprReg>=iMin ){
+
        iMin = pList->a[i].u.iConstExprReg + 1;
+
      }
+
    }
+
  }
+
  pParse->nTempReg = 0;
+
  pParse->nRangeReg = 0;
+
  return iMin;
+
}
+
#endif /* SQLITE_ENABLE_STAT4 || SQLITE_DEBUG */
+

+
/*
** Validate that no temporary register falls within the range of
** iFirst..iLast, inclusive.  This routine is only call from within assert()
** statements.
@@ -111551,6 +112974,14 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){
      return 0;
    }
  }
+
  if( pParse->pConstExpr ){
+
    ExprList *pList = pParse->pConstExpr;
+
    for(i=0; i<pList->nExpr; i++){
+
      int iReg = pList->a[i].u.iConstExprReg;
+
      if( iReg==0 ) continue;
+
      if( iReg>=iFirst && iReg<=iLast ) return 0;
+
    }
+
  }
  return 1;
}
#endif /* SQLITE_DEBUG */
@@ -112300,13 +113731,14 @@ static void renameTokenCheckAll(Parse *pParse, const void *pPtr){
  assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
  if( pParse->nErr==0 ){
    const RenameToken *p;
-
    u8 i = 0;
+
    u32 i = 1;
    for(p=pParse->pRename; p; p=p->pNext){
      if( p->p ){
        assert( p->p!=pPtr );
-
        i += *(u8*)(p->p);
+
        i += *(u8*)(p->p) | 1;
      }
    }
+
    assert( i>0 );
  }
}
#else
@@ -112838,6 +114270,19 @@ static int renameEditSql(
}

/*
+
** Set all pEList->a[].fg.eEName fields in the expression-list to val.
+
*/
+
static void renameSetENames(ExprList *pEList, int val){
+
  if( pEList ){
+
    int i;
+
    for(i=0; i<pEList->nExpr; i++){
+
      assert( val==ENAME_NAME || pEList->a[i].fg.eEName==ENAME_NAME );
+
      pEList->a[i].fg.eEName = val;
+
    }
+
  }
+
}
+

+
/*
** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming
** it was read from the schema of database zDb. Return SQLITE_OK if
** successful. Otherwise, return an SQLite error code and leave an error
@@ -112884,7 +114329,17 @@ static int renameResolveTrigger(Parse *pParse){
          pSrc = 0;
          rc = SQLITE_NOMEM;
        }else{
+
          /* pStep->pExprList contains an expression-list used for an UPDATE
+
          ** statement. So the a[].zEName values are the RHS of the
+
          ** "<col> = <expr>" clauses of the UPDATE statement. So, before
+
          ** running SelectPrep(), change all the eEName values in
+
          ** pStep->pExprList to ENAME_SPAN (from their current value of
+
          ** ENAME_NAME). This is to prevent any ids in ON() clauses that are
+
          ** part of pSrc from being incorrectly resolved against the
+
          ** a[].zEName values as if they were column aliases.  */
+
          renameSetENames(pStep->pExprList, ENAME_SPAN);
          sqlite3SelectPrep(pParse, pSel, 0);
+
          renameSetENames(pStep->pExprList, ENAME_NAME);
          rc = pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
          assert( pStep->pExprList==0 || pStep->pExprList==pSel->pEList );
          assert( pSrc==pSel->pSrc );
@@ -114833,11 +116288,15 @@ static void analyzeOneTable(
  int regIdxname = iMem++;     /* Register containing index name */
  int regStat1 = iMem++;       /* Value for the stat column of sqlite_stat1 */
  int regPrev = iMem;          /* MUST BE LAST (see below) */
+
#ifdef SQLITE_ENABLE_STAT4
+
  int doOnce = 1;              /* Flag for a one-time computation */
+
#endif
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
  Table *pStat1 = 0;
#endif

-
  pParse->nMem = MAX(pParse->nMem, iMem);
+
  sqlite3TouchRegister(pParse, iMem);
+
  assert( sqlite3NoTempsInRange(pParse, regNewRowid, iMem) );
  v = sqlite3GetVdbe(pParse);
  if( v==0 || NEVER(pTab==0) ){
    return;
@@ -114943,7 +116402,7 @@ static void analyzeOneTable(
    ** the regPrev array and a trailing rowid (the rowid slot is required
    ** when building a record to insert into the sample column of
    ** the sqlite_stat4 table.  */
-
    pParse->nMem = MAX(pParse->nMem, regPrev+nColTest);
+
    sqlite3TouchRegister(pParse, regPrev+nColTest);

    /* Open a read-only cursor on the index being analyzed. */
    assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) );
@@ -115115,7 +116574,35 @@ static void analyzeOneTable(
      int addrIsNull;
      u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;

-
      pParse->nMem = MAX(pParse->nMem, regCol+nCol);
+
      if( doOnce ){
+
        int mxCol = nCol;
+
        Index *pX;
+

+
        /* Compute the maximum number of columns in any index */
+
        for(pX=pTab->pIndex; pX; pX=pX->pNext){
+
          int nColX;                     /* Number of columns in pX */
+
          if( !HasRowid(pTab) && IsPrimaryKeyIndex(pX) ){
+
            nColX = pX->nKeyCol;
+
          }else{
+
            nColX = pX->nColumn;
+
          }
+
          if( nColX>mxCol ) mxCol = nColX;
+
        }
+

+
        /* Allocate space to compute results for the largest index */
+
        sqlite3TouchRegister(pParse, regCol+mxCol);
+
        doOnce = 0;
+
#ifdef SQLITE_DEBUG
+
        /* Verify that the call to sqlite3ClearTempRegCache() below
+
        ** really is needed.
+
        ** https://sqlite.org/forum/forumpost/83cb4a95a0 (2023-03-25)
+
        */
+
        testcase( !sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) );
+
#endif
+
        sqlite3ClearTempRegCache(pParse);  /* tag-20230325-1 */
+
        assert( sqlite3NoTempsInRange(pParse, regEq, regCol+mxCol) );
+
      }
+
      assert( sqlite3NoTempsInRange(pParse, regEq, regCol+nCol) );

      addrNext = sqlite3VdbeCurrentAddr(v);
      callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
@@ -115196,6 +116683,11 @@ static void analyzeDatabase(Parse *pParse, int iDb){
  for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
    Table *pTab = (Table*)sqliteHashData(k);
    analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab);
+
#ifdef SQLITE_ENABLE_STAT4
+
    iMem = sqlite3FirstAvailableRegister(pParse, iMem);
+
#else
+
    assert( iMem==sqlite3FirstAvailableRegister(pParse,iMem) );
+
#endif
  }
  loadAnalysis(pParse, iDb);
}
@@ -115436,6 +116928,8 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
** and its contents.
*/
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
+
  assert( db!=0 );
+
  assert( pIdx!=0 );
#ifdef SQLITE_ENABLE_STAT4
  if( pIdx->aSample ){
    int j;
@@ -115445,7 +116939,7 @@ SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
    }
    sqlite3DbFree(db, pIdx->aSample);
  }
-
  if( db && db->pnBytesFreed==0 ){
+
  if( db->pnBytesFreed==0 ){
    pIdx->nSample = 0;
    pIdx->aSample = 0;
  }
@@ -115581,6 +117075,10 @@ static int loadStatTbl(
    pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
    assert( pIdx==0 || pIdx->nSample==0 );
    if( pIdx==0 ) continue;
+
    if( pIdx->aSample!=0 ){
+
      /* The same index appears in sqlite_stat4 under multiple names */
+
      continue;
+
    }
    assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
    if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
      nIdxCol = pIdx->nKeyCol;
@@ -115588,6 +117086,7 @@ static int loadStatTbl(
      nIdxCol = pIdx->nColumn;
    }
    pIdx->nSampleCol = nIdxCol;
+
    pIdx->mxSample = nSample;
    nByte = sizeof(IndexSample) * nSample;
    nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
    nByte += nIdxCol * sizeof(tRowcnt);     /* Space for Index.aAvgEq[] */
@@ -115627,6 +117126,11 @@ static int loadStatTbl(
    if( zIndex==0 ) continue;
    pIdx = findIndexOrPrimaryKey(db, zIndex, zDb);
    if( pIdx==0 ) continue;
+
    if( pIdx->nSample>=pIdx->mxSample ){
+
      /* Too many slots used because the same index appears in
+
      ** sqlite_stat4 using multiple names */
+
      continue;
+
    }
    /* This next condition is true if data has already been loaded from
    ** the sqlite_stat4 table. */
    nCol = pIdx->nSampleCol;
@@ -115670,11 +117174,12 @@ static int loadStat4(sqlite3 *db, const char *zDb){
  const Table *pStat4;

  assert( db->lookaside.bDisable );
-
  if( (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0
+
  if( OptimizationEnabled(db, SQLITE_Stat4)
+
   && (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0
   && IsOrdinaryTable(pStat4)
  ){
    rc = loadStatTbl(db,
-
      "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx",
+
      "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx COLLATE nocase",
      "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
      zDb
    );
@@ -115864,7 +117369,7 @@ static void attachFunc(
  char *zErr = 0;
  unsigned int flags;
  Db *aNew;                 /* New array of Db pointers */
-
  Db *pNew;                 /* Db object for the newly attached database */
+
  Db *pNew = 0;             /* Db object for the newly attached database */
  char *zErrDyn = 0;
  sqlite3_vfs *pVfs;

@@ -115884,13 +117389,26 @@ static void attachFunc(
    /* This is not a real ATTACH.  Instead, this routine is being called
    ** from sqlite3_deserialize() to close database db->init.iDb and
    ** reopen it as a MemDB */
+
    Btree *pNewBt = 0;
    pVfs = sqlite3_vfs_find("memdb");
    if( pVfs==0 ) return;
-
    pNew = &db->aDb[db->init.iDb];
-
    if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt);
-
    pNew->pBt = 0;
-
    pNew->pSchema = 0;
-
    rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB);
+
    rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNewBt, 0, SQLITE_OPEN_MAIN_DB);
+
    if( rc==SQLITE_OK ){
+
      Schema *pNewSchema = sqlite3SchemaGet(db, pNewBt);
+
      if( pNewSchema ){
+
        /* Both the Btree and the new Schema were allocated successfully.
+
        ** Close the old db and update the aDb[] slot with the new memdb
+
        ** values.  */
+
        pNew = &db->aDb[db->init.iDb];
+
        if( ALWAYS(pNew->pBt) ) sqlite3BtreeClose(pNew->pBt);
+
        pNew->pBt = pNewBt;
+
        pNew->pSchema = pNewSchema;
+
      }else{
+
        sqlite3BtreeClose(pNewBt);
+
        rc = SQLITE_NOMEM;
+
      }
+
    }
+
    if( rc ) goto attach_error;
  }else{
    /* This is a real ATTACH
    **
@@ -116003,7 +117521,7 @@ static void attachFunc(
  }
#endif
  if( rc ){
-
    if( !REOPEN_AS_MEMDB(db) ){
+
    if( ALWAYS(!REOPEN_AS_MEMDB(db)) ){
      int iDb = db->nDb - 1;
      assert( iDb>=2 );
      if( db->aDb[iDb].pBt ){
@@ -116120,6 +117638,8 @@ static void codeAttach(
  sqlite3* db = pParse->db;
  int regArgs;

+
  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ) goto attach_end;
+

  if( pParse->nErr ) goto attach_end;
  memset(&sName, 0, sizeof(NameContext));
  sName.pParse = pParse;
@@ -116962,6 +118482,7 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  char saveBuf[PARSE_TAIL_SZ];

  if( pParse->nErr ) return;
+
  if( pParse->eParseMode ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(db, zFormat, ap);
@@ -117502,7 +119023,7 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){
  if( IsOrdinaryTable(pTable) ){
    sqlite3FkDelete(db, pTable);
  }
-
#ifndef SQLITE_OMIT_VIRTUAL_TABLE
+
#ifndef SQLITE_OMIT_VIRTUALTABLE
  else if( IsVirtual(pTable) ){
    sqlite3VtabClear(db, pTable);
  }
@@ -118105,7 +119626,7 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){
  if( pParse->pNewTrigger ){
    sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger");
  }else{
-
    assert( pParse->bReturning==0 );
+
    assert( pParse->bReturning==0 || pParse->ifNotExists );
  }
  pParse->bReturning = 1;
  pRet = sqlite3DbMallocZero(db, sizeof(*pRet));
@@ -118131,7 +119652,8 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){
  pRet->retTStep.pTrig = &pRet->retTrig;
  pRet->retTStep.pExprList = pList;
  pHash = &(db->aDb[1].pSchema->trigHash);
-
  assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 || pParse->nErr );
+
  assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0
+
          || pParse->nErr  || pParse->ifNotExists );
  if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig)
          ==&pRet->retTrig ){
    sqlite3OomFault(db);
@@ -118659,6 +120181,14 @@ SQLITE_PRIVATE void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType
  if( pCol->colFlags & COLFLAG_PRIMKEY ){
    makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */
  }
+
  if( ALWAYS(pExpr) && pExpr->op==TK_ID ){
+
    /* The value of a generated column needs to be a real expression, not
+
    ** just a reference to another column, in order for covering index
+
    ** optimizations to work correctly.  So if the value is not an expression,
+
    ** turn it into one by adding a unary "+" operator. */
+
    pExpr = sqlite3PExpr(pParse, TK_UPLUS, pExpr, 0);
+
  }
+
  if( pExpr && pExpr->op!=TK_RAISE ) pExpr->affExpr = pCol->affinity;
  sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr);
  pExpr = 0;
  goto generated_done;
@@ -118795,7 +120325,8 @@ static char *createTableStmt(sqlite3 *db, Table *p){
        /* SQLITE_AFF_TEXT    */ " TEXT",
        /* SQLITE_AFF_NUMERIC */ " NUM",
        /* SQLITE_AFF_INTEGER */ " INT",
-
        /* SQLITE_AFF_REAL    */ " REAL"
+
        /* SQLITE_AFF_REAL    */ " REAL",
+
        /* SQLITE_AFF_FLEXNUM */ " NUM",
    };
    int len;
    const char *zType;
@@ -118811,10 +120342,12 @@ static char *createTableStmt(sqlite3 *db, Table *p){
    testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
    testcase( pCol->affinity==SQLITE_AFF_INTEGER );
    testcase( pCol->affinity==SQLITE_AFF_REAL );
+
    testcase( pCol->affinity==SQLITE_AFF_FLEXNUM );

    zType = azType[pCol->affinity - SQLITE_AFF_BLOB];
    len = sqlite3Strlen30(zType);
    assert( pCol->affinity==SQLITE_AFF_BLOB
+
            || pCol->affinity==SQLITE_AFF_FLEXNUM
            || pCol->affinity==sqlite3AffinityType(zType, 0) );
    memcpy(&zStmt[k], zType, len);
    k += len;
@@ -119229,6 +120762,7 @@ SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName){
** not pass them into code generator routines by mistake.
*/
static int markImmutableExprStep(Walker *pWalker, Expr *pExpr){
+
  (void)pWalker;
  ExprSetVVAProperty(pExpr, EP_Immutable);
  return WRC_Continue;
}
@@ -119795,8 +121329,7 @@ static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){
       && pTable->nCol==pSel->pEList->nExpr
      ){
        assert( db->mallocFailed==0 );
-
        sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel,
-
                                               SQLITE_AFF_NONE);
+
        sqlite3SubqueryColumnTypes(pParse, pTable, pSel, SQLITE_AFF_NONE);
      }
    }else{
      /* CREATE VIEW name AS...  without an argument list.  Construct
@@ -122522,6 +124055,7 @@ SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8 enc){
  ** strings is BINARY.
  */
  db->pDfltColl = sqlite3FindCollSeq(db, enc, sqlite3StrBINARY, 0);
+
  sqlite3ExpirePreparedStatements(db, 1);
}

/*
@@ -122993,13 +124527,15 @@ static int tabIsReadOnly(Parse *pParse, Table *pTab){
** If pTab is writable but other errors have occurred -> return 1.
** If pTab is writable and no prior errors -> return 0;
*/
-
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
+
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, Trigger *pTrigger){
  if( tabIsReadOnly(pParse, pTab) ){
    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
    return 1;
  }
#ifndef SQLITE_OMIT_VIEW
-
  if( !viewOk && IsView(pTab) ){
+
  if( IsView(pTab)
+
   && (pTrigger==0 || (pTrigger->bReturning && pTrigger->pNext==0))
+
  ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
@@ -123253,7 +124789,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
    goto delete_from_cleanup;
  }

-
  if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){
+
  if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){
    goto delete_from_cleanup;
  }
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
@@ -123362,7 +124898,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
#endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */
  {
    u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK;
-
    if( sNC.ncFlags & NC_VarSelect ) bComplex = 1;
+
    if( sNC.ncFlags & NC_Subquery ) bComplex = 1;
    wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW);
    if( HasRowid(pTab) ){
      /* For a rowid table, initialize the RowSet to an empty set */
@@ -124980,7 +126516,7 @@ SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){
    }
    case SQLITE_BLOB: {
      char const *zBlob = sqlite3_value_blob(pValue);
-
      int nBlob = sqlite3_value_bytes(pValue);
+
      i64 nBlob = sqlite3_value_bytes(pValue);
      assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */
      sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4);
      if( pStr->accError==0 ){
@@ -125122,6 +126658,96 @@ static void hexFunc(
}

/*
+
** Buffer zStr contains nStr bytes of utf-8 encoded text. Return 1 if zStr
+
** contains character ch, or 0 if it does not.
+
*/
+
static int strContainsChar(const u8 *zStr, int nStr, u32 ch){
+
  const u8 *zEnd = &zStr[nStr];
+
  const u8 *z = zStr;
+
  while( z<zEnd ){
+
    u32 tst = Utf8Read(z);
+
    if( tst==ch ) return 1;
+
  }
+
  return 0;
+
}
+

+
/*
+
** The unhex() function. This function may be invoked with either one or
+
** two arguments. In both cases the first argument is interpreted as text
+
** a text value containing a set of pairs of hexadecimal digits which are
+
** decoded and returned as a blob.
+
**
+
** If there is only a single argument, then it must consist only of an
+
** even number of hexadeximal digits. Otherwise, return NULL.
+
**
+
** Or, if there is a second argument, then any character that appears in
+
** the second argument is also allowed to appear between pairs of hexadecimal
+
** digits in the first argument. If any other character appears in the
+
** first argument, or if one of the allowed characters appears between
+
** two hexadecimal digits that make up a single byte, NULL is returned.
+
**
+
** The following expressions are all true:
+
**
+
**     unhex('ABCD')       IS x'ABCD'
+
**     unhex('AB CD')      IS NULL
+
**     unhex('AB CD', ' ') IS x'ABCD'
+
**     unhex('A BCD', ' ') IS NULL
+
*/
+
static void unhexFunc(
+
  sqlite3_context *pCtx,
+
  int argc,
+
  sqlite3_value **argv
+
){
+
  const u8 *zPass = (const u8*)"";
+
  int nPass = 0;
+
  const u8 *zHex = sqlite3_value_text(argv[0]);
+
  int nHex = sqlite3_value_bytes(argv[0]);
+
#ifdef SQLITE_DEBUG
+
  const u8 *zEnd = zHex ? &zHex[nHex] : 0;
+
#endif
+
  u8 *pBlob = 0;
+
  u8 *p = 0;
+

+
  assert( argc==1 || argc==2 );
+
  if( argc==2 ){
+
    zPass = sqlite3_value_text(argv[1]);
+
    nPass = sqlite3_value_bytes(argv[1]);
+
  }
+
  if( !zHex || !zPass ) return;
+

+
  p = pBlob = contextMalloc(pCtx, (nHex/2)+1);
+
  if( pBlob ){
+
    u8 c;                         /* Most significant digit of next byte */
+
    u8 d;                         /* Least significant digit of next byte */
+

+
    while( (c = *zHex)!=0x00 ){
+
      while( !sqlite3Isxdigit(c) ){
+
        u32 ch = Utf8Read(zHex);
+
        assert( zHex<=zEnd );
+
        if( !strContainsChar(zPass, nPass, ch) ) goto unhex_null;
+
        c = *zHex;
+
        if( c==0x00 ) goto unhex_done;
+
      }
+
      zHex++;
+
      assert( *zEnd==0x00 );
+
      assert( zHex<=zEnd );
+
      d = *(zHex++);
+
      if( !sqlite3Isxdigit(d) ) goto unhex_null;
+
      *(p++) = (sqlite3HexToInt(c)<<4) | sqlite3HexToInt(d);
+
    }
+
  }
+

+
 unhex_done:
+
  sqlite3_result_blob(pCtx, pBlob, (p - pBlob), sqlite3_free);
+
  return;
+

+
 unhex_null:
+
  sqlite3_free(pBlob);
+
  return;
+
}
+

+

+
/*
** The zeroblob(N) function returns a zero-filled blob of size N bytes.
*/
static void zeroblobFunc(
@@ -125326,7 +126952,7 @@ static void trimFunc(
/*
** The "unknown" function is automatically substituted in place of
** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN
-
** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used.
+
** when the SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION compile-time option is used.
** When the "sqlite3" command-line shell is built using this functionality,
** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries
** involving application-defined functions to be examined in a generic
@@ -125338,6 +126964,9 @@ static void unknownFunc(
  sqlite3_value **argv
){
  /* no-op */
+
  (void)context;
+
  (void)argc;
+
  (void)argv;
}
#endif /*SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION*/

@@ -125967,6 +127596,18 @@ static double xCeil(double x){ return ceil(x); }
static double xFloor(double x){ return floor(x); }

/*
+
** Some systems do not have log2() and log10() in their standard math
+
** libraries.
+
*/
+
#if defined(HAVE_LOG10) && HAVE_LOG10==0
+
# define log10(X) (0.4342944819032517867*log(X))
+
#endif
+
#if defined(HAVE_LOG2) && HAVE_LOG2==0
+
# define log2(X) (1.442695040888963456*log(X))
+
#endif
+

+

+
/*
** Implementation of SQL functions:
**
**   ln(X)       - natural logarithm
@@ -126004,17 +127645,15 @@ static void logFunc(
    }
    ans = log(x)/b;
  }else{
-
    ans = log(x);
    switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){
      case 1:
-
        /* Convert from natural logarithm to log base 10 */
-
        ans /= M_LN10;
+
        ans = log10(x);
        break;
      case 2:
-
        /* Convert from natural logarithm to log base 2 */
-
        ans /= M_LN2;
+
        ans = log2(x);
        break;
      default:
+
        ans = log(x);
        break;
    }
  }
@@ -126083,6 +127722,7 @@ static void piFunc(
  sqlite3_value **argv
){
  assert( argc==0 );
+
  (void)argv;
  sqlite3_result_double(context, M_PI);
}

@@ -126183,6 +127823,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){
    FUNCTION(upper,              1, 0, 0, upperFunc        ),
    FUNCTION(lower,              1, 0, 0, lowerFunc        ),
    FUNCTION(hex,                1, 0, 0, hexFunc          ),
+
    FUNCTION(unhex,              1, 0, 0, unhexFunc        ),
+
    FUNCTION(unhex,              2, 0, 0, unhexFunc        ),
    INLINE_FUNC(ifnull,          2, INLINEFUNC_coalesce, 0 ),
    VFUNCTION(random,            0, 0, 0, randomFunc       ),
    VFUNCTION(randomblob,        1, 0, 0, randomBlob       ),
@@ -127613,22 +129255,22 @@ static Trigger *fkActionTrigger(

    if( action==OE_Restrict ){
      int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
-
      Token tFrom;
-
      Token tDb;
+
      SrcList *pSrc;
      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;
      }
+
      pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
+
      if( pSrc ){
+
        assert( pSrc->nSrc==1 );
+
        pSrc->a[0].zName = sqlite3DbStrDup(db, zFrom);
+
        pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName);
+
      }
      pSelect = sqlite3SelectNew(pParse,
          sqlite3ExprListAppend(pParse, 0, pRaise),
-
          sqlite3SrcListAppend(pParse, 0, &tDb, &tFrom),
+
          pSrc,
          pWhere,
          0, 0, 0, 0, 0
      );
@@ -127844,46 +129486,48 @@ SQLITE_PRIVATE void sqlite3OpenTable(
** is managed along with the rest of the Index structure. It will be
** released when sqlite3DeleteIndex() is called.
*/
-
SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
+
static SQLITE_NOINLINE const char *computeIndexAffStr(sqlite3 *db, Index *pIdx){
+
  /* The first time a column affinity string for a particular index is
+
  ** required, it is allocated and populated here. It is then stored as
+
  ** a member of the Index structure for subsequent use.
+
  **
+
  ** The column affinity string will eventually be deleted by
+
  ** sqliteDeleteIndex() when the Index structure itself is cleaned
+
  ** up.
+
  */
+
  int n;
+
  Table *pTab = pIdx->pTable;
+
  pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
  if( !pIdx->zColAff ){
-
    /* The first time a column affinity string for a particular index is
-
    ** required, it is allocated and populated here. It is then stored as
-
    ** a member of the Index structure for subsequent use.
-
    **
-
    ** The column affinity string will eventually be deleted by
-
    ** sqliteDeleteIndex() when the Index structure itself is cleaned
-
    ** up.
-
    */
-
    int n;
-
    Table *pTab = pIdx->pTable;
-
    pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1);
-
    if( !pIdx->zColAff ){
-
      sqlite3OomFault(db);
-
      return 0;
-
    }
-
    for(n=0; n<pIdx->nColumn; n++){
-
      i16 x = pIdx->aiColumn[n];
-
      char aff;
-
      if( x>=0 ){
-
        aff = pTab->aCol[x].affinity;
-
      }else if( x==XN_ROWID ){
-
        aff = SQLITE_AFF_INTEGER;
-
      }else{
-
        assert( x==XN_EXPR );
-
        assert( pIdx->bHasExpr );
-
        assert( pIdx->aColExpr!=0 );
-
        aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
-
      }
-
      if( aff<SQLITE_AFF_BLOB ) aff = SQLITE_AFF_BLOB;
-
      if( aff>SQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC;
-
      pIdx->zColAff[n] = aff;
+
    sqlite3OomFault(db);
+
    return 0;
+
  }
+
  for(n=0; n<pIdx->nColumn; n++){
+
    i16 x = pIdx->aiColumn[n];
+
    char aff;
+
    if( x>=0 ){
+
      aff = pTab->aCol[x].affinity;
+
    }else if( x==XN_ROWID ){
+
      aff = SQLITE_AFF_INTEGER;
+
    }else{
+
      assert( x==XN_EXPR );
+
      assert( pIdx->bHasExpr );
+
      assert( pIdx->aColExpr!=0 );
+
      aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
    }
-
    pIdx->zColAff[n] = 0;
+
    if( aff<SQLITE_AFF_BLOB ) aff = SQLITE_AFF_BLOB;
+
    if( aff>SQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC;
+
    pIdx->zColAff[n] = aff;
  }
-

+
  pIdx->zColAff[n] = 0;
+
  return pIdx->zColAff;
+
}
+
SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
+
  if( !pIdx->zColAff ) return computeIndexAffStr(db, pIdx);
  return pIdx->zColAff;
}

+

/*
** Compute an affinity string for a table.   Space is obtained
** from sqlite3DbMalloc().  The caller is responsible for freeing
@@ -128568,7 +130212,7 @@ SQLITE_PRIVATE void sqlite3Insert(

  /* Cannot insert into a read-only table.
  */
-
  if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
+
  if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){
    goto insert_cleanup;
  }

@@ -129015,7 +130659,7 @@ SQLITE_PRIVATE void sqlite3Insert(
    }

    /* Copy the new data already generated. */
-
    assert( pTab->nNVCol>0 );
+
    assert( pTab->nNVCol>0 || pParse->nErr>0 );
    sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1);

#ifndef SQLITE_OMIT_GENERATED_COLUMNS
@@ -129567,6 +131211,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
          case OE_Fail: {
            char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
                                        pCol->zCnName);
+
            testcase( zMsg==0 && db->mallocFailed==0 );
            sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL,
                              onError, iReg);
            sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
@@ -131458,6 +133103,8 @@ struct sqlite3_api_routines {
  const char *(*db_name)(sqlite3*,int);
  /* Version 3.40.0 and later */
  int (*value_encoding)(sqlite3_value*);
+
  /* Version 3.41.0 and later */
+
  int (*is_interrupted)(sqlite3*);
};

/*
@@ -131784,6 +133431,8 @@ typedef int (*sqlite3_loadext_entry)(
#define sqlite3_db_name                sqlite3_api->db_name
/* Version 3.40.0 and later */
#define sqlite3_value_encoding         sqlite3_api->value_encoding
+
/* Version 3.41.0 and later */
+
#define sqlite3_is_interrupted         sqlite3_api->is_interrupted
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */

#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
@@ -132298,7 +133947,9 @@ static const sqlite3_api_routines sqlite3Apis = {
#endif
  sqlite3_db_name,
  /* Version 3.40.0 and later */
-
  sqlite3_value_type
+
  sqlite3_value_encoding,
+
  /* Version 3.41.0 and later */
+
  sqlite3_is_interrupted
};

/* True if x is the directory separator character
@@ -132371,7 +134022,11 @@ static int sqlite3LoadExtension(
  /* tag-20210611-1.  Some dlopen() implementations will segfault if given
  ** an oversize filename.  Most filesystems have a pathname limit of 4K,
  ** so limit the extension filename length to about twice that.
-
  ** https://sqlite.org/forum/forumpost/08a0d6d9bf */
+
  ** https://sqlite.org/forum/forumpost/08a0d6d9bf
+
  **
+
  ** Later (2023-03-25): Save an extra 6 bytes for the filename suffix.
+
  ** See https://sqlite.org/forum/forumpost/24083b579d.
+
  */
  if( nMsg>SQLITE_MAX_PATHLEN ) goto extension_not_found;

  handle = sqlite3OsDlOpen(pVfs, zFile);
@@ -132379,7 +134034,9 @@ static int sqlite3LoadExtension(
  for(ii=0; ii<ArraySize(azEndings) && handle==0; ii++){
    char *zAltFile = sqlite3_mprintf("%s.%s", zFile, azEndings[ii]);
    if( zAltFile==0 ) return SQLITE_NOMEM_BKPT;
-
    handle = sqlite3OsDlOpen(pVfs, zAltFile);
+
    if( nMsg+strlen(azEndings[ii])+1<=SQLITE_MAX_PATHLEN ){
+
      handle = sqlite3OsDlOpen(pVfs, zAltFile);
+
    }
    sqlite3_free(zAltFile);
  }
#endif
@@ -134874,7 +136531,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
      zDb = db->aDb[iDb].zDbSName;
      sqlite3CodeVerifySchema(pParse, iDb);
      sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
-
      if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
+
      sqlite3TouchRegister(pParse, pTab->nCol+regRow);
      sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
      sqlite3VdbeLoadString(v, regResult, pTab->zName);
      assert( IsOrdinaryTable(pTab) );
@@ -134915,7 +136572,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
        ** regRow..regRow+n. If any of the child key values are NULL, this
        ** row cannot cause an FK violation. Jump directly to addrOk in
        ** this case. */
-
        if( regRow+pFK->nCol>pParse->nMem ) pParse->nMem = regRow+pFK->nCol;
+
        sqlite3TouchRegister(pParse, regRow + pFK->nCol);
        for(j=0; j<pFK->nCol; j++){
          int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;
          sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j);
@@ -135044,6 +136701,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
      if( iDb>=0 && i!=iDb ) continue;

      sqlite3CodeVerifySchema(pParse, i);
+
      pParse->okConstFactor = 0;  /* tag-20230327-1 */

      /* Do an integrity check of the B-Tree
      **
@@ -135079,7 +136737,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
      aRoot[0] = cnt;

      /* Make sure sufficient number of registers have been allocated */
-
      pParse->nMem = MAX( pParse->nMem, 8+mxIdx );
+
      sqlite3TouchRegister(pParse, 8+mxIdx);
      sqlite3ClearTempRegCache(pParse);

      /* Do the b-tree integrity checks */
@@ -135135,12 +136793,21 @@ SQLITE_PRIVATE void sqlite3Pragma(
        ** will also prepopulate the cursor column cache that is used
        ** by the OP_IsType code, so it is a required step.
        */
-
        mxCol = pTab->nCol-1;
-
        while( mxCol>=0
-
            && ((pTab->aCol[mxCol].colFlags & COLFLAG_VIRTUAL)!=0
-
                || pTab->iPKey==mxCol) ) mxCol--;
+
        assert( !IsVirtual(pTab) );
+
        if( HasRowid(pTab) ){
+
          mxCol = -1;
+
          for(j=0; j<pTab->nCol; j++){
+
            if( (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)==0 ) mxCol++;
+
          }
+
          if( mxCol==pTab->iPKey ) mxCol--;
+
        }else{
+
          /* COLFLAG_VIRTUAL columns are not included in the WITHOUT ROWID
+
          ** PK index column-count, so there is no need to account for them
+
          ** in this case. */
+
          mxCol = sqlite3PrimaryKeyIndex(pTab)->nColumn-1;
+
        }
        if( mxCol>=0 ){
-
          sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, mxCol, 3);
+
          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, mxCol, 3);
          sqlite3VdbeTypeofColumn(v, 3);
        }

@@ -135220,15 +136887,29 @@ SQLITE_PRIVATE void sqlite3Pragma(
          labelOk = sqlite3VdbeMakeLabel(pParse);
          if( pCol->notNull ){
            /* (1) NOT NULL columns may not contain a NULL */
+
            int jmp3;
            int jmp2 = sqlite3VdbeAddOp4Int(v, OP_IsType, p1, labelOk, p3, p4);
-
            sqlite3VdbeChangeP5(v, 0x0f);
            VdbeCoverage(v);
+
            if( p1<0 ){
+
              sqlite3VdbeChangeP5(v, 0x0f); /* INT, REAL, TEXT, or BLOB */
+
              jmp3 = jmp2;
+
            }else{
+
              sqlite3VdbeChangeP5(v, 0x0d); /* INT, TEXT, or BLOB */
+
              /* OP_IsType does not detect NaN values in the database file
+
              ** which should be treated as a NULL.  So if the header type
+
              ** is REAL, we have to load the actual data using OP_Column
+
              ** to reliably determine if the value is a NULL. */
+
              sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3);
+
              jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk);
+
              VdbeCoverage(v);
+
            }
            zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
                                pCol->zCnName);
            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
            if( doTypeCheck ){
              sqlite3VdbeGoto(v, labelError);
              sqlite3VdbeJumpHere(v, jmp2);
+
              sqlite3VdbeJumpHere(v, jmp3);
            }else{
              /* VDBE byte code will fall thru */
            }
@@ -135308,7 +136989,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
        if( !isQuick ){ /* Omit the remaining tests for quick_check */
          /* Validate index entries for the current row */
          for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
-
            int jmp2, jmp3, jmp4, jmp5;
+
            int jmp2, jmp3, jmp4, jmp5, label6;
+
            int kk;
            int ckUniq = sqlite3VdbeMakeLabel(pParse);
            if( pPk==pIdx ) continue;
            r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
@@ -135326,13 +137008,49 @@ SQLITE_PRIVATE void sqlite3Pragma(
            sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
            jmp4 = integrityCheckResultRow(v);
            sqlite3VdbeJumpHere(v, jmp2);
+

+
            /* The OP_IdxRowid opcode is an optimized version of OP_Column
+
            ** that extracts the rowid off the end of the index record.
+
            ** But it only works correctly if index record does not have
+
            ** any extra bytes at the end.  Verify that this is the case. */
+
            if( HasRowid(pTab) ){
+
              int jmp7;
+
              sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur+j, 3);
+
              jmp7 = sqlite3VdbeAddOp3(v, OP_Eq, 3, 0, r1+pIdx->nColumn-1);
+
              VdbeCoverageNeverNull(v);
+
              sqlite3VdbeLoadString(v, 3,
+
                 "rowid not at end-of-record for row ");
+
              sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
+
              sqlite3VdbeLoadString(v, 4, " of index ");
+
              sqlite3VdbeGoto(v, jmp5-1);
+
              sqlite3VdbeJumpHere(v, jmp7);
+
            }
+

+
            /* Any indexed columns with non-BINARY collations must still hold
+
            ** the exact same text value as the table. */
+
            label6 = 0;
+
            for(kk=0; kk<pIdx->nKeyCol; kk++){
+
              if( pIdx->azColl[kk]==sqlite3StrBINARY ) continue;
+
              if( label6==0 ) label6 = sqlite3VdbeMakeLabel(pParse);
+
              sqlite3VdbeAddOp3(v, OP_Column, iIdxCur+j, kk, 3);
+
              sqlite3VdbeAddOp3(v, OP_Ne, 3, label6, r1+kk); VdbeCoverage(v);
+
            }
+
            if( label6 ){
+
              int jmp6 = sqlite3VdbeAddOp0(v, OP_Goto);
+
              sqlite3VdbeResolveLabel(v, label6);
+
              sqlite3VdbeLoadString(v, 3, "row ");
+
              sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
+
              sqlite3VdbeLoadString(v, 4, " values differ from index ");
+
              sqlite3VdbeGoto(v, jmp5-1);
+
              sqlite3VdbeJumpHere(v, jmp6);
+
            }
+

            /* For UNIQUE indexes, verify that only one entry exists with the
            ** current key.  The entry is unique if (1) any column is NULL
            ** or (2) the next entry has a different key */
            if( IsUniqueIndex(pIdx) ){
              int uniqOk = sqlite3VdbeMakeLabel(pParse);
              int jmp6;
-
              int kk;
              for(kk=0; kk<pIdx->nKeyCol; kk++){
                int iCol = pIdx->aiColumn[kk];
                assert( iCol!=XN_ROWID && iCol<pTab->nCol );
@@ -136505,7 +138223,14 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl
#else
      encoding = SQLITE_UTF8;
#endif
-
      sqlite3SetTextEncoding(db, encoding);
+
      if( db->nVdbeActive>0 && encoding!=ENC(db)
+
       && (db->mDbFlags & DBFLAG_Vacuum)==0
+
      ){
+
        rc = SQLITE_LOCKED;
+
        goto initone_error_out;
+
      }else{
+
        sqlite3SetTextEncoding(db, encoding);
+
      }
    }else{
      /* If opening an attached database, the encoding much match ENC(db) */
      if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){
@@ -136719,8 +138444,8 @@ static void schemaIsValid(Parse *pParse){
    sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
    if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
+
      if( DbHasProperty(db, iDb, DB_SchemaLoaded) ) pParse->rc = SQLITE_SCHEMA;
      sqlite3ResetOneSchema(db, iDb);
-
      pParse->rc = SQLITE_SCHEMA;
    }

    /* Close the transaction, if one was opened. */
@@ -136894,7 +138619,11 @@ static int sqlite3Prepare(
  sParse.db = db;
  sParse.pReprepare = pReprepare;
  assert( ppStmt && *ppStmt==0 );
-
  if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory");
+
  if( db->mallocFailed ){
+
    sqlite3ErrorMsg(&sParse, "out of memory");
+
    db->errCode = rc = SQLITE_NOMEM;
+
    goto end_prepare;
+
  }
  assert( sqlite3_mutex_held(db->mutex) );

  /* For a long-term use prepared statement avoid the use of
@@ -137331,6 +139060,10 @@ struct SortCtx {
  } aDefer[4];
#endif
  struct RowLoadInfo *pDeferredRowLoad;  /* Deferred row loading info or NULL */
+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
  int addrPush;         /* First instruction to push data into sorter */
+
  int addrPushEnd;      /* Last instruction that pushes data into sorter */
+
#endif
};
#define SORTFLAG_UseSorter  0x01   /* Use SorterOpen instead of OpenEphemeral */

@@ -137979,7 +139712,7 @@ static void pushOntoSorter(
  **   (2) All output columns are included in the sort record.  In that
  **       case regData==regOrigData.
  **   (3) Some output columns are omitted from the sort record due to
-
  **       the SQLITE_ENABLE_SORTER_REFERENCE optimization, or due to the
+
  **       the SQLITE_ENABLE_SORTER_REFERENCES optimization, or due to the
  **       SQLITE_ECEL_OMITREF optimization, or due to the
  **       SortCtx.pDeferredRowLoad optimiation.  In any of these cases
  **       regOrigData is 0 to prevent this routine from trying to copy
@@ -137987,6 +139720,10 @@ static void pushOntoSorter(
  */
  assert( nData==1 || regData==regOrigData || regOrigData==0 );

+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
  pSort->addrPush = sqlite3VdbeCurrentAddr(v);
+
#endif
+

  if( nPrefixReg ){
    assert( nPrefixReg==nExpr+bSeq );
    regBase = regData - nPrefixReg;
@@ -138087,6 +139824,9 @@ static void pushOntoSorter(
    sqlite3VdbeChangeP2(v, iSkip,
         pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v));
  }
+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
  pSort->addrPushEnd = sqlite3VdbeCurrentAddr(v)-1;
+
#endif
}

/*
@@ -138553,9 +140293,6 @@ static void selectInnerLoop(
      testcase( eDest==SRT_Fifo );
      testcase( eDest==SRT_DistFifo );
      sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
-
      if( pDest->zAffSdst ){
-
        sqlite3VdbeChangeP4(v, -1, pDest->zAffSdst, nResultCol);
-
      }
#ifndef SQLITE_OMIT_CTE
      if( eDest==SRT_DistFifo ){
        /* If the destination is DistFifo, then cursor (iParm+1) is open
@@ -138913,6 +140650,16 @@ static void generateSortTail(
  int bSeq;                       /* True if sorter record includes seq. no. */
  int nRefKey = 0;
  struct ExprList_item *aOutEx = p->pEList->a;
+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
  int addrExplain;                /* Address of OP_Explain instruction */
+
#endif
+

+
  ExplainQueryPlan2(addrExplain, (pParse, 0,
+
        "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat>0?"RIGHT PART OF ":"")
+
  );
+
  sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd);
+
  sqlite3VdbeScanStatusCounters(v, addrExplain, addrExplain, pSort->addrPush);
+


  assert( addrBreak<0 );
  if( pSort->labelBkOut ){
@@ -139025,6 +140772,7 @@ static void generateSortTail(
      VdbeComment((v, "%s", aOutEx[i].zEName));
    }
  }
+
  sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1);
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
@@ -139086,6 +140834,7 @@ static void generateSortTail(
  }else{
    sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v);
  }
+
  sqlite3VdbeScanStatusRange(v, addrExplain, sqlite3VdbeCurrentAddr(v)-1, -1);
  if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn);
  sqlite3VdbeResolveLabel(v, addrBreak);
}
@@ -139357,7 +141106,7 @@ SQLITE_PRIVATE void sqlite3GenerateColumnNames(
  if( pParse->colNamesSet ) return;
  /* Column names are determined by the left-most term of a compound select */
  while( pSelect->pPrior ) pSelect = pSelect->pPrior;
-
  SELECTTRACE(1,pParse,pSelect,("generating column names\n"));
+
  TREETRACE(0x80,pParse,pSelect,("generating column names\n"));
  pTabList = pSelect->pSrc;
  pEList = pSelect->pEList;
  assert( v!=0 );
@@ -139457,7 +141206,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
  *pnCol = nCol;
  *paCol = aCol;

-
  for(i=0, pCol=aCol; i<nCol && !db->mallocFailed; i++, pCol++){
+
  for(i=0, pCol=aCol; i<nCol && !pParse->nErr; i++, pCol++){
    struct ExprList_item *pX = &pEList->a[i];
    struct ExprList_item *pCollide;
    /* Get an appropriate name for the column
@@ -139507,7 +141256,10 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
        if( zName[j]==':' ) nName = j;
      }
      zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt);
-
      if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt);
+
      sqlite3ProgressCheck(pParse);
+
      if( cnt>3 ){
+
        sqlite3_randomness(sizeof(cnt), &cnt);
+
      }
    }
    pCol->zCnName = zName;
    pCol->hName = sqlite3StrIHash(zName);
@@ -139520,71 +141272,104 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList(
    }
  }
  sqlite3HashClear(&ht);
-
  if( db->mallocFailed ){
+
  if( pParse->nErr ){
    for(j=0; j<i; j++){
      sqlite3DbFree(db, aCol[j].zCnName);
    }
    sqlite3DbFree(db, aCol);
    *paCol = 0;
    *pnCol = 0;
-
    return SQLITE_NOMEM_BKPT;
+
    return pParse->rc;
  }
  return SQLITE_OK;
}

/*
-
** Add type and collation information to a column list based on
-
** a SELECT statement.
+
** pTab is a transient Table object that represents a subquery of some
+
** kind (maybe a parenthesized subquery in the FROM clause of a larger
+
** query, or a VIEW, or a CTE).  This routine computes type information
+
** for that Table object based on the Select object that implements the
+
** subquery.  For the purposes of this routine, "type infomation" means:
**
-
** The column list presumably came from selectColumnNamesFromExprList().
-
** The column list has only names, not types or collations.  This
-
** routine goes through and adds the types and collations.
-
**
-
** This routine requires that all identifiers in the SELECT
-
** statement be resolved.
+
**    *   The datatype name, as it might appear in a CREATE TABLE statement
+
**    *   Which collating sequence to use for the column
+
**    *   The affinity of the column
*/
-
SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(
-
  Parse *pParse,        /* Parsing contexts */
-
  Table *pTab,          /* Add column type information to this table */
-
  Select *pSelect,      /* SELECT used to determine types and collations */
-
  char aff              /* Default affinity for columns */
+
SQLITE_PRIVATE void sqlite3SubqueryColumnTypes(
+
  Parse *pParse,      /* Parsing contexts */
+
  Table *pTab,        /* Add column type information to this table */
+
  Select *pSelect,    /* SELECT used to determine types and collations */
+
  char aff            /* Default affinity. */
){
  sqlite3 *db = pParse->db;
-
  NameContext sNC;
  Column *pCol;
  CollSeq *pColl;
-
  int i;
+
  int i,j;
  Expr *p;
  struct ExprList_item *a;
+
  NameContext sNC;

  assert( pSelect!=0 );
  assert( (pSelect->selFlags & SF_Resolved)!=0 );
-
  assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
-
  if( db->mallocFailed ) return;
+
  assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 );
+
  assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB );
+
  if( db->mallocFailed || IN_RENAME_OBJECT ) return;
+
  while( pSelect->pPrior ) pSelect = pSelect->pPrior;
+
  a = pSelect->pEList->a;
  memset(&sNC, 0, sizeof(sNC));
  sNC.pSrcList = pSelect->pSrc;
-
  a = pSelect->pEList->a;
  for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
    const char *zType;
-
    i64 n, m;
+
    i64 n;
    pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT);
    p = a[i].pExpr;
-
    zType = columnType(&sNC, p, 0, 0, 0);
    /* pCol->szEst = ... // Column size est for SELECT tables never used */
    pCol->affinity = sqlite3ExprAffinity(p);
+
    if( pCol->affinity<=SQLITE_AFF_NONE ){
+
      pCol->affinity = aff;
+
    }
+
    if( pCol->affinity>=SQLITE_AFF_TEXT && pSelect->pNext ){
+
      int m = 0;
+
      Select *pS2;
+
      for(m=0, pS2=pSelect->pNext; pS2; pS2=pS2->pNext){
+
        m |= sqlite3ExprDataType(pS2->pEList->a[i].pExpr);
+
      }
+
      if( pCol->affinity==SQLITE_AFF_TEXT && (m&0x01)!=0 ){
+
        pCol->affinity = SQLITE_AFF_BLOB;
+
      }else
+
      if( pCol->affinity>=SQLITE_AFF_NUMERIC && (m&0x02)!=0 ){
+
        pCol->affinity = SQLITE_AFF_BLOB;
+
      }
+
      if( pCol->affinity>=SQLITE_AFF_NUMERIC && p->op==TK_CAST ){
+
        pCol->affinity = SQLITE_AFF_FLEXNUM;
+
      }
+
    }
+
    zType = columnType(&sNC, p, 0, 0, 0);
+
    if( zType==0 || pCol->affinity!=sqlite3AffinityType(zType, 0) ){
+
      if( pCol->affinity==SQLITE_AFF_NUMERIC
+
       || pCol->affinity==SQLITE_AFF_FLEXNUM
+
      ){
+
        zType = "NUM";
+
      }else{
+
        zType = 0;
+
        for(j=1; j<SQLITE_N_STDTYPE; j++){
+
          if( sqlite3StdTypeAffinity[j]==pCol->affinity ){
+
            zType = sqlite3StdType[j];
+
            break;
+
          }
+
        }
+
      }
+
    }
    if( zType ){
-
      m = sqlite3Strlen30(zType);
+
      i64 m = sqlite3Strlen30(zType);
      n = sqlite3Strlen30(pCol->zCnName);
      pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
+
      pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
      if( pCol->zCnName ){
        memcpy(&pCol->zCnName[n+1], zType, m+1);
        pCol->colFlags |= COLFLAG_HASTYPE;
-
      }else{
-
        testcase( pCol->colFlags & COLFLAG_HASTYPE );
-
        pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
      }
    }
-
    if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
    pColl = sqlite3ExprCollSeq(pParse, p);
    if( pColl ){
      assert( pTab->pIndex==0 );
@@ -139618,7 +141403,7 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, c
  pTab->zName = 0;
  pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
  sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol);
-
  sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff);
+
  sqlite3SubqueryColumnTypes(pParse, pTab, pSelect, aff);
  pTab->iPKey = -1;
  if( db->mallocFailed ){
    sqlite3DeleteTable(db, pTab);
@@ -140143,7 +141928,7 @@ static int multiSelect(
        pPrior->iLimit = p->iLimit;
        pPrior->iOffset = p->iOffset;
        pPrior->pLimit = p->pLimit;
-
        SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL left...\n"));
+
        TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL left...\n"));
        rc = sqlite3Select(pParse, pPrior, &dest);
        pPrior->pLimit = 0;
        if( rc ){
@@ -140161,7 +141946,7 @@ static int multiSelect(
          }
        }
        ExplainQueryPlan((pParse, 1, "UNION ALL"));
-
        SELECTTRACE(1, pParse, p, ("multiSelect UNION ALL right...\n"));
+
        TREETRACE(0x200, pParse, p, ("multiSelect UNION ALL right...\n"));
        rc = sqlite3Select(pParse, p, &dest);
        testcase( rc!=SQLITE_OK );
        pDelete = p->pPrior;
@@ -140214,7 +141999,7 @@ static int multiSelect(
        */
        assert( !pPrior->pOrderBy );
        sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
-
        SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION left...\n"));
+
        TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION left...\n"));
        rc = sqlite3Select(pParse, pPrior, &uniondest);
        if( rc ){
          goto multi_select_end;
@@ -140234,7 +142019,7 @@ static int multiSelect(
        uniondest.eDest = op;
        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
                          sqlite3SelectOpName(p->op)));
-
        SELECTTRACE(1, pParse, p, ("multiSelect EXCEPT/UNION right...\n"));
+
        TREETRACE(0x200, pParse, p, ("multiSelect EXCEPT/UNION right...\n"));
        rc = sqlite3Select(pParse, p, &uniondest);
        testcase( rc!=SQLITE_OK );
        assert( p->pOrderBy==0 );
@@ -140295,7 +142080,7 @@ static int multiSelect(
        /* Code the SELECTs to our left into temporary table "tab1".
        */
        sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
-
        SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT left...\n"));
+
        TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT left...\n"));
        rc = sqlite3Select(pParse, pPrior, &intersectdest);
        if( rc ){
          goto multi_select_end;
@@ -140312,7 +142097,7 @@ static int multiSelect(
        intersectdest.iSDParm = tab2;
        ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE",
                          sqlite3SelectOpName(p->op)));
-
        SELECTTRACE(1, pParse, p, ("multiSelect INTERSECT right...\n"));
+
        TREETRACE(0x400, pParse, p, ("multiSelect INTERSECT right...\n"));
        rc = sqlite3Select(pParse, p, &intersectdest);
        testcase( rc!=SQLITE_OK );
        pDelete = p->pPrior;
@@ -141070,7 +142855,9 @@ static Expr *substExpr(
        sqlite3VectorErrorMsg(pSubst->pParse, pCopy);
      }else{
        sqlite3 *db = pSubst->pParse->db;
-
        if( pSubst->isOuterJoin && pCopy->op!=TK_COLUMN ){
+
        if( pSubst->isOuterJoin
+
         && (pCopy->op!=TK_COLUMN || pCopy->iTable!=pSubst->iNewTable)
+
        ){
          memset(&ifNullRow, 0, sizeof(ifNullRow));
          ifNullRow.op = TK_IF_NULL_ROW;
          ifNullRow.pLeft = pCopy;
@@ -141316,6 +143103,34 @@ static ExprList *findLeftmostExprlist(Select *pSel){
  return pSel->pEList;
}

+
/*
+
** Return true if any of the result-set columns in the compound query
+
** have incompatible affinities on one or more arms of the compound.
+
*/
+
static int compoundHasDifferentAffinities(Select *p){
+
  int ii;
+
  ExprList *pList;
+
  assert( p!=0 );
+
  assert( p->pEList!=0 );
+
  assert( p->pPrior!=0 );
+
  pList = p->pEList;
+
  for(ii=0; ii<pList->nExpr; ii++){
+
    char aff;
+
    Select *pSub1;
+
    assert( pList->a[ii].pExpr!=0 );
+
    aff = sqlite3ExprAffinity(pList->a[ii].pExpr);
+
    for(pSub1=p->pPrior; pSub1; pSub1=pSub1->pPrior){
+
      assert( pSub1->pEList!=0 );
+
      assert( pSub1->pEList->nExpr>ii );
+
      assert( pSub1->pEList->a[ii].pExpr!=0 );
+
      if( sqlite3ExprAffinity(pSub1->pEList->a[ii].pExpr)!=aff ){
+
        return 1;
+
      }
+
    }
+
  }
+
  return 0;
+
}
+

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/*
** This routine attempts to flatten subqueries as a performance optimization.
@@ -141638,19 +143453,7 @@ static int flattenSubquery(
    if( (p->selFlags & SF_Recursive) ) return 0;

    /* Restriction (17h) */
-
    for(ii=0; ii<pSub->pEList->nExpr; ii++){
-
      char aff;
-
      assert( pSub->pEList->a[ii].pExpr!=0 );
-
      aff = sqlite3ExprAffinity(pSub->pEList->a[ii].pExpr);
-
      for(pSub1=pSub->pPrior; pSub1; pSub1=pSub1->pPrior){
-
        assert( pSub1->pEList!=0 );
-
        assert( pSub1->pEList->nExpr>ii );
-
        assert( pSub1->pEList->a[ii].pExpr!=0 );
-
        if( sqlite3ExprAffinity(pSub1->pEList->a[ii].pExpr)!=aff ){
-
          return 0;
-
        }
-
      }
-
    }
+
    if( compoundHasDifferentAffinities(pSub) ) return 0;

    if( pSrc->nSrc>1 ){
      if( pParse->nSelect>500 ) return 0;
@@ -141661,7 +143464,7 @@ static int flattenSubquery(
  }

  /***** If we reach this point, flattening is permitted. *****/
-
  SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n",
+
  TREETRACE(0x4,pParse,p,("flatten %u.%p from term %d\n",
                   pSub->selId, pSub, iFrom));

  /* Authorize the subquery */
@@ -141740,7 +143543,7 @@ static int flattenSubquery(
      if( pPrior ) pPrior->pNext = pNew;
      pNew->pNext = p;
      p->pPrior = pNew;
-
      SELECTTRACE(2,pParse,p,("compound-subquery flattener"
+
      TREETRACE(0x4,pParse,p,("compound-subquery flattener"
                              " creates %u as peer\n",pNew->selId));
    }
    assert( pSubitem->pSelect==0 );
@@ -141920,8 +143723,8 @@ static int flattenSubquery(
  sqlite3SelectDelete(db, pSub1);

#if TREETRACE_ENABLED
-
  if( sqlite3TreeTrace & 0x100 ){
-
    SELECTTRACE(0x100,pParse,p,("After flattening:\n"));
+
  if( sqlite3TreeTrace & 0x4 ){
+
    TREETRACE(0x4,pParse,p,("After flattening:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
@@ -142295,12 +144098,28 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){
**       be materialized.  (This restriction is implemented in the calling
**       routine.)
**
-
**   (8) The subquery may not be a compound that uses UNION, INTERSECT,
-
**       or EXCEPT.  (We could, perhaps, relax this restriction to allow
-
**       this case if none of the comparisons operators between left and
-
**       right arms of the compound use a collation other than BINARY.
-
**       But it is a lot of work to check that case for an obscure and
-
**       minor optimization, so we omit it for now.)
+
**   (8) If the subquery is a compound that uses UNION, INTERSECT,
+
**       or EXCEPT, then all of the result set columns for all arms of
+
**       the compound must use the BINARY collating sequence.
+
**
+
**   (9) All three of the following are true:
+
**
+
**       (9a) The WHERE clause expression originates in the ON or USING clause
+
**            of a join (either an INNER or an OUTER join), and
+
**
+
**       (9b) The subquery is to the right of the ON/USING clause
+
**
+
**       (9c) There is a RIGHT JOIN (or FULL JOIN) in between the ON/USING
+
**            clause and the subquery.
+
**
+
**       Without this restriction, the push-down optimization might move
+
**       the ON/USING filter expression from the left side of a RIGHT JOIN
+
**       over to the right side, which leads to incorrect answers.  See
+
**       also restriction (6) in sqlite3ExprIsSingleTableConstraint().
+
**
+
**  (10) The inner query is not the right-hand table of a RIGHT JOIN.
+
**
+
**  (11) The subquery is not a VALUES clause
**
** Return 0 if no changes are made and non-zero if one or more WHERE clause
** terms are duplicated into the subquery.
@@ -142309,28 +144128,56 @@ static int pushDownWhereTerms(
  Parse *pParse,        /* Parse context (for malloc() and error reporting) */
  Select *pSubq,        /* The subquery whose WHERE clause is to be augmented */
  Expr *pWhere,         /* The WHERE clause of the outer query */
-
  SrcItem *pSrc         /* The subquery term of the outer FROM clause */
+
  SrcList *pSrcList,    /* The complete from clause of the outer query */
+
  int iSrc              /* Which FROM clause term to try to push into  */
){
  Expr *pNew;
+
  SrcItem *pSrc;        /* The subquery FROM term into which WHERE is pushed */
  int nChng = 0;
+
  pSrc = &pSrcList->a[iSrc];
  if( pWhere==0 ) return 0;
-
  if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0;
-
  if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ) return 0;
+
  if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ){
+
    return 0;           /* restrictions (2) and (11) */
+
  }
+
  if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ){
+
    return 0;           /* restrictions (10) */
+
  }

-
#ifndef SQLITE_OMIT_WINDOWFUNC
  if( pSubq->pPrior ){
    Select *pSel;
+
    int notUnionAll = 0;
    for(pSel=pSubq; pSel; pSel=pSel->pPrior){
      u8 op = pSel->op;
      assert( op==TK_ALL || op==TK_SELECT
           || op==TK_UNION || op==TK_INTERSECT || op==TK_EXCEPT );
-
      if( op!=TK_ALL && op!=TK_SELECT ) return 0;  /* restriction (8) */
+
      if( op!=TK_ALL && op!=TK_SELECT ){
+
        notUnionAll = 1;
+
      }
+
#ifndef SQLITE_OMIT_WINDOWFUNC
      if( pSel->pWin ) return 0;    /* restriction (6b) */
+
#endif
+
    }
+
    if( notUnionAll ){
+
      /* If any of the compound arms are connected using UNION, INTERSECT,
+
      ** or EXCEPT, then we must ensure that none of the columns use a
+
      ** non-BINARY collating sequence. */
+
      for(pSel=pSubq; pSel; pSel=pSel->pPrior){
+
        int ii;
+
        const ExprList *pList = pSel->pEList;
+
        assert( pList!=0 );
+
        for(ii=0; ii<pList->nExpr; ii++){
+
          CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[ii].pExpr);
+
          if( !sqlite3IsBinary(pColl) ){
+
            return 0;  /* Restriction (8) */
+
          }
+
        }
+
      }
    }
  }else{
+
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0;
-
  }
#endif
+
  }

#ifdef SQLITE_DEBUG
  /* Only the first term of a compound can have a WITH clause.  But make
@@ -142349,11 +144196,28 @@ static int pushDownWhereTerms(
    return 0; /* restriction (3) */
  }
  while( pWhere->op==TK_AND ){
-
    nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrc);
+
    nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrcList, iSrc);
    pWhere = pWhere->pLeft;
  }

-
#if 0  /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */
+
#if 0 /* These checks now done by sqlite3ExprIsSingleTableConstraint() */
+
  if( ExprHasProperty(pWhere, EP_OuterON|EP_InnerON) /* (9a) */
+
   && (pSrcList->a[0].fg.jointype & JT_LTORJ)!=0     /* Fast pre-test of (9c) */
+
  ){
+
    int jj;
+
    for(jj=0; jj<iSrc; jj++){
+
      if( pWhere->w.iJoin==pSrcList->a[jj].iCursor ){
+
        /* If we reach this point, both (9a) and (9b) are satisfied.
+
        ** The following loop checks (9c):
+
        */
+
        for(jj++; jj<iSrc; jj++){
+
          if( (pSrcList->a[jj].fg.jointype & JT_RIGHT)!=0 ){
+
            return 0;  /* restriction (9) */
+
          }
+
        }
+
      }
+
    }
+
  }
  if( isLeftJoin
   && (ExprHasProperty(pWhere,EP_OuterON)==0
         || pWhere->w.iJoin!=iCursor)
@@ -142367,7 +144231,7 @@ static int pushDownWhereTerms(
  }
#endif

-
  if( sqlite3ExprIsTableConstraint(pWhere, pSrc) ){
+
  if( sqlite3ExprIsSingleTableConstraint(pWhere, pSrcList, iSrc) ){
    nChng++;
    pSubq->selFlags |= SF_PushDown;
    while( pSubq ){
@@ -142402,6 +144266,78 @@ static int pushDownWhereTerms(
#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */

/*
+
** Check to see if a subquery contains result-set columns that are
+
** never used.  If it does, change the value of those result-set columns
+
** to NULL so that they do not cause unnecessary work to compute.
+
**
+
** Return the number of column that were changed to NULL.
+
*/
+
static int disableUnusedSubqueryResultColumns(SrcItem *pItem){
+
  int nCol;
+
  Select *pSub;      /* The subquery to be simplified */
+
  Select *pX;        /* For looping over compound elements of pSub */
+
  Table *pTab;       /* The table that describes the subquery */
+
  int j;             /* Column number */
+
  int nChng = 0;     /* Number of columns converted to NULL */
+
  Bitmask colUsed;   /* Columns that may not be NULLed out */
+

+
  assert( pItem!=0 );
+
  if( pItem->fg.isCorrelated || pItem->fg.isCte ){
+
    return 0;
+
  }
+
  assert( pItem->pTab!=0 );
+
  pTab = pItem->pTab;
+
  assert( pItem->pSelect!=0 );
+
  pSub = pItem->pSelect;
+
  assert( pSub->pEList->nExpr==pTab->nCol );
+
  if( (pSub->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){
+
    testcase( pSub->selFlags & SF_Distinct );
+
    testcase( pSub->selFlags & SF_Aggregate );
+
    return 0;
+
  }
+
  for(pX=pSub; pX; pX=pX->pPrior){
+
    if( pX->pPrior && pX->op!=TK_ALL ){
+
      /* This optimization does not work for compound subqueries that
+
      ** use UNION, INTERSECT, or EXCEPT.  Only UNION ALL is allowed. */
+
      return 0;
+
    }
+
#ifndef SQLITE_OMIT_WINDOWFUNC
+
    if( pX->pWin ){
+
      /* This optimization does not work for subqueries that use window
+
      ** functions. */
+
      return 0;
+
    }
+
#endif
+
  }
+
  colUsed = pItem->colUsed;
+
  if( pSub->pOrderBy ){
+
    ExprList *pList = pSub->pOrderBy;
+
    for(j=0; j<pList->nExpr; j++){
+
      u16 iCol = pList->a[j].u.x.iOrderByCol;
+
      if( iCol>0 ){
+
        iCol--;
+
        colUsed |= ((Bitmask)1)<<(iCol>=BMS ? BMS-1 : iCol);
+
      }
+
    }
+
  }
+
  nCol = pTab->nCol;
+
  for(j=0; j<nCol; j++){
+
    Bitmask m = j<BMS-1 ? MASKBIT(j) : TOPBIT;
+
    if( (m & colUsed)!=0 ) continue;
+
    for(pX=pSub; pX; pX=pX->pPrior) {
+
      Expr *pY = pX->pEList->a[j].pExpr;
+
      if( pY->op==TK_NULL ) continue;
+
      pY->op = TK_NULL;
+
      ExprClearProperty(pY, EP_Skip|EP_Unlikely);
+
      pX->selFlags |= SF_PushDown;
+
      nChng++;
+
    }
+
  }
+
  return nChng;
+
}
+

+

+
/*
** The pFunc is the only aggregate function in the query.  Check to see
** if the query is a candidate for the min/max optimization.
**
@@ -142792,9 +144728,6 @@ static int resolveFromTermToCte(
    pFrom->fg.isCte = 1;
    pFrom->u2.pCteUse = pCteUse;
    pCteUse->nUse++;
-
    if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){
-
      pCteUse->eM10d = M10d_Yes;
-
    }

    /* Check if this is a recursive CTE. */
    pRecTerm = pSel = pFrom->pSelect;
@@ -143334,8 +145267,8 @@ static int selectExpander(Walker *pWalker, Select *p){
    }
  }
#if TREETRACE_ENABLED
-
  if( sqlite3TreeTrace & 0x100 ){
-
    SELECTTRACE(0x100,pParse,p,("After result-set wildcard expansion:\n"));
+
  if( sqlite3TreeTrace & 0x8 ){
+
    TREETRACE(0x8,pParse,p,("After result-set wildcard expansion:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
@@ -143386,14 +145319,14 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo()
** interface.
**
-
** For each FROM-clause subquery, add Column.zType and Column.zColl
-
** information to the Table structure that represents the result set
-
** of that subquery.
+
** For each FROM-clause subquery, add Column.zType, Column.zColl, and
+
** Column.affinity information to the Table structure that represents
+
** the result set of that subquery.
**
** The Table structure that represents the result set was constructed
-
** by selectExpander() but the type and collation information was omitted
-
** at that point because identifiers had not yet been resolved.  This
-
** routine is called after identifier resolution.
+
** by selectExpander() but the type and collation and affinity information
+
** was omitted at that point because identifiers had not yet been resolved.
+
** This routine is called after identifier resolution.
*/
static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
  Parse *pParse;
@@ -143413,9 +145346,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
      /* A sub-query in the FROM clause of a SELECT */
      Select *pSel = pFrom->pSelect;
      if( pSel ){
-
        while( pSel->pPrior ) pSel = pSel->pPrior;
-
        sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel,
-
                                               SQLITE_AFF_NONE);
+
        sqlite3SubqueryColumnTypes(pParse, pTab, pSel, SQLITE_AFF_NONE);
      }
    }
  }
@@ -143470,6 +145401,178 @@ SQLITE_PRIVATE void sqlite3SelectPrep(
  sqlite3SelectAddTypeInfo(pParse, p);
}

+
#if TREETRACE_ENABLED
+
/*
+
** Display all information about an AggInfo object
+
*/
+
static void printAggInfo(AggInfo *pAggInfo){
+
  int ii;
+
  for(ii=0; ii<pAggInfo->nColumn; ii++){
+
    struct AggInfo_col *pCol = &pAggInfo->aCol[ii];
+
    sqlite3DebugPrintf(
+
       "agg-column[%d] pTab=%s iTable=%d iColumn=%d iMem=%d"
+
       " iSorterColumn=%d %s\n",
+
       ii, pCol->pTab ? pCol->pTab->zName : "NULL",
+
       pCol->iTable, pCol->iColumn, pAggInfo->iFirstReg+ii,
+
       pCol->iSorterColumn,
+
       ii>=pAggInfo->nAccumulator ? "" : " Accumulator");
+
    sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0);
+
  }
+
  for(ii=0; ii<pAggInfo->nFunc; ii++){
+
    sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
+
        ii, pAggInfo->iFirstReg+pAggInfo->nColumn+ii);
+
    sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0);
+
  }
+
}
+
#endif /* TREETRACE_ENABLED */
+

+
/*
+
** Analyze the arguments to aggregate functions.  Create new pAggInfo->aCol[]
+
** entries for columns that are arguments to aggregate functions but which
+
** are not otherwise used.
+
**
+
** The aCol[] entries in AggInfo prior to nAccumulator are columns that
+
** are referenced outside of aggregate functions.  These might be columns
+
** that are part of the GROUP by clause, for example.  Other database engines
+
** would throw an error if there is a column reference that is not in the
+
** GROUP BY clause and that is not part of an aggregate function argument.
+
** But SQLite allows this.
+
**
+
** The aCol[] entries beginning with the aCol[nAccumulator] and following
+
** are column references that are used exclusively as arguments to
+
** aggregate functions.  This routine is responsible for computing
+
** (or recomputing) those aCol[] entries.
+
*/
+
static void analyzeAggFuncArgs(
+
  AggInfo *pAggInfo,
+
  NameContext *pNC
+
){
+
  int i;
+
  assert( pAggInfo!=0 );
+
  assert( pAggInfo->iFirstReg==0 );
+
  pNC->ncFlags |= NC_InAggFunc;
+
  for(i=0; i<pAggInfo->nFunc; i++){
+
    Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
+
    assert( ExprUseXList(pExpr) );
+
    sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList);
+
#ifndef SQLITE_OMIT_WINDOWFUNC
+
    assert( !IsWindowFunc(pExpr) );
+
    if( ExprHasProperty(pExpr, EP_WinFunc) ){
+
      sqlite3ExprAnalyzeAggregates(pNC, pExpr->y.pWin->pFilter);
+
    }
+
#endif
+
  }
+
  pNC->ncFlags &= ~NC_InAggFunc;
+
}
+

+
/*
+
** An index on expressions is being used in the inner loop of an
+
** aggregate query with a GROUP BY clause.  This routine attempts
+
** to adjust the AggInfo object to take advantage of index and to
+
** perhaps use the index as a covering index.
+
**
+
*/
+
static void optimizeAggregateUseOfIndexedExpr(
+
  Parse *pParse,          /* Parsing context */
+
  Select *pSelect,        /* The SELECT statement being processed */
+
  AggInfo *pAggInfo,      /* The aggregate info */
+
  NameContext *pNC        /* Name context used to resolve agg-func args */
+
){
+
  assert( pAggInfo->iFirstReg==0 );
+
  assert( pSelect!=0 );
+
  assert( pSelect->pGroupBy!=0 );
+
  pAggInfo->nColumn = pAggInfo->nAccumulator;
+
  if( ALWAYS(pAggInfo->nSortingColumn>0) ){
+
    int mx = pSelect->pGroupBy->nExpr - 1;
+
    int j, k;
+
    for(j=0; j<pAggInfo->nColumn; j++){
+
      k = pAggInfo->aCol[j].iSorterColumn;
+
      if( k>mx ) mx = k;
+
    }
+
    pAggInfo->nSortingColumn = mx+1;
+
  }
+
  analyzeAggFuncArgs(pAggInfo, pNC);
+
#if TREETRACE_ENABLED
+
  if( sqlite3TreeTrace & 0x20 ){
+
    IndexedExpr *pIEpr;
+
    TREETRACE(0x20, pParse, pSelect,
+
        ("AggInfo (possibly) adjusted for Indexed Exprs\n"));
+
    sqlite3TreeViewSelect(0, pSelect, 0);
+
    for(pIEpr=pParse->pIdxEpr; pIEpr; pIEpr=pIEpr->pIENext){
+
      printf("data-cursor=%d index={%d,%d}\n",
+
          pIEpr->iDataCur, pIEpr->iIdxCur, pIEpr->iIdxCol);
+
      sqlite3TreeViewExpr(0, pIEpr->pExpr, 0);
+
    }
+
    printAggInfo(pAggInfo);
+
  }
+
#else
+
  UNUSED_PARAMETER(pSelect);
+
  UNUSED_PARAMETER(pParse);
+
#endif
+
}
+

+
/*
+
** Walker callback for aggregateConvertIndexedExprRefToColumn().
+
*/
+
static int aggregateIdxEprRefToColCallback(Walker *pWalker, Expr *pExpr){
+
  AggInfo *pAggInfo;
+
  struct AggInfo_col *pCol;
+
  UNUSED_PARAMETER(pWalker);
+
  if( pExpr->pAggInfo==0 ) return WRC_Continue;
+
  if( pExpr->op==TK_AGG_COLUMN ) return WRC_Continue;
+
  if( pExpr->op==TK_AGG_FUNCTION ) return WRC_Continue;
+
  if( pExpr->op==TK_IF_NULL_ROW ) return WRC_Continue;
+
  pAggInfo = pExpr->pAggInfo;
+
  if( NEVER(pExpr->iAgg>=pAggInfo->nColumn) ) return WRC_Continue;
+
  assert( pExpr->iAgg>=0 );
+
  pCol = &pAggInfo->aCol[pExpr->iAgg];
+
  pExpr->op = TK_AGG_COLUMN;
+
  pExpr->iTable = pCol->iTable;
+
  pExpr->iColumn = pCol->iColumn;
+
  ExprClearProperty(pExpr, EP_Skip|EP_Collate);
+
  return WRC_Prune;
+
}
+

+
/*
+
** Convert every pAggInfo->aFunc[].pExpr such that any node within
+
** those expressions that has pAppInfo set is changed into a TK_AGG_COLUMN
+
** opcode.
+
*/
+
static void aggregateConvertIndexedExprRefToColumn(AggInfo *pAggInfo){
+
  int i;
+
  Walker w;
+
  memset(&w, 0, sizeof(w));
+
  w.xExprCallback = aggregateIdxEprRefToColCallback;
+
  for(i=0; i<pAggInfo->nFunc; i++){
+
    sqlite3WalkExpr(&w, pAggInfo->aFunc[i].pFExpr);
+
  }
+
}
+

+

+
/*
+
** Allocate a block of registers so that there is one register for each
+
** pAggInfo->aCol[] and pAggInfo->aFunc[] entry in pAggInfo.  The first
+
** register in this block is stored in pAggInfo->iFirstReg.
+
**
+
** This routine may only be called once for each AggInfo object.  Prior
+
** to calling this routine:
+
**
+
**     *  The aCol[] and aFunc[] arrays may be modified
+
**     *  The AggInfoColumnReg() and AggInfoFuncReg() macros may not be used
+
**
+
** After clling this routine:
+
**
+
**     *  The aCol[] and aFunc[] arrays are fixed
+
**     *  The AggInfoColumnReg() and AggInfoFuncReg() macros may be used
+
**
+
*/
+
static void assignAggregateRegisters(Parse *pParse, AggInfo *pAggInfo){
+
  assert( pAggInfo!=0 );
+
  assert( pAggInfo->iFirstReg==0 );
+
  pAggInfo->iFirstReg = pParse->nMem + 1;
+
  pParse->nMem += pAggInfo->nColumn + pAggInfo->nFunc;
+
}
+

/*
** Reset the aggregate accumulator.
**
@@ -143483,24 +145586,13 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
  int i;
  struct AggInfo_func *pFunc;
  int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
+
  assert( pAggInfo->iFirstReg>0 );
  assert( pParse->db->pParse==pParse );
  assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 );
  if( nReg==0 ) return;
  if( pParse->nErr ) return;
-
#ifdef SQLITE_DEBUG
-
  /* Verify that all AggInfo registers are within the range specified by
-
  ** AggInfo.mnReg..AggInfo.mxReg */
-
  assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
-
  for(i=0; i<pAggInfo->nColumn; i++){
-
    assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg
-
         && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg );
-
  }
-
  for(i=0; i<pAggInfo->nFunc; i++){
-
    assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg
-
         && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg );
-
  }
-
#endif
-
  sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg);
+
  sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->iFirstReg,
+
                    pAggInfo->iFirstReg+nReg-1);
  for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
    if( pFunc->iDistinct>=0 ){
      Expr *pE = pFunc->pFExpr;
@@ -143532,15 +145624,16 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
    ExprList *pList;
    assert( ExprUseXList(pF->pFExpr) );
    pList = pF->pFExpr->x.pList;
-
    sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
+
    sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i),
+
                      pList ? pList->nExpr : 0);
    sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
  }
}


/*
-
** Update the accumulator memory cells for an aggregate based on
-
** the current cursor position.
+
** Generate code that will update the accumulator memory cells for an
+
** aggregate based on the current cursor position.
**
** If regAcc is non-zero and there are no min() or max() aggregates
** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator
@@ -143560,6 +145653,8 @@ static void updateAccumulator(
  struct AggInfo_func *pF;
  struct AggInfo_col *pC;

+
  assert( pAggInfo->iFirstReg>0 );
+
  if( pParse->nErr ) return;
  pAggInfo->directMode = 1;
  for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
    int nArg;
@@ -143620,7 +145715,7 @@ static void updateAccumulator(
      if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
      sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ);
    }
-
    sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem);
+
    sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
    sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
    sqlite3VdbeChangeP5(v, (u8)nArg);
    sqlite3ReleaseTempRange(pParse, regAgg, nArg);
@@ -143635,7 +145730,7 @@ static void updateAccumulator(
    addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
  }
  for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
-
    sqlite3ExprCode(pParse, pC->pCExpr, pC->iMem);
+
    sqlite3ExprCode(pParse, pC->pCExpr, AggInfoColumnReg(pAggInfo,i));
  }

  pAggInfo->directMode = 0;
@@ -143731,26 +145826,31 @@ static void havingToWhere(Parse *pParse, Select *p){
  sqlite3WalkExpr(&sWalker, p->pHaving);
#if TREETRACE_ENABLED
  if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){
-
    SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
+
    TREETRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
}

/*
-
** Check to see if the pThis entry of pTabList is a self-join of a prior view.
-
** If it is, then return the SrcItem for the prior view.  If it is not,
-
** then return 0.
+
** Check to see if the pThis entry of pTabList is a self-join of another view.
+
** Search FROM-clause entries in the range of iFirst..iEnd, including iFirst
+
** but stopping before iEnd.
+
**
+
** If pThis is a self-join, then return the SrcItem for the first other
+
** instance of that view found.  If pThis is not a self-join then return 0.
*/
static SrcItem *isSelfJoinView(
  SrcList *pTabList,           /* Search for self-joins in this FROM clause */
-
  SrcItem *pThis               /* Search for prior reference to this subquery */
+
  SrcItem *pThis,              /* Search for prior reference to this subquery */
+
  int iFirst, int iEnd        /* Range of FROM-clause entries to search. */
){
  SrcItem *pItem;
  assert( pThis->pSelect!=0 );
  if( pThis->pSelect->selFlags & SF_PushDown ) return 0;
-
  for(pItem = pTabList->a; pItem<pThis; pItem++){
+
  while( iFirst<iEnd ){
    Select *pS1;
+
    pItem = &pTabList->a[iFirst++];
    if( pItem->pSelect==0 ) continue;
    if( pItem->fg.viaCoroutine ) continue;
    if( pItem->zName==0 ) continue;
@@ -143783,7 +145883,6 @@ static void agginfoFree(sqlite3 *db, AggInfo *p){
  sqlite3DbFreeNN(db, p);
}

-
#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
/*
** Attempt to transform a query of the form
**
@@ -143811,7 +145910,9 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
  if( (p->selFlags & SF_Aggregate)==0 ) return 0;   /* This is an aggregate */
  if( p->pEList->nExpr!=1 ) return 0;               /* Single result column */
  if( p->pWhere ) return 0;
+
  if( p->pHaving ) return 0;
  if( p->pGroupBy ) return 0;
+
  if( p->pOrderBy ) return 0;
  pExpr = p->pEList->a[0].pExpr;
  if( pExpr->op!=TK_AGG_FUNCTION ) return 0;        /* Result is an aggregate */
  assert( ExprUseUToken(pExpr) );
@@ -143819,15 +145920,18 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
  assert( ExprUseXList(pExpr) );
  if( pExpr->x.pList!=0 ) return 0;                 /* Must be count(*) */
  if( p->pSrc->nSrc!=1 ) return 0;                  /* One table in FROM  */
+
  if( ExprHasProperty(pExpr, EP_WinFunc) ) return 0;/* Not a window function */
  pSub = p->pSrc->a[0].pSelect;
  if( pSub==0 ) return 0;                           /* The FROM is a subquery */
-
  if( pSub->pPrior==0 ) return 0;                   /* Must be a compound ry */
+
  if( pSub->pPrior==0 ) return 0;                   /* Must be a compound */
+
  if( pSub->selFlags & SF_CopyCte ) return 0;       /* Not a CTE */
  do{
    if( pSub->op!=TK_ALL && pSub->pPrior ) return 0;  /* Must be UNION ALL */
    if( pSub->pWhere ) return 0;                      /* No WHERE clause */
    if( pSub->pLimit ) return 0;                      /* No LIMIT clause */
    if( pSub->selFlags & SF_Aggregate ) return 0;     /* Not an aggregate */
-
    pSub = pSub->pPrior;                              /* Repeat over compound */
+
    assert( pSub->pHaving==0 );  /* Due to the previous */
+
   pSub = pSub->pPrior;                              /* Repeat over compound */
  }while( pSub );

  /* If we reach this point then it is OK to perform the transformation */
@@ -143863,14 +145967,13 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
  p->selFlags &= ~SF_Aggregate;

#if TREETRACE_ENABLED
-
  if( sqlite3TreeTrace & 0x400 ){
-
    SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n"));
+
  if( sqlite3TreeTrace & 0x200 ){
+
    TREETRACE(0x200,pParse,p,("After count-of-view optimization:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
  return 1;
}
-
#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */

/*
** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same
@@ -143896,6 +145999,68 @@ static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
}

/*
+
** Return TRUE (non-zero) if the i-th entry in the pTabList SrcList can
+
** be implemented as a co-routine.  The i-th entry is guaranteed to be
+
** a subquery.
+
**
+
** The subquery is implemented as a co-routine if all of the following are
+
** true:
+
**
+
**    (1)  The subquery will likely be implemented in the outer loop of
+
**         the query.  This will be the case if any one of the following
+
**         conditions hold:
+
**         (a)  The subquery is the only term in the FROM clause
+
**         (b)  The subquery is the left-most term and a CROSS JOIN or similar
+
**              requires it to be the outer loop
+
**         (c)  All of the following are true:
+
**                (i) The subquery is the left-most subquery in the FROM clause
+
**               (ii) There is nothing that would prevent the subquery from
+
**                    being used as the outer loop if the sqlite3WhereBegin()
+
**                    routine nominates it to that position.
+
**              (iii) The query is not a UPDATE ... FROM
+
**    (2)  The subquery is not a CTE that should be materialized because
+
**         (a) the AS MATERIALIZED keyword is used, or
+
**         (b) the CTE is used multiple times and does not have the
+
**             NOT MATERIALIZED keyword
+
**    (3)  The subquery is not part of a left operand for a RIGHT JOIN
+
**    (4)  The SQLITE_Coroutine optimization disable flag is not set
+
**    (5)  The subquery is not self-joined
+
*/
+
static int fromClauseTermCanBeCoroutine(
+
  Parse *pParse,          /* Parsing context */
+
  SrcList *pTabList,      /* FROM clause */
+
  int i,                  /* Which term of the FROM clause holds the subquery */
+
  int selFlags            /* Flags on the SELECT statement */
+
){
+
  SrcItem *pItem = &pTabList->a[i];
+
  if( pItem->fg.isCte ){
+
    const CteUse *pCteUse = pItem->u2.pCteUse;
+
    if( pCteUse->eM10d==M10d_Yes ) return 0;                          /* (2a) */
+
    if( pCteUse->nUse>=2 && pCteUse->eM10d!=M10d_No ) return 0;       /* (2b) */
+
  }
+
  if( pTabList->a[0].fg.jointype & JT_LTORJ ) return 0;               /* (3)  */
+
  if( OptimizationDisabled(pParse->db, SQLITE_Coroutines) ) return 0; /* (4)  */
+
  if( isSelfJoinView(pTabList, pItem, i+1, pTabList->nSrc)!=0 ){
+
    return 0;                                                          /* (5) */
+
  }
+
  if( i==0 ){
+
    if( pTabList->nSrc==1 ) return 1;                             /* (1a) */
+
    if( pTabList->a[1].fg.jointype & JT_CROSS ) return 1;         /* (1b) */
+
    if( selFlags & SF_UpdateFrom )              return 0;         /* (1c-iii) */
+
    return 1;
+
  }
+
  if( selFlags & SF_UpdateFrom ) return 0;                        /* (1c-iii) */
+
  while( 1 /*exit-by-break*/ ){
+
    if( pItem->fg.jointype & (JT_OUTER|JT_CROSS)  ) return 0;     /* (1c-ii) */
+
    if( i==0 ) break;
+
    i--;
+
    pItem--;
+
    if( pItem->pSelect!=0 ) return 0;                             /* (1c-i) */
+
  }
+
  return 1;
+
}
+

+
/*
** Generate code for the SELECT statement given in the p argument.
**
** The results are returned according to the SelectDest structure.
@@ -143940,8 +146105,8 @@ SQLITE_PRIVATE int sqlite3Select(
  assert( db->mallocFailed==0 );
  if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
#if TREETRACE_ENABLED
-
  SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
-
  if( sqlite3TreeTrace & 0x10100 ){
+
  TREETRACE(0x1,pParse,p, ("begin processing:\n", pParse->addrExplain));
+
  if( sqlite3TreeTrace & 0x10000 ){
    if( (sqlite3TreeTrace & 0x10001)==0x10000 ){
      sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d",
                           __FILE__, __LINE__);
@@ -143961,8 +146126,8 @@ SQLITE_PRIVATE int sqlite3Select(
    /* All of these destinations are also able to ignore the ORDER BY clause */
    if( p->pOrderBy ){
#if TREETRACE_ENABLED
-
      SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n"));
-
      if( sqlite3TreeTrace & 0x100 ){
+
      TREETRACE(0x800,pParse,p, ("dropping superfluous ORDER BY:\n"));
+
      if( sqlite3TreeTrace & 0x800 ){
        sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY");
      }
#endif
@@ -143982,8 +146147,8 @@ SQLITE_PRIVATE int sqlite3Select(
  assert( db->mallocFailed==0 );
  assert( p->pEList!=0 );
#if TREETRACE_ENABLED
-
  if( sqlite3TreeTrace & 0x104 ){
-
    SELECTTRACE(0x104,pParse,p, ("after name resolution:\n"));
+
  if( sqlite3TreeTrace & 0x10 ){
+
    TREETRACE(0x10,pParse,p, ("after name resolution:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
@@ -144024,8 +146189,8 @@ SQLITE_PRIVATE int sqlite3Select(
    goto select_end;
  }
#if TREETRACE_ENABLED
-
  if( p->pWin && (sqlite3TreeTrace & 0x108)!=0 ){
-
    SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n"));
+
  if( p->pWin && (sqlite3TreeTrace & 0x40)!=0 ){
+
    TREETRACE(0x40,pParse,p, ("after window rewrite:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
@@ -144056,7 +146221,7 @@ SQLITE_PRIVATE int sqlite3Select(
     && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
     && OptimizationEnabled(db, SQLITE_SimplifyJoin)
    ){
-
      SELECTTRACE(0x100,pParse,p,
+
      TREETRACE(0x1000,pParse,p,
                ("LEFT-JOIN simplifies to JOIN on term %d\n",i));
      pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
      assert( pItem->iCursor>=0 );
@@ -144064,7 +146229,7 @@ SQLITE_PRIVATE int sqlite3Select(
                    pTabList->a[0].fg.jointype & JT_LTORJ);
    }

-
    /* No futher action if this term of the FROM clause is no a subquery */
+
    /* No futher action if this term of the FROM clause is not a subquery */
    if( pSub==0 ) continue;

    /* Catch mismatch in the declared columns of a view and the number of
@@ -144112,7 +146277,7 @@ SQLITE_PRIVATE int sqlite3Select(
     && (p->selFlags & SF_OrderByReqd)==0         /* Condition (3) and (4) */
     && OptimizationEnabled(db, SQLITE_OmitOrderBy)
    ){
-
      SELECTTRACE(0x100,pParse,p,
+
      TREETRACE(0x800,pParse,p,
                ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1));
      sqlite3ParserAddCleanup(pParse,
         (void(*)(sqlite3*,void*))sqlite3ExprListDelete,
@@ -144167,8 +146332,8 @@ SQLITE_PRIVATE int sqlite3Select(
  if( p->pPrior ){
    rc = multiSelect(pParse, p, pDest);
#if TREETRACE_ENABLED
-
    SELECTTRACE(0x1,pParse,p,("end compound-select processing\n"));
-
    if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
+
    TREETRACE(0x400,pParse,p,("end compound-select processing\n"));
+
    if( (sqlite3TreeTrace & 0x400)!=0 && ExplainQueryPlanParent(pParse)==0 ){
      sqlite3TreeViewSelect(0, p, 0);
    }
#endif
@@ -144188,24 +146353,21 @@ SQLITE_PRIVATE int sqlite3Select(
   && propagateConstants(pParse, p)
  ){
#if TREETRACE_ENABLED
-
    if( sqlite3TreeTrace & 0x100 ){
-
      SELECTTRACE(0x100,pParse,p,("After constant propagation:\n"));
+
    if( sqlite3TreeTrace & 0x2000 ){
+
      TREETRACE(0x2000,pParse,p,("After constant propagation:\n"));
      sqlite3TreeViewSelect(0, p, 0);
    }
#endif
  }else{
-
    SELECTTRACE(0x100,pParse,p,("Constant propagation not helpful\n"));
+
    TREETRACE(0x2000,pParse,p,("Constant propagation not helpful\n"));
  }

-
#ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION
  if( OptimizationEnabled(db, SQLITE_QueryFlattener|SQLITE_CountOfView)
   && countOfViewOptimization(pParse, p)
  ){
    if( db->mallocFailed ) goto select_end;
-
    pEList = p->pEList;
    pTabList = p->pSrc;
  }
-
#endif

  /* For each term in the FROM clause, do two things:
  ** (1) Authorized unreferenced tables
@@ -144264,39 +146426,42 @@ SQLITE_PRIVATE int sqlite3Select(
    if( OptimizationEnabled(db, SQLITE_PushDown)
     && (pItem->fg.isCte==0
         || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
-
     && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem)
+
     && pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i)
    ){
#if TREETRACE_ENABLED
-
      if( sqlite3TreeTrace & 0x100 ){
-
        SELECTTRACE(0x100,pParse,p,
+
      if( sqlite3TreeTrace & 0x4000 ){
+
        TREETRACE(0x4000,pParse,p,
            ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
        sqlite3TreeViewSelect(0, p, 0);
      }
#endif
      assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 );
    }else{
-
      SELECTTRACE(0x100,pParse,p,("Push-down not possible\n"));
+
      TREETRACE(0x4000,pParse,p,("Push-down not possible\n"));
+
    }
+

+
    /* Convert unused result columns of the subquery into simple NULL
+
    ** expressions, to avoid unneeded searching and computation.
+
    */
+
    if( OptimizationEnabled(db, SQLITE_NullUnusedCols)
+
     && disableUnusedSubqueryResultColumns(pItem)
+
    ){
+
#if TREETRACE_ENABLED
+
      if( sqlite3TreeTrace & 0x4000 ){
+
        TREETRACE(0x4000,pParse,p,
+
            ("Change unused result columns to NULL for subquery %d:\n",
+
             pSub->selId));
+
        sqlite3TreeViewSelect(0, p, 0);
+
      }
+
#endif
    }

    zSavedAuthContext = pParse->zAuthContext;
    pParse->zAuthContext = pItem->zName;

    /* Generate code to implement the subquery
-
    **
-
    ** 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
-
    **    (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_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) */
-
    ){
+
    if( fromClauseTermCanBeCoroutine(pParse, pTabList, i, p->selFlags) ){
      /* Implement a co-routine that will return a single row of the result
      ** set on each invocation.
      */
@@ -144327,7 +146492,7 @@ SQLITE_PRIVATE int sqlite3Select(
        VdbeComment((v, "%!S", pItem));
      }
      pSub->nSelectRow = pCteUse->nRowEst;
-
    }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){
+
    }else if( (pPrior = isSelfJoinView(pTabList, pItem, 0, i))!=0 ){
      /* This view has already been materialized by a prior entry in
      ** this same FROM clause.  Reuse it. */
      if( pPrior->addrFillSub ){
@@ -144341,6 +146506,9 @@ SQLITE_PRIVATE int sqlite3Select(
      ** the same view can reuse the materialization. */
      int topAddr;
      int onceAddr = 0;
+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
      int addrExplain;
+
#endif

      pItem->regReturn = ++pParse->nMem;
      topAddr = sqlite3VdbeAddOp0(v, OP_Goto);
@@ -144356,15 +146524,14 @@ SQLITE_PRIVATE int sqlite3Select(
        VdbeNoopComment((v, "materialize %!S", pItem));
      }
      sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
-
      ExplainQueryPlan((pParse, 1, "MATERIALIZE %!S", pItem));
-
      dest.zAffSdst = sqlite3TableAffinityStr(db, pItem->pTab);
+

+
      ExplainQueryPlan2(addrExplain, (pParse, 1, "MATERIALIZE %!S", pItem));
      sqlite3Select(pParse, pSub, &dest);
-
      sqlite3DbFree(db, dest.zAffSdst);
-
      dest.zAffSdst = 0;
      pItem->pTab->nRowLogEst = pSub->nSelectRow;
      if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
      sqlite3VdbeAddOp2(v, OP_Return, pItem->regReturn, topAddr+1);
      VdbeComment((v, "end %!S", pItem));
+
      sqlite3VdbeScanStatusRange(v, addrExplain, addrExplain, -1);
      sqlite3VdbeJumpHere(v, topAddr);
      sqlite3ClearTempRegCache(pParse);
      if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){
@@ -144390,8 +146557,8 @@ SQLITE_PRIVATE int sqlite3Select(
  sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0;

#if TREETRACE_ENABLED
-
  if( sqlite3TreeTrace & 0x400 ){
-
    SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n"));
+
  if( sqlite3TreeTrace & 0x8000 ){
+
    TREETRACE(0x8000,pParse,p,("After all FROM-clause analysis:\n"));
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
@@ -144427,8 +146594,8 @@ SQLITE_PRIVATE int sqlite3Select(
    sDistinct.isTnct = 2;

#if TREETRACE_ENABLED
-
    if( sqlite3TreeTrace & 0x400 ){
-
      SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
+
    if( sqlite3TreeTrace & 0x20000 ){
+
      TREETRACE(0x20000,pParse,p,("Transform DISTINCT into GROUP BY:\n"));
      sqlite3TreeViewSelect(0, p, 0);
    }
#endif
@@ -144514,7 +146681,7 @@ SQLITE_PRIVATE int sqlite3Select(


    /* Begin the database scan. */
-
    SELECTTRACE(1,pParse,p,("WhereBegin\n"));
+
    TREETRACE(0x2,pParse,p,("WhereBegin\n"));
    pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
                               p->pEList, p, wctrlFlags, p->nSelectRow);
    if( pWInfo==0 ) goto select_end;
@@ -144531,7 +146698,7 @@ SQLITE_PRIVATE int sqlite3Select(
        sSort.pOrderBy = 0;
      }
    }
-
    SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
+
    TREETRACE(0x2,pParse,p,("WhereBegin returns\n"));

    /* If sorting index that was created by a prior OP_OpenEphemeral
    ** instruction ended up not being needed, then change the OP_OpenEphemeral
@@ -144570,7 +146737,7 @@ SQLITE_PRIVATE int sqlite3Select(

      /* End the database scan loop.
      */
-
      SELECTTRACE(1,pParse,p,("WhereEnd\n"));
+
      TREETRACE(0x2,pParse,p,("WhereEnd\n"));
      sqlite3WhereEnd(pWInfo);
    }
  }else{
@@ -144651,12 +146818,14 @@ SQLITE_PRIVATE int sqlite3Select(
      goto select_end;
    }
    pAggInfo->selId = p->selId;
+
#ifdef SQLITE_DEBUG
+
    pAggInfo->pSelect = p;
+
#endif
    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;
    sNC.pSrcList = pTabList;
    sNC.uNC.pAggInfo = pAggInfo;
    VVA_ONLY( sNC.ncFlags = NC_UAggInfo; )
-
    pAggInfo->mnReg = pParse->nMem+1;
    pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
    pAggInfo->pGroupBy = pGroupBy;
    sqlite3ExprAnalyzeAggList(&sNC, pEList);
@@ -144677,45 +146846,17 @@ SQLITE_PRIVATE int sqlite3Select(
    }else{
      minMaxFlag = WHERE_ORDERBY_NORMAL;
    }
-
    for(i=0; i<pAggInfo->nFunc; i++){
-
      Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
-
      assert( ExprUseXList(pExpr) );
-
      sNC.ncFlags |= NC_InAggFunc;
-
      sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList);
-
#ifndef SQLITE_OMIT_WINDOWFUNC
-
      assert( !IsWindowFunc(pExpr) );
-
      if( ExprHasProperty(pExpr, EP_WinFunc) ){
-
        sqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pWin->pFilter);
-
      }
-
#endif
-
      sNC.ncFlags &= ~NC_InAggFunc;
-
    }
-
    pAggInfo->mxReg = pParse->nMem;
+
    analyzeAggFuncArgs(pAggInfo, &sNC);
    if( db->mallocFailed ) goto select_end;
#if TREETRACE_ENABLED
-
    if( sqlite3TreeTrace & 0x400 ){
-
      int ii;
-
      SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo));
+
    if( sqlite3TreeTrace & 0x20 ){
+
      TREETRACE(0x20,pParse,p,("After aggregate analysis %p:\n", pAggInfo));
      sqlite3TreeViewSelect(0, p, 0);
      if( minMaxFlag ){
        sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag);
        sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY");
      }
-
      for(ii=0; ii<pAggInfo->nColumn; ii++){
-
        struct AggInfo_col *pCol = &pAggInfo->aCol[ii];
-
        sqlite3DebugPrintf(
-
           "agg-column[%d] pTab=%s iTable=%d iColumn=%d iMem=%d"
-
           " iSorterColumn=%d\n",
-
           ii, pCol->pTab ? pCol->pTab->zName : "NULL",
-
           pCol->iTable, pCol->iColumn, pCol->iMem,
-
           pCol->iSorterColumn);
-
        sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0);
-
      }
-
      for(ii=0; ii<pAggInfo->nFunc; ii++){
-
        sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
-
            ii, pAggInfo->aFunc[ii].iMem);
-
        sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pFExpr, 0);
-
      }
+
      printAggInfo(pAggInfo);
    }
#endif

@@ -144784,7 +146925,7 @@ SQLITE_PRIVATE int sqlite3Select(
      ** in the right order to begin with.
      */
      sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
-
      SELECTTRACE(1,pParse,p,("WhereBegin\n"));
+
      TREETRACE(0x2,pParse,p,("WhereBegin\n"));
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct,
          p, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY)
          |  (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0
@@ -144793,8 +146934,12 @@ SQLITE_PRIVATE int sqlite3Select(
        sqlite3ExprListDelete(db, pDistinct);
        goto select_end;
      }
+
      if( pParse->pIdxEpr ){
+
        optimizeAggregateUseOfIndexedExpr(pParse, p, pAggInfo, &sNC);
+
      }
+
      assignAggregateRegisters(pParse, pAggInfo);
      eDist = sqlite3WhereIsDistinct(pWInfo);
-
      SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
+
      TREETRACE(0x2,pParse,p,("WhereBegin returns\n"));
      if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){
        /* The optimizer is able to deliver rows in group by order so
        ** we do not have to sort.  The OP_OpenEphemeral table will be
@@ -144843,7 +146988,7 @@ SQLITE_PRIVATE int sqlite3Select(
        sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord);
        sqlite3ReleaseTempReg(pParse, regRecord);
        sqlite3ReleaseTempRange(pParse, regBase, nCol);
-
        SELECTTRACE(1,pParse,p,("WhereEnd\n"));
+
        TREETRACE(0x2,pParse,p,("WhereEnd\n"));
        sqlite3WhereEnd(pWInfo);
        pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++;
        sortOut = sqlite3GetTempReg(pParse);
@@ -144853,6 +146998,23 @@ SQLITE_PRIVATE int sqlite3Select(
        pAggInfo->useSortingIdx = 1;
      }

+
      /* If there are entries in pAgggInfo->aFunc[] that contain subexpressions
+
      ** that are indexed (and that were previously identified and tagged
+
      ** in optimizeAggregateUseOfIndexedExpr()) then those subexpressions
+
      ** must now be converted into a TK_AGG_COLUMN node so that the value
+
      ** is correctly pulled from the index rather than being recomputed. */
+
      if( pParse->pIdxEpr ){
+
        aggregateConvertIndexedExprRefToColumn(pAggInfo);
+
#if TREETRACE_ENABLED
+
        if( sqlite3TreeTrace & 0x20 ){
+
          TREETRACE(0x20, pParse, p,
+
             ("AggInfo function expressions converted to reference index\n"));
+
          sqlite3TreeViewSelect(0, p, 0);
+
          printAggInfo(pAggInfo);
+
        }
+
#endif
+
      }
+

      /* If the index or temporary table used by the GROUP BY sort
      ** will naturally deliver rows in the order required by the ORDER BY
      ** clause, cancel the ephemeral table open coded earlier.
@@ -144921,7 +147083,7 @@ SQLITE_PRIVATE int sqlite3Select(
        sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop);
        VdbeCoverage(v);
      }else{
-
        SELECTTRACE(1,pParse,p,("WhereEnd\n"));
+
        TREETRACE(0x2,pParse,p,("WhereEnd\n"));
        sqlite3WhereEnd(pWInfo);
        sqlite3VdbeChangeToNoop(v, addrSortingIdx);
      }
@@ -145031,7 +147193,8 @@ SQLITE_PRIVATE int sqlite3Select(
        if( pKeyInfo ){
          sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
        }
-
        sqlite3VdbeAddOp2(v, OP_Count, iCsr, pAggInfo->aFunc[0].iMem);
+
        assignAggregateRegisters(pParse, pAggInfo);
+
        sqlite3VdbeAddOp2(v, OP_Count, iCsr, AggInfoFuncReg(pAggInfo,0));
        sqlite3VdbeAddOp1(v, OP_Close, iCsr);
        explainSimpleCount(pParse, pTab, pBest);
      }else{
@@ -145067,6 +147230,7 @@ SQLITE_PRIVATE int sqlite3Select(
          pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList;
          distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0;
        }
+
        assignAggregateRegisters(pParse, pAggInfo);

        /* This case runs if the aggregate has no GROUP BY clause.  The
        ** processing is much simpler since there is only a single row
@@ -145083,13 +147247,13 @@ SQLITE_PRIVATE int sqlite3Select(
        assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
        assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );

-
        SELECTTRACE(1,pParse,p,("WhereBegin\n"));
+
        TREETRACE(0x2,pParse,p,("WhereBegin\n"));
        pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
                                   pDistinct, p, minMaxFlag|distFlag, 0);
        if( pWInfo==0 ){
          goto select_end;
        }
-
        SELECTTRACE(1,pParse,p,("WhereBegin returns\n"));
+
        TREETRACE(0x2,pParse,p,("WhereBegin returns\n"));
        eDist = sqlite3WhereIsDistinct(pWInfo);
        updateAccumulator(pParse, regAcc, pAggInfo, eDist);
        if( eDist!=WHERE_DISTINCT_NOOP ){
@@ -145103,7 +147267,7 @@ SQLITE_PRIVATE int sqlite3Select(
        if( minMaxFlag ){
          sqlite3WhereMinMaxOptEarlyOut(v, pWInfo);
        }
-
        SELECTTRACE(1,pParse,p,("WhereEnd\n"));
+
        TREETRACE(0x2,pParse,p,("WhereEnd\n"));
        sqlite3WhereEnd(pWInfo);
        finalizeAggFunctions(pParse, pAggInfo);
      }
@@ -145125,8 +147289,6 @@ SQLITE_PRIVATE int sqlite3Select(
  ** and send them to the callback one by one.
  */
  if( sSort.pOrderBy ){
-
    explainTempTable(pParse,
-
                     sSort.nOBSat>0 ? "RIGHT PART OF ORDER BY":"ORDER BY");
    assert( p->pEList==pEList );
    generateSortTail(pParse, p, &sSort, pEList->nExpr, pDest);
  }
@@ -145150,7 +147312,7 @@ select_end:
  if( pAggInfo && !db->mallocFailed ){
    for(i=0; i<pAggInfo->nColumn; i++){
      Expr *pExpr = pAggInfo->aCol[i].pCExpr;
-
      assert( pExpr!=0 );
+
      if( pExpr==0 ) continue;
      assert( pExpr->pAggInfo==pAggInfo );
      assert( pExpr->iAgg==i );
    }
@@ -145164,8 +147326,8 @@ select_end:
#endif

#if TREETRACE_ENABLED
-
  SELECTTRACE(0x1,pParse,p,("end processing\n"));
-
  if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
+
  TREETRACE(0x1,pParse,p,("end processing\n"));
+
  if( (sqlite3TreeTrace & 0x40000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
    sqlite3TreeViewSelect(0, p, 0);
  }
#endif
@@ -145439,7 +147601,7 @@ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
    if( pTrig->pTabSchema==pTab->pSchema
     && pTrig->table
     && 0==sqlite3StrICmp(pTrig->table, pTab->zName)
-
     && pTrig->pTabSchema!=pTmpSchema
+
     && (pTrig->pTabSchema!=pTmpSchema || pTrig->bReturning)
    ){
      pTrig->pNext = pList;
      pList = pTrig;
@@ -145580,6 +147742,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
      }else{
        assert( !db->init.busy );
        sqlite3CodeVerifySchema(pParse, iDb);
+
        VVA_ONLY( pParse->ifNotExists = 1; )
      }
      goto trigger_cleanup;
    }
@@ -146361,7 +148524,7 @@ static void codeReturningTrigger(
  }
  sqlite3ExprListDelete(db, sSelect.pEList);
  pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab);
-
  if( !db->mallocFailed ){
+
  if( pParse->nErr==0 ){
    NameContext sNC;
    memset(&sNC, 0, sizeof(sNC));
    if( pReturning->nRetCol==0 ){
@@ -146830,6 +148993,9 @@ SQLITE_PRIVATE u32 sqlite3TriggerColmask(
  Trigger *p;

  assert( isNew==1 || isNew==0 );
+
  if( IsView(pTab) ){
+
    return 0xffffffff;
+
  }
  for(p=pTrigger; p; p=p->pNext){
    if( p->op==op
     && (tr_tm&p->tr_tm)
@@ -147119,7 +149285,8 @@ static void updateFromSelect(
    }
  }
  pSelect = sqlite3SelectNew(pParse, pList,
-
      pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UFSrcCheck|SF_IncludeHidden, pLimit2
+
      pSrc, pWhere2, pGrp, 0, pOrderBy2,
+
      SF_UFSrcCheck|SF_IncludeHidden|SF_UpdateFrom, pLimit2
  );
  if( pSelect ) pSelect->selFlags |= SF_OrderByReqd;
  sqlite3SelectDestInit(&dest, eDest, iEph);
@@ -147263,7 +149430,7 @@ SQLITE_PRIVATE void sqlite3Update(
  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
    goto update_cleanup;
  }
-
  if( sqlite3IsReadOnly(pParse, pTab, tmask) ){
+
  if( sqlite3IsReadOnly(pParse, pTab, pTrigger) ){
    goto update_cleanup;
  }

@@ -147582,12 +149749,22 @@ SQLITE_PRIVATE void sqlite3Update(
      /* Begin the database scan.
      **
      ** Do not consider a single-pass strategy for a multi-row update if
-
      ** there are any triggers or foreign keys to process, or rows may
-
      ** be deleted as a result of REPLACE conflict handling. Any of these
-
      ** things might disturb a cursor being used to scan through the table
-
      ** or index, causing a single-pass approach to malfunction.  */
+
      ** there is anything that might disrupt the cursor being used to do
+
      ** the UPDATE:
+
      **   (1) This is a nested UPDATE
+
      **   (2) There are triggers
+
      **   (3) There are FOREIGN KEY constraints
+
      **   (4) There are REPLACE conflict handlers
+
      **   (5) There are subqueries in the WHERE clause
+
      */
      flags = WHERE_ONEPASS_DESIRED;
-
      if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
+
      if( !pParse->nested
+
       && !pTrigger
+
       && !hasFK
+
       && !chngKey
+
       && !bReplace
+
       && (sNC.ncFlags & NC_Subquery)==0
+
      ){
        flags |= WHERE_ONEPASS_MULTIROW;
      }
      pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
@@ -149153,10 +151330,10 @@ SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){
  pVTab->nRef--;
  if( pVTab->nRef==0 ){
    sqlite3_vtab *p = pVTab->pVtab;
-
    sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod);
    if( p ){
      p->pModule->xDisconnect(p);
    }
+
    sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod);
    sqlite3DbFree(db, pVTab);
  }
}
@@ -149552,7 +151729,9 @@ static int vtabCallConstructor(
  sCtx.pPrior = db->pVtabCtx;
  sCtx.bDeclared = 0;
  db->pVtabCtx = &sCtx;
+
  pTab->nTabRef++;
  rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
+
  sqlite3DeleteTable(db, pTab);
  db->pVtabCtx = sCtx.pPrior;
  if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
  assert( sCtx.pTab==pTab );
@@ -150042,7 +152221,10 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
            break;
        }
        if( xMethod && pVTab->iSavepoint>iSavepoint ){
+
          u64 savedFlags = (db->flags & SQLITE_Defensive);
+
          db->flags &= ~(u64)SQLITE_Defensive;
          rc = xMethod(pVTab->pVtab, iSavepoint);
+
          db->flags |= savedFlags;
        }
        sqlite3VtabUnlock(pVTab);
      }
@@ -150271,6 +152453,10 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
        p->pVTable->eVtabRisk = SQLITE_VTABRISK_High;
        break;
      }
+
      case SQLITE_VTAB_USES_ALL_SCHEMAS: {
+
        p->pVTable->bAllSchemas = 1;
+
        break;
+
      }
      default: {
        rc = SQLITE_MISUSE_BKPT;
        break;
@@ -150946,6 +153132,7 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*);
#define WHERE_SELFCULL     0x00800000  /* nOut reduced by extra WHERE terms */
#define WHERE_OMIT_OFFSET  0x01000000  /* Set offset counter to zero */
#define WHERE_VIEWSCAN     0x02000000  /* A full-scan of a VIEW or subquery */
+
#define WHERE_EXPRIDX      0x04000000  /* Uses an index-on-expressions */

#endif /* !defined(SQLITE_WHEREINT_H) */

@@ -151043,9 +153230,9 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){

/*
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
-
** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was
-
** defined at compile-time. If it is not a no-op, a single OP_Explain opcode
-
** is added to the output to describe the table scan strategy in pLevel.
+
** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG
+
** was defined at compile-time. If it is not a no-op, a single OP_Explain
+
** opcode is added to the output to describe the table scan strategy in pLevel.
**
** If an OP_Explain opcode is added to the VM, its address is returned.
** Otherwise, if no OP_Explain is coded, zero is returned.
@@ -151057,8 +153244,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan(
  u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
){
  int ret = 0;
-
#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
-
  if( sqlite3ParseToplevel(pParse)->explain==2 )
+
#if !defined(SQLITE_DEBUG)
+
  if( sqlite3ParseToplevel(pParse)->explain==2 || IS_STMT_SCANSTATUS(pParse->db) )
#endif
  {
    SrcItem *pItem = &pTabList->a[pLevel->iFrom];
@@ -151202,6 +153389,8 @@ SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter(
  zMsg = sqlite3StrAccumFinish(&str);
  ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
                          pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
+

+
  sqlite3VdbeScanStatus(v, sqlite3VdbeCurrentAddr(v)-1, 0, 0, 0, 0);
  return ret;
}
#endif /* SQLITE_OMIT_EXPLAIN */
@@ -151222,16 +153411,31 @@ SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
  WhereLevel *pLvl,               /* Level to add scanstatus() entry for */
  int addrExplain                 /* Address of OP_Explain (or 0) */
){
-
  const char *zObj = 0;
-
  WhereLoop *pLoop = pLvl->pWLoop;
-
  if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0  &&  pLoop->u.btree.pIndex!=0 ){
-
    zObj = pLoop->u.btree.pIndex->zName;
-
  }else{
-
    zObj = pSrclist->a[pLvl->iFrom].zName;
+
  if( IS_STMT_SCANSTATUS( sqlite3VdbeDb(v) ) ){
+
    const char *zObj = 0;
+
    WhereLoop *pLoop = pLvl->pWLoop;
+
    int wsFlags = pLoop->wsFlags;
+
    int viaCoroutine = 0;
+

+
    if( (wsFlags & WHERE_VIRTUALTABLE)==0  &&  pLoop->u.btree.pIndex!=0 ){
+
      zObj = pLoop->u.btree.pIndex->zName;
+
    }else{
+
      zObj = pSrclist->a[pLvl->iFrom].zName;
+
      viaCoroutine = pSrclist->a[pLvl->iFrom].fg.viaCoroutine;
+
    }
+
    sqlite3VdbeScanStatus(
+
        v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
+
    );
+

+
    if( viaCoroutine==0 ){
+
      if( (wsFlags & (WHERE_MULTI_OR|WHERE_AUTO_INDEX))==0 ){
+
        sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iTabCur);
+
      }
+
      if( wsFlags & WHERE_INDEXED ){
+
        sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur);
+
      }
+
    }
  }
-
  sqlite3VdbeScanStatus(
-
      v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
-
  );
}
#endif

@@ -151291,7 +153495,7 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
      pTerm->wtFlags |= TERM_CODED;
    }
#ifdef WHERETRACE_ENABLED
-
    if( sqlite3WhereTrace & 0x20000 ){
+
    if( (sqlite3WhereTrace & 0x4001)==0x4001 ){
      sqlite3DebugPrintf("DISABLE-");
      sqlite3WhereTermPrint(pTerm, (int)(pTerm - (pTerm->pWC->a)));
    }
@@ -151406,68 +153610,75 @@ static Expr *removeUnindexableInClauseTerms(
  Expr *pX              /* The IN expression to be reduced */
){
  sqlite3 *db = pParse->db;
+
  Select *pSelect;            /* Pointer to the SELECT on the RHS */
  Expr *pNew;
  pNew = sqlite3ExprDup(db, pX, 0);
  if( db->mallocFailed==0 ){
-
    ExprList *pOrigRhs;         /* Original unmodified RHS */
-
    ExprList *pOrigLhs;         /* Original unmodified LHS */
-
    ExprList *pRhs = 0;         /* New RHS after modifications */
-
    ExprList *pLhs = 0;         /* New LHS after mods */
-
    int i;                      /* Loop counter */
-
    Select *pSelect;            /* Pointer to the SELECT on the RHS */
-

-
    assert( ExprUseXSelect(pNew) );
-
    pOrigRhs = pNew->x.pSelect->pEList;
-
    assert( pNew->pLeft!=0 );
-
    assert( ExprUseXList(pNew->pLeft) );
-
    pOrigLhs = pNew->pLeft->x.pList;
-
    for(i=iEq; i<pLoop->nLTerm; i++){
-
      if( pLoop->aLTerm[i]->pExpr==pX ){
-
        int iField;
-
        assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 );
-
        iField = pLoop->aLTerm[i]->u.x.iField - 1;
-
        if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
-
        pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
-
        pOrigRhs->a[iField].pExpr = 0;
-
        assert( pOrigLhs->a[iField].pExpr!=0 );
-
        pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
-
        pOrigLhs->a[iField].pExpr = 0;
-
      }
-
    }
-
    sqlite3ExprListDelete(db, pOrigRhs);
-
    sqlite3ExprListDelete(db, pOrigLhs);
-
    pNew->pLeft->x.pList = pLhs;
-
    pNew->x.pSelect->pEList = pRhs;
-
    if( pLhs && pLhs->nExpr==1 ){
-
      /* Take care here not to generate a TK_VECTOR containing only a
-
      ** single value. Since the parser never creates such a vector, some
-
      ** of the subroutines do not handle this case.  */
-
      Expr *p = pLhs->a[0].pExpr;
-
      pLhs->a[0].pExpr = 0;
-
      sqlite3ExprDelete(db, pNew->pLeft);
-
      pNew->pLeft = p;
-
    }
-
    pSelect = pNew->x.pSelect;
-
    if( pSelect->pOrderBy ){
-
      /* If the SELECT statement has an ORDER BY clause, zero the
-
      ** iOrderByCol variables. These are set to non-zero when an
-
      ** ORDER BY term exactly matches one of the terms of the
-
      ** result-set. Since the result-set of the SELECT statement may
-
      ** have been modified or reordered, these variables are no longer
-
      ** set correctly.  Since setting them is just an optimization,
-
      ** it's easiest just to zero them here.  */
-
      ExprList *pOrderBy = pSelect->pOrderBy;
-
      for(i=0; i<pOrderBy->nExpr; i++){
-
        pOrderBy->a[i].u.x.iOrderByCol = 0;
+
    for(pSelect=pNew->x.pSelect; pSelect; pSelect=pSelect->pPrior){
+
      ExprList *pOrigRhs;         /* Original unmodified RHS */
+
      ExprList *pOrigLhs = 0;     /* Original unmodified LHS */
+
      ExprList *pRhs = 0;         /* New RHS after modifications */
+
      ExprList *pLhs = 0;         /* New LHS after mods */
+
      int i;                      /* Loop counter */
+

+
      assert( ExprUseXSelect(pNew) );
+
      pOrigRhs = pSelect->pEList;
+
      assert( pNew->pLeft!=0 );
+
      assert( ExprUseXList(pNew->pLeft) );
+
      if( pSelect==pNew->x.pSelect ){
+
        pOrigLhs = pNew->pLeft->x.pList;
+
      }
+
      for(i=iEq; i<pLoop->nLTerm; i++){
+
        if( pLoop->aLTerm[i]->pExpr==pX ){
+
          int iField;
+
          assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 );
+
          iField = pLoop->aLTerm[i]->u.x.iField - 1;
+
          if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
+
          pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
+
          pOrigRhs->a[iField].pExpr = 0;
+
          if( pOrigLhs ){
+
            assert( pOrigLhs->a[iField].pExpr!=0 );
+
            pLhs = sqlite3ExprListAppend(pParse,pLhs,pOrigLhs->a[iField].pExpr);
+
            pOrigLhs->a[iField].pExpr = 0;
+
          }
+
        }
+
      }
+
      sqlite3ExprListDelete(db, pOrigRhs);
+
      if( pOrigLhs ){
+
        sqlite3ExprListDelete(db, pOrigLhs);
+
        pNew->pLeft->x.pList = pLhs;
+
      }
+
      pSelect->pEList = pRhs;
+
      if( pLhs && pLhs->nExpr==1 ){
+
        /* Take care here not to generate a TK_VECTOR containing only a
+
        ** single value. Since the parser never creates such a vector, some
+
        ** of the subroutines do not handle this case.  */
+
        Expr *p = pLhs->a[0].pExpr;
+
        pLhs->a[0].pExpr = 0;
+
        sqlite3ExprDelete(db, pNew->pLeft);
+
        pNew->pLeft = p;
+
      }
+
      if( pSelect->pOrderBy ){
+
        /* If the SELECT statement has an ORDER BY clause, zero the
+
        ** iOrderByCol variables. These are set to non-zero when an
+
        ** ORDER BY term exactly matches one of the terms of the
+
        ** result-set. Since the result-set of the SELECT statement may
+
        ** have been modified or reordered, these variables are no longer
+
        ** set correctly.  Since setting them is just an optimization,
+
        ** it's easiest just to zero them here.  */
+
        ExprList *pOrderBy = pSelect->pOrderBy;
+
        for(i=0; i<pOrderBy->nExpr; i++){
+
          pOrderBy->a[i].u.x.iOrderByCol = 0;
+
        }
      }
-
    }

#if 0
-
    printf("For indexing, change the IN expr:\n");
-
    sqlite3TreeViewExpr(0, pX, 0);
-
    printf("Into:\n");
-
    sqlite3TreeViewExpr(0, pNew, 0);
+
      printf("For indexing, change the IN expr:\n");
+
      sqlite3TreeViewExpr(0, pX, 0);
+
      printf("Into:\n");
+
      sqlite3TreeViewExpr(0, pNew, 0);
#endif
+
    }
  }
  return pNew;
}
@@ -151919,11 +154130,12 @@ static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){
*/
static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){
  int rc = WRC_Continue;
+
  int reg;
  struct CCurHint *pHint = pWalker->u.pCCurHint;
  if( pExpr->op==TK_COLUMN ){
    if( pExpr->iTable!=pHint->iTabCur ){
-
      int reg = ++pWalker->pParse->nMem;   /* Register for column value */
-
      sqlite3ExprCode(pWalker->pParse, pExpr, reg);
+
      reg = ++pWalker->pParse->nMem;   /* Register for column value */
+
      reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg);
      pExpr->op = TK_REGISTER;
      pExpr->iTable = reg;
    }else if( pHint->pIdx!=0 ){
@@ -151931,15 +154143,15 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){
      pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn);
      assert( pExpr->iColumn>=0 );
    }
-
  }else if( pExpr->op==TK_AGG_FUNCTION ){
-
    /* An aggregate function in the WHERE clause of a query means this must
-
    ** be a correlated sub-query, and expression pExpr is an aggregate from
-
    ** the parent context. Do not walk the function arguments in this case.
-
    **
-
    ** todo: It should be possible to replace this node with a TK_REGISTER
-
    ** expression, as the result of the expression must be stored in a
-
    ** register at this point. The same holds for TK_AGG_COLUMN nodes. */
+
  }else if( pExpr->pAggInfo ){
    rc = WRC_Prune;
+
    reg = ++pWalker->pParse->nMem;   /* Register for column value */
+
    reg = sqlite3ExprCodeTarget(pWalker->pParse, pExpr, reg);
+
    pExpr->op = TK_REGISTER;
+
    pExpr->iTable = reg;
+
  }else if( pExpr->op==TK_TRUEFALSE ){
+
    /* Do not walk disabled expressions.  tag-20230504-1 */
+
    return WRC_Prune;
  }
  return rc;
}
@@ -152041,7 +154253,7 @@ static void codeCursorHint(
  }
  if( pExpr!=0 ){
    sWalker.xExprCallback = codeCursorHintFixExpr;
-
    sqlite3WalkExpr(&sWalker, pExpr);
+
    if( pParse->nErr==0 ) sqlite3WalkExpr(&sWalker, pExpr);
    sqlite3VdbeAddOp4(v, OP_CursorHint,
                      (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0,
                      (const char*)pExpr, P4_EXPR);
@@ -152278,13 +154490,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
  pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
  bRev = (pWInfo->revMask>>iLevel)&1;
  VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));
-
#if WHERETRACE_ENABLED /* 0x20800 */
-
  if( sqlite3WhereTrace & 0x800 ){
+
#if WHERETRACE_ENABLED /* 0x4001 */
+
  if( sqlite3WhereTrace & 0x1 ){
    sqlite3DebugPrintf("Coding level %d of %d:  notReady=%llx  iFrom=%d\n",
       iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom);
-
    sqlite3WhereLoopPrint(pLoop, pWC);
+
    if( sqlite3WhereTrace & 0x1000 ){
+
      sqlite3WhereLoopPrint(pLoop, pWC);
+
    }
  }
-
  if( sqlite3WhereTrace & 0x20000 ){
+
  if( (sqlite3WhereTrace & 0x4001)==0x4001 ){
    if( iLevel==0 ){
      sqlite3DebugPrintf("WHERE clause being coded:\n");
      sqlite3TreeViewExpr(0, pWInfo->pWhere, 0);
@@ -152833,7 +155047,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
        ** guess. */
        addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan,
                                         (pIdx->aiRowLogEst[0]+9)/10);
-
        if( pRangeStart ){
+
        if( pRangeStart || pRangeEnd ){
          sqlite3VdbeChangeP5(v, 1);
          sqlite3VdbeChangeP2(v, addrSeekScan, sqlite3VdbeCurrentAddr(v)+1);
          addrSeekScan = 0;
@@ -152874,16 +155088,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
    assert( pLevel->p2==0 );
    if( pRangeEnd ){
      Expr *pRight = pRangeEnd->pExpr->pRight;
-
      if( addrSeekScan ){
-
        /* For a seek-scan that has a range on the lowest term of the index,
-
        ** we have to make the top of the loop be code that sets the end
-
        ** condition of the range.  Otherwise, the OP_SeekScan might jump
-
        ** over that initialization, leaving the range-end value set to the
-
        ** range-start value, resulting in a wrong answer.
-
        ** See ticket 5981a8c041a3c2f3 (2021-11-02).
-
        */
-
        pLevel->p2 = sqlite3VdbeCurrentAddr(v);
-
      }
+
      assert( addrSeekScan==0 );
      codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
      whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
      if( (pRangeEnd->wtFlags & TERM_VNULL)==0
@@ -152917,7 +155122,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
    if( zEndAff ) sqlite3DbNNFreeNN(db, zEndAff);

    /* Top of the loop body */
-
    if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v);
+
    pLevel->p2 = sqlite3VdbeCurrentAddr(v);

    /* Check if the index cursor is past the end of the range. */
    if( nConstraint ){
@@ -153208,7 +155413,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
        }
        /* Loop through table entries that match term pOrTerm. */
        ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
-
        WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
+
        WHERETRACE(0xffffffff, ("Subplan for OR-clause:\n"));
        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0,
                                      WHERE_OR_SUBCLAUSE, iCovCur);
        assert( pSubWInfo || pParse->nErr );
@@ -153445,12 +155650,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
        }
#endif
      }
-
#ifdef WHERETRACE_ENABLED /* 0xffff */
+
#ifdef WHERETRACE_ENABLED /* 0xffffffff */
      if( sqlite3WhereTrace ){
        VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d",
                         pWC->nTerm-j, pTerm, iLoop));
      }
-
      if( sqlite3WhereTrace & 0x800 ){
+
      if( sqlite3WhereTrace & 0x4000 ){
        sqlite3DebugPrintf("Coding auxiliary constraint:\n");
        sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
      }
@@ -153479,8 +155684,8 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
    if( pTerm->leftCursor!=iCur ) continue;
    if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ|JT_RIGHT) ) continue;
    pE = pTerm->pExpr;
-
#ifdef WHERETRACE_ENABLED /* 0x800 */
-
    if( sqlite3WhereTrace & 0x800 ){
+
#ifdef WHERETRACE_ENABLED /* 0x4001 */
+
    if( (sqlite3WhereTrace & 0x4001)==0x4001 ){
      sqlite3DebugPrintf("Coding transitive constraint:\n");
      sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
    }
@@ -153595,13 +155800,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
    }
  }

-
#if WHERETRACE_ENABLED /* 0x20800 */
-
  if( sqlite3WhereTrace & 0x20000 ){
+
#if WHERETRACE_ENABLED /* 0x4001 */
+
  if( sqlite3WhereTrace & 0x4000 ){
    sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n",
                       iLevel);
    sqlite3WhereClausePrint(pWC);
  }
-
  if( sqlite3WhereTrace & 0x800 ){
+
  if( sqlite3WhereTrace & 0x1 ){
    sqlite3DebugPrintf("End Coding level %d:  notReady=%llx\n",
       iLevel, (u64)pLevel->notReady);
  }
@@ -154677,36 +156882,40 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){
*/
static SQLITE_NOINLINE int exprMightBeIndexed2(
  SrcList *pFrom,        /* The FROM clause */
-
  Bitmask mPrereq,       /* Bitmask of FROM clause terms referenced by pExpr */
  int *aiCurCol,         /* Write the referenced table cursor and column here */
-
  Expr *pExpr            /* An operand of a comparison operator */
+
  Expr *pExpr,           /* An operand of a comparison operator */
+
  int j                  /* Start looking with the j-th pFrom entry */
){
  Index *pIdx;
  int i;
  int iCur;
-
  for(i=0; mPrereq>1; i++, mPrereq>>=1){}
-
  iCur = pFrom->a[i].iCursor;
-
  for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
-
    if( pIdx->aColExpr==0 ) continue;
-
    for(i=0; i<pIdx->nKeyCol; i++){
-
      if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
-
      assert( pIdx->bHasExpr );
-
      if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){
-
        aiCurCol[0] = iCur;
-
        aiCurCol[1] = XN_EXPR;
-
        return 1;
+
  do{
+
    iCur = pFrom->a[j].iCursor;
+
    for(pIdx=pFrom->a[j].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+
      if( pIdx->aColExpr==0 ) continue;
+
      for(i=0; i<pIdx->nKeyCol; i++){
+
        if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
+
        assert( pIdx->bHasExpr );
+
        if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0
+
          && pExpr->op!=TK_STRING
+
        ){
+
          aiCurCol[0] = iCur;
+
          aiCurCol[1] = XN_EXPR;
+
          return 1;
+
        }
      }
    }
-
  }
+
  }while( ++j < pFrom->nSrc );
  return 0;
}
static int exprMightBeIndexed(
  SrcList *pFrom,        /* The FROM clause */
-
  Bitmask mPrereq,       /* Bitmask of FROM clause terms referenced by pExpr */
  int *aiCurCol,         /* Write the referenced table cursor & column here */
  Expr *pExpr,           /* An operand of a comparison operator */
  int op                 /* The specific comparison operator */
){
+
  int i;
+

  /* If this expression is a vector to the left or right of a
  ** inequality constraint (>, <, >= or <=), perform the processing
  ** on the first element of the vector.  */
@@ -154716,7 +156925,6 @@ static int exprMightBeIndexed(
  if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
    assert( ExprUseXList(pExpr) );
    pExpr = pExpr->x.pList->a[0].pExpr;
-

  }

  if( pExpr->op==TK_COLUMN ){
@@ -154724,9 +156932,16 @@ static int exprMightBeIndexed(
    aiCurCol[1] = pExpr->iColumn;
    return 1;
  }
-
  if( mPrereq==0 ) return 0;                 /* No table references */
-
  if( (mPrereq&(mPrereq-1))!=0 ) return 0;   /* Refs more than one table */
-
  return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr);
+

+
  for(i=0; i<pFrom->nSrc; i++){
+
    Index *pIdx;
+
    for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+
      if( pIdx->aColExpr ){
+
        return exprMightBeIndexed2(pFrom,aiCurCol,pExpr,i);
+
      }
+
    }
+
  }
+
  return 0;
}


@@ -154852,7 +157067,7 @@ static void exprAnalyze(
      pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr;
    }

-
    if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
+
    if( exprMightBeIndexed(pSrc, aiCurCol, pLeft, op) ){
      pTerm->leftCursor = aiCurCol[0];
      assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
      pTerm->u.x.leftColumn = aiCurCol[1];
@@ -154860,7 +157075,7 @@ static void exprAnalyze(
    }
    if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
    if( pRight
-
     && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op)
+
     && exprMightBeIndexed(pSrc, aiCurCol, pRight, op)
     && !ExprHasProperty(pRight, EP_FixedCol)
    ){
      WhereTerm *pNew;
@@ -154904,7 +157119,7 @@ static void exprAnalyze(
     && 0==sqlite3ExprCanBeNull(pLeft)
    ){
      assert( !ExprHasProperty(pExpr, EP_IntValue) );
-
      pExpr->op = TK_TRUEFALSE;
+
      pExpr->op = TK_TRUEFALSE;  /* See tag-20230504-1 */
      pExpr->u.zToken = "false";
      ExprSetProperty(pExpr, EP_IsFalse);
      pTerm->prereqAll = 0;
@@ -155071,7 +157286,6 @@ static void exprAnalyze(
    transferJoinMarkings(pNewExpr1, pExpr);
    idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags);
    testcase( idxNew1==0 );
-
    exprAnalyze(pSrc, pWC, idxNew1);
    pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
    pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
           sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
@@ -155079,6 +157293,7 @@ static void exprAnalyze(
    transferJoinMarkings(pNewExpr2, pExpr);
    idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags);
    testcase( idxNew2==0 );
+
    exprAnalyze(pSrc, pWC, idxNew1);
    exprAnalyze(pSrc, pWC, idxNew2);
    pTerm = &pWC->a[idxTerm];
    if( isComplete ){
@@ -155135,7 +157350,7 @@ static void exprAnalyze(
   && pTerm->u.x.iField==0
   && pExpr->pLeft->op==TK_VECTOR
   && ALWAYS( ExprUseXSelect(pExpr) )
-
   && pExpr->x.pSelect->pPrior==0
+
   && (pExpr->x.pSelect->pPrior==0 || (pExpr->x.pSelect->selFlags & SF_Values))
#ifndef SQLITE_OMIT_WINDOWFUNC
   && pExpr->x.pSelect->pWin==0
#endif
@@ -155323,6 +157538,13 @@ SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3WhereAddLimit(WhereClause *pWC, Selec
        assert( pWC->a[ii].eOperator==WO_ROWVAL );
        continue;
      }
+
      if( pWC->a[ii].nChild ){
+
        /* If this term has child terms, then they are also part of the
+
        ** pWC->a[] array. So this term can be ignored, as a LIMIT clause
+
        ** will only be added if each of the child terms passes the
+
        ** (leftCursor==iCsr) test below.  */
+
        continue;
+
      }
      if( pWC->a[ii].leftCursor!=iCsr ) return;
    }

@@ -155542,9 +157764,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|JT_LTORJ) ){
+
    if( pItem->fg.jointype & (JT_LEFT|JT_RIGHT) ){
+
      testcase( pItem->fg.jointype & JT_LEFT );  /* testtag-20230227a */
+
      testcase( pItem->fg.jointype & JT_RIGHT ); /* testtag-20230227b */
      joinType = EP_OuterON;
    }else{
+
      testcase( pItem->fg.jointype & JT_LTORJ ); /* testtag-20230227c */
      joinType = EP_InnerON;
    }
    sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType);
@@ -155623,7 +157848,7 @@ SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){
** block sorting is required.
*/
SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){
-
  return pWInfo->nOBSat;
+
  return pWInfo->nOBSat<0 ? 0 : pWInfo->nOBSat;
}

/*
@@ -156261,7 +158486,7 @@ static void translateColumnToCopy(
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED)
static void whereTraceIndexInfoInputs(sqlite3_index_info *p){
  int i;
-
  if( !sqlite3WhereTrace ) return;
+
  if( (sqlite3WhereTrace & 0x10)==0 ) return;
  for(i=0; i<p->nConstraint; i++){
    sqlite3DebugPrintf(
       "  constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n",
@@ -156281,7 +158506,7 @@ static void whereTraceIndexInfoInputs(sqlite3_index_info *p){
}
static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){
  int i;
-
  if( !sqlite3WhereTrace ) return;
+
  if( (sqlite3WhereTrace & 0x10)==0 ) return;
  for(i=0; i<p->nConstraint; i++){
    sqlite3DebugPrintf("  usage[%d]: argvIdx=%d omit=%d\n",
       i,
@@ -156368,6 +158593,57 @@ static int termCanDriveIndex(


#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
+

+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
/*
+
** Argument pIdx represents an automatic index that the current statement
+
** will create and populate. Add an OP_Explain with text of the form:
+
**
+
**     CREATE AUTOMATIC INDEX ON <table>(<cols>) [WHERE <expr>]
+
**
+
** This is only required if sqlite3_stmt_scanstatus() is enabled, to
+
** associate an SQLITE_SCANSTAT_NCYCLE and SQLITE_SCANSTAT_NLOOP
+
** values with. In order to avoid breaking legacy code and test cases,
+
** the OP_Explain is not added if this is an EXPLAIN QUERY PLAN command.
+
*/
+
static void explainAutomaticIndex(
+
  Parse *pParse,
+
  Index *pIdx,                    /* Automatic index to explain */
+
  int bPartial,                   /* True if pIdx is a partial index */
+
  int *pAddrExplain               /* OUT: Address of OP_Explain */
+
){
+
  if( IS_STMT_SCANSTATUS(pParse->db) && pParse->explain!=2 ){
+
    Table *pTab = pIdx->pTable;
+
    const char *zSep = "";
+
    char *zText = 0;
+
    int ii = 0;
+
    sqlite3_str *pStr = sqlite3_str_new(pParse->db);
+
    sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName);
+
    assert( pIdx->nColumn>1 );
+
    assert( pIdx->aiColumn[pIdx->nColumn-1]==XN_ROWID );
+
    for(ii=0; ii<(pIdx->nColumn-1); ii++){
+
      const char *zName = 0;
+
      int iCol = pIdx->aiColumn[ii];
+

+
      zName = pTab->aCol[iCol].zCnName;
+
      sqlite3_str_appendf(pStr, "%s%s", zSep, zName);
+
      zSep = ", ";
+
    }
+
    zText = sqlite3_str_finish(pStr);
+
    if( zText==0 ){
+
      sqlite3OomFault(pParse->db);
+
    }else{
+
      *pAddrExplain = sqlite3VdbeExplain(
+
          pParse, 0, "%s)%s", zText, (bPartial ? " WHERE <expr>" : "")
+
      );
+
      sqlite3_free(zText);
+
    }
+
  }
+
}
+
#else
+
# define explainAutomaticIndex(a,b,c,d)
+
#endif
+

/*
** Generate code to construct the Index object for an automatic index
** and to set up the WhereLevel object pLevel so that the code generator
@@ -156375,8 +158651,7 @@ static int termCanDriveIndex(
*/
static SQLITE_NOINLINE void constructAutomaticIndex(
  Parse *pParse,              /* The parsing context */
-
  const WhereClause *pWC,     /* The WHERE clause */
-
  const SrcItem *pSrc,        /* The FROM clause term to get the next index */
+
  WhereClause *pWC,           /* The WHERE clause */
  const Bitmask notReady,     /* Mask of cursors that are not available */
  WhereLevel *pLevel          /* Write new index here */
){
@@ -156397,12 +158672,17 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
  char *zNotUsed;             /* Extra space on the end of pIdx */
  Bitmask idxCols;            /* Bitmap of columns used for indexing */
  Bitmask extraCols;          /* Bitmap of additional columns */
-
  u8 sentWarning = 0;         /* True if a warnning has been issued */
+
  u8 sentWarning = 0;         /* True if a warning has been issued */
+
  u8 useBloomFilter = 0;      /* True to also add a Bloom filter */
  Expr *pPartial = 0;         /* Partial Index Expression */
  int iContinue = 0;          /* Jump here to skip excluded rows */
-
  SrcItem *pTabItem;          /* FROM clause term being indexed */
+
  SrcList *pTabList;          /* The complete FROM clause */
+
  SrcItem *pSrc;              /* The FROM clause term to get the next index */
  int addrCounter = 0;        /* Address where integer counter is initialized */
  int regBase;                /* Array of registers where record is assembled */
+
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+
  int addrExp = 0;            /* Address of OP_Explain */
+
#endif

  /* Generate code to skip over the creation and initialization of the
  ** transient index on 2nd and subsequent iterations of the loop. */
@@ -156413,6 +158693,8 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
  /* Count the number of columns that will be added to the index
  ** and used to match WHERE clause constraints */
  nKeyCol = 0;
+
  pTabList = pWC->pWInfo->pTabList;
+
  pSrc = &pTabList->a[pLevel->iFrom];
  pTable = pSrc->pTab;
  pWCEnd = &pWC->a[pWC->nTerm];
  pLoop = pLevel->pWLoop;
@@ -156423,7 +158705,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
    ** WHERE clause (or the ON clause of a LEFT join) that constrain which
    ** rows of the target table (pSrc) that can be used. */
    if( (pTerm->wtFlags & TERM_VIRTUAL)==0
-
     && sqlite3ExprIsTableConstraint(pExpr, pSrc)
+
     && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, pLevel->iFrom)
    ){
      pPartial = sqlite3ExprAnd(pParse, pPartial,
                                sqlite3ExprDup(pParse->db, pExpr, 0));
@@ -156464,7 +158746,11 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
  ** original table changes and the index and table cannot both be used
  ** if they go out of sync.
  */
-
  extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
+
  if( IsView(pTable) ){
+
    extraCols = ALLBITS;
+
  }else{
+
    extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
+
  }
  mxBitCol = MIN(BMS-1,pTable->nCol);
  testcase( pTable->nCol==BMS-1 );
  testcase( pTable->nCol==BMS-2 );
@@ -156500,6 +158786,16 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
        assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */
        pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY;
        n++;
+
        if( ALWAYS(pX->pLeft!=0)
+
         && sqlite3ExprAffinity(pX->pLeft)!=SQLITE_AFF_TEXT
+
        ){
+
          /* TUNING: only use a Bloom filter on an automatic index
+
          ** if one or more key columns has the ability to hold numeric
+
          ** values, since strings all have the same hash in the Bloom
+
          ** filter implementation and hence a Bloom filter on a text column
+
          ** is not usually helpful. */
+
          useBloomFilter = 1;
+
        }
      }
    }
  }
@@ -156526,25 +158822,27 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
  pIdx->azColl[n] = sqlite3StrBINARY;

  /* Create the automatic index */
+
  explainAutomaticIndex(pParse, pIdx, pPartial!=0, &addrExp);
  assert( pLevel->iIdxCur>=0 );
  pLevel->iIdxCur = pParse->nTab++;
  sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
  sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  VdbeComment((v, "for %s", pTable->zName));
-
  if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){
+
  if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) && useBloomFilter ){
+
    sqlite3WhereExplainBloomFilter(pParse, pWC->pWInfo, pLevel);
    pLevel->regFilter = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter);
  }

  /* Fill the automatic index with content */
-
  pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
-
  if( pTabItem->fg.viaCoroutine ){
-
    int regYield = pTabItem->regReturn;
+
  assert( pSrc == &pWC->pWInfo->pTabList->a[pLevel->iFrom] );
+
  if( pSrc->fg.viaCoroutine ){
+
    int regYield = pSrc->regReturn;
    addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0);
-
    sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
+
    sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pSrc->addrFillSub);
    addrTop =  sqlite3VdbeAddOp1(v, OP_Yield, regYield);
    VdbeCoverage(v);
-
    VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
+
    VdbeComment((v, "next row of %s", pSrc->pTab->zName));
  }else{
    addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
  }
@@ -156561,17 +158859,18 @@ static SQLITE_NOINLINE void constructAutomaticIndex(
    sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0,
                         regBase, pLoop->u.btree.nEq);
  }
+
  sqlite3VdbeScanStatusCounters(v, addrExp, addrExp, sqlite3VdbeCurrentAddr(v));
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
-
  if( pTabItem->fg.viaCoroutine ){
+
  if( pSrc->fg.viaCoroutine ){
    sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
    testcase( pParse->db->mallocFailed );
    assert( pLevel->iIdxCur>0 );
    translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
-
                          pTabItem->regResult, pLevel->iIdxCur);
+
                          pSrc->regResult, pLevel->iIdxCur);
    sqlite3VdbeGoto(v, addrTop);
-
    pTabItem->fg.viaCoroutine = 0;
+
    pSrc->fg.viaCoroutine = 0;
  }else{
    sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
    sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
@@ -156581,6 +158880,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex(

  /* Jump here when skipping the initialization */
  sqlite3VdbeJumpHere(v, addrInit);
+
  sqlite3VdbeScanStatusRange(v, addrExp, addrExp, -1);

end_auto_index_create:
  sqlite3ExprDelete(pParse->db, pPartial);
@@ -156622,6 +158922,10 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
  Vdbe *v = pParse->pVdbe;             /* VDBE under construction */
  WhereLoop *pLoop = pLevel->pWLoop;   /* The loop being coded */
  int iCur;                            /* Cursor for table getting the filter */
+
  IndexedExpr *saved_pIdxEpr;          /* saved copy of Parse.pIdxEpr */
+

+
  saved_pIdxEpr = pParse->pIdxEpr;
+
  pParse->pIdxEpr = 0;

  assert( pLoop!=0 );
  assert( v!=0 );
@@ -156629,9 +158933,11 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(

  addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  do{
+
    const SrcList *pTabList;
    const SrcItem *pItem;
    const Table *pTab;
    u64 sz;
+
    int iSrc;
    sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel);
    addrCont = sqlite3VdbeMakeLabel(pParse);
    iCur = pLevel->iTabCur;
@@ -156645,7 +158951,9 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
    ** testing complicated.  By basing the blob size on the value in the
    ** sqlite_stat1 table, testing is much easier.
    */
-
    pItem = &pWInfo->pTabList->a[pLevel->iFrom];
+
    pTabList = pWInfo->pTabList;
+
    iSrc = pLevel->iFrom;
+
    pItem = &pTabList->a[iSrc];
    assert( pItem!=0 );
    pTab = pItem->pTab;
    assert( pTab!=0 );
@@ -156662,7 +158970,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
    for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){
      Expr *pExpr = pTerm->pExpr;
      if( (pTerm->wtFlags & TERM_VIRTUAL)==0
-
       && sqlite3ExprIsTableConstraint(pExpr, pItem)
+
       && sqlite3ExprIsSingleTableConstraint(pExpr, pTabList, iSrc)
      ){
        sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
      }
@@ -156678,9 +158986,8 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
      int r1 = sqlite3GetTempRange(pParse, n);
      int jj;
      for(jj=0; jj<n; jj++){
-
        int iCol = pIdx->aiColumn[jj];
        assert( pIdx->pTable==pItem->pTab );
-
        sqlite3ExprCodeGetColumnOfTable(v, pIdx->pTable, iCur, iCol,r1+jj);
+
        sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iCur, jj, r1+jj);
      }
      sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n);
      sqlite3ReleaseTempRange(pParse, r1, n);
@@ -156711,6 +159018,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter(
    }
  }while( iLevel < pWInfo->nLevel );
  sqlite3VdbeJumpHere(v, addrOnce);
+
  pParse->pIdxEpr = saved_pIdxEpr;
}


@@ -156966,6 +159274,9 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
      sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg);
    }
  }
+
  if( pTab->u.vtab.p->bAllSchemas ){
+
    sqlite3VtabUsesAllSchemas(pParse);
+
  }
  sqlite3_free(pVtab->zErrMsg);
  pVtab->zErrMsg = 0;
  return rc;
@@ -157010,6 +159321,7 @@ static int whereKeyStats(
  assert( pIdx->nSample>0 );
  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
  ** is simply the aSample[] array. If the samples in aSample[] contain more
@@ -157054,7 +159366,12 @@ static int whereKeyStats(
  ** it is extended to two fields. The duplicates that this creates do not
  ** cause any problems.
  */
-
  nField = MIN(pRec->nField, pIdx->nSample);
+
  if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
+
    nField = pIdx->nKeyCol;
+
  }else{
+
    nField = pIdx->nColumn;
+
  }
+
  nField = MIN(pRec->nField, nField);
  iCol = 0;
  iSample = pIdx->nSample * nField;
  do{
@@ -157120,12 +159437,12 @@ static int whereKeyStats(
      if( iCol>0 ){
        pRec->nField = iCol;
        assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0
-
             || pParse->db->mallocFailed );
+
             || pParse->db->mallocFailed || CORRUPT_DB );
      }
      if( i>0 ){
        pRec->nField = nField;
        assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0
-
             || pParse->db->mallocFailed );
+
             || pParse->db->mallocFailed || CORRUPT_DB );
      }
    }
  }
@@ -157298,7 +159615,7 @@ static int whereRangeSkipScanEst(
      int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff));
      pLoop->nOut -= nAdjust;
      *pbDone = 1;
-
      WHERETRACE(0x10, ("range skip-scan regions: %u..%u  adjust=%d est=%d\n",
+
      WHERETRACE(0x20, ("range skip-scan regions: %u..%u  adjust=%d est=%d\n",
                           nLower, nUpper, nAdjust*-1, pLoop->nOut));
    }

@@ -157476,7 +159793,7 @@ static int whereRangeScanEst(
        if( nNew<nOut ){
          nOut = nNew;
        }
-
        WHERETRACE(0x10, ("STAT4 range scan: %u..%u  est=%d\n",
+
        WHERETRACE(0x20, ("STAT4 range scan: %u..%u  est=%d\n",
                           (u32)iLower, (u32)iUpper, nOut));
      }
    }else{
@@ -157490,7 +159807,7 @@ static int whereRangeScanEst(
  UNUSED_PARAMETER(pBuilder);
  assert( pLower || pUpper );
#endif
-
  assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 );
+
  assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 || pParse->nErr>0 );
  nNew = whereRangeAdjust(pLower, nOut);
  nNew = whereRangeAdjust(pUpper, nNew);

@@ -157509,7 +159826,7 @@ static int whereRangeScanEst(
  if( nNew<nOut ) nOut = nNew;
#if defined(WHERETRACE_ENABLED)
  if( pLoop->nOut>nOut ){
-
    WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n",
+
    WHERETRACE(0x20,("Range scan lowers nOut from %d to %d\n",
                    pLoop->nOut, nOut));
  }
#endif
@@ -157574,7 +159891,7 @@ static int whereEqualScanEst(
  pBuilder->nRecValid = nEq;

  whereKeyStats(pParse, p, pRec, 0, a);
-
  WHERETRACE(0x10,("equality scan regions %s(%d): %d\n",
+
  WHERETRACE(0x20,("equality scan regions %s(%d): %d\n",
                   p->zName, nEq-1, (int)a[1]));
  *pnRow = a[1];

@@ -157622,9 +159939,9 @@ static int whereInScanEst(
  }

  if( rc==SQLITE_OK ){
-
    if( nRowEst > nRow0 ) nRowEst = nRow0;
+
    if( nRowEst > (tRowcnt)nRow0 ) nRowEst = nRow0;
    *pnRow = nRowEst;
-
    WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst));
+
    WHERETRACE(0x20,("IN row estimate: est=%d\n", nRowEst));
  }
  assert( pBuilder->nRecValid==nRecValid );
  return rc;
@@ -157733,7 +160050,7 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){
    sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm);
  }
  sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
-
  if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){
+
  if( p->nLTerm && (sqlite3WhereTrace & 0x4000)!=0 ){
    int i;
    for(i=0; i<p->nLTerm; i++){
      sqlite3WhereTermPrint(p->aLTerm[i], i);
@@ -158197,6 +160514,7 @@ static void whereLoopOutputAdjust(
      if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
    }
    if( j<0 ){
+
      sqlite3ProgressCheck(pWC->pWInfo->pParse);
      if( pLoop->maskSelf==pTerm->prereqAll ){
        /* If there are extra terms in the WHERE clause not used by an index
        ** that depend only on the table being scanned, and that will tend to
@@ -158364,7 +160682,10 @@ static int whereLoopAddBtreeIndex(
  WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */

  pNew = pBuilder->pNew;
-
  if( db->mallocFailed ) return SQLITE_NOMEM_BKPT;
+
  assert( db->mallocFailed==0 || pParse->nErr>0 );
+
  if( pParse->nErr ){
+
    return pParse->rc;
+
  }
  WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d, nSkip=%d, rRun=%d\n",
                     pProbe->pTable->zName,pProbe->zName,
                     pNew->u.btree.nEq, pNew->nSkip, pNew->rRun));
@@ -158611,7 +160932,7 @@ static int whereLoopAddBtreeIndex(
             && pNew->nOut+10 > pProbe->aiRowLogEst[0]
            ){
#if WHERETRACE_ENABLED /* 0x01 */
-
              if( sqlite3WhereTrace & 0x01 ){
+
              if( sqlite3WhereTrace & 0x20 ){
                sqlite3DebugPrintf(
                   "STAT4 determines term has low selectivity:\n");
                sqlite3WhereTermPrint(pTerm, 999);
@@ -158648,9 +160969,17 @@ static int whereLoopAddBtreeIndex(
    ** seek only. Then, if this is a non-covering index, add the cost of
    ** visiting the rows in the main table.  */
    assert( pSrc->pTab->szTabRow>0 );
-
    rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
+
    if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){
+
      /* The pProbe->szIdxRow is low for an IPK table since the interior
+
      ** pages are small.  Thuse szIdxRow gives a good estimate of seek cost.
+
      ** But the leaf pages are full-size, so pProbe->szIdxRow would badly
+
      ** under-estimate the scanning cost. */
+
      rCostIdx = pNew->nOut + 16;
+
    }else{
+
      rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow;
+
    }
    pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx);
-
    if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
+
    if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK|WHERE_EXPRIDX))==0 ){
      pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16);
    }
    ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult);
@@ -158672,6 +161001,9 @@ static int whereLoopAddBtreeIndex(
     && (pNew->u.btree.nEq<pProbe->nKeyCol ||
           pProbe->idxType!=SQLITE_IDXTYPE_PRIMARYKEY)
    ){
+
      if( pNew->u.btree.nEq>3 ){
+
        sqlite3ProgressCheck(pParse);
+
      }
      whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
    }
    pNew->nOut = saved_nOut;
@@ -158804,15 +161136,38 @@ static int whereUsablePartialIndex(
}

/*
+
** pIdx is an index containing expressions.  Check it see if any of the
+
** expressions in the index match the pExpr expression.
+
*/
+
static int exprIsCoveredByIndex(
+
  const Expr *pExpr,
+
  const Index *pIdx,
+
  int iTabCur
+
){
+
  int i;
+
  for(i=0; i<pIdx->nColumn; i++){
+
    if( pIdx->aiColumn[i]==XN_EXPR
+
     && sqlite3ExprCompare(0, pExpr, pIdx->aColExpr->a[i].pExpr, iTabCur)==0
+
    ){
+
      return 1;
+
    }
+
  }
+
  return 0;
+
}
+

+
/*
** Structure passed to the whereIsCoveringIndex Walker callback.
*/
+
typedef struct CoveringIndexCheck CoveringIndexCheck;
struct CoveringIndexCheck {
  Index *pIdx;       /* The index */
  int iTabCur;       /* Cursor number for the corresponding table */
+
  u8 bExpr;          /* Uses an indexed expression */
+
  u8 bUnidx;         /* Uses an unindexed column not within an indexed expr */
};

/*
-
** Information passed in is pWalk->u.pCovIdxCk.  Call is pCk.
+
** Information passed in is pWalk->u.pCovIdxCk.  Call it pCk.
**
** If the Expr node references the table with cursor pCk->iTabCur, then
** make sure that column is covered by the index pCk->pIdx.  We know that
@@ -158824,71 +161179,103 @@ struct CoveringIndexCheck {
**
** If this node does not disprove that the index can be a covering index,
** then just return WRC_Continue, to continue the search.
+
**
+
** If pCk->pIdx contains indexed expressions and one of those expressions
+
** matches pExpr, then prune the search.
*/
static int whereIsCoveringIndexWalkCallback(Walker *pWalk, Expr *pExpr){
-
  int i;                  /* Loop counter */
-
  const Index *pIdx;      /* The index of interest */
-
  const i16 *aiColumn;    /* Columns contained in the index */
-
  u16 nColumn;            /* Number of columns in the index */
-
  if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_AGG_COLUMN ) return WRC_Continue;
-
  if( pExpr->iColumn<(BMS-1) ) return WRC_Continue;
-
  if( pExpr->iTable!=pWalk->u.pCovIdxCk->iTabCur ) return WRC_Continue;
-
  pIdx = pWalk->u.pCovIdxCk->pIdx;
-
  aiColumn = pIdx->aiColumn;
-
  nColumn = pIdx->nColumn;
-
  for(i=0; i<nColumn; i++){
-
    if( aiColumn[i]==pExpr->iColumn ) return WRC_Continue;
-
  }
-
  pWalk->eCode = 1;
-
  return WRC_Abort;
+
  int i;                    /* Loop counter */
+
  const Index *pIdx;        /* The index of interest */
+
  const i16 *aiColumn;      /* Columns contained in the index */
+
  u16 nColumn;              /* Number of columns in the index */
+
  CoveringIndexCheck *pCk;  /* Info about this search */
+

+
  pCk = pWalk->u.pCovIdxCk;
+
  pIdx = pCk->pIdx;
+
  if( (pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN) ){
+
    /* if( pExpr->iColumn<(BMS-1) && pIdx->bHasExpr==0 ) return WRC_Continue;*/
+
    if( pExpr->iTable!=pCk->iTabCur ) return WRC_Continue;
+
    pIdx = pWalk->u.pCovIdxCk->pIdx;
+
    aiColumn = pIdx->aiColumn;
+
    nColumn = pIdx->nColumn;
+
    for(i=0; i<nColumn; i++){
+
      if( aiColumn[i]==pExpr->iColumn ) return WRC_Continue;
+
    }
+
    pCk->bUnidx = 1;
+
    return WRC_Abort;
+
  }else if( pIdx->bHasExpr
+
         && exprIsCoveredByIndex(pExpr, pIdx, pWalk->u.pCovIdxCk->iTabCur) ){
+
    pCk->bExpr = 1;
+
    return WRC_Prune;
+
  }
+
  return WRC_Continue;
}


/*
** pIdx is an index that covers all of the low-number columns used by
-
** pWInfo->pSelect (columns from 0 through 62).  But there are columns
-
** in pWInfo->pSelect beyond 62.  This routine tries to answer the question
-
** of whether pIdx covers *all* columns in the query.
+
** pWInfo->pSelect (columns from 0 through 62) or an index that has
+
** expressions terms.  Hence, we cannot determine whether or not it is
+
** a covering index by using the colUsed bitmasks.  We have to do a search
+
** to see if the index is covering.  This routine does that search.
**
-
** Return 0 if pIdx is a covering index.   Return non-zero if pIdx is
-
** not a covering index or if we are unable to determine if pIdx is a
-
** covering index.
+
** The return value is one of these:
**
-
** This routine is an optimization.  It is always safe to return non-zero.
-
** But returning zero when non-zero should have been returned can lead to
-
** incorrect bytecode and assertion faults.
+
**      0                The index is definitely not a covering index
+
**
+
**      WHERE_IDX_ONLY   The index is definitely a covering index
+
**
+
**      WHERE_EXPRIDX    The index is likely a covering index, but it is
+
**                       difficult to determine precisely because of the
+
**                       expressions that are indexed.  Score it as a
+
**                       covering index, but still keep the main table open
+
**                       just in case we need it.
+
**
+
** This routine is an optimization.  It is always safe to return zero.
+
** But returning one of the other two values when zero should have been
+
** returned can lead to incorrect bytecode and assertion faults.
*/
static SQLITE_NOINLINE u32 whereIsCoveringIndex(
  WhereInfo *pWInfo,     /* The WHERE clause context */
  Index *pIdx,           /* Index that is being tested */
  int iTabCur            /* Cursor for the table being indexed */
){
-
  int i;
+
  int i, rc;
  struct CoveringIndexCheck ck;
  Walker w;
  if( pWInfo->pSelect==0 ){
    /* We don't have access to the full query, so we cannot check to see
    ** if pIdx is covering.  Assume it is not. */
-
    return 1;
-
  }
-
  for(i=0; i<pIdx->nColumn; i++){
-
    if( pIdx->aiColumn[i]>=BMS-1 ) break;
+
    return 0;
  }
-
  if( i>=pIdx->nColumn ){
-
    /* pIdx does not index any columns greater than 62, but we know from
-
    ** colMask that columns greater than 62 are used, so this is not a
-
    ** covering index */
-
    return 1;
+
  if( pIdx->bHasExpr==0 ){
+
    for(i=0; i<pIdx->nColumn; i++){
+
      if( pIdx->aiColumn[i]>=BMS-1 ) break;
+
    }
+
    if( i>=pIdx->nColumn ){
+
      /* pIdx does not index any columns greater than 62, but we know from
+
      ** colMask that columns greater than 62 are used, so this is not a
+
      ** covering index */
+
      return 0;
+
    }
  }
  ck.pIdx = pIdx;
  ck.iTabCur = iTabCur;
+
  ck.bExpr = 0;
+
  ck.bUnidx = 0;
  memset(&w, 0, sizeof(w));
  w.xExprCallback = whereIsCoveringIndexWalkCallback;
  w.xSelectCallback = sqlite3SelectWalkNoop;
  w.u.pCovIdxCk = &ck;
-
  w.eCode = 0;
  sqlite3WalkSelect(&w, pWInfo->pSelect);
-
  return w.eCode;
+
  if( ck.bUnidx ){
+
    rc = 0;
+
  }else if( ck.bExpr ){
+
    rc = WHERE_EXPRIDX;
+
  }else{
+
    rc = WHERE_IDX_ONLY;
+
  }
+
  return rc;
}

/*
@@ -158973,7 +161360,7 @@ static int whereLoopAddBtree(
    sPk.aiRowLogEst = aiRowEstPk;
    sPk.onError = OE_Replace;
    sPk.pTable = pTab;
-
    sPk.szIdxRow = pTab->szTabRow;
+
    sPk.szIdxRow = 3;  /* TUNING: Interior rows of IPK table are very small */
    sPk.idxType = SQLITE_IDXTYPE_IPK;
    aiRowEstPk[0] = pTab->nRowLogEst;
    aiRowEstPk[1] = 0;
@@ -159024,7 +161411,8 @@ static int whereLoopAddBtree(
        if( !IsView(pTab) && (pTab->tabFlags & TF_Ephemeral)==0 ){
          pNew->rSetup += 28;
        }else{
-
          pNew->rSetup -= 10;
+
          pNew->rSetup -= 25;  /* Greatly reduced setup cost for auto indexes
+
                               ** on ephemeral materializations of views */
        }
        ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
        if( pNew->rSetup<0 ) pNew->rSetup = 0;
@@ -159104,14 +161492,38 @@ static int whereLoopAddBtree(
    }else{
      Bitmask m;
      if( pProbe->isCovering ){
-
        pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
        m = 0;
+
        pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
      }else{
        m = pSrc->colUsed & pProbe->colNotIdxed;
-
        if( m==TOPBIT ){
-
          m = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor);
+
        pNew->wsFlags = WHERE_INDEXED;
+
        if( m==TOPBIT || (pProbe->bHasExpr && !pProbe->bHasVCol && m!=0) ){
+
          u32 isCov = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor);
+
          if( isCov==0 ){
+
            WHERETRACE(0x200,
+
               ("-> %s is not a covering index"
+
                " according to whereIsCoveringIndex()\n", pProbe->zName));
+
            assert( m!=0 );
+
          }else{
+
            m = 0;
+
            pNew->wsFlags |= isCov;
+
            if( isCov & WHERE_IDX_ONLY ){
+
              WHERETRACE(0x200,
+
                 ("-> %s is a covering expression index"
+
                  " according to whereIsCoveringIndex()\n", pProbe->zName));
+
            }else{
+
              assert( isCov==WHERE_EXPRIDX );
+
              WHERETRACE(0x200,
+
                 ("-> %s might be a covering expression index"
+
                  " according to whereIsCoveringIndex()\n", pProbe->zName));
+
            }
+
          }
+
        }else if( m==0 ){
+
          WHERETRACE(0x200,
+
             ("-> %s a covering index according to bitmasks\n",
+
             pProbe->zName, m==0 ? "is" : "is not"));
+
          pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
        }
-
        pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
      }

      /* Full scan via index */
@@ -159284,7 +161696,7 @@ static int whereLoopAddVirtualOne(
      ** that the particular combination of parameters provided is unusable.
      ** Make no entries in the loop table.
      */
-
      WHERETRACE(0xffff, ("  ^^^^--- non-viable plan rejected!\n"));
+
      WHERETRACE(0xffffffff, ("  ^^^^--- non-viable plan rejected!\n"));
      return SQLITE_OK;
    }
    return rc;
@@ -159395,7 +161807,7 @@ static int whereLoopAddVirtualOne(
    sqlite3_free(pNew->u.vtab.idxStr);
    pNew->u.vtab.needFree = 0;
  }
-
  WHERETRACE(0xffff, ("  bIn=%d prereqIn=%04llx prereqOut=%04llx\n",
+
  WHERETRACE(0xffffffff, ("  bIn=%d prereqIn=%04llx prereqOut=%04llx\n",
                      *pbIn, (sqlite3_uint64)mPrereq,
                      (sqlite3_uint64)(pNew->prereq & ~mPrereq)));

@@ -159496,32 +161908,27 @@ SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){
  return pHidden->eDistinct;
}

-
#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
-
    && !defined(SQLITE_OMIT_VIRTUALTABLE)
/*
** Cause the prepared statement that is associated with a call to
-
** xBestIndex to potentiall use all schemas.  If the statement being
+
** xBestIndex to potentially 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 sqlite3VtabUsesAllSchemas(sqlite3_index_info *pIdxInfo){
-
  HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1];
-
  Parse *pParse = pHidden->pParse;
+
SQLITE_PRIVATE void sqlite3VtabUsesAllSchemas(Parse *pParse){
  int nDb = pParse->db->nDb;
  int i;
  for(i=0; i<nDb; i++){
    sqlite3CodeVerifySchema(pParse, i);
  }
-
  if( pParse->writeMask ){
+
  if( DbMaskNonZero(pParse->writeMask) ){
    for(i=0; i<nDb; i++){
      sqlite3BeginWriteOperation(pParse, 0, i);
    }
  }
}
-
#endif

/*
** Add all WhereLoop objects for a table of the join identified by
@@ -159587,7 +161994,7 @@ static int whereLoopAddVirtual(

  /* First call xBestIndex() with all constraints usable. */
  WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
-
  WHERETRACE(0x40, ("  VirtualOne: all usable\n"));
+
  WHERETRACE(0x800, ("  VirtualOne: all usable\n"));
  rc = whereLoopAddVirtualOne(
      pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry
  );
@@ -159612,7 +162019,7 @@ static int whereLoopAddVirtual(
    /* If the plan produced by the earlier call uses an IN(...) term, call
    ** xBestIndex again, this time with IN(...) terms disabled. */
    if( bIn ){
-
      WHERETRACE(0x40, ("  VirtualOne: all usable w/o IN\n"));
+
      WHERETRACE(0x800, ("  VirtualOne: all usable w/o IN\n"));
      rc = whereLoopAddVirtualOne(
          pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0);
      assert( bIn==0 );
@@ -159638,7 +162045,7 @@ static int whereLoopAddVirtual(
      mPrev = mNext;
      if( mNext==ALLBITS ) break;
      if( mNext==mBest || mNext==mBestNoIn ) continue;
-
      WHERETRACE(0x40, ("  VirtualOne: mPrev=%04llx mNext=%04llx\n",
+
      WHERETRACE(0x800, ("  VirtualOne: mPrev=%04llx mNext=%04llx\n",
                       (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
      rc = whereLoopAddVirtualOne(
          pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn, 0);
@@ -159652,7 +162059,7 @@ static int whereLoopAddVirtual(
    ** that requires no source tables at all (i.e. one guaranteed to be
    ** usable), make a call here with all source tables disabled */
    if( rc==SQLITE_OK && seenZero==0 ){
-
      WHERETRACE(0x40, ("  VirtualOne: all disabled\n"));
+
      WHERETRACE(0x800, ("  VirtualOne: all disabled\n"));
      rc = whereLoopAddVirtualOne(
          pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0);
      if( bIn==0 ) seenZeroNoIN = 1;
@@ -159662,7 +162069,7 @@ static int whereLoopAddVirtual(
    ** that requires no source tables at all and does not use an IN(...)
    ** operator, make a final call to obtain one here.  */
    if( rc==SQLITE_OK && seenZeroNoIN==0 ){
-
      WHERETRACE(0x40, ("  VirtualOne: all disabled and w/o IN\n"));
+
      WHERETRACE(0x800, ("  VirtualOne: all disabled and w/o IN\n"));
      rc = whereLoopAddVirtualOne(
          pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0);
    }
@@ -159718,7 +162125,7 @@ static int whereLoopAddOr(
      sSubBuild = *pBuilder;
      sSubBuild.pOrSet = &sCur;

-
      WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
+
      WHERETRACE(0x400, ("Begin processing OR-clause %p\n", pTerm));
      for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
        if( (pOrTerm->eOperator & WO_AND)!=0 ){
          sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
@@ -159735,9 +162142,9 @@ static int whereLoopAddOr(
        }
        sCur.n = 0;
#ifdef WHERETRACE_ENABLED
-
        WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n",
+
        WHERETRACE(0x400, ("OR-term %d of %p has %d subterms:\n",
                   (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm));
-
        if( sqlite3WhereTrace & 0x400 ){
+
        if( sqlite3WhereTrace & 0x20000 ){
          sqlite3WhereClausePrint(sSubBuild.pWC);
        }
#endif
@@ -159752,8 +162159,6 @@ static int whereLoopAddOr(
        if( rc==SQLITE_OK ){
          rc = whereLoopAddOr(&sSubBuild, mPrereq, mUnusable);
        }
-
        assert( rc==SQLITE_OK || rc==SQLITE_DONE || sCur.n==0
-
                || rc==SQLITE_NOMEM );
        testcase( rc==SQLITE_NOMEM && sCur.n>0 );
        testcase( rc==SQLITE_DONE );
        if( sCur.n==0 ){
@@ -159799,7 +162204,7 @@ static int whereLoopAddOr(
        pNew->prereq = sSum.a[i].prereq;
        rc = whereLoopInsert(pBuilder, pNew);
      }
-
      WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm));
+
      WHERETRACE(0x400, ("End processing OR-clause %p\n", pTerm));
    }
  }
  return rc;
@@ -160147,8 +162552,8 @@ static i8 wherePathSatisfiesOrderBy(
            if( pOBExpr->iTable!=iCur ) continue;
            if( pOBExpr->iColumn!=iColumn ) continue;
          }else{
-
            Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr;
-
            if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){
+
            Expr *pIxExpr = pIndex->aColExpr->a[j].pExpr;
+
            if( sqlite3ExprCompareSkip(pOBExpr, pIxExpr, iCur) ){
              continue;
            }
          }
@@ -160280,37 +162685,56 @@ static const char *wherePathName(WherePath *pPath, int nLoop, WhereLoop *pLast){
** order.
*/
static LogEst whereSortingCost(
-
  WhereInfo *pWInfo,
-
  LogEst nRow,
-
  int nOrderBy,
-
  int nSorted
+
  WhereInfo *pWInfo, /* Query planning context */
+
  LogEst nRow,       /* Estimated number of rows to sort */
+
  int nOrderBy,      /* Number of ORDER BY clause terms */
+
  int nSorted        /* Number of initial ORDER BY terms naturally in order */
){
-
  /* TUNING: Estimated cost of a full external sort, where N is
+
  /* Estimated cost of a full external sort, where N is
  ** the number of rows to sort is:
  **
-
  **   cost = (3.0 * N * log(N)).
+
  **   cost = (K * N * log(N)).
  **
  ** Or, if the order-by clause has X terms but only the last Y
  ** terms are out of order, then block-sorting will reduce the
  ** sorting cost to:
  **
-
  **   cost = (3.0 * N * log(N)) * (Y/X)
+
  **   cost = (K * N * log(N)) * (Y/X)
  **
-
  ** The (Y/X) term is implemented using stack variable rScale
-
  ** below.
+
  ** The constant K is at least 2.0 but will be larger if there are a
+
  ** large number of columns to be sorted, as the sorting time is
+
  ** proportional to the amount of content to be sorted.  The algorithm
+
  ** does not currently distinguish between fat columns (BLOBs and TEXTs)
+
  ** and skinny columns (INTs).  It just uses the number of columns as
+
  ** an approximation for the row width.
+
  **
+
  ** And extra factor of 2.0 or 3.0 is added to the sorting cost if the sort
+
  ** is built using OP_IdxInsert and OP_Sort rather than with OP_SorterInsert.
  */
-
  LogEst rScale, rSortCost;
-
  assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
-
  rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
-
  rSortCost = nRow + rScale + 16;
+
  LogEst rSortCost, nCol;
+
  assert( pWInfo->pSelect!=0 );
+
  assert( pWInfo->pSelect->pEList!=0 );
+
  /* TUNING: sorting cost proportional to the number of output columns: */
+
  nCol = sqlite3LogEst((pWInfo->pSelect->pEList->nExpr+59)/30);
+
  rSortCost = nRow + nCol;
+
  if( nSorted>0 ){
+
    /* Scale the result by (Y/X) */
+
    rSortCost += sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
+
  }

  /* Multiple by log(M) where M is the number of output rows.
  ** Use the LIMIT for M if it is smaller.  Or if this sort is for
  ** a DISTINCT operator, M will be the number of distinct output
  ** rows, so fudge it downwards a bit.
  */
-
  if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
-
    nRow = pWInfo->iLimit;
+
  if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){
+
    rSortCost += 10;       /* TUNING: Extra 2.0x if using LIMIT */
+
    if( nSorted!=0 ){
+
      rSortCost += 6;      /* TUNING: Extra 1.5x if also using partial sort */
+
    }
+
    if( pWInfo->iLimit<nRow ){
+
      nRow = pWInfo->iLimit;
+
    }
  }else if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT) ){
    /* TUNING: In the sort for a DISTINCT operator, assume that the DISTINCT
    ** reduces the number of output rows by a factor of 2 */
@@ -160462,11 +162886,11 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
                pWInfo, nRowEst, nOrderBy, isOrdered
            );
          }
-
          /* TUNING:  Add a small extra penalty (5) to sorting as an
+
          /* TUNING:  Add a small extra penalty (3) to sorting as an
          ** extra encouragment to the query planner to select a plan
          ** where the rows emerge in the correct order without any sorting
          ** required. */
-
          rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5;
+
          rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 3;

          WHERETRACE(0x002,
              ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
@@ -160670,6 +163094,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
      if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){
        pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
      }
+
      if( pWInfo->pSelect->pOrderBy
+
       && pWInfo->nOBSat > pWInfo->pSelect->pOrderBy->nExpr ){
+
        pWInfo->nOBSat = pWInfo->pSelect->pOrderBy->nExpr;
+
      }
    }else{
      pWInfo->revMask = pFrom->revLoop;
      if( pWInfo->nOBSat<=0 ){
@@ -160814,7 +163242,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
    pLoop->cId = '0';
#endif
#ifdef WHERETRACE_ENABLED
-
    if( sqlite3WhereTrace ){
+
    if( sqlite3WhereTrace & 0x02 ){
      sqlite3DebugPrintf("whereShortCut() used to compute solution\n");
    }
#endif
@@ -160881,6 +163309,13 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){
**      at most a single row.
**   4) The table must not be referenced by any part of the query apart
**      from its own USING or ON clause.
+
**   5) The table must not have an inner-join ON or USING clause if there is
+
**      a RIGHT JOIN anywhere in the query.  Otherwise the ON/USING clause
+
**      might move from the right side to the left side of the RIGHT JOIN.
+
**      Note: Due to (2), this condition can only arise if the table is
+
**      the right-most table of a subquery that was flattened into the
+
**      main query and that subquery was the right-hand operand of an
+
**      inner join that held an ON or USING clause.
**
** For example, given:
**
@@ -160906,6 +163341,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
){
  int i;
  Bitmask tabUsed;
+
  int hasRightJoin;

  /* Preconditions checked by the caller */
  assert( pWInfo->nLevel>=2 );
@@ -160920,6 +163356,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
  if( pWInfo->pOrderBy ){
    tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy);
  }
+
  hasRightJoin = (pWInfo->pTabList->a[0].fg.jointype & JT_LTORJ)!=0;
  for(i=pWInfo->nLevel-1; i>=1; i--){
    WhereTerm *pTerm, *pEnd;
    SrcItem *pItem;
@@ -160942,9 +163379,15 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
          break;
        }
      }
+
      if( hasRightJoin
+
       && ExprHasProperty(pTerm->pExpr, EP_InnerON)
+
       && pTerm->pExpr->w.iJoin==pItem->iCursor
+
      ){
+
        break;  /* restriction (5) */
+
      }
    }
    if( pTerm<pEnd ) continue;
-
    WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
+
    WHERETRACE(0xffffffff, ("-> drop loop %c not used\n", pLoop->cId));
    notReady &= ~pLoop->maskSelf;
    for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
      if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
@@ -160983,28 +163426,27 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful(
  const WhereInfo *pWInfo
){
  int i;
-
  LogEst nSearch;
+
  LogEst nSearch = 0;

  assert( pWInfo->nLevel>=2 );
  assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) );
-
  nSearch = pWInfo->a[0].pWLoop->nOut;
-
  for(i=1; i<pWInfo->nLevel; i++){
+
  for(i=0; i<pWInfo->nLevel; i++){
    WhereLoop *pLoop = pWInfo->a[i].pWLoop;
    const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ);
-
    if( (pLoop->wsFlags & reqFlags)==reqFlags
+
    SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab];
+
    Table *pTab = pItem->pTab;
+
    if( (pTab->tabFlags & TF_HasStat1)==0 ) break;
+
    pTab->tabFlags |= TF_StatsUsed;
+
    if( i>=1
+
     && (pLoop->wsFlags & reqFlags)==reqFlags
     /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */
     && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0)
    ){
-
      SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab];
-
      Table *pTab = pItem->pTab;
-
      pTab->tabFlags |= TF_StatsUsed;
-
      if( nSearch > pTab->nRowLogEst
-
       && (pTab->tabFlags & TF_HasStat1)!=0
-
      ){
+
      if( nSearch > pTab->nRowLogEst ){
        testcase( pItem->fg.jointype & JT_LEFT );
        pLoop->wsFlags |= WHERE_BLOOMFILTER;
        pLoop->wsFlags &= ~WHERE_IDX_ONLY;
-
        WHERETRACE(0xffff, (
+
        WHERETRACE(0xffffffff, (
           "-> use Bloom-filter on loop %c because there are ~%.1e "
           "lookups into %s which has only ~%.1e rows\n",
           pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName,
@@ -161017,13 +163459,13 @@ static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful(

/*
** This is an sqlite3ParserAddCleanup() callback that is invoked to
-
** free the Parse->pIdxExpr list when the Parse object is destroyed.
+
** free the Parse->pIdxEpr list when the Parse object is destroyed.
*/
static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){
  Parse *pParse = (Parse*)pObject;
-
  while( pParse->pIdxExpr!=0 ){
-
    IndexedExpr *p = pParse->pIdxExpr;
-
    pParse->pIdxExpr = p->pIENext;
+
  while( pParse->pIdxEpr!=0 ){
+
    IndexedExpr *p = pParse->pIdxEpr;
+
    pParse->pIdxEpr = p->pIENext;
    sqlite3ExprDelete(db, p->pExpr);
    sqlite3DbFreeNN(db, p);
  }
@@ -161035,13 +163477,13 @@ static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){
** number for the index and iDataCur is the cursor number for the corresponding
** table.
**
-
** This routine adds IndexedExpr entries to the Parse->pIdxExpr field for
+
** This routine adds IndexedExpr entries to the Parse->pIdxEpr field for
** each of the expressions in the index so that the expression code generator
** will know to replace occurrences of the indexed expression with
** references to the corresponding column of the index.
*/
static SQLITE_NOINLINE void whereAddIndexedExpr(
-
  Parse *pParse,     /* Add IndexedExpr entries to pParse->pIdxExpr */
+
  Parse *pParse,     /* Add IndexedExpr entries to pParse->pIdxEpr */
  Index *pIdx,       /* The index-on-expression that contains the expressions */
  int iIdxCur,       /* Cursor number for pIdx */
  SrcItem *pTabItem  /* The FROM clause entry for the table */
@@ -161070,16 +163512,25 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
    if( sqlite3ExprIsConstant(pExpr) ) continue;
    p = sqlite3DbMallocRaw(pParse->db,  sizeof(IndexedExpr));
    if( p==0 ) break;
-
    p->pIENext = pParse->pIdxExpr;
+
    p->pIENext = pParse->pIdxEpr;
+
#ifdef WHERETRACE_ENABLED
+
    if( sqlite3WhereTrace & 0x200 ){
+
      sqlite3DebugPrintf("New pParse->pIdxEpr term {%d,%d}\n", iIdxCur, i);
+
      if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr);
+
    }
+
#endif
    p->pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
    p->iDataCur = pTabItem->iCursor;
    p->iIdxCur = iIdxCur;
    p->iIdxCol = i;
    p->bMaybeNullRow = bMaybeNullRow;
+
    if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){
+
      p->aff = pIdx->zColAff[i];
+
    }
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
    p->zIdxName = pIdx->zName;
#endif
-
    pParse->pIdxExpr = p;
+
    pParse->pIdxEpr = p;
    if( p->pIENext==0 ){
      sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse);
    }
@@ -161333,22 +163784,45 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
  }
  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
-
  ** generated code if the result is not true.
+
  /* The False-WHERE-Term-Bypass optimization:
+
  **
+
  ** If there are WHERE terms that are false, then no rows will be output,
+
  ** so skip over all of the code generated here.
+
  **
+
  ** Conditions:
+
  **
+
  **   (1)  The WHERE term must not refer to any tables in the join.
+
  **   (2)  The term must not come from an ON clause on the
+
  **        right-hand side of a LEFT or FULL JOIN.
+
  **   (3)  The term must not come from an ON clause, or there must be
+
  **        no RIGHT or FULL OUTER joins in pTabList.
+
  **   (4)  If the expression contains non-deterministic functions
+
  **        that are not within a sub-select. This is not required
+
  **        for correctness but rather to preserves SQLite's legacy
+
  **        behaviour in the following two cases:
  **
-
  ** Do not do this if the expression contains non-deterministic functions
-
  ** that are not within a sub-select. This is not strictly required, but
-
  ** preserves SQLite's legacy behaviour in the following two cases:
+
  **          WHERE random()>0;           -- eval random() once per row
+
  **          WHERE (SELECT random())>0;  -- eval random() just once overall
  **
-
  **   FROM ... WHERE random()>0;           -- eval random() once per row
-
  **   FROM ... WHERE (SELECT random())>0;  -- eval random() once overall
+
  ** Note that the Where term need not be a constant in order for this
+
  ** optimization to apply, though it does need to be constant relative to
+
  ** the current subquery (condition 1).  The term might include variables
+
  ** from outer queries so that the value of the term changes from one
+
  ** invocation of the current subquery to the next.
  */
  for(ii=0; ii<sWLB.pWC->nBase; ii++){
-
    WhereTerm *pT = &sWLB.pWC->a[ii];
+
    WhereTerm *pT = &sWLB.pWC->a[ii];  /* A term of the WHERE clause */
+
    Expr *pX;                          /* The expression of pT */
    if( pT->wtFlags & TERM_VIRTUAL ) continue;
-
    if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
-
      sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL);
+
    pX = pT->pExpr;
+
    assert( pX!=0 );
+
    assert( pT->prereqAll!=0 || !ExprHasProperty(pX, EP_OuterON) );
+
    if( pT->prereqAll==0                           /* Conditions (1) and (2) */
+
     && (nTabList==0 || exprIsDeterministic(pX))   /* Condition (4) */
+
     && !(ExprHasProperty(pX, EP_InnerON)          /* Condition (3) */
+
          && (pTabList->a[0].fg.jointype & JT_LTORJ)!=0 )
+
    ){
+
      sqlite3ExprIfFalse(pParse, pX, pWInfo->iBreak, SQLITE_JUMPIFNULL);
      pT->wtFlags |= TERM_CODED;
    }
  }
@@ -161371,13 +163845,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(

  /* Construct the WhereLoop objects */
#if defined(WHERETRACE_ENABLED)
-
  if( sqlite3WhereTrace & 0xffff ){
+
  if( sqlite3WhereTrace & 0xffffffff ){
    sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags);
    if( wctrlFlags & WHERE_USE_LIMIT ){
      sqlite3DebugPrintf(", limit: %d", iAuxArg);
    }
    sqlite3DebugPrintf(")\n");
-
    if( sqlite3WhereTrace & 0x100 ){
+
    if( sqlite3WhereTrace & 0x8000 ){
      Select sSelect;
      memset(&sSelect, 0, sizeof(sSelect));
      sSelect.selFlags = SF_WhereBegin;
@@ -161387,10 +163861,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
      sSelect.pEList = pResultSet;
      sqlite3TreeViewSelect(0, &sSelect, 0);
    }
-
  }
-
  if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
-
    sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n");
-
    sqlite3WhereClausePrint(sWLB.pWC);
+
    if( sqlite3WhereTrace & 0x4000 ){ /* Display all WHERE clause terms */
+
      sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n");
+
      sqlite3WhereClausePrint(sWLB.pWC);
+
    }
  }
#endif

@@ -161406,7 +163880,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
    ** loops will be built using the revised truthProb values. */
    if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){
      WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC);
-
      WHERETRACE(0xffff,
+
      WHERETRACE(0xffffffff,
           ("**** Redo all loop computations due to"
            " TERM_HIGHTRUTH changes ****\n"));
      while( pWInfo->pLoops ){
@@ -161492,11 +163966,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
  }

#if defined(WHERETRACE_ENABLED)
-
  if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
+
  if( sqlite3WhereTrace & 0x4000 ){ /* Display all terms of the WHERE clause */
    sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n");
    sqlite3WhereClausePrint(sWLB.pWC);
  }
-
  WHERETRACE(0xffff,("*** Optimizer Finished ***\n"));
+
  WHERETRACE(0xffffffff,("*** Optimizer Finished ***\n"));
#endif
  pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;

@@ -161591,7 +164065,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
        assert( n<=pTab->nCol );
      }
#ifdef SQLITE_ENABLE_CURSOR_HINTS
-
      if( pLoop->u.btree.pIndex!=0 ){
+
      if( pLoop->u.btree.pIndex!=0 && (pTab->tabFlags & TF_WithoutRowid)==0 ){
        sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete);
      }else
#endif
@@ -161728,11 +164202,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
        sqlite3VdbeJumpHere(v, iOnce);
      }
    }
+
    assert( pTabList == pWInfo->pTabList );
    if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
      if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
-
        constructAutomaticIndex(pParse, &pWInfo->sWC,
-
                  &pTabList->a[pLevel->iFrom], notReady, pLevel);
+
        constructAutomaticIndex(pParse, &pWInfo->sWC, notReady, pLevel);
#endif
      }else{
        sqlite3ConstructBloomFilter(pWInfo, ii, pLevel, notReady);
@@ -162030,9 +164504,16 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
        last = pWInfo->iEndWhere;
      }
      if( pIdx->bHasExpr ){
-
        IndexedExpr *p = pParse->pIdxExpr;
+
        IndexedExpr *p = pParse->pIdxEpr;
        while( p ){
          if( p->iIdxCur==pLevel->iIdxCur ){
+
#ifdef WHERETRACE_ENABLED
+
            if( sqlite3WhereTrace & 0x200 ){
+
              sqlite3DebugPrintf("Disable pParse->pIdxEpr term {%d,%d}\n",
+
                                  p->iIdxCur, p->iIdxCol);
+
              if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(p->pExpr);
+
            }
+
#endif
            p->iDataCur = -1;
            p->iIdxCur = -1;
          }
@@ -162042,7 +164523,8 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
      k = pLevel->addrBody + 1;
#ifdef SQLITE_DEBUG
      if( db->flags & SQLITE_VdbeAddopTrace ){
-
        printf("TRANSLATE opcodes in range %d..%d\n", k, last-1);
+
        printf("TRANSLATE cursor %d->%d in opcode range %d..%d\n",
+
                pLevel->iTabCur, pLevel->iIdxCur, k, last-1);
      }
      /* Proof that the "+1" on the k value above is safe */
      pOp = sqlite3VdbeGetOp(v, k - 1);
@@ -162917,6 +165399,7 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){
      }
      /* no break */ deliberate_fall_through

+
    case TK_IF_NULL_ROW:
    case TK_AGG_FUNCTION:
    case TK_COLUMN: {
      int iCol = -1;
@@ -163201,7 +165684,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
    pSub = sqlite3SelectNew(
        pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
    );
-
    SELECTTRACE(1,pParse,pSub,
+
    TREETRACE(0x40,pParse,pSub,
       ("New window-function subquery in FROM clause of (%u/%p)\n",
       p->selId, p));
    p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
@@ -163211,6 +165694,7 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){
    if( p->pSrc ){
      Table *pTab2;
      p->pSrc->a[0].pSelect = pSub;
+
      p->pSrc->a[0].fg.isCorrelated = 1;
      sqlite3SrcListAssignCursors(pParse, p->pSrc);
      pSub->selFlags |= SF_Expanded|SF_OrderByReqd;
      pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
@@ -165076,8 +167560,7 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep(
    VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */
    VdbeCoverageNeverNullIf(v, op==OP_Le); /*   values previously checked */
    windowAggFinal(&s, 0);
-
    sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
-
    VdbeCoverageNeverTaken(v);
+
    sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr);
    windowReturnOneRow(&s);
    sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
@@ -165089,13 +167572,10 @@ SQLITE_PRIVATE void sqlite3WindowCodeStep(
  }

  if( pMWin->eStart!=TK_UNBOUNDED ){
-
    sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1);
-
    VdbeCoverageNeverTaken(v);
+
    sqlite3VdbeAddOp1(v, OP_Rewind, s.start.csr);
  }
-
  sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
-
  VdbeCoverageNeverTaken(v);
-
  sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1);
-
  VdbeCoverageNeverTaken(v);
+
  sqlite3VdbeAddOp1(v, OP_Rewind, s.current.csr);
+
  sqlite3VdbeAddOp1(v, OP_Rewind, s.end.csr);
  if( regPeer && pOrderBy ){
    sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1);
    sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1);
@@ -165748,18 +168228,18 @@ typedef union {
#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse;
#define sqlite3ParserCTX_STORE yypParser->pParse=pParse;
#define YYFALLBACK 1
-
#define YYNSTATE             576
-
#define YYNRULE              405
-
#define YYNRULE_WITH_ACTION  342
+
#define YYNSTATE             575
+
#define YYNRULE              403
+
#define YYNRULE_WITH_ACTION  340
#define YYNTOKEN             185
-
#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
+
#define YY_MAX_SHIFT         574
+
#define YY_MIN_SHIFTREDUCE   833
+
#define YY_MAX_SHIFTREDUCE   1235
+
#define YY_ERROR_ACTION      1236
+
#define YY_ACCEPT_ACTION     1237
+
#define YY_NO_ACTION         1238
+
#define YY_MIN_REDUCE        1239
+
#define YY_MAX_REDUCE        1641
/************* End control #defines *******************************************/
#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])))

@@ -165826,218 +168306,218 @@ typedef union {
**  yy_default[]       Default action for each state.
**
*********** Begin parsing tables **********************************************/
-
#define YY_ACTTAB_COUNT (2098)
+
#define YY_ACTTAB_COUNT (2096)
static const YYACTIONTYPE yy_action[] = {
 /*     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,
+
 /*    10 */   568, 1310,  377, 1289,  408,  562,  562,  562,  568,  409,
+
 /*    20 */   378, 1310, 1272,   41,   41,   41,   41,  208, 1520,   71,
+
 /*    30 */    71,  969,  419,   41,   41,  491,  303,  279,  303,  970,
+
 /*    40 */   397,   71,   71,  125,  126,   80, 1212, 1212, 1047, 1050,
+
 /*    50 */  1037, 1037,  123,  123,  124,  124,  124,  124,  476,  409,
+
 /*    60 */  1237,    1,    1,  574,    2, 1241,  550,  118,  115,  229,
+
 /*    70 */   317,  480,  146,  480,  524,  118,  115,  229,  529, 1323,
+
 /*    80 */   417,  523,  142,  125,  126,   80, 1212, 1212, 1047, 1050,
+
 /*    90 */  1037, 1037,  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,
+
 /*   120 */   442, 1561,  376, 1563, 1188,  375, 1159,  565, 1159,  565,
+
 /*   130 */   409, 1561,  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,
+
 /*   150 */   120,  119,  116,  444,  125,  126,   80, 1212, 1212, 1047,
+
 /*   160 */  1050, 1037, 1037,  123,  123,  124,  124,  124,  124,  142,
+
 /*   170 */   294, 1188,  339,  448,  120,  120,  120,  119,  116,  444,
+
 /*   180 */   127, 1188, 1189, 1188,  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,
+
 /*   220 */   120,  120,  119,  116,  444,  422,  316,  559, 1188, 1189,
+
 /*   230 */  1188,  149, 1220,  409, 1220,  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,
+
 /*   250 */   444,  465,  342, 1034, 1034, 1048, 1051,  125,  126,   80,
+
 /*   260 */  1212, 1212, 1047, 1050, 1037, 1037,  123,  123,  124,  124,
+
 /*   270 */   124,  124, 1275,  522,  222, 1188,  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,
+
 /*   290 */   120,  120,  119,  116,  444, 1005,   16,   16, 1188,  133,
+
 /*   300 */   133,  125,  126,   80, 1212, 1212, 1047, 1050, 1037, 1037,
 /*   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,
+
 /*   320 */   121,  121,  120,  120,  120,  119,  116,  444, 1038,  546,
+
 /*   330 */  1188,  373, 1188, 1189, 1188,  252, 1429,  399,  504,  501,
+
 /*   340 */   500,  111,  560,  566,    4,  924,  924,  433,  499,  340,
+
 /*   350 */   460,  328,  360,  394, 1233, 1188, 1189, 1188,  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,
+
 /*   370 */   116,  444,  284,  284,  369, 1574, 1600,  441,  440,  154,
+
 /*   380 */   409,  445,   71,   71, 1282,  565, 1217, 1188, 1189, 1188,
+
 /*   390 */    85, 1219,  271,  557,  543,  515, 1555,  568,   98, 1218,
+
 /*   400 */     6, 1274,  472,  142,  125,  126,   80, 1212, 1212, 1047,
+
 /*   410 */  1050, 1037, 1037,  123,  123,  124,  124,  124,  124,  550,
+
 /*   420 */    13,   13, 1024,  507, 1220, 1188, 1220,  549,  109,  109,
+
 /*   430 */   222,  568, 1234,  175,  568,  427,  110,  197,  445,  569,
+
 /*   440 */   445,  430, 1546, 1014,  325,  551, 1188,  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,
+
 /*   460 */   316,  559, 1606,  122,  122,  122,  122,  121,  121,  120,
+
 /*   470 */   120,  120,  119,  116,  444, 1014, 1014, 1016, 1017,   27,
+
 /*   480 */   284,  284, 1188, 1189, 1188, 1154,  568, 1605,  409,  899,
+
 /*   490 */   190,  550,  356,  565,  550,  935,  533,  517, 1154,  516,
+
 /*   500 */   413, 1154,  552, 1188, 1189, 1188,  568,  544, 1548,   51,
+
 /*   510 */    51,  214,  125,  126,   80, 1212, 1212, 1047, 1050, 1037,
+
 /*   520 */  1037,  123,  123,  124,  124,  124,  124, 1188,  474,  135,
+
 /*   530 */   135,  409,  284,  284, 1484,  505,  121,  121,  120,  120,
+
 /*   540 */   120,  119,  116,  444, 1005,  565,  518,  217,  541, 1555,
+
 /*   550 */   316,  559,  142,    6,  532,  125,  126,   80, 1212, 1212,
+
 /*   560 */  1047, 1050, 1037, 1037,  123,  123,  124,  124,  124,  124,
+
 /*   570 */  1549,  122,  122,  122,  122,  121,  121,  120,  120,  120,
+
 /*   580 */   119,  116,  444,  485, 1188, 1189, 1188,  482,  281, 1263,
+
 /*   590 */   955,  252, 1188,  373,  504,  501,  500, 1188,  340,  570,
+
 /*   600 */  1188,  570,  409,  292,  499,  955,  874,  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,
+
 /*   620 */   120,  120,  120,  119,  116,  444,  125,  126,   80, 1212,
+
 /*   630 */  1212, 1047, 1050, 1037, 1037,  123,  123,  124,  124,  124,
+
 /*   640 */   124,  409,  394, 1132, 1188,  867,  100,  284,  284, 1188,
+
 /*   650 */  1189, 1188,  373, 1089, 1188, 1189, 1188, 1188, 1189, 1188,
+
 /*   660 */   565,  455,   32,  373,  233,  125,  126,   80, 1212, 1212,
+
 /*   670 */  1047, 1050, 1037, 1037,  123,  123,  124,  124,  124,  124,
+
 /*   680 */  1428,  957,  568,  228,  956,  122,  122,  122,  122,  121,
+
 /*   690 */   121,  120,  120,  120,  119,  116,  444, 1154,  228, 1188,
+
 /*   700 */   157, 1188, 1189, 1188, 1547,   13,   13,  301,  955, 1228,
+
 /*   710 */  1154,  153,  409, 1154,  373, 1577, 1172,    5,  369, 1574,
+
 /*   720 */   429, 1234,    3,  955,  122,  122,  122,  122,  121,  121,
+
 /*   730 */   120,  120,  120,  119,  116,  444,  125,  126,   80, 1212,
+
 /*   740 */  1212, 1047, 1050, 1037, 1037,  123,  123,  124,  124,  124,
+
 /*   750 */   124,  409,  208,  567, 1188, 1025, 1188, 1189, 1188, 1188,
+
 /*   760 */   388,  850,  155, 1546,  286,  402, 1094, 1094,  488,  568,
+
 /*   770 */   465,  342, 1315, 1315, 1546,  125,  126,   80, 1212, 1212,
+
 /*   780 */  1047, 1050, 1037, 1037,  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,
+
 /*   810 */   528, 1188, 1189, 1188,   13,   13, 1188, 1189, 1188, 1293,
+
 /*   820 */   463, 1263,  409, 1313, 1313, 1546, 1010,  453,  452,  200,
+
 /*   830 */   299,   71,   71, 1261,  122,  122,  122,  122,  121,  121,
+
 /*   840 */   120,  120,  120,  119,  116,  444,  125,  126,   80, 1212,
+
 /*   850 */  1212, 1047, 1050, 1037, 1037,  123,  123,  124,  124,  124,
+
 /*   860 */   124,  409,  227, 1069, 1154,  284,  284,  419,  312,  278,
+
 /*   870 */   278,  285,  285, 1415,  406,  405,  382, 1154,  565,  568,
+
 /*   880 */  1154, 1191,  565, 1594,  565,  125,  126,   80, 1212, 1212,
+
 /*   890 */  1047, 1050, 1037, 1037,  123,  123,  124,  124,  124,  124,
+
 /*   900 */   453, 1476,   13,   13, 1530,  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,
+
 /*   920 */  1580,  574,    2, 1241,  838,  839,  840, 1556,  317, 1207,
+
 /*   930 */   146,    6,  409,  255,  254,  253,  206, 1323,    9, 1191,
 /*   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,
+
 /*   950 */   120,  120,  120,  119,  116,  444,  125,  126,   80, 1212,
+
 /*   960 */  1212, 1047, 1050, 1037, 1037,  123,  123,  124,  124,  124,
+
 /*   970 */   124,  568,  284,  284,  568, 1208,  409,  573,  313, 1241,
+
 /*   980 */   349, 1292,  352,  419,  317,  565,  146,  491,  525, 1637,
+
 /*   990 */   395,  371,  491, 1323,   70,   70, 1291,   71,   71,  240,
+
 /*  1000 */  1321,  104,   80, 1212, 1212, 1047, 1050, 1037, 1037,  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,
+
 /*  1020 */   121,  120,  120,  120,  119,  116,  444, 1110,  284,  284,
+
 /*  1030 */   428,  448, 1519, 1208,  439,  284,  284, 1483, 1348,  311,
+
 /*  1040 */   474,  565, 1111,  969,  491,  491,  217, 1259,  565, 1532,
+
 /*  1050 */   568,  970,  207,  568, 1024,  240,  383, 1112,  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,
+
 /*  1070 */   444, 1015,  107,   71,   71, 1014,   13,   13,  910,  568,
+
 /*  1080 */  1489,  568,  284,  284,   97,  526,  491,  448,  911, 1322,
+
 /*  1090 */  1318,  545,  409,  284,  284,  565,  151,  209, 1489, 1491,
+
 /*  1100 */   262,  450,   55,   55,   56,   56,  565, 1014, 1014, 1016,
+
 /*  1110 */   443,  332,  409,  527,   12,  295,  125,  126,   80, 1212,
+
 /*  1120 */  1212, 1047, 1050, 1037, 1037,  123,  123,  124,  124,  124,
+
 /*  1130 */   124,  347,  409,  862, 1528, 1208,  125,  126,   80, 1212,
+
 /*  1140 */  1212, 1047, 1050, 1037, 1037,  123,  123,  124,  124,  124,
+
 /*  1150 */   124, 1133, 1635,  474, 1635,  371,  125,  114,   80, 1212,
+
 /*  1160 */  1212, 1047, 1050, 1037, 1037,  123,  123,  124,  124,  124,
+
 /*  1170 */   124, 1489,  329,  474,  331,  122,  122,  122,  122,  121,
+
 /*  1180 */   121,  120,  120,  120,  119,  116,  444,  203, 1415,  568,
+
 /*  1190 */  1290,  862,  464, 1208,  436,  122,  122,  122,  122,  121,
+
 /*  1200 */   121,  120,  120,  120,  119,  116,  444,  553, 1133, 1636,
+
 /*  1210 */   539, 1636,   15,   15,  890,  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,
+
 /*  1230 */  1131, 1415, 1553, 1554, 1327,  409,    6,    6, 1165, 1264,
+
 /*  1240 */   415,  320,  284,  284, 1415,  508,  565,  525,  300,  457,
+
 /*  1250 */    43,   43,  568,  891,   12,  565,  330,  478,  425,  407,
+
 /*  1260 */   126,   80, 1212, 1212, 1047, 1050, 1037, 1037,  123,  123,
+
 /*  1270 */   124,  124,  124,  124,  568,   57,   57,  288, 1188, 1415,
+
 /*  1280 */   496,  458,  392,  392,  391,  273,  389, 1131, 1552,  847,
+
 /*  1290 */  1165,  407,    6,  568,  321, 1154,  470,   44,   44, 1551,
+
 /*  1300 */  1110,  426,  234,    6,  323,  256,  540,  256, 1154,  431,
+
 /*  1310 */   568, 1154,  322,   17,  487, 1111,   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,
+
 /*  1330 */  1112,  216,  481,   59,   59, 1188, 1189, 1188,  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,
+
 /*  1350 */   168,  556,  420,  141,  479,  563,  568,  293,  568, 1091,
+
 /*  1360 */   568,  293,  568, 1091,  531,  568,  870,    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,
+
 /*  1400 */    64,   64,  561,  415,  535,  410,  568, 1024,  568,  534,
+
 /*  1410 */   316,  559,  316,  559,   65,   65,   14,   14,  568, 1024,
+
 /*  1420 */   568,  512,  930,  870, 1015,  109,  109,  929, 1014,   66,
+
 /*  1430 */    66,  131,  131,  110,  451,  445,  569,  445,  416,  177,
+
 /*  1440 */  1014,  132,  132,   67,   67,  568,  467,  568,  930,  471,
+
 /*  1450 */  1360,  283,  226,  929,  315, 1359,  407,  568,  459,  407,
+
 /*  1460 */  1014, 1014, 1016,  239,  407,   86,  213, 1346,   52,   52,
+
 /*  1470 */    68,   68, 1014, 1014, 1016, 1017,   27, 1579, 1176,  447,
+
 /*  1480 */    69,   69,  288,   97,  108, 1535,  106,  392,  392,  391,
+
 /*  1490 */   273,  389,  568,  877,  847,  881,  568,  111,  560,  466,
+
 /*  1500 */     4,  568,  152,   30,   38,  568, 1128,  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,
+
 /*  1530 */   568,  289, 1508,  568,   31, 1507,  568,  445,  338,  483,
+
 /*  1540 */   100,   54,   54,  344,   72,   72,  296,  236, 1076,  557,
+
 /*  1550 */   445,  877, 1356,  134,  134,  168,   73,   73,  141,  161,
+
 /*  1560 */   161, 1568,  557,  535,  568,  319,  568,  348,  536, 1007,
+
 /*  1570 */   473,  261,  261,  889,  888,  235,  535,  568, 1024,  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,
+
 /*  1590 */   130, 1024,  110,  366,  445,  569,  445,  109,  109, 1014,
+
 /*  1600 */   162,  162,  156,  156,  568,  110, 1076,  445,  569,  445,
+
 /*  1610 */   410,  351, 1014,  568,  353,  316,  559,  568,  343,  568,
+
 /*  1620 */   100,  497,  357,  258,  100,  896,  897,  140,  140,  355,
+
 /*  1630 */  1306, 1014, 1014, 1016, 1017,   27,  139,  139,  362,  451,
+
 /*  1640 */   137,  137,  138,  138, 1014, 1014, 1016, 1017,   27, 1176,
+
 /*  1650 */   447,  568,  372,  288,  111,  560, 1018,    4,  392,  392,
+
 /*  1660 */   391,  273,  389,  568, 1137,  847,  568, 1072,  568,  258,
+
 /*  1670 */   492,  563,  568,  211,   75,   75,  555,  960,  234,  261,
+
 /*  1680 */   323,  111,  560,  927,    4,  113,   77,   77,  322,   74,
+
 /*  1690 */    74,   42,   42, 1369,  445,   48,   48, 1414,  563,  972,
+
 /*  1700 */   973, 1088, 1087, 1088, 1087,  860,  557,  150,  928, 1342,
+
 /*  1710 */   113, 1354,  554, 1419, 1018, 1271, 1262, 1250,  236, 1249,
+
 /*  1720 */  1251,  445, 1587, 1339,  308,  276,  168,  309,   11,  141,
+
 /*  1730 */   393,  310,  232,  557, 1401, 1024,  335,  291, 1396,  219,
+
 /*  1740 */   336,  109,  109,  934,  297, 1406,  235,  341,  477,  110,
+
 /*  1750 */   502,  445,  569,  445, 1389, 1405, 1014,  400, 1289,  365,
+
 /*  1760 */   223, 1480, 1024, 1479, 1351, 1352, 1350, 1349,  109,  109,
+
 /*  1770 */   204, 1590, 1228,  558,  265,  218,  110,  205,  445,  569,
+
 /*  1780 */   445,  410,  387, 1014, 1527,  179,  316,  559, 1014, 1014,
+
 /*  1790 */  1016, 1017,   27,  230, 1525, 1225,   79,  560,   85,    4,
+
 /*  1800 */   418,  215,  548,   81,   84,  188, 1402,  173,  181,  461,
+
 /*  1810 */   451,   35,  462,  563,  183, 1014, 1014, 1016, 1017,   27,
+
 /*  1820 */   184, 1485,  185,  186,  495,  242,   98,  398, 1408,   36,
+
 /*  1830 */  1407,  484,   91,  469,  401, 1410,  445,  192, 1474,  246,
+
 /*  1840 */  1496,  490,  346,  277,  248,  196,  493,  511,  557,  350,
+
 /*  1850 */  1252,  249,  250,  403, 1309, 1308,  111,  560,  432,    4,
+
 /*  1860 */  1307, 1300,   93, 1604,  881, 1603,  224,  404,  434,  520,
+
 /*  1870 */   263,  435, 1573,  563, 1279, 1278,  364, 1024,  306, 1277,
+
 /*  1880 */   264, 1602, 1559,  109,  109,  370, 1299,  307, 1558,  438,
+
 /*  1890 */   128,  110, 1374,  445,  569,  445,  445,  546, 1014,   10,
+
 /*  1900 */  1461,  105,  381, 1373,   34,  571,   99, 1332,  557,  314,
+
 /*  1910 */  1182,  530,  272,  274,  379,  210, 1331,  547,  385,  386,
+
 /*  1920 */   275,  572, 1247, 1242,  411,  412, 1512,  165,  178, 1513,
+
 /*  1930 */  1014, 1014, 1016, 1017,   27, 1511, 1510, 1024,   78,  147,
+
 /*  1940 */   166,  220,  221,  109,  109,  834,  304,  167,  446,  212,
+
 /*  1950 */   318,  110,  231,  445,  569,  445,  144, 1086, 1014, 1084,
+
 /*  1960 */   326,  180,  169, 1207,  182,  334,  238,  913,  241, 1100,
 /*  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,
+
 /*  1980 */   172, 1103,  243, 1099,  244,  158,   18,  245,  345,  247,
+
 /*  1990 */  1014, 1014, 1016, 1017,   27,  261, 1092,  193, 1222,  489,
+
 /*  2000 */   194,   37,  366,  849,  494,  251,  195,  506,   92,   19,
+
 /*  2010 */   498,  358,   20,  503,  879,  361,   94,  892,  305,  159,
+
 /*  2020 */   513,   39,   95, 1170,  160, 1053,  964, 1139,   96,  174,
+
 /*  2030 */  1138,  225,  280,  282,  198,  958,  113, 1160, 1156,  260,
+
 /*  2040 */    21,   22,   23, 1158, 1164, 1163, 1144,   24,   33,   25,
+
 /*  2050 */   202,  542,   26,  100, 1067,  102, 1054,  103,    7, 1052,
+
 /*  2060 */  1056, 1109, 1057, 1108,  266,  267,   28,   40,  390, 1019,
+
 /*  2070 */   861,  112,   29,  564, 1178, 1177,  268,  176,  143,  923,
+
 /*  2080 */  1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1238,
+
 /*  2090 */  1238, 1238, 1238, 1238,  269, 1595,
};
static const YYCODETYPE yy_lookahead[] = {
 /*     0 */   193,  193,  193,  274,  275,  276,  193,  274,  275,  276,
@@ -166249,7 +168729,7 @@ static const YYCODETYPE yy_lookahead[] = {
 /*  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,  141,  141,  319,  141,  319,  319,
+
 /*  2090 */   319,  319,  319,  319,  141,  141,  319,  319,  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,
@@ -166268,9 +168748,9 @@ static const YYCODETYPE yy_lookahead[] = {
 /*  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,
+
 /*  2280 */   319,
};
-
#define YY_SHIFT_COUNT    (575)
+
#define YY_SHIFT_COUNT    (574)
#define YY_SHIFT_MIN      (0)
#define YY_SHIFT_MAX      (2074)
static const unsigned short int yy_shift_ofst[] = {
@@ -166290,12 +168770,12 @@ static const unsigned short int yy_shift_ofst[] = {
 /*   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,
+
 /*   160 */   113,   22,   22, 2096, 2096,  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,
+
 /*   210 */    67, 1274, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 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,
@@ -166313,8 +168793,8 @@ static const unsigned short int yy_shift_ofst[] = {
 /*   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,
+
 /*   390 */  1897, 1914, 1914, 1914, 2096, 2096, 2096, 2096, 2096, 2096,
+
 /*   400 */  2096, 2096, 2096, 2096, 2096, 2096, 2096, 2096, 2096,  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,
@@ -166331,7 +168811,7 @@ static const unsigned short int yy_shift_ofst[] = {
 /*   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,
+
 /*   570 */  2052, 2055, 2053, 2073, 2074,
};
#define YY_REDUCE_COUNT (408)
#define YY_REDUCE_MIN   (-271)
@@ -166380,64 +168860,64 @@ static const short yy_reduce_ofst[] = {
 /*   400 */  1722, 1723, 1733, 1717, 1724, 1727, 1728, 1725, 1740,
};
static const YYACTIONTYPE yy_default[] = {
-
 /*     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,
+
 /*     0 */  1641, 1641, 1641, 1469, 1236, 1347, 1236, 1236, 1236, 1469,
+
 /*    10 */  1469, 1469, 1236, 1377, 1377, 1522, 1269, 1236, 1236, 1236,
+
 /*    20 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1468, 1236, 1236,
+
 /*    30 */  1236, 1236, 1557, 1557, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*    40 */  1236, 1236, 1386, 1236, 1393, 1236, 1236, 1236, 1236, 1236,
+
 /*    50 */  1470, 1471, 1236, 1236, 1236, 1521, 1523, 1486, 1400, 1399,
+
 /*    60 */  1398, 1397, 1504, 1365, 1391, 1384, 1388, 1465, 1466, 1464,
+
 /*    70 */  1619, 1471, 1470, 1236, 1387, 1433, 1449, 1432, 1236, 1236,
+
 /*    80 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*    90 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   100 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   110 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   120 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   130 */  1441, 1448, 1447, 1446, 1455, 1445, 1442, 1435, 1434, 1436,
+
 /*   140 */  1437, 1236, 1236, 1260, 1236, 1236, 1257, 1311, 1236, 1236,
+
 /*   150 */  1236, 1236, 1236, 1541, 1540, 1236, 1438, 1236, 1269, 1427,
+
 /*   160 */  1426, 1452, 1439, 1451, 1450, 1529, 1593, 1592, 1487, 1236,
+
 /*   170 */  1236, 1236, 1236, 1236, 1236, 1557, 1236, 1236, 1236, 1236,
+
 /*   180 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   190 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1367,
+
 /*   200 */  1557, 1557, 1236, 1269, 1557, 1557, 1368, 1368, 1265, 1265,
+
 /*   210 */  1371, 1236, 1536, 1338, 1338, 1338, 1338, 1347, 1338, 1236,
+
 /*   220 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   230 */  1236, 1236, 1236, 1236, 1526, 1524, 1236, 1236, 1236, 1236,
+
 /*   240 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   250 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   260 */  1236, 1236, 1236, 1343, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   270 */  1236, 1236, 1236, 1236, 1236, 1586, 1236, 1499, 1325, 1343,
+
 /*   280 */  1343, 1343, 1343, 1345, 1326, 1324, 1337, 1270, 1243, 1633,
+
 /*   290 */  1403, 1392, 1344, 1392, 1630, 1390, 1403, 1403, 1390, 1403,
+
 /*   300 */  1344, 1630, 1286, 1608, 1281, 1377, 1377, 1377, 1367, 1367,
+
 /*   310 */  1367, 1367, 1371, 1371, 1467, 1344, 1337, 1236, 1633, 1633,
+
 /*   320 */  1353, 1353, 1632, 1632, 1353, 1487, 1616, 1412, 1314, 1320,
+
 /*   330 */  1320, 1320, 1320, 1353, 1254, 1390, 1616, 1616, 1390, 1412,
+
 /*   340 */  1314, 1390, 1314, 1390, 1353, 1254, 1503, 1627, 1353, 1254,
+
 /*   350 */  1477, 1353, 1254, 1353, 1254, 1477, 1312, 1312, 1312, 1301,
+
 /*   360 */  1236, 1236, 1477, 1312, 1286, 1312, 1301, 1312, 1312, 1575,
+
 /*   370 */  1236, 1481, 1481, 1477, 1353, 1567, 1567, 1380, 1380, 1385,
+
 /*   380 */  1371, 1472, 1353, 1236, 1385, 1383, 1381, 1390, 1304, 1589,
+
 /*   390 */  1589, 1585, 1585, 1585, 1638, 1638, 1536, 1601, 1269, 1269,
+
 /*   400 */  1269, 1269, 1601, 1288, 1288, 1270, 1270, 1269, 1601, 1236,
+
 /*   410 */  1236, 1236, 1236, 1236, 1236, 1596, 1236, 1531, 1488, 1357,
+
 /*   420 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   430 */  1236, 1236, 1236, 1236, 1542, 1236, 1236, 1236, 1236, 1236,
+
 /*   440 */  1236, 1236, 1236, 1236, 1236, 1417, 1236, 1239, 1533, 1236,
+
 /*   450 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1394, 1395, 1358,
+
 /*   460 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1409, 1236, 1236,
+
 /*   470 */  1236, 1404, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   480 */  1629, 1236, 1236, 1236, 1236, 1236, 1236, 1502, 1501, 1236,
+
 /*   490 */  1236, 1355, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   500 */  1236, 1236, 1236, 1236, 1236, 1284, 1236, 1236, 1236, 1236,
+
 /*   510 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   520 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1382,
+
 /*   530 */  1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   540 */  1236, 1236, 1236, 1236, 1572, 1372, 1236, 1236, 1236, 1236,
+
 /*   550 */  1620, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236, 1236,
+
 /*   560 */  1236, 1236, 1236, 1236, 1236, 1612, 1328, 1418, 1236, 1421,
+
 /*   570 */  1258, 1236, 1248, 1236, 1236,
};
/********** End of lemon-generated parsing tables *****************************/

@@ -167234,233 +169714,231 @@ static const char *const yyRuleName[] = {
 /* 175 */ "idlist ::= idlist COMMA nm",
 /* 176 */ "idlist ::= nm",
 /* 177 */ "expr ::= LP expr RP",
-
 /* 178 */ "expr ::= ID|INDEXED",
-
 /* 179 */ "expr ::= JOIN_KW",
-
 /* 180 */ "expr ::= nm DOT nm",
-
 /* 181 */ "expr ::= nm DOT nm DOT nm",
-
 /* 182 */ "term ::= NULL|FLOAT|BLOB",
-
 /* 183 */ "term ::= STRING",
-
 /* 184 */ "term ::= INTEGER",
-
 /* 185 */ "expr ::= VARIABLE",
-
 /* 186 */ "expr ::= expr COLLATE ID|STRING",
-
 /* 187 */ "expr ::= CAST LP expr AS typetoken RP",
-
 /* 188 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
-
 /* 189 */ "expr ::= ID|INDEXED LP STAR RP",
-
 /* 190 */ "expr ::= ID|INDEXED LP distinct exprlist RP filter_over",
-
 /* 191 */ "expr ::= ID|INDEXED LP STAR RP filter_over",
-
 /* 192 */ "term ::= CTIME_KW",
-
 /* 193 */ "expr ::= LP nexprlist COMMA expr RP",
-
 /* 194 */ "expr ::= expr AND expr",
-
 /* 195 */ "expr ::= expr OR expr",
-
 /* 196 */ "expr ::= expr LT|GT|GE|LE expr",
-
 /* 197 */ "expr ::= expr EQ|NE expr",
-
 /* 198 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
-
 /* 199 */ "expr ::= expr PLUS|MINUS expr",
-
 /* 200 */ "expr ::= expr STAR|SLASH|REM expr",
-
 /* 201 */ "expr ::= expr CONCAT expr",
-
 /* 202 */ "likeop ::= NOT LIKE_KW|MATCH",
-
 /* 203 */ "expr ::= expr likeop expr",
-
 /* 204 */ "expr ::= expr likeop expr ESCAPE expr",
-
 /* 205 */ "expr ::= expr ISNULL|NOTNULL",
-
 /* 206 */ "expr ::= expr NOT NULL",
-
 /* 207 */ "expr ::= expr IS expr",
-
 /* 208 */ "expr ::= expr IS NOT expr",
-
 /* 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 ::=",
+
 /* 178 */ "expr ::= ID|INDEXED|JOIN_KW",
+
 /* 179 */ "expr ::= nm DOT nm",
+
 /* 180 */ "expr ::= nm DOT nm DOT nm",
+
 /* 181 */ "term ::= NULL|FLOAT|BLOB",
+
 /* 182 */ "term ::= STRING",
+
 /* 183 */ "term ::= INTEGER",
+
 /* 184 */ "expr ::= VARIABLE",
+
 /* 185 */ "expr ::= expr COLLATE ID|STRING",
+
 /* 186 */ "expr ::= CAST LP expr AS typetoken RP",
+
 /* 187 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP",
+
 /* 188 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP",
+
 /* 189 */ "expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over",
+
 /* 190 */ "expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over",
+
 /* 191 */ "term ::= CTIME_KW",
+
 /* 192 */ "expr ::= LP nexprlist COMMA expr RP",
+
 /* 193 */ "expr ::= expr AND expr",
+
 /* 194 */ "expr ::= expr OR expr",
+
 /* 195 */ "expr ::= expr LT|GT|GE|LE expr",
+
 /* 196 */ "expr ::= expr EQ|NE expr",
+
 /* 197 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+
 /* 198 */ "expr ::= expr PLUS|MINUS expr",
+
 /* 199 */ "expr ::= expr STAR|SLASH|REM expr",
+
 /* 200 */ "expr ::= expr CONCAT expr",
+
 /* 201 */ "likeop ::= NOT LIKE_KW|MATCH",
+
 /* 202 */ "expr ::= expr likeop expr",
+
 /* 203 */ "expr ::= expr likeop expr ESCAPE expr",
+
 /* 204 */ "expr ::= expr ISNULL|NOTNULL",
+
 /* 205 */ "expr ::= expr NOT NULL",
+
 /* 206 */ "expr ::= expr IS expr",
+
 /* 207 */ "expr ::= expr IS NOT expr",
+
 /* 208 */ "expr ::= expr IS NOT DISTINCT FROM expr",
+
 /* 209 */ "expr ::= expr IS DISTINCT FROM expr",
+
 /* 210 */ "expr ::= NOT expr",
+
 /* 211 */ "expr ::= BITNOT expr",
+
 /* 212 */ "expr ::= PLUS|MINUS expr",
+
 /* 213 */ "expr ::= expr PTR expr",
+
 /* 214 */ "between_op ::= BETWEEN",
+
 /* 215 */ "between_op ::= NOT BETWEEN",
+
 /* 216 */ "expr ::= expr between_op expr AND expr",
+
 /* 217 */ "in_op ::= IN",
+
 /* 218 */ "in_op ::= NOT IN",
+
 /* 219 */ "expr ::= expr in_op LP exprlist RP",
+
 /* 220 */ "expr ::= LP select RP",
+
 /* 221 */ "expr ::= expr in_op LP select RP",
+
 /* 222 */ "expr ::= expr in_op nm dbnm paren_exprlist",
+
 /* 223 */ "expr ::= EXISTS LP select RP",
+
 /* 224 */ "expr ::= CASE case_operand case_exprlist case_else END",
+
 /* 225 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+
 /* 226 */ "case_exprlist ::= WHEN expr THEN expr",
+
 /* 227 */ "case_else ::= ELSE expr",
+
 /* 228 */ "case_else ::=",
+
 /* 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|JOIN_KW",
+
 /* 356 */ "nm ::= STRING",
+
 /* 357 */ "typetoken ::= typename",
+
 /* 358 */ "typename ::= ID|STRING",
+
 /* 359 */ "signed ::= plus_num",
+
 /* 360 */ "signed ::= minus_num",
+
 /* 361 */ "carglist ::= carglist ccons",
+
 /* 362 */ "carglist ::=",
+
 /* 363 */ "ccons ::= NULL onconf",
+
 /* 364 */ "ccons ::= GENERATED ALWAYS AS generated",
+
 /* 365 */ "ccons ::= AS generated",
+
 /* 366 */ "conslist_opt ::= COMMA conslist",
+
 /* 367 */ "conslist ::= conslist tconscomma tcons",
+
 /* 368 */ "conslist ::= tcons",
+
 /* 369 */ "tconscomma ::=",
+
 /* 370 */ "defer_subclause_opt ::= defer_subclause",
+
 /* 371 */ "resolvetype ::= raisetype",
+
 /* 372 */ "selectnowith ::= oneselect",
+
 /* 373 */ "oneselect ::= values",
+
 /* 374 */ "sclp ::= selcollist COMMA",
+
 /* 375 */ "as ::= ID|STRING",
+
 /* 376 */ "indexed_opt ::= indexed_by",
+
 /* 377 */ "returning ::=",
+
 /* 378 */ "expr ::= term",
+
 /* 379 */ "likeop ::= LIKE_KW|MATCH",
+
 /* 380 */ "case_operand ::= expr",
+
 /* 381 */ "exprlist ::= nexprlist",
+
 /* 382 */ "nmnum ::= plus_num",
+
 /* 383 */ "nmnum ::= nm",
+
 /* 384 */ "nmnum ::= ON",
+
 /* 385 */ "nmnum ::= DELETE",
+
 /* 386 */ "nmnum ::= DEFAULT",
+
 /* 387 */ "plus_num ::= INTEGER|FLOAT",
+
 /* 388 */ "foreach_clause ::=",
+
 /* 389 */ "foreach_clause ::= FOR EACH ROW",
+
 /* 390 */ "trnm ::= nm",
+
 /* 391 */ "tridxby ::=",
+
 /* 392 */ "database_kw_opt ::= DATABASE",
+
 /* 393 */ "database_kw_opt ::=",
+
 /* 394 */ "kwcolumn_opt ::=",
+
 /* 395 */ "kwcolumn_opt ::= COLUMNKW",
+
 /* 396 */ "vtabarglist ::= vtabarg",
+
 /* 397 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+
 /* 398 */ "vtabarg ::= vtabarg vtabargtoken",
+
 /* 399 */ "anylist ::=",
+
 /* 400 */ "anylist ::= anylist LP anylist RP",
+
 /* 401 */ "anylist ::= anylist ANY",
+
 /* 402 */ "with ::=",
};
#endif /* NDEBUG */

@@ -168145,233 +170623,231 @@ static const YYCODETYPE yyRuleInfoLhs[] = {
   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 */
-
   217,  /* (180) expr ::= nm DOT nm */
-
   217,  /* (181) expr ::= nm DOT nm DOT nm */
-
   216,  /* (182) term ::= NULL|FLOAT|BLOB */
-
   216,  /* (183) term ::= STRING */
-
   216,  /* (184) term ::= INTEGER */
-
   217,  /* (185) expr ::= VARIABLE */
-
   217,  /* (186) expr ::= expr COLLATE ID|STRING */
-
   217,  /* (187) expr ::= CAST LP expr AS typetoken RP */
-
   217,  /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */
-
   217,  /* (189) expr ::= ID|INDEXED LP STAR RP */
-
   217,  /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */
-
   217,  /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */
-
   216,  /* (192) term ::= CTIME_KW */
-
   217,  /* (193) expr ::= LP nexprlist COMMA expr RP */
-
   217,  /* (194) expr ::= expr AND expr */
-
   217,  /* (195) expr ::= expr OR expr */
-
   217,  /* (196) expr ::= expr LT|GT|GE|LE expr */
-
   217,  /* (197) expr ::= expr EQ|NE expr */
-
   217,  /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
-
   217,  /* (199) expr ::= expr PLUS|MINUS expr */
-
   217,  /* (200) expr ::= expr STAR|SLASH|REM expr */
-
   217,  /* (201) expr ::= expr CONCAT expr */
-
   274,  /* (202) likeop ::= NOT LIKE_KW|MATCH */
-
   217,  /* (203) expr ::= expr likeop expr */
-
   217,  /* (204) expr ::= expr likeop expr ESCAPE expr */
-
   217,  /* (205) expr ::= expr ISNULL|NOTNULL */
-
   217,  /* (206) expr ::= expr NOT NULL */
-
   217,  /* (207) expr ::= expr IS expr */
-
   217,  /* (208) expr ::= expr IS NOT expr */
-
   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 ::= */
+
   217,  /* (178) expr ::= ID|INDEXED|JOIN_KW */
+
   217,  /* (179) expr ::= nm DOT nm */
+
   217,  /* (180) expr ::= nm DOT nm DOT nm */
+
   216,  /* (181) term ::= NULL|FLOAT|BLOB */
+
   216,  /* (182) term ::= STRING */
+
   216,  /* (183) term ::= INTEGER */
+
   217,  /* (184) expr ::= VARIABLE */
+
   217,  /* (185) expr ::= expr COLLATE ID|STRING */
+
   217,  /* (186) expr ::= CAST LP expr AS typetoken RP */
+
   217,  /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
+
   217,  /* (188) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
+
   217,  /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
+
   217,  /* (190) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
+
   216,  /* (191) term ::= CTIME_KW */
+
   217,  /* (192) expr ::= LP nexprlist COMMA expr RP */
+
   217,  /* (193) expr ::= expr AND expr */
+
   217,  /* (194) expr ::= expr OR expr */
+
   217,  /* (195) expr ::= expr LT|GT|GE|LE expr */
+
   217,  /* (196) expr ::= expr EQ|NE expr */
+
   217,  /* (197) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+
   217,  /* (198) expr ::= expr PLUS|MINUS expr */
+
   217,  /* (199) expr ::= expr STAR|SLASH|REM expr */
+
   217,  /* (200) expr ::= expr CONCAT expr */
+
   274,  /* (201) likeop ::= NOT LIKE_KW|MATCH */
+
   217,  /* (202) expr ::= expr likeop expr */
+
   217,  /* (203) expr ::= expr likeop expr ESCAPE expr */
+
   217,  /* (204) expr ::= expr ISNULL|NOTNULL */
+
   217,  /* (205) expr ::= expr NOT NULL */
+
   217,  /* (206) expr ::= expr IS expr */
+
   217,  /* (207) expr ::= expr IS NOT expr */
+
   217,  /* (208) expr ::= expr IS NOT DISTINCT FROM expr */
+
   217,  /* (209) expr ::= expr IS DISTINCT FROM expr */
+
   217,  /* (210) expr ::= NOT expr */
+
   217,  /* (211) expr ::= BITNOT expr */
+
   217,  /* (212) expr ::= PLUS|MINUS expr */
+
   217,  /* (213) expr ::= expr PTR expr */
+
   275,  /* (214) between_op ::= BETWEEN */
+
   275,  /* (215) between_op ::= NOT BETWEEN */
+
   217,  /* (216) expr ::= expr between_op expr AND expr */
+
   276,  /* (217) in_op ::= IN */
+
   276,  /* (218) in_op ::= NOT IN */
+
   217,  /* (219) expr ::= expr in_op LP exprlist RP */
+
   217,  /* (220) expr ::= LP select RP */
+
   217,  /* (221) expr ::= expr in_op LP select RP */
+
   217,  /* (222) expr ::= expr in_op nm dbnm paren_exprlist */
+
   217,  /* (223) expr ::= EXISTS LP select RP */
+
   217,  /* (224) expr ::= CASE case_operand case_exprlist case_else END */
+
   279,  /* (225) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+
   279,  /* (226) case_exprlist ::= WHEN expr THEN expr */
+
   280,  /* (227) case_else ::= ELSE expr */
+
   280,  /* (228) case_else ::= */
+
   278,  /* (229) case_operand ::= */
+
   261,  /* (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|JOIN_KW */
+
   193,  /* (356) nm ::= STRING */
+
   208,  /* (357) typetoken ::= typename */
+
   209,  /* (358) typename ::= ID|STRING */
+
   210,  /* (359) signed ::= plus_num */
+
   210,  /* (360) signed ::= minus_num */
+
   207,  /* (361) carglist ::= carglist ccons */
+
   207,  /* (362) carglist ::= */
+
   215,  /* (363) ccons ::= NULL onconf */
+
   215,  /* (364) ccons ::= GENERATED ALWAYS AS generated */
+
   215,  /* (365) ccons ::= AS generated */
+
   202,  /* (366) conslist_opt ::= COMMA conslist */
+
   228,  /* (367) conslist ::= conslist tconscomma tcons */
+
   228,  /* (368) conslist ::= tcons */
+
   229,  /* (369) tconscomma ::= */
+
   233,  /* (370) defer_subclause_opt ::= defer_subclause */
+
   235,  /* (371) resolvetype ::= raisetype */
+
   239,  /* (372) selectnowith ::= oneselect */
+
   240,  /* (373) oneselect ::= values */
+
   254,  /* (374) sclp ::= selcollist COMMA */
+
   255,  /* (375) as ::= ID|STRING */
+
   264,  /* (376) indexed_opt ::= indexed_by */
+
   272,  /* (377) returning ::= */
+
   217,  /* (378) expr ::= term */
+
   274,  /* (379) likeop ::= LIKE_KW|MATCH */
+
   278,  /* (380) case_operand ::= expr */
+
   261,  /* (381) exprlist ::= nexprlist */
+
   284,  /* (382) nmnum ::= plus_num */
+
   284,  /* (383) nmnum ::= nm */
+
   284,  /* (384) nmnum ::= ON */
+
   284,  /* (385) nmnum ::= DELETE */
+
   284,  /* (386) nmnum ::= DEFAULT */
+
   211,  /* (387) plus_num ::= INTEGER|FLOAT */
+
   289,  /* (388) foreach_clause ::= */
+
   289,  /* (389) foreach_clause ::= FOR EACH ROW */
+
   292,  /* (390) trnm ::= nm */
+
   293,  /* (391) tridxby ::= */
+
   294,  /* (392) database_kw_opt ::= DATABASE */
+
   294,  /* (393) database_kw_opt ::= */
+
   297,  /* (394) kwcolumn_opt ::= */
+
   297,  /* (395) kwcolumn_opt ::= COLUMNKW */
+
   299,  /* (396) vtabarglist ::= vtabarg */
+
   299,  /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
+
   300,  /* (398) vtabarg ::= vtabarg vtabargtoken */
+
   303,  /* (399) anylist ::= */
+
   303,  /* (400) anylist ::= anylist LP anylist RP */
+
   303,  /* (401) anylist ::= anylist ANY */
+
   266,  /* (402) with ::= */
};

/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
@@ -168555,233 +171031,231 @@ static const signed char yyRuleInfoNRhs[] = {
   -3,  /* (175) idlist ::= idlist COMMA nm */
   -1,  /* (176) idlist ::= nm */
   -3,  /* (177) expr ::= LP expr RP */
-
   -1,  /* (178) expr ::= ID|INDEXED */
-
   -1,  /* (179) expr ::= JOIN_KW */
-
   -3,  /* (180) expr ::= nm DOT nm */
-
   -5,  /* (181) expr ::= nm DOT nm DOT nm */
-
   -1,  /* (182) term ::= NULL|FLOAT|BLOB */
-
   -1,  /* (183) term ::= STRING */
-
   -1,  /* (184) term ::= INTEGER */
-
   -1,  /* (185) expr ::= VARIABLE */
-
   -3,  /* (186) expr ::= expr COLLATE ID|STRING */
-
   -6,  /* (187) expr ::= CAST LP expr AS typetoken RP */
-
   -5,  /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */
-
   -4,  /* (189) expr ::= ID|INDEXED LP STAR RP */
-
   -6,  /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */
-
   -5,  /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */
-
   -1,  /* (192) term ::= CTIME_KW */
-
   -5,  /* (193) expr ::= LP nexprlist COMMA expr RP */
-
   -3,  /* (194) expr ::= expr AND expr */
-
   -3,  /* (195) expr ::= expr OR expr */
-
   -3,  /* (196) expr ::= expr LT|GT|GE|LE expr */
-
   -3,  /* (197) expr ::= expr EQ|NE expr */
-
   -3,  /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
-
   -3,  /* (199) expr ::= expr PLUS|MINUS expr */
-
   -3,  /* (200) expr ::= expr STAR|SLASH|REM expr */
-
   -3,  /* (201) expr ::= expr CONCAT expr */
-
   -2,  /* (202) likeop ::= NOT LIKE_KW|MATCH */
-
   -3,  /* (203) expr ::= expr likeop expr */
-
   -5,  /* (204) expr ::= expr likeop expr ESCAPE expr */
-
   -2,  /* (205) expr ::= expr ISNULL|NOTNULL */
-
   -3,  /* (206) expr ::= expr NOT NULL */
-
   -3,  /* (207) expr ::= expr IS expr */
-
   -4,  /* (208) expr ::= expr IS NOT expr */
-
   -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 ::= */
+
   -1,  /* (178) expr ::= ID|INDEXED|JOIN_KW */
+
   -3,  /* (179) expr ::= nm DOT nm */
+
   -5,  /* (180) expr ::= nm DOT nm DOT nm */
+
   -1,  /* (181) term ::= NULL|FLOAT|BLOB */
+
   -1,  /* (182) term ::= STRING */
+
   -1,  /* (183) term ::= INTEGER */
+
   -1,  /* (184) expr ::= VARIABLE */
+
   -3,  /* (185) expr ::= expr COLLATE ID|STRING */
+
   -6,  /* (186) expr ::= CAST LP expr AS typetoken RP */
+
   -5,  /* (187) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
+
   -4,  /* (188) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
+
   -6,  /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
+
   -5,  /* (190) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
+
   -1,  /* (191) term ::= CTIME_KW */
+
   -5,  /* (192) expr ::= LP nexprlist COMMA expr RP */
+
   -3,  /* (193) expr ::= expr AND expr */
+
   -3,  /* (194) expr ::= expr OR expr */
+
   -3,  /* (195) expr ::= expr LT|GT|GE|LE expr */
+
   -3,  /* (196) expr ::= expr EQ|NE expr */
+
   -3,  /* (197) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
+
   -3,  /* (198) expr ::= expr PLUS|MINUS expr */
+
   -3,  /* (199) expr ::= expr STAR|SLASH|REM expr */
+
   -3,  /* (200) expr ::= expr CONCAT expr */
+
   -2,  /* (201) likeop ::= NOT LIKE_KW|MATCH */
+
   -3,  /* (202) expr ::= expr likeop expr */
+
   -5,  /* (203) expr ::= expr likeop expr ESCAPE expr */
+
   -2,  /* (204) expr ::= expr ISNULL|NOTNULL */
+
   -3,  /* (205) expr ::= expr NOT NULL */
+
   -3,  /* (206) expr ::= expr IS expr */
+
   -4,  /* (207) expr ::= expr IS NOT expr */
+
   -6,  /* (208) expr ::= expr IS NOT DISTINCT FROM expr */
+
   -5,  /* (209) expr ::= expr IS DISTINCT FROM expr */
+
   -2,  /* (210) expr ::= NOT expr */
+
   -2,  /* (211) expr ::= BITNOT expr */
+
   -2,  /* (212) expr ::= PLUS|MINUS expr */
+
   -3,  /* (213) expr ::= expr PTR expr */
+
   -1,  /* (214) between_op ::= BETWEEN */
+
   -2,  /* (215) between_op ::= NOT BETWEEN */
+
   -5,  /* (216) expr ::= expr between_op expr AND expr */
+
   -1,  /* (217) in_op ::= IN */
+
   -2,  /* (218) in_op ::= NOT IN */
+
   -5,  /* (219) expr ::= expr in_op LP exprlist RP */
+
   -3,  /* (220) expr ::= LP select RP */
+
   -5,  /* (221) expr ::= expr in_op LP select RP */
+
   -5,  /* (222) expr ::= expr in_op nm dbnm paren_exprlist */
+
   -4,  /* (223) expr ::= EXISTS LP select RP */
+
   -5,  /* (224) expr ::= CASE case_operand case_exprlist case_else END */
+
   -5,  /* (225) case_exprlist ::= case_exprlist WHEN expr THEN expr */
+
   -4,  /* (226) case_exprlist ::= WHEN expr THEN expr */
+
   -2,  /* (227) case_else ::= ELSE expr */
+
    0,  /* (228) case_else ::= */
+
    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|JOIN_KW */
+
   -1,  /* (356) nm ::= STRING */
+
   -1,  /* (357) typetoken ::= typename */
+
   -1,  /* (358) typename ::= ID|STRING */
+
   -1,  /* (359) signed ::= plus_num */
+
   -1,  /* (360) signed ::= minus_num */
+
   -2,  /* (361) carglist ::= carglist ccons */
+
    0,  /* (362) carglist ::= */
+
   -2,  /* (363) ccons ::= NULL onconf */
+
   -4,  /* (364) ccons ::= GENERATED ALWAYS AS generated */
+
   -2,  /* (365) ccons ::= AS generated */
+
   -2,  /* (366) conslist_opt ::= COMMA conslist */
+
   -3,  /* (367) conslist ::= conslist tconscomma tcons */
+
   -1,  /* (368) conslist ::= tcons */
+
    0,  /* (369) tconscomma ::= */
+
   -1,  /* (370) defer_subclause_opt ::= defer_subclause */
+
   -1,  /* (371) resolvetype ::= raisetype */
+
   -1,  /* (372) selectnowith ::= oneselect */
+
   -1,  /* (373) oneselect ::= values */
+
   -2,  /* (374) sclp ::= selcollist COMMA */
+
   -1,  /* (375) as ::= ID|STRING */
+
   -1,  /* (376) indexed_opt ::= indexed_by */
+
    0,  /* (377) returning ::= */
+
   -1,  /* (378) expr ::= term */
+
   -1,  /* (379) likeop ::= LIKE_KW|MATCH */
+
   -1,  /* (380) case_operand ::= expr */
+
   -1,  /* (381) exprlist ::= nexprlist */
+
   -1,  /* (382) nmnum ::= plus_num */
+
   -1,  /* (383) nmnum ::= nm */
+
   -1,  /* (384) nmnum ::= ON */
+
   -1,  /* (385) nmnum ::= DELETE */
+
   -1,  /* (386) nmnum ::= DEFAULT */
+
   -1,  /* (387) plus_num ::= INTEGER|FLOAT */
+
    0,  /* (388) foreach_clause ::= */
+
   -3,  /* (389) foreach_clause ::= FOR EACH ROW */
+
   -1,  /* (390) trnm ::= nm */
+
    0,  /* (391) tridxby ::= */
+
   -1,  /* (392) database_kw_opt ::= DATABASE */
+
    0,  /* (393) database_kw_opt ::= */
+
    0,  /* (394) kwcolumn_opt ::= */
+
   -1,  /* (395) kwcolumn_opt ::= COLUMNKW */
+
   -1,  /* (396) vtabarglist ::= vtabarg */
+
   -3,  /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */
+
   -2,  /* (398) vtabarg ::= vtabarg vtabargtoken */
+
    0,  /* (399) anylist ::= */
+
   -4,  /* (400) anylist ::= anylist LP anylist RP */
+
   -2,  /* (401) anylist ::= anylist ANY */
+
    0,  /* (402) with ::= */
};

static void yy_accept(yyParser*);  /* Forward Declaration */
@@ -168841,7 +171315,7 @@ static YYACTIONTYPE yy_reduce(
      case 5: /* transtype ::= DEFERRED */
      case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
      case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
-
      case 323: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==323);
+
      case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321);
{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/}
        break;
      case 8: /* cmd ::= COMMIT|END trans_opt */
@@ -168878,7 +171352,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 244: /* collate ::= */ yytestcase(yyruleno==244);
+
      case 242: /* collate ::= */ yytestcase(yyruleno==242);
{yymsp[1].minor.yy394 = 0;}
        break;
      case 16: /* ifnotexists ::= IF NOT EXISTS */
@@ -169062,9 +171536,9 @@ static YYACTIONTYPE yy_reduce(
        break;
      case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
      case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80);
-
      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);
+
      case 215: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==215);
+
      case 218: /* in_op ::= NOT IN */ yytestcase(yyruleno==218);
+
      case 243: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==243);
{yymsp[-1].minor.yy394 = 1;}
        break;
      case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
@@ -169214,9 +171688,9 @@ static YYACTIONTYPE yy_reduce(
      case 99: /* sclp ::= */
      case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132);
      case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142);
-
      case 232: /* exprlist ::= */ yytestcase(yyruleno==232);
-
      case 235: /* paren_exprlist ::= */ yytestcase(yyruleno==235);
-
      case 240: /* eidlist_opt ::= */ yytestcase(yyruleno==240);
+
      case 230: /* exprlist ::= */ yytestcase(yyruleno==230);
+
      case 233: /* paren_exprlist ::= */ yytestcase(yyruleno==233);
+
      case 238: /* eidlist_opt ::= */ yytestcase(yyruleno==238);
{yymsp[1].minor.yy322 = 0;}
        break;
      case 100: /* selcollist ::= sclp scanpt expr scanpt as */
@@ -169242,8 +171716,8 @@ static YYACTIONTYPE yy_reduce(
        break;
      case 103: /* as ::= AS nm */
      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);
+
      case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254);
+
      case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
        break;
      case 105: /* from ::= */
@@ -169287,7 +171761,7 @@ static YYACTIONTYPE yy_reduce(
{
    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 ){
+
    }else if( ALWAYS(yymsp[-3].minor.yy131!=0) && 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];
@@ -169415,16 +171889,16 @@ static YYACTIONTYPE yy_reduce(
      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);
+
      case 228: /* case_else ::= */ yytestcase(yyruleno==228);
+
      case 229: /* case_operand ::= */ yytestcase(yyruleno==229);
+
      case 248: /* vinto ::= */ yytestcase(yyruleno==248);
{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);
+
      case 227: /* case_else ::= ELSE expr */ yytestcase(yyruleno==227);
+
      case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247);
{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;}
        break;
      case 147: /* limit_opt ::= LIMIT expr */
@@ -169536,11 +172010,10 @@ static YYACTIONTYPE yy_reduce(
      case 177: /* expr ::= LP expr RP */
{yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;}
        break;
-
      case 178: /* expr ::= ID|INDEXED */
-
      case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179);
+
      case 178: /* expr ::= ID|INDEXED|JOIN_KW */
{yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
        break;
-
      case 180: /* expr ::= nm DOT nm */
+
      case 179: /* expr ::= nm DOT nm */
{
  Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
  Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
@@ -169548,7 +172021,7 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[-2].minor.yy528 = yylhsminor.yy528;
        break;
-
      case 181: /* expr ::= nm DOT nm DOT nm */
+
      case 180: /* expr ::= nm DOT nm DOT nm */
{
  Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0);
  Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
@@ -169561,18 +172034,18 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[-4].minor.yy528 = yylhsminor.yy528;
        break;
-
      case 182: /* term ::= NULL|FLOAT|BLOB */
-
      case 183: /* term ::= STRING */ yytestcase(yyruleno==183);
+
      case 181: /* term ::= NULL|FLOAT|BLOB */
+
      case 182: /* term ::= STRING */ yytestcase(yyruleno==182);
{yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
        break;
-
      case 184: /* term ::= INTEGER */
+
      case 183: /* term ::= INTEGER */
{
  yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
  if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
}
  yymsp[0].minor.yy528 = yylhsminor.yy528;
        break;
-
      case 185: /* expr ::= VARIABLE */
+
      case 184: /* expr ::= VARIABLE */
{
  if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
    u32 n = yymsp[0].minor.yy0.n;
@@ -169594,50 +172067,50 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 186: /* expr ::= expr COLLATE ID|STRING */
+
      case 185: /* expr ::= expr COLLATE ID|STRING */
{
  yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1);
}
        break;
-
      case 187: /* expr ::= CAST LP expr AS typetoken RP */
+
      case 186: /* expr ::= CAST LP expr AS typetoken RP */
{
  yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
  sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0);
}
        break;
-
      case 188: /* expr ::= ID|INDEXED LP distinct exprlist RP */
+
      case 187: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
{
  yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394);
}
  yymsp[-4].minor.yy528 = yylhsminor.yy528;
        break;
-
      case 189: /* expr ::= ID|INDEXED LP STAR RP */
+
      case 188: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
{
  yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
}
  yymsp[-3].minor.yy528 = yylhsminor.yy528;
        break;
-
      case 190: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */
+
      case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
{
  yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394);
  sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41);
}
  yymsp[-5].minor.yy528 = yylhsminor.yy528;
        break;
-
      case 191: /* expr ::= ID|INDEXED LP STAR RP filter_over */
+
      case 190: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
{
  yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
  sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41);
}
  yymsp[-4].minor.yy528 = yylhsminor.yy528;
        break;
-
      case 192: /* term ::= CTIME_KW */
+
      case 191: /* term ::= CTIME_KW */
{
  yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
}
  yymsp[0].minor.yy528 = yylhsminor.yy528;
        break;
-
      case 193: /* expr ::= LP nexprlist COMMA expr RP */
+
      case 192: /* expr ::= LP nexprlist COMMA expr RP */
{
  ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528);
  yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
@@ -169651,22 +172124,22 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 194: /* expr ::= expr AND expr */
+
      case 193: /* expr ::= expr AND expr */
{yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);}
        break;
-
      case 195: /* expr ::= expr OR expr */
-
      case 196: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==196);
-
      case 197: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==197);
-
      case 198: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==198);
-
      case 199: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==199);
-
      case 200: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==200);
-
      case 201: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==201);
+
      case 194: /* expr ::= expr OR expr */
+
      case 195: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==195);
+
      case 196: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==196);
+
      case 197: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==197);
+
      case 198: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==198);
+
      case 199: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==199);
+
      case 200: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==200);
{yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);}
        break;
-
      case 202: /* likeop ::= NOT LIKE_KW|MATCH */
+
      case 201: /* likeop ::= NOT LIKE_KW|MATCH */
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
        break;
-
      case 203: /* expr ::= expr likeop expr */
+
      case 202: /* expr ::= expr likeop expr */
{
  ExprList *pList;
  int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
@@ -169678,7 +172151,7 @@ static YYACTIONTYPE yy_reduce(
  if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc;
}
        break;
-
      case 204: /* expr ::= expr likeop expr ESCAPE expr */
+
      case 203: /* expr ::= expr likeop expr ESCAPE expr */
{
  ExprList *pList;
  int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
@@ -169691,47 +172164,47 @@ static YYACTIONTYPE yy_reduce(
  if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc;
}
        break;
-
      case 205: /* expr ::= expr ISNULL|NOTNULL */
+
      case 204: /* expr ::= expr ISNULL|NOTNULL */
{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);}
        break;
-
      case 206: /* expr ::= expr NOT NULL */
+
      case 205: /* expr ::= expr NOT NULL */
{yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);}
        break;
-
      case 207: /* expr ::= expr IS expr */
+
      case 206: /* expr ::= expr IS expr */
{
  yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);
  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL);
}
        break;
-
      case 208: /* expr ::= expr IS NOT expr */
+
      case 207: /* expr ::= expr IS NOT expr */
{
  yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528);
  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL);
}
        break;
-
      case 209: /* expr ::= expr IS NOT DISTINCT FROM expr */
+
      case 208: /* 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 */
+
      case 209: /* 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);
+
      case 210: /* expr ::= NOT expr */
+
      case 211: /* expr ::= BITNOT expr */ yytestcase(yyruleno==211);
{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/}
        break;
-
      case 213: /* expr ::= PLUS|MINUS expr */
+
      case 212: /* 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 214: /* expr ::= expr PTR expr */
+
      case 213: /* expr ::= expr PTR expr */
{
  ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528);
  pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528);
@@ -169739,11 +172212,11 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[-2].minor.yy528 = yylhsminor.yy528;
        break;
-
      case 215: /* between_op ::= BETWEEN */
-
      case 218: /* in_op ::= IN */ yytestcase(yyruleno==218);
+
      case 214: /* between_op ::= BETWEEN */
+
      case 217: /* in_op ::= IN */ yytestcase(yyruleno==217);
{yymsp[0].minor.yy394 = 0;}
        break;
-
      case 217: /* expr ::= expr between_op expr AND expr */
+
      case 216: /* expr ::= expr between_op expr AND expr */
{
  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528);
  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528);
@@ -169756,7 +172229,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 220: /* expr ::= expr in_op LP exprlist RP */
+
      case 219: /* expr ::= expr in_op LP exprlist RP */
{
    if( yymsp[-1].minor.yy322==0 ){
      /* Expressions of the form
@@ -169777,6 +172250,11 @@ static YYACTIONTYPE yy_reduce(
        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
        pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
        yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS);
+
      }else if( yymsp[-1].minor.yy322->nExpr==1 && pRHS->op==TK_SELECT ){
+
        yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
+
        sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pRHS->x.pSelect);
+
        pRHS->x.pSelect = 0;
+
        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
      }else{
        yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0);
        if( yymsp[-4].minor.yy528==0 ){
@@ -169797,20 +172275,20 @@ static YYACTIONTYPE yy_reduce(
    }
  }
        break;
-
      case 221: /* expr ::= LP select RP */
+
      case 220: /* 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 222: /* expr ::= expr in_op LP select RP */
+
      case 221: /* 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 223: /* expr ::= expr in_op nm dbnm paren_exprlist */
+
      case 222: /* 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);
@@ -169820,14 +172298,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 224: /* expr ::= EXISTS LP select RP */
+
      case 223: /* 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 225: /* expr ::= CASE case_operand case_exprlist case_else END */
+
      case 224: /* 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 ){
@@ -169839,32 +172317,29 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 226: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+
      case 225: /* 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 227: /* case_exprlist ::= WHEN expr THEN expr */
+
      case 226: /* 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 230: /* case_operand ::= expr */
-
{yymsp[0].minor.yy528 = yymsp[0].minor.yy528; /*A-overwrites-X*/}
-
        break;
-
      case 233: /* nexprlist ::= nexprlist COMMA expr */
+
      case 231: /* nexprlist ::= nexprlist COMMA expr */
{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);}
        break;
-
      case 234: /* nexprlist ::= expr */
+
      case 232: /* nexprlist ::= expr */
{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/}
        break;
-
      case 236: /* paren_exprlist ::= LP exprlist RP */
-
      case 241: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==241);
+
      case 234: /* paren_exprlist ::= LP exprlist RP */
+
      case 239: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==239);
{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;}
        break;
-
      case 237: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
+
      case 235: /* 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,
@@ -169874,48 +172349,48 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 238: /* uniqueflag ::= UNIQUE */
-
      case 280: /* raisetype ::= ABORT */ yytestcase(yyruleno==280);
+
      case 236: /* uniqueflag ::= UNIQUE */
+
      case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278);
{yymsp[0].minor.yy394 = OE_Abort;}
        break;
-
      case 239: /* uniqueflag ::= */
+
      case 237: /* uniqueflag ::= */
{yymsp[1].minor.yy394 = OE_None;}
        break;
-
      case 242: /* eidlist ::= eidlist COMMA nm collate sortorder */
+
      case 240: /* 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 243: /* eidlist ::= nm collate sortorder */
+
      case 241: /* 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 246: /* cmd ::= DROP INDEX ifexists fullname */
+
      case 244: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);}
        break;
-
      case 247: /* cmd ::= VACUUM vinto */
+
      case 245: /* cmd ::= VACUUM vinto */
{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);}
        break;
-
      case 248: /* cmd ::= VACUUM nm vinto */
+
      case 246: /* cmd ::= VACUUM nm vinto */
{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);}
        break;
-
      case 251: /* cmd ::= PRAGMA nm dbnm */
+
      case 249: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
        break;
-
      case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+
      case 250: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
        break;
-
      case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+
      case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
        break;
-
      case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+
      case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
        break;
-
      case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+
      case 253: /* 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 258: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+
      case 256: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
  Token all;
  all.z = yymsp[-3].minor.yy0.z;
@@ -169923,50 +172398,50 @@ static YYACTIONTYPE yy_reduce(
  sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all);
}
        break;
-
      case 259: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+
      case 257: /* 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 260: /* trigger_time ::= BEFORE|AFTER */
+
      case 258: /* trigger_time ::= BEFORE|AFTER */
{ yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ }
        break;
-
      case 261: /* trigger_time ::= INSTEAD OF */
+
      case 259: /* trigger_time ::= INSTEAD OF */
{ yymsp[-1].minor.yy394 = TK_INSTEAD;}
        break;
-
      case 262: /* trigger_time ::= */
+
      case 260: /* trigger_time ::= */
{ yymsp[1].minor.yy394 = TK_BEFORE; }
        break;
-
      case 263: /* trigger_event ::= DELETE|INSERT */
-
      case 264: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==264);
+
      case 261: /* trigger_event ::= DELETE|INSERT */
+
      case 262: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==262);
{yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;}
        break;
-
      case 265: /* trigger_event ::= UPDATE OF idlist */
+
      case 263: /* trigger_event ::= UPDATE OF idlist */
{yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;}
        break;
-
      case 266: /* when_clause ::= */
-
      case 285: /* key_opt ::= */ yytestcase(yyruleno==285);
+
      case 264: /* when_clause ::= */
+
      case 283: /* key_opt ::= */ yytestcase(yyruleno==283);
{ yymsp[1].minor.yy528 = 0; }
        break;
-
      case 267: /* when_clause ::= WHEN expr */
-
      case 286: /* key_opt ::= KEY expr */ yytestcase(yyruleno==286);
+
      case 265: /* when_clause ::= WHEN expr */
+
      case 284: /* key_opt ::= KEY expr */ yytestcase(yyruleno==284);
{ yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; }
        break;
-
      case 268: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+
      case 266: /* 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 269: /* trigger_cmd_list ::= trigger_cmd SEMI */
+
      case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
  assert( yymsp[-1].minor.yy33!=0 );
  yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33;
}
        break;
-
      case 270: /* trnm ::= nm DOT nm */
+
      case 268: /* trnm ::= nm DOT nm */
{
  yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
  sqlite3ErrorMsg(pParse,
@@ -169974,39 +172449,39 @@ static YYACTIONTYPE yy_reduce(
        "statements within triggers");
}
        break;
-
      case 271: /* tridxby ::= INDEXED BY nm */
+
      case 269: /* tridxby ::= INDEXED BY nm */
{
  sqlite3ErrorMsg(pParse,
        "the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
        "within triggers");
}
        break;
-
      case 272: /* tridxby ::= NOT INDEXED */
+
      case 270: /* tridxby ::= NOT INDEXED */
{
  sqlite3ErrorMsg(pParse,
        "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
        "within triggers");
}
        break;
-
      case 273: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
+
      case 271: /* 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 274: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
+
      case 272: /* 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 275: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
+
      case 273: /* 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 276: /* trigger_cmd ::= scanpt select scanpt */
+
      case 274: /* 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 277: /* expr ::= RAISE LP IGNORE RP */
+
      case 275: /* expr ::= RAISE LP IGNORE RP */
{
  yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
  if( yymsp[-3].minor.yy528 ){
@@ -170014,7 +172489,7 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 278: /* expr ::= RAISE LP raisetype COMMA nm RP */
+
      case 276: /* 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 ) {
@@ -170022,118 +172497,118 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 279: /* raisetype ::= ROLLBACK */
+
      case 277: /* raisetype ::= ROLLBACK */
{yymsp[0].minor.yy394 = OE_Rollback;}
        break;
-
      case 281: /* raisetype ::= FAIL */
+
      case 279: /* raisetype ::= FAIL */
{yymsp[0].minor.yy394 = OE_Fail;}
        break;
-
      case 282: /* cmd ::= DROP TRIGGER ifexists fullname */
+
      case 280: /* cmd ::= DROP TRIGGER ifexists fullname */
{
  sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394);
}
        break;
-
      case 283: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+
      case 281: /* 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 284: /* cmd ::= DETACH database_kw_opt expr */
+
      case 282: /* cmd ::= DETACH database_kw_opt expr */
{
  sqlite3Detach(pParse, yymsp[0].minor.yy528);
}
        break;
-
      case 287: /* cmd ::= REINDEX */
+
      case 285: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
        break;
-
      case 288: /* cmd ::= REINDEX nm dbnm */
+
      case 286: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
        break;
-
      case 289: /* cmd ::= ANALYZE */
+
      case 287: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
        break;
-
      case 290: /* cmd ::= ANALYZE nm dbnm */
+
      case 288: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
        break;
-
      case 291: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+
      case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0);
}
        break;
-
      case 292: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
+
      case 290: /* 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 293: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
+
      case 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
{
  sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0);
}
        break;
-
      case 294: /* add_column_fullname ::= fullname */
+
      case 292: /* add_column_fullname ::= fullname */
{
  disableLookaside(pParse);
  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131);
}
        break;
-
      case 295: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
+
      case 293: /* 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 296: /* cmd ::= create_vtab */
+
      case 294: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
        break;
-
      case 297: /* cmd ::= create_vtab LP vtabarglist RP */
+
      case 295: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
        break;
-
      case 298: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+
      case 296: /* 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 299: /* vtabarg ::= */
+
      case 297: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
        break;
-
      case 300: /* vtabargtoken ::= ANY */
-
      case 301: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==301);
-
      case 302: /* lp ::= LP */ yytestcase(yyruleno==302);
+
      case 298: /* vtabargtoken ::= ANY */
+
      case 299: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==299);
+
      case 300: /* lp ::= LP */ yytestcase(yyruleno==300);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
        break;
-
      case 303: /* with ::= WITH wqlist */
-
      case 304: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==304);
+
      case 301: /* with ::= WITH wqlist */
+
      case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302);
{ sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); }
        break;
-
      case 305: /* wqas ::= AS */
+
      case 303: /* wqas ::= AS */
{yymsp[0].minor.yy516 = M10d_Any;}
        break;
-
      case 306: /* wqas ::= AS MATERIALIZED */
+
      case 304: /* wqas ::= AS MATERIALIZED */
{yymsp[-1].minor.yy516 = M10d_Yes;}
        break;
-
      case 307: /* wqas ::= AS NOT MATERIALIZED */
+
      case 305: /* wqas ::= AS NOT MATERIALIZED */
{yymsp[-2].minor.yy516 = M10d_No;}
        break;
-
      case 308: /* wqitem ::= nm eidlist_opt wqas LP select RP */
+
      case 306: /* 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 309: /* wqlist ::= wqitem */
+
      case 307: /* wqlist ::= wqitem */
{
  yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/
}
        break;
-
      case 310: /* wqlist ::= wqlist COMMA wqitem */
+
      case 308: /* wqlist ::= wqlist COMMA wqitem */
{
  yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385);
}
        break;
-
      case 311: /* windowdefn_list ::= windowdefn */
+
      case 309: /* windowdefn_list ::= windowdefn */
{ yylhsminor.yy41 = yymsp[0].minor.yy41; }
  yymsp[0].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 312: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
+
      case 310: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
{
  assert( yymsp[0].minor.yy41!=0 );
  sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41);
@@ -170142,7 +172617,7 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[-2].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 313: /* windowdefn ::= nm AS LP window RP */
+
      case 311: /* 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);
@@ -170151,90 +172626,90 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[-4].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 314: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
+
      case 312: /* 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 315: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
+
      case 313: /* 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 316: /* window ::= ORDER BY sortlist frame_opt */
+
      case 314: /* window ::= ORDER BY sortlist frame_opt */
{
  yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0);
}
        break;
-
      case 317: /* window ::= nm ORDER BY sortlist frame_opt */
+
      case 315: /* 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 318: /* window ::= frame_opt */
-
      case 337: /* filter_over ::= over_clause */ yytestcase(yyruleno==337);
+
      case 316: /* window ::= frame_opt */
+
      case 335: /* filter_over ::= over_clause */ yytestcase(yyruleno==335);
{
  yylhsminor.yy41 = yymsp[0].minor.yy41;
}
  yymsp[0].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 319: /* window ::= nm frame_opt */
+
      case 317: /* 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 320: /* frame_opt ::= */
+
      case 318: /* frame_opt ::= */
{
  yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
}
        break;
-
      case 321: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
+
      case 319: /* 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 322: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
+
      case 320: /* 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 324: /* frame_bound_s ::= frame_bound */
-
      case 326: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==326);
+
      case 322: /* frame_bound_s ::= frame_bound */
+
      case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324);
{yylhsminor.yy595 = yymsp[0].minor.yy595;}
  yymsp[0].minor.yy595 = yylhsminor.yy595;
        break;
-
      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);
+
      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);
{yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;}
  yymsp[-1].minor.yy595 = yylhsminor.yy595;
        break;
-
      case 328: /* frame_bound ::= expr PRECEDING|FOLLOWING */
+
      case 326: /* 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 330: /* frame_exclude_opt ::= */
+
      case 328: /* frame_exclude_opt ::= */
{yymsp[1].minor.yy516 = 0;}
        break;
-
      case 331: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
+
      case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
{yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;}
        break;
-
      case 332: /* frame_exclude ::= NO OTHERS */
-
      case 333: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==333);
+
      case 330: /* frame_exclude ::= NO OTHERS */
+
      case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331);
{yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/}
        break;
-
      case 334: /* frame_exclude ::= GROUP|TIES */
+
      case 332: /* frame_exclude ::= GROUP|TIES */
{yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/}
        break;
-
      case 335: /* window_clause ::= WINDOW windowdefn_list */
+
      case 333: /* window_clause ::= WINDOW windowdefn_list */
{ yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; }
        break;
-
      case 336: /* filter_over ::= filter_clause over_clause */
+
      case 334: /* filter_over ::= filter_clause over_clause */
{
  if( yymsp[0].minor.yy41 ){
    yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528;
@@ -170245,7 +172720,7 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[-1].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 338: /* filter_over ::= filter_clause */
+
      case 336: /* filter_over ::= filter_clause */
{
  yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  if( yylhsminor.yy41 ){
@@ -170257,13 +172732,13 @@ static YYACTIONTYPE yy_reduce(
}
  yymsp[0].minor.yy41 = yylhsminor.yy41;
        break;
-
      case 339: /* over_clause ::= OVER LP window RP */
+
      case 337: /* over_clause ::= OVER LP window RP */
{
  yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41;
  assert( yymsp[-3].minor.yy41!=0 );
}
        break;
-
      case 340: /* over_clause ::= OVER nm */
+
      case 338: /* over_clause ::= OVER nm */
{
  yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  if( yymsp[-1].minor.yy41 ){
@@ -170271,73 +172746,73 @@ static YYACTIONTYPE yy_reduce(
  }
}
        break;
-
      case 341: /* filter_clause ::= FILTER LP WHERE expr RP */
+
      case 339: /* filter_clause ::= FILTER LP WHERE expr RP */
{ yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; }
        break;
      default:
-
      /* (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);
+
      /* (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|JOIN_KW */ yytestcase(yyruleno==355);
+
      /* (356) nm ::= STRING */ yytestcase(yyruleno==356);
+
      /* (357) typetoken ::= typename */ yytestcase(yyruleno==357);
+
      /* (358) typename ::= ID|STRING */ yytestcase(yyruleno==358);
+
      /* (359) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=359);
+
      /* (360) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=360);
+
      /* (361) carglist ::= carglist ccons */ yytestcase(yyruleno==361);
+
      /* (362) carglist ::= */ yytestcase(yyruleno==362);
+
      /* (363) ccons ::= NULL onconf */ yytestcase(yyruleno==363);
+
      /* (364) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==364);
+
      /* (365) ccons ::= AS generated */ yytestcase(yyruleno==365);
+
      /* (366) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==366);
+
      /* (367) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==367);
+
      /* (368) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=368);
+
      /* (369) tconscomma ::= */ yytestcase(yyruleno==369);
+
      /* (370) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=370);
+
      /* (371) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=371);
+
      /* (372) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=372);
+
      /* (373) oneselect ::= values */ yytestcase(yyruleno==373);
+
      /* (374) sclp ::= selcollist COMMA */ yytestcase(yyruleno==374);
+
      /* (375) as ::= ID|STRING */ yytestcase(yyruleno==375);
+
      /* (376) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=376);
+
      /* (377) returning ::= */ yytestcase(yyruleno==377);
+
      /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378);
+
      /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379);
+
      /* (380) case_operand ::= expr */ yytestcase(yyruleno==380);
+
      /* (381) exprlist ::= nexprlist */ yytestcase(yyruleno==381);
+
      /* (382) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=382);
+
      /* (383) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=383);
+
      /* (384) nmnum ::= ON */ yytestcase(yyruleno==384);
+
      /* (385) nmnum ::= DELETE */ yytestcase(yyruleno==385);
+
      /* (386) nmnum ::= DEFAULT */ yytestcase(yyruleno==386);
+
      /* (387) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==387);
+
      /* (388) foreach_clause ::= */ yytestcase(yyruleno==388);
+
      /* (389) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==389);
+
      /* (390) trnm ::= nm */ yytestcase(yyruleno==390);
+
      /* (391) tridxby ::= */ yytestcase(yyruleno==391);
+
      /* (392) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==392);
+
      /* (393) database_kw_opt ::= */ yytestcase(yyruleno==393);
+
      /* (394) kwcolumn_opt ::= */ yytestcase(yyruleno==394);
+
      /* (395) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==395);
+
      /* (396) vtabarglist ::= vtabarg */ yytestcase(yyruleno==396);
+
      /* (397) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==397);
+
      /* (398) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==398);
+
      /* (399) anylist ::= */ yytestcase(yyruleno==399);
+
      /* (400) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==400);
+
      /* (401) anylist ::= anylist ANY */ yytestcase(yyruleno==401);
+
      /* (402) with ::= */ yytestcase(yyruleno==402);
        break;
/********** End reduce actions ************************************************/
  };
@@ -170913,7 +173388,7 @@ static const unsigned char aKWHash[127] = {
/* aKWNext[] forms the hash collision chain.  If aKWHash[i]==0
** then the i-th keyword has no more hash collisions.  Otherwise,
** the next keyword with the same hash is aKWHash[i]-1. */
-
static const unsigned char aKWNext[147] = {
+
static const unsigned char aKWNext[148] = {0,
     0,   0,   0,   0,   4,   0,  43,   0,   0, 106, 114,   0,   0,
     0,   2,   0,   0, 143,   0,   0,   0,  13,   0,   0,   0,   0,
   141,   0,   0, 119,  52,   0,   0, 137,  12,   0,   0,  62,   0,
@@ -170928,7 +173403,7 @@ static const unsigned char aKWNext[147] = {
   102,   0,   0,  87,
};
/* aKWLen[i] is the length (in bytes) of the i-th keyword */
-
static const unsigned char aKWLen[147] = {
+
static const unsigned char aKWLen[148] = {0,
     7,   7,   5,   4,   6,   4,   5,   3,   6,   7,   3,   6,   6,
     7,   7,   3,   8,   2,   6,   5,   4,   4,   3,  10,   4,   7,
     6,   9,   4,   2,   6,   5,   9,   9,   4,   7,   3,   2,   4,
@@ -170944,7 +173419,7 @@ static const unsigned char aKWLen[147] = {
};
/* aKWOffset[i] is the index into zKWText[] of the start of
** the text for the i-th keyword. */
-
static const unsigned short int aKWOffset[147] = {
+
static const unsigned short int aKWOffset[148] = {0,
     0,   2,   2,   8,   9,  14,  16,  20,  23,  25,  25,  29,  33,
    36,  41,  46,  48,  53,  54,  59,  62,  65,  67,  69,  78,  81,
    86,  90,  90,  94,  99, 101, 105, 111, 119, 123, 123, 123, 126,
@@ -170959,7 +173434,7 @@ static const unsigned short int aKWOffset[147] = {
   648, 650, 655, 659,
};
/* aKWCode[i] is the parser symbol code for the i-th keyword */
-
static const unsigned char aKWCode[147] = {
+
static const unsigned char aKWCode[148] = {0,
  TK_REINDEX,    TK_INDEXED,    TK_INDEX,      TK_DESC,       TK_ESCAPE,
  TK_EACH,       TK_CHECK,      TK_KEY,        TK_BEFORE,     TK_FOREIGN,
  TK_FOR,        TK_IGNORE,     TK_LIKE_KW,    TK_EXPLAIN,    TK_INSTEAD,
@@ -171128,7 +173603,7 @@ static int keywordCode(const char *z, int n, int *pType){
  const char *zKW;
  if( n>=2 ){
    i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127;
-
    for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){
+
    for(i=(int)aKWHash[i]; i>0; i=aKWNext[i]){
      if( aKWLen[i]!=n ) continue;
      zKW = &zKWText[aKWOffset[i]];
#ifdef SQLITE_ASCII
@@ -171144,153 +173619,153 @@ static int keywordCode(const char *z, int n, int *pType){
      while( j<n && toupper(z[j])==zKW[j] ){ j++; }
#endif
      if( j<n ) continue;
-
      testcase( i==0 ); /* REINDEX */
-
      testcase( i==1 ); /* INDEXED */
-
      testcase( i==2 ); /* INDEX */
-
      testcase( i==3 ); /* DESC */
-
      testcase( i==4 ); /* ESCAPE */
-
      testcase( i==5 ); /* EACH */
-
      testcase( i==6 ); /* CHECK */
-
      testcase( i==7 ); /* KEY */
-
      testcase( i==8 ); /* BEFORE */
-
      testcase( i==9 ); /* FOREIGN */
-
      testcase( i==10 ); /* FOR */
-
      testcase( i==11 ); /* IGNORE */
-
      testcase( i==12 ); /* REGEXP */
-
      testcase( i==13 ); /* EXPLAIN */
-
      testcase( i==14 ); /* INSTEAD */
-
      testcase( i==15 ); /* ADD */
-
      testcase( i==16 ); /* DATABASE */
-
      testcase( i==17 ); /* AS */
-
      testcase( i==18 ); /* SELECT */
-
      testcase( i==19 ); /* TABLE */
-
      testcase( i==20 ); /* LEFT */
-
      testcase( i==21 ); /* THEN */
-
      testcase( i==22 ); /* END */
-
      testcase( i==23 ); /* DEFERRABLE */
-
      testcase( i==24 ); /* ELSE */
-
      testcase( i==25 ); /* EXCLUDE */
-
      testcase( i==26 ); /* DELETE */
-
      testcase( i==27 ); /* TEMPORARY */
-
      testcase( i==28 ); /* TEMP */
-
      testcase( i==29 ); /* OR */
-
      testcase( i==30 ); /* ISNULL */
-
      testcase( i==31 ); /* NULLS */
-
      testcase( i==32 ); /* SAVEPOINT */
-
      testcase( i==33 ); /* INTERSECT */
-
      testcase( i==34 ); /* TIES */
-
      testcase( i==35 ); /* NOTNULL */
-
      testcase( i==36 ); /* NOT */
-
      testcase( i==37 ); /* NO */
-
      testcase( i==38 ); /* NULL */
-
      testcase( i==39 ); /* LIKE */
-
      testcase( i==40 ); /* EXCEPT */
-
      testcase( i==41 ); /* TRANSACTION */
-
      testcase( i==42 ); /* ACTION */
-
      testcase( i==43 ); /* ON */
-
      testcase( i==44 ); /* NATURAL */
-
      testcase( i==45 ); /* ALTER */
-
      testcase( i==46 ); /* RAISE */
-
      testcase( i==47 ); /* EXCLUSIVE */
-
      testcase( i==48 ); /* EXISTS */
-
      testcase( i==49 ); /* CONSTRAINT */
-
      testcase( i==50 ); /* INTO */
-
      testcase( i==51 ); /* OFFSET */
-
      testcase( i==52 ); /* OF */
-
      testcase( i==53 ); /* SET */
-
      testcase( i==54 ); /* TRIGGER */
-
      testcase( i==55 ); /* RANGE */
-
      testcase( i==56 ); /* GENERATED */
-
      testcase( i==57 ); /* DETACH */
-
      testcase( i==58 ); /* HAVING */
-
      testcase( i==59 ); /* GLOB */
-
      testcase( i==60 ); /* BEGIN */
-
      testcase( i==61 ); /* INNER */
-
      testcase( i==62 ); /* REFERENCES */
-
      testcase( i==63 ); /* UNIQUE */
-
      testcase( i==64 ); /* QUERY */
-
      testcase( i==65 ); /* WITHOUT */
-
      testcase( i==66 ); /* WITH */
-
      testcase( i==67 ); /* OUTER */
-
      testcase( i==68 ); /* RELEASE */
-
      testcase( i==69 ); /* ATTACH */
-
      testcase( i==70 ); /* BETWEEN */
-
      testcase( i==71 ); /* NOTHING */
-
      testcase( i==72 ); /* GROUPS */
-
      testcase( i==73 ); /* GROUP */
-
      testcase( i==74 ); /* CASCADE */
-
      testcase( i==75 ); /* ASC */
-
      testcase( i==76 ); /* DEFAULT */
-
      testcase( i==77 ); /* CASE */
-
      testcase( i==78 ); /* COLLATE */
-
      testcase( i==79 ); /* CREATE */
-
      testcase( i==80 ); /* CURRENT_DATE */
-
      testcase( i==81 ); /* IMMEDIATE */
-
      testcase( i==82 ); /* JOIN */
-
      testcase( i==83 ); /* INSERT */
-
      testcase( i==84 ); /* MATCH */
-
      testcase( i==85 ); /* PLAN */
-
      testcase( i==86 ); /* ANALYZE */
-
      testcase( i==87 ); /* PRAGMA */
-
      testcase( i==88 ); /* MATERIALIZED */
-
      testcase( i==89 ); /* DEFERRED */
-
      testcase( i==90 ); /* DISTINCT */
-
      testcase( i==91 ); /* IS */
-
      testcase( i==92 ); /* UPDATE */
-
      testcase( i==93 ); /* VALUES */
-
      testcase( i==94 ); /* VIRTUAL */
-
      testcase( i==95 ); /* ALWAYS */
-
      testcase( i==96 ); /* WHEN */
-
      testcase( i==97 ); /* WHERE */
-
      testcase( i==98 ); /* RECURSIVE */
-
      testcase( i==99 ); /* ABORT */
-
      testcase( i==100 ); /* AFTER */
-
      testcase( i==101 ); /* RENAME */
-
      testcase( i==102 ); /* AND */
-
      testcase( i==103 ); /* DROP */
-
      testcase( i==104 ); /* PARTITION */
-
      testcase( i==105 ); /* AUTOINCREMENT */
-
      testcase( i==106 ); /* TO */
-
      testcase( i==107 ); /* IN */
-
      testcase( i==108 ); /* CAST */
-
      testcase( i==109 ); /* COLUMN */
-
      testcase( i==110 ); /* COMMIT */
-
      testcase( i==111 ); /* CONFLICT */
-
      testcase( i==112 ); /* CROSS */
-
      testcase( i==113 ); /* CURRENT_TIMESTAMP */
-
      testcase( i==114 ); /* CURRENT_TIME */
-
      testcase( i==115 ); /* CURRENT */
-
      testcase( i==116 ); /* PRECEDING */
-
      testcase( i==117 ); /* FAIL */
-
      testcase( i==118 ); /* LAST */
-
      testcase( i==119 ); /* FILTER */
-
      testcase( i==120 ); /* REPLACE */
-
      testcase( i==121 ); /* FIRST */
-
      testcase( i==122 ); /* FOLLOWING */
-
      testcase( i==123 ); /* FROM */
-
      testcase( i==124 ); /* FULL */
-
      testcase( i==125 ); /* LIMIT */
-
      testcase( i==126 ); /* IF */
-
      testcase( i==127 ); /* ORDER */
-
      testcase( i==128 ); /* RESTRICT */
-
      testcase( i==129 ); /* OTHERS */
-
      testcase( i==130 ); /* OVER */
-
      testcase( i==131 ); /* RETURNING */
-
      testcase( i==132 ); /* RIGHT */
-
      testcase( i==133 ); /* ROLLBACK */
-
      testcase( i==134 ); /* ROWS */
-
      testcase( i==135 ); /* ROW */
-
      testcase( i==136 ); /* UNBOUNDED */
-
      testcase( i==137 ); /* UNION */
-
      testcase( i==138 ); /* USING */
-
      testcase( i==139 ); /* VACUUM */
-
      testcase( i==140 ); /* VIEW */
-
      testcase( i==141 ); /* WINDOW */
-
      testcase( i==142 ); /* DO */
-
      testcase( i==143 ); /* BY */
-
      testcase( i==144 ); /* INITIALLY */
-
      testcase( i==145 ); /* ALL */
-
      testcase( i==146 ); /* PRIMARY */
+
      testcase( i==1 ); /* REINDEX */
+
      testcase( i==2 ); /* INDEXED */
+
      testcase( i==3 ); /* INDEX */
+
      testcase( i==4 ); /* DESC */
+
      testcase( i==5 ); /* ESCAPE */
+
      testcase( i==6 ); /* EACH */
+
      testcase( i==7 ); /* CHECK */
+
      testcase( i==8 ); /* KEY */
+
      testcase( i==9 ); /* BEFORE */
+
      testcase( i==10 ); /* FOREIGN */
+
      testcase( i==11 ); /* FOR */
+
      testcase( i==12 ); /* IGNORE */
+
      testcase( i==13 ); /* REGEXP */
+
      testcase( i==14 ); /* EXPLAIN */
+
      testcase( i==15 ); /* INSTEAD */
+
      testcase( i==16 ); /* ADD */
+
      testcase( i==17 ); /* DATABASE */
+
      testcase( i==18 ); /* AS */
+
      testcase( i==19 ); /* SELECT */
+
      testcase( i==20 ); /* TABLE */
+
      testcase( i==21 ); /* LEFT */
+
      testcase( i==22 ); /* THEN */
+
      testcase( i==23 ); /* END */
+
      testcase( i==24 ); /* DEFERRABLE */
+
      testcase( i==25 ); /* ELSE */
+
      testcase( i==26 ); /* EXCLUDE */
+
      testcase( i==27 ); /* DELETE */
+
      testcase( i==28 ); /* TEMPORARY */
+
      testcase( i==29 ); /* TEMP */
+
      testcase( i==30 ); /* OR */
+
      testcase( i==31 ); /* ISNULL */
+
      testcase( i==32 ); /* NULLS */
+
      testcase( i==33 ); /* SAVEPOINT */
+
      testcase( i==34 ); /* INTERSECT */
+
      testcase( i==35 ); /* TIES */
+
      testcase( i==36 ); /* NOTNULL */
+
      testcase( i==37 ); /* NOT */
+
      testcase( i==38 ); /* NO */
+
      testcase( i==39 ); /* NULL */
+
      testcase( i==40 ); /* LIKE */
+
      testcase( i==41 ); /* EXCEPT */
+
      testcase( i==42 ); /* TRANSACTION */
+
      testcase( i==43 ); /* ACTION */
+
      testcase( i==44 ); /* ON */
+
      testcase( i==45 ); /* NATURAL */
+
      testcase( i==46 ); /* ALTER */
+
      testcase( i==47 ); /* RAISE */
+
      testcase( i==48 ); /* EXCLUSIVE */
+
      testcase( i==49 ); /* EXISTS */
+
      testcase( i==50 ); /* CONSTRAINT */
+
      testcase( i==51 ); /* INTO */
+
      testcase( i==52 ); /* OFFSET */
+
      testcase( i==53 ); /* OF */
+
      testcase( i==54 ); /* SET */
+
      testcase( i==55 ); /* TRIGGER */
+
      testcase( i==56 ); /* RANGE */
+
      testcase( i==57 ); /* GENERATED */
+
      testcase( i==58 ); /* DETACH */
+
      testcase( i==59 ); /* HAVING */
+
      testcase( i==60 ); /* GLOB */
+
      testcase( i==61 ); /* BEGIN */
+
      testcase( i==62 ); /* INNER */
+
      testcase( i==63 ); /* REFERENCES */
+
      testcase( i==64 ); /* UNIQUE */
+
      testcase( i==65 ); /* QUERY */
+
      testcase( i==66 ); /* WITHOUT */
+
      testcase( i==67 ); /* WITH */
+
      testcase( i==68 ); /* OUTER */
+
      testcase( i==69 ); /* RELEASE */
+
      testcase( i==70 ); /* ATTACH */
+
      testcase( i==71 ); /* BETWEEN */
+
      testcase( i==72 ); /* NOTHING */
+
      testcase( i==73 ); /* GROUPS */
+
      testcase( i==74 ); /* GROUP */
+
      testcase( i==75 ); /* CASCADE */
+
      testcase( i==76 ); /* ASC */
+
      testcase( i==77 ); /* DEFAULT */
+
      testcase( i==78 ); /* CASE */
+
      testcase( i==79 ); /* COLLATE */
+
      testcase( i==80 ); /* CREATE */
+
      testcase( i==81 ); /* CURRENT_DATE */
+
      testcase( i==82 ); /* IMMEDIATE */
+
      testcase( i==83 ); /* JOIN */
+
      testcase( i==84 ); /* INSERT */
+
      testcase( i==85 ); /* MATCH */
+
      testcase( i==86 ); /* PLAN */
+
      testcase( i==87 ); /* ANALYZE */
+
      testcase( i==88 ); /* PRAGMA */
+
      testcase( i==89 ); /* MATERIALIZED */
+
      testcase( i==90 ); /* DEFERRED */
+
      testcase( i==91 ); /* DISTINCT */
+
      testcase( i==92 ); /* IS */
+
      testcase( i==93 ); /* UPDATE */
+
      testcase( i==94 ); /* VALUES */
+
      testcase( i==95 ); /* VIRTUAL */
+
      testcase( i==96 ); /* ALWAYS */
+
      testcase( i==97 ); /* WHEN */
+
      testcase( i==98 ); /* WHERE */
+
      testcase( i==99 ); /* RECURSIVE */
+
      testcase( i==100 ); /* ABORT */
+
      testcase( i==101 ); /* AFTER */
+
      testcase( i==102 ); /* RENAME */
+
      testcase( i==103 ); /* AND */
+
      testcase( i==104 ); /* DROP */
+
      testcase( i==105 ); /* PARTITION */
+
      testcase( i==106 ); /* AUTOINCREMENT */
+
      testcase( i==107 ); /* TO */
+
      testcase( i==108 ); /* IN */
+
      testcase( i==109 ); /* CAST */
+
      testcase( i==110 ); /* COLUMN */
+
      testcase( i==111 ); /* COMMIT */
+
      testcase( i==112 ); /* CONFLICT */
+
      testcase( i==113 ); /* CROSS */
+
      testcase( i==114 ); /* CURRENT_TIMESTAMP */
+
      testcase( i==115 ); /* CURRENT_TIME */
+
      testcase( i==116 ); /* CURRENT */
+
      testcase( i==117 ); /* PRECEDING */
+
      testcase( i==118 ); /* FAIL */
+
      testcase( i==119 ); /* LAST */
+
      testcase( i==120 ); /* FILTER */
+
      testcase( i==121 ); /* REPLACE */
+
      testcase( i==122 ); /* FIRST */
+
      testcase( i==123 ); /* FOLLOWING */
+
      testcase( i==124 ); /* FROM */
+
      testcase( i==125 ); /* FULL */
+
      testcase( i==126 ); /* LIMIT */
+
      testcase( i==127 ); /* IF */
+
      testcase( i==128 ); /* ORDER */
+
      testcase( i==129 ); /* RESTRICT */
+
      testcase( i==130 ); /* OTHERS */
+
      testcase( i==131 ); /* OVER */
+
      testcase( i==132 ); /* RETURNING */
+
      testcase( i==133 ); /* RIGHT */
+
      testcase( i==134 ); /* ROLLBACK */
+
      testcase( i==135 ); /* ROWS */
+
      testcase( i==136 ); /* ROW */
+
      testcase( i==137 ); /* UNBOUNDED */
+
      testcase( i==138 ); /* UNION */
+
      testcase( i==139 ); /* USING */
+
      testcase( i==140 ); /* VACUUM */
+
      testcase( i==141 ); /* VIEW */
+
      testcase( i==142 ); /* WINDOW */
+
      testcase( i==143 ); /* DO */
+
      testcase( i==144 ); /* BY */
+
      testcase( i==145 ); /* INITIALLY */
+
      testcase( i==146 ); /* ALL */
+
      testcase( i==147 ); /* PRIMARY */
      *pType = aKWCode[i];
      break;
    }
@@ -171305,6 +173780,7 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
#define SQLITE_N_KEYWORD 147
SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){
  if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR;
+
  i++;
  *pzName = zKWText + aKWOffset[i];
  *pnName = aKWLen[i];
  return SQLITE_OK;
@@ -172843,9 +175319,21 @@ SQLITE_API int sqlite3_config(int op, ...){
  va_list ap;
  int rc = SQLITE_OK;

-
  /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while
-
  ** the SQLite library is in use. */
-
  if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT;
+
  /* sqlite3_config() normally returns SQLITE_MISUSE if it is invoked while
+
  ** the SQLite library is in use.  Except, a few selected opcodes
+
  ** are allowed.
+
  */
+
  if( sqlite3GlobalConfig.isInit ){
+
    static const u64 mAnytimeConfigOption = 0
+
       | MASKBIT64( SQLITE_CONFIG_LOG )
+
       | MASKBIT64( SQLITE_CONFIG_PCACHE_HDRSZ )
+
    ;
+
    if( op<0 || op>63 || (MASKBIT64(op) & mAnytimeConfigOption)==0 ){
+
      return SQLITE_MISUSE_BKPT;
+
    }
+
    testcase( op==SQLITE_CONFIG_LOG );
+
    testcase( op==SQLITE_CONFIG_PCACHE_HDRSZ );
+
  }

  va_start(ap, op);
  switch( op ){
@@ -172914,6 +175402,7 @@ SQLITE_API int sqlite3_config(int op, ...){
      break;
    }
    case SQLITE_CONFIG_MEMSTATUS: {
+
      assert( !sqlite3GlobalConfig.isInit );  /* Cannot change at runtime */
      /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes
      ** single argument of type int, interpreted as a boolean, which enables
      ** or disables the collection of memory allocation statistics. */
@@ -173037,8 +175526,10 @@ SQLITE_API int sqlite3_config(int op, ...){
      ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*));
      */
      typedef void(*LOGFUNC_t)(void*,int,const char*);
-
      sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t);
-
      sqlite3GlobalConfig.pLogArg = va_arg(ap, void*);
+
      LOGFUNC_t xLog = va_arg(ap, LOGFUNC_t);
+
      void *pLogArg = va_arg(ap, void*);
+
      AtomicStore(&sqlite3GlobalConfig.xLog, xLog);
+
      AtomicStore(&sqlite3GlobalConfig.pLogArg, pLogArg);
      break;
    }

@@ -173052,7 +175543,8 @@ SQLITE_API int sqlite3_config(int op, ...){
      ** argument of type int. If non-zero, then URI handling is globally
      ** enabled. If the parameter is zero, then URI handling is globally
      ** disabled. */
-
      sqlite3GlobalConfig.bOpenUri = va_arg(ap, int);
+
      int bOpenUri = va_arg(ap, int);
+
      AtomicStore(&sqlite3GlobalConfig.bOpenUri, bOpenUri);
      break;
    }

@@ -173367,6 +175859,8 @@ SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
        { SQLITE_DBCONFIG_DQS_DML,               SQLITE_DqsDML         },
        { SQLITE_DBCONFIG_LEGACY_FILE_FORMAT,    SQLITE_LegacyFileFmt  },
        { SQLITE_DBCONFIG_TRUSTED_SCHEMA,        SQLITE_TrustedSchema  },
+
        { SQLITE_DBCONFIG_STMT_SCANSTATUS,       SQLITE_StmtScanStatus },
+
        { SQLITE_DBCONFIG_REVERSE_SCANORDER,     SQLITE_ReverseOrder   },
      };
      unsigned int i;
      rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
@@ -173979,6 +176473,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
      case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break;
      case SQLITE_NOTICE_RECOVER_ROLLBACK:
                                zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break;
+
      case SQLITE_NOTICE_RBU:         zName = "SQLITE_NOTICE_RBU"; break;
      case SQLITE_WARNING:            zName = "SQLITE_WARNING";           break;
      case SQLITE_WARNING_AUTOINDEX:  zName = "SQLITE_WARNING_AUTOINDEX"; break;
      case SQLITE_DONE:               zName = "SQLITE_DONE";              break;
@@ -174208,7 +176703,9 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
*/
SQLITE_API void sqlite3_interrupt(sqlite3 *db){
#ifdef SQLITE_ENABLE_API_ARMOR
-
  if( !sqlite3SafetyCheckOk(db) && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) ){
+
  if( !sqlite3SafetyCheckOk(db)
+
   && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE)
+
  ){
    (void)SQLITE_MISUSE_BKPT;
    return;
  }
@@ -174216,6 +176713,21 @@ SQLITE_API void sqlite3_interrupt(sqlite3 *db){
  AtomicStore(&db->u1.isInterrupted, 1);
}

+
/*
+
** Return true or false depending on whether or not an interrupt is
+
** pending on connection db.
+
*/
+
SQLITE_API int sqlite3_is_interrupted(sqlite3 *db){
+
#ifdef SQLITE_ENABLE_API_ARMOR
+
  if( !sqlite3SafetyCheckOk(db)
+
   && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE)
+
  ){
+
    (void)SQLITE_MISUSE_BKPT;
+
    return 0;
+
  }
+
#endif
+
  return AtomicLoad(&db->u1.isInterrupted)!=0;
+
}

/*
** This function is exactly the same as sqlite3_create_function(), except
@@ -174260,7 +176772,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
  /* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE.  But
  ** the meaning is inverted.  So flip the bit. */
  assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS );
-
  extraFlags ^= SQLITE_FUNC_UNSAFE;
+
  extraFlags ^= SQLITE_FUNC_UNSAFE;  /* tag-20230109-1 */


#ifndef SQLITE_OMIT_UTF16
@@ -174278,11 +176790,11 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
    case SQLITE_ANY: {
      int rc;
      rc = sqlite3CreateFunc(db, zFunctionName, nArg,
-
           (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE,
+
           (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, /* tag-20230109-1 */
           pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
      if( rc==SQLITE_OK ){
        rc = sqlite3CreateFunc(db, zFunctionName, nArg,
-
             (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE,
+
             (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, /* tag-20230109-1*/
             pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor);
      }
      if( rc!=SQLITE_OK ){
@@ -174531,7 +177043,7 @@ SQLITE_API int sqlite3_overload_function(
  rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0;
  sqlite3_mutex_leave(db->mutex);
  if( rc ) return SQLITE_OK;
-
  zCopy = sqlite3_mprintf(zName);
+
  zCopy = sqlite3_mprintf("%s", zName);
  if( zCopy==0 ) return SQLITE_NOMEM;
  return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8,
                           zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free);
@@ -175334,9 +177846,9 @@ SQLITE_PRIVATE int sqlite3ParseUri(

  assert( *pzErrMsg==0 );

-
  if( ((flags & SQLITE_OPEN_URI)             /* IMP: R-48725-32206 */
-
            || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */
-
   && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */
+
  if( ((flags & SQLITE_OPEN_URI)                     /* IMP: R-48725-32206 */
+
       || AtomicLoad(&sqlite3GlobalConfig.bOpenUri)) /* IMP: R-51689-46548 */
+
   && nUri>=5 && memcmp(zUri, "file:", 5)==0         /* IMP: R-57884-37496 */
  ){
    char *zOpt;
    int eState;                   /* Parser state when parsing URI */
@@ -175743,6 +178255,9 @@ static int openDatabase(
#if defined(SQLITE_DEFAULT_LEGACY_ALTER_TABLE)
                 | SQLITE_LegacyAlter
#endif
+
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+
                 | SQLITE_StmtScanStatus
+
#endif
      ;
  sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -176307,7 +178822,7 @@ SQLITE_API int sqlite3_sleep(int ms){
  /* This function works in milliseconds, but the underlying OsSleep()
  ** API uses microseconds. Hence the 1000's.
  */
-
  rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000);
+
  rc = (sqlite3OsSleep(pVfs, ms<0 ? 0 : 1000*ms)/1000);
  return rc;
}

@@ -176363,6 +178878,9 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo
        sqlite3BtreeSetPageSize(pBtree, 0, iNew, 0);
      }
      rc = SQLITE_OK;
+
    }else if( op==SQLITE_FCNTL_RESET_CACHE ){
+
      sqlite3BtreeClearCache(pBtree);
+
      rc = SQLITE_OK;
    }else{
      int nSave = db->busyHandler.nBusy;
      rc = sqlite3OsFileControl(fd, op, pArg);
@@ -178861,6 +181379,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int);
SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int);
#endif

+
SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*);
+

#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
#endif /* _FTSINT_H */

@@ -183864,9 +186384,8 @@ static void fts3EvalNextRow(
  Fts3Expr *pExpr,                /* Expr. to advance to next matching row */
  int *pRc                        /* IN/OUT: Error code */
){
-
  if( *pRc==SQLITE_OK ){
+
  if( *pRc==SQLITE_OK && pExpr->bEof==0 ){
    int bDescDoclist = pCsr->bDesc;         /* Used by DOCID_CMP() macro */
-
    assert( pExpr->bEof==0 );
    pExpr->bStart = 1;

    switch( pExpr->eType ){
@@ -184343,6 +186862,22 @@ static void fts3EvalUpdateCounts(Fts3Expr *pExpr, int nCol){
}

/*
+
** This is an sqlite3Fts3ExprIterate() callback. If the Fts3Expr.aMI[] array
+
** has not yet been allocated, allocate and zero it. Otherwise, just zero
+
** it.
+
*/
+
static int fts3AllocateMSI(Fts3Expr *pExpr, int iPhrase, void *pCtx){
+
  Fts3Table *pTab = (Fts3Table*)pCtx;
+
  UNUSED_PARAMETER(iPhrase);
+
  if( pExpr->aMI==0 ){
+
    pExpr->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32));
+
    if( pExpr->aMI==0 ) return SQLITE_NOMEM;
+
  }
+
  memset(pExpr->aMI, 0, pTab->nColumn * 3 * sizeof(u32));
+
  return SQLITE_OK;
+
}
+

+
/*
** Expression pExpr must be of type FTSQUERY_PHRASE.
**
** If it is not already allocated and populated, this function allocates and
@@ -184363,7 +186898,6 @@ static int fts3EvalGatherStats(
  if( pExpr->aMI==0 ){
    Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
    Fts3Expr *pRoot;                /* Root of NEAR expression */
-
    Fts3Expr *p;                    /* Iterator used for several purposes */

    sqlite3_int64 iPrevId = pCsr->iPrevId;
    sqlite3_int64 iDocid;
@@ -184371,7 +186905,9 @@ static int fts3EvalGatherStats(

    /* Find the root of the NEAR expression */
    pRoot = pExpr;
-
    while( pRoot->pParent && pRoot->pParent->eType==FTSQUERY_NEAR ){
+
    while( pRoot->pParent
+
        && (pRoot->pParent->eType==FTSQUERY_NEAR || pRoot->bDeferred)
+
    ){
      pRoot = pRoot->pParent;
    }
    iDocid = pRoot->iDocid;
@@ -184379,14 +186915,8 @@ static int fts3EvalGatherStats(
    assert( pRoot->bStart );

    /* Allocate space for the aMSI[] array of each FTSQUERY_PHRASE node */
-
    for(p=pRoot; p; p=p->pLeft){
-
      Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight);
-
      assert( pE->aMI==0 );
-
      pE->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32));
-
      if( !pE->aMI ) return SQLITE_NOMEM;
-
      memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32));
-
    }
-

+
    rc = sqlite3Fts3ExprIterate(pRoot, fts3AllocateMSI, (void*)pTab);
+
    if( rc!=SQLITE_OK ) return rc;
    fts3EvalRestart(pCsr, pRoot, &rc);

    while( pCsr->isEof==0 && rc==SQLITE_OK ){
@@ -184542,6 +187072,7 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
    u8 bTreeEof = 0;
    Fts3Expr *p;                  /* Used to iterate from pExpr to root */
    Fts3Expr *pNear;              /* Most senior NEAR ancestor (or pExpr) */
+
    Fts3Expr *pRun;               /* Closest non-deferred ancestor of pNear */
    int bMatch;

    /* Check if this phrase descends from an OR expression node. If not,
@@ -184556,25 +187087,30 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
      if( p->bEof ) bTreeEof = 1;
    }
    if( bOr==0 ) return SQLITE_OK;
+
    pRun = pNear;
+
    while( pRun->bDeferred ){
+
      assert( pRun->pParent );
+
      pRun = pRun->pParent;
+
    }

    /* This is the descendent of an OR node. In this case we cannot use
    ** an incremental phrase. Load the entire doclist for the phrase
    ** into memory in this case.  */
    if( pPhrase->bIncr ){
-
      int bEofSave = pNear->bEof;
-
      fts3EvalRestart(pCsr, pNear, &rc);
-
      while( rc==SQLITE_OK && !pNear->bEof ){
-
        fts3EvalNextRow(pCsr, pNear, &rc);
-
        if( bEofSave==0 && pNear->iDocid==iDocid ) break;
+
      int bEofSave = pRun->bEof;
+
      fts3EvalRestart(pCsr, pRun, &rc);
+
      while( rc==SQLITE_OK && !pRun->bEof ){
+
        fts3EvalNextRow(pCsr, pRun, &rc);
+
        if( bEofSave==0 && pRun->iDocid==iDocid ) break;
      }
      assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
-
      if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){
+
      if( rc==SQLITE_OK && pRun->bEof!=bEofSave ){
        rc = FTS_CORRUPT_VTAB;
      }
    }
    if( bTreeEof ){
-
      while( rc==SQLITE_OK && !pNear->bEof ){
-
        fts3EvalNextRow(pCsr, pNear, &rc);
+
      while( rc==SQLITE_OK && !pRun->bEof ){
+
        fts3EvalNextRow(pCsr, pRun, &rc);
      }
    }
    if( rc!=SQLITE_OK ) return rc;
@@ -191490,16 +194026,18 @@ static int fts3MsrBufferData(
  char *pList,
  i64 nList
){
-
  if( nList>pMsr->nBuffer ){
+
  if( (nList+FTS3_NODE_PADDING)>pMsr->nBuffer ){
    char *pNew;
-
    pMsr->nBuffer = nList*2;
-
    pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, pMsr->nBuffer);
+
    int nNew = nList*2 + FTS3_NODE_PADDING;
+
    pNew = (char *)sqlite3_realloc64(pMsr->aBuffer, nNew);
    if( !pNew ) return SQLITE_NOMEM;
    pMsr->aBuffer = pNew;
+
    pMsr->nBuffer = nNew;
  }

  assert( nList>0 );
  memcpy(pMsr->aBuffer, pList, nList);
+
  memset(&pMsr->aBuffer[nList], 0, FTS3_NODE_PADDING);
  return SQLITE_OK;
}

@@ -194681,7 +197219,7 @@ typedef sqlite3_int64 i64;


/*
-
** Used as an fts3ExprIterate() context when loading phrase doclists to
+
** Used as an sqlite3Fts3ExprIterate() context when loading phrase doclists to
** Fts3Expr.aDoclist[]/nDoclist.
*/
typedef struct LoadDoclistCtx LoadDoclistCtx;
@@ -194725,7 +197263,7 @@ struct SnippetFragment {
};

/*
-
** This type is used as an fts3ExprIterate() context object while
+
** This type is used as an sqlite3Fts3ExprIterate() context object while
** accumulating the data returned by the matchinfo() function.
*/
typedef struct MatchInfo MatchInfo;
@@ -194884,7 +197422,7 @@ static void fts3GetDeltaPosition(char **pp, i64 *piPos){
}

/*
-
** Helper function for fts3ExprIterate() (see below).
+
** Helper function for sqlite3Fts3ExprIterate() (see below).
*/
static int fts3ExprIterate2(
  Fts3Expr *pExpr,                /* Expression to iterate phrases of */
@@ -194918,7 +197456,7 @@ static int fts3ExprIterate2(
** Otherwise, SQLITE_OK is returned after a callback has been made for
** all eligible phrase nodes.
*/
-
static int fts3ExprIterate(
+
SQLITE_PRIVATE int sqlite3Fts3ExprIterate(
  Fts3Expr *pExpr,                /* Expression to iterate phrases of */
  int (*x)(Fts3Expr*,int,void*),  /* Callback function to invoke for phrases */
  void *pCtx                      /* Second argument to pass to callback */
@@ -194927,10 +197465,9 @@ static int fts3ExprIterate(
  return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx);
}

-

/*
-
** This is an fts3ExprIterate() callback used while loading the doclists
-
** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
+
** This is an sqlite3Fts3ExprIterate() callback used while loading the
+
** doclists for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
** fts3ExprLoadDoclists().
*/
static int fts3ExprLoadDoclistsCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
@@ -194962,9 +197499,9 @@ static int fts3ExprLoadDoclists(
  int *pnToken                    /* OUT: Number of tokens in query */
){
  int rc;                         /* Return Code */
-
  LoadDoclistCtx sCtx = {0,0,0};  /* Context for fts3ExprIterate() */
+
  LoadDoclistCtx sCtx = {0,0,0};  /* Context for sqlite3Fts3ExprIterate() */
  sCtx.pCsr = pCsr;
-
  rc = fts3ExprIterate(pCsr->pExpr, fts3ExprLoadDoclistsCb, (void *)&sCtx);
+
  rc = sqlite3Fts3ExprIterate(pCsr->pExpr,fts3ExprLoadDoclistsCb,(void*)&sCtx);
  if( pnPhrase ) *pnPhrase = sCtx.nPhrase;
  if( pnToken ) *pnToken = sCtx.nToken;
  return rc;
@@ -194977,7 +197514,7 @@ static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
}
static int fts3ExprPhraseCount(Fts3Expr *pExpr){
  int nPhrase = 0;
-
  (void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase);
+
  (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase);
  return nPhrase;
}

@@ -195105,8 +197642,9 @@ static void fts3SnippetDetails(
}

/*
-
** This function is an fts3ExprIterate() callback used by fts3BestSnippet().
-
** Each invocation populates an element of the SnippetIter.aPhrase[] array.
+
** This function is an sqlite3Fts3ExprIterate() callback used by
+
** fts3BestSnippet().  Each invocation populates an element of the
+
** SnippetIter.aPhrase[] array.
*/
static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){
  SnippetIter *p = (SnippetIter *)ctx;
@@ -195196,7 +197734,9 @@ static int fts3BestSnippet(
  sIter.nSnippet = nSnippet;
  sIter.nPhrase = nList;
  sIter.iCurrent = -1;
-
  rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter);
+
  rc = sqlite3Fts3ExprIterate(
+
      pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter
+
  );
  if( rc==SQLITE_OK ){

    /* Set the *pmSeen output variable. */
@@ -195557,10 +198097,10 @@ static int fts3ExprLHitGather(
}

/*
-
** fts3ExprIterate() callback used to collect the "global" matchinfo stats
-
** for a single query.
+
** sqlite3Fts3ExprIterate() callback used to collect the "global" matchinfo
+
** stats for a single query.
**
-
** fts3ExprIterate() callback to load the 'global' elements of a
+
** sqlite3Fts3ExprIterate() callback to load the 'global' elements of a
** FTS3_MATCHINFO_HITS matchinfo array. The global stats are those elements
** of the matchinfo array that are constant for all rows returned by the
** current query.
@@ -195595,7 +198135,7 @@ static int fts3ExprGlobalHitsCb(
}

/*
-
** fts3ExprIterate() callback used to collect the "local" part of the
+
** sqlite3Fts3ExprIterate() callback used to collect the "local" part of the
** FTS3_MATCHINFO_HITS array. The local stats are those elements of the
** array that are different for each row returned by the query.
*/
@@ -195791,7 +198331,7 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
  **/
  aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase);
  if( !aIter ) return SQLITE_NOMEM;
-
  (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
+
  (void)sqlite3Fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);

  for(i=0; i<pInfo->nPhrase; i++){
    LcsIterator *pIter = &aIter[i];
@@ -195968,11 +198508,11 @@ static int fts3MatchinfoValues(
            rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc,0,0);
            if( rc!=SQLITE_OK ) break;
          }
-
          rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);
+
          rc = sqlite3Fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);
          sqlite3Fts3EvalTestDeferred(pCsr, &rc);
          if( rc!=SQLITE_OK ) break;
        }
-
        (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo);
+
        (void)sqlite3Fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo);
        break;
      }
    }
@@ -196195,7 +198735,7 @@ struct TermOffsetCtx {
};

/*
-
** This function is an fts3ExprIterate() callback used by sqlite3Fts3Offsets().
+
** This function is an sqlite3Fts3ExprIterate() callback used by sqlite3Fts3Offsets().
*/
static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){
  TermOffsetCtx *p = (TermOffsetCtx *)ctx;
@@ -196277,7 +198817,9 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets(
    */
    sCtx.iCol = iCol;
    sCtx.iTerm = 0;
-
    rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
+
    rc = sqlite3Fts3ExprIterate(
+
        pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx
+
    );
    if( rc!=SQLITE_OK ) goto offsets_out;

    /* Retreive the text stored in column iCol. If an SQL NULL is stored
@@ -197284,6 +199826,7 @@ static const char * const jsonType[] = {
#define JNODE_PATCH   0x10         /* Patch with JsonNode.u.pPatch */
#define JNODE_APPEND  0x20         /* More ARRAY/OBJECT entries at u.iAppend */
#define JNODE_LABEL   0x40         /* Is a label of an object */
+
#define JNODE_JSON5   0x80         /* Node contains JSON5 enhancements */


/* A single node of parsed JSON
@@ -197310,10 +199853,12 @@ struct JsonParse {
  JsonNode *aNode;   /* Array of nodes containing the parse */
  const char *zJson; /* Original JSON string */
  u32 *aUp;          /* Index of parent of each node */
-
  u8 oom;            /* Set to true if out of memory */
-
  u8 nErr;           /* Number of errors seen */
  u16 iDepth;        /* Nesting depth */
+
  u8 nErr;           /* Number of errors seen */
+
  u8 oom;            /* Set to true if out of memory */
+
  u8 hasNonstd;      /* True if input uses non-standard features like JSON5 */
  int nJson;         /* Length of the zJson string in bytes */
+
  u32 iErr;          /* Error location in zJson[] */
  u32 iHold;         /* Replace cache line with the lowest iHold value */
};

@@ -197321,10 +199866,10 @@ struct JsonParse {
** Maximum nesting depth of JSON for this implementation.
**
** This limit is needed to avoid a stack overflow in the recursive
-
** descent parser.  A depth of 2000 is far deeper than any sane JSON
-
** should go.
+
** descent parser.  A depth of 1000 is far deeper than any sane JSON
+
** should go.  Historical note: This limit was 2000 prior to version 3.42.0
*/
-
#define JSON_MAX_DEPTH  2000
+
#define JSON_MAX_DEPTH  1000

/**************************************************************************
** Utility routines for dealing with JsonString objects
@@ -197475,6 +200020,129 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){
}

/*
+
** The zIn[0..N] string is a JSON5 string literal.  Append to p a translation
+
** of the string literal that standard JSON and that omits all JSON5
+
** features.
+
*/
+
static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){
+
  u32 i;
+
  jsonAppendChar(p, '"');
+
  zIn++;
+
  N -= 2;
+
  while( N>0 ){
+
    for(i=0; i<N && zIn[i]!='\\'; i++){}
+
    if( i>0 ){
+
      jsonAppendRaw(p, zIn, i);
+
      zIn += i;
+
      N -= i;
+
      if( N==0 ) break;
+
    }
+
    assert( zIn[0]=='\\' );
+
    switch( (u8)zIn[1] ){
+
      case '\'':
+
        jsonAppendChar(p, '\'');
+
        break;
+
      case 'v':
+
        jsonAppendRaw(p, "\\u0009", 6);
+
        break;
+
      case 'x':
+
        jsonAppendRaw(p, "\\u00", 4);
+
        jsonAppendRaw(p, &zIn[2], 2);
+
        zIn += 2;
+
        N -= 2;
+
        break;
+
      case '0':
+
        jsonAppendRaw(p, "\\u0000", 6);
+
        break;
+
      case '\r':
+
        if( zIn[2]=='\n' ){
+
          zIn++;
+
          N--;
+
        }
+
        break;
+
      case '\n':
+
        break;
+
      case 0xe2:
+
        assert( N>=4 );
+
        assert( 0x80==(u8)zIn[2] );
+
        assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] );
+
        zIn += 2;
+
        N -= 2;
+
        break;
+
      default:
+
        jsonAppendRaw(p, zIn, 2);
+
        break;
+
    }
+
    zIn += 2;
+
    N -= 2;
+
  }
+
  jsonAppendChar(p, '"');
+
}
+

+
/*
+
** The zIn[0..N] string is a JSON5 integer literal.  Append to p a translation
+
** of the string literal that standard JSON and that omits all JSON5
+
** features.
+
*/
+
static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){
+
  if( zIn[0]=='+' ){
+
    zIn++;
+
    N--;
+
  }else if( zIn[0]=='-' ){
+
    jsonAppendChar(p, '-');
+
    zIn++;
+
    N--;
+
  }
+
  if( zIn[0]=='0' && (zIn[1]=='x' || zIn[1]=='X') ){
+
    sqlite3_int64 i = 0;
+
    int rc = sqlite3DecOrHexToI64(zIn, &i);
+
    if( rc<=1 ){
+
      jsonPrintf(100,p,"%lld",i);
+
    }else{
+
      assert( rc==2 );
+
      jsonAppendRaw(p, "9.0e999", 7);
+
    }
+
    return;
+
  }
+
  jsonAppendRaw(p, zIn, N);
+
}
+

+
/*
+
** The zIn[0..N] string is a JSON5 real literal.  Append to p a translation
+
** of the string literal that standard JSON and that omits all JSON5
+
** features.
+
*/
+
static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){
+
  u32 i;
+
  if( zIn[0]=='+' ){
+
    zIn++;
+
    N--;
+
  }else if( zIn[0]=='-' ){
+
    jsonAppendChar(p, '-');
+
    zIn++;
+
    N--;
+
  }
+
  if( zIn[0]=='.' ){
+
    jsonAppendChar(p, '0');
+
  }
+
  for(i=0; i<N; i++){
+
    if( zIn[i]=='.' && (i+1==N || !sqlite3Isdigit(zIn[i+1])) ){
+
      i++;
+
      jsonAppendRaw(p, zIn, i);
+
      zIn += i;
+
      N -= i;
+
      jsonAppendChar(p, '0');
+
      break;
+
    }
+
  }
+
  if( N>0 ){
+
    jsonAppendRaw(p, zIn, N);
+
  }
+
}
+

+

+

+
/*
** Append a function parameter value to the JSON string under
** construction.
*/
@@ -197487,8 +200155,11 @@ static void jsonAppendValue(
      jsonAppendRaw(p, "null", 4);
      break;
    }
-
    case SQLITE_INTEGER:
    case SQLITE_FLOAT: {
+
      jsonPrintf(100, p, "%!0.15g", sqlite3_value_double(pValue));
+
      break;
+
    }
+
    case SQLITE_INTEGER: {
      const char *z = (const char*)sqlite3_value_text(pValue);
      u32 n = (u32)sqlite3_value_bytes(pValue);
      jsonAppendRaw(p, z, n);
@@ -197601,17 +200272,38 @@ static void jsonRenderNode(
      break;
    }
    case JSON_STRING: {
+
      assert( pNode->eU==1 );
      if( pNode->jnFlags & JNODE_RAW ){
-
        assert( pNode->eU==1 );
-
        jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
-
        break;
+
        if( pNode->jnFlags & JNODE_LABEL ){
+
          jsonAppendChar(pOut, '"');
+
          jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
+
          jsonAppendChar(pOut, '"');
+
        }else{
+
          jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
+
        }
+
      }else if( pNode->jnFlags & JNODE_JSON5 ){
+
        jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n);
+
      }else{
+
        jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
      }
-
      /* no break */ deliberate_fall_through
+
      break;
+
    }
+
    case JSON_REAL: {
+
      assert( pNode->eU==1 );
+
      if( pNode->jnFlags & JNODE_JSON5 ){
+
        jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n);
+
      }else{
+
        jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
+
      }
+
      break;
    }
-
    case JSON_REAL:
    case JSON_INT: {
      assert( pNode->eU==1 );
-
      jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
+
      if( pNode->jnFlags & JNODE_JSON5 ){
+
        jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n);
+
      }else{
+
        jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
+
      }
      break;
    }
    case JSON_ARRAY: {
@@ -197727,59 +200419,41 @@ static void jsonReturn(
    }
    case JSON_INT: {
      sqlite3_int64 i = 0;
+
      int rc;
+
      int bNeg = 0;
      const char *z;
+

+

      assert( pNode->eU==1 );
      z = pNode->u.zJContent;
-
      if( z[0]=='-' ){ z++; }
-
      while( z[0]>='0' && z[0]<='9' ){
-
        unsigned v = *(z++) - '0';
-
        if( i>=LARGEST_INT64/10 ){
-
          if( i>LARGEST_INT64/10 ) goto int_as_real;
-
          if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
-
          if( v==9 ) goto int_as_real;
-
          if( v==8 ){
-
            if( pNode->u.zJContent[0]=='-' ){
-
              sqlite3_result_int64(pCtx, SMALLEST_INT64);
-
              goto int_done;
-
            }else{
-
              goto int_as_real;
-
            }
-
          }
-
        }
-
        i = i*10 + v;
+
      if( z[0]=='-' ){ z++; bNeg = 1; }
+
      else if( z[0]=='+' ){ z++; }
+
      rc = sqlite3DecOrHexToI64(z, &i);
+
      if( rc<=1 ){
+
        sqlite3_result_int64(pCtx, bNeg ? -i : i);
+
      }else if( rc==3 && bNeg ){
+
        sqlite3_result_int64(pCtx, SMALLEST_INT64);
+
      }else{
+
        goto to_double;
      }
-
      if( pNode->u.zJContent[0]=='-' ){ i = -i; }
-
      sqlite3_result_int64(pCtx, i);
-
      int_done:
      break;
-
      int_as_real: ; /* no break */ deliberate_fall_through
    }
    case JSON_REAL: {
      double r;
-
#ifdef SQLITE_AMALGAMATION
      const char *z;
      assert( pNode->eU==1 );
+
    to_double:
      z = pNode->u.zJContent;
      sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
-
#else
-
      assert( pNode->eU==1 );
-
      r = strtod(pNode->u.zJContent, 0);
-
#endif
      sqlite3_result_double(pCtx, r);
      break;
    }
    case JSON_STRING: {
-
#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
-
      ** json_insert() and json_replace() and those routines do not
-
      ** call jsonReturn() */
      if( pNode->jnFlags & JNODE_RAW ){
        assert( pNode->eU==1 );
        sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
                            SQLITE_TRANSIENT);
-
      }else
-
#endif
-
      assert( (pNode->jnFlags & JNODE_RAW)==0 );
-
      if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
+
      }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
        /* JSON formatted without any backslash-escapes */
        assert( pNode->eU==1 );
        sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
@@ -197791,18 +200465,17 @@ static void jsonReturn(
        const char *z;
        char *zOut;
        u32 j;
+
        u32 nOut = n;
        assert( pNode->eU==1 );
        z = pNode->u.zJContent;
-
        zOut = sqlite3_malloc( n+1 );
+
        zOut = sqlite3_malloc( nOut+1 );
        if( zOut==0 ){
          sqlite3_result_error_nomem(pCtx);
          break;
        }
        for(i=1, j=0; i<n-1; i++){
          char c = z[i];
-
          if( c!='\\' ){
-
            zOut[j++] = c;
-
          }else{
+
          if( c=='\\' ){
            c = z[++i];
            if( c=='u' ){
              u32 v = jsonHexToInt4(z+i+1);
@@ -197834,22 +200507,40 @@ static void jsonReturn(
                  zOut[j++] = 0x80 | (v&0x3f);
                }
              }
+
              continue;
+
            }else if( c=='b' ){
+
              c = '\b';
+
            }else if( c=='f' ){
+
              c = '\f';
+
            }else if( c=='n' ){
+
              c = '\n';
+
            }else if( c=='r' ){
+
              c = '\r';
+
            }else if( c=='t' ){
+
              c = '\t';
+
            }else if( c=='v' ){
+
              c = '\v';
+
            }else if( c=='\'' || c=='"' || c=='/' || c=='\\' ){
+
              /* pass through unchanged */
+
            }else if( c=='0' ){
+
              c = 0;
+
            }else if( c=='x' ){
+
              c = (jsonHexToInt(z[i+1])<<4) | jsonHexToInt(z[i+2]);
+
              i += 2;
+
            }else if( c=='\r' && z[i+1]=='\n' ){
+
              i++;
+
              continue;
+
            }else if( 0xe2==(u8)c ){
+
              assert( 0x80==(u8)z[i+1] );
+
              assert( 0xa8==(u8)z[i+2] || 0xa9==(u8)z[i+2] );
+
              i += 2;
+
              continue;
            }else{
-
              if( c=='b' ){
-
                c = '\b';
-
              }else if( c=='f' ){
-
                c = '\f';
-
              }else if( c=='n' ){
-
                c = '\n';
-
              }else if( c=='r' ){
-
                c = '\r';
-
              }else if( c=='t' ){
-
                c = '\t';
-
              }
-
              zOut[j++] = c;
+
              continue;
            }
-
          }
-
        }
+
          } /* end if( c=='\\' ) */
+
          zOut[j++] = c;
+
        } /* end for() */
        zOut[j] = 0;
        sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
      }
@@ -197917,8 +200608,8 @@ static int jsonParseAddNode(
    return jsonParseAddNodeExpand(pParse, eType, n, zContent);
  }
  p = &pParse->aNode[pParse->nNode];
-
  p->eType = (u8)eType;
-
  p->jnFlags = 0;
+
  p->eType = (u8)(eType & 0xff);
+
  p->jnFlags = (u8)(eType >> 8);
  VVA( p->eU = zContent ? 1 : 0 );
  p->n = n;
  p->u.zJContent = zContent;
@@ -197926,21 +200617,177 @@ static int jsonParseAddNode(
}

/*
+
** Return true if z[] begins with 2 (or more) hexadecimal digits
+
*/
+
static int jsonIs2Hex(const char *z){
+
  return sqlite3Isxdigit(z[0]) && sqlite3Isxdigit(z[1]);
+
}
+

+
/*
** Return true if z[] begins with 4 (or more) hexadecimal digits
*/
static int jsonIs4Hex(const char *z){
-
  int i;
-
  for(i=0; i<4; i++) if( !sqlite3Isxdigit(z[i]) ) return 0;
-
  return 1;
+
  return jsonIs2Hex(z) && jsonIs2Hex(&z[2]);
+
}
+

+
/*
+
** Return the number of bytes of JSON5 whitespace at the beginning of
+
** the input string z[].
+
**
+
** JSON5 whitespace consists of any of the following characters:
+
**
+
**    Unicode  UTF-8         Name
+
**    U+0009   09            horizontal tab
+
**    U+000a   0a            line feed
+
**    U+000b   0b            vertical tab
+
**    U+000c   0c            form feed
+
**    U+000d   0d            carriage return
+
**    U+0020   20            space
+
**    U+00a0   c2 a0         non-breaking space
+
**    U+1680   e1 9a 80      ogham space mark
+
**    U+2000   e2 80 80      en quad
+
**    U+2001   e2 80 81      em quad
+
**    U+2002   e2 80 82      en space
+
**    U+2003   e2 80 83      em space
+
**    U+2004   e2 80 84      three-per-em space
+
**    U+2005   e2 80 85      four-per-em space
+
**    U+2006   e2 80 86      six-per-em space
+
**    U+2007   e2 80 87      figure space
+
**    U+2008   e2 80 88      punctuation space
+
**    U+2009   e2 80 89      thin space
+
**    U+200a   e2 80 8a      hair space
+
**    U+2028   e2 80 a8      line separator
+
**    U+2029   e2 80 a9      paragraph separator
+
**    U+202f   e2 80 af      narrow no-break space (NNBSP)
+
**    U+205f   e2 81 9f      medium mathematical space (MMSP)
+
**    U+3000   e3 80 80      ideographical space
+
**    U+FEFF   ef bb bf      byte order mark
+
**
+
** In addition, comments between '/', '*' and '*', '/' and
+
** from '/', '/' to end-of-line are also considered to be whitespace.
+
*/
+
static int json5Whitespace(const char *zIn){
+
  int n = 0;
+
  const u8 *z = (u8*)zIn;
+
  while( 1 /*exit by "goto whitespace_done"*/ ){
+
    switch( z[n] ){
+
      case 0x09:
+
      case 0x0a:
+
      case 0x0b:
+
      case 0x0c:
+
      case 0x0d:
+
      case 0x20: {
+
        n++;
+
        break;
+
      }
+
      case '/': {
+
        if( z[n+1]=='*' && z[n+2]!=0 ){
+
          int j;
+
          for(j=n+3; z[j]!='/' || z[j-1]!='*'; j++){
+
            if( z[j]==0 ) goto whitespace_done;
+
          }
+
          n = j+1;
+
          break;
+
        }else if( z[n+1]=='/' ){
+
          int j;
+
          char c;
+
          for(j=n+2; (c = z[j])!=0; j++){
+
            if( c=='\n' || c=='\r' ) break;
+
            if( 0xe2==(u8)c && 0x80==(u8)z[j+1]
+
             && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])
+
            ){
+
              j += 2;
+
              break;
+
            }
+
          }
+
          n = j;
+
          if( z[n] ) n++;
+
          break;
+
        }
+
        goto whitespace_done;
+
      }
+
      case 0xc2: {
+
        if( z[n+1]==0xa0 ){
+
          n += 2;
+
          break;
+
        }
+
        goto whitespace_done;
+
      }
+
      case 0xe1: {
+
        if( z[n+1]==0x9a && z[n+2]==0x80 ){
+
          n += 3;
+
          break;
+
        }
+
        goto whitespace_done;
+
      }
+
      case 0xe2: {
+
        if( z[n+1]==0x80 ){
+
          u8 c = z[n+2];
+
          if( c<0x80 ) goto whitespace_done;
+
          if( c<=0x8a || c==0xa8 || c==0xa9 || c==0xaf ){
+
            n += 3;
+
            break;
+
          }
+
        }else if( z[n+1]==0x81 && z[n+2]==0x9f ){
+
          n += 3;
+
          break;
+
        }
+
        goto whitespace_done;
+
      }
+
      case 0xe3: {
+
        if( z[n+1]==0x80 && z[n+2]==0x80 ){
+
          n += 3;
+
          break;
+
        }
+
        goto whitespace_done;
+
      }
+
      case 0xef: {
+
        if( z[n+1]==0xbb && z[n+2]==0xbf ){
+
          n += 3;
+
          break;
+
        }
+
        goto whitespace_done;
+
      }
+
      default: {
+
        goto whitespace_done;
+
      }
+
    }
+
  }
+
  whitespace_done:
+
  return n;
}

/*
+
** Extra floating-point literals to allow in JSON.
+
*/
+
static const struct NanInfName {
+
  char c1;
+
  char c2;
+
  char n;
+
  char eType;
+
  char nRepl;
+
  char *zMatch;
+
  char *zRepl;
+
} aNanInfName[] = {
+
  { 'i', 'I', 3, JSON_REAL, 7, "inf", "9.0e999" },
+
  { 'i', 'I', 8, JSON_REAL, 7, "infinity", "9.0e999" },
+
  { 'n', 'N', 3, JSON_NULL, 4, "NaN", "null" },
+
  { 'q', 'Q', 4, JSON_NULL, 4, "QNaN", "null" },
+
  { 's', 'S', 4, JSON_NULL, 4, "SNaN", "null" },
+
};
+

+
/*
** Parse a single JSON value which begins at pParse->zJson[i].  Return the
** index of the first character past the end of the value parsed.
**
-
** Return negative for a syntax error.  Special cases:  return -2 if the
-
** first non-whitespace character is '}' and return -3 if the first
-
** non-whitespace character is ']'.
+
** Special return values:
+
**
+
**      0    End if input
+
**     -1    Syntax error
+
**     -2    '}' seen
+
**     -3    ']' seen
+
**     -4    ',' seen
+
**     -5    ':' seen
*/
static int jsonParseValue(JsonParse *pParse, u32 i){
  char c;
@@ -197949,151 +200796,430 @@ static int jsonParseValue(JsonParse *pParse, u32 i){
  int x;
  JsonNode *pNode;
  const char *z = pParse->zJson;
-
  while( fast_isspace(z[i]) ){ i++; }
-
  if( (c = z[i])=='{' ){
+
json_parse_restart:
+
  switch( (u8)z[i] ){
+
  case '{': {
    /* Parse object */
    iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0);
    if( iThis<0 ) return -1;
+
    if( ++pParse->iDepth > JSON_MAX_DEPTH ){
+
      pParse->iErr = i;
+
      return -1;
+
    }
    for(j=i+1;;j++){
-
      while( fast_isspace(z[j]) ){ j++; }
-
      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
+
      u32 nNode = pParse->nNode;
      x = jsonParseValue(pParse, j);
-
      if( x<0 ){
-
        pParse->iDepth--;
-
        if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1;
-
        return -1;
+
      if( x<=0 ){
+
        if( x==(-2) ){
+
          j = pParse->iErr;
+
          if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1;
+
          break;
+
        }
+
        j += json5Whitespace(&z[j]);
+
        if( sqlite3JsonId1(z[j])
+
         || (z[j]=='\\' && z[j+1]=='u' && jsonIs4Hex(&z[j+2]))
+
        ){
+
          int k = j+1;
+
          while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0)
+
            || (z[k]=='\\' && z[k+1]=='u' && jsonIs4Hex(&z[k+2]))
+
          ){
+
            k++;
+
          }
+
          jsonParseAddNode(pParse, JSON_STRING | (JNODE_RAW<<8), k-j, &z[j]);
+
          pParse->hasNonstd = 1;
+
          x = k;
+
        }else{
+
          if( x!=-1 ) pParse->iErr = j;
+
          return -1;
+
        }
      }
      if( pParse->oom ) return -1;
-
      pNode = &pParse->aNode[pParse->nNode-1];
-
      if( pNode->eType!=JSON_STRING ) return -1;
+
      pNode = &pParse->aNode[nNode];
+
      if( pNode->eType!=JSON_STRING ){
+
        pParse->iErr = j;
+
        return -1;
+
      }
      pNode->jnFlags |= JNODE_LABEL;
      j = x;
-
      while( fast_isspace(z[j]) ){ j++; }
-
      if( z[j]!=':' ) return -1;
-
      j++;
+
      if( z[j]==':' ){
+
        j++;
+
      }else{
+
        if( fast_isspace(z[j]) ){
+
          do{ j++; }while( fast_isspace(z[j]) );
+
          if( z[j]==':' ){
+
            j++;
+
            goto parse_object_value;
+
          }
+
        }
+
        x = jsonParseValue(pParse, j);
+
        if( x!=(-5) ){
+
          if( x!=(-1) ) pParse->iErr = j;
+
          return -1;
+
        }
+
        j = pParse->iErr+1;
+
      }
+
    parse_object_value:
      x = jsonParseValue(pParse, j);
-
      pParse->iDepth--;
-
      if( x<0 ) return -1;
+
      if( x<=0 ){
+
        if( x!=(-1) ) pParse->iErr = j;
+
        return -1;
+
      }
      j = x;
-
      while( fast_isspace(z[j]) ){ j++; }
-
      c = z[j];
-
      if( c==',' ) continue;
-
      if( c!='}' ) return -1;
-
      break;
+
      if( z[j]==',' ){
+
        continue;
+
      }else if( z[j]=='}' ){
+
        break;
+
      }else{
+
        if( fast_isspace(z[j]) ){
+
          do{ j++; }while( fast_isspace(z[j]) );
+
          if( z[j]==',' ){
+
            continue;
+
          }else if( z[j]=='}' ){
+
            break;
+
          }
+
        }
+
        x = jsonParseValue(pParse, j);
+
        if( x==(-4) ){
+
          j = pParse->iErr;
+
          continue;
+
        }
+
        if( x==(-2) ){
+
          j = pParse->iErr;
+
          break;
+
        }
+
      }
+
      pParse->iErr = j;
+
      return -1;
    }
    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
+
    pParse->iDepth--;
    return j+1;
-
  }else if( c=='[' ){
+
  }
+
  case '[': {
    /* Parse array */
    iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
    if( iThis<0 ) return -1;
+
    if( ++pParse->iDepth > JSON_MAX_DEPTH ){
+
      pParse->iErr = i;
+
      return -1;
+
    }
    memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u));
    for(j=i+1;;j++){
-
      while( fast_isspace(z[j]) ){ j++; }
-
      if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
      x = jsonParseValue(pParse, j);
-
      pParse->iDepth--;
-
      if( x<0 ){
-
        if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1;
+
      if( x<=0 ){
+
        if( x==(-3) ){
+
          j = pParse->iErr;
+
          if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1;
+
          break;
+
        }
+
        if( x!=(-1) ) pParse->iErr = j;
        return -1;
      }
      j = x;
-
      while( fast_isspace(z[j]) ){ j++; }
-
      c = z[j];
-
      if( c==',' ) continue;
-
      if( c!=']' ) return -1;
-
      break;
+
      if( z[j]==',' ){
+
        continue;
+
      }else if( z[j]==']' ){
+
        break;
+
      }else{
+
        if( fast_isspace(z[j]) ){
+
          do{ j++; }while( fast_isspace(z[j]) );
+
          if( z[j]==',' ){
+
            continue;
+
          }else if( z[j]==']' ){
+
            break;
+
          }
+
        }
+
        x = jsonParseValue(pParse, j);
+
        if( x==(-4) ){
+
          j = pParse->iErr;
+
          continue;
+
        }
+
        if( x==(-3) ){
+
          j = pParse->iErr;
+
          break;
+
        }
+
      }
+
      pParse->iErr = j;
+
      return -1;
    }
    pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1;
+
    pParse->iDepth--;
    return j+1;
-
  }else if( c=='"' ){
+
  }
+
  case '\'': {
+
    u8 jnFlags;
+
    char cDelim;
+
    pParse->hasNonstd = 1;
+
    jnFlags = JNODE_JSON5;
+
    goto parse_string;
+
  case '"':
    /* Parse string */
-
    u8 jnFlags = 0;
+
    jnFlags = 0;
+
  parse_string:
+
    cDelim = z[i];
    j = i+1;
    for(;;){
      c = z[j];
      if( (c & ~0x1f)==0 ){
        /* Control characters are not allowed in strings */
+
        pParse->iErr = j;
        return -1;
      }
      if( c=='\\' ){
        c = z[++j];
        if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
           || c=='n' || c=='r' || c=='t'
-
           || (c=='u' && jsonIs4Hex(z+j+1)) ){
-
          jnFlags = JNODE_ESCAPE;
+
           || (c=='u' && jsonIs4Hex(&z[j+1])) ){
+
          jnFlags |= JNODE_ESCAPE;
+
        }else if( c=='\'' || c=='0' || c=='v' || c=='\n'
+
           || (0xe2==(u8)c && 0x80==(u8)z[j+1]
+
                && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]))
+
           || (c=='x' && jsonIs2Hex(&z[j+1])) ){
+
          jnFlags |= (JNODE_ESCAPE|JNODE_JSON5);
+
          pParse->hasNonstd = 1;
+
        }else if( c=='\r' ){
+
          if( z[j+1]=='\n' ) j++;
+
          jnFlags |= (JNODE_ESCAPE|JNODE_JSON5);
+
          pParse->hasNonstd = 1;
        }else{
+
          pParse->iErr = j;
          return -1;
        }
-
      }else if( c=='"' ){
+
      }else if( c==cDelim ){
        break;
      }
      j++;
    }
-
    jsonParseAddNode(pParse, JSON_STRING, j+1-i, &z[i]);
-
    if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags;
+
    jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]);
    return j+1;
-
  }else if( c=='n'
-
         && strncmp(z+i,"null",4)==0
-
         && !sqlite3Isalnum(z[i+4]) ){
-
    jsonParseAddNode(pParse, JSON_NULL, 0, 0);
-
    return i+4;
-
  }else if( c=='t'
-
         && strncmp(z+i,"true",4)==0
-
         && !sqlite3Isalnum(z[i+4]) ){
-
    jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
-
    return i+4;
-
  }else if( c=='f'
-
         && strncmp(z+i,"false",5)==0
-
         && !sqlite3Isalnum(z[i+5]) ){
-
    jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
-
    return i+5;
-
  }else if( c=='-' || (c>='0' && c<='9') ){
+
  }
+
  case 't': {
+
    if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){
+
      jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
+
      return i+4;
+
    }
+
    pParse->iErr = i;
+
    return -1;
+
  }
+
  case 'f': {
+
    if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){
+
      jsonParseAddNode(pParse, JSON_FALSE, 0, 0);
+
      return i+5;
+
    }
+
    pParse->iErr = i;
+
    return -1;
+
  }
+
  case '+': {
+
    u8 seenDP, seenE, jnFlags;
+
    pParse->hasNonstd = 1;
+
    jnFlags = JNODE_JSON5;
+
    goto parse_number;
+
  case '.':
+
    if( sqlite3Isdigit(z[i+1]) ){
+
      pParse->hasNonstd = 1;
+
      jnFlags = JNODE_JSON5;
+
      seenE = 0;
+
      seenDP = JSON_REAL;
+
      goto parse_number_2;
+
    }
+
    pParse->iErr = i;
+
    return -1;
+
  case '-':
+
  case '0':
+
  case '1':
+
  case '2':
+
  case '3':
+
  case '4':
+
  case '5':
+
  case '6':
+
  case '7':
+
  case '8':
+
  case '9':
    /* Parse number */
-
    u8 seenDP = 0;
-
    u8 seenE = 0;
+
    jnFlags = 0;
+
  parse_number:
+
    seenDP = JSON_INT;
+
    seenE = 0;
    assert( '-' < '0' );
+
    assert( '+' < '0' );
+
    assert( '.' < '0' );
+
    c = z[i];
+

    if( c<='0' ){
-
      j = c=='-' ? i+1 : i;
-
      if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return -1;
+
      if( c=='0' ){
+
        if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){
+
          assert( seenDP==JSON_INT );
+
          pParse->hasNonstd = 1;
+
          jnFlags |= JNODE_JSON5;
+
          for(j=i+3; sqlite3Isxdigit(z[j]); j++){}
+
          goto parse_number_finish;
+
        }else if( sqlite3Isdigit(z[i+1]) ){
+
          pParse->iErr = i+1;
+
          return -1;
+
        }
+
      }else{
+
        if( !sqlite3Isdigit(z[i+1]) ){
+
          /* JSON5 allows for "+Infinity" and "-Infinity" using exactly
+
          ** that case.  SQLite also allows these in any case and it allows
+
          ** "+inf" and "-inf". */
+
          if( (z[i+1]=='I' || z[i+1]=='i')
+
           && sqlite3StrNICmp(&z[i+1], "inf",3)==0
+
          ){
+
            pParse->hasNonstd = 1;
+
            if( z[i]=='-' ){
+
              jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999");
+
            }else{
+
              jsonParseAddNode(pParse, JSON_REAL, 7, "9.0e999");
+
            }
+
            return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4);
+
          }
+
          if( z[i+1]=='.' ){
+
            pParse->hasNonstd = 1;
+
            jnFlags |= JNODE_JSON5;
+
            goto parse_number_2;
+
          }
+
          pParse->iErr = i;
+
          return -1;
+
        }
+
        if( z[i+1]=='0' ){
+
          if( sqlite3Isdigit(z[i+2]) ){
+
            pParse->iErr = i+1;
+
            return -1;
+
          }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){
+
            pParse->hasNonstd = 1;
+
            jnFlags |= JNODE_JSON5;
+
            for(j=i+4; sqlite3Isxdigit(z[j]); j++){}
+
            goto parse_number_finish;
+
          }
+
        }
+
      }
    }
-
    j = i+1;
-
    for(;; j++){
+
  parse_number_2:
+
    for(j=i+1;; j++){
      c = z[j];
-
      if( c>='0' && c<='9' ) continue;
+
      if( sqlite3Isdigit(c) ) continue;
      if( c=='.' ){
-
        if( z[j-1]=='-' ) return -1;
-
        if( seenDP ) return -1;
-
        seenDP = 1;
+
        if( seenDP==JSON_REAL ){
+
          pParse->iErr = j;
+
          return -1;
+
        }
+
        seenDP = JSON_REAL;
        continue;
      }
      if( c=='e' || c=='E' ){
-
        if( z[j-1]<'0' ) return -1;
-
        if( seenE ) return -1;
-
        seenDP = seenE = 1;
+
        if( z[j-1]<'0' ){
+
          if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){
+
            pParse->hasNonstd = 1;
+
            jnFlags |= JNODE_JSON5;
+
          }else{
+
            pParse->iErr = j;
+
            return -1;
+
          }
+
        }
+
        if( seenE ){
+
          pParse->iErr = j;
+
          return -1;
+
        }
+
        seenDP = JSON_REAL;
+
        seenE = 1;
        c = z[j+1];
        if( c=='+' || c=='-' ){
          j++;
          c = z[j+1];
        }
-
        if( c<'0' || c>'9' ) return -1;
+
        if( c<'0' || c>'9' ){
+
          pParse->iErr = j;
+
          return -1;
+
        }
        continue;
      }
      break;
    }
-
    if( z[j-1]<'0' ) return -1;
-
    jsonParseAddNode(pParse, seenDP ? JSON_REAL : JSON_INT,
-
                        j - i, &z[i]);
+
    if( z[j-1]<'0' ){
+
      if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){
+
        pParse->hasNonstd = 1;
+
        jnFlags |= JNODE_JSON5;
+
      }else{
+
        pParse->iErr = j;
+
        return -1;
+
      }
+
    }
+
  parse_number_finish:
+
    jsonParseAddNode(pParse, seenDP | (jnFlags<<8), j - i, &z[i]);
    return j;
-
  }else if( c=='}' ){
+
  }
+
  case '}': {
+
    pParse->iErr = i;
    return -2;  /* End of {...} */
-
  }else if( c==']' ){
+
  }
+
  case ']': {
+
    pParse->iErr = i;
    return -3;  /* End of [...] */
-
  }else if( c==0 ){
+
  }
+
  case ',': {
+
    pParse->iErr = i;
+
    return -4;  /* List separator */
+
  }
+
  case ':': {
+
    pParse->iErr = i;
+
    return -5;  /* Object label/value separator */
+
  }
+
  case 0: {
    return 0;   /* End of file */
-
  }else{
+
  }
+
  case 0x09:
+
  case 0x0a:
+
  case 0x0d:
+
  case 0x20: {
+
    do{
+
      i++;
+
    }while( fast_isspace(z[i]) );
+
    goto json_parse_restart;
+
  }
+
  case 0x0b:
+
  case 0x0c:
+
  case '/':
+
  case 0xc2:
+
  case 0xe1:
+
  case 0xe2:
+
  case 0xe3:
+
  case 0xef: {
+
    j = json5Whitespace(&z[i]);
+
    if( j>0 ){
+
      i += j;
+
      pParse->hasNonstd = 1;
+
      goto json_parse_restart;
+
    }
+
    pParse->iErr = i;
+
    return -1;
+
  }
+
  case 'n': {
+
    if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){
+
      jsonParseAddNode(pParse, JSON_NULL, 0, 0);
+
      return i+4;
+
    }
+
    /* fall-through into the default case that checks for NaN */
+
  }
+
  default: {
+
    u32 k;
+
    int nn;
+
    c = z[i];
+
    for(k=0; k<sizeof(aNanInfName)/sizeof(aNanInfName[0]); k++){
+
      if( c!=aNanInfName[k].c1 && c!=aNanInfName[k].c2 ) continue;
+
      nn = aNanInfName[k].n;
+
      if( sqlite3StrNICmp(&z[i], aNanInfName[k].zMatch, nn)!=0 ){
+
        continue;
+
      }
+
      if( sqlite3Isalnum(z[i+nn]) ) continue;
+
      jsonParseAddNode(pParse, aNanInfName[k].eType,
+
          aNanInfName[k].nRepl, aNanInfName[k].zRepl);
+
      pParse->hasNonstd = 1;
+
      return i + nn;
+
    }
+
    pParse->iErr = i;
    return -1;  /* Syntax error */
  }
+
  } /* End switch(z[i]) */
}

/*
@@ -198117,7 +201243,14 @@ static int jsonParse(
  if( i>0 ){
    assert( pParse->iDepth==0 );
    while( fast_isspace(zJson[i]) ) i++;
-
    if( zJson[i] ) i = -1;
+
    if( zJson[i] ){
+
      i += json5Whitespace(&zJson[i]);
+
      if( zJson[i] ){
+
        jsonParseReset(pParse);
+
        return 1;
+
      }
+
      pParse->hasNonstd = 1;
+
    }
  }
  if( i<=0 ){
    if( pCtx!=0 ){
@@ -198188,6 +201321,15 @@ static int jsonParseFindParents(JsonParse *pParse){
** is no longer valid, parse the JSON again and return the new parse,
** and also register the new parse so that it will be available for
** future sqlite3_get_auxdata() calls.
+
**
+
** If an error occurs and pErrCtx!=0 then report the error on pErrCtx
+
** and return NULL.
+
**
+
** If an error occurs and pErrCtx==0 then return the Parse object with
+
** JsonParse.nErr non-zero.  If the caller invokes this routine with
+
** pErrCtx==0 and it gets back a JsonParse with nErr!=0, then the caller
+
** is responsible for invoking jsonParseFree() on the returned value.
+
** But the caller may invoke jsonParseFree() *only* if pParse->nErr!=0.
*/
static JsonParse *jsonParseCached(
  sqlite3_context *pCtx,
@@ -198237,6 +201379,10 @@ static JsonParse *jsonParseCached(
  p->zJson = (char*)&p[1];
  memcpy((char*)p->zJson, zJson, nJson+1);
  if( jsonParse(p, pErrCtx, p->zJson) ){
+
    if( pErrCtx==0 ){
+
      p->nErr = 1;
+
      return p;
+
    }
    sqlite3_free(p);
    return 0;
  }
@@ -198251,7 +201397,7 @@ static JsonParse *jsonParseCached(
** Compare the OBJECT label at pNode against zKey,nKey.  Return true on
** a match.
*/
-
static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
+
static int jsonLabelCompare(const JsonNode *pNode, const char *zKey, u32 nKey){
  assert( pNode->eU==1 );
  if( pNode->jnFlags & JNODE_RAW ){
    if( pNode->n!=nKey ) return 0;
@@ -198261,6 +201407,15 @@ static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
    return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
  }
}
+
static int jsonSameLabel(const JsonNode *p1, const JsonNode *p2){
+
  if( p1->jnFlags & JNODE_RAW ){
+
    return jsonLabelCompare(p2, p1->u.zJContent, p1->n);
+
  }else if( p2->jnFlags & JNODE_RAW ){
+
    return jsonLabelCompare(p1, p2->u.zJContent, p2->n);
+
  }else{
+
    return p1->n==p2->n && strncmp(p1->u.zJContent,p2->u.zJContent,p1->n)==0;
+
  }
+
}

/* forward declaration */
static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**);
@@ -198731,7 +201886,7 @@ static void jsonExtractFunc(
    zPath = (const char*)sqlite3_value_text(argv[1]);
    if( zPath==0 ) return;
    if( flags & JSON_ABPATH ){
-
      if( zPath[0]!='$' ){
+
      if( zPath[0]!='$' || (zPath[1]!='.' && zPath[1]!='[' && zPath[1]!=0) ){
        /* The -> and ->> operators accept abbreviated PATH arguments.  This
        ** is mostly for compatibility with PostgreSQL, but also for
        ** convenience.
@@ -198822,12 +201977,10 @@ static JsonNode *jsonMergePatch(
    assert( pPatch[i].eU==1 );
    nKey = pPatch[i].n;
    zKey = pPatch[i].u.zJContent;
-
    assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
    for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
      assert( pTarget[j].eType==JSON_STRING );
      assert( pTarget[j].jnFlags & JNODE_LABEL );
-
      assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
-
      if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){
+
      if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){
        if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break;
        if( pPatch[i+1].eType==JSON_NULL ){
          pTarget[j+1].jnFlags |= JNODE_REMOVE;
@@ -199114,8 +202267,8 @@ static void jsonTypeFunc(
/*
** json_valid(JSON)
**
-
** Return 1 if JSON is a well-formed JSON string according to RFC-7159.
-
** Return 0 otherwise.
+
** Return 1 if JSON is a well-formed canonical JSON string according
+
** to RFC-7159. Return 0 otherwise.
*/
static void jsonValidFunc(
  sqlite3_context *ctx,
@@ -199124,8 +202277,69 @@ static void jsonValidFunc(
){
  JsonParse *p;          /* The parse */
  UNUSED_PARAMETER(argc);
+
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  p = jsonParseCached(ctx, argv, 0);
-
  sqlite3_result_int(ctx, p!=0);
+
  if( p==0 || p->oom ){
+
    sqlite3_result_error_nomem(ctx);
+
    sqlite3_free(p);
+
  }else{
+
    sqlite3_result_int(ctx, p->nErr==0 && p->hasNonstd==0);
+
    if( p->nErr ) jsonParseFree(p);
+
  }
+
}
+

+
/*
+
** json_error_position(JSON)
+
**
+
** If the argument is not an interpretable JSON string, then return the 1-based
+
** character position at which the parser first recognized that the input
+
** was in error.  The left-most character is 1.  If the string is valid
+
** JSON, then return 0.
+
**
+
** Note that json_valid() is only true for strictly conforming canonical JSON.
+
** But this routine returns zero if the input contains extension.  Thus:
+
**
+
** (1) If the input X is strictly conforming canonical JSON:
+
**
+
**         json_valid(X) returns true
+
**         json_error_position(X) returns 0
+
**
+
** (2) If the input X is JSON but it includes extension (such as JSON5) that
+
**     are not part of RFC-8259:
+
**
+
**         json_valid(X) returns false
+
**         json_error_position(X) return 0
+
**
+
** (3) If the input X cannot be interpreted as JSON even taking extensions
+
**     into account:
+
**
+
**         json_valid(X) return false
+
**         json_error_position(X) returns 1 or more
+
*/
+
static void jsonErrorFunc(
+
  sqlite3_context *ctx,
+
  int argc,
+
  sqlite3_value **argv
+
){
+
  JsonParse *p;          /* The parse */
+
  UNUSED_PARAMETER(argc);
+
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+
  p = jsonParseCached(ctx, argv, 0);
+
  if( p==0 || p->oom ){
+
    sqlite3_result_error_nomem(ctx);
+
    sqlite3_free(p);
+
  }else if( p->nErr==0 ){
+
    sqlite3_result_int(ctx, 0);
+
  }else{
+
    int n = 1;
+
    u32 i;
+
    const char *z = p->zJson;
+
    for(i=0; i<p->iErr && ALWAYS(z[i]); i++){
+
      if( (z[i]&0xc0)!=0x80 ) n++;
+
    }
+
    sqlite3_result_int(ctx, n);
+
    jsonParseFree(p);
+
  }
}


@@ -199469,14 +202683,16 @@ static void jsonAppendObjectPathElement(
  assert( pNode->eU==1 );
  z = pNode->u.zJContent;
  nn = pNode->n;
-
  assert( nn>=2 );
-
  assert( z[0]=='"' );
-
  assert( z[nn-1]=='"' );
-
  if( nn>2 && sqlite3Isalpha(z[1]) ){
-
    for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){}
-
    if( jj==nn-1 ){
-
      z++;
-
      nn -= 2;
+
  if( (pNode->jnFlags & JNODE_RAW)==0 ){
+
    assert( nn>=2 );
+
    assert( z[0]=='"' || z[0]=='\'' );
+
    assert( z[nn-1]=='"' || z[0]=='\'' );
+
    if( nn>2 && sqlite3Isalpha(z[1]) ){
+
      for(jj=2; jj<nn-1 && sqlite3Isalnum(z[jj]); jj++){}
+
      if( jj==nn-1 ){
+
        z++;
+
        nn -= 2;
+
      }
    }
  }
  jsonPrintf(nn+2, pStr, ".%.*s", nn, z);
@@ -199653,6 +202869,13 @@ static int jsonEachBestIndex(
      idxMask |= iMask;
    }
  }
+
  if( pIdxInfo->nOrderBy>0
+
   && pIdxInfo->aOrderBy[0].iColumn<0
+
   && pIdxInfo->aOrderBy[0].desc==0
+
  ){
+
    pIdxInfo->orderByConsumed = 1;
+
  }
+

  if( (unusableMask & ~idxMask)!=0 ){
    /* If there are any unusable constraints on JSON or ROOT, then reject
    ** this entire plan */
@@ -199829,6 +203052,7 @@ SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){
    JFUNCTION(json_array,        -1, 0,  jsonArrayFunc),
    JFUNCTION(json_array_length,  1, 0,  jsonArrayLengthFunc),
    JFUNCTION(json_array_length,  2, 0,  jsonArrayLengthFunc),
+
    JFUNCTION(json_error_position,1, 0,  jsonErrorFunc),
    JFUNCTION(json_extract,      -1, 0,  jsonExtractFunc),
    JFUNCTION(->,                 2, JSON_JSON, jsonExtractFunc),
    JFUNCTION(->>,                2, JSON_SQL, jsonExtractFunc),
@@ -199848,10 +203072,10 @@ SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){
#endif
    WAGGREGATE(json_group_array,  1, 0, 0,
       jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
-
       SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS),
+
       SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC),
    WAGGREGATE(json_group_object, 2, 0, 0,
       jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
-
       SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS)
+
       SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC)
  };
  sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
#endif
@@ -200353,16 +203577,17 @@ struct RtreeMatchArg {
** at run-time.
*/
#ifndef SQLITE_BYTEORDER
-
#if defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
-
    defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)  ||    \
-
    defined(_M_AMD64) || defined(_M_ARM)     || defined(__x86)   ||    \
-
    defined(__arm__)
-
# define SQLITE_BYTEORDER    1234
-
#elif defined(sparc)    || defined(__ppc__)
-
# define SQLITE_BYTEORDER    4321
-
#else
-
# define SQLITE_BYTEORDER    0     /* 0 means "unknown at compile-time" */
-
#endif
+
# if defined(i386)      || defined(__i386__)      || defined(_M_IX86) ||    \
+
     defined(__x86_64)  || defined(__x86_64__)    || defined(_M_X64)  ||    \
+
     defined(_M_AMD64)  || defined(_M_ARM)        || defined(__x86)   ||    \
+
     defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64)
+
#   define SQLITE_BYTEORDER    1234
+
# elif defined(sparc)     || defined(__ppc__) || \
+
       defined(__ARMEB__) || defined(__AARCH64EB__)
+
#   define SQLITE_BYTEORDER    4321
+
# else
+
#   define SQLITE_BYTEORDER 0
+
# endif
#endif


@@ -200383,7 +203608,7 @@ static int readInt16(u8 *p){
  return (p[0]<<8) + p[1];
}
static void readCoord(u8 *p, RtreeCoord *pCoord){
-
  assert( ((((char*)p) - (char*)0)&3)==0 );  /* p is always 4-byte aligned */
+
  assert( (((sqlite3_uint64)p)&3)==0 );  /* p is always 4-byte aligned */
#if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300
  pCoord->u = _byteswap_ulong(*(u32*)p);
#elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
@@ -200437,7 +203662,7 @@ static void writeInt16(u8 *p, int i){
}
static int writeCoord(u8 *p, RtreeCoord *pCoord){
  u32 i;
-
  assert( ((((char*)p) - (char*)0)&3)==0 );  /* p is always 4-byte aligned */
+
  assert( (((sqlite3_uint64)p)&3)==0 );  /* p is always 4-byte aligned */
  assert( sizeof(RtreeCoord)==4 );
  assert( sizeof(u32)==4 );
#if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000
@@ -201165,7 +204390,7 @@ static void rtreeNonleafConstraint(
  assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE
      || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE
      || p->op==RTREE_FALSE );
-
  assert( ((((char*)pCellData) - (char*)0)&3)==0 );  /* 4-byte aligned */
+
  assert( (((sqlite3_uint64)pCellData)&3)==0 );  /* 4-byte aligned */
  switch( p->op ){
    case RTREE_TRUE:  return;   /* Always satisfied */
    case RTREE_FALSE: break;    /* Never satisfied */
@@ -201218,7 +204443,7 @@ static void rtreeLeafConstraint(
      || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE
      || p->op==RTREE_FALSE );
  pCellData += 8 + p->iCoord*4;
-
  assert( ((((char*)pCellData) - (char*)0)&3)==0 );  /* 4-byte aligned */
+
  assert( (((sqlite3_uint64)pCellData)&3)==0 );  /* 4-byte aligned */
  RTREE_DECODE_COORD(eInt, pCellData, xN);
  switch( p->op ){
    case RTREE_TRUE:  return;   /* Always satisfied */
@@ -204590,7 +207815,7 @@ static GeoPoly *geopolyFuncParam(
  int nByte;
  testcase( pCtx==0 );
  if( sqlite3_value_type(pVal)==SQLITE_BLOB
-
   && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord))
+
   && (nByte = sqlite3_value_bytes(pVal))>=(int)(4+6*sizeof(GeoCoord))
  ){
    const unsigned char *a = sqlite3_value_blob(pVal);
    int nVertex;
@@ -204648,6 +207873,7 @@ static void geopolyBlobFunc(
  sqlite3_value **argv
){
  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+
  (void)argc;
  if( p ){
    sqlite3_result_blob(context, p->hdr,
       4+8*p->nVertex, SQLITE_TRANSIENT);
@@ -204667,6 +207893,7 @@ static void geopolyJsonFunc(
  sqlite3_value **argv
){
  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+
  (void)argc;
  if( p ){
    sqlite3 *db = sqlite3_context_db_handle(context);
    sqlite3_str *x = sqlite3_str_new(db);
@@ -204748,6 +207975,7 @@ static void geopolyXformFunc(
  double F = sqlite3_value_double(argv[6]);
  GeoCoord x1, y1, x0, y0;
  int ii;
+
  (void)argc;
  if( p ){
    for(ii=0; ii<p->nVertex; ii++){
      x0 = GeoX(p,ii);
@@ -204798,6 +208026,7 @@ static void geopolyAreaFunc(
  sqlite3_value **argv
){
  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+
  (void)argc;
  if( p ){
    sqlite3_result_double(context, geopolyArea(p));
    sqlite3_free(p);
@@ -204823,6 +208052,7 @@ static void geopolyCcwFunc(
  sqlite3_value **argv
){
  GeoPoly *p = geopolyFuncParam(context, argv[0], 0);
+
  (void)argc;
  if( p ){
    if( geopolyArea(p)<0.0 ){
      int ii, jj;
@@ -204877,6 +208107,7 @@ static void geopolyRegularFunc(
  int n = sqlite3_value_int(argv[3]);
  int i;
  GeoPoly *p;
+
  (void)argc;

  if( n<3 || r<=0.0 ) return;
  if( n>1000 ) n = 1000;
@@ -204986,6 +208217,7 @@ static void geopolyBBoxFunc(
  sqlite3_value **argv
){
  GeoPoly *p = geopolyBBox(context, argv[0], 0, 0);
+
  (void)argc;
  if( p ){
    sqlite3_result_blob(context, p->hdr,
       4+8*p->nVertex, SQLITE_TRANSIENT);
@@ -205013,6 +208245,7 @@ static void geopolyBBoxStep(
){
  RtreeCoord a[4];
  int rc = SQLITE_OK;
+
  (void)argc;
  (void)geopolyBBox(context, argv[0], a, &rc);
  if( rc==SQLITE_OK ){
    GeoBBox *pBBox;
@@ -205101,6 +208334,8 @@ static void geopolyContainsPointFunc(
  int v = 0;
  int cnt = 0;
  int ii;
+
  (void)argc;
+

  if( p1==0 ) return;
  for(ii=0; ii<p1->nVertex-1; ii++){
    v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
@@ -205140,6 +208375,7 @@ static void geopolyWithinFunc(
){
  GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
  GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
+
  (void)argc;
  if( p1 && p2 ){
    int x = geopolyOverlap(p1, p2);
    if( x<0 ){
@@ -205470,6 +208706,7 @@ static void geopolyOverlapFunc(
){
  GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0);
  GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0);
+
  (void)argc;
  if( p1 && p2 ){
    int x = geopolyOverlap(p1, p2);
    if( x<0 ){
@@ -205490,8 +208727,12 @@ static void geopolyDebugFunc(
  int argc,
  sqlite3_value **argv
){
+
  (void)context;
+
  (void)argc;
#ifdef GEOPOLY_ENABLE_DEBUG
  geo_debug = sqlite3_value_int(argv[0]);
+
#else
+
  (void)argv;
#endif
}

@@ -205519,6 +208760,7 @@ static int geopolyInit(
  sqlite3_str *pSql;
  char *zSql;
  int ii;
+
  (void)pAux;

  sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);

@@ -205635,6 +208877,7 @@ static int geopolyFilter(
  RtreeNode *pRoot = 0;
  int rc = SQLITE_OK;
  int iCell = 0;
+
  (void)idxStr;

  rtreeReference(pRtree);

@@ -205761,6 +209004,7 @@ static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  int iRowidTerm = -1;
  int iFuncTerm = -1;
  int idxNum = 0;
+
  (void)tab;

  for(ii=0; ii<pIdxInfo->nConstraint; ii++){
    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
@@ -206007,6 +209251,8 @@ static int geopolyFindFunction(
  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
  void **ppArg
){
+
  (void)pVtab;
+
  (void)nArg;
  if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){
    *pxFunc = geopolyOverlapFunc;
    *ppArg = 0;
@@ -206076,7 +209322,7 @@ static int sqlite3_geopoly_init(sqlite3 *db){
  } aAgg[] = {
     { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox"    },
  };
-
  int i;
+
  unsigned int i;
  for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
    int enc;
    if( aFunc[i].bPure ){
@@ -207297,7 +210543,7 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
** The order of the columns in the data_% table does not matter.
**
** Instead of a regular table, the RBU database may also contain virtual
-
** tables or view named using the data_<target> naming scheme.
+
** tables or views named using the data_<target> naming scheme.
**
** Instead of the plain data_<target> naming scheme, RBU database tables
** may also be named data<integer>_<target>, where <integer> is any sequence
@@ -207310,7 +210556,7 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
**
** If the target database table is a virtual table or a table that has no
** PRIMARY KEY declaration, the data_% table must also contain a column
-
** named "rbu_rowid". This column is mapped to the tables implicit primary
+
** named "rbu_rowid". This column is mapped to the table's implicit primary
** key column - "rowid". Virtual tables for which the "rowid" column does
** not function like a primary key value cannot be updated using RBU. For
** example, if the target db contains either of the following:
@@ -210776,11 +214022,11 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
  **     no-ops. These locks will not be released until the connection
  **     is closed.
  **
-
  **   * Attempting to xSync() the database file causes an SQLITE_INTERNAL
+
  **   * Attempting to xSync() the database file causes an SQLITE_NOTICE
  **     error.
  **
  ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the
-
  ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[]
+
  ** checkpoint below fails with SQLITE_NOTICE, and leaves the aFrame[]
  ** array populated with a set of (frame -> page) mappings. Because the
  ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy
  ** data from the wal file into the database file according to the
@@ -210790,7 +214036,7 @@ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){
    int rc2;
    p->eStage = RBU_STAGE_CAPTURE;
    rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0);
-
    if( rc2!=SQLITE_INTERNAL ) p->rc = rc2;
+
    if( rc2!=SQLITE_NOTICE ) p->rc = rc2;
  }

  if( p->rc==SQLITE_OK && p->nFrame>0 ){
@@ -210836,7 +214082,7 @@ static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){

  if( pRbu->mLock!=mReq ){
    pRbu->rc = SQLITE_BUSY;
-
    return SQLITE_INTERNAL;
+
    return SQLITE_NOTICE_RBU;
  }

  pRbu->pgsz = iAmt;
@@ -210886,6 +214132,11 @@ static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){
  p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
}

+
/*
+
** This value is copied from the definition of ZIPVFS_CTRL_FILE_POINTER
+
** in zipvfs.h.
+
*/
+
#define RBU_ZIPVFS_CTRL_FILE_POINTER 230439

/*
** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if
@@ -210894,9 +214145,20 @@ static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){
static int rbuLockDatabase(sqlite3 *db){
  int rc = SQLITE_OK;
  sqlite3_file *fd = 0;
-
  sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd);

-
  if( fd->pMethods ){
+
  sqlite3_file_control(db, "main", RBU_ZIPVFS_CTRL_FILE_POINTER, &fd);
+
  if( fd ){
+
    sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd);
+
    rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED);
+
    if( rc==SQLITE_OK ){
+
      rc = fd->pMethods->xUnlock(fd, SQLITE_LOCK_NONE);
+
    }
+
    sqlite3_file_control(db, "main", RBU_ZIPVFS_CTRL_FILE_POINTER, &fd);
+
  }else{
+
    sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd);
+
  }
+

+
  if( rc==SQLITE_OK && fd->pMethods ){
    rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED);
    if( rc==SQLITE_OK ){
      rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE);
@@ -211575,7 +214837,8 @@ static void rbuSetupOal(sqlite3rbu *p, RbuState *pState){
static void rbuDeleteOalFile(sqlite3rbu *p){
  char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget);
  if( zOal ){
-
    sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
+
    sqlite3_vfs *pVfs = 0;
+
    sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_VFS_POINTER, &pVfs);
    assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 );
    pVfs->xDelete(pVfs, zOal, 0);
    sqlite3_free(zOal);
@@ -212223,7 +215486,7 @@ SQLITE_API void sqlite3rbu_rename_handler(
**     database file are recorded. xShmLock() calls to unlock the same
**     locks are no-ops (so that once obtained, these locks are never
**     relinquished). Finally, calls to xSync() on the target database
-
**     file fail with SQLITE_INTERNAL errors.
+
**     file fail with SQLITE_NOTICE errors.
*/

static void rbuUnlockShm(rbu_file *p){
@@ -212332,9 +215595,12 @@ static int rbuVfsClose(sqlite3_file *pFile){
  sqlite3_free(p->zDel);

  if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
+
    const sqlite3_io_methods *pMeth = p->pReal->pMethods;
    rbuMainlistRemove(p);
    rbuUnlockShm(p);
-
    p->pReal->pMethods->xShmUnmap(p->pReal, 0);
+
    if( pMeth->iVersion>1 && pMeth->xShmUnmap ){
+
      pMeth->xShmUnmap(p->pReal, 0);
+
    }
  }
  else if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){
    rbuUpdateTempSize(p, 0);
@@ -212502,7 +215768,7 @@ static int rbuVfsSync(sqlite3_file *pFile, int flags){
  rbu_file *p = (rbu_file *)pFile;
  if( p->pRbu && p->pRbu->eStage==RBU_STAGE_CAPTURE ){
    if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
-
      return SQLITE_INTERNAL;
+
      return SQLITE_NOTICE_RBU;
    }
    return SQLITE_OK;
  }
@@ -212793,6 +216059,25 @@ static int rbuVfsOpen(
    rbuVfsShmUnmap,               /* xShmUnmap */
    0, 0                          /* xFetch, xUnfetch */
  };
+
  static sqlite3_io_methods rbuvfs_io_methods1 = {
+
    1,                            /* iVersion */
+
    rbuVfsClose,                  /* xClose */
+
    rbuVfsRead,                   /* xRead */
+
    rbuVfsWrite,                  /* xWrite */
+
    rbuVfsTruncate,               /* xTruncate */
+
    rbuVfsSync,                   /* xSync */
+
    rbuVfsFileSize,               /* xFileSize */
+
    rbuVfsLock,                   /* xLock */
+
    rbuVfsUnlock,                 /* xUnlock */
+
    rbuVfsCheckReservedLock,      /* xCheckReservedLock */
+
    rbuVfsFileControl,            /* xFileControl */
+
    rbuVfsSectorSize,             /* xSectorSize */
+
    rbuVfsDeviceCharacteristics,  /* xDeviceCharacteristics */
+
    0, 0, 0, 0, 0, 0
+
  };
+

+

+

  rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs;
  sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs;
  rbu_file *pFd = (rbu_file *)pFile;
@@ -212847,10 +216132,15 @@ static int rbuVfsOpen(
    rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags);
  }
  if( pFd->pReal->pMethods ){
+
    const sqlite3_io_methods *pMeth = pFd->pReal->pMethods;
    /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
    ** pointer and, if the file is a main database file, link it into the
    ** mutex protected linked list of all such files.  */
-
    pFile->pMethods = &rbuvfs_io_methods;
+
    if( pMeth->iVersion<2 || pMeth->xShmLock==0 ){
+
      pFile->pMethods = &rbuvfs_io_methods1;
+
    }else{
+
      pFile->pMethods = &rbuvfs_io_methods;
+
    }
    if( flags & SQLITE_OPEN_MAIN_DB ){
      rbuMainlistAdd(pFd);
    }
@@ -213283,6 +216573,7 @@ static int statConnect(
  StatTable *pTab = 0;
  int rc = SQLITE_OK;
  int iDb;
+
  (void)pAux;

  if( argc>=4 ){
    Token nm;
@@ -213336,6 +216627,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  int iSchema = -1;
  int iName = -1;
  int iAgg = -1;
+
  (void)tab;

  /* Look for a valid schema=? constraint.  If found, change the idxNum to
  ** 1 and request the value of that constraint be sent to xFilter.  And
@@ -213861,6 +217153,8 @@ static int statFilter(
  int iArg = 0;           /* Count of argv[] parameters used so far */
  int rc = SQLITE_OK;     /* Result of this operation */
  const char *zName = 0;  /* Only provide analysis of this table */
+
  (void)argc;
+
  (void)idxStr;

  statResetCsr(pCsr);
  sqlite3_finalize(pCsr->pStmt);
@@ -213944,16 +217238,16 @@ static int statColumn(
      }
      break;
    case 4:            /* ncell */
-
      sqlite3_result_int(ctx, pCsr->nCell);
+
      sqlite3_result_int64(ctx, pCsr->nCell);
      break;
    case 5:            /* payload */
-
      sqlite3_result_int(ctx, pCsr->nPayload);
+
      sqlite3_result_int64(ctx, pCsr->nPayload);
      break;
    case 6:            /* unused */
-
      sqlite3_result_int(ctx, pCsr->nUnused);
+
      sqlite3_result_int64(ctx, pCsr->nUnused);
      break;
    case 7:            /* mx_payload */
-
      sqlite3_result_int(ctx, pCsr->nMxPayload);
+
      sqlite3_result_int64(ctx, pCsr->nMxPayload);
      break;
    case 8:            /* pgoffset */
      if( !pCsr->isAgg ){
@@ -213961,7 +217255,7 @@ static int statColumn(
      }
      break;
    case 9:            /* pgsize */
-
      sqlite3_result_int(ctx, pCsr->szPage);
+
      sqlite3_result_int64(ctx, pCsr->szPage);
      break;
    case 10: {         /* schema */
      sqlite3 *db = sqlite3_context_db_handle(ctx);
@@ -214095,8 +217389,13 @@ static int dbpageConnect(
){
  DbpageTable *pTab = 0;
  int rc = SQLITE_OK;
+
  (void)pAux;
+
  (void)argc;
+
  (void)argv;
+
  (void)pzErr;

  sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
+
  sqlite3_vtab_config(db, SQLITE_VTAB_USES_ALL_SCHEMAS);
  rc = sqlite3_declare_vtab(db,
          "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)");
  if( rc==SQLITE_OK ){
@@ -214133,6 +217432,7 @@ static int dbpageDisconnect(sqlite3_vtab *pVtab){
static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  int i;
  int iPlan = 0;
+
  (void)tab;

  /* If there is a schema= constraint, it must be honored.  Report a
  ** ridiculously large estimated cost if the schema= constraint is
@@ -214179,7 +217479,6 @@ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  ){
    pIdxInfo->orderByConsumed = 1;
  }
-
  sqlite3VtabUsesAllSchemas(pIdxInfo);
  return SQLITE_OK;
}

@@ -214248,6 +217547,8 @@ static int dbpageFilter(
  sqlite3 *db = pTab->db;
  Btree *pBt;

+
  (void)idxStr;
+

  /* Default setting is no rows of result */
  pCsr->pgno = 1;
  pCsr->mxPgno = 0;
@@ -214262,7 +217563,7 @@ static int dbpageFilter(
    pCsr->iDb = 0;
  }
  pBt = db->aDb[pCsr->iDb].pBt;
-
  if( pBt==0 ) return SQLITE_OK;
+
  if( NEVER(pBt==0) ) return SQLITE_OK;
  pCsr->pPager = sqlite3BtreePager(pBt);
  pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
  pCsr->mxPgno = sqlite3BtreeLastPage(pBt);
@@ -214343,6 +217644,7 @@ static int dbpageUpdate(
  Pager *pPager;
  int szPage;

+
  (void)pRowid;
  if( pTab->db->flags & SQLITE_Defensive ){
    zErr = "read-only";
    goto update_fail;
@@ -214352,18 +217654,20 @@ static int dbpageUpdate(
    goto update_fail;
  }
  pgno = sqlite3_value_int(argv[0]);
-
  if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){
+
  if( sqlite3_value_type(argv[0])==SQLITE_NULL
+
   || (Pgno)sqlite3_value_int(argv[1])!=pgno
+
  ){
    zErr = "cannot insert";
    goto update_fail;
  }
  zSchema = (const char*)sqlite3_value_text(argv[4]);
-
  iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1;
-
  if( iDb<0 ){
+
  iDb = ALWAYS(zSchema) ? sqlite3FindDbName(pTab->db, zSchema) : -1;
+
  if( NEVER(iDb<0) ){
    zErr = "no such schema";
    goto update_fail;
  }
  pBt = pTab->db->aDb[iDb].pBt;
-
  if( pgno<1 || pBt==0 || pgno>sqlite3BtreeLastPage(pBt) ){
+
  if( NEVER(pgno<1) || NEVER(pBt==0) || NEVER(pgno>sqlite3BtreeLastPage(pBt)) ){
    zErr = "bad page number";
    goto update_fail;
  }
@@ -214402,12 +217706,11 @@ static int dbpageBegin(sqlite3_vtab *pVtab){
  DbpageTable *pTab = (DbpageTable *)pVtab;
  sqlite3 *db = pTab->db;
  int i;
-
  int rc = SQLITE_OK;
-
  for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
+
  for(i=0; i<db->nDb; i++){
    Btree *pBt = db->aDb[i].pBt;
-
    if( pBt ) rc = sqlite3BtreeBeginTrans(pBt, 1, 0);
+
    if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0);
  }
-
  return rc;
+
  return SQLITE_OK;
}


@@ -214476,6 +217779,8 @@ typedef struct SessionInput SessionInput;
# endif
#endif

+
#define SESSIONS_ROWID "_rowid_"
+

static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE;

typedef struct SessionHook SessionHook;
@@ -214497,6 +217802,7 @@ struct sqlite3_session {
  int bEnable;                    /* True if currently recording */
  int bIndirect;                  /* True if all changes are indirect */
  int bAutoAttach;                /* True to auto-attach tables */
+
  int bImplicitPK;                /* True to handle tables with implicit PK */
  int rc;                         /* Non-zero if an error has occurred */
  void *pFilterCtx;               /* First argument to pass to xTableFilter */
  int (*xTableFilter)(void *pCtx, const char *zTab);
@@ -214573,6 +217879,7 @@ struct SessionTable {
  char *zName;                    /* Local name of table */
  int nCol;                       /* Number of columns in table zName */
  int bStat1;                     /* True if this is sqlite_stat1 */
+
  int bRowid;                     /* True if this table uses rowid for PK */
  const char **azCol;             /* Column names */
  u8 *abPK;                       /* Array of primary key flags */
  int nEntry;                     /* Total number of entries in hash table */
@@ -214965,6 +218272,7 @@ static unsigned int sessionHashAppendType(unsigned int h, int eType){
*/
static int sessionPreupdateHash(
  sqlite3_session *pSession,      /* Session object that owns pTab */
+
  i64 iRowid,
  SessionTable *pTab,             /* Session table handle */
  int bNew,                       /* True to hash the new.* PK */
  int *piHash,                    /* OUT: Hash value */
@@ -214973,48 +218281,53 @@ static int sessionPreupdateHash(
  unsigned int h = 0;             /* Hash value to return */
  int i;                          /* Used to iterate through columns */

-
  assert( *pbNullPK==0 );
-
  assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) );
-
  for(i=0; i<pTab->nCol; i++){
-
    if( pTab->abPK[i] ){
-
      int rc;
-
      int eType;
-
      sqlite3_value *pVal;
-

-
      if( bNew ){
-
        rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal);
-
      }else{
-
        rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal);
-
      }
-
      if( rc!=SQLITE_OK ) return rc;
+
  if( pTab->bRowid ){
+
    assert( pTab->nCol-1==pSession->hook.xCount(pSession->hook.pCtx) );
+
    h = sessionHashAppendI64(h, iRowid);
+
  }else{
+
    assert( *pbNullPK==0 );
+
    assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) );
+
    for(i=0; i<pTab->nCol; i++){
+
      if( pTab->abPK[i] ){
+
        int rc;
+
        int eType;
+
        sqlite3_value *pVal;

-
      eType = sqlite3_value_type(pVal);
-
      h = sessionHashAppendType(h, eType);
-
      if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
-
        i64 iVal;
-
        if( eType==SQLITE_INTEGER ){
-
          iVal = sqlite3_value_int64(pVal);
+
        if( bNew ){
+
          rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal);
        }else{
-
          double rVal = sqlite3_value_double(pVal);
-
          assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
-
          memcpy(&iVal, &rVal, 8);
+
          rc = pSession->hook.xOld(pSession->hook.pCtx, i, &pVal);
        }
-
        h = sessionHashAppendI64(h, iVal);
-
      }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
-
        const u8 *z;
-
        int n;
-
        if( eType==SQLITE_TEXT ){
-
          z = (const u8 *)sqlite3_value_text(pVal);
+
        if( rc!=SQLITE_OK ) return rc;
+

+
        eType = sqlite3_value_type(pVal);
+
        h = sessionHashAppendType(h, eType);
+
        if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
+
          i64 iVal;
+
          if( eType==SQLITE_INTEGER ){
+
            iVal = sqlite3_value_int64(pVal);
+
          }else{
+
            double rVal = sqlite3_value_double(pVal);
+
            assert( sizeof(iVal)==8 && sizeof(rVal)==8 );
+
            memcpy(&iVal, &rVal, 8);
+
          }
+
          h = sessionHashAppendI64(h, iVal);
+
        }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
+
          const u8 *z;
+
          int n;
+
          if( eType==SQLITE_TEXT ){
+
            z = (const u8 *)sqlite3_value_text(pVal);
+
          }else{
+
            z = (const u8 *)sqlite3_value_blob(pVal);
+
          }
+
          n = sqlite3_value_bytes(pVal);
+
          if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
+
          h = sessionHashAppendBlob(h, n, z);
        }else{
-
          z = (const u8 *)sqlite3_value_blob(pVal);
+
          assert( eType==SQLITE_NULL );
+
          assert( pTab->bStat1==0 || i!=1 );
+
          *pbNullPK = 1;
        }
-
        n = sqlite3_value_bytes(pVal);
-
        if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
-
        h = sessionHashAppendBlob(h, n, z);
-
      }else{
-
        assert( eType==SQLITE_NULL );
-
        assert( pTab->bStat1==0 || i!=1 );
-
        *pbNullPK = 1;
      }
    }
  }
@@ -215297,6 +218610,7 @@ static int sessionMergeUpdate(
*/
static int sessionPreupdateEqual(
  sqlite3_session *pSession,      /* Session object that owns SessionTable */
+
  i64 iRowid,                     /* Rowid value if pTab->bRowid */
  SessionTable *pTab,             /* Table associated with change */
  SessionChange *pChange,         /* Change to compare to */
  int op                          /* Current pre-update operation */
@@ -215304,6 +218618,11 @@ static int sessionPreupdateEqual(
  int iCol;                       /* Used to iterate through columns */
  u8 *a = pChange->aRecord;       /* Cursor used to scan change record */

+
  if( pTab->bRowid ){
+
    if( a[0]!=SQLITE_INTEGER ) return 0;
+
    return sessionGetI64(&a[1])==iRowid;
+
  }
+

  assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
  for(iCol=0; iCol<pTab->nCol; iCol++){
    if( !pTab->abPK[iCol] ){
@@ -215448,7 +218767,8 @@ static int sessionTableInfo(
  int *pnCol,                     /* OUT: number of columns */
  const char **pzTab,             /* OUT: Copy of zThis */
  const char ***pazCol,           /* OUT: Array of column names for table */
-
  u8 **pabPK                      /* OUT: Array of booleans - true for PK col */
+
  u8 **pabPK,                     /* OUT: Array of booleans - true for PK col */
+
  int *pbRowid                    /* OUT: True if only PK is a rowid */
){
  char *zPragma;
  sqlite3_stmt *pStmt;
@@ -215460,6 +218780,7 @@ static int sessionTableInfo(
  u8 *pAlloc = 0;
  char **azCol = 0;
  u8 *abPK = 0;
+
  int bRowid = 0;                 /* Set to true to use rowid as PK */

  assert( pazCol && pabPK );

@@ -215504,10 +218825,15 @@ static int sessionTableInfo(
  }

  nByte = nThis + 1;
+
  bRowid = (pbRowid!=0);
  while( SQLITE_ROW==sqlite3_step(pStmt) ){
    nByte += sqlite3_column_bytes(pStmt, 1);
    nDbCol++;
+
    if( sqlite3_column_int(pStmt, 5) ) bRowid = 0;
  }
+
  if( nDbCol==0 ) bRowid = 0;
+
  nDbCol += bRowid;
+
  nByte += strlen(SESSIONS_ROWID);
  rc = sqlite3_reset(pStmt);

  if( rc==SQLITE_OK ){
@@ -215529,6 +218855,14 @@ static int sessionTableInfo(
    }

    i = 0;
+
    if( bRowid ){
+
      size_t nName = strlen(SESSIONS_ROWID);
+
      memcpy(pAlloc, SESSIONS_ROWID, nName+1);
+
      azCol[i] = (char*)pAlloc;
+
      pAlloc += nName+1;
+
      abPK[i] = 1;
+
      i++;
+
    }
    while( SQLITE_ROW==sqlite3_step(pStmt) ){
      int nName = sqlite3_column_bytes(pStmt, 1);
      const unsigned char *zName = sqlite3_column_text(pStmt, 1);
@@ -215540,7 +218874,6 @@ static int sessionTableInfo(
      i++;
    }
    rc = sqlite3_reset(pStmt);
-

  }

  /* If successful, populate the output variables. Otherwise, zero them and
@@ -215557,6 +218890,7 @@ static int sessionTableInfo(
    if( pzTab ) *pzTab = 0;
    sessionFree(pSession, azCol);
  }
+
  if( pbRowid ) *pbRowid = bRowid;
  sqlite3_finalize(pStmt);
  return rc;
}
@@ -215578,7 +218912,8 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){
    u8 *abPK;
    assert( pTab->azCol==0 || pTab->abPK==0 );
    pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb,
-
        pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK
+
        pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK,
+
        (pSession->bImplicitPK ? &pTab->bRowid : 0)
    );
    if( pSession->rc==SQLITE_OK ){
      int i;
@@ -215650,6 +218985,7 @@ static int sessionUpdateMaxSize(
){
  i64 nNew = 2;
  if( pC->op==SQLITE_INSERT ){
+
    if( pTab->bRowid ) nNew += 9;
    if( op!=SQLITE_DELETE ){
      int ii;
      for(ii=0; ii<pTab->nCol; ii++){
@@ -215666,12 +219002,16 @@ static int sessionUpdateMaxSize(
  }else{
    int ii;
    u8 *pCsr = pC->aRecord;
-
    for(ii=0; ii<pTab->nCol; ii++){
+
    if( pTab->bRowid ){
+
      nNew += 9 + 1;
+
      pCsr += 9;
+
    }
+
    for(ii=pTab->bRowid; ii<pTab->nCol; ii++){
      int bChanged = 1;
      int nOld = 0;
      int eType;
      sqlite3_value *p = 0;
-
      pSession->hook.xNew(pSession->hook.pCtx, ii, &p);
+
      pSession->hook.xNew(pSession->hook.pCtx, ii-pTab->bRowid, &p);
      if( p==0 ){
        return SQLITE_NOMEM;
      }
@@ -215750,6 +219090,7 @@ static int sessionUpdateMaxSize(
*/
static void sessionPreupdateOneChange(
  int op,                         /* One of SQLITE_UPDATE, INSERT, DELETE */
+
  i64 iRowid,
  sqlite3_session *pSession,      /* Session object pTab is attached to */
  SessionTable *pTab              /* Table that change applies to */
){
@@ -215765,7 +219106,7 @@ static void sessionPreupdateOneChange(

  /* Check the number of columns in this xPreUpdate call matches the
  ** number of columns in the table.  */
-
  if( pTab->nCol!=pSession->hook.xCount(pSession->hook.pCtx) ){
+
  if( (pTab->nCol-pTab->bRowid)!=pSession->hook.xCount(pSession->hook.pCtx) ){
    pSession->rc = SQLITE_SCHEMA;
    return;
  }
@@ -215798,14 +219139,16 @@ static void sessionPreupdateOneChange(
  /* Calculate the hash-key for this change. If the primary key of the row
  ** includes a NULL value, exit early. Such changes are ignored by the
  ** session module. */
-
  rc = sessionPreupdateHash(pSession, pTab, op==SQLITE_INSERT, &iHash, &bNull);
+
  rc = sessionPreupdateHash(
+
      pSession, iRowid, pTab, op==SQLITE_INSERT, &iHash, &bNull
+
  );
  if( rc!=SQLITE_OK ) goto error_out;

  if( bNull==0 ){
    /* Search the hash table for an existing record for this row. */
    SessionChange *pC;
    for(pC=pTab->apChange[iHash]; pC; pC=pC->pNext){
-
      if( sessionPreupdateEqual(pSession, pTab, pC, op) ) break;
+
      if( sessionPreupdateEqual(pSession, iRowid, pTab, pC, op) ) break;
    }

    if( pC==0 ){
@@ -215820,7 +219163,7 @@ static void sessionPreupdateOneChange(

      /* Figure out how large an allocation is required */
      nByte = sizeof(SessionChange);
-
      for(i=0; i<pTab->nCol; i++){
+
      for(i=0; i<(pTab->nCol-pTab->bRowid); i++){
        sqlite3_value *p = 0;
        if( op!=SQLITE_INSERT ){
          TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p);
@@ -215835,6 +219178,9 @@ static void sessionPreupdateOneChange(
        rc = sessionSerializeValue(0, p, &nByte);
        if( rc!=SQLITE_OK ) goto error_out;
      }
+
      if( pTab->bRowid ){
+
        nByte += 9;               /* Size of rowid field - an integer */
+
      }

      /* Allocate the change object */
      pC = (SessionChange *)sessionMalloc64(pSession, nByte);
@@ -215851,7 +219197,12 @@ static void sessionPreupdateOneChange(
      ** required values and encodings have already been cached in memory.
      ** It is not possible for an OOM to occur in this block. */
      nByte = 0;
-
      for(i=0; i<pTab->nCol; i++){
+
      if( pTab->bRowid ){
+
        pC->aRecord[0] = SQLITE_INTEGER;
+
        sessionPutI64(&pC->aRecord[1], iRowid);
+
        nByte = 9;
+
      }
+
      for(i=0; i<(pTab->nCol-pTab->bRowid); i++){
        sqlite3_value *p = 0;
        if( op!=SQLITE_INSERT ){
          pSession->hook.xOld(pSession->hook.pCtx, i, &p);
@@ -215950,6 +219301,8 @@ static void xPreUpdate(
  int nDb = sqlite3Strlen30(zDb);

  assert( sqlite3_mutex_held(db->mutex) );
+
  (void)iKey1;
+
  (void)iKey2;

  for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){
    SessionTable *pTab;
@@ -215964,9 +219317,10 @@ static void xPreUpdate(
    pSession->rc = sessionFindTable(pSession, zName, &pTab);
    if( pTab ){
      assert( pSession->rc==SQLITE_OK );
-
      sessionPreupdateOneChange(op, pSession, pTab);
+
      assert( op==SQLITE_UPDATE || iKey1==iKey2 );
+
      sessionPreupdateOneChange(op, iKey1, pSession, pTab);
      if( op==SQLITE_UPDATE ){
-
        sessionPreupdateOneChange(SQLITE_INSERT, pSession, pTab);
+
        sessionPreupdateOneChange(SQLITE_INSERT, iKey2, pSession, pTab);
      }
    }
  }
@@ -216005,6 +219359,7 @@ static void sessionPreupdateHooks(
typedef struct SessionDiffCtx SessionDiffCtx;
struct SessionDiffCtx {
  sqlite3_stmt *pStmt;
+
  int bRowid;
  int nOldOff;
};

@@ -216013,19 +219368,20 @@ struct SessionDiffCtx {
*/
static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){
  SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
-
  *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff);
+
  *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff+p->bRowid);
  return SQLITE_OK;
}
static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){
  SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
-
  *ppVal = sqlite3_column_value(p->pStmt, iVal);
+
  *ppVal = sqlite3_column_value(p->pStmt, iVal+p->bRowid);
   return SQLITE_OK;
}
static int sessionDiffCount(void *pCtx){
  SessionDiffCtx *p = (SessionDiffCtx*)pCtx;
-
  return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt);
+
  return (p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt)) - p->bRowid;
}
static int sessionDiffDepth(void *pCtx){
+
  (void)pCtx;
  return 0;
}

@@ -216099,17 +219455,18 @@ static char *sessionExprCompareOther(
}

static char *sessionSelectFindNew(
-
  int nCol,
  const char *zDb1,      /* Pick rows in this db only */
  const char *zDb2,      /* But not in this one */
+
  int bRowid,
  const char *zTbl,      /* Table name */
  const char *zExpr
){
+
  const char *zSel = (bRowid ? SESSIONS_ROWID ", *" : "*");
  char *zRet = sqlite3_mprintf(
-
      "SELECT * FROM \"%w\".\"%w\" WHERE NOT EXISTS ("
+
      "SELECT %s FROM \"%w\".\"%w\" WHERE NOT EXISTS ("
      "  SELECT 1 FROM \"%w\".\"%w\" WHERE %s"
      ")",
-
      zDb1, zTbl, zDb2, zTbl, zExpr
+
      zSel, zDb1, zTbl, zDb2, zTbl, zExpr
  );
  return zRet;
}
@@ -216123,7 +219480,9 @@ static int sessionDiffFindNew(
  char *zExpr
){
  int rc = SQLITE_OK;
-
  char *zStmt = sessionSelectFindNew(pTab->nCol, zDb1, zDb2, pTab->zName,zExpr);
+
  char *zStmt = sessionSelectFindNew(
+
      zDb1, zDb2, pTab->bRowid, pTab->zName, zExpr
+
  );

  if( zStmt==0 ){
    rc = SQLITE_NOMEM;
@@ -216134,8 +219493,10 @@ static int sessionDiffFindNew(
      SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx;
      pDiffCtx->pStmt = pStmt;
      pDiffCtx->nOldOff = 0;
+
      pDiffCtx->bRowid = pTab->bRowid;
      while( SQLITE_ROW==sqlite3_step(pStmt) ){
-
        sessionPreupdateOneChange(op, pSession, pTab);
+
        i64 iRowid = (pTab->bRowid ? sqlite3_column_int64(pStmt, 0) : 0);
+
        sessionPreupdateOneChange(op, iRowid, pSession, pTab);
      }
      rc = sqlite3_finalize(pStmt);
    }
@@ -216145,6 +219506,27 @@ static int sessionDiffFindNew(
  return rc;
}

+
/*
+
** Return a comma-separated list of the fully-qualified (with both database
+
** and table name) column names from table pTab. e.g.
+
**
+
**    "main"."t1"."a", "main"."t1"."b", "main"."t1"."c"
+
*/
+
static char *sessionAllCols(
+
  const char *zDb,
+
  SessionTable *pTab
+
){
+
  int ii;
+
  char *zRet = 0;
+
  for(ii=0; ii<pTab->nCol; ii++){
+
    zRet = sqlite3_mprintf("%z%s\"%w\".\"%w\".\"%w\"",
+
        zRet, (zRet ? ", " : ""), zDb, pTab->zName, pTab->azCol[ii]
+
    );
+
    if( !zRet ) break;
+
  }
+
  return zRet;
+
}
+

static int sessionDiffFindModified(
  sqlite3_session *pSession,
  SessionTable *pTab,
@@ -216159,11 +219541,13 @@ static int sessionDiffFindModified(
  if( zExpr2==0 ){
    rc = SQLITE_NOMEM;
  }else{
+
    char *z1 = sessionAllCols(pSession->zDb, pTab);
+
    char *z2 = sessionAllCols(zFrom, pTab);
    char *zStmt = sqlite3_mprintf(
-
        "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)",
-
        pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2
+
        "SELECT %s,%s FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)",
+
        z1, z2, pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2
    );
-
    if( zStmt==0 ){
+
    if( zStmt==0 || z1==0 || z2==0 ){
      rc = SQLITE_NOMEM;
    }else{
      sqlite3_stmt *pStmt;
@@ -216174,12 +219558,15 @@ static int sessionDiffFindModified(
        pDiffCtx->pStmt = pStmt;
        pDiffCtx->nOldOff = pTab->nCol;
        while( SQLITE_ROW==sqlite3_step(pStmt) ){
-
          sessionPreupdateOneChange(SQLITE_UPDATE, pSession, pTab);
+
          i64 iRowid = (pTab->bRowid ? sqlite3_column_int64(pStmt, 0) : 0);
+
          sessionPreupdateOneChange(SQLITE_UPDATE, iRowid, pSession, pTab);
        }
        rc = sqlite3_finalize(pStmt);
      }
-
      sqlite3_free(zStmt);
    }
+
    sqlite3_free(zStmt);
+
    sqlite3_free(z1);
+
    sqlite3_free(z2);
  }

  return rc;
@@ -216218,9 +219605,12 @@ SQLITE_API int sqlite3session_diff(
      int bHasPk = 0;
      int bMismatch = 0;
      int nCol;                   /* Columns in zFrom.zTbl */
+
      int bRowid = 0;
      u8 *abPK;
      const char **azCol = 0;
-
      rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK);
+
      rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK,
+
          pSession->bImplicitPK ? &bRowid : 0
+
      );
      if( rc==SQLITE_OK ){
        if( pTo->nCol!=nCol ){
          bMismatch = 1;
@@ -216562,9 +219952,10 @@ static void sessionAppendStr(
  int *pRc
){
  int nStr = sqlite3Strlen30(zStr);
-
  if( 0==sessionBufferGrow(p, nStr, pRc) ){
+
  if( 0==sessionBufferGrow(p, nStr+1, pRc) ){
    memcpy(&p->aBuf[p->nBuf], zStr, nStr);
    p->nBuf += nStr;
+
    p->aBuf[p->nBuf] = 0x00;
  }
}

@@ -216586,6 +219977,27 @@ static void sessionAppendInteger(
  sessionAppendStr(p, aBuf, pRc);
}

+
static void sessionAppendPrintf(
+
  SessionBuffer *p,               /* Buffer to append to */
+
  int *pRc,
+
  const char *zFmt,
+
  ...
+
){
+
  if( *pRc==SQLITE_OK ){
+
    char *zApp = 0;
+
    va_list ap;
+
    va_start(ap, zFmt);
+
    zApp = sqlite3_vmprintf(zFmt, ap);
+
    if( zApp==0 ){
+
      *pRc = SQLITE_NOMEM;
+
    }else{
+
      sessionAppendStr(p, zApp, pRc);
+
    }
+
    va_end(ap);
+
    sqlite3_free(zApp);
+
  }
+
}
+

/*
** This function is a no-op if *pRc is other than SQLITE_OK when it is
** called. Otherwise, append the string zStr enclosed in quotes (") and
@@ -216600,7 +220012,7 @@ static void sessionAppendIdent(
  const char *zStr,               /* String to quote, escape and append */
  int *pRc                        /* IN/OUT: Error code */
){
-
  int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1;
+
  int nStr = sqlite3Strlen30(zStr)*2 + 2 + 2;
  if( 0==sessionBufferGrow(p, nStr, pRc) ){
    char *zOut = (char *)&p->aBuf[p->nBuf];
    const char *zIn = zStr;
@@ -216611,6 +220023,7 @@ static void sessionAppendIdent(
    }
    *zOut++ = '"';
    p->nBuf = (int)((u8 *)zOut - p->aBuf);
+
    p->aBuf[p->nBuf] = 0x00;
  }
}

@@ -216746,7 +220159,7 @@ static int sessionAppendUpdate(
    /* If at least one field has been modified, this is not a no-op. */
    if( bChanged ) bNoop = 0;

-
    /* Add a field to the old.* record. This is omitted if this modules is
+
    /* Add a field to the old.* record. This is omitted if this module is
    ** currently generating a patchset. */
    if( bPatchset==0 ){
      if( bChanged || abPK[i] ){
@@ -216835,12 +220248,20 @@ static int sessionAppendDelete(
** Formulate and prepare a SELECT statement to retrieve a row from table
** zTab in database zDb based on its primary key. i.e.
**
-
**   SELECT * FROM zDb.zTab WHERE pk1 = ? AND pk2 = ? AND ...
+
**   SELECT *, <noop-test> FROM zDb.zTab WHERE (pk1, pk2,...) IS (?1, ?2,...)
+
**
+
** where <noop-test> is:
+
**
+
**   1 AND (?A OR ?1 IS <column>) AND ...
+
**
+
** for each non-pk <column>.
*/
static int sessionSelectStmt(
  sqlite3 *db,                    /* Database handle */
+
  int bIgnoreNoop,
  const char *zDb,                /* Database name */
  const char *zTab,               /* Table name */
+
  int bRowid,
  int nCol,                       /* Number of columns in table */
  const char **azCol,             /* Names of table columns */
  u8 *abPK,                       /* PRIMARY KEY  array */
@@ -216848,8 +220269,50 @@ static int sessionSelectStmt(
){
  int rc = SQLITE_OK;
  char *zSql = 0;
+
  const char *zSep = "";
+
  const char *zCols = bRowid ? SESSIONS_ROWID ", *" : "*";
  int nSql = -1;
+
  int i;

+
  SessionBuffer nooptest = {0, 0, 0};
+
  SessionBuffer pkfield = {0, 0, 0};
+
  SessionBuffer pkvar = {0, 0, 0};
+

+
  sessionAppendStr(&nooptest, ", 1", &rc);
+

+
  if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
+
    sessionAppendStr(&nooptest, " AND (?6 OR ?3 IS stat)", &rc);
+
    sessionAppendStr(&pkfield, "tbl, idx", &rc);
+
    sessionAppendStr(&pkvar,
+
        "?1, (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", &rc
+
    );
+
    zCols = "tbl, ?2, stat";
+
  }else{
+
    for(i=0; i<nCol; i++){
+
      if( abPK[i] ){
+
        sessionAppendStr(&pkfield, zSep, &rc);
+
        sessionAppendStr(&pkvar, zSep, &rc);
+
        zSep = ", ";
+
        sessionAppendIdent(&pkfield, azCol[i], &rc);
+
        sessionAppendPrintf(&pkvar, &rc, "?%d", i+1);
+
      }else{
+
        sessionAppendPrintf(&nooptest, &rc,
+
            " AND (?%d OR ?%d IS %w.%w)", i+1+nCol, i+1, zTab, azCol[i]
+
        );
+
      }
+
    }
+
  }
+

+
  if( rc==SQLITE_OK ){
+
    zSql = sqlite3_mprintf(
+
        "SELECT %s%s FROM %Q.%Q WHERE (%s) IS (%s)",
+
        zCols, (bIgnoreNoop ? (char*)nooptest.aBuf : ""),
+
        zDb, zTab, (char*)pkfield.aBuf, (char*)pkvar.aBuf
+
    );
+
    if( zSql==0 ) rc = SQLITE_NOMEM;
+
  }
+

+
#if 0
  if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
    zSql = sqlite3_mprintf(
        "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
@@ -216857,7 +220320,6 @@ static int sessionSelectStmt(
    );
    if( zSql==0 ) rc = SQLITE_NOMEM;
  }else{
-
    int i;
    const char *zSep = "";
    SessionBuffer buf = {0, 0, 0};

@@ -216878,11 +220340,15 @@ static int sessionSelectStmt(
    zSql = (char*)buf.aBuf;
    nSql = buf.nBuf;
  }
+
#endif

  if( rc==SQLITE_OK ){
    rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
  }
  sqlite3_free(zSql);
+
  sqlite3_free(nooptest.aBuf);
+
  sqlite3_free(pkfield.aBuf);
+
  sqlite3_free(pkvar.aBuf);
  return rc;
}

@@ -217029,10 +220495,18 @@ static int sessionGenerateChangeset(
      sqlite3_stmt *pSel = 0;     /* SELECT statement to query table pTab */
      int nRewind = buf.nBuf;     /* Initial size of write buffer */
      int nNoop;                  /* Size of buffer after writing tbl header */
+
      int bRowid = 0;

      /* Check the table schema is still Ok. */
-
      rc = sessionTableInfo(0, db, pSession->zDb, zName, &nCol, 0,&azCol,&abPK);
-
      if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){
+
      rc = sessionTableInfo(
+
          0, db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK,
+
          (pSession->bImplicitPK ? &bRowid : 0)
+
      );
+
      if( rc==SQLITE_OK && (
+
          pTab->nCol!=nCol
+
       || pTab->bRowid!=bRowid
+
       || memcmp(abPK, pTab->abPK, nCol)
+
      )){
        rc = SQLITE_SCHEMA;
      }

@@ -217042,7 +220516,8 @@ static int sessionGenerateChangeset(
      /* Build and compile a statement to execute: */
      if( rc==SQLITE_OK ){
        rc = sessionSelectStmt(
-
            db, pSession->zDb, zName, nCol, azCol, abPK, &pSel);
+
            db, 0, pSession->zDb, zName, bRowid, nCol, azCol, abPK, &pSel
+
        );
      }

      nNoop = buf.nBuf;
@@ -217125,7 +220600,7 @@ SQLITE_API int sqlite3session_changeset(
  int rc;

  if( pnChangeset==0 || ppChangeset==0 ) return SQLITE_MISUSE;
-
  rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset);
+
  rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset, ppChangeset);
  assert( rc || pnChangeset==0
       || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize
  );
@@ -217243,6 +220718,19 @@ SQLITE_API int sqlite3session_object_config(sqlite3_session *pSession, int op, v
      break;
    }

+
    case SQLITE_SESSION_OBJCONFIG_ROWID: {
+
      int iArg = *(int*)pArg;
+
      if( iArg>=0 ){
+
        if( pSession->pTable ){
+
          rc = SQLITE_MISUSE;
+
        }else{
+
          pSession->bImplicitPK = (iArg!=0);
+
        }
+
      }
+
      *(int*)pArg = pSession->bImplicitPK;
+
      break;
+
    }
+

    default:
      rc = SQLITE_MISUSE;
  }
@@ -217778,6 +221266,22 @@ static int sessionChangesetNextOne(
      if( p->op==SQLITE_INSERT ) p->op = SQLITE_DELETE;
      else if( p->op==SQLITE_DELETE ) p->op = SQLITE_INSERT;
    }
+

+
    /* If this is an UPDATE that is part of a changeset, then check that
+
    ** there are no fields in the old.* record that are not (a) PK fields,
+
    ** or (b) also present in the new.* record.
+
    **
+
    ** Such records are technically corrupt, but the rebaser was at one
+
    ** point generating them. Under most circumstances this is benign, but
+
    ** can cause spurious SQLITE_RANGE errors when applying the changeset. */
+
    if( p->bPatchset==0 && p->op==SQLITE_UPDATE){
+
      for(i=0; i<p->nCol; i++){
+
        if( p->abPK[i]==0 && p->apValue[i+p->nCol]==0 ){
+
          sqlite3ValueFree(p->apValue[i]);
+
          p->apValue[i] = 0;
+
        }
+
      }
+
    }
  }

  return SQLITE_ROW;
@@ -218215,6 +221719,8 @@ struct SessionApplyCtx {
  SessionBuffer rebase;           /* Rebase information (if any) here */
  u8 bRebaseStarted;              /* If table header is already in rebase */
  u8 bRebase;                     /* True to collect rebase information */
+
  u8 bIgnoreNoop;                 /* True to ignore no-op conflicts */
+
  int bRowid;
};

/* Number of prepared UPDATE statements to cache. */
@@ -218465,8 +221971,10 @@ static int sessionSelectRow(
  const char *zTab,               /* Table name */
  SessionApplyCtx *p              /* Session changeset-apply context */
){
-
  return sessionSelectStmt(
-
      db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect);
+
  /* TODO */
+
  return sessionSelectStmt(db, p->bIgnoreNoop,
+
      "main", zTab, p->bRowid, p->nCol, p->azCol, p->abPK, &p->pSelect
+
  );
}

/*
@@ -218624,22 +222132,34 @@ static int sessionBindRow(
** UPDATE, bind values from the old.* record.
*/
static int sessionSeekToRow(
-
  sqlite3 *db,                    /* Database handle */
  sqlite3_changeset_iter *pIter,  /* Changeset iterator */
-
  u8 *abPK,                       /* Primary key flags array */
-
  sqlite3_stmt *pSelect           /* SELECT statement from sessionSelectRow() */
+
  SessionApplyCtx *p
){
+
  sqlite3_stmt *pSelect = p->pSelect;
  int rc;                         /* Return code */
  int nCol;                       /* Number of columns in table */
  int op;                         /* Changset operation (SQLITE_UPDATE etc.) */
  const char *zDummy;             /* Unused */

+
  sqlite3_clear_bindings(pSelect);
  sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0);
  rc = sessionBindRow(pIter,
      op==SQLITE_INSERT ? sqlite3changeset_new : sqlite3changeset_old,
-
      nCol, abPK, pSelect
+
      nCol, p->abPK, pSelect
  );

+
  if( op!=SQLITE_DELETE && p->bIgnoreNoop ){
+
    int ii;
+
    for(ii=0; rc==SQLITE_OK && ii<nCol; ii++){
+
      if( p->abPK[ii]==0 ){
+
        sqlite3_value *pVal = 0;
+
        sqlite3changeset_new(pIter, ii, &pVal);
+
        sqlite3_bind_int(pSelect, ii+1+nCol, (pVal==0));
+
        if( pVal ) rc = sessionBindValue(pSelect, ii+1, pVal);
+
      }
+
    }
+
  }
+

  if( rc==SQLITE_OK ){
    rc = sqlite3_step(pSelect);
    if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect);
@@ -218754,16 +222274,22 @@ static int sessionConflictHandler(

  /* Bind the new.* PRIMARY KEY values to the SELECT statement. */
  if( pbReplace ){
-
    rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
+
    rc = sessionSeekToRow(pIter, p);
  }else{
    rc = SQLITE_OK;
  }

  if( rc==SQLITE_ROW ){
    /* There exists another row with the new.* primary key. */
-
    pIter->pConflict = p->pSelect;
-
    res = xConflict(pCtx, eType, pIter);
-
    pIter->pConflict = 0;
+
    if( p->bIgnoreNoop
+
     && sqlite3_column_int(p->pSelect, sqlite3_column_count(p->pSelect)-1)
+
    ){
+
      res = SQLITE_CHANGESET_OMIT;
+
    }else{
+
      pIter->pConflict = p->pSelect;
+
      res = xConflict(pCtx, eType, pIter);
+
      pIter->pConflict = 0;
+
    }
    rc = sqlite3_reset(p->pSelect);
  }else if( rc==SQLITE_OK ){
    if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){
@@ -218871,7 +222397,7 @@ static int sessionApplyOneOp(

    sqlite3_step(p->pDelete);
    rc = sqlite3_reset(p->pDelete);
-
    if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){
+
    if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 && p->bIgnoreNoop==0 ){
      rc = sessionConflictHandler(
          SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry
      );
@@ -218928,7 +222454,7 @@ static int sessionApplyOneOp(
      /* Check if there is a conflicting row. For sqlite_stat1, this needs
      ** to be done using a SELECT, as there is no PRIMARY KEY in the
      ** database schema to throw an exception if a duplicate is inserted.  */
-
      rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
+
      rc = sessionSeekToRow(pIter, p);
      if( rc==SQLITE_ROW ){
        rc = SQLITE_CONSTRAINT;
        sqlite3_reset(p->pSelect);
@@ -219105,6 +222631,7 @@ static int sessionChangesetApply(
  memset(&sApply, 0, sizeof(sApply));
  sApply.bRebase = (ppRebase && pnRebase);
  sApply.bInvertConstraints = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
+
  sApply.bIgnoreNoop = !!(flags & SQLITE_CHANGESETAPPLY_IGNORENOOP);
  sqlite3_mutex_enter(sqlite3_db_mutex(db));
  if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
    rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0);
@@ -219142,6 +222669,7 @@ static int sessionChangesetApply(
      sApply.bStat1 = 0;
      sApply.bDeferConstraints = 1;
      sApply.bRebaseStarted = 0;
+
      sApply.bRowid = 0;
      memset(&sApply.constraints, 0, sizeof(SessionBuffer));

      /* If an xFilter() callback was specified, invoke it now. If the
@@ -219161,8 +222689,8 @@ static int sessionChangesetApply(
        int i;

        sqlite3changeset_pk(pIter, &abPK, 0);
-
        rc = sessionTableInfo(0,
-
            db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK
+
        rc = sessionTableInfo(0, db, "main", zNew,
+
            &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK, &sApply.bRowid
        );
        if( rc!=SQLITE_OK ) break;
        for(i=0; i<sApply.nCol; i++){
@@ -219974,7 +223502,7 @@ static void sessionAppendPartialUpdate(
        if( !pIter->abPK[i] && a1[0] ) bData = 1;
        memcpy(pOut, a1, n1);
        pOut += n1;
-
      }else if( a2[0]!=0xFF ){
+
      }else if( a2[0]!=0xFF && a1[0] ){
        bData = 1;
        memcpy(pOut, a2, n2);
        pOut += n2;
@@ -221044,6 +224572,7 @@ struct Fts5Config {
  int ePattern;                   /* FTS_PATTERN_XXX constant */

  /* Values loaded from the %_config table */
+
  int iVersion;                   /* fts5 file format 'version' */
  int iCookie;                    /* Incremented when %_config is modified */
  int pgsz;                       /* Approximate page size used in %_data */
  int nAutomerge;                 /* 'automerge' setting */
@@ -221052,6 +224581,7 @@ struct Fts5Config {
  int nHashSize;                  /* Bytes of memory for in-memory hash */
  char *zRank;                    /* Name of rank function */
  char *zRankArgs;                /* Arguments to rank function */
+
  int bSecureDelete;              /* 'secure-delete' */

  /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */
  char **pzErrmsg;
@@ -221061,8 +224591,11 @@ struct Fts5Config {
#endif
};

-
/* Current expected value of %_config table 'version' field */
-
#define FTS5_CURRENT_VERSION  4
+
/* Current expected value of %_config table 'version' field. And
+
** the expected version if the 'secure-delete' option has ever been
+
** set on the table.  */
+
#define FTS5_CURRENT_VERSION               4
+
#define FTS5_CURRENT_VERSION_SECUREDELETE  5

#define FTS5_CONTENT_NORMAL   0
#define FTS5_CONTENT_NONE     1
@@ -221228,6 +224761,7 @@ struct Fts5IndexIter {
** above. */
#define FTS5INDEX_QUERY_SKIPEMPTY  0x0010
#define FTS5INDEX_QUERY_NOOUTPUT   0x0020
+
#define FTS5INDEX_QUERY_SKIPHASH   0x0040

/*
** Create/destroy an Fts5Index object.
@@ -221382,7 +224916,7 @@ static int sqlite3Fts5GetVarintLen(u32 iVal);
static u8 sqlite3Fts5GetVarint(const unsigned char*, u64*);
static int sqlite3Fts5PutVarint(unsigned char *p, u64 v);

-
#define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&b)
+
#define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&(b))
#define fts5GetVarint    sqlite3Fts5GetVarint

#define fts5FastGetVarint32(a, iOff, nVal) {      \
@@ -223361,7 +226895,7 @@ static int fts5HighlightCb(
  if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK;
  iPos = p->iPos++;

-
  if( p->iRangeEnd>0 ){
+
  if( p->iRangeEnd>=0 ){
    if( iPos<p->iRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK;
    if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff;
  }
@@ -223373,7 +226907,7 @@ static int fts5HighlightCb(
  }

  if( iPos==p->iter.iEnd ){
-
    if( p->iRangeEnd && p->iter.iStart<p->iRangeStart ){
+
    if( p->iRangeEnd>=0 && p->iter.iStart<p->iRangeStart ){
      fts5HighlightAppend(&rc, p, p->zOpen, -1);
    }
    fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
@@ -223384,7 +226918,7 @@ static int fts5HighlightCb(
    }
  }

-
  if( p->iRangeEnd>0 && iPos==p->iRangeEnd ){
+
  if( p->iRangeEnd>=0 && iPos==p->iRangeEnd ){
    fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff);
    p->iOff = iEndOff;
    if( iPos>=p->iter.iStart && iPos<p->iter.iEnd ){
@@ -223419,6 +226953,7 @@ static void fts5HighlightFunction(
  memset(&ctx, 0, sizeof(HighlightContext));
  ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
  ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
+
  ctx.iRangeEnd = -1;
  rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn);

  if( ctx.zIn ){
@@ -223604,6 +227139,7 @@ static void fts5SnippetFunction(
  iCol = sqlite3_value_int(apVal[0]);
  ctx.zOpen = fts5ValueToText(apVal[1]);
  ctx.zClose = fts5ValueToText(apVal[2]);
+
  ctx.iRangeEnd = -1;
  zEllips = fts5ValueToText(apVal[3]);
  nToken = sqlite3_value_int(apVal[4]);

@@ -224872,6 +228408,7 @@ static int sqlite3Fts5ConfigParse(
    rc = SQLITE_ERROR;
  }

+
  assert( (pRet->abUnindexed && pRet->azCol) || rc!=SQLITE_OK );
  for(i=3; rc==SQLITE_OK && i<nArg; i++){
    const char *zOrig = azArg[i];
    const char *z;
@@ -225225,6 +228762,18 @@ static int sqlite3Fts5ConfigSetValue(
      rc = SQLITE_OK;
      *pbBadkey = 1;
    }
+
  }
+

+
  else if( 0==sqlite3_stricmp(zKey, "secure-delete") ){
+
    int bVal = -1;
+
    if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){
+
      bVal = sqlite3_value_int(pVal);
+
    }
+
    if( bVal<0 ){
+
      *pbBadkey = 1;
+
    }else{
+
      pConfig->bSecureDelete = (bVal ? 1 : 0);
+
    }
  }else{
    *pbBadkey = 1;
  }
@@ -225269,15 +228818,20 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
    rc = sqlite3_finalize(p);
  }

-
  if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){
+
  if( rc==SQLITE_OK
+
   && iVersion!=FTS5_CURRENT_VERSION
+
   && iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE
+
  ){
    rc = SQLITE_ERROR;
    if( pConfig->pzErrmsg ){
      assert( 0==*pConfig->pzErrmsg );
-
      *pConfig->pzErrmsg = sqlite3_mprintf(
-
          "invalid fts5 file format (found %d, expected %d) - run 'rebuild'",
-
          iVersion, FTS5_CURRENT_VERSION
+
      *pConfig->pzErrmsg = sqlite3_mprintf("invalid fts5 file format "
+
          "(found %d, expected %d or %d) - run 'rebuild'",
+
          iVersion, FTS5_CURRENT_VERSION, FTS5_CURRENT_VERSION_SECUREDELETE
      );
    }
+
  }else{
+
    pConfig->iVersion = iVersion;
  }

  if( rc==SQLITE_OK ){
@@ -225305,6 +228859,10 @@ static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){
/* #include "fts5Int.h" */
/* #include "fts5parse.h" */

+
#ifndef SQLITE_FTS5_MAX_EXPR_DEPTH
+
# define SQLITE_FTS5_MAX_EXPR_DEPTH 256
+
#endif
+

/*
** All token types in the generated fts5parse.h file are greater than 0.
*/
@@ -225345,11 +228903,17 @@ struct Fts5Expr {
**       FTS5_NOT                 (nChild, apChild valid)
**       FTS5_STRING              (pNear valid)
**       FTS5_TERM                (pNear valid)
+
**
+
** iHeight:
+
**   Distance from this node to furthest leaf. This is always 0 for nodes
+
**   of type FTS5_STRING and FTS5_TERM. For all other nodes it is one
+
**   greater than the largest child value.
*/
struct Fts5ExprNode {
  int eType;                      /* Node type */
  int bEof;                       /* True at EOF */
  int bNomatch;                   /* True if entry is not a match */
+
  int iHeight;                    /* Distance to tree leaf nodes */

  /* Next method for this node. */
  int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64);
@@ -225419,6 +228983,31 @@ struct Fts5Parse {
  int bPhraseToAnd;               /* Convert "a+b" to "a AND b" */
};

+
/*
+
** Check that the Fts5ExprNode.iHeight variables are set correctly in
+
** the expression tree passed as the only argument.
+
*/
+
#ifndef NDEBUG
+
static void assert_expr_depth_ok(int rc, Fts5ExprNode *p){
+
  if( rc==SQLITE_OK ){
+
    if( p->eType==FTS5_TERM || p->eType==FTS5_STRING || p->eType==0 ){
+
      assert( p->iHeight==0 );
+
    }else{
+
      int ii;
+
      int iMaxChild = 0;
+
      for(ii=0; ii<p->nChild; ii++){
+
        Fts5ExprNode *pChild = p->apChild[ii];
+
        iMaxChild = MAX(iMaxChild, pChild->iHeight);
+
        assert_expr_depth_ok(SQLITE_OK, pChild);
+
      }
+
      assert( p->iHeight==iMaxChild+1 );
+
    }
+
  }
+
}
+
#else
+
# define assert_expr_depth_ok(rc, p)
+
#endif
+

static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){
  va_list ap;
  va_start(ap, zFmt);
@@ -225533,6 +229122,8 @@ static int sqlite3Fts5ExprNew(
  }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF );
  sqlite3Fts5ParserFree(pEngine, fts5ParseFree);

+
  assert_expr_depth_ok(sParse.rc, sParse.pExpr);
+

  /* If the LHS of the MATCH expression was a user column, apply the
  ** implicit column-filter.  */
  if( iCol<pConfig->nCol && sParse.pExpr && sParse.rc==SQLITE_OK ){
@@ -225578,6 +229169,19 @@ static int sqlite3Fts5ExprNew(
}

/*
+
** Assuming that buffer z is at least nByte bytes in size and contains a
+
** valid utf-8 string, return the number of characters in the string.
+
*/
+
static int fts5ExprCountChar(const char *z, int nByte){
+
  int nRet = 0;
+
  int ii;
+
  for(ii=0; ii<nByte; ii++){
+
    if( (z[ii] & 0xC0)!=0x80 ) nRet++;
+
  }
+
  return nRet;
+
}
+

+
/*
** This function is only called when using the special 'trigram' tokenizer.
** Argument zText contains the text of a LIKE or GLOB pattern matched
** against column iCol. This function creates and compiles an FTS5 MATCH
@@ -225614,7 +229218,8 @@ static int sqlite3Fts5ExprPattern(
      if( i==nText
       || zText[i]==aSpec[0] || zText[i]==aSpec[1] || zText[i]==aSpec[2]
      ){
-
        if( i-iFirst>=3 ){
+

+
        if( fts5ExprCountChar(&zText[iFirst], i-iFirst)>=3 ){
          int jj;
          zExpr[iOut++] = '"';
          for(jj=iFirst; jj<i; jj++){
@@ -225681,7 +229286,7 @@ static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
  Fts5Parse sParse;
  memset(&sParse, 0, sizeof(sParse));

-
  if( *pp1 ){
+
  if( *pp1 && p2 ){
    Fts5Expr *p1 = *pp1;
    int nPhrase = p1->nPhrase + p2->nPhrase;

@@ -225706,7 +229311,7 @@ static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){
    }
    sqlite3_free(p2->apExprPhrase);
    sqlite3_free(p2);
-
  }else{
+
  }else if( p2 ){
    *pp1 = p2;
  }

@@ -227480,6 +231085,7 @@ static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
}

static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
+
  int ii = p->nChild;
  if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){
    int nByte = sizeof(Fts5ExprNode*) * pSub->nChild;
    memcpy(&p->apChild[p->nChild], pSub->apChild, nByte);
@@ -227488,6 +231094,9 @@ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){
  }else{
    p->apChild[p->nChild++] = pSub;
  }
+
  for( ; ii<p->nChild; ii++){
+
    p->iHeight = MAX(p->iHeight, p->apChild[ii]->iHeight + 1);
+
  }
}

/*
@@ -227518,6 +231127,7 @@ static Fts5ExprNode *fts5ParsePhraseToAnd(
  if( pRet ){
    pRet->eType = FTS5_AND;
    pRet->nChild = nTerm;
+
    pRet->iHeight = 1;
    fts5ExprAssignXNext(pRet);
    pParse->nPhrase--;
    for(ii=0; ii<nTerm; ii++){
@@ -227623,6 +231233,14 @@ static Fts5ExprNode *sqlite3Fts5ParseNode(
        }else{
          fts5ExprAddChildren(pRet, pLeft);
          fts5ExprAddChildren(pRet, pRight);
+
          if( pRet->iHeight>SQLITE_FTS5_MAX_EXPR_DEPTH ){
+
            sqlite3Fts5ParseError(pParse,
+
                "fts5 expression tree is too large (maximum depth %d)",
+
                SQLITE_FTS5_MAX_EXPR_DEPTH
+
            );
+
            sqlite3_free(pRet);
+
            pRet = 0;
+
          }
        }
      }
    }
@@ -228975,6 +232593,8 @@ static void sqlite3Fts5HashScanEntry(
# error "FTS5_MAX_PREFIX_INDEXES is too large"
#endif

+
#define FTS5_MAX_LEVEL 64
+

/*
** Details:
**
@@ -229221,6 +232841,8 @@ struct Fts5Index {
  sqlite3_stmt *pIdxSelect;
  int nRead;                      /* Total number of blocks read */

+
  sqlite3_stmt *pDeleteFromIdx;
+

  sqlite3_stmt *pDataVersion;
  i64 iStructVersion;             /* data_version when pStruct read */
  Fts5Structure *pStruct;         /* Current db structure (or NULL) */
@@ -229313,9 +232935,6 @@ struct Fts5CResult {
** iLeafOffset:
**   Byte offset within the current leaf that is the first byte of the
**   position list data (one byte passed the position-list size field).
-
**   rowid field of the current entry. Usually this is the size field of the
-
**   position list data. The exception is if the rowid for the current entry
-
**   is the last thing on the leaf page.
**
** pLeaf:
**   Buffer containing current leaf page data. Set to NULL at EOF.
@@ -229874,6 +233493,7 @@ static int fts5StructureDecode(
            rc = FTS5_CORRUPT;
            break;
          }
+
          assert( pSeg!=0 );
          i += fts5GetVarint32(&pData[i], pSeg->iSegid);
          i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst);
          i += fts5GetVarint32(&pData[i], pSeg->pgnoLast);
@@ -229904,6 +233524,7 @@ static int fts5StructureDecode(
*/
static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
  fts5StructureMakeWritable(pRc, ppStruct);
+
  assert( (ppStruct!=0 && (*ppStruct)!=0) || (*pRc)!=SQLITE_OK );
  if( *pRc==SQLITE_OK ){
    Fts5Structure *pStruct = *ppStruct;
    int nLevel = pStruct->nLevel;
@@ -230362,42 +233983,25 @@ static int fts5DlidxLvlPrev(Fts5DlidxLvl *pLvl){
    pLvl->bEof = 1;
  }else{
    u8 *a = pLvl->pData->p;
-
    i64 iVal;
-
    int iLimit;
-
    int ii;
-
    int nZero = 0;
-

-
    /* Currently iOff points to the first byte of a varint. This block
-
    ** decrements iOff until it points to the first byte of the previous
-
    ** varint. Taking care not to read any memory locations that occur
-
    ** before the buffer in memory.  */
-
    iLimit = (iOff>9 ? iOff-9 : 0);
-
    for(iOff--; iOff>iLimit; iOff--){
-
      if( (a[iOff-1] & 0x80)==0 ) break;
-
    }
-

-
    fts5GetVarint(&a[iOff], (u64*)&iVal);
-
    pLvl->iRowid -= iVal;
-
    pLvl->iLeafPgno--;
-

-
    /* Skip backwards past any 0x00 varints. */
-
    for(ii=iOff-1; ii>=pLvl->iFirstOff && a[ii]==0x00; ii--){
-
      nZero++;
-
    }
-
    if( ii>=pLvl->iFirstOff && (a[ii] & 0x80) ){
-
      /* The byte immediately before the last 0x00 byte has the 0x80 bit
-
      ** set. So the last 0x00 is only a varint 0 if there are 8 more 0x80
-
      ** bytes before a[ii]. */
-
      int bZero = 0;              /* True if last 0x00 counts */
-
      if( (ii-8)>=pLvl->iFirstOff ){
-
        int j;
-
        for(j=1; j<=8 && (a[ii-j] & 0x80); j++);
-
        bZero = (j>8);
+

+
    pLvl->iOff = 0;
+
    fts5DlidxLvlNext(pLvl);
+
    while( 1 ){
+
      int nZero = 0;
+
      int ii = pLvl->iOff;
+
      u64 delta = 0;
+

+
      while( a[ii]==0 ){
+
        nZero++;
+
        ii++;
      }
-
      if( bZero==0 ) nZero--;
+
      ii += sqlite3Fts5GetVarint(&a[ii], &delta);
+

+
      if( ii>=iOff ) break;
+
      pLvl->iLeafPgno += nZero+1;
+
      pLvl->iRowid += delta;
+
      pLvl->iOff = ii;
    }
-
    pLvl->iLeafPgno -= nZero;
-
    pLvl->iOff = iOff - nZero;
  }

  return pLvl->bEof;
@@ -230593,7 +234197,7 @@ static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
  i64 iOff = pIter->iLeafOffset;

  ASSERT_SZLEAF_OK(pIter->pLeaf);
-
  if( iOff>=pIter->pLeaf->szLeaf ){
+
  while( iOff>=pIter->pLeaf->szLeaf ){
    fts5SegIterNextPage(p, pIter);
    if( pIter->pLeaf==0 ){
      if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT;
@@ -230692,10 +234296,12 @@ static void fts5SegIterInit(
    fts5SegIterSetNext(p, pIter);
    pIter->pSeg = pSeg;
    pIter->iLeafPgno = pSeg->pgnoFirst-1;
-
    fts5SegIterNextPage(p, pIter);
+
    do {
+
      fts5SegIterNextPage(p, pIter);
+
    }while( p->rc==SQLITE_OK && pIter->pLeaf && pIter->pLeaf->nn==4 );
  }

-
  if( p->rc==SQLITE_OK ){
+
  if( p->rc==SQLITE_OK && pIter->pLeaf ){
    pIter->iLeafOffset = 4;
    assert( pIter->pLeaf!=0 );
    assert_nc( pIter->pLeaf->nn>4 );
@@ -230889,7 +234495,7 @@ static void fts5SegIterNext_None(
  iOff = pIter->iLeafOffset;

  /* Next entry is on the next page */
-
  if( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){
+
  while( pIter->pSeg && iOff>=pIter->pLeaf->szLeaf ){
    fts5SegIterNextPage(p, pIter);
    if( p->rc || pIter->pLeaf==0 ) return;
    pIter->iRowid = 0;
@@ -231082,7 +234688,7 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){
  Fts5Data *pLast = 0;
  int pgnoLast = 0;

-
  if( pDlidx ){
+
  if( pDlidx && p->pConfig->iVersion==FTS5_CURRENT_VERSION ){
    int iSegid = pIter->pSeg->iSegid;
    pgnoLast = fts5DlidxIterPgno(pDlidx);
    pLast = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast));
@@ -231643,7 +235249,8 @@ static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){

/*
** Move the seg-iter so that it points to the first rowid on page iLeafPgno.
-
** It is an error if leaf iLeafPgno does not exist or contains no rowids.
+
** It is an error if leaf iLeafPgno does not exist. Unless the db is
+
** a 'secure-delete' db, if it contains no rowids then this is also an error.
*/
static void fts5SegIterGotoPage(
  Fts5Index *p,                   /* FTS5 backend object */
@@ -231658,21 +235265,23 @@ static void fts5SegIterGotoPage(
    fts5DataRelease(pIter->pNextLeaf);
    pIter->pNextLeaf = 0;
    pIter->iLeafPgno = iLeafPgno-1;
-
    fts5SegIterNextPage(p, pIter);
-
    assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno );

-
    if( p->rc==SQLITE_OK && ALWAYS(pIter->pLeaf!=0) ){
+
    while( p->rc==SQLITE_OK ){
      int iOff;
-
      u8 *a = pIter->pLeaf->p;
-
      int n = pIter->pLeaf->szLeaf;
-

+
      fts5SegIterNextPage(p, pIter);
+
      if( pIter->pLeaf==0 ) break;
      iOff = fts5LeafFirstRowidOff(pIter->pLeaf);
-
      if( iOff<4 || iOff>=n ){
-
        p->rc = FTS5_CORRUPT;
-
      }else{
-
        iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
-
        pIter->iLeafOffset = iOff;
-
        fts5SegIterLoadNPos(p, pIter);
+
      if( iOff>0 ){
+
        u8 *a = pIter->pLeaf->p;
+
        int n = pIter->pLeaf->szLeaf;
+
        if( iOff<4 || iOff>=n ){
+
          p->rc = FTS5_CORRUPT;
+
        }else{
+
          iOff += fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid);
+
          pIter->iLeafOffset = iOff;
+
          fts5SegIterLoadNPos(p, pIter);
+
        }
+
        break;
      }
    }
  }
@@ -232387,7 +235996,7 @@ static void fts5MultiIterNew(
    if( iLevel<0 ){
      assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
      nSeg = pStruct->nSegment;
-
      nSeg += (p->pHash ? 1 : 0);
+
      nSeg += (p->pHash && 0==(flags & FTS5INDEX_QUERY_SKIPHASH));
    }else{
      nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment);
    }
@@ -232408,7 +236017,7 @@ static void fts5MultiIterNew(
  if( p->rc==SQLITE_OK ){
    if( iLevel<0 ){
      Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel];
-
      if( p->pHash ){
+
      if( p->pHash && 0==(flags & FTS5INDEX_QUERY_SKIPHASH) ){
        /* Add a segment iterator for the current contents of the hash table. */
        Fts5SegIter *pIter = &pNew->aSeg[iIter++];
        fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter);
@@ -233163,7 +236772,7 @@ static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
          fts5BufferAppendBlob(&p->rc, &buf, sizeof(aHdr), aHdr);
          fts5BufferAppendVarint(&p->rc, &buf, pSeg->term.n);
          fts5BufferAppendBlob(&p->rc, &buf, pSeg->term.n, pSeg->term.p);
-
          fts5BufferAppendBlob(&p->rc, &buf, pData->szLeaf-iOff,&pData->p[iOff]);
+
          fts5BufferAppendBlob(&p->rc, &buf,pData->szLeaf-iOff,&pData->p[iOff]);
          if( p->rc==SQLITE_OK ){
            /* Set the szLeaf field */
            fts5PutU16(&buf.p[2], (u16)buf.n);
@@ -233441,16 +237050,16 @@ static void fts5IndexCrisismerge(
){
  const int nCrisis = p->pConfig->nCrisisMerge;
  Fts5Structure *pStruct = *ppStruct;
-
  int iLvl = 0;
-

-
  assert( p->rc!=SQLITE_OK || pStruct->nLevel>0 );
-
  while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){
-
    fts5IndexMergeLevel(p, &pStruct, iLvl, 0);
-
    assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) );
-
    fts5StructurePromote(p, iLvl+1, pStruct);
-
    iLvl++;
+
  if( pStruct && pStruct->nLevel>0 ){
+
    int iLvl = 0;
+
    while( p->rc==SQLITE_OK && pStruct->aLevel[iLvl].nSeg>=nCrisis ){
+
      fts5IndexMergeLevel(p, &pStruct, iLvl, 0);
+
      assert( p->rc!=SQLITE_OK || pStruct->nLevel>(iLvl+1) );
+
      fts5StructurePromote(p, iLvl+1, pStruct);
+
      iLvl++;
+
    }
+
    *ppStruct = pStruct;
  }
-
  *ppStruct = pStruct;
}

static int fts5IndexReturn(Fts5Index *p){
@@ -233485,6 +237094,413 @@ static int fts5PoslistPrefix(const u8 *aBuf, int nMax){
}

/*
+
** Execute the SQL statement:
+
**
+
**    DELETE FROM %_idx WHERE (segid, (pgno/2)) = ($iSegid, $iPgno);
+
**
+
** This is used when a secure-delete operation removes the last term
+
** from a segment leaf page. In that case the %_idx entry is removed
+
** too. This is done to ensure that if all instances of a token are
+
** removed from an fts5 database in secure-delete mode, no trace of
+
** the token itself remains in the database.
+
*/
+
static void fts5SecureDeleteIdxEntry(
+
  Fts5Index *p,                   /* FTS5 backend object */
+
  int iSegid,                     /* Id of segment to delete entry for */
+
  int iPgno                       /* Page number within segment */
+
){
+
  if( iPgno!=1 ){
+
    assert( p->pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE );
+
    if( p->pDeleteFromIdx==0 ){
+
      fts5IndexPrepareStmt(p, &p->pDeleteFromIdx, sqlite3_mprintf(
+
          "DELETE FROM '%q'.'%q_idx' WHERE (segid, (pgno/2)) = (?1, ?2)",
+
          p->pConfig->zDb, p->pConfig->zName
+
      ));
+
    }
+
    if( p->rc==SQLITE_OK ){
+
      sqlite3_bind_int(p->pDeleteFromIdx, 1, iSegid);
+
      sqlite3_bind_int(p->pDeleteFromIdx, 2, iPgno);
+
      sqlite3_step(p->pDeleteFromIdx);
+
      p->rc = sqlite3_reset(p->pDeleteFromIdx);
+
    }
+
  }
+
}
+

+
/*
+
** This is called when a secure-delete operation removes a position-list
+
** that overflows onto segment page iPgno of segment pSeg. This function
+
** rewrites node iPgno, and possibly one or more of its right-hand peers,
+
** to remove this portion of the position list.
+
**
+
** Output variable (*pbLastInDoclist) is set to true if the position-list
+
** removed is followed by a new term or the end-of-segment, or false if
+
** it is followed by another rowid/position list.
+
*/
+
static void fts5SecureDeleteOverflow(
+
  Fts5Index *p,
+
  Fts5StructureSegment *pSeg,
+
  int iPgno,
+
  int *pbLastInDoclist
+
){
+
  const int bDetailNone = (p->pConfig->eDetail==FTS5_DETAIL_NONE);
+
  int pgno;
+
  Fts5Data *pLeaf = 0;
+
  assert( iPgno!=1 );
+

+
  *pbLastInDoclist = 1;
+
  for(pgno=iPgno; p->rc==SQLITE_OK && pgno<=pSeg->pgnoLast; pgno++){
+
    i64 iRowid = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno);
+
    int iNext = 0;
+
    u8 *aPg = 0;
+

+
    pLeaf = fts5DataRead(p, iRowid);
+
    if( pLeaf==0 ) break;
+
    aPg = pLeaf->p;
+

+
    iNext = fts5GetU16(&aPg[0]);
+
    if( iNext!=0 ){
+
      *pbLastInDoclist = 0;
+
    }
+
    if( iNext==0 && pLeaf->szLeaf!=pLeaf->nn ){
+
      fts5GetVarint32(&aPg[pLeaf->szLeaf], iNext);
+
    }
+

+
    if( iNext==0 ){
+
      /* The page contains no terms or rowids. Replace it with an empty
+
      ** page and move on to the right-hand peer.  */
+
      const u8 aEmpty[] = {0x00, 0x00, 0x00, 0x04};
+
      assert_nc( bDetailNone==0 || pLeaf->nn==4 );
+
      if( bDetailNone==0 ) fts5DataWrite(p, iRowid, aEmpty, sizeof(aEmpty));
+
      fts5DataRelease(pLeaf);
+
      pLeaf = 0;
+
    }else if( bDetailNone ){
+
      break;
+
    }else if( iNext>=pLeaf->szLeaf || iNext<4 ){
+
      p->rc = FTS5_CORRUPT;
+
      break;
+
    }else{
+
      int nShift = iNext - 4;
+
      int nPg;
+

+
      int nIdx = 0;
+
      u8 *aIdx = 0;
+

+
      /* Unless the current page footer is 0 bytes in size (in which case
+
      ** the new page footer will be as well), allocate and populate a
+
      ** buffer containing the new page footer. Set stack variables aIdx
+
      ** and nIdx accordingly.  */
+
      if( pLeaf->nn>pLeaf->szLeaf ){
+
        int iFirst = 0;
+
        int i1 = pLeaf->szLeaf;
+
        int i2 = 0;
+

+
        aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2);
+
        if( aIdx==0 ) break;
+
        i1 += fts5GetVarint32(&aPg[i1], iFirst);
+
        i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift);
+
        if( i1<pLeaf->nn ){
+
          memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1);
+
          i2 += (pLeaf->nn-i1);
+
        }
+
        nIdx = i2;
+
      }
+

+
      /* Modify the contents of buffer aPg[]. Set nPg to the new size
+
      ** in bytes. The new page is always smaller than the old.  */
+
      nPg = pLeaf->szLeaf - nShift;
+
      memmove(&aPg[4], &aPg[4+nShift], nPg-4);
+
      fts5PutU16(&aPg[2], nPg);
+
      if( fts5GetU16(&aPg[0]) ) fts5PutU16(&aPg[0], 4);
+
      if( nIdx>0 ){
+
        memcpy(&aPg[nPg], aIdx, nIdx);
+
        nPg += nIdx;
+
      }
+
      sqlite3_free(aIdx);
+

+
      /* Write the new page to disk and exit the loop */
+
      assert( nPg>4 || fts5GetU16(aPg)==0 );
+
      fts5DataWrite(p, iRowid, aPg, nPg);
+
      break;
+
    }
+
  }
+
  fts5DataRelease(pLeaf);
+
}
+

+
/*
+
** Completely remove the entry that pSeg currently points to from
+
** the database.
+
*/
+
static void fts5DoSecureDelete(
+
  Fts5Index *p,
+
  Fts5SegIter *pSeg
+
){
+
  const int bDetailNone = (p->pConfig->eDetail==FTS5_DETAIL_NONE);
+
  int iSegid = pSeg->pSeg->iSegid;
+
  u8 *aPg = pSeg->pLeaf->p;
+
  int nPg = pSeg->pLeaf->nn;
+
  int iPgIdx = pSeg->pLeaf->szLeaf;
+

+
  u64 iDelta = 0;
+
  u64 iNextDelta = 0;
+
  int iNextOff = 0;
+
  int iOff = 0;
+
  int nIdx = 0;
+
  u8 *aIdx = 0;
+
  int bLastInDoclist = 0;
+
  int iIdx = 0;
+
  int iStart = 0;
+
  int iKeyOff = 0;
+
  int iPrevKeyOff = 0;
+
  int iDelKeyOff = 0;       /* Offset of deleted key, if any */
+

+
  nIdx = nPg-iPgIdx;
+
  aIdx = sqlite3Fts5MallocZero(&p->rc, nIdx+16);
+
  if( p->rc ) return;
+
  memcpy(aIdx, &aPg[iPgIdx], nIdx);
+

+
  /* At this point segment iterator pSeg points to the entry
+
  ** this function should remove from the b-tree segment.
+
  **
+
  ** In detail=full or detail=column mode, pSeg->iLeafOffset is the
+
  ** offset of the first byte in the position-list for the entry to
+
  ** remove. Immediately before this comes two varints that will also
+
  ** need to be removed:
+
  **
+
  **     + the rowid or delta rowid value for the entry, and
+
  **     + the size of the position list in bytes.
+
  **
+
  ** Or, in detail=none mode, there is a single varint prior to
+
  ** pSeg->iLeafOffset - the rowid or delta rowid value.
+
  **
+
  ** This block sets the following variables:
+
  **
+
  **   iStart:
+
  **   iDelta:
+
  */
+
  {
+
    int iSOP;
+
    if( pSeg->iLeafPgno==pSeg->iTermLeafPgno ){
+
      iStart = pSeg->iTermLeafOffset;
+
    }else{
+
      iStart = fts5GetU16(&aPg[0]);
+
    }
+

+
    iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta);
+
    assert_nc( iSOP<=pSeg->iLeafOffset );
+

+
    if( bDetailNone ){
+
      while( iSOP<pSeg->iLeafOffset ){
+
        if( aPg[iSOP]==0x00 ) iSOP++;
+
        if( aPg[iSOP]==0x00 ) iSOP++;
+
        iStart = iSOP;
+
        iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta);
+
      }
+

+
      iNextOff = iSOP;
+
      if( iNextOff<pSeg->iEndofDoclist && aPg[iNextOff]==0x00 ) iNextOff++;
+
      if( iNextOff<pSeg->iEndofDoclist && aPg[iNextOff]==0x00 ) iNextOff++;
+

+
    }else{
+
      int nPos = 0;
+
      iSOP += fts5GetVarint32(&aPg[iSOP], nPos);
+
      while( iSOP<pSeg->iLeafOffset ){
+
        iStart = iSOP + (nPos/2);
+
        iSOP = iStart + fts5GetVarint(&aPg[iStart], &iDelta);
+
        iSOP += fts5GetVarint32(&aPg[iSOP], nPos);
+
      }
+
      assert_nc( iSOP==pSeg->iLeafOffset );
+
      iNextOff = pSeg->iLeafOffset + pSeg->nPos;
+
    }
+
  }
+

+
  iOff = iStart;
+
  if( iNextOff>=iPgIdx ){
+
    int pgno = pSeg->iLeafPgno+1;
+
    fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist);
+
    iNextOff = iPgIdx;
+
  }else{
+
    /* Set bLastInDoclist to true if the entry being removed is the last
+
    ** in its doclist.  */
+
    for(iIdx=0, iKeyOff=0; iIdx<nIdx; /* no-op */){
+
      u32 iVal = 0;
+
      iIdx += fts5GetVarint32(&aIdx[iIdx], iVal);
+
      iKeyOff += iVal;
+
      if( iKeyOff==iNextOff ){
+
        bLastInDoclist = 1;
+
      }
+
    }
+
  }
+

+
  if( fts5GetU16(&aPg[0])==iStart && (bLastInDoclist||iNextOff==iPgIdx) ){
+
    fts5PutU16(&aPg[0], 0);
+
  }
+

+
  if( bLastInDoclist==0 ){
+
    if( iNextOff!=iPgIdx ){
+
      iNextOff += fts5GetVarint(&aPg[iNextOff], &iNextDelta);
+
      iOff += sqlite3Fts5PutVarint(&aPg[iOff], iDelta + iNextDelta);
+
    }
+
  }else if(
+
      iStart==pSeg->iTermLeafOffset && pSeg->iLeafPgno==pSeg->iTermLeafPgno
+
  ){
+
    /* The entry being removed was the only position list in its
+
    ** doclist. Therefore the term needs to be removed as well. */
+
    int iKey = 0;
+
    for(iIdx=0, iKeyOff=0; iIdx<nIdx; iKey++){
+
      u32 iVal = 0;
+
      iIdx += fts5GetVarint32(&aIdx[iIdx], iVal);
+
      if( (iKeyOff+iVal)>(u32)iStart ) break;
+
      iKeyOff += iVal;
+
    }
+

+
    iDelKeyOff = iOff = iKeyOff;
+
    if( iNextOff!=iPgIdx ){
+
      int nPrefix = 0;
+
      int nSuffix = 0;
+
      int nPrefix2 = 0;
+
      int nSuffix2 = 0;
+

+
      iDelKeyOff = iNextOff;
+
      iNextOff += fts5GetVarint32(&aPg[iNextOff], nPrefix2);
+
      iNextOff += fts5GetVarint32(&aPg[iNextOff], nSuffix2);
+

+
      if( iKey!=1 ){
+
        iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nPrefix);
+
      }
+
      iKeyOff += fts5GetVarint32(&aPg[iKeyOff], nSuffix);
+

+
      nPrefix = MIN(nPrefix, nPrefix2);
+
      nSuffix = (nPrefix2 + nSuffix2) - nPrefix;
+

+
      if( (iKeyOff+nSuffix)>iPgIdx || (iNextOff+nSuffix2)>iPgIdx ){
+
        p->rc = FTS5_CORRUPT;
+
      }else{
+
        if( iKey!=1 ){
+
          iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix);
+
        }
+
        iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix);
+
        if( nPrefix2>nPrefix ){
+
          memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix);
+
          iOff += (nPrefix2-nPrefix);
+
        }
+
        memmove(&aPg[iOff], &aPg[iNextOff], nSuffix2);
+
        iOff += nSuffix2;
+
        iNextOff += nSuffix2;
+
      }
+
    }
+
  }else if( iStart==4 ){
+
      int iPgno;
+

+
      assert_nc( pSeg->iLeafPgno>pSeg->iTermLeafPgno );
+
      /* The entry being removed may be the only position list in
+
      ** its doclist. */
+
      for(iPgno=pSeg->iLeafPgno-1; iPgno>pSeg->iTermLeafPgno; iPgno-- ){
+
        Fts5Data *pPg = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno));
+
        int bEmpty = (pPg && pPg->nn==4);
+
        fts5DataRelease(pPg);
+
        if( bEmpty==0 ) break;
+
      }
+

+
      if( iPgno==pSeg->iTermLeafPgno ){
+
        i64 iId = FTS5_SEGMENT_ROWID(iSegid, pSeg->iTermLeafPgno);
+
        Fts5Data *pTerm = fts5DataRead(p, iId);
+
        if( pTerm && pTerm->szLeaf==pSeg->iTermLeafOffset ){
+
          u8 *aTermIdx = &pTerm->p[pTerm->szLeaf];
+
          int nTermIdx = pTerm->nn - pTerm->szLeaf;
+
          int iTermIdx = 0;
+
          int iTermOff = 0;
+

+
          while( 1 ){
+
            u32 iVal = 0;
+
            int nByte = fts5GetVarint32(&aTermIdx[iTermIdx], iVal);
+
            iTermOff += iVal;
+
            if( (iTermIdx+nByte)>=nTermIdx ) break;
+
            iTermIdx += nByte;
+
          }
+
          nTermIdx = iTermIdx;
+

+
          memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx);
+
          fts5PutU16(&pTerm->p[2], iTermOff);
+

+
          fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx);
+
          if( nTermIdx==0 ){
+
            fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno);
+
          }
+
        }
+
        fts5DataRelease(pTerm);
+
      }
+
    }
+

+
    if( p->rc==SQLITE_OK ){
+
      const int nMove = nPg - iNextOff;
+
      int nShift = 0;
+

+
      memmove(&aPg[iOff], &aPg[iNextOff], nMove);
+
      iPgIdx -= (iNextOff - iOff);
+
      nPg = iPgIdx;
+
      fts5PutU16(&aPg[2], iPgIdx);
+

+
      nShift = iNextOff - iOff;
+
      for(iIdx=0, iKeyOff=0, iPrevKeyOff=0; iIdx<nIdx; /* no-op */){
+
        u32 iVal = 0;
+
        iIdx += fts5GetVarint32(&aIdx[iIdx], iVal);
+
        iKeyOff += iVal;
+
        if( iKeyOff!=iDelKeyOff ){
+
          if( iKeyOff>iOff ){
+
            iKeyOff -= nShift;
+
            nShift = 0;
+
          }
+
          nPg += sqlite3Fts5PutVarint(&aPg[nPg], iKeyOff - iPrevKeyOff);
+
          iPrevKeyOff = iKeyOff;
+
        }
+
      }
+

+
      if( iPgIdx==nPg && nIdx>0 && pSeg->iLeafPgno!=1 ){
+
        fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iLeafPgno);
+
      }
+

+
      assert_nc( nPg>4 || fts5GetU16(aPg)==0 );
+
      fts5DataWrite(p, FTS5_SEGMENT_ROWID(iSegid,pSeg->iLeafPgno), aPg,nPg);
+
    }
+
    sqlite3_free(aIdx);
+
}
+

+
/*
+
** This is called as part of flushing a delete to disk in 'secure-delete'
+
** mode. It edits the segments within the database described by argument
+
** pStruct to remove the entries for term zTerm, rowid iRowid.
+
*/
+
static void fts5FlushSecureDelete(
+
  Fts5Index *p,
+
  Fts5Structure *pStruct,
+
  const char *zTerm,
+
  i64 iRowid
+
){
+
  const int f = FTS5INDEX_QUERY_SKIPHASH;
+
  int nTerm = (int)strlen(zTerm);
+
  Fts5Iter *pIter = 0;            /* Used to find term instance */
+

+
  fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter);
+
  if( fts5MultiIterEof(p, pIter)==0 ){
+
    i64 iThis = fts5MultiIterRowid(pIter);
+
    if( iThis<iRowid ){
+
      fts5MultiIterNextFrom(p, pIter, iRowid);
+
    }
+

+
    if( p->rc==SQLITE_OK
+
     && fts5MultiIterEof(p, pIter)==0
+
     && iRowid==fts5MultiIterRowid(pIter)
+
    ){
+
      Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
+
      fts5DoSecureDelete(p, pSeg);
+
    }
+
  }
+

+
  fts5MultiIterFree(pIter);
+
}
+

+

+
/*
** Flush the contents of in-memory hash table iHash to a new level-0
** segment on disk. Also update the corresponding structure record.
**
@@ -233506,6 +237522,7 @@ static void fts5FlushOneHash(Fts5Index *p){
  if( iSegid ){
    const int pgsz = p->pConfig->pgsz;
    int eDetail = p->pConfig->eDetail;
+
    int bSecureDelete = p->pConfig->bSecureDelete;
    Fts5StructureSegment *pSeg;   /* New segment within pStruct */
    Fts5Buffer *pBuf;             /* Buffer in which to assemble leaf page */
    Fts5Buffer *pPgidx;           /* Buffer in which to assemble pgidx */
@@ -233528,40 +237545,77 @@ static void fts5FlushOneHash(Fts5Index *p){
    }
    while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){
      const char *zTerm;          /* Buffer containing term */
+
      int nTerm;                  /* Size of zTerm in bytes */
      const u8 *pDoclist;         /* Pointer to doclist for this term */
      int nDoclist;               /* Size of doclist in bytes */

-
      /* Write the term for this entry to disk. */
+
      /* Get the term and doclist for this entry. */
      sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist);
-
      fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm);
-
      if( p->rc!=SQLITE_OK ) break;
+
      nTerm = (int)strlen(zTerm);
+
      if( bSecureDelete==0 ){
+
        fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
+
        if( p->rc!=SQLITE_OK ) break;
+
        assert( writer.bFirstRowidInPage==0 );
+
      }

-
      assert( writer.bFirstRowidInPage==0 );
-
      if( pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
+
      if( !bSecureDelete && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){
        /* The entire doclist will fit on the current leaf. */
        fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist);
      }else{
+
        int bTermWritten = !bSecureDelete;
        i64 iRowid = 0;
-
        u64 iDelta = 0;
+
        i64 iPrev = 0;
        int iOff = 0;

        /* The entire doclist will not fit on this leaf. The following
        ** loop iterates through the poslists that make up the current
        ** doclist.  */
        while( p->rc==SQLITE_OK && iOff<nDoclist ){
+
          u64 iDelta = 0;
          iOff += fts5GetVarint(&pDoclist[iOff], &iDelta);
          iRowid += iDelta;

+
          /* If in secure delete mode, and if this entry in the poslist is
+
          ** in fact a delete, then edit the existing segments directly
+
          ** using fts5FlushSecureDelete().  */
+
          if( bSecureDelete ){
+
            if( eDetail==FTS5_DETAIL_NONE ){
+
              if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
+
                fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
+
                iOff++;
+
                if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
+
                  iOff++;
+
                  nDoclist = 0;
+
                }else{
+
                  continue;
+
                }
+
              }
+
            }else if( (pDoclist[iOff] & 0x01) ){
+
              fts5FlushSecureDelete(p, pStruct, zTerm, iRowid);
+
              if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){
+
                iOff++;
+
                continue;
+
              }
+
            }
+
          }
+

+
          if( p->rc==SQLITE_OK && bTermWritten==0 ){
+
            fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm);
+
            bTermWritten = 1;
+
            assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 );
+
          }
+

          if( writer.bFirstRowidInPage ){
            fts5PutU16(&pBuf->p[0], (u16)pBuf->n);   /* first rowid on page */
            pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid);
            writer.bFirstRowidInPage = 0;
            fts5WriteDlidxAppend(p, &writer, iRowid);
-
            if( p->rc!=SQLITE_OK ) break;
          }else{
-
            pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta);
+
            pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid-iPrev);
          }
+
          if( p->rc!=SQLITE_OK ) break;
          assert( pBuf->n<=pBuf->nSpace );
+
          iPrev = iRowid;

          if( eDetail==FTS5_DETAIL_NONE ){
            if( iOff<nDoclist && pDoclist[iOff]==0 ){
@@ -233620,20 +237674,23 @@ static void fts5FlushOneHash(Fts5Index *p){
    sqlite3Fts5HashClear(pHash);
    fts5WriteFinish(p, &writer, &pgnoLast);

-
    /* Update the Fts5Structure. It is written back to the database by the
-
    ** fts5StructureRelease() call below.  */
-
    if( pStruct->nLevel==0 ){
-
      fts5StructureAddLevel(&p->rc, &pStruct);
-
    }
-
    fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0);
-
    if( p->rc==SQLITE_OK ){
-
      pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ];
-
      pSeg->iSegid = iSegid;
-
      pSeg->pgnoFirst = 1;
-
      pSeg->pgnoLast = pgnoLast;
-
      pStruct->nSegment++;
+
    assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 );
+
    if( pgnoLast>0 ){
+
      /* Update the Fts5Structure. It is written back to the database by the
+
      ** fts5StructureRelease() call below.  */
+
      if( pStruct->nLevel==0 ){
+
        fts5StructureAddLevel(&p->rc, &pStruct);
+
      }
+
      fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0);
+
      if( p->rc==SQLITE_OK ){
+
        pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ];
+
        pSeg->iSegid = iSegid;
+
        pSeg->pgnoFirst = 1;
+
        pSeg->pgnoLast = pgnoLast;
+
        pStruct->nSegment++;
+
      }
+
      fts5StructurePromote(p, 0, pStruct);
    }
-
    fts5StructurePromote(p, 0, pStruct);
  }

  fts5IndexAutomerge(p, &pStruct, pgnoLast);
@@ -233689,10 +237746,10 @@ static Fts5Structure *fts5IndexOptimizeStruct(
  if( pNew ){
    Fts5StructureLevel *pLvl;
    nByte = nSeg * sizeof(Fts5StructureSegment);
-
    pNew->nLevel = pStruct->nLevel+1;
+
    pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL);
    pNew->nRef = 1;
    pNew->nWriteCounter = pStruct->nWriteCounter;
-
    pLvl = &pNew->aLevel[pStruct->nLevel];
+
    pLvl = &pNew->aLevel[pNew->nLevel-1];
    pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte);
    if( pLvl->aSeg ){
      int iLvl, iSeg;
@@ -233994,7 +238051,7 @@ static void fts5MergePrefixLists(
  /* Initialize a doclist-iterator for each input buffer. Arrange them in
  ** a linked-list starting at pHead in ascending order of rowid. Avoid
  ** linking any iterators already at EOF into the linked list at all. */
-
  assert( nBuf+1<=sizeof(aMerger)/sizeof(aMerger[0]) );
+
  assert( nBuf+1<=(int)(sizeof(aMerger)/sizeof(aMerger[0])) );
  memset(aMerger, 0, sizeof(PrefixMerger)*(nBuf+1));
  pHead = &aMerger[nBuf];
  fts5DoclistIterInit(p1, &pHead->iter);
@@ -234374,6 +238431,7 @@ static int sqlite3Fts5IndexClose(Fts5Index *p){
    sqlite3_finalize(p->pIdxDeleter);
    sqlite3_finalize(p->pIdxSelect);
    sqlite3_finalize(p->pDataVersion);
+
    sqlite3_finalize(p->pDeleteFromIdx);
    sqlite3Fts5HashFree(p->pHash);
    sqlite3_free(p->zDataTbl);
    sqlite3_free(p);
@@ -235004,6 +239062,7 @@ static void fts5IndexIntegrityCheckSegment(
  Fts5StructureSegment *pSeg      /* Segment to check internal consistency */
){
  Fts5Config *pConfig = p->pConfig;
+
  int bSecureDelete = (pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE);
  sqlite3_stmt *pStmt = 0;
  int rc2;
  int iIdxPrevLeaf = pSeg->pgnoFirst-1;
@@ -235039,7 +239098,19 @@ static void fts5IndexIntegrityCheckSegment(
    ** is also a rowid pointer within the leaf page header, it points to a
    ** location before the term.  */
    if( pLeaf->nn<=pLeaf->szLeaf ){
-
      p->rc = FTS5_CORRUPT;
+

+
      if( nIdxTerm==0
+
       && pConfig->iVersion==FTS5_CURRENT_VERSION_SECUREDELETE
+
       && pLeaf->nn==pLeaf->szLeaf
+
       && pLeaf->nn==4
+
      ){
+
        /* special case - the very first page in a segment keeps its %_idx
+
        ** entry even if all the terms are removed from it by secure-delete
+
        ** operations. */
+
      }else{
+
        p->rc = FTS5_CORRUPT;
+
      }
+

    }else{
      int iOff;                   /* Offset of first term on leaf */
      int iRowidOff;              /* Offset of first rowid on leaf */
@@ -235103,9 +239174,12 @@ static void fts5IndexIntegrityCheckSegment(
          ASSERT_SZLEAF_OK(pLeaf);
          if( iRowidOff>=pLeaf->szLeaf ){
            p->rc = FTS5_CORRUPT;
-
          }else{
+
          }else if( bSecureDelete==0 || iRowidOff>0 ){
+
            i64 iDlRowid = fts5DlidxIterRowid(pDlidx);
            fts5GetVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid);
-
            if( iRowid!=fts5DlidxIterRowid(pDlidx) ) p->rc = FTS5_CORRUPT;
+
            if( iRowid<iDlRowid || (bSecureDelete==0 && iRowid!=iDlRowid) ){
+
              p->rc = FTS5_CORRUPT;
+
            }
          }
          fts5DataRelease(pLeaf);
        }
@@ -236004,7 +240078,7 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){
      break;

    case FTS5_SYNC:
-
      assert( p->ts.eState==1 );
+
      assert( p->ts.eState==1 || p->ts.eState==2 );
      p->ts.eState = 2;
      break;

@@ -236019,21 +240093,21 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){
      break;

    case FTS5_SAVEPOINT:
-
      assert( p->ts.eState==1 );
+
      assert( p->ts.eState>=1 );
      assert( iSavepoint>=0 );
      assert( iSavepoint>=p->ts.iSavepoint );
      p->ts.iSavepoint = iSavepoint;
      break;

    case FTS5_RELEASE:
-
      assert( p->ts.eState==1 );
+
      assert( p->ts.eState>=1 );
      assert( iSavepoint>=0 );
      assert( iSavepoint<=p->ts.iSavepoint );
      p->ts.iSavepoint = iSavepoint-1;
      break;

    case FTS5_ROLLBACKTO:
-
      assert( p->ts.eState==1 );
+
      assert( p->ts.eState>=1 );
      assert( iSavepoint>=-1 );
      /* The following assert() can fail if another vtab strikes an error
      ** within an xSavepoint() call then SQLite calls xRollbackTo() - without
@@ -237367,9 +241441,11 @@ static int fts5UpdateMethod(
  Fts5Config *pConfig = pTab->p.pConfig;
  int eType0;                     /* value_type() of apVal[0] */
  int rc = SQLITE_OK;             /* Return code */
+
  int bUpdateOrDelete = 0;
+


  /* A transaction must be open when this is called. */
-
  assert( pTab->ts.eState==1 );
+
  assert( pTab->ts.eState==1 || pTab->ts.eState==2 );

  assert( pVtab->zErrMsg==0 );
  assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
@@ -237377,6 +241453,11 @@ static int fts5UpdateMethod(
       || sqlite3_value_type(apVal[0])==SQLITE_NULL
  );
  assert( pTab->p.pConfig->pzErrmsg==0 );
+
  if( pConfig->pgsz==0 ){
+
    rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
+
    if( rc!=SQLITE_OK ) return rc;
+
  }
+

  pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;

  /* Put any active cursors into REQUIRE_SEEK state. */
@@ -237429,6 +241510,7 @@ static int fts5UpdateMethod(
    else if( nArg==1 ){
      i64 iDel = sqlite3_value_int64(apVal[0]);  /* Rowid to delete */
      rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0);
+
      bUpdateOrDelete = 1;
    }

    /* INSERT or UPDATE */
@@ -237444,6 +241526,7 @@ static int fts5UpdateMethod(
        if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
          i64 iNew = sqlite3_value_int64(apVal[1]);  /* Rowid to delete */
          rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0);
+
          bUpdateOrDelete = 1;
        }
        fts5StorageInsert(&rc, pTab, apVal, pRowid);
      }
@@ -237472,10 +241555,24 @@ static int fts5UpdateMethod(
          rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0);
          fts5StorageInsert(&rc, pTab, apVal, pRowid);
        }
+
        bUpdateOrDelete = 1;
      }
    }
  }

+
  if( rc==SQLITE_OK
+
   && bUpdateOrDelete
+
   && pConfig->bSecureDelete
+
   && pConfig->iVersion==FTS5_CURRENT_VERSION
+
  ){
+
    rc = sqlite3Fts5StorageConfigValue(
+
        pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE
+
    );
+
    if( rc==SQLITE_OK ){
+
      pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE;
+
    }
+
  }
+

  pTab->p.pConfig->pzErrmsg = 0;
  return rc;
}
@@ -238335,6 +242432,7 @@ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
  UNUSED_PARAM(iSavepoint);  /* Call below is a no-op for NDEBUG builds */
  fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
  fts5TripCursors(pTab);
+
  pTab->p.pConfig->pgsz = 0;
  return sqlite3Fts5StorageRollback(pTab->pStorage);
}

@@ -238537,7 +242635,7 @@ static void fts5SourceIdFunc(
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
-
  sqlite3_result_text(pCtx, "fts5: 2022-11-16 12:10:08 89c459e766ea7e9165d0beeb124708b955a4950d0f4792f457465d71b158d318", -1, SQLITE_TRANSIENT);
+
  sqlite3_result_text(pCtx, "fts5: 2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0", -1, SQLITE_TRANSIENT);
}

/*
@@ -238610,7 +242708,9 @@ static int fts5Init(sqlite3 *db){
    }
    if( rc==SQLITE_OK ){
      rc = sqlite3_create_function(
-
          db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0
+
          db, "fts5_source_id", 0,
+
          SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
+
          p, fts5SourceIdFunc, 0, 0
      );
    }
  }
@@ -243275,6 +247375,10 @@ static int stmtConnect(
#define STMT_COLUMN_MEM    10   /* SQLITE_STMTSTATUS_MEMUSED */


+
  (void)pAux;
+
  (void)argc;
+
  (void)argv;
+
  (void)pzErr;
  rc = sqlite3_declare_vtab(db,
     "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep,"
                    "reprep,run,mem)");
@@ -243394,6 +247498,10 @@ static int stmtFilter(
  sqlite3_int64 iRowid = 1;
  StmtRow **ppRow = 0;

+
  (void)idxNum;
+
  (void)idxStr;
+
  (void)argc;
+
  (void)argv;
  stmtCsrReset(pCur);
  ppRow = &pCur->pRow;
  for(p=sqlite3_next_stmt(pCur->db, 0); p; p=sqlite3_next_stmt(pCur->db, p)){
@@ -243449,6 +247557,7 @@ static int stmtBestIndex(
  sqlite3_vtab *tab,
  sqlite3_index_info *pIdxInfo
){
+
  (void)tab;
  pIdxInfo->estimatedCost = (double)500;
  pIdxInfo->estimatedRows = 500;
  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.41.0"
-
#define SQLITE_VERSION_NUMBER 3041000
-
#define SQLITE_SOURCE_ID      "2023-02-21 18:09:37 05941c2a04037fc3ed2ffae11f5d2260706f89431f463518740f72ada350866d"
+
#define SQLITE_VERSION        "3.42.0"
+
#define SQLITE_VERSION_NUMBER 3042000
+
#define SQLITE_SOURCE_ID      "2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0"

/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -1655,20 +1655,23 @@ SQLITE_API int sqlite3_os_end(void);
** must ensure that no other SQLite interfaces are invoked by other
** threads while sqlite3_config() is running.</b>
**
-
** The sqlite3_config() interface
-
** may only be invoked prior to library initialization using
-
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
-
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
-
** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
-
** Note, however, that ^sqlite3_config() can be called as part of the
-
** implementation of an application-defined [sqlite3_os_init()].
-
**
** The first argument to sqlite3_config() is an integer
** [configuration option] that determines
** what property of SQLite is to be configured.  Subsequent arguments
** vary depending on the [configuration option]
** in the first argument.
**
+
** For most configuration options, the sqlite3_config() interface
+
** may only be invoked prior to library initialization using
+
** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
+
** The exceptional configuration options that may be invoked at any time
+
** are called "anytime configuration options".
+
** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
+
** [sqlite3_shutdown()] with a first argument that is not an anytime
+
** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE.
+
** Note, however, that ^sqlite3_config() can be called as part of the
+
** implementation of an application-defined [sqlite3_os_init()].
+
**
** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
** ^If the option is unknown or SQLite is unable to set the option
** then this routine returns a non-zero [error code].
@@ -1776,6 +1779,23 @@ struct sqlite3_mem_methods {
** These constants are the available integer configuration options that
** can be passed as the first argument to the [sqlite3_config()] interface.
**
+
** Most of the configuration options for sqlite3_config()
+
** will only work if invoked prior to [sqlite3_initialize()] or after
+
** [sqlite3_shutdown()].  The few exceptions to this rule are called
+
** "anytime configuration options".
+
** ^Calling [sqlite3_config()] with a first argument that is not an
+
** anytime configuration option in between calls to [sqlite3_initialize()] and
+
** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE.
+
**
+
** The set of anytime configuration options can change (by insertions
+
** and/or deletions) from one release of SQLite to the next.
+
** As of SQLite version 3.42.0, the complete set of anytime configuration
+
** options is:
+
** <ul>
+
** <li> SQLITE_CONFIG_LOG
+
** <li> SQLITE_CONFIG_PCACHE_HDRSZ
+
** </ul>
+
**
** New configuration options may be added in future releases of SQLite.
** Existing configuration options might be discontinued.  Applications
** should check the return code from [sqlite3_config()] to make sure that
@@ -2122,28 +2142,28 @@ struct sqlite3_mem_methods {
** compile-time option is not set, then the default maximum is 1073741824.
** </dl>
*/
-
#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
-
#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
-
#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
-
#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
-
#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
-
#define SQLITE_CONFIG_SCRATCH       6  /* No longer used */
-
#define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */
-
#define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
-
#define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
-
#define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
-
#define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
-
/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
-
#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
-
#define SQLITE_CONFIG_PCACHE       14  /* no-op */
-
#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
-
#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
-
#define SQLITE_CONFIG_URI          17  /* int */
-
#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
-
#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
+
#define SQLITE_CONFIG_SINGLETHREAD         1  /* nil */
+
#define SQLITE_CONFIG_MULTITHREAD          2  /* nil */
+
#define SQLITE_CONFIG_SERIALIZED           3  /* nil */
+
#define SQLITE_CONFIG_MALLOC               4  /* sqlite3_mem_methods* */
+
#define SQLITE_CONFIG_GETMALLOC            5  /* sqlite3_mem_methods* */
+
#define SQLITE_CONFIG_SCRATCH              6  /* No longer used */
+
#define SQLITE_CONFIG_PAGECACHE            7  /* void*, int sz, int N */
+
#define SQLITE_CONFIG_HEAP                 8  /* void*, int nByte, int min */
+
#define SQLITE_CONFIG_MEMSTATUS            9  /* boolean */
+
#define SQLITE_CONFIG_MUTEX               10  /* sqlite3_mutex_methods* */
+
#define SQLITE_CONFIG_GETMUTEX            11  /* sqlite3_mutex_methods* */
+
/* previously SQLITE_CONFIG_CHUNKALLOC    12 which is now unused. */
+
#define SQLITE_CONFIG_LOOKASIDE           13  /* int int */
+
#define SQLITE_CONFIG_PCACHE              14  /* no-op */
+
#define SQLITE_CONFIG_GETPCACHE           15  /* no-op */
+
#define SQLITE_CONFIG_LOG                 16  /* xFunc, void* */
+
#define SQLITE_CONFIG_URI                 17  /* int */
+
#define SQLITE_CONFIG_PCACHE2             18  /* sqlite3_pcache_methods2* */
+
#define SQLITE_CONFIG_GETPCACHE2          19  /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
-
#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
-
#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
+
#define SQLITE_CONFIG_SQLLOG              21  /* xSqllog, void* */
+
#define SQLITE_CONFIG_MMAP_SIZE           22  /* sqlite3_int64, sqlite3_int64 */
#define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
#define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
#define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
@@ -2378,7 +2398,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_DBCONFIG_DQS_DML]]
-
** <dt>SQLITE_DBCONFIG_DQS_DML</td>
+
** <dt>SQLITE_DBCONFIG_DQS_DML</dt>
** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates
** the legacy [double-quoted string literal] misfeature for DML statements
** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The
@@ -2387,7 +2407,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_DBCONFIG_DQS_DDL]]
-
** <dt>SQLITE_DBCONFIG_DQS_DDL</td>
+
** <dt>SQLITE_DBCONFIG_DQS_DDL</dt>
** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates
** the legacy [double-quoted string literal] misfeature for DDL statements,
** such as CREATE TABLE and CREATE INDEX. The
@@ -2396,7 +2416,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]]
-
** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td>
+
** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</dt>
** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to
** assume that database schemas are untainted by malicious content.
** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite
@@ -2416,7 +2436,7 @@ struct sqlite3_mem_methods {
** </dd>
**
** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]]
-
** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</td>
+
** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</dt>
** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates
** the legacy file format flag.  When activated, this flag causes all newly
** created database file to have a schema format version number (the 4-byte
@@ -2425,7 +2445,7 @@ struct sqlite3_mem_methods {
** any SQLite version back to 3.0.0 ([dateof:3.0.0]).  Without this setting,
** newly created databases are generally not understandable by SQLite versions
** prior to 3.3.0 ([dateof:3.3.0]).  As these words are written, there
-
** is now scarcely any need to generated database files that are compatible
+
** is now scarcely any need to generate database files that are compatible
** all the way back to version 3.0.0, and so this setting is of little
** practical use, but is provided so that SQLite can continue to claim the
** ability to generate new database files that are compatible with  version
@@ -2436,6 +2456,38 @@ struct sqlite3_mem_methods {
** not considered a bug since SQLite versions 3.3.0 and earlier do not support
** either generated columns or decending indexes.
** </dd>
+
**
+
** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]
+
** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>
+
** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in
+
** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears
+
** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()
+
** statistics. For statistics to be collected, the flag must be set on
+
** the database handle both when the SQL statement is prepared and when it
+
** is stepped. The flag is set (collection of statistics is enabled)
+
** by default.  This option takes two arguments: an integer and a pointer to
+
** an integer..  The first argument is 1, 0, or -1 to enable, disable, or
+
** leave unchanged the statement scanstatus option.  If the second argument
+
** is not NULL, then the value of the statement scanstatus setting after
+
** processing the first argument is written into the integer that the second
+
** argument points to.
+
** </dd>
+
**
+
** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]]
+
** <dt>SQLITE_DBCONFIG_REVERSE_SCANORDER</dt>
+
** <dd>The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order
+
** in which tables and indexes are scanned so that the scans start at the end
+
** and work toward the beginning rather than starting at the beginning and
+
** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the
+
** same as setting [PRAGMA reverse_unordered_selects].  This option takes
+
** two arguments which are an integer and a pointer to an integer.  The first
+
** argument is 1, 0, or -1 to enable, disable, or leave unchanged the
+
** reverse scan order flag, respectively.  If the second argument is not NULL,
+
** then 0 or 1 is written into the integer that the second argument points to
+
** depending on if the reverse scan order flag is set after processing the
+
** first argument.
+
** </dd>
+
**
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
@@ -2456,7 +2508,9 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_ENABLE_VIEW           1015 /* int int* */
#define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT    1016 /* int int* */
#define SQLITE_DBCONFIG_TRUSTED_SCHEMA        1017 /* int int* */
-
#define SQLITE_DBCONFIG_MAX                   1017 /* Largest DBCONFIG */
+
#define SQLITE_DBCONFIG_STMT_SCANSTATUS       1018 /* int int* */
+
#define SQLITE_DBCONFIG_REVERSE_SCANORDER     1019 /* int int* */
+
#define SQLITE_DBCONFIG_MAX                   1019 /* Largest DBCONFIG */

/*
** CAPI3REF: Enable Or Disable Extended Result Codes
@@ -6201,6 +6255,13 @@ SQLITE_API void sqlite3_activate_cerod(
** of the default VFS is not implemented correctly, or not implemented at
** all, then the behavior of sqlite3_sleep() may deviate from the description
** in the previous paragraphs.
+
**
+
** If a negative argument is passed to sqlite3_sleep() the results vary by
+
** VFS and operating system.  Some system treat a negative argument as an
+
** instruction to sleep forever.  Others understand it to mean do not sleep
+
** at all. ^In SQLite version 3.42.0 and later, a negative
+
** argument passed into sqlite3_sleep() is changed to zero before it is relayed
+
** down into the xSleep method of the VFS.
*/
SQLITE_API int sqlite3_sleep(int);

@@ -7828,9 +7889,9 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
** is undefined if the mutex is not currently entered by the
** calling thread or is not currently allocated.
**
-
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
-
** sqlite3_mutex_leave() is a NULL pointer, then all three routines
-
** behave as no-ops.
+
** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(),
+
** sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer,
+
** then any of the four routines behaves as a no-op.
**
** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
*/
@@ -9564,18 +9625,28 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt>
** <dd>Calls of the form
** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the
-
** the [xConnect] or [xCreate] methods of a [virtual table] implmentation
+
** the [xConnect] or [xCreate] methods of a [virtual table] implementation
** identify that virtual table as being safe to use from within triggers
** and views.  Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the
** virtual table can do no serious harm even if it is controlled by a
** malicious hacker.  Developers should avoid setting the SQLITE_VTAB_INNOCUOUS
** flag unless absolutely necessary.
** </dd>
+
**
+
** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]<dt>SQLITE_VTAB_USES_ALL_SCHEMAS</dt>
+
** <dd>Calls of the form
+
** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the
+
** the [xConnect] or [xCreate] methods of a [virtual table] implementation
+
** instruct the query planner to begin at least a read transaction on
+
** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the
+
** virtual table is used.
+
** </dd>
** </dl>
*/
#define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
#define SQLITE_VTAB_INNOCUOUS          2
#define SQLITE_VTAB_DIRECTONLY         3
+
#define SQLITE_VTAB_USES_ALL_SCHEMAS   4

/*
** CAPI3REF: Determine The Virtual Table Conflict Policy
@@ -10750,16 +10821,20 @@ SQLITE_API int sqlite3session_create(
SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);

/*
-
** CAPIREF: Conigure a Session Object
+
** CAPI3REF: Configure a Session Object
** METHOD: sqlite3_session
**
** This method is used to configure a session object after it has been
-
** created. At present the only valid value for the second parameter is
-
** [SQLITE_SESSION_OBJCONFIG_SIZE].
+
** created. At present the only valid values for the second parameter are
+
** [SQLITE_SESSION_OBJCONFIG_SIZE] and [SQLITE_SESSION_OBJCONFIG_ROWID].
**
-
** Arguments for sqlite3session_object_config()
+
*/
+
SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
+

+
/*
+
** CAPI3REF: Options for sqlite3session_object_config
**
-
** The following values may passed as the the 4th parameter to
+
** The following values may passed as the the 2nd parameter to
** sqlite3session_object_config().
**
** <dt>SQLITE_SESSION_OBJCONFIG_SIZE <dd>
@@ -10775,12 +10850,21 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);
**
**   It is an error (SQLITE_MISUSE) to attempt to modify this setting after
**   the first table has been attached to the session object.
+
**
+
** <dt>SQLITE_SESSION_OBJCONFIG_ROWID <dd>
+
**   This option is used to set, clear or query the flag that enables
+
**   collection of data for tables with no explicit PRIMARY KEY.
+
**
+
**   Normally, tables with no explicit PRIMARY KEY are simply ignored
+
**   by the sessions module. However, if this flag is set, it behaves
+
**   as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted
+
**   as their leftmost columns.
+
**
+
**   It is an error (SQLITE_MISUSE) to attempt to modify this setting after
+
**   the first table has been attached to the session object.
*/
-
SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
-

-
/*
-
*/
-
#define SQLITE_SESSION_OBJCONFIG_SIZE 1
+
#define SQLITE_SESSION_OBJCONFIG_SIZE  1
+
#define SQLITE_SESSION_OBJCONFIG_ROWID 2

/*
** CAPI3REF: Enable Or Disable A Session Object
@@ -11913,9 +11997,23 @@ SQLITE_API int sqlite3changeset_apply_v2(
**   Invert the changeset before applying it. This is equivalent to inverting
**   a changeset using sqlite3changeset_invert() before applying it. It is
**   an error to specify this flag with a patchset.
+
**
+
** <dt>SQLITE_CHANGESETAPPLY_IGNORENOOP <dd>
+
**   Do not invoke the conflict handler callback for any changes that
+
**   would not actually modify the database even if they were applied.
+
**   Specifically, this means that the conflict handler is not invoked
+
**   for:
+
**    <ul>
+
**    <li>a delete change if the row being deleted cannot be found,
+
**    <li>an update change if the modified fields are already set to
+
**        their new values in the conflicting row, or
+
**    <li>an insert change if all fields of the conflicting row match
+
**        the row being inserted.
+
**    </ul>
*/
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001
#define SQLITE_CHANGESETAPPLY_INVERT        0x0002
+
#define SQLITE_CHANGESETAPPLY_IGNORENOOP    0x0004

/*
** CAPI3REF: Constants Passed To The Conflict Handler