Merge "Remove sqlite 3.42.0 code" into main
diff --git a/dist/sqlite-autoconf-3420000/Android.patch b/dist/sqlite-autoconf-3420000/Android.patch
deleted file mode 100644
index f38906c..0000000
--- a/dist/sqlite-autoconf-3420000/Android.patch
+++ /dev/null
@@ -1,153 +0,0 @@
---- orig/shell.c	2024-03-14 11:00:02.445940614 -0700
-+++ shell.c	2024-03-14 11:00:02.477940578 -0700
-@@ -127,6 +127,11 @@
- #endif
- #include <ctype.h>
- #include <stdarg.h>
-+// Begin Android Add
-+#ifndef NO_ANDROID_FUNCS
-+#include <sqlite3_android.h>
-+#endif
-+// End Android Add
- 
- #if !defined(_WIN32) && !defined(WIN32)
- # include <signal.h>
-@@ -246,7 +251,9 @@
- #if SQLITE_OS_WINRT
- #include <intrin.h>
- #endif
-+#ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
-+#endif
- #include <windows.h>
- 
- /* string conversion routines only needed on Win32 */
-@@ -20793,6 +20800,21 @@
-                             editFunc, 0, 0);
- #endif
- 
-+// Begin Android Add
-+#ifndef NO_ANDROID_FUNCS
-+    int err = register_localized_collators(p->db, "en_US", 0);
-+    if (err != SQLITE_OK) {
-+      fprintf(stderr, "register_localized_collators() failed\n");
-+      exit(1);
-+    }
-+    err = register_android_functions(p->db, 0);
-+    if (err != SQLITE_OK) {
-+      fprintf(stderr, "register_android_functions() failed\n");
-+      exit(1);
-+    }
-+#endif
-+// End Android Add
-+
-     if( p->openMode==SHELL_OPEN_ZIPFILE ){
-       char *zSql = sqlite3_mprintf(
-          "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", zDbFilename);
---- orig/sqlite3.c	2024-03-14 11:00:02.457940601 -0700
-+++ sqlite3.c	2024-03-14 11:00:02.509940542 -0700
-@@ -37314,6 +37314,10 @@
- # include <sys/mount.h>
- #endif
- 
-+#if defined(__BIONIC__)
-+# include <android/fdsan.h>
-+#endif
-+
- #ifdef HAVE_UTIME
- # include <utime.h>
- #endif
-@@ -37922,6 +37926,12 @@
- #if defined(FD_CLOEXEC) && (!defined(O_CLOEXEC) || O_CLOEXEC==0)
-     osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
- #endif
-+
-+#if defined(__BIONIC__) && __ANDROID_API__ >= __ANDROID_API_Q__
-+    uint64_t tag = android_fdsan_create_owner_tag(
-+        ANDROID_FDSAN_OWNER_TYPE_SQLITE, fd);
-+    android_fdsan_exchange_owner_tag(fd, 0, tag);
-+#endif
-   }
-   return fd;
- }
-@@ -38502,7 +38512,13 @@
- ** and move on.
- */
- static void robust_close(unixFile *pFile, int h, int lineno){
-+#if defined(__BIONIC__) && __ANDROID_API__ >= __ANDROID_API_Q__
-+  uint64_t tag = android_fdsan_create_owner_tag(
-+      ANDROID_FDSAN_OWNER_TYPE_SQLITE, h);
-+  if( android_fdsan_close_with_tag(h, tag) ){
-+#else
-   if( osClose(h) ){
-+#endif
-     unixLogErrorAtLine(SQLITE_IOERR_CLOSE, "close",
-                        pFile ? pFile->zPath : 0, lineno);
-   }
-@@ -41051,7 +41067,7 @@
-   SimulateIOError( rc=1 );
-   if( rc!=0 ){
-     storeLastErrno((unixFile*)id, errno);
--    return SQLITE_IOERR_FSTAT;
-+    return unixLogError(SQLITE_IOERR_FSTAT, "fstat", ((unixFile*)id)->zPath);
-   }
-   *pSize = buf.st_size;
- 
-@@ -41087,7 +41103,7 @@
-     struct stat buf;              /* Used to hold return values of fstat() */
- 
-     if( osFstat(pFile->h, &buf) ){
--      return SQLITE_IOERR_FSTAT;
-+      return unixLogError(SQLITE_IOERR_FSTAT, "fstat", pFile->zPath);
-     }
- 
-     nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
-@@ -41829,7 +41845,7 @@
-     ** with the same permissions.
-     */
-     if( osFstat(pDbFd->h, &sStat) ){
--      rc = SQLITE_IOERR_FSTAT;
-+      rc = unixLogError(SQLITE_IOERR_FSTAT, "fstat", pDbFd->zPath);
-       goto shm_open_err;
-     }
- 
-@@ -138266,7 +138282,7 @@
-   }
-   if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
-     sqlite3SetString(pzErrMsg, db, "unsupported file format");
--    rc = SQLITE_ERROR;
-+    rc = SQLITE_CORRUPT_BKPT; // Android Change from "rc = SQLITE_ERROR;";
-     goto initone_error_out;
-   }
- 
-@@ -185208,7 +185224,9 @@
-   ** module with sqlite.
-   */
-   if( SQLITE_OK==rc
-+#ifndef ANDROID    /* fts3_tokenizer disabled for security reasons */
-    && SQLITE_OK==(rc=sqlite3Fts3InitHashTable(db,&pHash->hash,"fts3_tokenizer"))
-+#endif
-    && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1))
-    && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1))
-    && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1))
-@@ -185219,6 +185237,20 @@
-     rc = sqlite3_create_module_v2(
-         db, "fts3", &fts3Module, (void *)pHash, hashDestroy
-     );
-+#ifdef SQLITE_ENABLE_FTS3_BACKWARDS
-+    if( rc==SQLITE_OK ){
-+      pHash->nRef++;
-+      rc = sqlite3_create_module_v2(
-+          db, "fts1", &fts3Module, (void *)pHash, hashDestroy
-+      );
-+    }
-+    if( rc==SQLITE_OK ){
-+      pHash->nRef++;
-+      rc = sqlite3_create_module_v2(
-+          db, "fts2", &fts3Module, (void *)pHash, hashDestroy
-+      );
-+    }
-+#endif
-     if( rc==SQLITE_OK ){
-       pHash->nRef++;
-       rc = sqlite3_create_module_v2(
diff --git a/dist/sqlite-autoconf-3420000/METADATA b/dist/sqlite-autoconf-3420000/METADATA
deleted file mode 100644
index 76cc062..0000000
--- a/dist/sqlite-autoconf-3420000/METADATA
+++ /dev/null
@@ -1,21 +0,0 @@
-name: "SQLite"
-description:
-    "SQLite database"
-
-third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://www.sqlite.org"
-  }
-  url {
-    type: ARCHIVE
-    value: "https://www.sqlite.org/2023/sqlite-autoconf-3420000.tar.gz"
-  }
-  version: "3.42.0"
-  last_upgrade_date { year: 2024 month: 00 day: 03/14/24 }
-  license_type: NOTICE
-
-  security: {
-    tag: "NVD-CPE2.3:cpe:/a:sqlite:sqlite"  # see http://go/metadata-cpe
-  }
-}
diff --git a/dist/sqlite-autoconf-3420000/README.version b/dist/sqlite-autoconf-3420000/README.version
deleted file mode 100644
index c892550..0000000
--- a/dist/sqlite-autoconf-3420000/README.version
+++ /dev/null
@@ -1,3 +0,0 @@
-URL: https://www.sqlite.org/2023/sqlite-autoconf-3420000.tar.gz
-Version: 3.42.0
-BugComponent: 24950
diff --git a/dist/sqlite-autoconf-3420000/orig/shell.c b/dist/sqlite-autoconf-3420000/orig/shell.c
deleted file mode 100644
index 647a214..0000000
--- a/dist/sqlite-autoconf-3420000/orig/shell.c
+++ /dev/null
@@ -1,28032 +0,0 @@
-/* DO NOT EDIT!
-** This file is automatically generated by the script in the canonical
-** SQLite source tree at tool/mkshellc.tcl.  That script combines source
-** code from various constituent source files of SQLite into this single
-** "shell.c" file used to implement the SQLite command-line shell.
-**
-** Most of the code found below comes from the "src/shell.c.in" file in
-** the canonical SQLite source tree.  That main file contains "INCLUDE"
-** lines that specify other files in the canonical source tree that are
-** inserted to getnerate this complete program source file.
-**
-** The code from multiple files is combined into this single "shell.c"
-** source file to help make the command-line program easier to compile.
-**
-** To modify this program, get a copy of the canonical SQLite source tree,
-** edit the src/shell.c.in" and/or some of the other files that are included
-** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script.
-*/
-/*
-** 2001 September 15
-**
-** 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 code to implement the "sqlite" command line
-** utility for accessing SQLite databases.
-*/
-#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
-/* This needs to come before any includes for MSVC compiler */
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-typedef unsigned int u32;
-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.
-** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include
-** file. Note that this macro has a like effect on sqlite3.c compilation.
-*/
-# define SHELL_STRINGIFY_(f) #f
-# define SHELL_STRINGIFY(f) SHELL_STRINGIFY_(f)
-#ifdef SQLITE_CUSTOM_INCLUDE
-# include SHELL_STRINGIFY(SQLITE_CUSTOM_INCLUDE)
-#endif
-
-/*
-** Determine if we are dealing with WinRT, which provides only a subset of
-** the full Win32 API.
-*/
-#if !defined(SQLITE_OS_WINRT)
-# define SQLITE_OS_WINRT 0
-#endif
-
-/*
-** If SQLITE_SHELL_FIDDLE is defined then the shell is modified
-** somewhat for use as a WASM module in a web browser. This flag
-** should only be used when building the "fiddle" web application, as
-** the browser-mode build has much different user input requirements
-** and this build mode rewires the user input subsystem to account for
-** that.
-*/
-
-/*
-** Warning pragmas copied from msvc.h in the core.
-*/
-#if defined(_MSC_VER)
-#pragma warning(disable : 4054)
-#pragma warning(disable : 4055)
-#pragma warning(disable : 4100)
-#pragma warning(disable : 4127)
-#pragma warning(disable : 4130)
-#pragma warning(disable : 4152)
-#pragma warning(disable : 4189)
-#pragma warning(disable : 4206)
-#pragma warning(disable : 4210)
-#pragma warning(disable : 4232)
-#pragma warning(disable : 4244)
-#pragma warning(disable : 4305)
-#pragma warning(disable : 4306)
-#pragma warning(disable : 4702)
-#pragma warning(disable : 4706)
-#endif /* defined(_MSC_VER) */
-
-/*
-** No support for loadable extensions in VxWorks.
-*/
-#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
-# define SQLITE_OMIT_LOAD_EXTENSION 1
-#endif
-
-/*
-** Enable large-file support for fopen() and friends on unix.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE       1
-# ifndef _FILE_OFFSET_BITS
-#   define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
-#if defined(SQLITE_SHELL_FIDDLE) && !defined(_POSIX_SOURCE)
-/*
-** emcc requires _POSIX_SOURCE (or one of several similar defines)
-** to expose strdup().
-*/
-# define _POSIX_SOURCE
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <assert.h>
-#include <math.h>
-#include "sqlite3.h"
-typedef sqlite3_int64 i64;
-typedef sqlite3_uint64 u64;
-typedef unsigned char u8;
-#if SQLITE_USER_AUTHENTICATION
-# include "sqlite3userauth.h"
-#endif
-#include <ctype.h>
-#include <stdarg.h>
-
-#if !defined(_WIN32) && !defined(WIN32)
-# include <signal.h>
-# if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI)
-#  include <pwd.h>
-# endif
-#endif
-#if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__)
-# include <unistd.h>
-# include <dirent.h>
-# define GETPID getpid
-# if defined(__MINGW32__)
-#  define DIRENT dirent
-#  ifndef S_ISLNK
-#   define S_ISLNK(mode) (0)
-#  endif
-# endif
-#else
-# define GETPID (int)GetCurrentProcessId
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#if HAVE_READLINE
-# include <readline/readline.h>
-# include <readline/history.h>
-#endif
-
-#if HAVE_EDITLINE
-# include <editline/readline.h>
-#endif
-
-#if HAVE_EDITLINE || HAVE_READLINE
-
-# define shell_add_history(X) add_history(X)
-# define shell_read_history(X) read_history(X)
-# define shell_write_history(X) write_history(X)
-# define shell_stifle_history(X) stifle_history(X)
-# define shell_readline(X) readline(X)
-
-#elif HAVE_LINENOISE
-
-# include "linenoise.h"
-# define shell_add_history(X) linenoiseHistoryAdd(X)
-# define shell_read_history(X) linenoiseHistoryLoad(X)
-# define shell_write_history(X) linenoiseHistorySave(X)
-# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
-# define shell_readline(X) linenoise(X)
-
-#else
-
-# define shell_read_history(X)
-# define shell_write_history(X)
-# define shell_stifle_history(X)
-
-# 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
-#  define SQLITE_OMIT_POPEN 1
-# else
-#  include <io.h>
-#  include <fcntl.h>
-#  define isatty(h) _isatty(h)
-#  ifndef access
-#   define access(f,m) _access((f),(m))
-#  endif
-#  ifndef unlink
-#   define unlink _unlink
-#  endif
-#  ifndef strdup
-#   define strdup _strdup
-#  endif
-#  undef popen
-#  define popen _popen
-#  undef pclose
-#  define pclose _pclose
-# endif
-#else
- /* Make sure isatty() has a prototype. */
- extern int isatty(int);
-
-# 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*);
-   extern int pclose(FILE*);
-# else
-#  define SQLITE_OMIT_POPEN 1
-# endif
-#endif
-
-#if defined(_WIN32_WCE)
-/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
- * thus we always assume that we have a console. That can be
- * overridden with the -batch command line option.
- */
-#define isatty(x) 1
-#endif
-
-/* ctype macros that work with signed characters */
-#define IsSpace(X)  isspace((unsigned char)X)
-#define IsDigit(X)  isdigit((unsigned char)X)
-#define ToLower(X)  (char)tolower((unsigned char)X)
-
-#if defined(_WIN32) || defined(WIN32)
-#if SQLITE_OS_WINRT
-#include <intrin.h>
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-/* string conversion routines only needed on Win32 */
-extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
-extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
-extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
-extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
-#endif
-
-/* On Windows, we normally run with output mode of TEXT so that \n characters
-** are automatically translated into \r\n.  However, this behavior needs
-** to be disabled in some cases (ex: when generating CSV output and when
-** rendering quoted strings that contain \n characters).  The following
-** routines take care of that.
-*/
-#if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT
-static void setBinaryMode(FILE *file, int isOutput){
-  if( isOutput ) fflush(file);
-  _setmode(_fileno(file), _O_BINARY);
-}
-static void setTextMode(FILE *file, int isOutput){
-  if( isOutput ) fflush(file);
-  _setmode(_fileno(file), _O_TEXT);
-}
-#else
-# define setBinaryMode(X,Y)
-# define setTextMode(X,Y)
-#endif
-
-/* True if the timer is enabled */
-static int enableTimer = 0;
-
-/* A version of strcmp() that works with NULL values */
-static int cli_strcmp(const char *a, const char *b){
-  if( a==0 ) a = "";
-  if( b==0 ) b = "";
-  return strcmp(a,b);
-}
-static int cli_strncmp(const char *a, const char *b, size_t n){
-  if( a==0 ) a = "";
-  if( b==0 ) b = "";
-  return strncmp(a,b,n);
-}
-
-/* Return the current wall-clock time */
-static sqlite3_int64 timeOfDay(void){
-  static sqlite3_vfs *clockVfs = 0;
-  sqlite3_int64 t;
-  if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
-  if( clockVfs==0 ) return 0;  /* Never actually happens */
-  if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
-    clockVfs->xCurrentTimeInt64(clockVfs, &t);
-  }else{
-    double r;
-    clockVfs->xCurrentTime(clockVfs, &r);
-    t = (sqlite3_int64)(r*86400000.0);
-  }
-  return t;
-}
-
-#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
-#include <sys/time.h>
-#include <sys/resource.h>
-
-/* VxWorks does not support getrusage() as far as we can determine */
-#if defined(_WRS_KERNEL) || defined(__RTP__)
-struct rusage {
-  struct timeval ru_utime; /* user CPU time used */
-  struct timeval ru_stime; /* system CPU time used */
-};
-#define getrusage(A,B) memset(B,0,sizeof(*B))
-#endif
-
-/* Saved resource information for the beginning of an operation */
-static struct rusage sBegin;  /* CPU time at start */
-static sqlite3_int64 iBegin;  /* Wall-clock time at start */
-
-/*
-** Begin timing an operation
-*/
-static void beginTimer(void){
-  if( enableTimer ){
-    getrusage(RUSAGE_SELF, &sBegin);
-    iBegin = timeOfDay();
-  }
-}
-
-/* Return the difference of two time_structs in seconds */
-static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
-  return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
-         (double)(pEnd->tv_sec - pStart->tv_sec);
-}
-
-/*
-** Print the timing results.
-*/
-static void endTimer(void){
-  if( enableTimer ){
-    sqlite3_int64 iEnd = timeOfDay();
-    struct rusage sEnd;
-    getrusage(RUSAGE_SELF, &sEnd);
-    printf("Run Time: real %.3f user %f sys %f\n",
-       (iEnd - iBegin)*0.001,
-       timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
-       timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
-  }
-}
-
-#define BEGIN_TIMER beginTimer()
-#define END_TIMER endTimer()
-#define HAS_TIMER 1
-
-#elif (defined(_WIN32) || defined(WIN32))
-
-/* Saved resource information for the beginning of an operation */
-static HANDLE hProcess;
-static FILETIME ftKernelBegin;
-static FILETIME ftUserBegin;
-static sqlite3_int64 ftWallBegin;
-typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
-                                    LPFILETIME, LPFILETIME);
-static GETPROCTIMES getProcessTimesAddr = NULL;
-
-/*
-** Check to see if we have timer support.  Return 1 if necessary
-** support found (or found previously).
-*/
-static int hasTimer(void){
-  if( getProcessTimesAddr ){
-    return 1;
-  } else {
-#if !SQLITE_OS_WINRT
-    /* GetProcessTimes() isn't supported in WIN95 and some other Windows
-    ** versions. See if the version we are running on has it, and if it
-    ** does, save off a pointer to it and the current process handle.
-    */
-    hProcess = GetCurrentProcess();
-    if( hProcess ){
-      HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
-      if( NULL != hinstLib ){
-        getProcessTimesAddr =
-            (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
-        if( NULL != getProcessTimesAddr ){
-          return 1;
-        }
-        FreeLibrary(hinstLib);
-      }
-    }
-#endif
-  }
-  return 0;
-}
-
-/*
-** Begin timing an operation
-*/
-static void beginTimer(void){
-  if( enableTimer && getProcessTimesAddr ){
-    FILETIME ftCreation, ftExit;
-    getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
-                        &ftKernelBegin,&ftUserBegin);
-    ftWallBegin = timeOfDay();
-  }
-}
-
-/* Return the difference of two FILETIME structs in seconds */
-static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
-  sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
-  sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
-  return (double) ((i64End - i64Start) / 10000000.0);
-}
-
-/*
-** Print the timing results.
-*/
-static void endTimer(void){
-  if( enableTimer && getProcessTimesAddr){
-    FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
-    sqlite3_int64 ftWallEnd = timeOfDay();
-    getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
-    printf("Run Time: real %.3f user %f sys %f\n",
-       (ftWallEnd - ftWallBegin)*0.001,
-       timeDiff(&ftUserBegin, &ftUserEnd),
-       timeDiff(&ftKernelBegin, &ftKernelEnd));
-  }
-}
-
-#define BEGIN_TIMER beginTimer()
-#define END_TIMER endTimer()
-#define HAS_TIMER hasTimer()
-
-#else
-#define BEGIN_TIMER
-#define END_TIMER
-#define HAS_TIMER 0
-#endif
-
-/*
-** Used to prevent warnings about unused parameters
-*/
-#define UNUSED_PARAMETER(x) (void)(x)
-
-/*
-** Number of elements in an array
-*/
-#define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
-
-/*
-** If the following flag is set, then command execution stops
-** at an error if we are not interactive.
-*/
-static int bail_on_error = 0;
-
-/*
-** 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
-** true if translation is required.
-*/
-static int stdout_is_console = 1;
-
-/*
-** The following is the open SQLite database.  We make a pointer
-** to this database a static variable so that it can be accessed
-** by the SIGINT handler to interrupt database processing.
-*/
-static sqlite3 *globalDb = 0;
-
-/*
-** True if an interrupt (Control-C) has been received.
-*/
-static volatile int seenInterrupt = 0;
-
-/*
-** This is the name of our program. It is set in main(), used
-** in a number of other places, mostly for error messages.
-*/
-static char *Argv0;
-
-/*
-** Prompt strings. Initialized in main. Settable with
-**   .prompt main continue
-*/
-#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, 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 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);
-    fputs(z2, out);
-    sqlite3_free(z2);
-  }else{
-    vfprintf(out, zFormat, ap);
-  }
-  va_end(ap);
-}
-#elif !defined(utf8_printf)
-# define utf8_printf fprintf
-#endif
-
-/*
-** Render output like fprintf().  This should not be used on anything that
-** includes string formatting (e.g. "%s").
-*/
-#if !defined(raw_printf)
-# define raw_printf fprintf
-#endif
-
-/* Indicate out-of-memory and exit. */
-static void shell_out_of_memory(void){
-  raw_printf(stderr,"Error: out of memory\n");
-  exit(1);
-}
-
-/* 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(const void *p){
-  if( p==0 ) shell_out_of_memory();
-}
-
-/*
-** Write I/O traces to the following stream.
-*/
-#ifdef SQLITE_ENABLE_IOTRACE
-static FILE *iotrace = 0;
-#endif
-
-/*
-** This routine works like printf in that its first argument is a
-** format string and subsequent arguments are values to be substituted
-** in place of % fields.  The result of formatting this string
-** is written to iotrace.
-*/
-#ifdef SQLITE_ENABLE_IOTRACE
-static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
-  va_list ap;
-  char *z;
-  if( iotrace==0 ) return;
-  va_start(ap, zFormat);
-  z = sqlite3_vmprintf(zFormat, ap);
-  va_end(ap);
-  utf8_printf(iotrace, "%s", z);
-  sqlite3_free(z);
-}
-#endif
-
-/*
-** Output string zUtf to stream pOut as w characters.  If w is negative,
-** then right-justify the text.  W is the width in UTF-8 characters, not
-** in bytes.  This is different from the %*.*s specification in printf
-** since with %*.*s the width is measured in bytes, not characters.
-*/
-static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
-  int i;
-  int n;
-  int aw = w<0 ? -w : w;
-  if( zUtf==0 ) zUtf = "";
-  for(i=n=0; zUtf[i]; i++){
-    if( (zUtf[i]&0xc0)!=0x80 ){
-      n++;
-      if( n==aw ){
-        do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
-        break;
-      }
-    }
-  }
-  if( n>=aw ){
-    utf8_printf(pOut, "%.*s", i, zUtf);
-  }else if( w<0 ){
-    utf8_printf(pOut, "%*s%s", aw-n, "", zUtf);
-  }else{
-    utf8_printf(pOut, "%s%*s", zUtf, aw-n, "");
-  }
-}
-
-
-/*
-** Determines if a string is a number of not.
-*/
-static int isNumber(const char *z, int *realnum){
-  if( *z=='-' || *z=='+' ) z++;
-  if( !IsDigit(*z) ){
-    return 0;
-  }
-  z++;
-  if( realnum ) *realnum = 0;
-  while( IsDigit(*z) ){ z++; }
-  if( *z=='.' ){
-    z++;
-    if( !IsDigit(*z) ) return 0;
-    while( IsDigit(*z) ){ z++; }
-    if( realnum ) *realnum = 1;
-  }
-  if( *z=='e' || *z=='E' ){
-    z++;
-    if( *z=='+' || *z=='-' ) z++;
-    if( !IsDigit(*z) ) return 0;
-    while( IsDigit(*z) ){ z++; }
-    if( realnum ) *realnum = 1;
-  }
-  return *z==0;
-}
-
-/*
-** Compute a string length that is limited to what can be stored in
-** lower 30 bits of a 32-bit signed integer.
-*/
-static int strlen30(const char *z){
-  const char *z2 = z;
-  while( *z2 ){ z2++; }
-  return 0x3fffffff & (int)(z2 - z);
-}
-
-/*
-** Return the length of a string in characters.  Multibyte UTF8 characters
-** count as a single character.
-*/
-static int strlenChar(const char *z){
-  int n = 0;
-  while( *z ){
-    if( (0xc0&*(z++))!=0x80 ) n++;
-  }
-  return n;
-}
-
-/*
-** Return open FILE * if zFile exists, can be opened for read
-** and is an ordinary file or a character stream source.
-** Otherwise return 0.
-*/
-static FILE * openChrSource(const char *zFile){
-#ifdef _WIN32
-  struct _stat x = {0};
-# define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0)
-  /* On Windows, open first, then check the stream nature. This order
-  ** is necessary because _stat() and sibs, when checking a named pipe,
-  ** effectively break the pipe as its supplier sees it. */
-  FILE *rv = fopen(zFile, "rb");
-  if( rv==0 ) return 0;
-  if( _fstat(_fileno(rv), &x) != 0
-      || !STAT_CHR_SRC(x.st_mode)){
-    fclose(rv);
-    rv = 0;
-  }
-  return rv;
-#else
-  struct stat x = {0};
-  int rc = stat(zFile, &x);
-# define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode))
-  if( rc!=0 ) return 0;
-  if( STAT_CHR_SRC(x.st_mode) ){
-    return fopen(zFile, "rb");
-  }else{
-    return 0;
-  }
-#endif
-#undef STAT_CHR_SRC
-}
-
-/*
-** This routine reads a line of text from FILE in, stores
-** the text in memory obtained from malloc() and returns a pointer
-** to the text.  NULL is returned at end of file, or if malloc()
-** fails.
-**
-** If zLine is not NULL then it is a malloced buffer returned from
-** a previous call to this routine that may be reused.
-*/
-static char *local_getline(char *zLine, FILE *in){
-  int nLine = zLine==0 ? 0 : 100;
-  int n = 0;
-
-  while( 1 ){
-    if( n+100>nLine ){
-      nLine = nLine*2 + 100;
-      zLine = realloc(zLine, nLine);
-      shell_check_oom(zLine);
-    }
-    if( fgets(&zLine[n], nLine - n, in)==0 ){
-      if( n==0 ){
-        free(zLine);
-        return 0;
-      }
-      zLine[n] = 0;
-      break;
-    }
-    while( zLine[n] ) n++;
-    if( n>0 && zLine[n-1]=='\n' ){
-      n--;
-      if( n>0 && zLine[n-1]=='\r' ) n--;
-      zLine[n] = 0;
-      break;
-    }
-  }
-#if defined(_WIN32) || defined(WIN32)
-  /* 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;
-      if( nTrans>nLine ){
-        zLine = realloc(zLine, nTrans);
-        shell_check_oom(zLine);
-      }
-      memcpy(zLine, zTrans, nTrans);
-      sqlite3_free(zTrans);
-    }
-  }
-#endif /* defined(_WIN32) || defined(WIN32) */
-  return zLine;
-}
-
-/*
-** Retrieve a single line of input text.
-**
-** If in==0 then read from standard input and prompt before each line.
-** If isContinuation is true, then a continuation prompt is appropriate.
-** If isContinuation is zero, then the main prompt should be used.
-**
-** If zPrior is not NULL then it is a buffer from a prior call to this
-** routine that can be reused.
-**
-** The result is stored in space obtained from malloc() and must either
-** be freed by the caller or else passed back into this routine via the
-** zPrior argument for reuse.
-*/
-#ifndef SQLITE_SHELL_FIDDLE
-static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
-  char *zPrompt;
-  char *zResult;
-  if( in!=0 ){
-    zResult = local_getline(zPrior, in);
-  }else{
-    zPrompt = isContinuation ? CONTINUATION_PROMPT : mainPrompt;
-#if SHELL_USE_LOCAL_GETLINE
-    printf("%s", zPrompt);
-    fflush(stdout);
-    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
-  }
-  return zResult;
-}
-#endif /* !SQLITE_SHELL_FIDDLE */
-
-/*
-** Return the value of a hexadecimal digit.  Return -1 if the input
-** is not a hex digit.
-*/
-static int hexDigitValue(char c){
-  if( c>='0' && c<='9' ) return c - '0';
-  if( c>='a' && c<='f' ) return c - 'a' + 10;
-  if( c>='A' && c<='F' ) return c - 'A' + 10;
-  return -1;
-}
-
-/*
-** Interpret zArg as an integer value, possibly with suffixes.
-*/
-static sqlite3_int64 integerValue(const char *zArg){
-  sqlite3_int64 v = 0;
-  static const struct { char *zSuffix; int iMult; } aMult[] = {
-    { "KiB", 1024 },
-    { "MiB", 1024*1024 },
-    { "GiB", 1024*1024*1024 },
-    { "KB",  1000 },
-    { "MB",  1000000 },
-    { "GB",  1000000000 },
-    { "K",   1000 },
-    { "M",   1000000 },
-    { "G",   1000000000 },
-  };
-  int i;
-  int isNeg = 0;
-  if( zArg[0]=='-' ){
-    isNeg = 1;
-    zArg++;
-  }else if( zArg[0]=='+' ){
-    zArg++;
-  }
-  if( zArg[0]=='0' && zArg[1]=='x' ){
-    int x;
-    zArg += 2;
-    while( (x = hexDigitValue(zArg[0]))>=0 ){
-      v = (v<<4) + x;
-      zArg++;
-    }
-  }else{
-    while( IsDigit(zArg[0]) ){
-      v = v*10 + zArg[0] - '0';
-      zArg++;
-    }
-  }
-  for(i=0; i<ArraySize(aMult); i++){
-    if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
-      v *= aMult[i].iMult;
-      break;
-    }
-  }
-  return isNeg? -v : v;
-}
-
-/*
-** A variable length string to which one can append text.
-*/
-typedef struct ShellText ShellText;
-struct ShellText {
-  char *z;
-  int n;
-  int nAlloc;
-};
-
-/*
-** Initialize and destroy a ShellText object
-*/
-static void initText(ShellText *p){
-  memset(p, 0, sizeof(*p));
-}
-static void freeText(ShellText *p){
-  free(p->z);
-  initText(p);
-}
-
-/* zIn is either a pointer to a NULL-terminated string in memory obtained
-** from malloc(), or a NULL pointer. The string pointed to by zAppend is
-** added to zIn, and the result returned in memory obtained from malloc().
-** zIn, if it was not NULL, is freed.
-**
-** If the third argument, quote, is not '\0', then it is used as a
-** quote character for zAppend.
-*/
-static void appendText(ShellText *p, const char *zAppend, char quote){
-  i64 len;
-  i64 i;
-  i64 nAppend = strlen30(zAppend);
-
-  len = nAppend+p->n+1;
-  if( quote ){
-    len += 2;
-    for(i=0; i<nAppend; i++){
-      if( zAppend[i]==quote ) len++;
-    }
-  }
-
-  if( p->z==0 || p->n+len>=p->nAlloc ){
-    p->nAlloc = p->nAlloc*2 + len + 20;
-    p->z = realloc(p->z, p->nAlloc);
-    shell_check_oom(p->z);
-  }
-
-  if( quote ){
-    char *zCsr = p->z+p->n;
-    *zCsr++ = quote;
-    for(i=0; i<nAppend; i++){
-      *zCsr++ = zAppend[i];
-      if( zAppend[i]==quote ) *zCsr++ = quote;
-    }
-    *zCsr++ = quote;
-    p->n = (int)(zCsr - p->z);
-    *zCsr = '\0';
-  }else{
-    memcpy(p->z+p->n, zAppend, nAppend);
-    p->n += nAppend;
-    p->z[p->n] = '\0';
-  }
-}
-
-/*
-** Attempt to determine if identifier zName needs to be quoted, either
-** because it contains non-alphanumeric characters, or because it is an
-** SQLite keyword.  Be conservative in this estimate:  When in doubt assume
-** that quoting is required.
-**
-** Return '"' if quoting is required.  Return 0 if no quoting is required.
-*/
-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 '"';
-  }
-  return sqlite3_keyword_check(zName, i) ? '"' : 0;
-}
-
-/*
-** Construct a fake object name and column list to describe the structure
-** of the view, virtual table, or table valued function zSchema.zName.
-*/
-static char *shellFakeSchema(
-  sqlite3 *db,            /* The database connection containing the vtab */
-  const char *zSchema,    /* Schema of the database holding the vtab */
-  const char *zName       /* The name of the virtual table */
-){
-  sqlite3_stmt *pStmt = 0;
-  char *zSql;
-  ShellText s;
-  char cQuote;
-  char *zDiv = "(";
-  int nRow = 0;
-
-  zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;",
-                         zSchema ? zSchema : "main", zName);
-  shell_check_oom(zSql);
-  sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
-  sqlite3_free(zSql);
-  initText(&s);
-  if( zSchema ){
-    cQuote = quoteChar(zSchema);
-    if( cQuote && sqlite3_stricmp(zSchema,"temp")==0 ) cQuote = 0;
-    appendText(&s, zSchema, cQuote);
-    appendText(&s, ".", 0);
-  }
-  cQuote = quoteChar(zName);
-  appendText(&s, zName, cQuote);
-  while( sqlite3_step(pStmt)==SQLITE_ROW ){
-    const char *zCol = (const char*)sqlite3_column_text(pStmt, 1);
-    nRow++;
-    appendText(&s, zDiv, 0);
-    zDiv = ",";
-    if( zCol==0 ) zCol = "";
-    cQuote = quoteChar(zCol);
-    appendText(&s, zCol, cQuote);
-  }
-  appendText(&s, ")", 0);
-  sqlite3_finalize(pStmt);
-  if( nRow==0 ){
-    freeText(&s);
-    s.z = 0;
-  }
-  return s.z;
-}
-
-/*
-** SQL function:  shell_module_schema(X)
-**
-** Return a fake schema for the table-valued function or eponymous virtual
-** table X.
-*/
-static void shellModuleSchema(
-  sqlite3_context *pCtx,
-  int nVal,
-  sqlite3_value **apVal
-){
-  const char *zName;
-  char *zFake;
-  UNUSED_PARAMETER(nVal);
-  zName = (const char*)sqlite3_value_text(apVal[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);
-    free(zFake);
-  }
-}
-
-/*
-** SQL function:  shell_add_schema(S,X)
-**
-** Add the schema name X to the CREATE statement in S and return the result.
-** Examples:
-**
-**    CREATE TABLE t1(x)   ->   CREATE TABLE xyz.t1(x);
-**
-** Also works on
-**
-**    CREATE INDEX
-**    CREATE UNIQUE INDEX
-**    CREATE VIEW
-**    CREATE TRIGGER
-**    CREATE VIRTUAL TABLE
-**
-** This UDF is used by the .schema command to insert the schema name of
-** attached databases into the middle of the sqlite_schema.sql field.
-*/
-static void shellAddSchemaName(
-  sqlite3_context *pCtx,
-  int nVal,
-  sqlite3_value **apVal
-){
-  static const char *aPrefix[] = {
-     "TABLE",
-     "INDEX",
-     "UNIQUE INDEX",
-     "VIEW",
-     "TRIGGER",
-     "VIRTUAL TABLE"
-  };
-  int i = 0;
-  const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
-  const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
-  const char *zName = (const char*)sqlite3_value_text(apVal[2]);
-  sqlite3 *db = sqlite3_context_db_handle(pCtx);
-  UNUSED_PARAMETER(nVal);
-  if( zIn!=0 && cli_strncmp(zIn, "CREATE ", 7)==0 ){
-    for(i=0; i<ArraySize(aPrefix); i++){
-      int n = strlen30(aPrefix[i]);
-      if( cli_strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
-        char *z = 0;
-        char *zFake = 0;
-        if( zSchema ){
-          char cQuote = quoteChar(zSchema);
-          if( cQuote && sqlite3_stricmp(zSchema,"temp")!=0 ){
-            z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
-          }else{
-            z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8);
-          }
-        }
-        if( zName
-         && aPrefix[i][0]=='V'
-         && (zFake = shellFakeSchema(db, zSchema, zName))!=0
-        ){
-          if( z==0 ){
-            z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
-          }else{
-            z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
-          }
-          free(zFake);
-        }
-        if( z ){
-          sqlite3_result_text(pCtx, z, -1, sqlite3_free);
-          return;
-        }
-      }
-    }
-  }
-  sqlite3_result_value(pCtx, apVal[0]);
-}
-
-/*
-** The source code for several run-time loadable extensions is inserted
-** below by the ../tool/mkshellc.tcl script.  Before processing that included
-** code, we need to override some macros to make the included program code
-** work here in the middle of this regular program.
-*/
-#define SQLITE_EXTENSION_INIT1
-#define SQLITE_EXTENSION_INIT2(X) (void)(X)
-
-#if defined(_WIN32) && defined(_MSC_VER)
-/************************* Begin test_windirent.h ******************/
-/*
-** 2015 November 30
-**
-** 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 declarations for most of the opendir() family of
-** POSIX functions on Win32 using the MSVCRT.
-*/
-
-#if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H)
-#define SQLITE_WINDIRENT_H
-
-/*
-** We need several data types from the Windows SDK header.
-*/
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-
-#include "windows.h"
-
-/*
-** We need several support functions from the SQLite core.
-*/
-
-/* #include "sqlite3.h" */
-
-/*
-** We need several things from the ANSI and MSVCRT headers.
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <io.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-/*
-** We may need several defines that should have been in "sys/stat.h".
-*/
-
-#ifndef S_ISREG
-#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
-#endif
-
-#ifndef S_ISDIR
-#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
-#endif
-
-#ifndef S_ISLNK
-#define S_ISLNK(mode) (0)
-#endif
-
-/*
-** We may need to provide the "mode_t" type.
-*/
-
-#ifndef MODE_T_DEFINED
-  #define MODE_T_DEFINED
-  typedef unsigned short mode_t;
-#endif
-
-/*
-** We may need to provide the "ino_t" type.
-*/
-
-#ifndef INO_T_DEFINED
-  #define INO_T_DEFINED
-  typedef unsigned short ino_t;
-#endif
-
-/*
-** We need to define "NAME_MAX" if it was not present in "limits.h".
-*/
-
-#ifndef NAME_MAX
-#  ifdef FILENAME_MAX
-#    define NAME_MAX (FILENAME_MAX)
-#  else
-#    define NAME_MAX (260)
-#  endif
-#endif
-
-/*
-** We need to define "NULL_INTPTR_T" and "BAD_INTPTR_T".
-*/
-
-#ifndef NULL_INTPTR_T
-#  define NULL_INTPTR_T ((intptr_t)(0))
-#endif
-
-#ifndef BAD_INTPTR_T
-#  define BAD_INTPTR_T ((intptr_t)(-1))
-#endif
-
-/*
-** We need to provide the necessary structures and related types.
-*/
-
-#ifndef DIRENT_DEFINED
-#define DIRENT_DEFINED
-typedef struct DIRENT DIRENT;
-typedef DIRENT *LPDIRENT;
-struct DIRENT {
-  ino_t d_ino;               /* Sequence number, do not use. */
-  unsigned d_attributes;     /* Win32 file attributes. */
-  char d_name[NAME_MAX + 1]; /* Name within the directory. */
-};
-#endif
-
-#ifndef DIR_DEFINED
-#define DIR_DEFINED
-typedef struct DIR DIR;
-typedef DIR *LPDIR;
-struct DIR {
-  intptr_t d_handle; /* Value returned by "_findfirst". */
-  DIRENT d_first;    /* DIRENT constructed based on "_findfirst". */
-  DIRENT d_next;     /* DIRENT constructed based on "_findnext". */
-};
-#endif
-
-/*
-** Provide a macro, for use by the implementation, to determine if a
-** particular directory entry should be skipped over when searching for
-** the next directory entry that should be returned by the readdir() or
-** readdir_r() functions.
-*/
-
-#ifndef is_filtered
-#  define is_filtered(a) ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM))
-#endif
-
-/*
-** Provide the function prototype for the POSIX compatiable getenv()
-** function.  This function is not thread-safe.
-*/
-
-extern const char *windirent_getenv(const char *name);
-
-/*
-** Finally, we can provide the function prototypes for the opendir(),
-** readdir(), readdir_r(), and closedir() POSIX functions.
-*/
-
-extern LPDIR opendir(const char *dirname);
-extern LPDIRENT readdir(LPDIR dirp);
-extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result);
-extern INT closedir(LPDIR dirp);
-
-#endif /* defined(WIN32) && defined(_MSC_VER) */
-
-/************************* End test_windirent.h ********************/
-/************************* Begin test_windirent.c ******************/
-/*
-** 2015 November 30
-**
-** 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 code to implement most of the opendir() family of
-** POSIX functions on Win32 using the MSVCRT.
-*/
-
-#if defined(_WIN32) && defined(_MSC_VER)
-/* #include "test_windirent.h" */
-
-/*
-** Implementation of the POSIX getenv() function using the Win32 API.
-** This function is not thread-safe.
-*/
-const char *windirent_getenv(
-  const char *name
-){
-  static char value[32768]; /* Maximum length, per MSDN */
-  DWORD dwSize = sizeof(value) / sizeof(char); /* Size in chars */
-  DWORD dwRet; /* Value returned by GetEnvironmentVariableA() */
-
-  memset(value, 0, sizeof(value));
-  dwRet = GetEnvironmentVariableA(name, value, dwSize);
-  if( dwRet==0 || dwRet>dwSize ){
-    /*
-    ** The function call to GetEnvironmentVariableA() failed -OR-
-    ** the buffer is not large enough.  Either way, return NULL.
-    */
-    return 0;
-  }else{
-    /*
-    ** The function call to GetEnvironmentVariableA() succeeded
-    ** -AND- the buffer contains the entire value.
-    */
-    return value;
-  }
-}
-
-/*
-** Implementation of the POSIX opendir() function using the MSVCRT.
-*/
-LPDIR opendir(
-  const char *dirname
-){
-  struct _finddata_t data;
-  LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
-  SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
-
-  if( dirp==NULL ) return NULL;
-  memset(dirp, 0, sizeof(DIR));
-
-  /* TODO: Remove this if Unix-style root paths are not used. */
-  if( sqlite3_stricmp(dirname, "/")==0 ){
-    dirname = windirent_getenv("SystemDrive");
-  }
-
-  memset(&data, 0, sizeof(struct _finddata_t));
-  _snprintf(data.name, namesize, "%s\\*", dirname);
-  dirp->d_handle = _findfirst(data.name, &data);
-
-  if( dirp->d_handle==BAD_INTPTR_T ){
-    closedir(dirp);
-    return NULL;
-  }
-
-  /* TODO: Remove this block to allow hidden and/or system files. */
-  if( is_filtered(data) ){
-next:
-
-    memset(&data, 0, sizeof(struct _finddata_t));
-    if( _findnext(dirp->d_handle, &data)==-1 ){
-      closedir(dirp);
-      return NULL;
-    }
-
-    /* TODO: Remove this block to allow hidden and/or system files. */
-    if( is_filtered(data) ) goto next;
-  }
-
-  dirp->d_first.d_attributes = data.attrib;
-  strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
-  dirp->d_first.d_name[NAME_MAX] = '\0';
-
-  return dirp;
-}
-
-/*
-** Implementation of the POSIX readdir() function using the MSVCRT.
-*/
-LPDIRENT readdir(
-  LPDIR dirp
-){
-  struct _finddata_t data;
-
-  if( dirp==NULL ) return NULL;
-
-  if( dirp->d_first.d_ino==0 ){
-    dirp->d_first.d_ino++;
-    dirp->d_next.d_ino++;
-
-    return &dirp->d_first;
-  }
-
-next:
-
-  memset(&data, 0, sizeof(struct _finddata_t));
-  if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
-
-  /* TODO: Remove this block to allow hidden and/or system files. */
-  if( is_filtered(data) ) goto next;
-
-  dirp->d_next.d_ino++;
-  dirp->d_next.d_attributes = data.attrib;
-  strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
-  dirp->d_next.d_name[NAME_MAX] = '\0';
-
-  return &dirp->d_next;
-}
-
-/*
-** Implementation of the POSIX readdir_r() function using the MSVCRT.
-*/
-INT readdir_r(
-  LPDIR dirp,
-  LPDIRENT entry,
-  LPDIRENT *result
-){
-  struct _finddata_t data;
-
-  if( dirp==NULL ) return EBADF;
-
-  if( dirp->d_first.d_ino==0 ){
-    dirp->d_first.d_ino++;
-    dirp->d_next.d_ino++;
-
-    entry->d_ino = dirp->d_first.d_ino;
-    entry->d_attributes = dirp->d_first.d_attributes;
-    strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
-    entry->d_name[NAME_MAX] = '\0';
-
-    *result = entry;
-    return 0;
-  }
-
-next:
-
-  memset(&data, 0, sizeof(struct _finddata_t));
-  if( _findnext(dirp->d_handle, &data)==-1 ){
-    *result = NULL;
-    return ENOENT;
-  }
-
-  /* TODO: Remove this block to allow hidden and/or system files. */
-  if( is_filtered(data) ) goto next;
-
-  entry->d_ino = (ino_t)-1; /* not available */
-  entry->d_attributes = data.attrib;
-  strncpy(entry->d_name, data.name, NAME_MAX);
-  entry->d_name[NAME_MAX] = '\0';
-
-  *result = entry;
-  return 0;
-}
-
-/*
-** Implementation of the POSIX closedir() function using the MSVCRT.
-*/
-INT closedir(
-  LPDIR dirp
-){
-  INT result = 0;
-
-  if( dirp==NULL ) return EINVAL;
-
-  if( dirp->d_handle!=NULL_INTPTR_T && dirp->d_handle!=BAD_INTPTR_T ){
-    result = _findclose(dirp->d_handle);
-  }
-
-  sqlite3_free(dirp);
-  return result;
-}
-
-#endif /* defined(WIN32) && defined(_MSC_VER) */
-
-/************************* End test_windirent.c ********************/
-#define dirent DIRENT
-#endif
-/************************* Begin ../ext/misc/memtrace.c ******************/
-/*
-** 2019-01-21
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file implements an extension that uses the SQLITE_CONFIG_MALLOC
-** mechanism to add a tracing layer on top of SQLite.  If this extension
-** is registered prior to sqlite3_initialize(), it will cause all memory
-** allocation activities to be logged on standard output, or to some other
-** FILE specified by the initializer.
-**
-** This file needs to be compiled into the application that uses it.
-**
-** This extension is used to implement the --memtrace option of the
-** command-line shell.
-*/
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-
-/* The original memory allocation routines */
-static sqlite3_mem_methods memtraceBase;
-static FILE *memtraceOut;
-
-/* Methods that trace memory allocations */
-static void *memtraceMalloc(int n){
-  if( memtraceOut ){
-    fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n", 
-            memtraceBase.xRoundup(n));
-  }
-  return memtraceBase.xMalloc(n);
-}
-static void memtraceFree(void *p){
-  if( p==0 ) return;
-  if( memtraceOut ){
-    fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p));
-  }
-  memtraceBase.xFree(p);
-}
-static void *memtraceRealloc(void *p, int n){
-  if( p==0 ) return memtraceMalloc(n);
-  if( n==0 ){
-    memtraceFree(p);
-    return 0;
-  }
-  if( memtraceOut ){
-    fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n",
-            memtraceBase.xSize(p), memtraceBase.xRoundup(n));
-  }
-  return memtraceBase.xRealloc(p, n);
-}
-static int memtraceSize(void *p){
-  return memtraceBase.xSize(p);
-}
-static int memtraceRoundup(int n){
-  return memtraceBase.xRoundup(n);
-}
-static int memtraceInit(void *p){
-  return memtraceBase.xInit(p);
-}
-static void memtraceShutdown(void *p){
-  memtraceBase.xShutdown(p);
-}
-
-/* The substitute memory allocator */
-static sqlite3_mem_methods ersaztMethods = {
-  memtraceMalloc,
-  memtraceFree,
-  memtraceRealloc,
-  memtraceSize,
-  memtraceRoundup,
-  memtraceInit,
-  memtraceShutdown,
-  0
-};
-
-/* Begin tracing memory allocations to out. */
-int sqlite3MemTraceActivate(FILE *out){
-  int rc = SQLITE_OK;
-  if( memtraceBase.xMalloc==0 ){
-    rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase);
-    if( rc==SQLITE_OK ){
-      rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods);
-    }
-  }
-  memtraceOut = out;
-  return rc;
-}
-
-/* Deactivate memory tracing */
-int sqlite3MemTraceDeactivate(void){
-  int rc = SQLITE_OK;
-  if( memtraceBase.xMalloc!=0 ){
-    rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase);
-    if( rc==SQLITE_OK ){
-      memset(&memtraceBase, 0, sizeof(memtraceBase));
-    }
-  }
-  memtraceOut = 0;
-  return rc;
-}
-
-/************************* End ../ext/misc/memtrace.c ********************/
-/************************* Begin ../ext/misc/shathree.c ******************/
-/*
-** 2017-03-08
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This SQLite extension implements functions 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)
-**     sha3_query(Y,SIZE)
-**
-** The sha3(X) function computes the SHA3 hash of the input X, or NULL if
-** X is NULL.
-**
-** The sha3_query(Y) function evaluates all queries in the SQL statements of Y
-** and returns a hash of their results.
-**
-** The SIZE argument is optional.  If omitted, the SHA3-256 hash algorithm
-** is used.  If SIZE is included it must be one of the integers 224, 256,
-** 384, or 512, to determine SHA3 hash variant that is computed.
-*/
-/* #include "sqlite3ext.h" */
-SQLITE_EXTENSION_INIT1
-#include <assert.h>
-#include <string.h>
-#include <stdarg.h>
-
-#ifndef SQLITE_AMALGAMATION
-/* typedef sqlite3_uint64 u64; */
-#endif /* SQLITE_AMALGAMATION */
-
-/******************************************************************************
-** The Hash Engine
-*/
-/*
-** Macros to determine whether the machine is big or little endian,
-** and whether or not that determination is run-time or compile-time.
-**
-** For best performance, an attempt is made to guess at the byte-order
-** using C-preprocessor macros.  If that is unsuccessful, or if
-** -DSHA3_BYTEORDER=0 is set, then byte-order is determined
-** at run-time.
-*/
-#ifndef SHA3_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 SHA3_BYTEORDER    1234
-# elif defined(sparc)    || defined(__ppc__)
-#   define SHA3_BYTEORDER    4321
-# else
-#   define SHA3_BYTEORDER 0
-# endif
-#endif
-
-
-/*
-** State structure for a SHA3 hash in progress
-*/
-typedef struct SHA3Context SHA3Context;
-struct SHA3Context {
-  union {
-    u64 s[25];                /* Keccak state. 5x5 lines of 64 bits each */
-    unsigned char x[1600];    /* ... or 1600 bytes */
-  } u;
-  unsigned nRate;        /* Bytes of input accepted per Keccak iteration */
-  unsigned nLoaded;      /* Input bytes loaded into u.x[] so far this cycle */
-  unsigned ixMask;       /* Insert next input into u.x[nLoaded^ixMask]. */
-};
-
-/*
-** A single step of the Keccak mixing function for a 1600-bit state
-*/
-static void KeccakF1600Step(SHA3Context *p){
-  int i;
-  u64 b0, b1, b2, b3, b4;
-  u64 c0, c1, c2, c3, c4;
-  u64 d0, d1, d2, d3, d4;
-  static const u64 RC[] = {
-    0x0000000000000001ULL,  0x0000000000008082ULL,
-    0x800000000000808aULL,  0x8000000080008000ULL,
-    0x000000000000808bULL,  0x0000000080000001ULL,
-    0x8000000080008081ULL,  0x8000000000008009ULL,
-    0x000000000000008aULL,  0x0000000000000088ULL,
-    0x0000000080008009ULL,  0x000000008000000aULL,
-    0x000000008000808bULL,  0x800000000000008bULL,
-    0x8000000000008089ULL,  0x8000000000008003ULL,
-    0x8000000000008002ULL,  0x8000000000000080ULL,
-    0x000000000000800aULL,  0x800000008000000aULL,
-    0x8000000080008081ULL,  0x8000000000008080ULL,
-    0x0000000080000001ULL,  0x8000000080008008ULL
-  };
-# define a00 (p->u.s[0])
-# define a01 (p->u.s[1])
-# define a02 (p->u.s[2])
-# define a03 (p->u.s[3])
-# define a04 (p->u.s[4])
-# define a10 (p->u.s[5])
-# define a11 (p->u.s[6])
-# define a12 (p->u.s[7])
-# define a13 (p->u.s[8])
-# define a14 (p->u.s[9])
-# define a20 (p->u.s[10])
-# define a21 (p->u.s[11])
-# define a22 (p->u.s[12])
-# define a23 (p->u.s[13])
-# define a24 (p->u.s[14])
-# define a30 (p->u.s[15])
-# define a31 (p->u.s[16])
-# define a32 (p->u.s[17])
-# define a33 (p->u.s[18])
-# define a34 (p->u.s[19])
-# define a40 (p->u.s[20])
-# define a41 (p->u.s[21])
-# define a42 (p->u.s[22])
-# define a43 (p->u.s[23])
-# define a44 (p->u.s[24])
-# define ROL64(a,x) ((a<<x)|(a>>(64-x)))
-
-  for(i=0; i<24; i+=4){
-    c0 = a00^a10^a20^a30^a40;
-    c1 = a01^a11^a21^a31^a41;
-    c2 = a02^a12^a22^a32^a42;
-    c3 = a03^a13^a23^a33^a43;
-    c4 = a04^a14^a24^a34^a44;
-    d0 = c4^ROL64(c1, 1);
-    d1 = c0^ROL64(c2, 1);
-    d2 = c1^ROL64(c3, 1);
-    d3 = c2^ROL64(c4, 1);
-    d4 = c3^ROL64(c0, 1);
-
-    b0 = (a00^d0);
-    b1 = ROL64((a11^d1), 44);
-    b2 = ROL64((a22^d2), 43);
-    b3 = ROL64((a33^d3), 21);
-    b4 = ROL64((a44^d4), 14);
-    a00 =   b0 ^((~b1)&  b2 );
-    a00 ^= RC[i];
-    a11 =   b1 ^((~b2)&  b3 );
-    a22 =   b2 ^((~b3)&  b4 );
-    a33 =   b3 ^((~b4)&  b0 );
-    a44 =   b4 ^((~b0)&  b1 );
-
-    b2 = ROL64((a20^d0), 3);
-    b3 = ROL64((a31^d1), 45);
-    b4 = ROL64((a42^d2), 61);
-    b0 = ROL64((a03^d3), 28);
-    b1 = ROL64((a14^d4), 20);
-    a20 =   b0 ^((~b1)&  b2 );
-    a31 =   b1 ^((~b2)&  b3 );
-    a42 =   b2 ^((~b3)&  b4 );
-    a03 =   b3 ^((~b4)&  b0 );
-    a14 =   b4 ^((~b0)&  b1 );
-
-    b4 = ROL64((a40^d0), 18);
-    b0 = ROL64((a01^d1), 1);
-    b1 = ROL64((a12^d2), 6);
-    b2 = ROL64((a23^d3), 25);
-    b3 = ROL64((a34^d4), 8);
-    a40 =   b0 ^((~b1)&  b2 );
-    a01 =   b1 ^((~b2)&  b3 );
-    a12 =   b2 ^((~b3)&  b4 );
-    a23 =   b3 ^((~b4)&  b0 );
-    a34 =   b4 ^((~b0)&  b1 );
-
-    b1 = ROL64((a10^d0), 36);
-    b2 = ROL64((a21^d1), 10);
-    b3 = ROL64((a32^d2), 15);
-    b4 = ROL64((a43^d3), 56);
-    b0 = ROL64((a04^d4), 27);
-    a10 =   b0 ^((~b1)&  b2 );
-    a21 =   b1 ^((~b2)&  b3 );
-    a32 =   b2 ^((~b3)&  b4 );
-    a43 =   b3 ^((~b4)&  b0 );
-    a04 =   b4 ^((~b0)&  b1 );
-
-    b3 = ROL64((a30^d0), 41);
-    b4 = ROL64((a41^d1), 2);
-    b0 = ROL64((a02^d2), 62);
-    b1 = ROL64((a13^d3), 55);
-    b2 = ROL64((a24^d4), 39);
-    a30 =   b0 ^((~b1)&  b2 );
-    a41 =   b1 ^((~b2)&  b3 );
-    a02 =   b2 ^((~b3)&  b4 );
-    a13 =   b3 ^((~b4)&  b0 );
-    a24 =   b4 ^((~b0)&  b1 );
-
-    c0 = a00^a20^a40^a10^a30;
-    c1 = a11^a31^a01^a21^a41;
-    c2 = a22^a42^a12^a32^a02;
-    c3 = a33^a03^a23^a43^a13;
-    c4 = a44^a14^a34^a04^a24;
-    d0 = c4^ROL64(c1, 1);
-    d1 = c0^ROL64(c2, 1);
-    d2 = c1^ROL64(c3, 1);
-    d3 = c2^ROL64(c4, 1);
-    d4 = c3^ROL64(c0, 1);
-
-    b0 = (a00^d0);
-    b1 = ROL64((a31^d1), 44);
-    b2 = ROL64((a12^d2), 43);
-    b3 = ROL64((a43^d3), 21);
-    b4 = ROL64((a24^d4), 14);
-    a00 =   b0 ^((~b1)&  b2 );
-    a00 ^= RC[i+1];
-    a31 =   b1 ^((~b2)&  b3 );
-    a12 =   b2 ^((~b3)&  b4 );
-    a43 =   b3 ^((~b4)&  b0 );
-    a24 =   b4 ^((~b0)&  b1 );
-
-    b2 = ROL64((a40^d0), 3);
-    b3 = ROL64((a21^d1), 45);
-    b4 = ROL64((a02^d2), 61);
-    b0 = ROL64((a33^d3), 28);
-    b1 = ROL64((a14^d4), 20);
-    a40 =   b0 ^((~b1)&  b2 );
-    a21 =   b1 ^((~b2)&  b3 );
-    a02 =   b2 ^((~b3)&  b4 );
-    a33 =   b3 ^((~b4)&  b0 );
-    a14 =   b4 ^((~b0)&  b1 );
-
-    b4 = ROL64((a30^d0), 18);
-    b0 = ROL64((a11^d1), 1);
-    b1 = ROL64((a42^d2), 6);
-    b2 = ROL64((a23^d3), 25);
-    b3 = ROL64((a04^d4), 8);
-    a30 =   b0 ^((~b1)&  b2 );
-    a11 =   b1 ^((~b2)&  b3 );
-    a42 =   b2 ^((~b3)&  b4 );
-    a23 =   b3 ^((~b4)&  b0 );
-    a04 =   b4 ^((~b0)&  b1 );
-
-    b1 = ROL64((a20^d0), 36);
-    b2 = ROL64((a01^d1), 10);
-    b3 = ROL64((a32^d2), 15);
-    b4 = ROL64((a13^d3), 56);
-    b0 = ROL64((a44^d4), 27);
-    a20 =   b0 ^((~b1)&  b2 );
-    a01 =   b1 ^((~b2)&  b3 );
-    a32 =   b2 ^((~b3)&  b4 );
-    a13 =   b3 ^((~b4)&  b0 );
-    a44 =   b4 ^((~b0)&  b1 );
-
-    b3 = ROL64((a10^d0), 41);
-    b4 = ROL64((a41^d1), 2);
-    b0 = ROL64((a22^d2), 62);
-    b1 = ROL64((a03^d3), 55);
-    b2 = ROL64((a34^d4), 39);
-    a10 =   b0 ^((~b1)&  b2 );
-    a41 =   b1 ^((~b2)&  b3 );
-    a22 =   b2 ^((~b3)&  b4 );
-    a03 =   b3 ^((~b4)&  b0 );
-    a34 =   b4 ^((~b0)&  b1 );
-
-    c0 = a00^a40^a30^a20^a10;
-    c1 = a31^a21^a11^a01^a41;
-    c2 = a12^a02^a42^a32^a22;
-    c3 = a43^a33^a23^a13^a03;
-    c4 = a24^a14^a04^a44^a34;
-    d0 = c4^ROL64(c1, 1);
-    d1 = c0^ROL64(c2, 1);
-    d2 = c1^ROL64(c3, 1);
-    d3 = c2^ROL64(c4, 1);
-    d4 = c3^ROL64(c0, 1);
-
-    b0 = (a00^d0);
-    b1 = ROL64((a21^d1), 44);
-    b2 = ROL64((a42^d2), 43);
-    b3 = ROL64((a13^d3), 21);
-    b4 = ROL64((a34^d4), 14);
-    a00 =   b0 ^((~b1)&  b2 );
-    a00 ^= RC[i+2];
-    a21 =   b1 ^((~b2)&  b3 );
-    a42 =   b2 ^((~b3)&  b4 );
-    a13 =   b3 ^((~b4)&  b0 );
-    a34 =   b4 ^((~b0)&  b1 );
-
-    b2 = ROL64((a30^d0), 3);
-    b3 = ROL64((a01^d1), 45);
-    b4 = ROL64((a22^d2), 61);
-    b0 = ROL64((a43^d3), 28);
-    b1 = ROL64((a14^d4), 20);
-    a30 =   b0 ^((~b1)&  b2 );
-    a01 =   b1 ^((~b2)&  b3 );
-    a22 =   b2 ^((~b3)&  b4 );
-    a43 =   b3 ^((~b4)&  b0 );
-    a14 =   b4 ^((~b0)&  b1 );
-
-    b4 = ROL64((a10^d0), 18);
-    b0 = ROL64((a31^d1), 1);
-    b1 = ROL64((a02^d2), 6);
-    b2 = ROL64((a23^d3), 25);
-    b3 = ROL64((a44^d4), 8);
-    a10 =   b0 ^((~b1)&  b2 );
-    a31 =   b1 ^((~b2)&  b3 );
-    a02 =   b2 ^((~b3)&  b4 );
-    a23 =   b3 ^((~b4)&  b0 );
-    a44 =   b4 ^((~b0)&  b1 );
-
-    b1 = ROL64((a40^d0), 36);
-    b2 = ROL64((a11^d1), 10);
-    b3 = ROL64((a32^d2), 15);
-    b4 = ROL64((a03^d3), 56);
-    b0 = ROL64((a24^d4), 27);
-    a40 =   b0 ^((~b1)&  b2 );
-    a11 =   b1 ^((~b2)&  b3 );
-    a32 =   b2 ^((~b3)&  b4 );
-    a03 =   b3 ^((~b4)&  b0 );
-    a24 =   b4 ^((~b0)&  b1 );
-
-    b3 = ROL64((a20^d0), 41);
-    b4 = ROL64((a41^d1), 2);
-    b0 = ROL64((a12^d2), 62);
-    b1 = ROL64((a33^d3), 55);
-    b2 = ROL64((a04^d4), 39);
-    a20 =   b0 ^((~b1)&  b2 );
-    a41 =   b1 ^((~b2)&  b3 );
-    a12 =   b2 ^((~b3)&  b4 );
-    a33 =   b3 ^((~b4)&  b0 );
-    a04 =   b4 ^((~b0)&  b1 );
-
-    c0 = a00^a30^a10^a40^a20;
-    c1 = a21^a01^a31^a11^a41;
-    c2 = a42^a22^a02^a32^a12;
-    c3 = a13^a43^a23^a03^a33;
-    c4 = a34^a14^a44^a24^a04;
-    d0 = c4^ROL64(c1, 1);
-    d1 = c0^ROL64(c2, 1);
-    d2 = c1^ROL64(c3, 1);
-    d3 = c2^ROL64(c4, 1);
-    d4 = c3^ROL64(c0, 1);
-
-    b0 = (a00^d0);
-    b1 = ROL64((a01^d1), 44);
-    b2 = ROL64((a02^d2), 43);
-    b3 = ROL64((a03^d3), 21);
-    b4 = ROL64((a04^d4), 14);
-    a00 =   b0 ^((~b1)&  b2 );
-    a00 ^= RC[i+3];
-    a01 =   b1 ^((~b2)&  b3 );
-    a02 =   b2 ^((~b3)&  b4 );
-    a03 =   b3 ^((~b4)&  b0 );
-    a04 =   b4 ^((~b0)&  b1 );
-
-    b2 = ROL64((a10^d0), 3);
-    b3 = ROL64((a11^d1), 45);
-    b4 = ROL64((a12^d2), 61);
-    b0 = ROL64((a13^d3), 28);
-    b1 = ROL64((a14^d4), 20);
-    a10 =   b0 ^((~b1)&  b2 );
-    a11 =   b1 ^((~b2)&  b3 );
-    a12 =   b2 ^((~b3)&  b4 );
-    a13 =   b3 ^((~b4)&  b0 );
-    a14 =   b4 ^((~b0)&  b1 );
-
-    b4 = ROL64((a20^d0), 18);
-    b0 = ROL64((a21^d1), 1);
-    b1 = ROL64((a22^d2), 6);
-    b2 = ROL64((a23^d3), 25);
-    b3 = ROL64((a24^d4), 8);
-    a20 =   b0 ^((~b1)&  b2 );
-    a21 =   b1 ^((~b2)&  b3 );
-    a22 =   b2 ^((~b3)&  b4 );
-    a23 =   b3 ^((~b4)&  b0 );
-    a24 =   b4 ^((~b0)&  b1 );
-
-    b1 = ROL64((a30^d0), 36);
-    b2 = ROL64((a31^d1), 10);
-    b3 = ROL64((a32^d2), 15);
-    b4 = ROL64((a33^d3), 56);
-    b0 = ROL64((a34^d4), 27);
-    a30 =   b0 ^((~b1)&  b2 );
-    a31 =   b1 ^((~b2)&  b3 );
-    a32 =   b2 ^((~b3)&  b4 );
-    a33 =   b3 ^((~b4)&  b0 );
-    a34 =   b4 ^((~b0)&  b1 );
-
-    b3 = ROL64((a40^d0), 41);
-    b4 = ROL64((a41^d1), 2);
-    b0 = ROL64((a42^d2), 62);
-    b1 = ROL64((a43^d3), 55);
-    b2 = ROL64((a44^d4), 39);
-    a40 =   b0 ^((~b1)&  b2 );
-    a41 =   b1 ^((~b2)&  b3 );
-    a42 =   b2 ^((~b3)&  b4 );
-    a43 =   b3 ^((~b4)&  b0 );
-    a44 =   b4 ^((~b0)&  b1 );
-  }
-}
-
-/*
-** Initialize a new hash.  iSize determines the size of the hash
-** in bits and should be one of 224, 256, 384, or 512.  Or iSize
-** can be zero to use the default hash size of 256 bits.
-*/
-static void SHA3Init(SHA3Context *p, int iSize){
-  memset(p, 0, sizeof(*p));
-  if( iSize>=128 && iSize<=512 ){
-    p->nRate = (1600 - ((iSize + 31)&~31)*2)/8;
-  }else{
-    p->nRate = (1600 - 2*256)/8;
-  }
-#if SHA3_BYTEORDER==1234
-  /* Known to be little-endian at compile-time. No-op */
-#elif SHA3_BYTEORDER==4321
-  p->ixMask = 7;  /* Big-endian */
-#else
-  {
-    static unsigned int one = 1;
-    if( 1==*(unsigned char*)&one ){
-      /* Little endian.  No byte swapping. */
-      p->ixMask = 0;
-    }else{
-      /* Big endian.  Byte swap. */
-      p->ixMask = 7;
-    }
-  }
-#endif
-}
-
-/*
-** Make consecutive calls to the SHA3Update function to add new content
-** to the hash
-*/
-static void SHA3Update(
-  SHA3Context *p,
-  const unsigned char *aData,
-  unsigned int nData
-){
-  unsigned int i = 0;
-  if( aData==0 ) return;
-#if SHA3_BYTEORDER==1234
-  if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){
-    for(; i+7<nData; i+=8){
-      p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i];
-      p->nLoaded += 8;
-      if( p->nLoaded>=p->nRate ){
-        KeccakF1600Step(p);
-        p->nLoaded = 0;
-      }
-    }
-  }
-#endif
-  for(; i<nData; i++){
-#if SHA3_BYTEORDER==1234
-    p->u.x[p->nLoaded] ^= aData[i];
-#elif SHA3_BYTEORDER==4321
-    p->u.x[p->nLoaded^0x07] ^= aData[i];
-#else
-    p->u.x[p->nLoaded^p->ixMask] ^= aData[i];
-#endif
-    p->nLoaded++;
-    if( p->nLoaded==p->nRate ){
-      KeccakF1600Step(p);
-      p->nLoaded = 0;
-    }
-  }
-}
-
-/*
-** After all content has been added, invoke SHA3Final() to compute
-** the final hash.  The function returns a pointer to the binary
-** hash value.
-*/
-static unsigned char *SHA3Final(SHA3Context *p){
-  unsigned int i;
-  if( p->nLoaded==p->nRate-1 ){
-    const unsigned char c1 = 0x86;
-    SHA3Update(p, &c1, 1);
-  }else{
-    const unsigned char c2 = 0x06;
-    const unsigned char c3 = 0x80;
-    SHA3Update(p, &c2, 1);
-    p->nLoaded = p->nRate - 1;
-    SHA3Update(p, &c3, 1);
-  }
-  for(i=0; i<p->nRate; i++){
-    p->u.x[i+p->nRate] = p->u.x[i^p->ixMask];
-  }
-  return &p->u.x[p->nRate];
-}
-/* End of the hashing logic
-*****************************************************************************/
-
-/*
-** Implementation of the sha3(X,SIZE) function.
-**
-** Return a BLOB which is the SIZE-bit SHA3 hash of X.  The default
-** size is 256.  If X is a BLOB, it is hashed as is.  
-** For all other non-NULL types of input, X is converted into a UTF-8 string
-** and the string is hashed without the trailing 0x00 terminator.  The hash
-** of a NULL value is NULL.
-*/
-static void sha3Func(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  SHA3Context cx;
-  int eType = sqlite3_value_type(argv[0]);
-  int nByte = sqlite3_value_bytes(argv[0]);
-  int iSize;
-  if( argc==1 ){
-    iSize = 256;
-  }else{
-    iSize = sqlite3_value_int(argv[1]);
-    if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
-      sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
-                                    "384 512", -1);
-      return;
-    }
-  }
-  if( eType==SQLITE_NULL ) return;
-  SHA3Init(&cx, iSize);
-  if( eType==SQLITE_BLOB ){
-    SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte);
-  }else{
-    SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte);
-  }
-  sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
-}
-
-/* Compute a string using sqlite3_vsnprintf() with a maximum length
-** of 50 bytes and add it to the hash.
-*/
-static void sha3_step_vformat(
-  SHA3Context *p,                 /* Add content to this context */
-  const char *zFormat,
-  ...
-){
-  va_list ap;
-  int n;
-  char zBuf[50];
-  va_start(ap, zFormat);
-  sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap);
-  va_end(ap);
-  n = (int)strlen(zBuf);
-  SHA3Update(p, (unsigned char*)zBuf, n);
-}
-
-/*
-** Implementation of the sha3_query(SQL,SIZE) function.
-**
-** This function compiles and runs the SQL statement(s) given in the
-** argument. The results are hashed using a SIZE-bit SHA3.  The default
-** size is 256.
-**
-** The format of the byte stream that is hashed is summarized as follows:
-**
-**       S<n>:<sql>
-**       R
-**       N
-**       I<int>
-**       F<ieee-float>
-**       B<size>:<bytes>
-**       T<size>:<text>
-**
-** <sql> is the original SQL text for each statement run and <n> is
-** the size of that text.  The SQL text is UTF-8.  A single R character
-** occurs before the start of each row.  N means a NULL value.
-** I mean an 8-byte little-endian integer <int>.  F is a floating point
-** number with an 8-byte little-endian IEEE floating point value <ieee-float>.
-** B means blobs of <size> bytes.  T means text rendered as <size>
-** bytes of UTF-8.  The <n> and <size> values are expressed as an ASCII
-** text integers.
-**
-** For each SQL statement in the X input, there is one S segment.  Each
-** S segment is followed by zero or more R segments, one for each row in the
-** result set.  After each R, there are one or more N, I, F, B, or T segments,
-** one for each column in the result set.  Segments are concatentated directly
-** with no delimiters of any kind.
-*/
-static void sha3QueryFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  sqlite3 *db = sqlite3_context_db_handle(context);
-  const char *zSql = (const char*)sqlite3_value_text(argv[0]);
-  sqlite3_stmt *pStmt = 0;
-  int nCol;                   /* Number of columns in the result set */
-  int i;                      /* Loop counter */
-  int rc;
-  int n;
-  const char *z;
-  SHA3Context cx;
-  int iSize;
-
-  if( argc==1 ){
-    iSize = 256;
-  }else{
-    iSize = sqlite3_value_int(argv[1]);
-    if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){
-      sqlite3_result_error(context, "SHA3 size should be one of: 224 256 "
-                                    "384 512", -1);
-      return;
-    }
-  }
-  if( zSql==0 ) return;
-  SHA3Init(&cx, iSize);
-  while( zSql[0] ){
-    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql);
-    if( rc ){
-      char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s",
-                                   zSql, sqlite3_errmsg(db));
-      sqlite3_finalize(pStmt);
-      sqlite3_result_error(context, zMsg, -1);
-      sqlite3_free(zMsg);
-      return;
-    }
-    if( !sqlite3_stmt_readonly(pStmt) ){
-      char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt));
-      sqlite3_finalize(pStmt);
-      sqlite3_result_error(context, zMsg, -1);
-      sqlite3_free(zMsg);
-      return;
-    }
-    nCol = sqlite3_column_count(pStmt);
-    z = sqlite3_sql(pStmt);
-    if( z ){
-      n = (int)strlen(z);
-      sha3_step_vformat(&cx,"S%d:",n);
-      SHA3Update(&cx,(unsigned char*)z,n);
-    }
-
-    /* Compute a hash over the result of the query */
-    while( SQLITE_ROW==sqlite3_step(pStmt) ){
-      SHA3Update(&cx,(const unsigned char*)"R",1);
-      for(i=0; i<nCol; i++){
-        switch( sqlite3_column_type(pStmt,i) ){
-          case SQLITE_NULL: {
-            SHA3Update(&cx, (const unsigned char*)"N",1);
-            break;
-          }
-          case SQLITE_INTEGER: {
-            sqlite3_uint64 u;
-            int j;
-            unsigned char x[9];
-            sqlite3_int64 v = sqlite3_column_int64(pStmt,i);
-            memcpy(&u, &v, 8);
-            for(j=8; j>=1; j--){
-              x[j] = u & 0xff;
-              u >>= 8;
-            }
-            x[0] = 'I';
-            SHA3Update(&cx, x, 9);
-            break;
-          }
-          case SQLITE_FLOAT: {
-            sqlite3_uint64 u;
-            int j;
-            unsigned char x[9];
-            double r = sqlite3_column_double(pStmt,i);
-            memcpy(&u, &r, 8);
-            for(j=8; j>=1; j--){
-              x[j] = u & 0xff;
-              u >>= 8;
-            }
-            x[0] = 'F';
-            SHA3Update(&cx,x,9);
-            break;
-          }
-          case SQLITE_TEXT: {
-            int n2 = sqlite3_column_bytes(pStmt, i);
-            const unsigned char *z2 = sqlite3_column_text(pStmt, i);
-            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);
-            sha3_step_vformat(&cx,"B%d:",n2);
-            SHA3Update(&cx, z2, n2);
-            break;
-          }
-        }
-      }
-    }
-    sqlite3_finalize(pStmt);
-  }
-  sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT);
-}
-
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_shathree_init(
-  sqlite3 *db,
-  char **pzErrMsg,
-  const sqlite3_api_routines *pApi
-){
-  int rc = SQLITE_OK;
-  SQLITE_EXTENSION_INIT2(pApi);
-  (void)pzErrMsg;  /* Unused parameter */
-  rc = sqlite3_create_function(db, "sha3", 1,
-                      SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
-                      0, sha3Func, 0, 0);
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_create_function(db, "sha3", 2,
-                      SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC,
-                      0, sha3Func, 0, 0);
-  }
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_create_function(db, "sha3_query", 1,
-                      SQLITE_UTF8 | SQLITE_DIRECTONLY,
-                      0, sha3QueryFunc, 0, 0);
-  }
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_create_function(db, "sha3_query", 2,
-                      SQLITE_UTF8 | SQLITE_DIRECTONLY,
-                      0, sha3QueryFunc, 0, 0);
-  }
-  return rc;
-}
-
-/************************* End ../ext/misc/shathree.c ********************/
-/************************* Begin ../ext/misc/uint.c ******************/
-/*
-** 2020-04-14
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This SQLite extension implements the UINT collating sequence.
-**
-** UINT works like BINARY for text, except that embedded strings
-** of digits compare in numeric order.
-**
-**     *   Leading zeros are handled properly, in the sense that
-**         they do not mess of the maginitude comparison of embedded
-**         strings of digits.  "x00123y" is equal to "x123y".
-**
-**     *   Only unsigned integers are recognized.  Plus and minus
-**         signs are ignored.  Decimal points and exponential notation
-**         are ignored.
-**
-**     *   Embedded integers can be of arbitrary length.  Comparison
-**         is *not* limited integers that can be expressed as a
-**         64-bit machine integer.
-*/
-/* #include "sqlite3ext.h" */
-SQLITE_EXTENSION_INIT1
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-
-/*
-** Compare text in lexicographic order, except strings of digits
-** compare in numeric order.
-*/
-static int uintCollFunc(
-  void *notUsed,
-  int nKey1, const void *pKey1,
-  int nKey2, const void *pKey2
-){
-  const unsigned char *zA = (const unsigned char*)pKey1;
-  const unsigned char *zB = (const unsigned char*)pKey2;
-  int i=0, j=0, x;
-  (void)notUsed;
-  while( i<nKey1 && j<nKey2 ){
-    x = zA[i] - zB[j];
-    if( isdigit(zA[i]) ){
-      int k;
-      if( !isdigit(zB[j]) ) return x;
-      while( i<nKey1 && zA[i]=='0' ){ i++; }
-      while( j<nKey2 && zB[j]=='0' ){ j++; }
-      k = 0;
-      while( i+k<nKey1 && isdigit(zA[i+k])
-             && j+k<nKey2 && isdigit(zB[j+k]) ){
-        k++;
-      }
-      if( i+k<nKey1 && isdigit(zA[i+k]) ){
-        return +1;
-      }else if( j+k<nKey2 && isdigit(zB[j+k]) ){
-        return -1;
-      }else{
-        x = memcmp(zA+i, zB+j, k);
-        if( x ) return x;
-        i += k;
-        j += k;
-      }
-    }else if( x ){
-      return x;
-    }else{
-      i++;
-      j++;
-    }
-  }
-  return (nKey1 - i) - (nKey2 - j);
-}
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_uint_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
-  SQLITE_EXTENSION_INIT2(pApi);
-  (void)pzErrMsg;  /* Unused parameter */
-  return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc);
-}
-
-/************************* End ../ext/misc/uint.c ********************/
-/************************* Begin ../ext/misc/decimal.c ******************/
-/*
-** 2020-06-22
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** Routines to implement arbitrary-precision decimal math.
-**
-** The focus here is on simplicity and correctness, not performance.
-*/
-/* #include "sqlite3ext.h" */
-SQLITE_EXTENSION_INIT1
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-/* Mark a function parameter as unused, to suppress nuisance compiler
-** warnings. */
-#ifndef UNUSED_PARAMETER
-# define UNUSED_PARAMETER(X)  (void)(X)
-#endif
-
-
-/* A decimal object */
-typedef struct Decimal Decimal;
-struct Decimal {
-  char sign;        /* 0 for positive, 1 for negative */
-  char oom;         /* True if an OOM is encountered */
-  char isNull;      /* True if holds a NULL rather than a number */
-  char isInit;      /* True upon initialization */
-  int nDigit;       /* Total number of digits */
-  int nFrac;        /* Number of digits to the right of the decimal point */
-  signed char *a;   /* Array of digits.  Most significant first. */
-};
-
-/*
-** Release memory held by a Decimal, but do not free the object itself.
-*/
-static void decimal_clear(Decimal *p){
-  sqlite3_free(p->a);
-}
-
-/*
-** Destroy a Decimal object
-*/
-static void decimal_free(Decimal *p){
-  if( p ){
-    decimal_clear(p);
-    sqlite3_free(p);
-  }
-}
-
-/*
-** Allocate a new Decimal object.  Initialize it to the number given
-** by the input string.
-*/
-static Decimal *decimal_new(
-  sqlite3_context *pCtx,
-  sqlite3_value *pIn,
-  int nAlt,
-  const unsigned char *zAlt
-){
-  Decimal *p;
-  int n, i;
-  const unsigned char *zIn;
-  int iExp = 0;
-  p = sqlite3_malloc( sizeof(*p) );
-  if( p==0 ) goto new_no_mem;
-  p->sign = 0;
-  p->oom = 0;
-  p->isInit = 1;
-  p->isNull = 0;
-  p->nDigit = 0;
-  p->nFrac = 0;
-  if( zAlt ){
-    n = nAlt,
-    zIn = zAlt;
-  }else{
-    if( sqlite3_value_type(pIn)==SQLITE_NULL ){
-      p->a = 0;
-      p->isNull = 1;
-      return p;
-    }
-    n = sqlite3_value_bytes(pIn);
-    zIn = sqlite3_value_text(pIn);
-  }
-  p->a = sqlite3_malloc64( n+1 );
-  if( p->a==0 ) goto new_no_mem;
-  for(i=0; isspace(zIn[i]); i++){}
-  if( zIn[i]=='-' ){
-    p->sign = 1;
-    i++;
-  }else if( zIn[i]=='+' ){
-    i++;
-  }
-  while( i<n && zIn[i]=='0' ) i++;
-  while( i<n ){
-    char c = zIn[i];
-    if( c>='0' && c<='9' ){
-      p->a[p->nDigit++] = c - '0';
-    }else if( c=='.' ){
-      p->nFrac = p->nDigit + 1;
-    }else if( c=='e' || c=='E' ){
-      int j = i+1;
-      int neg = 0;
-      if( j>=n ) break;
-      if( zIn[j]=='-' ){
-        neg = 1;
-        j++;
-      }else if( zIn[j]=='+' ){
-        j++;
-      }
-      while( j<n && iExp<1000000 ){
-        if( zIn[j]>='0' && zIn[j]<='9' ){
-          iExp = iExp*10 + zIn[j] - '0';
-        }
-        j++;
-      }
-      if( neg ) iExp = -iExp;
-      break;
-    }
-    i++;
-  }
-  if( p->nFrac ){
-    p->nFrac = p->nDigit - (p->nFrac - 1);
-  }
-  if( iExp>0 ){
-    if( p->nFrac>0 ){
-      if( iExp<=p->nFrac ){
-        p->nFrac -= iExp;
-        iExp = 0;
-      }else{
-        iExp -= p->nFrac;
-        p->nFrac = 0;
-      }
-    }
-    if( iExp>0 ){   
-      p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
-      if( p->a==0 ) goto new_no_mem;
-      memset(p->a+p->nDigit, 0, iExp);
-      p->nDigit += iExp;
-    }
-  }else if( iExp<0 ){
-    int nExtra;
-    iExp = -iExp;
-    nExtra = p->nDigit - p->nFrac - 1;
-    if( nExtra ){
-      if( nExtra>=iExp ){
-        p->nFrac += iExp;
-        iExp  = 0;
-      }else{
-        iExp -= nExtra;
-        p->nFrac = p->nDigit - 1;
-      }
-    }
-    if( iExp>0 ){
-      p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 );
-      if( p->a==0 ) goto new_no_mem;
-      memmove(p->a+iExp, p->a, p->nDigit);
-      memset(p->a, 0, iExp);
-      p->nDigit += iExp;
-      p->nFrac += iExp;
-    }
-  }
-  return p;
-
-new_no_mem:
-  if( pCtx ) sqlite3_result_error_nomem(pCtx);
-  sqlite3_free(p);
-  return 0;
-}
-
-/*
-** Make the given Decimal the result.
-*/
-static void decimal_result(sqlite3_context *pCtx, Decimal *p){
-  char *z;
-  int i, j;
-  int n;
-  if( p==0 || p->oom ){
-    sqlite3_result_error_nomem(pCtx);
-    return;
-  }
-  if( p->isNull ){
-    sqlite3_result_null(pCtx);
-    return;
-  }
-  z = sqlite3_malloc( p->nDigit+4 );
-  if( z==0 ){
-    sqlite3_result_error_nomem(pCtx);
-    return;
-  }
-  i = 0;
-  if( p->nDigit==0 || (p->nDigit==1 && p->a[0]==0) ){
-    p->sign = 0;
-  }
-  if( p->sign ){
-    z[0] = '-';
-    i = 1;
-  }
-  n = p->nDigit - p->nFrac;
-  if( n<=0 ){
-    z[i++] = '0';
-  }
-  j = 0;
-  while( n>1 && p->a[j]==0 ){
-    j++;
-    n--;
-  }
-  while( n>0  ){
-    z[i++] = p->a[j] + '0';
-    j++;
-    n--;
-  }
-  if( p->nFrac ){
-    z[i++] = '.';
-    do{
-      z[i++] = p->a[j] + '0';
-      j++;
-    }while( j<p->nDigit );
-  }
-  z[i] = 0;
-  sqlite3_result_text(pCtx, z, i, sqlite3_free);
-}
-
-/*
-** SQL Function:   decimal(X)
-**
-** Convert input X into decimal and then back into text
-*/
-static void decimalFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  Decimal *p = decimal_new(context, argv[0], 0, 0);
-  UNUSED_PARAMETER(argc);
-  decimal_result(context, p);
-  decimal_free(p);
-}
-
-/*
-** Compare to Decimal objects.  Return negative, 0, or positive if the
-** first object is less than, equal to, or greater than the second.
-**
-** Preconditions for this routine:
-**
-**    pA!=0
-**    pA->isNull==0
-**    pB!=0
-**    pB->isNull==0
-*/
-static int decimal_cmp(const Decimal *pA, const Decimal *pB){
-  int nASig, nBSig, rc, n;
-  if( pA->sign!=pB->sign ){
-    return pA->sign ? -1 : +1;
-  }
-  if( pA->sign ){
-    const Decimal *pTemp = pA;
-    pA = pB;
-    pB = pTemp;
-  }
-  nASig = pA->nDigit - pA->nFrac;
-  nBSig = pB->nDigit - pB->nFrac;
-  if( nASig!=nBSig ){
-    return nASig - nBSig;
-  }
-  n = pA->nDigit;
-  if( n>pB->nDigit ) n = pB->nDigit;
-  rc = memcmp(pA->a, pB->a, n);
-  if( rc==0 ){
-    rc = pA->nDigit - pB->nDigit;
-  }
-  return rc;
-}
-
-/*
-** SQL Function:   decimal_cmp(X, Y)
-**
-** Return negative, zero, or positive if X is less then, equal to, or
-** greater than Y.
-*/
-static void decimalCmpFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  Decimal *pA = 0, *pB = 0;
-  int rc;
-
-  UNUSED_PARAMETER(argc);
-  pA = decimal_new(context, argv[0], 0, 0);
-  if( pA==0 || pA->isNull ) goto cmp_done;
-  pB = decimal_new(context, argv[1], 0, 0);
-  if( pB==0 || pB->isNull ) goto cmp_done;
-  rc = decimal_cmp(pA, pB);
-  if( rc<0 ) rc = -1;
-  else if( rc>0 ) rc = +1;
-  sqlite3_result_int(context, rc);
-cmp_done:
-  decimal_free(pA);
-  decimal_free(pB);
-}
-
-/*
-** Expand the Decimal so that it has a least nDigit digits and nFrac
-** digits to the right of the decimal point.
-*/
-static void decimal_expand(Decimal *p, int nDigit, int nFrac){
-  int nAddSig;
-  int nAddFrac;
-  if( p==0 ) return;
-  nAddFrac = nFrac - p->nFrac;
-  nAddSig = (nDigit - p->nDigit) - nAddFrac;
-  if( nAddFrac==0 && nAddSig==0 ) return;
-  p->a = sqlite3_realloc64(p->a, nDigit+1);
-  if( p->a==0 ){
-    p->oom = 1;
-    return;
-  }
-  if( nAddSig ){
-    memmove(p->a+nAddSig, p->a, p->nDigit);
-    memset(p->a, 0, nAddSig);
-    p->nDigit += nAddSig;
-  }
-  if( nAddFrac ){
-    memset(p->a+p->nDigit, 0, nAddFrac);
-    p->nDigit += nAddFrac;
-    p->nFrac += nAddFrac;
-  }
-}
-
-/*
-** Add the value pB into pA.
-**
-** Both pA and pB might become denormalized by this routine.
-*/
-static void decimal_add(Decimal *pA, Decimal *pB){
-  int nSig, nFrac, nDigit;
-  int i, rc;
-  if( pA==0 ){
-    return;
-  }
-  if( pA->oom || pB==0 || pB->oom ){
-    pA->oom = 1;
-    return;
-  }
-  if( pA->isNull || pB->isNull ){
-    pA->isNull = 1;
-    return;
-  }
-  nSig = pA->nDigit - pA->nFrac;
-  if( nSig && pA->a[0]==0 ) nSig--;
-  if( nSig<pB->nDigit-pB->nFrac ){
-    nSig = pB->nDigit - pB->nFrac;
-  }
-  nFrac = pA->nFrac;
-  if( nFrac<pB->nFrac ) nFrac = pB->nFrac;
-  nDigit = nSig + nFrac + 1;
-  decimal_expand(pA, nDigit, nFrac);
-  decimal_expand(pB, nDigit, nFrac);
-  if( pA->oom || pB->oom ){
-    pA->oom = 1;
-  }else{
-    if( pA->sign==pB->sign ){
-      int carry = 0;
-      for(i=nDigit-1; i>=0; i--){
-        int x = pA->a[i] + pB->a[i] + carry;
-        if( x>=10 ){
-          carry = 1;
-          pA->a[i] = x - 10;
-        }else{
-          carry = 0;
-          pA->a[i] = x;
-        }
-      }
-    }else{
-      signed char *aA, *aB;
-      int borrow = 0;
-      rc = memcmp(pA->a, pB->a, nDigit);
-      if( rc<0 ){
-        aA = pB->a;
-        aB = pA->a;
-        pA->sign = !pA->sign;
-      }else{
-        aA = pA->a;
-        aB = pB->a;
-      }
-      for(i=nDigit-1; i>=0; i--){
-        int x = aA[i] - aB[i] - borrow;
-        if( x<0 ){
-          pA->a[i] = x+10;
-          borrow = 1;
-        }else{
-          pA->a[i] = x;
-          borrow = 0;
-        }
-      }
-    }
-  }
-}
-
-/*
-** Compare text in decimal order.
-*/
-static int decimalCollFunc(
-  void *notUsed,
-  int nKey1, const void *pKey1,
-  int nKey2, const void *pKey2
-){
-  const unsigned char *zA = (const unsigned char*)pKey1;
-  const unsigned char *zB = (const unsigned char*)pKey2;
-  Decimal *pA = decimal_new(0, 0, nKey1, zA);
-  Decimal *pB = decimal_new(0, 0, nKey2, zB);
-  int rc;
-  UNUSED_PARAMETER(notUsed);
-  if( pA==0 || pB==0 ){
-    rc = 0;
-  }else{
-    rc = decimal_cmp(pA, pB);
-  }
-  decimal_free(pA);
-  decimal_free(pB);
-  return rc;
-}
-
-
-/*
-** SQL Function:   decimal_add(X, Y)
-**                 decimal_sub(X, Y)
-**
-** Return the sum or difference of X and Y.
-*/
-static void decimalAddFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  Decimal *pA = decimal_new(context, argv[0], 0, 0);
-  Decimal *pB = decimal_new(context, argv[1], 0, 0);
-  UNUSED_PARAMETER(argc);
-  decimal_add(pA, pB);
-  decimal_result(context, pA);
-  decimal_free(pA);
-  decimal_free(pB);
-}
-static void decimalSubFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  Decimal *pA = decimal_new(context, argv[0], 0, 0);
-  Decimal *pB = decimal_new(context, argv[1], 0, 0);
-  UNUSED_PARAMETER(argc);
-  if( pB ){
-    pB->sign = !pB->sign;
-    decimal_add(pA, pB);
-    decimal_result(context, pA);
-  }
-  decimal_free(pA);
-  decimal_free(pB);
-}
-
-/* Aggregate funcion:   decimal_sum(X)
-**
-** Works like sum() except that it uses decimal arithmetic for unlimited
-** precision.
-*/
-static void decimalSumStep(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  Decimal *p;
-  Decimal *pArg;
-  UNUSED_PARAMETER(argc);
-  p = sqlite3_aggregate_context(context, sizeof(*p));
-  if( p==0 ) return;
-  if( !p->isInit ){
-    p->isInit = 1;
-    p->a = sqlite3_malloc(2);
-    if( p->a==0 ){
-      p->oom = 1;
-    }else{
-      p->a[0] = 0;
-    }
-    p->nDigit = 1;
-    p->nFrac = 0;
-  }
-  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
-  pArg = decimal_new(context, argv[0], 0, 0);
-  decimal_add(p, pArg);
-  decimal_free(pArg);
-}
-static void decimalSumInverse(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  Decimal *p;
-  Decimal *pArg;
-  UNUSED_PARAMETER(argc);
-  p = sqlite3_aggregate_context(context, sizeof(*p));
-  if( p==0 ) return;
-  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
-  pArg = decimal_new(context, argv[0], 0, 0);
-  if( pArg ) pArg->sign = !pArg->sign;
-  decimal_add(p, pArg);
-  decimal_free(pArg);
-}
-static void decimalSumValue(sqlite3_context *context){
-  Decimal *p = sqlite3_aggregate_context(context, 0);
-  if( p==0 ) return;
-  decimal_result(context, p);
-}
-static void decimalSumFinalize(sqlite3_context *context){
-  Decimal *p = sqlite3_aggregate_context(context, 0);
-  if( p==0 ) return;
-  decimal_result(context, p);
-  decimal_clear(p);
-}
-
-/*
-** SQL Function:   decimal_mul(X, Y)
-**
-** Return the product of X and Y.
-**
-** All significant digits after the decimal point are retained.
-** Trailing zeros after the decimal point are omitted as long as
-** the number of digits after the decimal point is no less than
-** either the number of digits in either input.
-*/
-static void decimalMulFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  Decimal *pA = decimal_new(context, argv[0], 0, 0);
-  Decimal *pB = decimal_new(context, argv[1], 0, 0);
-  signed char *acc = 0;
-  int i, j, k;
-  int minFrac;
-  UNUSED_PARAMETER(argc);
-  if( pA==0 || pA->oom || pA->isNull
-   || pB==0 || pB->oom || pB->isNull 
-  ){
-    goto mul_end;
-  }
-  acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 );
-  if( acc==0 ){
-    sqlite3_result_error_nomem(context);
-    goto mul_end;
-  }
-  memset(acc, 0, pA->nDigit + pB->nDigit + 2);
-  minFrac = pA->nFrac;
-  if( pB->nFrac<minFrac ) minFrac = pB->nFrac;
-  for(i=pA->nDigit-1; i>=0; i--){
-    signed char f = pA->a[i];
-    int carry = 0, x;
-    for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){
-      x = acc[k] + f*pB->a[j] + carry;
-      acc[k] = x%10;
-      carry = x/10;
-    }
-    x = acc[k] + carry;
-    acc[k] = x%10;
-    acc[k-1] += x/10;
-  }
-  sqlite3_free(pA->a);
-  pA->a = acc;
-  acc = 0;
-  pA->nDigit += pB->nDigit + 2;
-  pA->nFrac += pB->nFrac;
-  pA->sign ^= pB->sign;
-  while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){
-    pA->nFrac--;
-    pA->nDigit--;
-  }
-  decimal_result(context, pA);
-
-mul_end:
-  sqlite3_free(acc);
-  decimal_free(pA);
-  decimal_free(pB);
-}
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_decimal_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
-  int rc = SQLITE_OK;
-  static const struct {
-    const char *zFuncName;
-    int nArg;
-    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
-  } aFunc[] = {
-    { "decimal",       1,   decimalFunc        },
-    { "decimal_cmp",   2,   decimalCmpFunc     },
-    { "decimal_add",   2,   decimalAddFunc     },
-    { "decimal_sub",   2,   decimalSubFunc     },
-    { "decimal_mul",   2,   decimalMulFunc     },
-  };
-  unsigned int i;
-  (void)pzErrMsg;  /* Unused parameter */
-
-  SQLITE_EXTENSION_INIT2(pApi);
-
-  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);
-  }
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_create_window_function(db, "decimal_sum", 1,
-                   SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0,
-                   decimalSumStep, decimalSumFinalize,
-                   decimalSumValue, decimalSumInverse, 0);
-  }
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_create_collation(db, "decimal", SQLITE_UTF8,
-                                  0, decimalCollFunc);
-  }
-  return rc;
-}
-
-/************************* End ../ext/misc/decimal.c ********************/
-#undef sqlite3_base_init
-#define sqlite3_base_init sqlite3_base64_init
-/************************* Begin ../ext/misc/base64.c ******************/
-/*
-** 2022-11-18
-**
-** 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 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 <assert.h>
-
-/* #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
-
-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 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;
-      }
-    }
-    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;
-    }
-    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)(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;
-    }
-    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)(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);
-}
-
-/*
-** Establish linkage to running SQLite library.
-*/
-#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;
-    }
-  }
-  return pOut;
-}
-
-#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);
-    }
-    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_base_init
-#else
-static int sqlite3_base85_init
-#endif
-(sqlite3 *db, char **pzErr, const sqlite3_api_routines *pApi){
-  SQLITE_EXTENSION_INIT2(pApi);
-  (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;
-}
-
-#endif
-
-/************************* End ../ext/misc/base85.c ********************/
-/************************* Begin ../ext/misc/ieee754.c ******************/
-/*
-** 2013-04-17
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This SQLite extension implements functions for the exact display
-** and input of IEEE754 Binary64 floating-point numbers.
-**
-**   ieee754(X)
-**   ieee754(Y,Z)
-**
-** In the first form, the value X should be a floating-point number.
-** The function will return a string of the form 'ieee754(Y,Z)' where
-** Y and Z are integers such that X==Y*pow(2,Z).
-**
-** In the second form, Y and Z are integers which are the mantissa and
-** base-2 exponent of a new floating point number.  The function returns
-** a floating-point value equal to Y*pow(2,Z).
-**
-** Examples:
-**
-**     ieee754(2.0)             ->     'ieee754(2,0)'
-**     ieee754(45.25)           ->     'ieee754(181,-2)'
-**     ieee754(2, 0)            ->     2.0
-**     ieee754(181, -2)         ->     45.25
-**
-** Two additional functions break apart the one-argument ieee754()
-** result into separate integer values:
-**
-**     ieee754_mantissa(45.25)  ->     181
-**     ieee754_exponent(45.25)  ->     -2
-**
-** These functions convert binary64 numbers into blobs and back again.
-**
-**     ieee754_from_blob(x'3ff0000000000000')  ->  1.0
-**     ieee754_to_blob(1.0)                    ->  x'3ff0000000000000'
-**
-** In all single-argument functions, if the argument is an 8-byte blob
-** then that blob is interpreted as a big-endian binary64 value.
-**
-**
-** EXACT DECIMAL REPRESENTATION OF BINARY64 VALUES
-** -----------------------------------------------
-**
-** This extension in combination with the separate 'decimal' extension
-** can be used to compute the exact decimal representation of binary64
-** values.  To begin, first compute a table of exponent values:
-**
-**    CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT);
-**    WITH RECURSIVE c(x,v) AS (
-**      VALUES(0,'1')
-**      UNION ALL
-**      SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1<=971
-**    ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
-**    WITH RECURSIVE c(x,v) AS (
-**      VALUES(-1,'0.5')
-**      UNION ALL
-**      SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1>=-1075
-**    ) INSERT INTO pow2(x,v) SELECT x, v FROM c;
-**
-** Then, to compute the exact decimal representation of a floating
-** point value (the value 47.49 is used in the example) do:
-**
-**    WITH c(n) AS (VALUES(47.49))
-**          ---------------^^^^^---- Replace with whatever you want
-**    SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v)
-**      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);
-**
-** Here is a query to show various boundry values for the binary64
-** number format:
-**
-**    WITH c(name,bin) AS (VALUES
-**       ('minimum positive value',        x'0000000000000001'),
-**       ('maximum subnormal value',       x'000fffffffffffff'),
-**       ('mininum positive nornal value', x'0010000000000000'),
-**       ('maximum value',                 x'7fefffffffffffff'))
-**    SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v)
-**      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin);
-**
-*/
-/* #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)
-#endif
-
-/*
-** Implementation of the ieee754() function
-*/
-static void ieee754func(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  if( argc==1 ){
-    sqlite3_int64 m, a;
-    double r;
-    int e;
-    int isNeg;
-    char zResult[100];
-    assert( sizeof(m)==sizeof(r) );
-    if( sqlite3_value_type(argv[0])==SQLITE_BLOB
-     && sqlite3_value_bytes(argv[0])==sizeof(r)
-    ){
-      const unsigned char *x = sqlite3_value_blob(argv[0]);
-      unsigned int i;
-      sqlite3_uint64 v = 0;
-      for(i=0; i<sizeof(r); i++){
-        v = (v<<8) | x[i];
-      }
-      memcpy(&r, &v, sizeof(r));
-    }else{
-      r = sqlite3_value_double(argv[0]);
-    }
-    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]);
-
-    /* Limit the range of e.  Ticket 22dea1cfdb9151e4 2021-03-02 */
-    if( e>10000 ){
-      e = 10000;
-    }else if( e<-10000 ){
-      e = -10000;
-    }
-
-    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);
-  }
-}
-
-/*
-** Functions to convert between blobs and floats.
-*/
-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.
-*/
-static int seriesClose(sqlite3_vtab_cursor *cur){
-  sqlite3_free(cur);
-  return SQLITE_OK;
-}
-
-
-/*
-** Advance a series_cursor to its next row of output.
-*/
-static int seriesNext(sqlite3_vtab_cursor *cur){
-  series_cursor *pCur = (series_cursor*)cur;
-  progressSequence( & pCur->ss );
-  return SQLITE_OK;
-}
-
-/*
-** Return values of columns for the row at which the series_cursor
-** is currently pointing.
-*/
-static int seriesColumn(
-  sqlite3_vtab_cursor *cur,   /* The cursor */
-  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
-  int i                       /* Which column to return */
-){
-  series_cursor *pCur = (series_cursor*)cur;
-  sqlite3_int64 x = 0;
-  switch( i ){
-    case SERIES_COLUMN_START:  x = pCur->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, 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;
-  sqlite3_uint64 n = pCur->ss.uSeqIndexNow;
-  *pRowid = (sqlite3_int64)((n<0xffffffffffffffff)? n+1 : 0);
-  return SQLITE_OK;
-}
-
-/*
-** Return TRUE if the cursor has been moved off of the last
-** row of output.
-*/
-static int seriesEof(sqlite3_vtab_cursor *cur){
-  series_cursor *pCur = (series_cursor*)cur;
-  return !pCur->ss.isNotEOF;
-}
-
-/* True to cause run-time checking of the start=, stop=, and/or step=
-** parameters.  The only reason to do this is for testing the
-** constraint checking logic for virtual tables in the SQLite core.
-*/
-#ifndef SQLITE_SERIES_CONSTRAINT_VERIFY
-# define SQLITE_SERIES_CONSTRAINT_VERIFY 0
-#endif
-
-/*
-** This method is called to "rewind" the series_cursor object back
-** to the first row of output.  This method is always called at least
-** once prior to any call to seriesColumn() or seriesRowid() or
-** seriesEof().
-**
-** The query plan selected by seriesBestIndex is passed in the idxNum
-** parameter.  (idxStr is not used in this implementation.)  idxNum
-** is a bitmask showing which constraints are available:
-**
-**    1:    start=VALUE
-**    2:    stop=VALUE
-**    4:    step=VALUE
-**
-** Also, if bit 8 is set, that means that the series should be output
-** in descending order rather than in ascending order.  If bit 16 is
-** set, then output must appear in ascending order.
-**
-** This routine should initialize the cursor and position it so that it
-** is pointing at the first row, or pointing off the end of the table
-** (so that seriesEof() will return true) if the table is empty.
-*/
-static int seriesFilter(
-  sqlite3_vtab_cursor *pVtabCursor,
-  int idxNum, const char *idxStrUnused,
-  int argc, sqlite3_value **argv
-){
-  series_cursor *pCur = (series_cursor *)pVtabCursor;
-  int i = 0;
-  (void)idxStrUnused;
-  if( idxNum & 1 ){
-    pCur->ss.iBase = sqlite3_value_int64(argv[i++]);
-  }else{
-    pCur->ss.iBase = 0;
-  }
-  if( idxNum & 2 ){
-    pCur->ss.iTerm = sqlite3_value_int64(argv[i++]);
-  }else{
-    pCur->ss.iTerm = 0xffffffff;
-  }
-  if( idxNum & 4 ){
-    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->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->ss.iBase = 1;
-      pCur->ss.iTerm = 0;
-      pCur->ss.iStep = 1;
-      break;
-    }
-  }
-  if( idxNum & 8 ){
-    pCur->ss.isReversing = pCur->ss.iStep > 0;
-  }else{
-    pCur->ss.isReversing = pCur->ss.iStep < 0;
-  }
-  setupSequence( &pCur->ss );
-  return SQLITE_OK;
-}
-
-/*
-** SQLite will invoke this method one or more times while planning a query
-** that uses the generate_series virtual table.  This routine needs to create
-** a query plan for each invocation and compute an estimated cost for that
-** plan.
-**
-** In this implementation idxNum is used to represent the
-** query plan.  idxStr is unused.
-**
-** The query plan is represented by bits in idxNum:
-**
-**  (1)  start = $value  -- constraint exists
-**  (2)  stop = $value   -- constraint exists
-**  (4)  step = $value   -- constraint exists
-**  (8)  output in descending order
-*/
-static int seriesBestIndex(
-  sqlite3_vtab *pVTab,
-  sqlite3_index_info *pIdxInfo
-){
-  int i, j;              /* Loop over constraints */
-  int idxNum = 0;        /* The query plan bitmask */
-  int bStartSeen = 0;    /* EQ constraint seen on the START column */
-  int unusableMask = 0;  /* Mask of unusable constraints */
-  int nArg = 0;          /* Number of arguments that seriesFilter() expects */
-  int aIdx[3];           /* Constraints on start, stop, and step */
-  const struct sqlite3_index_constraint *pConstraint;
-
-  /* This implementation assumes that the start, stop, and step columns
-  ** are the last three columns in the virtual table. */
-  assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
-  assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );
-
-  aIdx[0] = aIdx[1] = aIdx[2] = -1;
-  pConstraint = pIdxInfo->aConstraint;
-  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
-    int iCol;    /* 0 for start, 1 for stop, 2 for step */
-    int iMask;   /* bitmask for those column */
-    if( pConstraint->iColumn<SERIES_COLUMN_START ) continue;
-    iCol = pConstraint->iColumn - SERIES_COLUMN_START;
-    assert( iCol>=0 && iCol<=2 );
-    iMask = 1 << iCol;
-    if( iCol==0 ) bStartSeen = 1;
-    if( pConstraint->usable==0 ){
-      unusableMask |=  iMask;
-      continue;
-    }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
-      idxNum |= iMask;
-      aIdx[iCol] = i;
-    }
-  }
-  for(i=0; i<3; i++){
-    if( (j = aIdx[i])>=0 ){
-      pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
-      pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
-    }
-  }
-  /* The current generate_column() implementation requires at least one
-  ** argument (the START value).  Legacy versions assumed START=0 if the
-  ** first argument was omitted.  Compile with -DZERO_ARGUMENT_GENERATE_SERIES
-  ** to obtain the legacy behavior */
-#ifndef ZERO_ARGUMENT_GENERATE_SERIES
-  if( !bStartSeen ){
-    sqlite3_free(pVTab->zErrMsg);
-    pVTab->zErrMsg = sqlite3_mprintf(
-        "first argument to \"generate_series()\" missing or unusable");
-    return SQLITE_ERROR;
-  }
-#endif
-  if( (unusableMask & ~idxNum)!=0 ){
-    /* The start, stop, and step columns are inputs.  Therefore if there
-    ** are unusable constraints on any of start, stop, or step then
-    ** this plan is unusable */
-    return SQLITE_CONSTRAINT;
-  }
-  if( (idxNum & 3)==3 ){
-    /* Both start= and stop= boundaries are available.  This is the 
-    ** the preferred case */
-    pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0));
-    pIdxInfo->estimatedRows = 1000;
-    if( pIdxInfo->nOrderBy>=1 && pIdxInfo->aOrderBy[0].iColumn==0 ){
-      if( pIdxInfo->aOrderBy[0].desc ){
-        idxNum |= 8;
-      }else{
-        idxNum |= 16;
-      }
-      pIdxInfo->orderByConsumed = 1;
-    }
-  }else{
-    /* If either boundary is missing, we have to generate a huge span
-    ** of numbers.  Make this case very expensive so that the query
-    ** planner will work hard to avoid it. */
-    pIdxInfo->estimatedRows = 2147483647;
-  }
-  pIdxInfo->idxNum = idxNum;
-  return SQLITE_OK;
-}
-
-/*
-** This following structure defines all the methods for the 
-** generate_series virtual table.
-*/
-static sqlite3_module seriesModule = {
-  0,                         /* iVersion */
-  0,                         /* xCreate */
-  seriesConnect,             /* xConnect */
-  seriesBestIndex,           /* xBestIndex */
-  seriesDisconnect,          /* xDisconnect */
-  0,                         /* xDestroy */
-  seriesOpen,                /* xOpen - open a cursor */
-  seriesClose,               /* xClose - close a cursor */
-  seriesFilter,              /* xFilter - configure scan constraints */
-  seriesNext,                /* xNext - advance a cursor */
-  seriesEof,                 /* xEof - check for end of scan */
-  seriesColumn,              /* xColumn - read data */
-  seriesRowid,               /* xRowid - read data */
-  0,                         /* xUpdate */
-  0,                         /* xBegin */
-  0,                         /* xSync */
-  0,                         /* xCommit */
-  0,                         /* xRollback */
-  0,                         /* xFindMethod */
-  0,                         /* xRename */
-  0,                         /* xSavepoint */
-  0,                         /* xRelease */
-  0,                         /* xRollbackTo */
-  0                          /* xShadowName */
-};
-
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_series_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
-  int rc = SQLITE_OK;
-  SQLITE_EXTENSION_INIT2(pApi);
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-  if( sqlite3_libversion_number()<3008012 && pzErrMsg!=0 ){
-    *pzErrMsg = sqlite3_mprintf(
-        "generate_series() requires SQLite 3.8.12 or later");
-    return SQLITE_ERROR;
-  }
-  rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0);
-#endif
-  return rc;
-}
-
-/************************* End ../ext/misc/series.c ********************/
-/************************* Begin ../ext/misc/regexp.c ******************/
-/*
-** 2012-11-13
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** The code in this file implements a compact but reasonably
-** efficient regular-expression matcher for posix extended regular
-** expressions against UTF8 text.
-**
-** This file is an SQLite extension.  It registers a single function
-** named "regexp(A,B)" where A is the regular expression and B is the
-** string to be matched.  By registering this function, SQLite will also
-** then implement the "B regexp A" operator.  Note that with the function
-** the regular expression comes first, but with the operator it comes
-** second.
-**
-**  The following regular expression syntax is supported:
-**
-**     X*      zero or more occurrences of X
-**     X+      one or more occurrences of X
-**     X?      zero or one occurrences of X
-**     X{p,q}  between p and q occurrences of X
-**     (X)     match X
-**     X|Y     X or Y
-**     ^X      X occurring at the beginning of the string
-**     X$      X occurring at the end of the string
-**     .       Match any single character
-**     \c      Character c where c is one of \{}()[]|*+?.
-**     \c      C-language escapes for c in afnrtv.  ex: \t or \n
-**     \uXXXX  Where XXXX is exactly 4 hex digits, unicode value XXXX
-**     \xXX    Where XX is exactly 2 hex digits, unicode value XX
-**     [abc]   Any single character from the set abc
-**     [^abc]  Any single character not in the set abc
-**     [a-z]   Any single character in the range a-z
-**     [^a-z]  Any single character not in the range a-z
-**     \b      Word boundary
-**     \w      Word character.  [A-Za-z0-9_]
-**     \W      Non-word character
-**     \d      Digit
-**     \D      Non-digit
-**     \s      Whitespace character
-**     \S      Non-whitespace character
-**
-** A nondeterministic finite automaton (NFA) is used for matching, so the
-** performance is bounded by O(N*M) where N is the size of the regular
-** expression and M is the size of the input string.  The matcher never
-** exhibits exponential behavior.  Note that the X{p,q} operator expands
-** to p copies of X following by q-p copies of X? and that the size of the
-** regular expression in the O(N*M) performance bound is computed after
-** this expansion.
-*/
-#include <string.h>
-#include <stdlib.h>
-/* #include "sqlite3ext.h" */
-SQLITE_EXTENSION_INIT1
-
-/*
-** The following #defines change the names of some functions implemented in
-** this file to prevent name collisions with C-library functions of the
-** same name.
-*/
-#define re_match   sqlite3re_match
-#define re_compile sqlite3re_compile
-#define re_free    sqlite3re_free
-
-/* The end-of-input character */
-#define RE_EOF            0    /* End of input */
-#define RE_START  0xfffffff    /* Start of input - larger than an UTF-8 */
-
-/* The NFA is implemented as sequence of opcodes taken from the following
-** set.  Each opcode has a single integer argument.
-*/
-#define RE_OP_MATCH       1    /* Match the one character in the argument */
-#define RE_OP_ANY         2    /* Match any one character.  (Implements ".") */
-#define RE_OP_ANYSTAR     3    /* Special optimized version of .* */
-#define RE_OP_FORK        4    /* Continue to both next and opcode at iArg */
-#define RE_OP_GOTO        5    /* Jump to opcode at iArg */
-#define RE_OP_ACCEPT      6    /* Halt and indicate a successful match */
-#define RE_OP_CC_INC      7    /* Beginning of a [...] character class */
-#define RE_OP_CC_EXC      8    /* Beginning of a [^...] character class */
-#define RE_OP_CC_VALUE    9    /* Single value in a character class */
-#define RE_OP_CC_RANGE   10    /* Range of values in a character class */
-#define RE_OP_WORD       11    /* Perl word character [A-Za-z0-9_] */
-#define RE_OP_NOTWORD    12    /* Not a perl word character */
-#define RE_OP_DIGIT      13    /* digit:  [0-9] */
-#define RE_OP_NOTDIGIT   14    /* Not a digit */
-#define RE_OP_SPACE      15    /* space:  [ \t\n\r\v\f] */
-#define RE_OP_NOTSPACE   16    /* Not a digit */
-#define RE_OP_BOUNDARY   17    /* Boundary between word and non-word */
-#define RE_OP_ATSTART    18    /* Currently at the start of the string */
-
-#if defined(SQLITE_DEBUG)
-/* Opcode names used for symbolic debugging */
-static const char *ReOpName[] = {
-  "EOF",
-  "MATCH",
-  "ANY",
-  "ANYSTAR",
-  "FORK",
-  "GOTO",
-  "ACCEPT",
-  "CC_INC",
-  "CC_EXC",
-  "CC_VALUE",
-  "CC_RANGE",
-  "WORD",
-  "NOTWORD",
-  "DIGIT",
-  "NOTDIGIT",
-  "SPACE",
-  "NOTSPACE",
-  "BOUNDARY",
-  "ATSTART",
-};
-#endif /* SQLITE_DEBUG */
-
-
-/* Each opcode is a "state" in the NFA */
-typedef unsigned short ReStateNumber;
-
-/* Because this is an NFA and not a DFA, multiple states can be active at
-** once.  An instance of the following object records all active states in
-** the NFA.  The implementation is optimized for the common case where the
-** number of actives states is small.
-*/
-typedef struct ReStateSet {
-  unsigned nState;            /* Number of current states */
-  ReStateNumber *aState;      /* Current states */
-} ReStateSet;
-
-/* An input string read one character at a time.
-*/
-typedef struct ReInput ReInput;
-struct ReInput {
-  const unsigned char *z;  /* All text */
-  int i;                   /* Next byte to read */
-  int mx;                  /* EOF when i>=mx */
-};
-
-/* A compiled NFA (or an NFA that is in the process of being compiled) is
-** an instance of the following object.
-*/
-typedef struct ReCompiled ReCompiled;
-struct ReCompiled {
-  ReInput sIn;                /* Regular expression text */
-  const char *zErr;           /* Error message to return */
-  char *aOp;                  /* Operators for the virtual machine */
-  int *aArg;                  /* Arguments to each operator */
-  unsigned (*xNextChar)(ReInput*);  /* Next character function */
-  unsigned char zInit[12];    /* Initial text to match */
-  int nInit;                  /* Number of bytes in zInit */
-  unsigned nState;            /* Number of entries in aOp[] and aArg[] */
-  unsigned nAlloc;            /* Slots allocated for aOp[] and aArg[] */
-};
-
-/* Add a state to the given state set if it is not already there */
-static void re_add_state(ReStateSet *pSet, int newState){
-  unsigned i;
-  for(i=0; i<pSet->nState; i++) if( pSet->aState[i]==newState ) return;
-  pSet->aState[pSet->nState++] = (ReStateNumber)newState;
-}
-
-/* Extract the next unicode character from *pzIn and return it.  Advance
-** *pzIn to the first byte past the end of the character returned.  To
-** be clear:  this routine converts utf8 to unicode.  This routine is 
-** optimized for the common case where the next character is a single byte.
-*/
-static unsigned re_next_char(ReInput *p){
-  unsigned c;
-  if( p->i>=p->mx ) return 0;
-  c = p->z[p->i++];
-  if( c>=0x80 ){
-    if( (c&0xe0)==0xc0 && p->i<p->mx && (p->z[p->i]&0xc0)==0x80 ){
-      c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f);
-      if( c<0x80 ) c = 0xfffd;
-    }else if( (c&0xf0)==0xe0 && p->i+1<p->mx && (p->z[p->i]&0xc0)==0x80
-           && (p->z[p->i+1]&0xc0)==0x80 ){
-      c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
-      p->i += 2;
-      if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
-    }else if( (c&0xf8)==0xf0 && p->i+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);
-      p->i += 3;
-      if( c<=0xffff || c>0x10ffff ) c = 0xfffd;
-    }else{
-      c = 0xfffd;
-    }
-  }
-  return c;
-}
-static unsigned re_next_char_nocase(ReInput *p){
-  unsigned c = re_next_char(p);
-  if( c>='A' && c<='Z' ) c += 'a' - 'A';
-  return c;
-}
-
-/* Return true if c is a perl "word" character:  [A-Za-z0-9_] */
-static int re_word_char(int c){
-  return (c>='0' && c<='9') || (c>='a' && c<='z')
-      || (c>='A' && c<='Z') || c=='_';
-}
-
-/* Return true if c is a "digit" character:  [0-9] */
-static int re_digit_char(int c){
-  return (c>='0' && c<='9');
-}
-
-/* Return true if c is a perl "space" character:  [ \t\r\n\v\f] */
-static int re_space_char(int c){
-  return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f';
-}
-
-/* Run a compiled regular expression on the zero-terminated input
-** string zIn[].  Return true on a match and false if there is no match.
-*/
-static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
-  ReStateSet aStateSet[2], *pThis, *pNext;
-  ReStateNumber aSpace[100];
-  ReStateNumber *pToFree;
-  unsigned int i = 0;
-  unsigned int iSwap = 0;
-  int c = RE_START;
-  int cPrev = 0;
-  int rc = 0;
-  ReInput in;
-
-  in.z = zIn;
-  in.i = 0;
-  in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn);
-
-  /* Look for the initial prefix match, if there is one. */
-  if( pRe->nInit ){
-    unsigned char x = pRe->zInit[0];
-    while( in.i+pRe->nInit<=in.mx 
-     && (zIn[in.i]!=x ||
-         strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
-    ){
-      in.i++;
-    }
-    if( in.i+pRe->nInit>in.mx ) return 0;
-    c = RE_START-1;
-  }
-
-  if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
-    pToFree = 0;
-    aStateSet[0].aState = aSpace;
-  }else{
-    pToFree = sqlite3_malloc64( sizeof(ReStateNumber)*2*pRe->nState );
-    if( pToFree==0 ) return -1;
-    aStateSet[0].aState = pToFree;
-  }
-  aStateSet[1].aState = &aStateSet[0].aState[pRe->nState];
-  pNext = &aStateSet[1];
-  pNext->nState = 0;
-  re_add_state(pNext, 0);
-  while( c!=RE_EOF && pNext->nState>0 ){
-    cPrev = c;
-    c = pRe->xNextChar(&in);
-    pThis = pNext;
-    pNext = &aStateSet[iSwap];
-    iSwap = 1 - iSwap;
-    pNext->nState = 0;
-    for(i=0; i<pThis->nState; i++){
-      int x = pThis->aState[i];
-      switch( pRe->aOp[x] ){
-        case RE_OP_MATCH: {
-          if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
-          break;
-        }
-        case RE_OP_ATSTART: {
-          if( cPrev==RE_START ) re_add_state(pThis, x+1);
-          break;
-        }
-        case RE_OP_ANY: {
-          if( c!=0 ) re_add_state(pNext, x+1);
-          break;
-        }
-        case RE_OP_WORD: {
-          if( re_word_char(c) ) re_add_state(pNext, x+1);
-          break;
-        }
-        case RE_OP_NOTWORD: {
-          if( !re_word_char(c) && c!=0 ) re_add_state(pNext, x+1);
-          break;
-        }
-        case RE_OP_DIGIT: {
-          if( re_digit_char(c) ) re_add_state(pNext, x+1);
-          break;
-        }
-        case RE_OP_NOTDIGIT: {
-          if( !re_digit_char(c) && c!=0 ) re_add_state(pNext, x+1);
-          break;
-        }
-        case RE_OP_SPACE: {
-          if( re_space_char(c) ) re_add_state(pNext, x+1);
-          break;
-        }
-        case RE_OP_NOTSPACE: {
-          if( !re_space_char(c) && c!=0 ) re_add_state(pNext, x+1);
-          break;
-        }
-        case RE_OP_BOUNDARY: {
-          if( re_word_char(c)!=re_word_char(cPrev) ) re_add_state(pThis, x+1);
-          break;
-        }
-        case RE_OP_ANYSTAR: {
-          re_add_state(pNext, x);
-          re_add_state(pThis, x+1);
-          break;
-        }
-        case RE_OP_FORK: {
-          re_add_state(pThis, x+pRe->aArg[x]);
-          re_add_state(pThis, x+1);
-          break;
-        }
-        case RE_OP_GOTO: {
-          re_add_state(pThis, x+pRe->aArg[x]);
-          break;
-        }
-        case RE_OP_ACCEPT: {
-          rc = 1;
-          goto re_match_end;
-        }
-        case RE_OP_CC_EXC: {
-          if( c==0 ) break;
-          /* fall-through */ goto re_op_cc_inc;
-        }
-        case RE_OP_CC_INC: re_op_cc_inc: {
-          int j = 1;
-          int n = pRe->aArg[x];
-          int hit = 0;
-          for(j=1; j>0 && j<n; j++){
-            if( pRe->aOp[x+j]==RE_OP_CC_VALUE ){
-              if( pRe->aArg[x+j]==c ){
-                hit = 1;
-                j = -1;
-              }
-            }else{
-              if( pRe->aArg[x+j]<=c && pRe->aArg[x+j+1]>=c ){
-                hit = 1;
-                j = -1;
-              }else{
-                j++;
-              }
-            }
-          }
-          if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit;
-          if( hit ) re_add_state(pNext, x+n);
-          break;
-        }
-      }
-    }
-  }
-  for(i=0; i<pNext->nState; i++){
-    int x = pNext->aState[i];
-    while( pRe->aOp[x]==RE_OP_GOTO ) x += pRe->aArg[x];
-    if( pRe->aOp[x]==RE_OP_ACCEPT ){ rc = 1; break; }
-  }
-re_match_end:
-  sqlite3_free(pToFree);
-  return rc;
-}
-
-/* Resize the opcode and argument arrays for an RE under construction.
-*/
-static int re_resize(ReCompiled *p, int N){
-  char *aOp;
-  int *aArg;
-  aOp = sqlite3_realloc64(p->aOp, N*sizeof(p->aOp[0]));
-  if( aOp==0 ) return 1;
-  p->aOp = aOp;
-  aArg = sqlite3_realloc64(p->aArg, N*sizeof(p->aArg[0]));
-  if( aArg==0 ) return 1;
-  p->aArg = aArg;
-  p->nAlloc = N;
-  return 0;
-}
-
-/* Insert a new opcode and argument into an RE under construction.  The
-** insertion point is just prior to existing opcode iBefore.
-*/
-static int re_insert(ReCompiled *p, int iBefore, int op, int arg){
-  int i;
-  if( p->nAlloc<=p->nState && re_resize(p, p->nAlloc*2) ) return 0;
-  for(i=p->nState; i>iBefore; i--){
-    p->aOp[i] = p->aOp[i-1];
-    p->aArg[i] = p->aArg[i-1];
-  }
-  p->nState++;
-  p->aOp[iBefore] = (char)op;
-  p->aArg[iBefore] = arg;
-  return iBefore;
-}
-
-/* Append a new opcode and argument to the end of the RE under construction.
-*/
-static int re_append(ReCompiled *p, int op, int arg){
-  return re_insert(p, p->nState, op, arg);
-}
-
-/* Make a copy of N opcodes starting at iStart onto the end of the RE
-** under construction.
-*/
-static void re_copy(ReCompiled *p, int iStart, int N){
-  if( p->nState+N>=p->nAlloc && re_resize(p, p->nAlloc*2+N) ) return;
-  memcpy(&p->aOp[p->nState], &p->aOp[iStart], N*sizeof(p->aOp[0]));
-  memcpy(&p->aArg[p->nState], &p->aArg[iStart], N*sizeof(p->aArg[0]));
-  p->nState += N;
-}
-
-/* Return true if c is a hexadecimal digit character:  [0-9a-fA-F]
-** If c is a hex digit, also set *pV = (*pV)*16 + valueof(c).  If
-** c is not a hex digit *pV is unchanged.
-*/
-static int re_hex(int c, int *pV){
-  if( c>='0' && c<='9' ){
-    c -= '0';
-  }else if( c>='a' && c<='f' ){
-    c -= 'a' - 10;
-  }else if( c>='A' && c<='F' ){
-    c -= 'A' - 10;
-  }else{
-    return 0;
-  }
-  *pV = (*pV)*16 + (c & 0xff);
-  return 1;
-}
-
-/* A backslash character has been seen, read the next character and
-** return its interpretation.
-*/
-static unsigned re_esc_char(ReCompiled *p){
-  static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]";
-  static const char zTrans[] = "\a\f\n\r\t\v";
-  int i, v = 0;
-  char c;
-  if( p->sIn.i>=p->sIn.mx ) return 0;
-  c = p->sIn.z[p->sIn.i];
-  if( c=='u' && p->sIn.i+4<p->sIn.mx ){
-    const unsigned char *zIn = p->sIn.z + p->sIn.i;
-    if( re_hex(zIn[1],&v)
-     && re_hex(zIn[2],&v)
-     && re_hex(zIn[3],&v)
-     && re_hex(zIn[4],&v)
-    ){
-      p->sIn.i += 5;
-      return v;
-    }
-  }
-  if( c=='x' && p->sIn.i+2<p->sIn.mx ){
-    const unsigned char *zIn = p->sIn.z + p->sIn.i;
-    if( re_hex(zIn[1],&v)
-     && re_hex(zIn[2],&v)
-    ){
-      p->sIn.i += 3;
-      return v;
-    }
-  }
-  for(i=0; zEsc[i] && zEsc[i]!=c; i++){}
-  if( zEsc[i] ){
-    if( i<6 ) c = zTrans[i];
-    p->sIn.i++;
-  }else{
-    p->zErr = "unknown \\ escape";
-  }
-  return c;
-}
-
-/* Forward declaration */
-static const char *re_subcompile_string(ReCompiled*);
-
-/* Peek at the next byte of input */
-static unsigned char rePeek(ReCompiled *p){
-  return p->sIn.i<p->sIn.mx ? p->sIn.z[p->sIn.i] : 0;
-}
-
-/* Compile RE text into a sequence of opcodes.  Continue up to the
-** first unmatched ")" character, then return.  If an error is found,
-** return a pointer to the error message string.
-*/
-static const char *re_subcompile_re(ReCompiled *p){
-  const char *zErr;
-  int iStart, iEnd, iGoto;
-  iStart = p->nState;
-  zErr = re_subcompile_string(p);
-  if( zErr ) return zErr;
-  while( rePeek(p)=='|' ){
-    iEnd = p->nState;
-    re_insert(p, iStart, RE_OP_FORK, iEnd + 2 - iStart);
-    iGoto = re_append(p, RE_OP_GOTO, 0);
-    p->sIn.i++;
-    zErr = re_subcompile_string(p);
-    if( zErr ) return zErr;
-    p->aArg[iGoto] = p->nState - iGoto;
-  }
-  return 0;
-}
-
-/* Compile an element of regular expression text (anything that can be
-** an operand to the "|" operator).  Return NULL on success or a pointer
-** to the error message if there is a problem.
-*/
-static const char *re_subcompile_string(ReCompiled *p){
-  int iPrev = -1;
-  int iStart;
-  unsigned c;
-  const char *zErr;
-  while( (c = p->xNextChar(&p->sIn))!=0 ){
-    iStart = p->nState;
-    switch( c ){
-      case '|':
-      case ')': {
-        p->sIn.i--;
-        return 0;
-      }
-      case '(': {
-        zErr = re_subcompile_re(p);
-        if( zErr ) return zErr;
-        if( rePeek(p)!=')' ) return "unmatched '('";
-        p->sIn.i++;
-        break;
-      }
-      case '.': {
-        if( rePeek(p)=='*' ){
-          re_append(p, RE_OP_ANYSTAR, 0);
-          p->sIn.i++;
-        }else{
-          re_append(p, RE_OP_ANY, 0);
-        }
-        break;
-      }
-      case '*': {
-        if( iPrev<0 ) return "'*' without operand";
-        re_insert(p, iPrev, RE_OP_GOTO, p->nState - iPrev + 1);
-        re_append(p, RE_OP_FORK, iPrev - p->nState + 1);
-        break;
-      }
-      case '+': {
-        if( iPrev<0 ) return "'+' without operand";
-        re_append(p, RE_OP_FORK, iPrev - p->nState);
-        break;
-      }
-      case '?': {
-        if( iPrev<0 ) return "'?' without operand";
-        re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
-        break;
-      }
-      case '$': {
-        re_append(p, RE_OP_MATCH, RE_EOF);
-        break;
-      }
-      case '^': {
-        re_append(p, RE_OP_ATSTART, 0);
-        break;
-      }
-      case '{': {
-        int m = 0, n = 0;
-        int sz, j;
-        if( iPrev<0 ) return "'{m,n}' without operand";
-        while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }
-        n = m;
-        if( c==',' ){
-          p->sIn.i++;
-          n = 0;
-          while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }
-        }
-        if( c!='}' ) return "unmatched '{'";
-        if( n>0 && n<m ) return "n less than m in '{m,n}'";
-        p->sIn.i++;
-        sz = p->nState - iPrev;
-        if( m==0 ){
-          if( n==0 ) return "both m and n are zero in '{m,n}'";
-          re_insert(p, iPrev, RE_OP_FORK, sz+1);
-          iPrev++;
-          n--;
-        }else{
-          for(j=1; j<m; j++) re_copy(p, iPrev, sz);
-        }
-        for(j=m; j<n; j++){
-          re_append(p, RE_OP_FORK, sz+1);
-          re_copy(p, iPrev, sz);
-        }
-        if( n==0 && m>0 ){
-          re_append(p, RE_OP_FORK, -sz);
-        }
-        break;
-      }
-      case '[': {
-        unsigned int iFirst = p->nState;
-        if( rePeek(p)=='^' ){
-          re_append(p, RE_OP_CC_EXC, 0);
-          p->sIn.i++;
-        }else{
-          re_append(p, RE_OP_CC_INC, 0);
-        }
-        while( (c = p->xNextChar(&p->sIn))!=0 ){
-          if( c=='[' && rePeek(p)==':' ){
-            return "POSIX character classes not supported";
-          }
-          if( c=='\\' ) c = re_esc_char(p);
-          if( rePeek(p)=='-' ){
-            re_append(p, RE_OP_CC_RANGE, c);
-            p->sIn.i++;
-            c = p->xNextChar(&p->sIn);
-            if( c=='\\' ) c = re_esc_char(p);
-            re_append(p, RE_OP_CC_RANGE, c);
-          }else{
-            re_append(p, RE_OP_CC_VALUE, c);
-          }
-          if( rePeek(p)==']' ){ p->sIn.i++; break; }
-        }
-        if( c==0 ) return "unclosed '['";
-        if( p->nState>iFirst ) p->aArg[iFirst] = p->nState - iFirst;
-        break;
-      }
-      case '\\': {
-        int specialOp = 0;
-        switch( rePeek(p) ){
-          case 'b': specialOp = RE_OP_BOUNDARY;   break;
-          case 'd': specialOp = RE_OP_DIGIT;      break;
-          case 'D': specialOp = RE_OP_NOTDIGIT;   break;
-          case 's': specialOp = RE_OP_SPACE;      break;
-          case 'S': specialOp = RE_OP_NOTSPACE;   break;
-          case 'w': specialOp = RE_OP_WORD;       break;
-          case 'W': specialOp = RE_OP_NOTWORD;    break;
-        }
-        if( specialOp ){
-          p->sIn.i++;
-          re_append(p, specialOp, 0);
-        }else{
-          c = re_esc_char(p);
-          re_append(p, RE_OP_MATCH, c);
-        }
-        break;
-      }
-      default: {
-        re_append(p, RE_OP_MATCH, c);
-        break;
-      }
-    }
-    iPrev = iStart;
-  }
-  return 0;
-}
-
-/* Free and reclaim all the memory used by a previously compiled
-** regular expression.  Applications should invoke this routine once
-** for every call to re_compile() to avoid memory leaks.
-*/
-static void re_free(ReCompiled *pRe){
-  if( pRe ){
-    sqlite3_free(pRe->aOp);
-    sqlite3_free(pRe->aArg);
-    sqlite3_free(pRe);
-  }
-}
-
-/*
-** Compile a textual regular expression in zIn[] into a compiled regular
-** expression suitable for us by re_match() and return a pointer to the
-** compiled regular expression in *ppRe.  Return NULL on success or an
-** error message if something goes wrong.
-*/
-static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){
-  ReCompiled *pRe;
-  const char *zErr;
-  int i, j;
-
-  *ppRe = 0;
-  pRe = sqlite3_malloc( sizeof(*pRe) );
-  if( pRe==0 ){
-    return "out of memory";
-  }
-  memset(pRe, 0, sizeof(*pRe));
-  pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char;
-  if( re_resize(pRe, 30) ){
-    re_free(pRe);
-    return "out of memory";
-  }
-  if( zIn[0]=='^' ){
-    zIn++;
-  }else{
-    re_append(pRe, RE_OP_ANYSTAR, 0);
-  }
-  pRe->sIn.z = (unsigned char*)zIn;
-  pRe->sIn.i = 0;
-  pRe->sIn.mx = (int)strlen(zIn);
-  zErr = re_subcompile_re(pRe);
-  if( zErr ){
-    re_free(pRe);
-    return zErr;
-  }
-  if( pRe->sIn.i>=pRe->sIn.mx ){
-    re_append(pRe, RE_OP_ACCEPT, 0);
-    *ppRe = pRe;
-  }else{
-    re_free(pRe);
-    return "unrecognized character";
-  }
-
-  /* The following is a performance optimization.  If the regex begins with
-  ** ".*" (if the input regex lacks an initial "^") and afterwards there are
-  ** one or more matching characters, enter those matching characters into
-  ** zInit[].  The re_match() routine can then search ahead in the input 
-  ** string looking for the initial match without having to run the whole
-  ** regex engine over the string.  Do not worry 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<=0x7f ){
-        pRe->zInit[j++] = (unsigned char)x;
-      }else if( x<=0x7ff ){
-        pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
-        pRe->zInit[j++] = 0x80 | (x&0x3f);
-      }else if( x<=0xffff ){
-        pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12));
-        pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
-        pRe->zInit[j++] = 0x80 | (x&0x3f);
-      }else{
-        break;
-      }
-    }
-    if( j>0 && pRe->zInit[j-1]==0 ) j--;
-    pRe->nInit = j;
-  }
-  return pRe->zErr;
-}
-
-/*
-** Implementation of the regexp() SQL function.  This function implements
-** the build-in REGEXP operator.  The first argument to the function is the
-** pattern and the second argument is the string.  So, the SQL statements:
-**
-**       A REGEXP B
-**
-** is implemented as regexp(B,A).
-*/
-static void re_sql_func(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  ReCompiled *pRe;          /* Compiled regular expression */
-  const char *zPattern;     /* The regular expression */
-  const unsigned char *zStr;/* String being searched */
-  const char *zErr;         /* Compile error message */
-  int setAux = 0;           /* True to invoke sqlite3_set_auxdata() */
-
-  (void)argc;  /* Unused */
-  pRe = sqlite3_get_auxdata(context, 0);
-  if( pRe==0 ){
-    zPattern = (const char*)sqlite3_value_text(argv[0]);
-    if( zPattern==0 ) return;
-    zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0);
-    if( zErr ){
-      re_free(pRe);
-      sqlite3_result_error(context, zErr, -1);
-      return;
-    }
-    if( pRe==0 ){
-      sqlite3_result_error_nomem(context);
-      return;
-    }
-    setAux = 1;
-  }
-  zStr = (const unsigned char*)sqlite3_value_text(argv[1]);
-  if( zStr!=0 ){
-    sqlite3_result_int(context, re_match(pRe, zStr, -1));
-  }
-  if( setAux ){
-    sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free);
-  }
-}
-
-#if defined(SQLITE_DEBUG)
-/*
-** This function is used for testing and debugging only.  It is only available
-** if the SQLITE_DEBUG compile-time option is used.
-**
-** Compile a regular expression and then convert the compiled expression into
-** text and return that text.
-*/
-static void re_bytecode_func(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  const char *zPattern;
-  const char *zErr;
-  ReCompiled *pRe;
-  sqlite3_str *pStr;
-  int i;
-  int n;
-  char *z;
-  (void)argc;
-
-  zPattern = (const char*)sqlite3_value_text(argv[0]);
-  if( zPattern==0 ) return;
-  zErr = re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0);
-  if( zErr ){
-    re_free(pRe);
-    sqlite3_result_error(context, zErr, -1);
-    return;
-  }
-  if( pRe==0 ){
-    sqlite3_result_error_nomem(context);
-    return;
-  }
-  pStr = sqlite3_str_new(0);
-  if( pStr==0 ) goto re_bytecode_func_err;
-  if( pRe->nInit>0 ){
-    sqlite3_str_appendf(pStr, "INIT     ");
-    for(i=0; i<pRe->nInit; i++){
-      sqlite3_str_appendf(pStr, "%02x", pRe->zInit[i]);
-    }
-    sqlite3_str_appendf(pStr, "\n");
-  }
-  for(i=0; (unsigned)i<pRe->nState; i++){
-    sqlite3_str_appendf(pStr, "%-8s %4d\n",
-         ReOpName[(unsigned char)pRe->aOp[i]], pRe->aArg[i]);
-  }
-  n = sqlite3_str_length(pStr);
-  z = sqlite3_str_finish(pStr);
-  if( n==0 ){
-    sqlite3_free(z);
-  }else{
-    sqlite3_result_text(context, z, n-1, sqlite3_free);
-  }
-
-re_bytecode_func_err:
-  re_free(pRe);
-}
-
-#endif /* SQLITE_DEBUG */
-
-
-/*
-** Invoke this routine to register the regexp() function with the
-** SQLite database connection.
-*/
-#ifdef _WIN32
-
-#endif
-int sqlite3_regexp_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
-  int rc = SQLITE_OK;
-  SQLITE_EXTENSION_INIT2(pApi);
-  (void)pzErrMsg;  /* Unused */
-  rc = sqlite3_create_function(db, "regexp", 2, 
-                            SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
-                            0, re_sql_func, 0, 0);
-  if( rc==SQLITE_OK ){
-    /* The regexpi(PATTERN,STRING) function is a case-insensitive version
-    ** of regexp(PATTERN,STRING). */
-    rc = sqlite3_create_function(db, "regexpi", 2,
-                            SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
-                            (void*)db, re_sql_func, 0, 0);
-#if defined(SQLITE_DEBUG)
-    if( rc==SQLITE_OK ){
-      rc = sqlite3_create_function(db, "regexp_bytecode", 1,
-                            SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
-                            0, re_bytecode_func, 0, 0);
-    }
-#endif /* SQLITE_DEBUG */
-  }
-  return rc;
-}
-
-/************************* End ../ext/misc/regexp.c ********************/
-#ifndef SQLITE_SHELL_FIDDLE
-/************************* Begin ../ext/misc/fileio.c ******************/
-/*
-** 2014-06-13
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This SQLite extension implements SQL functions readfile() and
-** writefile(), and eponymous virtual type "fsdir".
-**
-** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
-**
-**   If neither of the optional arguments is present, then this UDF
-**   function writes blob DATA to file FILE. If successful, the number
-**   of bytes written is returned. If an error occurs, NULL is returned.
-**
-**   If the first option argument - MODE - is present, then it must
-**   be passed an integer value that corresponds to a POSIX mode
-**   value (file type + permissions, as returned in the stat.st_mode
-**   field by the stat() system call). Three types of files may
-**   be written/created:
-**
-**     regular files:  (mode & 0170000)==0100000
-**     symbolic links: (mode & 0170000)==0120000
-**     directories:    (mode & 0170000)==0040000
-**
-**   For a directory, the DATA is ignored. For a symbolic link, it is
-**   interpreted as text and used as the target of the link. For a
-**   regular file, it is interpreted as a blob and written into the
-**   named file. Regardless of the type of file, its permissions are
-**   set to (mode & 0777) before returning.
-**
-**   If the optional MTIME argument is present, then it is interpreted
-**   as an integer - the number of seconds since the unix epoch. The
-**   modification-time of the target file is set to this value before
-**   returning.
-**
-**   If three or more arguments are passed to this function and an
-**   error is encountered, an exception is raised.
-**
-** READFILE(FILE):
-**
-**   Read and return the contents of file FILE (type blob) from disk.
-**
-** FSDIR:
-**
-**   Used as follows:
-**
-**     SELECT * FROM fsdir($path [, $dir]);
-**
-**   Parameter $path is an absolute or relative pathname. If the file that it
-**   refers to does not exist, it is an error. If the path refers to a regular
-**   file or symbolic link, it returns a single row. Or, if the path refers
-**   to a directory, it returns one row for the directory, and one row for each
-**   file within the hierarchy rooted at $path.
-**
-**   Each row has the following columns:
-**
-**     name:  Path to file or directory (text value).
-**     mode:  Value of stat.st_mode for directory entry (an integer).
-**     mtime: Value of stat.st_mtime for directory entry (an integer).
-**     data:  For a regular file, a blob containing the file data. For a
-**            symlink, a text value containing the text of the link. For a
-**            directory, NULL.
-**
-**   If a non-NULL value is specified for the optional $dir parameter and
-**   $path is a relative path, then $path is interpreted relative to $dir. 
-**   And the paths returned in the "name" column of the table are also 
-**   relative to directory $dir.
-**
-** Notes on building this extension for Windows:
-**   Unless linked statically with the SQLite library, a preprocessor
-**   symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone
-**   DLL form of this extension for WIN32. See its use below for details.
-*/
-/* #include "sqlite3ext.h" */
-SQLITE_EXTENSION_INIT1
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#if !defined(_WIN32) && !defined(WIN32)
-#  include <unistd.h>
-#  include <dirent.h>
-#  include <utime.h>
-#  include <sys/time.h>
-#else
-#  include "windows.h"
-#  include <io.h>
-#  include <direct.h>
-/* #  include "test_windirent.h" */
-#  define dirent DIRENT
-#  ifndef chmod
-#    define chmod _chmod
-#  endif
-#  ifndef stat
-#    define stat _stat
-#  endif
-#  define mkdir(path,mode) _mkdir(path)
-#  define lstat(path,buf) stat(path,buf)
-#endif
-#include <time.h>
-#include <errno.h>
-
-
-/*
-** Structure of the fsdir() table-valued function
-*/
-                 /*    0    1    2     3    4           5             */
-#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
-#define FSDIR_COLUMN_NAME     0     /* Name of the file */
-#define FSDIR_COLUMN_MODE     1     /* Access mode */
-#define FSDIR_COLUMN_MTIME    2     /* Last modification time */
-#define FSDIR_COLUMN_DATA     3     /* File content */
-#define FSDIR_COLUMN_PATH     4     /* Path to top of search */
-#define FSDIR_COLUMN_DIR      5     /* Path is relative to this directory */
-
-
-/*
-** Set the result stored by context ctx to a blob containing the 
-** contents of file zName.  Or, leave the result unchanged (NULL)
-** if the file does not exist or is unreadable.
-**
-** If the file exceeds the SQLite blob size limit, through an
-** SQLITE_TOOBIG error.
-**
-** Throw an SQLITE_IOERR if there are difficulties pulling the file
-** off of disk.
-*/
-static void readFileContents(sqlite3_context *ctx, const char *zName){
-  FILE *in;
-  sqlite3_int64 nIn;
-  void *pBuf;
-  sqlite3 *db;
-  int mxBlob;
-
-  in = fopen(zName, "rb");
-  if( in==0 ){
-    /* File does not exist or is unreadable. Leave the result set to NULL. */
-    return;
-  }
-  fseek(in, 0, SEEK_END);
-  nIn = ftell(in);
-  rewind(in);
-  db = sqlite3_context_db_handle(ctx);
-  mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
-  if( nIn>mxBlob ){
-    sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
-    fclose(in);
-    return;
-  }
-  pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
-  if( pBuf==0 ){
-    sqlite3_result_error_nomem(ctx);
-    fclose(in);
-    return;
-  }
-  if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
-    sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
-  }else{
-    sqlite3_result_error_code(ctx, SQLITE_IOERR);
-    sqlite3_free(pBuf);
-  }
-  fclose(in);
-}
-
-/*
-** Implementation of the "readfile(X)" SQL function.  The entire content
-** of the file named X is read and returned as a BLOB.  NULL is returned
-** if the file does not exist or is unreadable.
-*/
-static void readfileFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  const char *zName;
-  (void)(argc);  /* Unused parameter */
-  zName = (const char*)sqlite3_value_text(argv[0]);
-  if( zName==0 ) return;
-  readFileContents(context, zName);
-}
-
-/*
-** Set the error message contained in context ctx to the results of
-** vprintf(zFmt, ...).
-*/
-static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
-  char *zMsg = 0;
-  va_list ap;
-  va_start(ap, zFmt);
-  zMsg = sqlite3_vmprintf(zFmt, ap);
-  sqlite3_result_error(ctx, zMsg, -1);
-  sqlite3_free(zMsg);
-  va_end(ap);
-}
-
-#if defined(_WIN32)
-/*
-** This function is designed to convert a Win32 FILETIME structure into the
-** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
-*/
-static sqlite3_uint64 fileTimeToUnixTime(
-  LPFILETIME pFileTime
-){
-  SYSTEMTIME epochSystemTime;
-  ULARGE_INTEGER epochIntervals;
-  FILETIME epochFileTime;
-  ULARGE_INTEGER fileIntervals;
-
-  memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
-  epochSystemTime.wYear = 1970;
-  epochSystemTime.wMonth = 1;
-  epochSystemTime.wDay = 1;
-  SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
-  epochIntervals.LowPart = epochFileTime.dwLowDateTime;
-  epochIntervals.HighPart = epochFileTime.dwHighDateTime;
-
-  fileIntervals.LowPart = pFileTime->dwLowDateTime;
-  fileIntervals.HighPart = pFileTime->dwHighDateTime;
-
-  return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
-}
-
-
-#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
-#  /* To allow a standalone DLL, use this next replacement function: */
-#  undef sqlite3_win32_utf8_to_unicode
-#  define sqlite3_win32_utf8_to_unicode utf8_to_utf16
-#
-LPWSTR utf8_to_utf16(const char *z){
-  int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0);
-  LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR));
-  if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) )
-    return rv;
-  sqlite3_free(rv);
-  return 0;
-}
-#endif
-
-/*
-** This function attempts to normalize the time values found in the stat()
-** buffer to UTC.  This is necessary on Win32, where the runtime library
-** appears to return these values as local times.
-*/
-static void statTimesToUtc(
-  const char *zPath,
-  struct stat *pStatBuf
-){
-  HANDLE hFindFile;
-  WIN32_FIND_DATAW fd;
-  LPWSTR zUnicodeName;
-  extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
-  zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
-  if( zUnicodeName ){
-    memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
-    hFindFile = FindFirstFileW(zUnicodeName, &fd);
-    if( hFindFile!=NULL ){
-      pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
-      pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
-      pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
-      FindClose(hFindFile);
-    }
-    sqlite3_free(zUnicodeName);
-  }
-}
-#endif
-
-/*
-** This function is used in place of stat().  On Windows, special handling
-** is required in order for the included time to be returned as UTC.  On all
-** other systems, this function simply calls stat().
-*/
-static int fileStat(
-  const char *zPath,
-  struct stat *pStatBuf
-){
-#if defined(_WIN32)
-  int rc = stat(zPath, pStatBuf);
-  if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
-  return rc;
-#else
-  return stat(zPath, pStatBuf);
-#endif
-}
-
-/*
-** This function is used in place of lstat().  On Windows, special handling
-** is required in order for the included time to be returned as UTC.  On all
-** other systems, this function simply calls lstat().
-*/
-static int fileLinkStat(
-  const char *zPath,
-  struct stat *pStatBuf
-){
-#if defined(_WIN32)
-  int rc = lstat(zPath, pStatBuf);
-  if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
-  return rc;
-#else
-  return lstat(zPath, pStatBuf);
-#endif
-}
-
-/*
-** Argument zFile is the name of a file that will be created and/or written
-** by SQL function writefile(). This function ensures that the directory
-** zFile will be written to exists, creating it if required. The permissions
-** for any path components created by this function are set in accordance
-** with the current umask.
-**
-** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
-** SQLITE_OK is returned if the directory is successfully created, or
-** SQLITE_ERROR otherwise.
-*/
-static int makeDirectory(
-  const char *zFile
-){
-  char *zCopy = sqlite3_mprintf("%s", zFile);
-  int rc = SQLITE_OK;
-
-  if( zCopy==0 ){
-    rc = SQLITE_NOMEM;
-  }else{
-    int nCopy = (int)strlen(zCopy);
-    int i = 1;
-
-    while( rc==SQLITE_OK ){
-      struct stat sStat;
-      int rc2;
-
-      for(; zCopy[i]!='/' && i<nCopy; i++);
-      if( i==nCopy ) break;
-      zCopy[i] = '\0';
-
-      rc2 = fileStat(zCopy, &sStat);
-      if( rc2!=0 ){
-        if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR;
-      }else{
-        if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
-      }
-      zCopy[i] = '/';
-      i++;
-    }
-
-    sqlite3_free(zCopy);
-  }
-
-  return rc;
-}
-
-/*
-** This function does the work for the writefile() UDF. Refer to 
-** header comments at the top of this file for details.
-*/
-static int writeFile(
-  sqlite3_context *pCtx,          /* Context to return bytes written in */
-  const char *zFile,              /* File to write */
-  sqlite3_value *pData,           /* Data to write */
-  mode_t mode,                    /* MODE parameter passed to writefile() */
-  sqlite3_int64 mtime             /* MTIME parameter (or -1 to not set time) */
-){
-  if( zFile==0 ) return 1;
-#if !defined(_WIN32) && !defined(WIN32)
-  if( S_ISLNK(mode) ){
-    const char *zTo = (const char*)sqlite3_value_text(pData);
-    if( zTo==0 || symlink(zTo, zFile)<0 ) return 1;
-  }else
-#endif
-  {
-    if( S_ISDIR(mode) ){
-      if( mkdir(zFile, mode) ){
-        /* The mkdir() call to create the directory failed. This might not
-        ** be an error though - if there is already a directory at the same
-        ** path and either the permissions already match or can be changed
-        ** to do so using chmod(), it is not an error.  */
-        struct stat sStat;
-        if( errno!=EEXIST
-         || 0!=fileStat(zFile, &sStat)
-         || !S_ISDIR(sStat.st_mode)
-         || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
-        ){
-          return 1;
-        }
-      }
-    }else{
-      sqlite3_int64 nWrite = 0;
-      const char *z;
-      int rc = 0;
-      FILE *out = fopen(zFile, "wb");
-      if( out==0 ) return 1;
-      z = (const char*)sqlite3_value_blob(pData);
-      if( z ){
-        sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
-        nWrite = sqlite3_value_bytes(pData);
-        if( nWrite!=n ){
-          rc = 1;
-        }
-      }
-      fclose(out);
-      if( rc==0 && mode && chmod(zFile, mode & 0777) ){
-        rc = 1;
-      }
-      if( rc ) return 2;
-      sqlite3_result_int64(pCtx, nWrite);
-    }
-  }
-
-  if( mtime>=0 ){
-#if defined(_WIN32)
-#if !SQLITE_OS_WINRT
-    /* Windows */
-    FILETIME lastAccess;
-    FILETIME lastWrite;
-    SYSTEMTIME currentTime;
-    LONGLONG intervals;
-    HANDLE hFile;
-    LPWSTR zUnicodeName;
-    extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
-
-    GetSystemTime(&currentTime);
-    SystemTimeToFileTime(&currentTime, &lastAccess);
-    intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
-    lastWrite.dwLowDateTime = (DWORD)intervals;
-    lastWrite.dwHighDateTime = intervals >> 32;
-    zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
-    if( zUnicodeName==0 ){
-      return 1;
-    }
-    hFile = CreateFileW(
-      zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
-      FILE_FLAG_BACKUP_SEMANTICS, NULL
-    );
-    sqlite3_free(zUnicodeName);
-    if( hFile!=INVALID_HANDLE_VALUE ){
-      BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
-      CloseHandle(hFile);
-      return !bResult;
-    }else{
-      return 1;
-    }
-#endif
-#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
-    /* Recent unix */
-    struct timespec times[2];
-    times[0].tv_nsec = times[1].tv_nsec = 0;
-    times[0].tv_sec = time(0);
-    times[1].tv_sec = mtime;
-    if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
-      return 1;
-    }
-#else
-    /* Legacy unix */
-    struct timeval times[2];
-    times[0].tv_usec = times[1].tv_usec = 0;
-    times[0].tv_sec = time(0);
-    times[1].tv_sec = mtime;
-    if( utimes(zFile, times) ){
-      return 1;
-    }
-#endif
-  }
-
-  return 0;
-}
-
-/*
-** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.  
-** Refer to header comments at the top of this file for details.
-*/
-static void writefileFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  const char *zFile;
-  mode_t mode = 0;
-  int res;
-  sqlite3_int64 mtime = -1;
-
-  if( argc<2 || argc>4 ){
-    sqlite3_result_error(context, 
-        "wrong number of arguments to function writefile()", -1
-    );
-    return;
-  }
-
-  zFile = (const char*)sqlite3_value_text(argv[0]);
-  if( zFile==0 ) return;
-  if( argc>=3 ){
-    mode = (mode_t)sqlite3_value_int(argv[2]);
-  }
-  if( argc==4 ){
-    mtime = sqlite3_value_int64(argv[3]);
-  }
-
-  res = writeFile(context, zFile, argv[1], mode, mtime);
-  if( res==1 && errno==ENOENT ){
-    if( makeDirectory(zFile)==SQLITE_OK ){
-      res = writeFile(context, zFile, argv[1], mode, mtime);
-    }
-  }
-
-  if( argc>2 && res!=0 ){
-    if( S_ISLNK(mode) ){
-      ctxErrorMsg(context, "failed to create symlink: %s", zFile);
-    }else if( S_ISDIR(mode) ){
-      ctxErrorMsg(context, "failed to create directory: %s", zFile);
-    }else{
-      ctxErrorMsg(context, "failed to write file: %s", zFile);
-    }
-  }
-}
-
-/*
-** SQL function:   lsmode(MODE)
-**
-** Given a numberic st_mode from stat(), convert it into a human-readable
-** text string in the style of "ls -l".
-*/
-static void lsModeFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  int i;
-  int iMode = sqlite3_value_int(argv[0]);
-  char z[16];
-  (void)argc;
-  if( S_ISLNK(iMode) ){
-    z[0] = 'l';
-  }else if( S_ISREG(iMode) ){
-    z[0] = '-';
-  }else if( S_ISDIR(iMode) ){
-    z[0] = 'd';
-  }else{
-    z[0] = '?';
-  }
-  for(i=0; i<3; i++){
-    int m = (iMode >> ((2-i)*3));
-    char *a = &z[1 + i*3];
-    a[0] = (m & 0x4) ? 'r' : '-';
-    a[1] = (m & 0x2) ? 'w' : '-';
-    a[2] = (m & 0x1) ? 'x' : '-';
-  }
-  z[10] = '\0';
-  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
-}
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-
-/* 
-** Cursor type for recursively iterating through a directory structure.
-*/
-typedef struct fsdir_cursor fsdir_cursor;
-typedef struct FsdirLevel FsdirLevel;
-
-struct FsdirLevel {
-  DIR *pDir;                 /* From opendir() */
-  char *zDir;                /* Name of directory (nul-terminated) */
-};
-
-struct fsdir_cursor {
-  sqlite3_vtab_cursor base;  /* Base class - must be first */
-
-  int nLvl;                  /* Number of entries in aLvl[] array */
-  int iLvl;                  /* Index of current entry */
-  FsdirLevel *aLvl;          /* Hierarchy of directories being traversed */
-
-  const char *zBase;
-  int nBase;
-
-  struct stat sStat;         /* Current lstat() results */
-  char *zPath;               /* Path to current entry */
-  sqlite3_int64 iRowid;      /* Current rowid */
-};
-
-typedef struct fsdir_tab fsdir_tab;
-struct fsdir_tab {
-  sqlite3_vtab base;         /* Base class - must be first */
-};
-
-/*
-** Construct a new fsdir virtual table object.
-*/
-static int fsdirConnect(
-  sqlite3 *db,
-  void *pAux,
-  int argc, const char *const*argv,
-  sqlite3_vtab **ppVtab,
-  char **pzErr
-){
-  fsdir_tab *pNew = 0;
-  int rc;
-  (void)pAux;
-  (void)argc;
-  (void)argv;
-  (void)pzErr;
-  rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
-  if( rc==SQLITE_OK ){
-    pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
-    if( pNew==0 ) return SQLITE_NOMEM;
-    memset(pNew, 0, sizeof(*pNew));
-    sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
-  }
-  *ppVtab = (sqlite3_vtab*)pNew;
-  return rc;
-}
-
-/*
-** This method is the destructor for fsdir vtab objects.
-*/
-static int fsdirDisconnect(sqlite3_vtab *pVtab){
-  sqlite3_free(pVtab);
-  return SQLITE_OK;
-}
-
-/*
-** Constructor for a new fsdir_cursor object.
-*/
-static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
-  fsdir_cursor *pCur;
-  (void)p;
-  pCur = sqlite3_malloc( sizeof(*pCur) );
-  if( pCur==0 ) return SQLITE_NOMEM;
-  memset(pCur, 0, sizeof(*pCur));
-  pCur->iLvl = -1;
-  *ppCursor = &pCur->base;
-  return SQLITE_OK;
-}
-
-/*
-** Reset a cursor back to the state it was in when first returned
-** by fsdirOpen().
-*/
-static void fsdirResetCursor(fsdir_cursor *pCur){
-  int i;
-  for(i=0; i<=pCur->iLvl; i++){
-    FsdirLevel *pLvl = &pCur->aLvl[i];
-    if( pLvl->pDir ) closedir(pLvl->pDir);
-    sqlite3_free(pLvl->zDir);
-  }
-  sqlite3_free(pCur->zPath);
-  sqlite3_free(pCur->aLvl);
-  pCur->aLvl = 0;
-  pCur->zPath = 0;
-  pCur->zBase = 0;
-  pCur->nBase = 0;
-  pCur->nLvl = 0;
-  pCur->iLvl = -1;
-  pCur->iRowid = 1;
-}
-
-/*
-** Destructor for an fsdir_cursor.
-*/
-static int fsdirClose(sqlite3_vtab_cursor *cur){
-  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-
-  fsdirResetCursor(pCur);
-  sqlite3_free(pCur);
-  return SQLITE_OK;
-}
-
-/*
-** Set the error message for the virtual table associated with cursor
-** pCur to the results of vprintf(zFmt, ...).
-*/
-static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
-  va_list ap;
-  va_start(ap, zFmt);
-  pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
-  va_end(ap);
-}
-
-
-/*
-** Advance an fsdir_cursor to its next row of output.
-*/
-static int fsdirNext(sqlite3_vtab_cursor *cur){
-  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-  mode_t m = pCur->sStat.st_mode;
-
-  pCur->iRowid++;
-  if( S_ISDIR(m) ){
-    /* Descend into this directory */
-    int iNew = pCur->iLvl + 1;
-    FsdirLevel *pLvl;
-    if( iNew>=pCur->nLvl ){
-      int nNew = iNew+1;
-      sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
-      FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
-      if( aNew==0 ) return SQLITE_NOMEM;
-      memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
-      pCur->aLvl = aNew;
-      pCur->nLvl = nNew;
-    }
-    pCur->iLvl = iNew;
-    pLvl = &pCur->aLvl[iNew];
-    
-    pLvl->zDir = pCur->zPath;
-    pCur->zPath = 0;
-    pLvl->pDir = opendir(pLvl->zDir);
-    if( pLvl->pDir==0 ){
-      fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
-      return SQLITE_ERROR;
-    }
-  }
-
-  while( pCur->iLvl>=0 ){
-    FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
-    struct dirent *pEntry = readdir(pLvl->pDir);
-    if( pEntry ){
-      if( pEntry->d_name[0]=='.' ){
-       if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
-       if( pEntry->d_name[1]=='\0' ) continue;
-      }
-      sqlite3_free(pCur->zPath);
-      pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
-      if( pCur->zPath==0 ) return SQLITE_NOMEM;
-      if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
-        fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
-        return SQLITE_ERROR;
-      }
-      return SQLITE_OK;
-    }
-    closedir(pLvl->pDir);
-    sqlite3_free(pLvl->zDir);
-    pLvl->pDir = 0;
-    pLvl->zDir = 0;
-    pCur->iLvl--;
-  }
-
-  /* EOF */
-  sqlite3_free(pCur->zPath);
-  pCur->zPath = 0;
-  return SQLITE_OK;
-}
-
-/*
-** Return values of columns for the row at which the series_cursor
-** is currently pointing.
-*/
-static int fsdirColumn(
-  sqlite3_vtab_cursor *cur,   /* The cursor */
-  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
-  int i                       /* Which column to return */
-){
-  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-  switch( i ){
-    case FSDIR_COLUMN_NAME: {
-      sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
-      break;
-    }
-
-    case FSDIR_COLUMN_MODE:
-      sqlite3_result_int64(ctx, pCur->sStat.st_mode);
-      break;
-
-    case FSDIR_COLUMN_MTIME:
-      sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
-      break;
-
-    case FSDIR_COLUMN_DATA: {
-      mode_t m = pCur->sStat.st_mode;
-      if( S_ISDIR(m) ){
-        sqlite3_result_null(ctx);
-#if !defined(_WIN32) && !defined(WIN32)
-      }else if( S_ISLNK(m) ){
-        char aStatic[64];
-        char *aBuf = aStatic;
-        sqlite3_int64 nBuf = 64;
-        int n;
-
-        while( 1 ){
-          n = readlink(pCur->zPath, aBuf, nBuf);
-          if( n<nBuf ) break;
-          if( aBuf!=aStatic ) sqlite3_free(aBuf);
-          nBuf = nBuf*2;
-          aBuf = sqlite3_malloc64(nBuf);
-          if( aBuf==0 ){
-            sqlite3_result_error_nomem(ctx);
-            return SQLITE_NOMEM;
-          }
-        }
-
-        sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
-        if( aBuf!=aStatic ) sqlite3_free(aBuf);
-#endif
-      }else{
-        readFileContents(ctx, pCur->zPath);
-      }
-    }
-    case FSDIR_COLUMN_PATH:
-    default: {
-      /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
-      ** always return their values as NULL */
-      break;
-    }
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Return the rowid for the current row. In this implementation, the
-** first row returned is assigned rowid value 1, and each subsequent
-** row a value 1 more than that of the previous.
-*/
-static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
-  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-  *pRowid = pCur->iRowid;
-  return SQLITE_OK;
-}
-
-/*
-** Return TRUE if the cursor has been moved off of the last
-** row of output.
-*/
-static int fsdirEof(sqlite3_vtab_cursor *cur){
-  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-  return (pCur->zPath==0);
-}
-
-/*
-** xFilter callback.
-**
-** idxNum==1   PATH parameter only
-** idxNum==2   Both PATH and DIR supplied
-*/
-static int fsdirFilter(
-  sqlite3_vtab_cursor *cur, 
-  int idxNum, const char *idxStr,
-  int argc, sqlite3_value **argv
-){
-  const char *zDir = 0;
-  fsdir_cursor *pCur = (fsdir_cursor*)cur;
-  (void)idxStr;
-  fsdirResetCursor(pCur);
-
-  if( idxNum==0 ){
-    fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
-    return SQLITE_ERROR;
-  }
-
-  assert( argc==idxNum && (argc==1 || argc==2) );
-  zDir = (const char*)sqlite3_value_text(argv[0]);
-  if( zDir==0 ){
-    fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
-    return SQLITE_ERROR;
-  }
-  if( argc==2 ){
-    pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
-  }
-  if( pCur->zBase ){
-    pCur->nBase = (int)strlen(pCur->zBase)+1;
-    pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
-  }else{
-    pCur->zPath = sqlite3_mprintf("%s", zDir);
-  }
-
-  if( pCur->zPath==0 ){
-    return SQLITE_NOMEM;
-  }
-  if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
-    fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
-    return SQLITE_ERROR;
-  }
-
-  return SQLITE_OK;
-}
-
-/*
-** SQLite will invoke this method one or more times while planning a query
-** that uses the generate_series virtual table.  This routine needs to create
-** a query plan for each invocation and compute an estimated cost for that
-** plan.
-**
-** In this implementation idxNum is used to represent the
-** query plan.  idxStr is unused.
-**
-** The query plan is represented by values of idxNum:
-**
-**  (1)  The path value is supplied by argv[0]
-**  (2)  Path is in argv[0] and dir is in argv[1]
-*/
-static int fsdirBestIndex(
-  sqlite3_vtab *tab,
-  sqlite3_index_info *pIdxInfo
-){
-  int i;                 /* Loop over constraints */
-  int idxPath = -1;      /* Index in pIdxInfo->aConstraint of PATH= */
-  int idxDir = -1;       /* Index in pIdxInfo->aConstraint of DIR= */
-  int seenPath = 0;      /* True if an unusable PATH= constraint is seen */
-  int seenDir = 0;       /* True if an unusable DIR= constraint is seen */
-  const struct sqlite3_index_constraint *pConstraint;
-
-  (void)tab;
-  pConstraint = pIdxInfo->aConstraint;
-  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
-    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
-    switch( pConstraint->iColumn ){
-      case FSDIR_COLUMN_PATH: {
-        if( pConstraint->usable ){
-          idxPath = i;
-          seenPath = 0;
-        }else if( idxPath<0 ){
-          seenPath = 1;
-        }
-        break;
-      }
-      case FSDIR_COLUMN_DIR: {
-        if( pConstraint->usable ){
-          idxDir = i;
-          seenDir = 0;
-        }else if( idxDir<0 ){
-          seenDir = 1;
-        }
-        break;
-      }
-    } 
-  }
-  if( seenPath || seenDir ){
-    /* If input parameters are unusable, disallow this plan */
-    return SQLITE_CONSTRAINT;
-  }
-
-  if( idxPath<0 ){
-    pIdxInfo->idxNum = 0;
-    /* The pIdxInfo->estimatedCost should have been initialized to a huge
-    ** number.  Leave it unchanged. */
-    pIdxInfo->estimatedRows = 0x7fffffff;
-  }else{
-    pIdxInfo->aConstraintUsage[idxPath].omit = 1;
-    pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
-    if( idxDir>=0 ){
-      pIdxInfo->aConstraintUsage[idxDir].omit = 1;
-      pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
-      pIdxInfo->idxNum = 2;
-      pIdxInfo->estimatedCost = 10.0;
-    }else{
-      pIdxInfo->idxNum = 1;
-      pIdxInfo->estimatedCost = 100.0;
-    }
-  }
-
-  return SQLITE_OK;
-}
-
-/*
-** Register the "fsdir" virtual table.
-*/
-static int fsdirRegister(sqlite3 *db){
-  static sqlite3_module fsdirModule = {
-    0,                         /* iVersion */
-    0,                         /* xCreate */
-    fsdirConnect,              /* xConnect */
-    fsdirBestIndex,            /* xBestIndex */
-    fsdirDisconnect,           /* xDisconnect */
-    0,                         /* xDestroy */
-    fsdirOpen,                 /* xOpen - open a cursor */
-    fsdirClose,                /* xClose - close a cursor */
-    fsdirFilter,               /* xFilter - configure scan constraints */
-    fsdirNext,                 /* xNext - advance a cursor */
-    fsdirEof,                  /* xEof - check for end of scan */
-    fsdirColumn,               /* xColumn - read data */
-    fsdirRowid,                /* xRowid - read data */
-    0,                         /* xUpdate */
-    0,                         /* xBegin */
-    0,                         /* xSync */
-    0,                         /* xCommit */
-    0,                         /* xRollback */
-    0,                         /* xFindMethod */
-    0,                         /* xRename */
-    0,                         /* xSavepoint */
-    0,                         /* xRelease */
-    0,                         /* xRollbackTo */
-    0,                         /* xShadowName */
-  };
-
-  int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
-  return rc;
-}
-#else         /* SQLITE_OMIT_VIRTUALTABLE */
-# define fsdirRegister(x) SQLITE_OK
-#endif
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_fileio_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
-  int rc = SQLITE_OK;
-  SQLITE_EXTENSION_INIT2(pApi);
-  (void)pzErrMsg;  /* Unused parameter */
-  rc = sqlite3_create_function(db, "readfile", 1, 
-                               SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
-                               readfileFunc, 0, 0);
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_create_function(db, "writefile", -1,
-                                 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
-                                 writefileFunc, 0, 0);
-  }
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
-                                 lsModeFunc, 0, 0);
-  }
-  if( rc==SQLITE_OK ){
-    rc = fsdirRegister(db);
-  }
-  return rc;
-}
-
-#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
-/* To allow a standalone DLL, make test_windirent.c use the same
- * redefined SQLite API calls as the above extension code does.
- * Just pull in this .c to accomplish this. As a beneficial side
- * effect, this extension becomes a single translation unit. */
-#  include "test_windirent.c"
-#endif
-
-/************************* End ../ext/misc/fileio.c ********************/
-/************************* Begin ../ext/misc/completion.c ******************/
-/*
-** 2017-07-10
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file implements an eponymous virtual table that returns suggested
-** completions for a partial SQL input.
-**
-** Suggested usage:
-**
-**     SELECT DISTINCT candidate COLLATE nocase
-**       FROM completion($prefix,$wholeline)
-**      ORDER BY 1;
-**
-** The two query parameters are optional.  $prefix is the text of the
-** current word being typed and that is to be completed.  $wholeline is
-** the complete input line, used for context.
-**
-** The raw completion() table might return the same candidate multiple
-** times, for example if the same column name is used to two or more
-** tables.  And the candidates are returned in an arbitrary order.  Hence,
-** the DISTINCT and ORDER BY are recommended.
-**
-** This virtual table operates at the speed of human typing, and so there
-** is no attempt to make it fast.  Even a slow implementation will be much
-** faster than any human can type.
-**
-*/
-/* #include "sqlite3ext.h" */
-SQLITE_EXTENSION_INIT1
-#include <assert.h>
-#include <string.h>
-#include <ctype.h>
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-
-/* completion_vtab is a subclass of sqlite3_vtab which will
-** serve as the underlying representation of a completion virtual table
-*/
-typedef struct completion_vtab completion_vtab;
-struct completion_vtab {
-  sqlite3_vtab base;  /* Base class - must be first */
-  sqlite3 *db;        /* Database connection for this completion vtab */
-};
-
-/* completion_cursor is a subclass of sqlite3_vtab_cursor which will
-** serve as the underlying representation of a cursor that scans
-** over rows of the result
-*/
-typedef struct completion_cursor completion_cursor;
-struct completion_cursor {
-  sqlite3_vtab_cursor base;  /* Base class - must be first */
-  sqlite3 *db;               /* Database connection for this cursor */
-  int nPrefix, nLine;        /* Number of bytes in zPrefix and zLine */
-  char *zPrefix;             /* The prefix for the word we want to complete */
-  char *zLine;               /* The whole that we want to complete */
-  const char *zCurrentRow;   /* Current output row */
-  int szRow;                 /* Length of the zCurrentRow string */
-  sqlite3_stmt *pStmt;       /* Current statement */
-  sqlite3_int64 iRowid;      /* The rowid */
-  int ePhase;                /* Current phase */
-  int j;                     /* inter-phase counter */
-};
-
-/* Values for ePhase:
-*/
-#define COMPLETION_FIRST_PHASE   1
-#define COMPLETION_KEYWORDS      1
-#define COMPLETION_PRAGMAS       2
-#define COMPLETION_FUNCTIONS     3
-#define COMPLETION_COLLATIONS    4
-#define COMPLETION_INDEXES       5
-#define COMPLETION_TRIGGERS      6
-#define COMPLETION_DATABASES     7
-#define COMPLETION_TABLES        8    /* Also VIEWs and TRIGGERs */
-#define COMPLETION_COLUMNS       9
-#define COMPLETION_MODULES       10
-#define COMPLETION_EOF           11
-
-/*
-** The completionConnect() method is invoked to create a new
-** completion_vtab that describes the completion virtual table.
-**
-** Think of this routine as the constructor for completion_vtab objects.
-**
-** All this routine needs to do is:
-**
-**    (1) Allocate the completion_vtab object and initialize all fields.
-**
-**    (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
-**        result set of queries against completion will look like.
-*/
-static int completionConnect(
-  sqlite3 *db,
-  void *pAux,
-  int argc, const char *const*argv,
-  sqlite3_vtab **ppVtab,
-  char **pzErr
-){
-  completion_vtab *pNew;
-  int rc;
-
-  (void)(pAux);    /* Unused parameter */
-  (void)(argc);    /* Unused parameter */
-  (void)(argv);    /* Unused parameter */
-  (void)(pzErr);   /* Unused parameter */
-
-/* Column numbers */
-#define COMPLETION_COLUMN_CANDIDATE 0  /* Suggested completion of the input */
-#define COMPLETION_COLUMN_PREFIX    1  /* Prefix of the word to be completed */
-#define COMPLETION_COLUMN_WHOLELINE 2  /* Entire line seen so far */
-#define COMPLETION_COLUMN_PHASE     3  /* ePhase - used for debugging only */
-
-  sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
-  rc = sqlite3_declare_vtab(db,
-      "CREATE TABLE x("
-      "  candidate TEXT,"
-      "  prefix TEXT HIDDEN,"
-      "  wholeline TEXT HIDDEN,"
-      "  phase INT HIDDEN"        /* Used for debugging only */
-      ")");
-  if( rc==SQLITE_OK ){
-    pNew = sqlite3_malloc( sizeof(*pNew) );
-    *ppVtab = (sqlite3_vtab*)pNew;
-    if( pNew==0 ) return SQLITE_NOMEM;
-    memset(pNew, 0, sizeof(*pNew));
-    pNew->db = db;
-  }
-  return rc;
-}
-
-/*
-** This method is the destructor for completion_cursor objects.
-*/
-static int completionDisconnect(sqlite3_vtab *pVtab){
-  sqlite3_free(pVtab);
-  return SQLITE_OK;
-}
-
-/*
-** Constructor for a new completion_cursor object.
-*/
-static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
-  completion_cursor *pCur;
-  pCur = sqlite3_malloc( sizeof(*pCur) );
-  if( pCur==0 ) return SQLITE_NOMEM;
-  memset(pCur, 0, sizeof(*pCur));
-  pCur->db = ((completion_vtab*)p)->db;
-  *ppCursor = &pCur->base;
-  return SQLITE_OK;
-}
-
-/*
-** Reset the completion_cursor.
-*/
-static void completionCursorReset(completion_cursor *pCur){
-  sqlite3_free(pCur->zPrefix);   pCur->zPrefix = 0;  pCur->nPrefix = 0;
-  sqlite3_free(pCur->zLine);     pCur->zLine = 0;    pCur->nLine = 0;
-  sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0;
-  pCur->j = 0;
-}
-
-/*
-** Destructor for a completion_cursor.
-*/
-static int completionClose(sqlite3_vtab_cursor *cur){
-  completionCursorReset((completion_cursor*)cur);
-  sqlite3_free(cur);
-  return SQLITE_OK;
-}
-
-/*
-** Advance a completion_cursor to its next row of output.
-**
-** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object
-** record the current state of the scan.  This routine sets ->zCurrentRow
-** to the current row of output and then returns.  If no more rows remain,
-** then ->ePhase is set to COMPLETION_EOF which will signal the virtual
-** table that has reached the end of its scan.
-**
-** The current implementation just lists potential identifiers and
-** keywords and filters them by zPrefix.  Future enhancements should
-** take zLine into account to try to restrict the set of identifiers and
-** keywords based on what would be legal at the current point of input.
-*/
-static int completionNext(sqlite3_vtab_cursor *cur){
-  completion_cursor *pCur = (completion_cursor*)cur;
-  int eNextPhase = 0;  /* Next phase to try if current phase reaches end */
-  int iCol = -1;       /* If >=0, step pCur->pStmt and use the i-th column */
-  pCur->iRowid++;
-  while( pCur->ePhase!=COMPLETION_EOF ){
-    switch( pCur->ePhase ){
-      case COMPLETION_KEYWORDS: {
-        if( pCur->j >= sqlite3_keyword_count() ){
-          pCur->zCurrentRow = 0;
-          pCur->ePhase = COMPLETION_DATABASES;
-        }else{
-          sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow);
-        }
-        iCol = -1;
-        break;
-      }
-      case COMPLETION_DATABASES: {
-        if( pCur->pStmt==0 ){
-          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1,
-                             &pCur->pStmt, 0);
-        }
-        iCol = 1;
-        eNextPhase = COMPLETION_TABLES;
-        break;
-      }
-      case COMPLETION_TABLES: {
-        if( pCur->pStmt==0 ){
-          sqlite3_stmt *pS2;
-          char *zSql = 0;
-          const char *zSep = "";
-          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
-          while( sqlite3_step(pS2)==SQLITE_ROW ){
-            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
-            zSql = sqlite3_mprintf(
-               "%z%s"
-               "SELECT name FROM \"%w\".sqlite_schema",
-               zSql, zSep, zDb
-            );
-            if( zSql==0 ) return SQLITE_NOMEM;
-            zSep = " UNION ";
-          }
-          sqlite3_finalize(pS2);
-          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
-          sqlite3_free(zSql);
-        }
-        iCol = 0;
-        eNextPhase = COMPLETION_COLUMNS;
-        break;
-      }
-      case COMPLETION_COLUMNS: {
-        if( pCur->pStmt==0 ){
-          sqlite3_stmt *pS2;
-          char *zSql = 0;
-          const char *zSep = "";
-          sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0);
-          while( sqlite3_step(pS2)==SQLITE_ROW ){
-            const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
-            zSql = sqlite3_mprintf(
-               "%z%s"
-               "SELECT pti.name FROM \"%w\".sqlite_schema AS sm"
-                       " JOIN pragma_table_info(sm.name,%Q) AS pti"
-               " WHERE sm.type='table'",
-               zSql, zSep, zDb, zDb
-            );
-            if( zSql==0 ) return SQLITE_NOMEM;
-            zSep = " UNION ";
-          }
-          sqlite3_finalize(pS2);
-          sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
-          sqlite3_free(zSql);
-        }
-        iCol = 0;
-        eNextPhase = COMPLETION_EOF;
-        break;
-      }
-    }
-    if( iCol<0 ){
-      /* This case is when the phase presets zCurrentRow */
-      if( pCur->zCurrentRow==0 ) continue;
-    }else{
-      if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){
-        /* Extract the next row of content */
-        pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol);
-        pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol);
-      }else{
-        /* When all rows are finished, advance to the next phase */
-        sqlite3_finalize(pCur->pStmt);
-        pCur->pStmt = 0;
-        pCur->ePhase = eNextPhase;
-        continue;
-      }
-    }
-    if( pCur->nPrefix==0 ) break;
-    if( pCur->nPrefix<=pCur->szRow
-     && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0
-    ){
-      break;
-    }
-  }
-
-  return SQLITE_OK;
-}
-
-/*
-** Return values of columns for the row at which the completion_cursor
-** is currently pointing.
-*/
-static int completionColumn(
-  sqlite3_vtab_cursor *cur,   /* The cursor */
-  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
-  int i                       /* Which column to return */
-){
-  completion_cursor *pCur = (completion_cursor*)cur;
-  switch( i ){
-    case COMPLETION_COLUMN_CANDIDATE: {
-      sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT);
-      break;
-    }
-    case COMPLETION_COLUMN_PREFIX: {
-      sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT);
-      break;
-    }
-    case COMPLETION_COLUMN_WHOLELINE: {
-      sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT);
-      break;
-    }
-    case COMPLETION_COLUMN_PHASE: {
-      sqlite3_result_int(ctx, pCur->ePhase);
-      break;
-    }
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Return the rowid for the current row.  In this implementation, the
-** rowid is the same as the output value.
-*/
-static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
-  completion_cursor *pCur = (completion_cursor*)cur;
-  *pRowid = pCur->iRowid;
-  return SQLITE_OK;
-}
-
-/*
-** Return TRUE if the cursor has been moved off of the last
-** row of output.
-*/
-static int completionEof(sqlite3_vtab_cursor *cur){
-  completion_cursor *pCur = (completion_cursor*)cur;
-  return pCur->ePhase >= COMPLETION_EOF;
-}
-
-/*
-** This method is called to "rewind" the completion_cursor object back
-** to the first row of output.  This method is always called at least
-** once prior to any call to completionColumn() or completionRowid() or 
-** completionEof().
-*/
-static int completionFilter(
-  sqlite3_vtab_cursor *pVtabCursor, 
-  int idxNum, const char *idxStr,
-  int argc, sqlite3_value **argv
-){
-  completion_cursor *pCur = (completion_cursor *)pVtabCursor;
-  int iArg = 0;
-  (void)(idxStr);   /* Unused parameter */
-  (void)(argc);     /* Unused parameter */
-  completionCursorReset(pCur);
-  if( idxNum & 1 ){
-    pCur->nPrefix = sqlite3_value_bytes(argv[iArg]);
-    if( pCur->nPrefix>0 ){
-      pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
-      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
-    }
-    iArg = 1;
-  }
-  if( idxNum & 2 ){
-    pCur->nLine = sqlite3_value_bytes(argv[iArg]);
-    if( pCur->nLine>0 ){
-      pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
-      if( pCur->zLine==0 ) return SQLITE_NOMEM;
-    }
-  }
-  if( pCur->zLine!=0 && pCur->zPrefix==0 ){
-    int i = pCur->nLine;
-    while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
-      i--;
-    }
-    pCur->nPrefix = pCur->nLine - i;
-    if( pCur->nPrefix>0 ){
-      pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
-      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
-    }
-  }
-  pCur->iRowid = 0;
-  pCur->ePhase = COMPLETION_FIRST_PHASE;
-  return completionNext(pVtabCursor);
-}
-
-/*
-** SQLite will invoke this method one or more times while planning a query
-** that uses the completion virtual table.  This routine needs to create
-** a query plan for each invocation and compute an estimated cost for that
-** plan.
-**
-** There are two hidden parameters that act as arguments to the table-valued
-** function:  "prefix" and "wholeline".  Bit 0 of idxNum is set if "prefix"
-** is available and bit 1 is set if "wholeline" is available.
-*/
-static int completionBestIndex(
-  sqlite3_vtab *tab,
-  sqlite3_index_info *pIdxInfo
-){
-  int i;                 /* Loop over constraints */
-  int idxNum = 0;        /* The query plan bitmask */
-  int prefixIdx = -1;    /* Index of the start= constraint, or -1 if none */
-  int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */
-  int nArg = 0;          /* Number of arguments that completeFilter() expects */
-  const struct sqlite3_index_constraint *pConstraint;
-
-  (void)(tab);    /* Unused parameter */
-  pConstraint = pIdxInfo->aConstraint;
-  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
-    if( pConstraint->usable==0 ) continue;
-    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
-    switch( pConstraint->iColumn ){
-      case COMPLETION_COLUMN_PREFIX:
-        prefixIdx = i;
-        idxNum |= 1;
-        break;
-      case COMPLETION_COLUMN_WHOLELINE:
-        wholelineIdx = i;
-        idxNum |= 2;
-        break;
-    }
-  }
-  if( prefixIdx>=0 ){
-    pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg;
-    pIdxInfo->aConstraintUsage[prefixIdx].omit = 1;
-  }
-  if( wholelineIdx>=0 ){
-    pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg;
-    pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1;
-  }
-  pIdxInfo->idxNum = idxNum;
-  pIdxInfo->estimatedCost = (double)5000 - 1000*nArg;
-  pIdxInfo->estimatedRows = 500 - 100*nArg;
-  return SQLITE_OK;
-}
-
-/*
-** This following structure defines all the methods for the 
-** completion virtual table.
-*/
-static sqlite3_module completionModule = {
-  0,                         /* iVersion */
-  0,                         /* xCreate */
-  completionConnect,         /* xConnect */
-  completionBestIndex,       /* xBestIndex */
-  completionDisconnect,      /* xDisconnect */
-  0,                         /* xDestroy */
-  completionOpen,            /* xOpen - open a cursor */
-  completionClose,           /* xClose - close a cursor */
-  completionFilter,          /* xFilter - configure scan constraints */
-  completionNext,            /* xNext - advance a cursor */
-  completionEof,             /* xEof - check for end of scan */
-  completionColumn,          /* xColumn - read data */
-  completionRowid,           /* xRowid - read data */
-  0,                         /* xUpdate */
-  0,                         /* xBegin */
-  0,                         /* xSync */
-  0,                         /* xCommit */
-  0,                         /* xRollback */
-  0,                         /* xFindMethod */
-  0,                         /* xRename */
-  0,                         /* xSavepoint */
-  0,                         /* xRelease */
-  0,                         /* xRollbackTo */
-  0                          /* xShadowName */
-};
-
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
-
-int sqlite3CompletionVtabInit(sqlite3 *db){
-  int rc = SQLITE_OK;
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-  rc = sqlite3_create_module(db, "completion", &completionModule, 0);
-#endif
-  return rc;
-}
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_completion_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
-  int rc = SQLITE_OK;
-  SQLITE_EXTENSION_INIT2(pApi);
-  (void)(pzErrMsg);  /* Unused parameter */
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-  rc = sqlite3CompletionVtabInit(db);
-#endif
-  return rc;
-}
-
-/************************* End ../ext/misc/completion.c ********************/
-/************************* Begin ../ext/misc/appendvfs.c ******************/
-/*
-** 2017-10-20
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file implements a VFS shim that allows an SQLite database to be
-** appended onto the end of some other file, such as an executable.
-**
-** A special record must appear at the end of the file that identifies the
-** file as an appended database and provides the offset to the first page
-** of the exposed content. (Or, it is the length of the content prefix.)
-** For best performance page 1 should be located at a disk page boundary,
-** though that is not required.
-**
-** When opening a database using this VFS, the connection might treat
-** the file as an ordinary SQLite database, or it might treat it as a
-** database appended onto some other file.  The decision is made by
-** applying the following rules in order:
-**
-**  (1)  An empty file is an ordinary database.
-**
-**  (2)  If the file ends with the appendvfs trailer string
-**       "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
-**
-**  (3)  If the file begins with the standard SQLite prefix string
-**       "SQLite format 3", that file is an ordinary database.
-**
-**  (4)  If none of the above apply and the SQLITE_OPEN_CREATE flag is
-**       set, then a new database is appended to the already existing file.
-**
-**  (5)  Otherwise, SQLITE_CANTOPEN is returned.
-**
-** To avoid unnecessary complications with the PENDING_BYTE, the size of
-** the file containing the database is limited to 1GiB. (1073741824 bytes)
-** This VFS will not read or write past the 1GiB mark.  This restriction
-** might be lifted in future versions.  For now, if you need a larger
-** database, then keep it in a separate file.
-**
-** If the file being opened is a plain database (not an appended one), then
-** this shim is a pass-through into the default underlying VFS. (rule 3)
-**/
-/* #include "sqlite3ext.h" */
-SQLITE_EXTENSION_INIT1
-#include <string.h>
-#include <assert.h>
-
-/* The append mark at the end of the database is:
-**
-**     Start-Of-SQLite3-NNNNNNNN
-**     123456789 123456789 12345
-**
-** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
-** the offset to page 1, and also the length of the prefix content.
-*/
-#define APND_MARK_PREFIX     "Start-Of-SQLite3-"
-#define APND_MARK_PREFIX_SZ  17
-#define APND_MARK_FOS_SZ      8
-#define APND_MARK_SIZE       (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ)
-
-/*
-** Maximum size of the combined prefix + database + append-mark.  This
-** must be less than 0x40000000 to avoid locking issues on Windows.
-*/
-#define APND_MAX_SIZE  (0x40000000)
-
-/*
-** Try to align the database to an even multiple of APND_ROUNDUP bytes.
-*/
-#ifndef APND_ROUNDUP
-#define APND_ROUNDUP 4096
-#endif
-#define APND_ALIGN_MASK         ((sqlite3_int64)(APND_ROUNDUP-1))
-#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK)
-
-/*
-** Forward declaration of objects used by this utility
-*/
-typedef struct sqlite3_vfs ApndVfs;
-typedef struct ApndFile ApndFile;
-
-/* Access to a lower-level VFS that (might) implement dynamic loading,
-** access to randomness, etc.
-*/
-#define ORIGVFS(p)  ((sqlite3_vfs*)((p)->pAppData))
-#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
-
-/* An open appendvfs file
-**
-** An instance of this structure describes the appended database file.
-** A separate sqlite3_file object is always appended. The appended
-** sqlite3_file object (which can be accessed using ORIGFILE()) describes
-** the entire file, including the prefix, the database, and the
-** append-mark.
-**
-** The structure of an AppendVFS database is like this:
-**
-**   +-------------+---------+----------+-------------+
-**   | prefix-file | padding | database | append-mark |
-**   +-------------+---------+----------+-------------+
-**                           ^          ^
-**                           |          |
-**                         iPgOne      iMark
-**
-**
-** "prefix file" -  file onto which the database has been appended.
-** "padding"     -  zero or more bytes inserted so that "database"
-**                  starts on an APND_ROUNDUP boundary
-** "database"    -  The SQLite database file
-** "append-mark" -  The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates
-**                  the offset from the start of prefix-file to the start
-**                  of "database".
-**
-** The size of the database is iMark - iPgOne.
-**
-** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value
-** of iPgOne stored as a big-ending 64-bit integer.
-**
-** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE).
-** Or, iMark is -1 to indicate that it has not yet been written.
-*/
-struct ApndFile {
-  sqlite3_file base;        /* Subclass.  MUST BE FIRST! */
-  sqlite3_int64 iPgOne;     /* Offset to the start of the database */
-  sqlite3_int64 iMark;      /* Offset of the append mark.  -1 if unwritten */
-  /* Always followed by another sqlite3_file that describes the whole file */
-};
-
-/*
-** Methods for ApndFile
-*/
-static int apndClose(sqlite3_file*);
-static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
-static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
-static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
-static int apndSync(sqlite3_file*, int flags);
-static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
-static int apndLock(sqlite3_file*, int);
-static int apndUnlock(sqlite3_file*, int);
-static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
-static int apndFileControl(sqlite3_file*, int op, void *pArg);
-static int apndSectorSize(sqlite3_file*);
-static int apndDeviceCharacteristics(sqlite3_file*);
-static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
-static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
-static void apndShmBarrier(sqlite3_file*);
-static int apndShmUnmap(sqlite3_file*, int deleteFlag);
-static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
-static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
-
-/*
-** Methods for ApndVfs
-*/
-static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
-static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
-static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
-static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
-static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
-static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
-static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
-static void apndDlClose(sqlite3_vfs*, void*);
-static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
-static int apndSleep(sqlite3_vfs*, int microseconds);
-static int apndCurrentTime(sqlite3_vfs*, double*);
-static int apndGetLastError(sqlite3_vfs*, int, char *);
-static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
-static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
-static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
-static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);
-
-static sqlite3_vfs apnd_vfs = {
-  3,                            /* iVersion (set when registered) */
-  0,                            /* szOsFile (set when registered) */
-  1024,                         /* mxPathname */
-  0,                            /* pNext */
-  "apndvfs",                    /* zName */
-  0,                            /* pAppData (set when registered) */ 
-  apndOpen,                     /* xOpen */
-  apndDelete,                   /* xDelete */
-  apndAccess,                   /* xAccess */
-  apndFullPathname,             /* xFullPathname */
-  apndDlOpen,                   /* xDlOpen */
-  apndDlError,                  /* xDlError */
-  apndDlSym,                    /* xDlSym */
-  apndDlClose,                  /* xDlClose */
-  apndRandomness,               /* xRandomness */
-  apndSleep,                    /* xSleep */
-  apndCurrentTime,              /* xCurrentTime */
-  apndGetLastError,             /* xGetLastError */
-  apndCurrentTimeInt64,         /* xCurrentTimeInt64 */
-  apndSetSystemCall,            /* xSetSystemCall */
-  apndGetSystemCall,            /* xGetSystemCall */
-  apndNextSystemCall            /* xNextSystemCall */
-};
-
-static const sqlite3_io_methods apnd_io_methods = {
-  3,                              /* iVersion */
-  apndClose,                      /* xClose */
-  apndRead,                       /* xRead */
-  apndWrite,                      /* xWrite */
-  apndTruncate,                   /* xTruncate */
-  apndSync,                       /* xSync */
-  apndFileSize,                   /* xFileSize */
-  apndLock,                       /* xLock */
-  apndUnlock,                     /* xUnlock */
-  apndCheckReservedLock,          /* xCheckReservedLock */
-  apndFileControl,                /* xFileControl */
-  apndSectorSize,                 /* xSectorSize */
-  apndDeviceCharacteristics,      /* xDeviceCharacteristics */
-  apndShmMap,                     /* xShmMap */
-  apndShmLock,                    /* xShmLock */
-  apndShmBarrier,                 /* xShmBarrier */
-  apndShmUnmap,                   /* xShmUnmap */
-  apndFetch,                      /* xFetch */
-  apndUnfetch                     /* xUnfetch */
-};
-
-/*
-** Close an apnd-file.
-*/
-static int apndClose(sqlite3_file *pFile){
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xClose(pFile);
-}
-
-/*
-** Read data from an apnd-file.
-*/
-static int apndRead(
-  sqlite3_file *pFile, 
-  void *zBuf, 
-  int iAmt, 
-  sqlite_int64 iOfst
-){
-  ApndFile *paf = (ApndFile *)pFile;
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
-}
-
-/*
-** Add the append-mark onto what should become the end of the file.
-*  If and only if this succeeds, internal ApndFile.iMark is updated.
-*  Parameter iWriteEnd is the appendvfs-relative offset of the new mark.
-*/
-static int apndWriteMark(
-  ApndFile *paf,
-  sqlite3_file *pFile,
-  sqlite_int64 iWriteEnd
-){
-  sqlite_int64 iPgOne = paf->iPgOne;
-  unsigned char a[APND_MARK_SIZE];
-  int i = APND_MARK_FOS_SZ;
-  int rc;
-  assert(pFile == ORIGFILE(paf));
-  memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
-  while( --i >= 0 ){
-    a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
-    iPgOne >>= 8;
-  }
-  iWriteEnd += paf->iPgOne;
-  if( SQLITE_OK==(rc = pFile->pMethods->xWrite
-                  (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
-    paf->iMark = iWriteEnd;
-  }
-  return rc;
-}
-
-/*
-** Write data to an apnd-file.
-*/
-static int apndWrite(
-  sqlite3_file *pFile,
-  const void *zBuf,
-  int iAmt,
-  sqlite_int64 iOfst
-){
-  ApndFile *paf = (ApndFile *)pFile;
-  sqlite_int64 iWriteEnd = iOfst + iAmt;
-  if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
-  pFile = ORIGFILE(pFile);
-  /* If append-mark is absent or will be overwritten, write it. */
-  if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
-    int rc = apndWriteMark(paf, pFile, iWriteEnd);
-    if( SQLITE_OK!=rc ) return rc;
-  }
-  return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
-}
-
-/*
-** Truncate an apnd-file.
-*/
-static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
-  ApndFile *paf = (ApndFile *)pFile;
-  pFile = ORIGFILE(pFile);
-  /* The append mark goes out first so truncate failure does not lose it. */
-  if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR;
-  /* Truncate underlying file just past append mark */
-  return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
-}
-
-/*
-** Sync an apnd-file.
-*/
-static int apndSync(sqlite3_file *pFile, int flags){
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xSync(pFile, flags);
-}
-
-/*
-** Return the current file-size of an apnd-file.
-** If the append mark is not yet there, the file-size is 0.
-*/
-static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
-  ApndFile *paf = (ApndFile *)pFile;
-  *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;
-  return SQLITE_OK;
-}
-
-/*
-** Lock an apnd-file.
-*/
-static int apndLock(sqlite3_file *pFile, int eLock){
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xLock(pFile, eLock);
-}
-
-/*
-** Unlock an apnd-file.
-*/
-static int apndUnlock(sqlite3_file *pFile, int eLock){
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xUnlock(pFile, eLock);
-}
-
-/*
-** Check if another file-handle holds a RESERVED lock on an apnd-file.
-*/
-static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
-}
-
-/*
-** File control method. For custom operations on an apnd-file.
-*/
-static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
-  ApndFile *paf = (ApndFile *)pFile;
-  int rc;
-  pFile = ORIGFILE(pFile);
-  if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne;
-  rc = pFile->pMethods->xFileControl(pFile, op, pArg);
-  if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
-    *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
-  }
-  return rc;
-}
-
-/*
-** Return the sector-size in bytes for an apnd-file.
-*/
-static int apndSectorSize(sqlite3_file *pFile){
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xSectorSize(pFile);
-}
-
-/*
-** Return the device characteristic flags supported by an apnd-file.
-*/
-static int apndDeviceCharacteristics(sqlite3_file *pFile){
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xDeviceCharacteristics(pFile);
-}
-
-/* Create a shared memory file mapping */
-static int apndShmMap(
-  sqlite3_file *pFile,
-  int iPg,
-  int pgsz,
-  int bExtend,
-  void volatile **pp
-){
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
-}
-
-/* Perform locking on a shared-memory segment */
-static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xShmLock(pFile,offset,n,flags);
-}
-
-/* Memory barrier operation on shared memory */
-static void apndShmBarrier(sqlite3_file *pFile){
-  pFile = ORIGFILE(pFile);
-  pFile->pMethods->xShmBarrier(pFile);
-}
-
-/* Unmap a shared memory segment */
-static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
-}
-
-/* Fetch a page of a memory-mapped file */
-static int apndFetch(
-  sqlite3_file *pFile,
-  sqlite3_int64 iOfst,
-  int iAmt,
-  void **pp
-){
-  ApndFile *p = (ApndFile *)pFile;
-  if( p->iMark < 0 || iOfst+iAmt > p->iMark ){
-    return SQLITE_IOERR; /* Cannot read what is not yet there. */
-  }
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
-}
-
-/* Release a memory-mapped page */
-static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
-  ApndFile *p = (ApndFile *)pFile;
-  pFile = ORIGFILE(pFile);
-  return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
-}
-
-/*
-** Try to read the append-mark off the end of a file.  Return the
-** start of the appended database if the append-mark is present.
-** If there is no valid append-mark, return -1;
-**
-** An append-mark is only valid if the NNNNNNNN start-of-database offset
-** indicates that the appended database contains at least one page.  The
-** start-of-database value must be a multiple of 512.
-*/
-static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
-  int rc, i;
-  sqlite3_int64 iMark;
-  int msbs = 8 * (APND_MARK_FOS_SZ-1);
-  unsigned char a[APND_MARK_SIZE];
-
-  if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
-  rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
-  if( rc ) return -1;
-  if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
-  iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
-  for(i=1; i<8; i++){
-    msbs -= 8;
-    iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
-  }
-  if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1;
-  if( iMark & 0x1ff ) return -1;
-  return iMark;
-}
-
-static const char apvfsSqliteHdr[] = "SQLite format 3";
-/*
-** Check to see if the file is an appendvfs SQLite database file.
-** Return true iff it is such. Parameter sz is the file's size.
-*/
-static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
-  int rc;
-  char zHdr[16];
-  sqlite3_int64 iMark = apndReadMark(sz, pFile);
-  if( iMark>=0 ){
-    /* If file has the correct end-marker, the expected odd size, and the
-    ** SQLite DB type marker where the end-marker puts it, then it
-    ** is an appendvfs database.
-    */
-    rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
-    if( SQLITE_OK==rc
-     && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
-     && (sz & 0x1ff) == APND_MARK_SIZE
-     && sz>=512+APND_MARK_SIZE
-    ){
-      return 1; /* It's an appendvfs database */
-    }
-  }
-  return 0;
-}
-
-/*
-** Check to see if the file is an ordinary SQLite database file.
-** Return true iff so. Parameter sz is the file's size.
-*/
-static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
-  char zHdr[16];
-  if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */
-   || (sz & 0x1ff) != 0
-   || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0)
-   || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0
-  ){
-    return 0;
-  }else{
-    return 1;
-  }
-}
-
-/*
-** Open an apnd file handle.
-*/
-static int apndOpen(
-  sqlite3_vfs *pApndVfs,
-  const char *zName,
-  sqlite3_file *pFile,
-  int flags,
-  int *pOutFlags
-){
-  ApndFile *pApndFile = (ApndFile*)pFile;
-  sqlite3_file *pBaseFile = ORIGFILE(pFile);
-  sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs);
-  int rc;
-  sqlite3_int64 sz = 0;
-  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
-    /* The appendvfs is not to be used for transient or temporary databases.
-    ** Just use the base VFS open to initialize the given file object and
-    ** open the underlying file. (Appendvfs is then unused for this file.)
-    */
-    return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags);
-  }
-  memset(pApndFile, 0, sizeof(ApndFile));
-  pFile->pMethods = &apnd_io_methods;
-  pApndFile->iMark = -1;    /* Append mark not yet written */
-
-  rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags);
-  if( rc==SQLITE_OK ){
-    rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
-    if( rc ){
-      pBaseFile->pMethods->xClose(pBaseFile);
-    }
-  }
-  if( rc ){
-    pFile->pMethods = 0;
-    return rc;
-  }
-  if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){
-    /* The file being opened appears to be just an ordinary DB. Copy
-    ** the base dispatch-table so this instance mimics the base VFS. 
-    */
-    memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile);
-    return SQLITE_OK;
-  }
-  pApndFile->iPgOne = apndReadMark(sz, pFile);
-  if( pApndFile->iPgOne>=0 ){
-    pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */
-    return SQLITE_OK;
-  }
-  if( (flags & SQLITE_OPEN_CREATE)==0 ){
-    pBaseFile->pMethods->xClose(pBaseFile);
-    rc = SQLITE_CANTOPEN;
-    pFile->pMethods = 0;
-  }else{
-    /* Round newly added appendvfs location to #define'd page boundary. 
-    ** Note that nothing has yet been written to the underlying file.
-    ** The append mark will be written along with first content write.
-    ** Until then, paf->iMark value indicates it is not yet written.
-    */
-    pApndFile->iPgOne = APND_START_ROUNDUP(sz);
-  }
-  return rc;
-}
-
-/*
-** Delete an apnd file.
-** For an appendvfs, this could mean delete the appendvfs portion,
-** leaving the appendee as it was before it gained an appendvfs.
-** For now, this code deletes the underlying file too.
-*/
-static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
-  return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
-}
-
-/*
-** All other VFS methods are pass-thrus.
-*/
-static int apndAccess(
-  sqlite3_vfs *pVfs, 
-  const char *zPath, 
-  int flags, 
-  int *pResOut
-){
-  return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
-}
-static int apndFullPathname(
-  sqlite3_vfs *pVfs, 
-  const char *zPath, 
-  int nOut, 
-  char *zOut
-){
-  return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
-}
-static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
-  return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
-}
-static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
-  ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
-}
-static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
-  return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
-}
-static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
-  ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
-}
-static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
-  return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
-}
-static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
-  return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
-}
-static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
-  return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
-}
-static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
-  return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
-}
-static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
-  return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
-}
-static int apndSetSystemCall(
-  sqlite3_vfs *pVfs,
-  const char *zName,
-  sqlite3_syscall_ptr pCall
-){
-  return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
-}
-static sqlite3_syscall_ptr apndGetSystemCall(
-  sqlite3_vfs *pVfs,
-  const char *zName
-){
-  return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
-}
-static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
-  return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
-}
-
-  
-#ifdef _WIN32
-
-#endif
-/* 
-** This routine is called when the extension is loaded.
-** Register the new VFS.
-*/
-int sqlite3_appendvfs_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
-  int rc = SQLITE_OK;
-  sqlite3_vfs *pOrig;
-  SQLITE_EXTENSION_INIT2(pApi);
-  (void)pzErrMsg;
-  (void)db;
-  pOrig = sqlite3_vfs_find(0);
-  if( pOrig==0 ) return SQLITE_ERROR;
-  apnd_vfs.iVersion = pOrig->iVersion;
-  apnd_vfs.pAppData = pOrig;
-  apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
-  rc = sqlite3_vfs_register(&apnd_vfs, 0);
-#ifdef APPENDVFS_TEST
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
-  }
-#endif
-  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
-  return rc;
-}
-
-/************************* End ../ext/misc/appendvfs.c ********************/
-#endif
-#ifdef SQLITE_HAVE_ZLIB
-/************************* Begin ../ext/misc/zipfile.c ******************/
-/*
-** 2017-12-26
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This file implements a virtual table for reading and writing ZIP archive
-** files.
-**
-** Usage example:
-**
-**     SELECT name, sz, datetime(mtime,'unixepoch') FROM zipfile($filename);
-**
-** Current limitations:
-**
-**    *  No support for encryption
-**    *  No support for ZIP archives spanning multiple files
-**    *  No support for zip64 extensions
-**    *  Only the "inflate/deflate" (zlib) compression method is supported
-*/
-/* #include "sqlite3ext.h" */
-SQLITE_EXTENSION_INIT1
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-
-#include <zlib.h>
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-
-#ifndef SQLITE_AMALGAMATION
-
-#ifndef UINT32_TYPE
-# ifdef HAVE_UINT32_T
-#  define UINT32_TYPE uint32_t
-# else
-#  define UINT32_TYPE unsigned int
-# endif
-#endif
-#ifndef UINT16_TYPE
-# ifdef HAVE_UINT16_T
-#  define UINT16_TYPE uint16_t
-# else
-#  define UINT16_TYPE unsigned short int
-# endif
-#endif
-/* typedef sqlite3_int64 i64; */
-/* typedef unsigned char u8; */
-/* typedef UINT32_TYPE u32;           // 4-byte unsigned integer // */
-/* typedef UINT16_TYPE u16;           // 2-byte unsigned integer // */
-#define MIN(a,b) ((a)<(b) ? (a) : (b))
-
-#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
-# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
-#endif
-#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
-# define ALWAYS(X)      (1)
-# define NEVER(X)       (0)
-#elif !defined(NDEBUG)
-# define ALWAYS(X)      ((X)?1:(assert(0),0))
-# define NEVER(X)       ((X)?(assert(0),1):0)
-#else
-# define ALWAYS(X)      (X)
-# define NEVER(X)       (X)
-#endif
-
-#endif   /* SQLITE_AMALGAMATION */
-
-/*
-** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK.
-**
-** In some ways it would be better to obtain these values from system 
-** header files. But, the dependency is undesirable and (a) these
-** have been stable for decades, (b) the values are part of POSIX and
-** are also made explicit in [man stat], and (c) are part of the 
-** file format for zip archives.
-*/
-#ifndef S_IFDIR
-# define S_IFDIR 0040000
-#endif
-#ifndef S_IFREG
-# define S_IFREG 0100000
-#endif
-#ifndef S_IFLNK
-# define S_IFLNK 0120000
-#endif
-
-static const char ZIPFILE_SCHEMA[] = 
-  "CREATE TABLE y("
-    "name PRIMARY KEY,"  /* 0: Name of file in zip archive */
-    "mode,"              /* 1: POSIX mode for file */
-    "mtime,"             /* 2: Last modification time (secs since 1970)*/
-    "sz,"                /* 3: Size of object */
-    "rawdata,"           /* 4: Raw data */
-    "data,"              /* 5: Uncompressed data */
-    "method,"            /* 6: Compression method (integer) */
-    "z HIDDEN"           /* 7: Name of zip file */
-  ") WITHOUT ROWID;";
-
-#define ZIPFILE_F_COLUMN_IDX 7    /* Index of column "file" in the above */
-#define ZIPFILE_BUFFER_SIZE (64*1024)
-
-
-/*
-** Magic numbers used to read and write zip files.
-**
-** ZIPFILE_NEWENTRY_MADEBY:
-**   Use this value for the "version-made-by" field in new zip file
-**   entries. The upper byte indicates "unix", and the lower byte 
-**   indicates that the zip file matches pkzip specification 3.0. 
-**   This is what info-zip seems to do.
-**
-** ZIPFILE_NEWENTRY_REQUIRED:
-**   Value for "version-required-to-extract" field of new entries.
-**   Version 2.0 is required to support folders and deflate compression.
-**
-** ZIPFILE_NEWENTRY_FLAGS:
-**   Value for "general-purpose-bit-flags" field of new entries. Bit
-**   11 means "utf-8 filename and comment".
-**
-** ZIPFILE_SIGNATURE_CDS:
-**   First 4 bytes of a valid CDS record.
-**
-** ZIPFILE_SIGNATURE_LFH:
-**   First 4 bytes of a valid LFH record.
-**
-** ZIPFILE_SIGNATURE_EOCD
-**   First 4 bytes of a valid EOCD record.
-*/
-#define ZIPFILE_EXTRA_TIMESTAMP   0x5455
-#define ZIPFILE_NEWENTRY_MADEBY   ((3<<8) + 30)
-#define ZIPFILE_NEWENTRY_REQUIRED 20
-#define ZIPFILE_NEWENTRY_FLAGS    0x800
-#define ZIPFILE_SIGNATURE_CDS     0x02014b50
-#define ZIPFILE_SIGNATURE_LFH     0x04034b50
-#define ZIPFILE_SIGNATURE_EOCD    0x06054b50
-
-/*
-** The sizes of the fixed-size part of each of the three main data 
-** structures in a zip archive.
-*/
-#define ZIPFILE_LFH_FIXED_SZ      30
-#define ZIPFILE_EOCD_FIXED_SZ     22
-#define ZIPFILE_CDS_FIXED_SZ      46
-
-/*
-*** 4.3.16  End of central directory record:
-***
-***   end of central dir signature    4 bytes  (0x06054b50)
-***   number of this disk             2 bytes
-***   number of the disk with the
-***   start of the central directory  2 bytes
-***   total number of entries in the
-***   central directory on this disk  2 bytes
-***   total number of entries in
-***   the central directory           2 bytes
-***   size of the central directory   4 bytes
-***   offset of start of central
-***   directory with respect to
-***   the starting disk number        4 bytes
-***   .ZIP file comment length        2 bytes
-***   .ZIP file comment       (variable size)
-*/
-typedef struct ZipfileEOCD ZipfileEOCD;
-struct ZipfileEOCD {
-  u16 iDisk;
-  u16 iFirstDisk;
-  u16 nEntry;
-  u16 nEntryTotal;
-  u32 nSize;
-  u32 iOffset;
-};
-
-/*
-*** 4.3.12  Central directory structure:
-***
-*** ...
-***
-***   central file header signature   4 bytes  (0x02014b50)
-***   version made by                 2 bytes
-***   version needed to extract       2 bytes
-***   general purpose bit flag        2 bytes
-***   compression method              2 bytes
-***   last mod file time              2 bytes
-***   last mod file date              2 bytes
-***   crc-32                          4 bytes
-***   compressed size                 4 bytes
-***   uncompressed size               4 bytes
-***   file name length                2 bytes
-***   extra field length              2 bytes
-***   file comment length             2 bytes
-***   disk number start               2 bytes
-***   internal file attributes        2 bytes
-***   external file attributes        4 bytes
-***   relative offset of local header 4 bytes
-*/
-typedef struct ZipfileCDS ZipfileCDS;
-struct ZipfileCDS {
-  u16 iVersionMadeBy;
-  u16 iVersionExtract;
-  u16 flags;
-  u16 iCompression;
-  u16 mTime;
-  u16 mDate;
-  u32 crc32;
-  u32 szCompressed;
-  u32 szUncompressed;
-  u16 nFile;
-  u16 nExtra;
-  u16 nComment;
-  u16 iDiskStart;
-  u16 iInternalAttr;
-  u32 iExternalAttr;
-  u32 iOffset;
-  char *zFile;                    /* Filename (sqlite3_malloc()) */
-};
-
-/*
-*** 4.3.7  Local file header:
-***
-***   local file header signature     4 bytes  (0x04034b50)
-***   version needed to extract       2 bytes
-***   general purpose bit flag        2 bytes
-***   compression method              2 bytes
-***   last mod file time              2 bytes
-***   last mod file date              2 bytes
-***   crc-32                          4 bytes
-***   compressed size                 4 bytes
-***   uncompressed size               4 bytes
-***   file name length                2 bytes
-***   extra field length              2 bytes
-***   
-*/
-typedef struct ZipfileLFH ZipfileLFH;
-struct ZipfileLFH {
-  u16 iVersionExtract;
-  u16 flags;
-  u16 iCompression;
-  u16 mTime;
-  u16 mDate;
-  u32 crc32;
-  u32 szCompressed;
-  u32 szUncompressed;
-  u16 nFile;
-  u16 nExtra;
-};
-
-typedef struct ZipfileEntry ZipfileEntry;
-struct ZipfileEntry {
-  ZipfileCDS cds;            /* Parsed CDS record */
-  u32 mUnixTime;             /* Modification time, in UNIX format */
-  u8 *aExtra;                /* cds.nExtra+cds.nComment bytes of extra data */
-  i64 iDataOff;              /* Offset to data in file (if aData==0) */
-  u8 *aData;                 /* cds.szCompressed bytes of compressed data */
-  ZipfileEntry *pNext;       /* Next element in in-memory CDS */
-};
-
-/* 
-** Cursor type for zipfile tables.
-*/
-typedef struct ZipfileCsr ZipfileCsr;
-struct ZipfileCsr {
-  sqlite3_vtab_cursor base;  /* Base class - must be first */
-  i64 iId;                   /* Cursor ID */
-  u8 bEof;                   /* True when at EOF */
-  u8 bNoop;                  /* If next xNext() call is no-op */
-
-  /* Used outside of write transactions */
-  FILE *pFile;               /* Zip file */
-  i64 iNextOff;              /* Offset of next record in central directory */
-  ZipfileEOCD eocd;          /* Parse of central directory record */
-
-  ZipfileEntry *pFreeEntry;  /* Free this list when cursor is closed or reset */
-  ZipfileEntry *pCurrent;    /* Current entry */
-  ZipfileCsr *pCsrNext;      /* Next cursor on same virtual table */
-};
-
-typedef struct ZipfileTab ZipfileTab;
-struct ZipfileTab {
-  sqlite3_vtab base;         /* Base class - must be first */
-  char *zFile;               /* Zip file this table accesses (may be NULL) */
-  sqlite3 *db;               /* Host database connection */
-  u8 *aBuffer;               /* Temporary buffer used for various tasks */
-
-  ZipfileCsr *pCsrList;      /* List of cursors */
-  i64 iNextCsrid;
-
-  /* The following are used by write transactions only */
-  ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */
-  ZipfileEntry *pLastEntry;  /* Last element in pFirstEntry list */
-  FILE *pWriteFd;            /* File handle open on zip archive */
-  i64 szCurrent;             /* Current size of zip archive */
-  i64 szOrig;                /* Size of archive at start of transaction */
-};
-
-/*
-** Set the error message contained in context ctx to the results of
-** vprintf(zFmt, ...).
-*/
-static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
-  char *zMsg = 0;
-  va_list ap;
-  va_start(ap, zFmt);
-  zMsg = sqlite3_vmprintf(zFmt, ap);
-  sqlite3_result_error(ctx, zMsg, -1);
-  sqlite3_free(zMsg);
-  va_end(ap);
-}
-
-/*
-** If string zIn is quoted, dequote it in place. Otherwise, if the string
-** is not quoted, do nothing.
-*/
-static void zipfileDequote(char *zIn){
-  char q = zIn[0];
-  if( q=='"' || q=='\'' || q=='`' || q=='[' ){
-    int iIn = 1;
-    int iOut = 0;
-    if( q=='[' ) q = ']';
-    while( ALWAYS(zIn[iIn]) ){
-      char c = zIn[iIn++];
-      if( c==q && zIn[iIn++]!=q ) break;
-      zIn[iOut++] = c;
-    }
-    zIn[iOut] = '\0';
-  }
-}
-
-/*
-** Construct a new ZipfileTab virtual table object.
-** 
-**   argv[0]   -> module name  ("zipfile")
-**   argv[1]   -> database name
-**   argv[2]   -> table name
-**   argv[...] -> "column name" and other module argument fields.
-*/
-static int zipfileConnect(
-  sqlite3 *db,
-  void *pAux,
-  int argc, const char *const*argv,
-  sqlite3_vtab **ppVtab,
-  char **pzErr
-){
-  int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE;
-  int nFile = 0;
-  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:
-  **
-  **   CREATE VIRTUAL TABLE zzz USING zipfile();
-  **
-  ** It does not prevent:
-  **
-  **   CREATE VIRTUAL TABLE zipfile USING zipfile();
-  */
-  assert( 0==sqlite3_stricmp(argv[0], "zipfile") );
-  if( (0!=sqlite3_stricmp(argv[2], "zipfile") && argc<4) || argc>4 ){
-    *pzErr = sqlite3_mprintf("zipfile constructor requires one argument");
-    return SQLITE_ERROR;
-  }
-
-  if( argc>3 ){
-    zFile = argv[3];
-    nFile = (int)strlen(zFile)+1;
-  }
-
-  rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA);
-  if( rc==SQLITE_OK ){
-    pNew = (ZipfileTab*)sqlite3_malloc64((sqlite3_int64)nByte+nFile);
-    if( pNew==0 ) return SQLITE_NOMEM;
-    memset(pNew, 0, nByte+nFile);
-    pNew->db = db;
-    pNew->aBuffer = (u8*)&pNew[1];
-    if( zFile ){
-      pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE];
-      memcpy(pNew->zFile, zFile, nFile);
-      zipfileDequote(pNew->zFile);
-    }
-  }
-  sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
-  *ppVtab = (sqlite3_vtab*)pNew;
-  return rc;
-}
-
-/*
-** Free the ZipfileEntry structure indicated by the only argument.
-*/
-static void zipfileEntryFree(ZipfileEntry *p){
-  if( p ){
-    sqlite3_free(p->cds.zFile);
-    sqlite3_free(p);
-  }
-}
-
-/*
-** Release resources that should be freed at the end of a write 
-** transaction.
-*/
-static void zipfileCleanupTransaction(ZipfileTab *pTab){
-  ZipfileEntry *pEntry;
-  ZipfileEntry *pNext;
-
-  if( pTab->pWriteFd ){
-    fclose(pTab->pWriteFd);
-    pTab->pWriteFd = 0;
-  }
-  for(pEntry=pTab->pFirstEntry; pEntry; pEntry=pNext){
-    pNext = pEntry->pNext;
-    zipfileEntryFree(pEntry);
-  }
-  pTab->pFirstEntry = 0;
-  pTab->pLastEntry = 0;
-  pTab->szCurrent = 0;
-  pTab->szOrig = 0;
-}
-
-/*
-** This method is the destructor for zipfile vtab objects.
-*/
-static int zipfileDisconnect(sqlite3_vtab *pVtab){
-  zipfileCleanupTransaction((ZipfileTab*)pVtab);
-  sqlite3_free(pVtab);
-  return SQLITE_OK;
-}
-
-/*
-** Constructor for a new ZipfileCsr object.
-*/
-static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
-  ZipfileTab *pTab = (ZipfileTab*)p;
-  ZipfileCsr *pCsr;
-  pCsr = sqlite3_malloc(sizeof(*pCsr));
-  *ppCsr = (sqlite3_vtab_cursor*)pCsr;
-  if( pCsr==0 ){
-    return SQLITE_NOMEM;
-  }
-  memset(pCsr, 0, sizeof(*pCsr));
-  pCsr->iId = ++pTab->iNextCsrid;
-  pCsr->pCsrNext = pTab->pCsrList;
-  pTab->pCsrList = pCsr;
-  return SQLITE_OK;
-}
-
-/*
-** Reset a cursor back to the state it was in when first returned
-** by zipfileOpen().
-*/
-static void zipfileResetCursor(ZipfileCsr *pCsr){
-  ZipfileEntry *p;
-  ZipfileEntry *pNext;
-
-  pCsr->bEof = 0;
-  if( pCsr->pFile ){
-    fclose(pCsr->pFile);
-    pCsr->pFile = 0;
-    zipfileEntryFree(pCsr->pCurrent);
-    pCsr->pCurrent = 0;
-  }
-
-  for(p=pCsr->pFreeEntry; p; p=pNext){
-    pNext = p->pNext;
-    zipfileEntryFree(p);
-  }
-}
-
-/*
-** Destructor for an ZipfileCsr.
-*/
-static int zipfileClose(sqlite3_vtab_cursor *cur){
-  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
-  ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab);
-  ZipfileCsr **pp;
-  zipfileResetCursor(pCsr);
-
-  /* Remove this cursor from the ZipfileTab.pCsrList list. */
-  for(pp=&pTab->pCsrList; *pp!=pCsr; pp=&((*pp)->pCsrNext));
-  *pp = pCsr->pCsrNext;
-
-  sqlite3_free(pCsr);
-  return SQLITE_OK;
-}
-
-/*
-** Set the error message for the virtual table associated with cursor
-** pCsr to the results of vprintf(zFmt, ...).
-*/
-static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...){
-  va_list ap;
-  va_start(ap, zFmt);
-  sqlite3_free(pTab->base.zErrMsg);
-  pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap);
-  va_end(ap);
-}
-static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){
-  va_list ap;
-  va_start(ap, zFmt);
-  sqlite3_free(pCsr->base.pVtab->zErrMsg);
-  pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
-  va_end(ap);
-}
-
-/*
-** Read nRead bytes of data from offset iOff of file pFile into buffer
-** aRead[]. Return SQLITE_OK if successful, or an SQLite error code
-** otherwise. 
-**
-** If an error does occur, output variable (*pzErrmsg) may be set to point
-** to an English language error message. It is the responsibility of the
-** caller to eventually free this buffer using
-** sqlite3_free().
-*/
-static int zipfileReadData(
-  FILE *pFile,                    /* Read from this file */
-  u8 *aRead,                      /* Read into this buffer */
-  int nRead,                      /* Number of bytes to read */
-  i64 iOff,                       /* Offset to read from */
-  char **pzErrmsg                 /* OUT: Error message (from sqlite3_malloc) */
-){
-  size_t n;
-  fseek(pFile, (long)iOff, SEEK_SET);
-  n = fread(aRead, 1, nRead, pFile);
-  if( (int)n!=nRead ){
-    *pzErrmsg = sqlite3_mprintf("error in fread()");
-    return SQLITE_ERROR;
-  }
-  return SQLITE_OK;
-}
-
-static int zipfileAppendData(
-  ZipfileTab *pTab,
-  const u8 *aWrite,
-  int nWrite
-){
-  if( nWrite>0 ){
-    size_t n = nWrite;
-    fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
-    n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
-    if( (int)n!=nWrite ){
-      pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
-      return SQLITE_ERROR;
-    }
-    pTab->szCurrent += nWrite;
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Read and return a 16-bit little-endian unsigned integer from buffer aBuf.
-*/
-static u16 zipfileGetU16(const u8 *aBuf){
-  return (aBuf[1] << 8) + aBuf[0];
-}
-
-/*
-** Read and return a 32-bit little-endian unsigned integer from buffer aBuf.
-*/
-static u32 zipfileGetU32(const u8 *aBuf){
-  if( aBuf==0 ) return 0;
-  return ((u32)(aBuf[3]) << 24)
-       + ((u32)(aBuf[2]) << 16)
-       + ((u32)(aBuf[1]) <<  8)
-       + ((u32)(aBuf[0]) <<  0);
-}
-
-/*
-** Write a 16-bit little endiate integer into buffer aBuf.
-*/
-static void zipfilePutU16(u8 *aBuf, u16 val){
-  aBuf[0] = val & 0xFF;
-  aBuf[1] = (val>>8) & 0xFF;
-}
-
-/*
-** Write a 32-bit little endiate integer into buffer aBuf.
-*/
-static void zipfilePutU32(u8 *aBuf, u32 val){
-  aBuf[0] = val & 0xFF;
-  aBuf[1] = (val>>8) & 0xFF;
-  aBuf[2] = (val>>16) & 0xFF;
-  aBuf[3] = (val>>24) & 0xFF;
-}
-
-#define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) )
-#define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) )
-
-#define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; }
-#define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; }
-
-/*
-** Magic numbers used to read CDS records.
-*/
-#define ZIPFILE_CDS_NFILE_OFF        28
-#define ZIPFILE_CDS_SZCOMPRESSED_OFF 20
-
-/*
-** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR
-** if the record is not well-formed, or SQLITE_OK otherwise.
-*/
-static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){
-  u8 *aRead = aBuf;
-  u32 sig = zipfileRead32(aRead);
-  int rc = SQLITE_OK;
-  if( sig!=ZIPFILE_SIGNATURE_CDS ){
-    rc = SQLITE_ERROR;
-  }else{
-    pCDS->iVersionMadeBy = zipfileRead16(aRead);
-    pCDS->iVersionExtract = zipfileRead16(aRead);
-    pCDS->flags = zipfileRead16(aRead);
-    pCDS->iCompression = zipfileRead16(aRead);
-    pCDS->mTime = zipfileRead16(aRead);
-    pCDS->mDate = zipfileRead16(aRead);
-    pCDS->crc32 = zipfileRead32(aRead);
-    pCDS->szCompressed = zipfileRead32(aRead);
-    pCDS->szUncompressed = zipfileRead32(aRead);
-    assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
-    pCDS->nFile = zipfileRead16(aRead);
-    pCDS->nExtra = zipfileRead16(aRead);
-    pCDS->nComment = zipfileRead16(aRead);
-    pCDS->iDiskStart = zipfileRead16(aRead);
-    pCDS->iInternalAttr = zipfileRead16(aRead);
-    pCDS->iExternalAttr = zipfileRead32(aRead);
-    pCDS->iOffset = zipfileRead32(aRead);
-    assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] );
-  }
-
-  return rc;
-}
-
-/*
-** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR
-** if the record is not well-formed, or SQLITE_OK otherwise.
-*/
-static int zipfileReadLFH(
-  u8 *aBuffer,
-  ZipfileLFH *pLFH
-){
-  u8 *aRead = aBuffer;
-  int rc = SQLITE_OK;
-
-  u32 sig = zipfileRead32(aRead);
-  if( sig!=ZIPFILE_SIGNATURE_LFH ){
-    rc = SQLITE_ERROR;
-  }else{
-    pLFH->iVersionExtract = zipfileRead16(aRead);
-    pLFH->flags = zipfileRead16(aRead);
-    pLFH->iCompression = zipfileRead16(aRead);
-    pLFH->mTime = zipfileRead16(aRead);
-    pLFH->mDate = zipfileRead16(aRead);
-    pLFH->crc32 = zipfileRead32(aRead);
-    pLFH->szCompressed = zipfileRead32(aRead);
-    pLFH->szUncompressed = zipfileRead32(aRead);
-    pLFH->nFile = zipfileRead16(aRead);
-    pLFH->nExtra = zipfileRead16(aRead);
-  }
-  return rc;
-}
-
-
-/*
-** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields.
-** Scan through this buffer to find an "extra-timestamp" field. If one
-** exists, extract the 32-bit modification-timestamp from it and store
-** the value in output parameter *pmTime.
-**
-** Zero is returned if no extra-timestamp record could be found (and so
-** *pmTime is left unchanged), or non-zero otherwise.
-**
-** The general format of an extra field is:
-**
-**   Header ID    2 bytes
-**   Data Size    2 bytes
-**   Data         N bytes
-*/
-static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){
-  int ret = 0;
-  u8 *p = aExtra;
-  u8 *pEnd = &aExtra[nExtra];
-
-  while( p<pEnd ){
-    u16 id = zipfileRead16(p);
-    u16 nByte = zipfileRead16(p);
-
-    switch( id ){
-      case ZIPFILE_EXTRA_TIMESTAMP: {
-        u8 b = p[0];
-        if( b & 0x01 ){     /* 0x01 -> modtime is present */
-          *pmTime = zipfileGetU32(&p[1]);
-          ret = 1;
-        }
-        break;
-      }
-    }
-
-    p += nByte;
-  }
-  return ret;
-}
-
-/*
-** Convert the standard MS-DOS timestamp stored in the mTime and mDate
-** fields of the CDS structure passed as the only argument to a 32-bit
-** UNIX seconds-since-the-epoch timestamp. Return the result.
-**
-** "Standard" MS-DOS time format:
-**
-**   File modification time:
-**     Bits 00-04: seconds divided by 2
-**     Bits 05-10: minute
-**     Bits 11-15: hour
-**   File modification date:
-**     Bits 00-04: day
-**     Bits 05-08: month (1-12)
-**     Bits 09-15: years from 1980 
-**
-** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx
-*/
-static u32 zipfileMtime(ZipfileCDS *pCDS){
-  int Y,M,D,X1,X2,A,B,sec,min,hr;
-  i64 JDsec;
-  Y = (1980 + ((pCDS->mDate >> 9) & 0x7F));
-  M = ((pCDS->mDate >> 5) & 0x0F);
-  D = (pCDS->mDate & 0x1F);
-  sec = (pCDS->mTime & 0x1F)*2;
-  min = (pCDS->mTime >> 5) & 0x3F;
-  hr = (pCDS->mTime >> 11) & 0x1F;
-  if( M<=2 ){
-    Y--;
-    M += 12;
-  }
-  X1 = 36525*(Y+4716)/100;
-  X2 = 306001*(M+1)/10000;
-  A = Y/100;
-  B = 2 - A + (A/4);
-  JDsec = (i64)((X1 + X2 + D + B - 1524.5)*86400) + hr*3600 + min*60 + sec;
-  return (u32)(JDsec - (i64)24405875*(i64)8640);
-}
-
-/*
-** The opposite of zipfileMtime(). This function populates the mTime and
-** mDate fields of the CDS structure passed as the first argument according
-** to the UNIX timestamp value passed as the second.
-*/
-static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){
-  /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */
-  i64 JD = (i64)2440588 + mUnixTime / (24*60*60);
-
-  int A, B, C, D, E;
-  int yr, mon, day;
-  int hr, min, sec;
-
-  A = (int)((JD - 1867216.25)/36524.25);
-  A = (int)(JD + 1 + A - (A/4));
-  B = A + 1524;
-  C = (int)((B - 122.1)/365.25);
-  D = (36525*(C&32767))/100;
-  E = (int)((B-D)/30.6001);
-
-  day = B - D - (int)(30.6001*E);
-  mon = (E<14 ? E-1 : E-13);
-  yr = mon>2 ? C-4716 : C-4715;
-
-  hr = (mUnixTime % (24*60*60)) / (60*60);
-  min = (mUnixTime % (60*60)) / 60;
-  sec = (mUnixTime % 60);
-
-  if( yr>=1980 ){
-    pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9));
-    pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11));
-  }else{
-    pCds->mDate = pCds->mTime = 0;
-  }
-
-  assert( mUnixTime<315507600 
-       || mUnixTime==zipfileMtime(pCds) 
-       || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) 
-       /* || (mUnixTime % 2) */
-  );
-}
-
-/*
-** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in
-** size) containing an entire zip archive image. Or, if aBlob is NULL,
-** then pFile is a file-handle open on a zip file. In either case, this
-** function creates a ZipfileEntry object based on the zip archive entry
-** for which the CDS record is at offset iOff.
-**
-** If successful, SQLITE_OK is returned and (*ppEntry) set to point to
-** the new object. Otherwise, an SQLite error code is returned and the
-** final value of (*ppEntry) undefined.
-*/
-static int zipfileGetEntry(
-  ZipfileTab *pTab,               /* Store any error message here */
-  const u8 *aBlob,                /* Pointer to in-memory file image */
-  int nBlob,                      /* Size of aBlob[] in bytes */
-  FILE *pFile,                    /* If aBlob==0, read from this file */
-  i64 iOff,                       /* Offset of CDS record */
-  ZipfileEntry **ppEntry          /* OUT: Pointer to new object */
-){
-  u8 *aRead;
-  char **pzErr = &pTab->base.zErrMsg;
-  int rc = SQLITE_OK;
-  (void)nBlob;
-
-  if( aBlob==0 ){
-    aRead = pTab->aBuffer;
-    rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr);
-  }else{
-    aRead = (u8*)&aBlob[iOff];
-  }
-
-  if( rc==SQLITE_OK ){
-    sqlite3_int64 nAlloc;
-    ZipfileEntry *pNew;
-
-    int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]);
-    int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+2]);
-    nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+4]);
-
-    nAlloc = sizeof(ZipfileEntry) + nExtra;
-    if( aBlob ){
-      nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]);
-    }
-
-    pNew = (ZipfileEntry*)sqlite3_malloc64(nAlloc);
-    if( pNew==0 ){
-      rc = SQLITE_NOMEM;
-    }else{
-      memset(pNew, 0, sizeof(ZipfileEntry));
-      rc = zipfileReadCDS(aRead, &pNew->cds);
-      if( rc!=SQLITE_OK ){
-        *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld", iOff);
-      }else if( aBlob==0 ){
-        rc = zipfileReadData(
-            pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr
-        );
-      }else{
-        aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ];
-      }
-    }
-
-    if( rc==SQLITE_OK ){
-      u32 *pt = &pNew->mUnixTime;
-      pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead); 
-      pNew->aExtra = (u8*)&pNew[1];
-      memcpy(pNew->aExtra, &aRead[nFile], nExtra);
-      if( pNew->cds.zFile==0 ){
-        rc = SQLITE_NOMEM;
-      }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){
-        pNew->mUnixTime = zipfileMtime(&pNew->cds);
-      }
-    }
-
-    if( rc==SQLITE_OK ){
-      static const int szFix = ZIPFILE_LFH_FIXED_SZ;
-      ZipfileLFH lfh;
-      if( pFile ){
-        rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr);
-      }else{
-        aRead = (u8*)&aBlob[pNew->cds.iOffset];
-      }
-
-      if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh);
-      if( rc==SQLITE_OK ){
-        pNew->iDataOff =  pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
-        pNew->iDataOff += lfh.nFile + lfh.nExtra;
-        if( aBlob && pNew->cds.szCompressed ){
-          pNew->aData = &pNew->aExtra[nExtra];
-          memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
-        }
-      }else{
-        *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", 
-            (int)pNew->cds.iOffset
-        );
-      }
-    }
-
-    if( rc!=SQLITE_OK ){
-      zipfileEntryFree(pNew);
-    }else{
-      *ppEntry = pNew;
-    }
-  }
-
-  return rc;
-}
-
-/*
-** Advance an ZipfileCsr to its next row of output.
-*/
-static int zipfileNext(sqlite3_vtab_cursor *cur){
-  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
-  int rc = SQLITE_OK;
-
-  if( pCsr->pFile ){
-    i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize;
-    zipfileEntryFree(pCsr->pCurrent);
-    pCsr->pCurrent = 0;
-    if( pCsr->iNextOff>=iEof ){
-      pCsr->bEof = 1;
-    }else{
-      ZipfileEntry *p = 0;
-      ZipfileTab *pTab = (ZipfileTab*)(cur->pVtab);
-      rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p);
-      if( rc==SQLITE_OK ){
-        pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ;
-        pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment;
-      }
-      pCsr->pCurrent = p;
-    }
-  }else{
-    if( !pCsr->bNoop ){
-      pCsr->pCurrent = pCsr->pCurrent->pNext;
-    }
-    if( pCsr->pCurrent==0 ){
-      pCsr->bEof = 1;
-    }
-  }
-
-  pCsr->bNoop = 0;
-  return rc;
-}
-
-static void zipfileFree(void *p) { 
-  sqlite3_free(p); 
-}
-
-/*
-** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the
-** size is nOut bytes. This function uncompresses the data and sets the
-** return value in context pCtx to the result (a blob).
-**
-** If an error occurs, an error code is left in pCtx instead.
-*/
-static void zipfileInflate(
-  sqlite3_context *pCtx,          /* Store result here */
-  const u8 *aIn,                  /* Compressed data */
-  int nIn,                        /* Size of buffer aIn[] in bytes */
-  int nOut                        /* Expected output size */
-){
-  u8 *aRes = sqlite3_malloc(nOut);
-  if( aRes==0 ){
-    sqlite3_result_error_nomem(pCtx);
-  }else{
-    int err;
-    z_stream str;
-    memset(&str, 0, sizeof(str));
-
-    str.next_in = (Byte*)aIn;
-    str.avail_in = nIn;
-    str.next_out = (Byte*)aRes;
-    str.avail_out = nOut;
-
-    err = inflateInit2(&str, -15);
-    if( err!=Z_OK ){
-      zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err);
-    }else{
-      err = inflate(&str, Z_NO_FLUSH);
-      if( err!=Z_STREAM_END ){
-        zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err);
-      }else{
-        sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree);
-        aRes = 0;
-      }
-    }
-    sqlite3_free(aRes);
-    inflateEnd(&str);
-  }
-}
-
-/*
-** Buffer aIn (size nIn bytes) contains uncompressed data. This function
-** compresses it and sets (*ppOut) to point to a buffer containing the
-** compressed data. The caller is responsible for eventually calling
-** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut) 
-** is set to the size of buffer (*ppOut) in bytes.
-**
-** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error
-** code is returned and an error message left in virtual-table handle
-** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this
-** case.
-*/
-static int zipfileDeflate(
-  const u8 *aIn, int nIn,         /* Input */
-  u8 **ppOut, int *pnOut,         /* Output */
-  char **pzErr                    /* OUT: Error message */
-){
-  int rc = SQLITE_OK;
-  sqlite3_int64 nAlloc;
-  z_stream str;
-  u8 *aOut;
-
-  memset(&str, 0, sizeof(str));
-  str.next_in = (Bytef*)aIn;
-  str.avail_in = nIn;
-  deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
-
-  nAlloc = deflateBound(&str, nIn);
-  aOut = (u8*)sqlite3_malloc64(nAlloc);
-  if( aOut==0 ){
-    rc = SQLITE_NOMEM;
-  }else{
-    int res;
-    str.next_out = aOut;
-    str.avail_out = nAlloc;
-    res = deflate(&str, Z_FINISH);
-    if( res==Z_STREAM_END ){
-      *ppOut = aOut;
-      *pnOut = (int)str.total_out;
-    }else{
-      sqlite3_free(aOut);
-      *pzErr = sqlite3_mprintf("zipfile: deflate() error");
-      rc = SQLITE_ERROR;
-    }
-    deflateEnd(&str);
-  }
-
-  return rc;
-}
-
-
-/*
-** Return values of columns for the row at which the series_cursor
-** is currently pointing.
-*/
-static int zipfileColumn(
-  sqlite3_vtab_cursor *cur,   /* The cursor */
-  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
-  int i                       /* Which column to return */
-){
-  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
-  ZipfileCDS *pCDS = &pCsr->pCurrent->cds;
-  int rc = SQLITE_OK;
-  switch( i ){
-    case 0:   /* name */
-      sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT);
-      break;
-    case 1:   /* mode */
-      /* TODO: Whether or not the following is correct surely depends on
-      ** the platform on which the archive was created.  */
-      sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16);
-      break;
-    case 2: { /* mtime */
-      sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime);
-      break;
-    }
-    case 3: { /* sz */
-      if( sqlite3_vtab_nochange(ctx)==0 ){
-        sqlite3_result_int64(ctx, pCDS->szUncompressed);
-      }
-      break;
-    }
-    case 4:   /* rawdata */
-      if( sqlite3_vtab_nochange(ctx) ) break;
-    case 5: { /* data */
-      if( i==4 || pCDS->iCompression==0 || pCDS->iCompression==8 ){
-        int sz = pCDS->szCompressed;
-        int szFinal = pCDS->szUncompressed;
-        if( szFinal>0 ){
-          u8 *aBuf;
-          u8 *aFree = 0;
-          if( pCsr->pCurrent->aData ){
-            aBuf = pCsr->pCurrent->aData;
-          }else{
-            aBuf = aFree = sqlite3_malloc64(sz);
-            if( aBuf==0 ){
-              rc = SQLITE_NOMEM;
-            }else{
-              FILE *pFile = pCsr->pFile;
-              if( pFile==0 ){
-                pFile = ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd;
-              }
-              rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff,
-                  &pCsr->base.pVtab->zErrMsg
-              );
-            }
-          }
-          if( rc==SQLITE_OK ){
-            if( i==5 && pCDS->iCompression ){
-              zipfileInflate(ctx, aBuf, sz, szFinal);
-            }else{
-              sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
-            }
-          }
-          sqlite3_free(aFree);
-        }else{
-          /* Figure out if this is a directory or a zero-sized file. Consider
-          ** 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->nFile>=1
-           && pCDS->zFile[pCDS->nFile-1]!='/'
-          ){
-            sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC);
-          }
-        }
-      }
-      break;
-    }
-    case 6:   /* method */
-      sqlite3_result_int(ctx, pCDS->iCompression);
-      break;
-    default:  /* z */
-      assert( i==7 );
-      sqlite3_result_int64(ctx, pCsr->iId);
-      break;
-  }
-
-  return rc;
-}
-
-/*
-** Return TRUE if the cursor is at EOF.
-*/
-static int zipfileEof(sqlite3_vtab_cursor *cur){
-  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
-  return pCsr->bEof;
-}
-
-/*
-** If aBlob is not NULL, then it points to a buffer nBlob bytes in size
-** containing an entire zip archive image. Or, if aBlob is NULL, then pFile
-** is guaranteed to be a file-handle open on a zip file.
-**
-** This function attempts to locate the EOCD record within the zip archive
-** and populate *pEOCD with the results of decoding it. SQLITE_OK is
-** returned if successful. Otherwise, an SQLite error code is returned and
-** an English language error message may be left in virtual-table pTab.
-*/
-static int zipfileReadEOCD(
-  ZipfileTab *pTab,               /* Return errors here */
-  const u8 *aBlob,                /* Pointer to in-memory file image */
-  int nBlob,                      /* Size of aBlob[] in bytes */
-  FILE *pFile,                    /* Read from this file if aBlob==0 */
-  ZipfileEOCD *pEOCD              /* Object to populate */
-){
-  u8 *aRead = pTab->aBuffer;      /* Temporary buffer */
-  int nRead;                      /* Bytes to read from file */
-  int rc = SQLITE_OK;
-
-  memset(pEOCD, 0, sizeof(ZipfileEOCD));
-  if( aBlob==0 ){
-    i64 iOff;                     /* Offset to read from */
-    i64 szFile;                   /* Total size of file in bytes */
-    fseek(pFile, 0, SEEK_END);
-    szFile = (i64)ftell(pFile);
-    if( szFile==0 ){
-      return SQLITE_OK;
-    }
-    nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE));
-    iOff = szFile - nRead;
-    rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg);
-  }else{
-    nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE));
-    aRead = (u8*)&aBlob[nBlob-nRead];
-  }
-
-  if( rc==SQLITE_OK ){
-    int i;
-
-    /* Scan backwards looking for the signature bytes */
-    for(i=nRead-20; i>=0; i--){
-      if( aRead[i]==0x50 && aRead[i+1]==0x4b 
-       && aRead[i+2]==0x05 && aRead[i+3]==0x06 
-      ){
-        break;
-      }
-    }
-    if( i<0 ){
-      pTab->base.zErrMsg = sqlite3_mprintf(
-          "cannot find end of central directory record"
-      );
-      return SQLITE_ERROR;
-    }
-
-    aRead += i+4;
-    pEOCD->iDisk = zipfileRead16(aRead);
-    pEOCD->iFirstDisk = zipfileRead16(aRead);
-    pEOCD->nEntry = zipfileRead16(aRead);
-    pEOCD->nEntryTotal = zipfileRead16(aRead);
-    pEOCD->nSize = zipfileRead32(aRead);
-    pEOCD->iOffset = zipfileRead32(aRead);
-  }
-
-  return rc;
-}
-
-/*
-** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry 
-** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added
-** to the end of the list. Otherwise, it is added to the list immediately
-** before pBefore (which is guaranteed to be a part of said list).
-*/
-static void zipfileAddEntry(
-  ZipfileTab *pTab, 
-  ZipfileEntry *pBefore, 
-  ZipfileEntry *pNew
-){
-  assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) );
-  assert( pNew->pNext==0 );
-  if( pBefore==0 ){
-    if( pTab->pFirstEntry==0 ){
-      pTab->pFirstEntry = pTab->pLastEntry = pNew;
-    }else{
-      assert( pTab->pLastEntry->pNext==0 );
-      pTab->pLastEntry->pNext = pNew;
-      pTab->pLastEntry = pNew;
-    }
-  }else{
-    ZipfileEntry **pp;
-    for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext));
-    pNew->pNext = pBefore;
-    *pp = pNew;
-  }
-}
-
-static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){
-  ZipfileEOCD eocd;
-  int rc;
-  int i;
-  i64 iOff;
-
-  rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd);
-  iOff = eocd.iOffset;
-  for(i=0; rc==SQLITE_OK && i<eocd.nEntry; i++){
-    ZipfileEntry *pNew = 0;
-    rc = zipfileGetEntry(pTab, aBlob, nBlob, pTab->pWriteFd, iOff, &pNew);
-
-    if( rc==SQLITE_OK ){
-      zipfileAddEntry(pTab, 0, pNew);
-      iOff += ZIPFILE_CDS_FIXED_SZ;
-      iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment;
-    }
-  }
-  return rc;
-}
-
-/*
-** xFilter callback.
-*/
-static int zipfileFilter(
-  sqlite3_vtab_cursor *cur, 
-  int idxNum, const char *idxStr,
-  int argc, sqlite3_value **argv
-){
-  ZipfileTab *pTab = (ZipfileTab*)cur->pVtab;
-  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
-  const char *zFile = 0;          /* Zip file to scan */
-  int rc = SQLITE_OK;             /* Return Code */
-  int bInMemory = 0;              /* True for an in-memory zipfile */
-
-  (void)idxStr;
-  (void)argc;
-
-  zipfileResetCursor(pCsr);
-
-  if( pTab->zFile ){
-    zFile = pTab->zFile;
-  }else if( idxNum==0 ){
-    zipfileCursorErr(pCsr, "zipfile() function requires an argument");
-    return SQLITE_ERROR;
-  }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
-    static const u8 aEmptyBlob = 0;
-    const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]);
-    int nBlob = sqlite3_value_bytes(argv[0]);
-    assert( pTab->pFirstEntry==0 );
-    if( aBlob==0 ){
-      aBlob = &aEmptyBlob;
-      nBlob = 0;
-    }
-    rc = zipfileLoadDirectory(pTab, aBlob, nBlob);
-    pCsr->pFreeEntry = pTab->pFirstEntry;
-    pTab->pFirstEntry = pTab->pLastEntry = 0;
-    if( rc!=SQLITE_OK ) return rc;
-    bInMemory = 1;
-  }else{
-    zFile = (const char*)sqlite3_value_text(argv[0]);
-  }
-
-  if( 0==pTab->pWriteFd && 0==bInMemory ){
-    pCsr->pFile = zFile ? fopen(zFile, "rb") : 0;
-    if( pCsr->pFile==0 ){
-      zipfileCursorErr(pCsr, "cannot open file: %s", zFile);
-      rc = SQLITE_ERROR;
-    }else{
-      rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd);
-      if( rc==SQLITE_OK ){
-        if( pCsr->eocd.nEntry==0 ){
-          pCsr->bEof = 1;
-        }else{
-          pCsr->iNextOff = pCsr->eocd.iOffset;
-          rc = zipfileNext(cur);
-        }
-      }
-    }
-  }else{
-    pCsr->bNoop = 1;
-    pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry;
-    rc = zipfileNext(cur);
-  }
-
-  return rc;
-}
-
-/*
-** xBestIndex callback.
-*/
-static int zipfileBestIndex(
-  sqlite3_vtab *tab,
-  sqlite3_index_info *pIdxInfo
-){
-  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];
-    if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
-    if( pCons->usable==0 ){
-      unusable = 1;
-    }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
-      idx = i;
-    }
-  }
-  pIdxInfo->estimatedCost = 1000.0;
-  if( idx>=0 ){
-    pIdxInfo->aConstraintUsage[idx].argvIndex = 1;
-    pIdxInfo->aConstraintUsage[idx].omit = 1;
-    pIdxInfo->idxNum = 1;
-  }else if( unusable ){
-    return SQLITE_CONSTRAINT;
-  }
-  return SQLITE_OK;
-}
-
-static ZipfileEntry *zipfileNewEntry(const char *zPath){
-  ZipfileEntry *pNew;
-  pNew = sqlite3_malloc(sizeof(ZipfileEntry));
-  if( pNew ){
-    memset(pNew, 0, sizeof(ZipfileEntry));
-    pNew->cds.zFile = sqlite3_mprintf("%s", zPath);
-    if( pNew->cds.zFile==0 ){
-      sqlite3_free(pNew);
-      pNew = 0;
-    }
-  }
-  return pNew;
-}
-
-static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){
-  ZipfileCDS *pCds = &pEntry->cds;
-  u8 *a = aBuf;
-
-  pCds->nExtra = 9;
-
-  /* Write the LFH itself */
-  zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH);
-  zipfileWrite16(a, pCds->iVersionExtract);
-  zipfileWrite16(a, pCds->flags);
-  zipfileWrite16(a, pCds->iCompression);
-  zipfileWrite16(a, pCds->mTime);
-  zipfileWrite16(a, pCds->mDate);
-  zipfileWrite32(a, pCds->crc32);
-  zipfileWrite32(a, pCds->szCompressed);
-  zipfileWrite32(a, pCds->szUncompressed);
-  zipfileWrite16(a, (u16)pCds->nFile);
-  zipfileWrite16(a, pCds->nExtra);
-  assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] );
-
-  /* Add the file name */
-  memcpy(a, pCds->zFile, (int)pCds->nFile);
-  a += (int)pCds->nFile;
-
-  /* The "extra" data */
-  zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
-  zipfileWrite16(a, 5);
-  *a++ = 0x01;
-  zipfileWrite32(a, pEntry->mUnixTime);
-
-  return a-aBuf;
-}
-
-static int zipfileAppendEntry(
-  ZipfileTab *pTab,
-  ZipfileEntry *pEntry,
-  const u8 *pData,
-  int nData
-){
-  u8 *aBuf = pTab->aBuffer;
-  int nBuf;
-  int rc;
-
-  nBuf = zipfileSerializeLFH(pEntry, aBuf);
-  rc = zipfileAppendData(pTab, aBuf, nBuf);
-  if( rc==SQLITE_OK ){
-    pEntry->iDataOff = pTab->szCurrent;
-    rc = zipfileAppendData(pTab, pData, nData);
-  }
-
-  return rc;
-}
-
-static int zipfileGetMode(
-  sqlite3_value *pVal, 
-  int bIsDir,                     /* If true, default to directory */
-  u32 *pMode,                     /* OUT: Mode value */
-  char **pzErr                    /* OUT: Error message */
-){
-  const char *z = (const char*)sqlite3_value_text(pVal);
-  u32 mode = 0;
-  if( z==0 ){
-    mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644));
-  }else if( z[0]>='0' && z[0]<='9' ){
-    mode = (unsigned int)sqlite3_value_int(pVal);
-  }else{
-    const char zTemplate[11] = "-rwxrwxrwx";
-    int i;
-    if( strlen(z)!=10 ) goto parse_error;
-    switch( z[0] ){
-      case '-': mode |= S_IFREG; break;
-      case 'd': mode |= S_IFDIR; break;
-      case 'l': mode |= S_IFLNK; break;
-      default: goto parse_error;
-    }
-    for(i=1; i<10; i++){
-      if( z[i]==zTemplate[i] ) mode |= 1 << (9-i);
-      else if( z[i]!='-' ) goto parse_error;
-    }
-  }
-  if( ((mode & S_IFDIR)==0)==bIsDir ){
-    /* The "mode" attribute is a directory, but data has been specified.
-    ** Or vice-versa - no data but "mode" is a file or symlink.  */
-    *pzErr = sqlite3_mprintf("zipfile: mode does not match data");
-    return SQLITE_CONSTRAINT;
-  }
-  *pMode = mode;
-  return SQLITE_OK;
-
- parse_error:
-  *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z);
-  return SQLITE_ERROR;
-}
-
-/*
-** Both (const char*) arguments point to nul-terminated strings. Argument
-** nB is the value of strlen(zB). This function returns 0 if the strings are
-** identical, ignoring any trailing '/' character in either path.  */
-static int zipfileComparePath(const char *zA, const char *zB, int nB){
-  int nA = (int)strlen(zA);
-  if( nA>0 && zA[nA-1]=='/' ) nA--;
-  if( nB>0 && zB[nB-1]=='/' ) nB--;
-  if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
-  return 1;
-}
-
-static int zipfileBegin(sqlite3_vtab *pVtab){
-  ZipfileTab *pTab = (ZipfileTab*)pVtab;
-  int rc = SQLITE_OK;
-
-  assert( pTab->pWriteFd==0 );
-  if( pTab->zFile==0 || pTab->zFile[0]==0 ){
-    pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename");
-    return SQLITE_ERROR;
-  }
-
-  /* Open a write fd on the file. Also load the entire central directory
-  ** structure into memory. During the transaction any new file data is 
-  ** appended to the archive file, but the central directory is accumulated
-  ** in main-memory until the transaction is committed.  */
-  pTab->pWriteFd = fopen(pTab->zFile, "ab+");
-  if( pTab->pWriteFd==0 ){
-    pTab->base.zErrMsg = sqlite3_mprintf(
-        "zipfile: failed to open file %s for writing", pTab->zFile
-        );
-    rc = SQLITE_ERROR;
-  }else{
-    fseek(pTab->pWriteFd, 0, SEEK_END);
-    pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd);
-    rc = zipfileLoadDirectory(pTab, 0, 0);
-  }
-
-  if( rc!=SQLITE_OK ){
-    zipfileCleanupTransaction(pTab);
-  }
-
-  return rc;
-}
-
-/*
-** Return the current time as a 32-bit timestamp in UNIX epoch format (like
-** time(2)).
-*/
-static u32 zipfileTime(void){
-  sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
-  u32 ret;
-  if( pVfs==0 ) return 0;
-  if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){
-    i64 ms;
-    pVfs->xCurrentTimeInt64(pVfs, &ms);
-    ret = (u32)((ms/1000) - ((i64)24405875 * 8640));
-  }else{
-    double day;
-    pVfs->xCurrentTime(pVfs, &day);
-    ret = (u32)((day - 2440587.5) * 86400);
-  }
-  return ret;
-}
-
-/*
-** Return a 32-bit timestamp in UNIX epoch format.
-**
-** If the value passed as the only argument is either NULL or an SQL NULL,
-** return the current time. Otherwise, return the value stored in (*pVal)
-** cast to a 32-bit unsigned integer.
-*/
-static u32 zipfileGetTime(sqlite3_value *pVal){
-  if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
-    return zipfileTime();
-  }
-  return (u32)sqlite3_value_int64(pVal);
-}
-
-/*
-** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry
-** linked list.  Remove it from the list and free the object.
-*/
-static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){
-  if( pOld ){
-    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);
-  }
-}
-
-/*
-** xUpdate method.
-*/
-static int zipfileUpdate(
-  sqlite3_vtab *pVtab, 
-  int nVal, 
-  sqlite3_value **apVal, 
-  sqlite_int64 *pRowid
-){
-  ZipfileTab *pTab = (ZipfileTab*)pVtab;
-  int rc = SQLITE_OK;             /* Return Code */
-  ZipfileEntry *pNew = 0;         /* New in-memory CDS entry */
-
-  u32 mode = 0;                   /* Mode for new entry */
-  u32 mTime = 0;                  /* Modification time for new entry */
-  i64 sz = 0;                     /* Uncompressed size */
-  const char *zPath = 0;          /* Path for new entry */
-  int nPath = 0;                  /* strlen(zPath) */
-  const u8 *pData = 0;            /* Pointer to buffer containing content */
-  int nData = 0;                  /* Size of pData buffer in bytes */
-  int iMethod = 0;                /* Compression method for new entry */
-  u8 *pFree = 0;                  /* Free this */
-  char *zFree = 0;                /* Also free this */
-  ZipfileEntry *pOld = 0;
-  ZipfileEntry *pOld2 = 0;
-  int bUpdate = 0;                /* True for an update that modifies "name" */
-  int bIsDir = 0;
-  u32 iCrc32 = 0;
-
-  (void)pRowid;
-
-  if( pTab->pWriteFd==0 ){
-    rc = zipfileBegin(pVtab);
-    if( rc!=SQLITE_OK ) return rc;
-  }
-
-  /* If this is a DELETE or UPDATE, find the archive entry to delete. */
-  if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
-    const char *zDelete = (const char*)sqlite3_value_text(apVal[0]);
-    int nDelete = (int)strlen(zDelete);
-    if( nVal>1 ){
-      const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]);
-      if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
-        bUpdate = 1;
-      }
-    }
-    for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
-      if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
-        break;
-      }
-      assert( pOld->pNext );
-    }
-  }
-
-  if( nVal>1 ){
-    /* Check that "sz" and "rawdata" are both NULL: */
-    if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){
-      zipfileTableErr(pTab, "sz must be NULL");
-      rc = SQLITE_CONSTRAINT;
-    }
-    if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){
-      zipfileTableErr(pTab, "rawdata must be NULL"); 
-      rc = SQLITE_CONSTRAINT;
-    }
-
-    if( rc==SQLITE_OK ){
-      if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){
-        /* data=NULL. A directory */
-        bIsDir = 1;
-      }else{
-        /* Value specified for "data", and possibly "method". This must be
-        ** a regular file or a symlink. */
-        const u8 *aIn = sqlite3_value_blob(apVal[7]);
-        int nIn = sqlite3_value_bytes(apVal[7]);
-        int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL;
-
-        iMethod = sqlite3_value_int(apVal[8]);
-        sz = nIn;
-        pData = aIn;
-        nData = nIn;
-        if( iMethod!=0 && iMethod!=8 ){
-          zipfileTableErr(pTab, "unknown compression method: %d", iMethod);
-          rc = SQLITE_CONSTRAINT;
-        }else{
-          if( bAuto || iMethod ){
-            int nCmp;
-            rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg);
-            if( rc==SQLITE_OK ){
-              if( iMethod || nCmp<nIn ){
-                iMethod = 8;
-                pData = pFree;
-                nData = nCmp;
-              }
-            }
-          }
-          iCrc32 = crc32(0, aIn, nIn);
-        }
-      }
-    }
-
-    if( rc==SQLITE_OK ){
-      rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg);
-    }
-
-    if( rc==SQLITE_OK ){
-      zPath = (const char*)sqlite3_value_text(apVal[2]);
-      if( zPath==0 ) zPath = "";
-      nPath = (int)strlen(zPath);
-      mTime = zipfileGetTime(apVal[4]);
-    }
-
-    if( rc==SQLITE_OK && bIsDir ){
-      /* For a directory, check that the last character in the path is a
-      ** '/'. This appears to be required for compatibility with info-zip
-      ** (the unzip command on unix). It does not create directories
-      ** otherwise.  */
-      if( nPath<=0 || zPath[nPath-1]!='/' ){
-        zFree = sqlite3_mprintf("%s/", zPath);
-        zPath = (const char*)zFree;
-        if( zFree==0 ){
-          rc = SQLITE_NOMEM;
-          nPath = 0;
-        }else{
-          nPath = (int)strlen(zPath);
-        }
-      }
-    }
-
-    /* Check that we're not inserting a duplicate entry -OR- updating an
-    ** entry with a path, thereby making it into a duplicate. */
-    if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
-      ZipfileEntry *p;
-      for(p=pTab->pFirstEntry; p; p=p->pNext){
-        if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){
-          switch( sqlite3_vtab_on_conflict(pTab->db) ){
-            case SQLITE_IGNORE: {
-              goto zipfile_update_done;
-            }
-            case SQLITE_REPLACE: {
-              pOld2 = p;
-              break;
-            }
-            default: {
-              zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath);
-              rc = SQLITE_CONSTRAINT;
-              break;
-            }
-          }
-          break;
-        }
-      }
-    }
-
-    if( rc==SQLITE_OK ){
-      /* Create the new CDS record. */
-      pNew = zipfileNewEntry(zPath);
-      if( pNew==0 ){
-        rc = SQLITE_NOMEM;
-      }else{
-        pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
-        pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
-        pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS;
-        pNew->cds.iCompression = (u16)iMethod;
-        zipfileMtimeToDos(&pNew->cds, mTime);
-        pNew->cds.crc32 = iCrc32;
-        pNew->cds.szCompressed = nData;
-        pNew->cds.szUncompressed = (u32)sz;
-        pNew->cds.iExternalAttr = (mode<<16);
-        pNew->cds.iOffset = (u32)pTab->szCurrent;
-        pNew->cds.nFile = (u16)nPath;
-        pNew->mUnixTime = (u32)mTime;
-        rc = zipfileAppendEntry(pTab, pNew, pData, nData);
-        zipfileAddEntry(pTab, pOld, pNew);
-      }
-    }
-  }
-
-  if( rc==SQLITE_OK && (pOld || pOld2) ){
-    ZipfileCsr *pCsr;
-    for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
-      if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){
-        pCsr->pCurrent = pCsr->pCurrent->pNext;
-        pCsr->bNoop = 1;
-      }
-    }
-
-    zipfileRemoveEntryFromList(pTab, pOld);
-    zipfileRemoveEntryFromList(pTab, pOld2);
-  }
-
-zipfile_update_done:
-  sqlite3_free(pFree);
-  sqlite3_free(zFree);
-  return rc;
-}
-
-static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){
-  u8 *a = aBuf;
-  zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD);
-  zipfileWrite16(a, p->iDisk);
-  zipfileWrite16(a, p->iFirstDisk);
-  zipfileWrite16(a, p->nEntry);
-  zipfileWrite16(a, p->nEntryTotal);
-  zipfileWrite32(a, p->nSize);
-  zipfileWrite32(a, p->iOffset);
-  zipfileWrite16(a, 0);        /* Size of trailing comment in bytes*/
-
-  return a-aBuf;
-}
-
-static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){
-  int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer);
-  assert( nBuf==ZIPFILE_EOCD_FIXED_SZ );
-  return zipfileAppendData(pTab, pTab->aBuffer, nBuf);
-}
-
-/*
-** Serialize the CDS structure into buffer aBuf[]. Return the number
-** of bytes written.
-*/
-static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){
-  u8 *a = aBuf;
-  ZipfileCDS *pCDS = &pEntry->cds;
-
-  if( pEntry->aExtra==0 ){
-    pCDS->nExtra = 9;
-  }
-
-  zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS);
-  zipfileWrite16(a, pCDS->iVersionMadeBy);
-  zipfileWrite16(a, pCDS->iVersionExtract);
-  zipfileWrite16(a, pCDS->flags);
-  zipfileWrite16(a, pCDS->iCompression);
-  zipfileWrite16(a, pCDS->mTime);
-  zipfileWrite16(a, pCDS->mDate);
-  zipfileWrite32(a, pCDS->crc32);
-  zipfileWrite32(a, pCDS->szCompressed);
-  zipfileWrite32(a, pCDS->szUncompressed);
-  assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
-  zipfileWrite16(a, pCDS->nFile);
-  zipfileWrite16(a, pCDS->nExtra);
-  zipfileWrite16(a, pCDS->nComment);
-  zipfileWrite16(a, pCDS->iDiskStart);
-  zipfileWrite16(a, pCDS->iInternalAttr);
-  zipfileWrite32(a, pCDS->iExternalAttr);
-  zipfileWrite32(a, pCDS->iOffset);
-
-  memcpy(a, pCDS->zFile, pCDS->nFile);
-  a += pCDS->nFile;
-
-  if( pEntry->aExtra ){
-    int n = (int)pCDS->nExtra + (int)pCDS->nComment;
-    memcpy(a, pEntry->aExtra, n);
-    a += n;
-  }else{
-    assert( pCDS->nExtra==9 );
-    zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP);
-    zipfileWrite16(a, 5);
-    *a++ = 0x01;
-    zipfileWrite32(a, pEntry->mUnixTime);
-  }
-
-  return a-aBuf;
-}
-
-static int zipfileCommit(sqlite3_vtab *pVtab){
-  ZipfileTab *pTab = (ZipfileTab*)pVtab;
-  int rc = SQLITE_OK;
-  if( pTab->pWriteFd ){
-    i64 iOffset = pTab->szCurrent;
-    ZipfileEntry *p;
-    ZipfileEOCD eocd;
-    int nEntry = 0;
-
-    /* Write out all entries */
-    for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){
-      int n = zipfileSerializeCDS(p, pTab->aBuffer);
-      rc = zipfileAppendData(pTab, pTab->aBuffer, n);
-      nEntry++;
-    }
-
-    /* Write out the EOCD record */
-    eocd.iDisk = 0;
-    eocd.iFirstDisk = 0;
-    eocd.nEntry = (u16)nEntry;
-    eocd.nEntryTotal = (u16)nEntry;
-    eocd.nSize = (u32)(pTab->szCurrent - iOffset);
-    eocd.iOffset = (u32)iOffset;
-    rc = zipfileAppendEOCD(pTab, &eocd);
-
-    zipfileCleanupTransaction(pTab);
-  }
-  return rc;
-}
-
-static int zipfileRollback(sqlite3_vtab *pVtab){
-  return zipfileCommit(pVtab);
-}
-
-static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){
-  ZipfileCsr *pCsr;
-  for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
-    if( iId==pCsr->iId ) break;
-  }
-  return pCsr;
-}
-
-static void zipfileFunctionCds(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  ZipfileCsr *pCsr;
-  ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context);
-  assert( argc>0 );
-
-  pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0]));
-  if( pCsr ){
-    ZipfileCDS *p = &pCsr->pCurrent->cds;
-    char *zRes = sqlite3_mprintf("{"
-        "\"version-made-by\" : %u, "
-        "\"version-to-extract\" : %u, "
-        "\"flags\" : %u, "
-        "\"compression\" : %u, "
-        "\"time\" : %u, "
-        "\"date\" : %u, "
-        "\"crc32\" : %u, "
-        "\"compressed-size\" : %u, "
-        "\"uncompressed-size\" : %u, "
-        "\"file-name-length\" : %u, "
-        "\"extra-field-length\" : %u, "
-        "\"file-comment-length\" : %u, "
-        "\"disk-number-start\" : %u, "
-        "\"internal-attr\" : %u, "
-        "\"external-attr\" : %u, "
-        "\"offset\" : %u }",
-        (u32)p->iVersionMadeBy, (u32)p->iVersionExtract,
-        (u32)p->flags, (u32)p->iCompression,
-        (u32)p->mTime, (u32)p->mDate,
-        (u32)p->crc32, (u32)p->szCompressed,
-        (u32)p->szUncompressed, (u32)p->nFile,
-        (u32)p->nExtra, (u32)p->nComment,
-        (u32)p->iDiskStart, (u32)p->iInternalAttr,
-        (u32)p->iExternalAttr, (u32)p->iOffset
-    );
-
-    if( zRes==0 ){
-      sqlite3_result_error_nomem(context);
-    }else{
-      sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
-      sqlite3_free(zRes);
-    }
-  }
-}
-
-/*
-** xFindFunction method.
-*/
-static int zipfileFindFunction(
-  sqlite3_vtab *pVtab,            /* Virtual table handle */
-  int nArg,                       /* Number of SQL function arguments */
-  const char *zName,              /* Name of SQL function */
-  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;
-    return 1;
-  }
-  return 0;
-}
-
-typedef struct ZipfileBuffer ZipfileBuffer;
-struct ZipfileBuffer {
-  u8 *a;                          /* Pointer to buffer */
-  int n;                          /* Size of buffer in bytes */
-  int nAlloc;                     /* Byte allocated at a[] */
-};
-
-typedef struct ZipfileCtx ZipfileCtx;
-struct ZipfileCtx {
-  int nEntry;
-  ZipfileBuffer body;
-  ZipfileBuffer cds;
-};
-
-static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){
-  if( pBuf->n+nByte>pBuf->nAlloc ){
-    u8 *aNew;
-    sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512;
-    int nReq = pBuf->n + nByte;
-
-    while( nNew<nReq ) nNew = nNew*2;
-    aNew = sqlite3_realloc64(pBuf->a, nNew);
-    if( aNew==0 ) return SQLITE_NOMEM;
-    pBuf->a = aNew;
-    pBuf->nAlloc = (int)nNew;
-  }
-  return SQLITE_OK;
-}
-
-/*
-** xStep() callback for the zipfile() aggregate. This can be called in
-** any of the following ways:
-**
-**   SELECT zipfile(name,data) ...
-**   SELECT zipfile(name,mode,mtime,data) ...
-**   SELECT zipfile(name,mode,mtime,data,method) ...
-*/
-static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
-  ZipfileCtx *p;                  /* Aggregate function context */
-  ZipfileEntry e;                 /* New entry to add to zip archive */
-
-  sqlite3_value *pName = 0;
-  sqlite3_value *pMode = 0;
-  sqlite3_value *pMtime = 0;
-  sqlite3_value *pData = 0;
-  sqlite3_value *pMethod = 0;
-
-  int bIsDir = 0;
-  u32 mode;
-  int rc = SQLITE_OK;
-  char *zErr = 0;
-
-  int iMethod = -1;               /* Compression method to use (0 or 8) */
-
-  const u8 *aData = 0;            /* Possibly compressed data for new entry */
-  int nData = 0;                  /* Size of aData[] in bytes */
-  int szUncompressed = 0;         /* Size of data before compression */
-  u8 *aFree = 0;                  /* Free this before returning */
-  u32 iCrc32 = 0;                 /* crc32 of uncompressed data */
-
-  char *zName = 0;                /* Path (name) of new entry */
-  int nName = 0;                  /* Size of zName in bytes */
-  char *zFree = 0;                /* Free this before returning */
-  int nByte;
-
-  memset(&e, 0, sizeof(e));
-  p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
-  if( p==0 ) return;
-
-  /* Martial the arguments into stack variables */
-  if( nVal!=2 && nVal!=4 && nVal!=5 ){
-    zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()");
-    rc = SQLITE_ERROR;
-    goto zipfile_step_out;
-  }
-  pName = apVal[0];
-  if( nVal==2 ){
-    pData = apVal[1];
-  }else{
-    pMode = apVal[1];
-    pMtime = apVal[2];
-    pData = apVal[3];
-    if( nVal==5 ){
-      pMethod = apVal[4];
-    }
-  }
-
-  /* Check that the 'name' parameter looks ok. */
-  zName = (char*)sqlite3_value_text(pName);
-  nName = sqlite3_value_bytes(pName);
-  if( zName==0 ){
-    zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL");
-    rc = SQLITE_ERROR;
-    goto zipfile_step_out;
-  }
-
-  /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
-  ** deflate compression) or NULL (choose automatically).  */
-  if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
-    iMethod = (int)sqlite3_value_int64(pMethod);
-    if( iMethod!=0 && iMethod!=8 ){
-      zErr = sqlite3_mprintf("illegal method value: %d", iMethod);
-      rc = SQLITE_ERROR;
-      goto zipfile_step_out;
-    }
-  }
-
-  /* Now inspect the data. If this is NULL, then the new entry must be a
-  ** directory.  Otherwise, figure out whether or not the data should
-  ** be deflated or simply stored in the zip archive. */
-  if( sqlite3_value_type(pData)==SQLITE_NULL ){
-    bIsDir = 1;
-    iMethod = 0;
-  }else{
-    aData = sqlite3_value_blob(pData);
-    szUncompressed = nData = sqlite3_value_bytes(pData);
-    iCrc32 = crc32(0, aData, nData);
-    if( iMethod<0 || iMethod==8 ){
-      int nOut = 0;
-      rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr);
-      if( rc!=SQLITE_OK ){
-        goto zipfile_step_out;
-      }
-      if( iMethod==8 || nOut<nData ){
-        aData = aFree;
-        nData = nOut;
-        iMethod = 8;
-      }else{
-        iMethod = 0;
-      }
-    }
-  }
-
-  /* Decode the "mode" argument. */
-  rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr);
-  if( rc ) goto zipfile_step_out;
-
-  /* Decode the "mtime" argument. */
-  e.mUnixTime = zipfileGetTime(pMtime);
-
-  /* If this is a directory entry, ensure that there is exactly one '/'
-  ** at the end of the path. Or, if this is not a directory and the path
-  ** ends in '/' it is an error. */
-  if( bIsDir==0 ){
-    if( nName>0 && zName[nName-1]=='/' ){
-      zErr = sqlite3_mprintf("non-directory name must not end with /");
-      rc = SQLITE_ERROR;
-      goto zipfile_step_out;
-    }
-  }else{
-    if( nName==0 || zName[nName-1]!='/' ){
-      zName = zFree = sqlite3_mprintf("%s/", zName);
-      if( zName==0 ){
-        rc = SQLITE_NOMEM;
-        goto zipfile_step_out;
-      }
-      nName = (int)strlen(zName);
-    }else{
-      while( nName>1 && zName[nName-2]=='/' ) nName--;
-    }
-  }
-
-  /* Assemble the ZipfileEntry object for the new zip archive entry */
-  e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
-  e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
-  e.cds.flags = ZIPFILE_NEWENTRY_FLAGS;
-  e.cds.iCompression = (u16)iMethod;
-  zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime);
-  e.cds.crc32 = iCrc32;
-  e.cds.szCompressed = nData;
-  e.cds.szUncompressed = szUncompressed;
-  e.cds.iExternalAttr = (mode<<16);
-  e.cds.iOffset = p->body.n;
-  e.cds.nFile = (u16)nName;
-  e.cds.zFile = zName;
-
-  /* Append the LFH to the body of the new archive */
-  nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9;
-  if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out;
-  p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]);
-
-  /* Append the data to the body of the new archive */
-  if( nData>0 ){
-    if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out;
-    memcpy(&p->body.a[p->body.n], aData, nData);
-    p->body.n += nData;
-  }
-
-  /* Append the CDS record to the directory of the new archive */
-  nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9;
-  if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out;
-  p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]);
-
-  /* Increment the count of entries in the archive */
-  p->nEntry++;
-
- zipfile_step_out:
-  sqlite3_free(aFree);
-  sqlite3_free(zFree);
-  if( rc ){
-    if( zErr ){
-      sqlite3_result_error(pCtx, zErr, -1);
-    }else{
-      sqlite3_result_error_code(pCtx, rc);
-    }
-  }
-  sqlite3_free(zErr);
-}
-
-/*
-** xFinalize() callback for zipfile aggregate function.
-*/
-static void zipfileFinal(sqlite3_context *pCtx){
-  ZipfileCtx *p;
-  ZipfileEOCD eocd;
-  sqlite3_int64 nZip;
-  u8 *aZip;
-
-  p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
-  if( p==0 ) return;
-  if( p->nEntry>0 ){
-    memset(&eocd, 0, sizeof(eocd));
-    eocd.nEntry = (u16)p->nEntry;
-    eocd.nEntryTotal = (u16)p->nEntry;
-    eocd.nSize = p->cds.n;
-    eocd.iOffset = p->body.n;
-
-    nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
-    aZip = (u8*)sqlite3_malloc64(nZip);
-    if( aZip==0 ){
-      sqlite3_result_error_nomem(pCtx);
-    }else{
-      memcpy(aZip, p->body.a, p->body.n);
-      memcpy(&aZip[p->body.n], p->cds.a, p->cds.n);
-      zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]);
-      sqlite3_result_blob(pCtx, aZip, (int)nZip, zipfileFree);
-    }
-  }
-
-  sqlite3_free(p->body.a);
-  sqlite3_free(p->cds.a);
-}
-
-
-/*
-** Register the "zipfile" virtual table.
-*/
-static int zipfileRegister(sqlite3 *db){
-  static sqlite3_module zipfileModule = {
-    1,                         /* iVersion */
-    zipfileConnect,            /* xCreate */
-    zipfileConnect,            /* xConnect */
-    zipfileBestIndex,          /* xBestIndex */
-    zipfileDisconnect,         /* xDisconnect */
-    zipfileDisconnect,         /* xDestroy */
-    zipfileOpen,               /* xOpen - open a cursor */
-    zipfileClose,              /* xClose - close a cursor */
-    zipfileFilter,             /* xFilter - configure scan constraints */
-    zipfileNext,               /* xNext - advance a cursor */
-    zipfileEof,                /* xEof - check for end of scan */
-    zipfileColumn,             /* xColumn - read data */
-    0,                         /* xRowid - read data */
-    zipfileUpdate,             /* xUpdate */
-    zipfileBegin,              /* xBegin */
-    0,                         /* xSync */
-    zipfileCommit,             /* xCommit */
-    zipfileRollback,           /* xRollback */
-    zipfileFindFunction,       /* xFindMethod */
-    0,                         /* xRename */
-    0,                         /* xSavepoint */
-    0,                         /* xRelease */
-    0,                         /* xRollback */
-    0                          /* xShadowName */
-  };
-
-  int rc = sqlite3_create_module(db, "zipfile"  , &zipfileModule, 0);
-  if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1);
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0, 
-        zipfileStep, zipfileFinal
-    );
-  }
-  assert( sizeof(i64)==8 );
-  assert( sizeof(u32)==4 );
-  assert( sizeof(u16)==2 );
-  assert( sizeof(u8)==1 );
-  return rc;
-}
-#else         /* SQLITE_OMIT_VIRTUALTABLE */
-# define zipfileRegister(x) SQLITE_OK
-#endif
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_zipfile_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
-  SQLITE_EXTENSION_INIT2(pApi);
-  (void)pzErrMsg;  /* Unused parameter */
-  return zipfileRegister(db);
-}
-
-/************************* End ../ext/misc/zipfile.c ********************/
-/************************* Begin ../ext/misc/sqlar.c ******************/
-/*
-** 2017-12-17
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** Utility functions sqlar_compress() and sqlar_uncompress(). Useful
-** for working with sqlar archives and used by the shell tool's built-in
-** sqlar support.
-*/
-/* #include "sqlite3ext.h" */
-SQLITE_EXTENSION_INIT1
-#include <zlib.h>
-#include <assert.h>
-
-/*
-** Implementation of the "sqlar_compress(X)" SQL function.
-**
-** If the type of X is SQLITE_BLOB, and compressing that blob using
-** zlib utility function compress() yields a smaller blob, return the
-** compressed blob. Otherwise, return a copy of X.
-**
-** SQLar uses the "zlib format" for compressed content.  The zlib format
-** contains a two-byte identification header and a four-byte checksum at
-** the end.  This is different from ZIP which uses the raw deflate format.
-**
-** Future enhancements to SQLar might add support for new compression formats.
-** If so, those new formats will be identified by alternative headers in the
-** compressed data.
-*/
-static void sqlarCompressFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  assert( argc==1 );
-  if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
-    const Bytef *pData = sqlite3_value_blob(argv[0]);
-    uLong nData = sqlite3_value_bytes(argv[0]);
-    uLongf nOut = compressBound(nData);
-    Bytef *pOut;
-
-    pOut = (Bytef*)sqlite3_malloc(nOut);
-    if( pOut==0 ){
-      sqlite3_result_error_nomem(context);
-      return;
-    }else{
-      if( Z_OK!=compress(pOut, &nOut, pData, nData) ){
-        sqlite3_result_error(context, "error in compress()", -1);
-      }else if( nOut<nData ){
-        sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT);
-      }else{
-        sqlite3_result_value(context, argv[0]);
-      }
-      sqlite3_free(pOut);
-    }
-  }else{
-    sqlite3_result_value(context, argv[0]);
-  }
-}
-
-/*
-** Implementation of the "sqlar_uncompress(X,SZ)" SQL function
-**
-** Parameter SZ is interpreted as an integer. If it is less than or
-** equal to zero, then this function returns a copy of X. Or, if
-** SZ is equal to the size of X when interpreted as a blob, also
-** return a copy of X. Otherwise, decompress blob X using zlib
-** utility function uncompress() and return the results (another
-** blob).
-*/
-static void sqlarUncompressFunc(
-  sqlite3_context *context,
-  int argc,
-  sqlite3_value **argv
-){
-  uLong nData;
-  uLongf sz;
-
-  assert( argc==2 );
-  sz = sqlite3_value_int(argv[1]);
-
-  if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){
-    sqlite3_result_value(context, argv[0]);
-  }else{
-    const Bytef *pData= sqlite3_value_blob(argv[0]);
-    Bytef *pOut = sqlite3_malloc(sz);
-    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);
-    }
-    sqlite3_free(pOut);
-  }
-}
-
-#ifdef _WIN32
-
-#endif
-int sqlite3_sqlar_init(
-  sqlite3 *db, 
-  char **pzErrMsg, 
-  const sqlite3_api_routines *pApi
-){
-  int rc = SQLITE_OK;
-  SQLITE_EXTENSION_INIT2(pApi);
-  (void)pzErrMsg;  /* Unused parameter */
-  rc = sqlite3_create_function(db, "sqlar_compress", 1, 
-                               SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
-                               sqlarCompressFunc, 0, 0);
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_create_function(db, "sqlar_uncompress", 2,
-                                 SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
-                                 sqlarUncompressFunc, 0, 0);
-  }
-  return rc;
-}
-
-/************************* End ../ext/misc/sqlar.c ********************/
-#endif
-/************************* Begin ../ext/expert/sqlite3expert.h ******************/
-/*
-** 2017 April 07
-**
-** 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.
-**
-*************************************************************************
-*/
-#if !defined(SQLITEEXPERT_H)
-#define SQLITEEXPERT_H 1
-/* #include "sqlite3.h" */
-
-typedef struct sqlite3expert sqlite3expert;
-
-/*
-** Create a new sqlite3expert object.
-**
-** If successful, a pointer to the new object is returned and (*pzErr) set
-** to NULL. Or, if an error occurs, NULL is returned and (*pzErr) set to
-** an English-language error message. In this case it is the responsibility
-** of the caller to eventually free the error message buffer using
-** sqlite3_free().
-*/
-sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErr);
-
-/*
-** Configure an sqlite3expert object.
-**
-** EXPERT_CONFIG_SAMPLE:
-**   By default, sqlite3_expert_analyze() generates sqlite_stat1 data for
-**   each candidate index. This involves scanning and sorting the entire
-**   contents of each user database table once for each candidate index
-**   associated with the table. For large databases, this can be 
-**   prohibitively slow. This option allows the sqlite3expert object to
-**   be configured so that sqlite_stat1 data is instead generated based on a
-**   subset of each table, or so that no sqlite_stat1 data is used at all.
-**
-**   A single integer argument is passed to this option. If the value is less
-**   than or equal to zero, then no sqlite_stat1 data is generated or used by
-**   the analysis - indexes are recommended based on the database schema only.
-**   Or, if the value is 100 or greater, complete sqlite_stat1 data is
-**   generated for each candidate index (this is the default). Finally, if the
-**   value falls between 0 and 100, then it represents the percentage of user
-**   table rows that should be considered when generating sqlite_stat1 data.
-**
-**   Examples:
-**
-**     // Do not generate any sqlite_stat1 data
-**     sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 0);
-**
-**     // Generate sqlite_stat1 data based on 10% of the rows in each table.
-**     sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 10);
-*/
-int sqlite3_expert_config(sqlite3expert *p, int op, ...);
-
-#define EXPERT_CONFIG_SAMPLE 1    /* int */
-
-/*
-** Specify zero or more SQL statements to be included in the analysis.
-**
-** Buffer zSql must contain zero or more complete SQL statements. This
-** function parses all statements contained in the buffer and adds them
-** to the internal list of statements to analyze. If successful, SQLITE_OK
-** is returned and (*pzErr) set to NULL. Or, if an error occurs - for example
-** due to a error in the SQL - an SQLite error code is returned and (*pzErr)
-** may be set to point to an English language error message. In this case
-** the caller is responsible for eventually freeing the error message buffer
-** using sqlite3_free().
-**
-** If an error does occur while processing one of the statements in the
-** buffer passed as the second argument, none of the statements in the
-** buffer are added to the analysis.
-**
-** This function must be called before sqlite3_expert_analyze(). If a call
-** to this function is made on an sqlite3expert object that has already
-** been passed to sqlite3_expert_analyze() SQLITE_MISUSE is returned
-** immediately and no statements are added to the analysis.
-*/
-int sqlite3_expert_sql(
-  sqlite3expert *p,               /* From a successful sqlite3_expert_new() */
-  const char *zSql,               /* SQL statement(s) to add */
-  char **pzErr                    /* OUT: Error message (if any) */
-);
-
-
-/*
-** This function is called after the sqlite3expert object has been configured
-** with all SQL statements using sqlite3_expert_sql() to actually perform
-** the analysis. Once this function has been called, it is not possible to
-** add further SQL statements to the analysis.
-**
-** If successful, SQLITE_OK is returned and (*pzErr) is set to NULL. Or, if
-** an error occurs, an SQLite error code is returned and (*pzErr) set to 
-** point to a buffer containing an English language error message. In this
-** case it is the responsibility of the caller to eventually free the buffer
-** using sqlite3_free().
-**
-** If an error does occur within this function, the sqlite3expert object
-** is no longer useful for any purpose. At that point it is no longer
-** possible to add further SQL statements to the object or to re-attempt
-** the analysis. The sqlite3expert object must still be freed using a call
-** sqlite3_expert_destroy().
-*/
-int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr);
-
-/*
-** Return the total number of statements loaded using sqlite3_expert_sql().
-** The total number of SQL statements may be different from the total number
-** to calls to sqlite3_expert_sql().
-*/
-int sqlite3_expert_count(sqlite3expert*);
-
-/*
-** Return a component of the report.
-**
-** This function is called after sqlite3_expert_analyze() to extract the
-** results of the analysis. Each call to this function returns either a
-** NULL pointer or a pointer to a buffer containing a nul-terminated string.
-** The value passed as the third argument must be one of the EXPERT_REPORT_*
-** #define constants defined below.
-**
-** For some EXPERT_REPORT_* parameters, the buffer returned contains 
-** information relating to a specific SQL statement. In these cases that
-** SQL statement is identified by the value passed as the second argument.
-** SQL statements are numbered from 0 in the order in which they are parsed.
-** If an out-of-range value (less than zero or equal to or greater than the
-** value returned by sqlite3_expert_count()) is passed as the second argument
-** along with such an EXPERT_REPORT_* parameter, NULL is always returned.
-**
-** EXPERT_REPORT_SQL:
-**   Return the text of SQL statement iStmt.
-**
-** EXPERT_REPORT_INDEXES:
-**   Return a buffer containing the CREATE INDEX statements for all recommended
-**   indexes for statement iStmt. If there are no new recommeded indexes, NULL 
-**   is returned.
-**
-** EXPERT_REPORT_PLAN:
-**   Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query
-**   iStmt after the proposed indexes have been added to the database schema.
-**
-** EXPERT_REPORT_CANDIDATES:
-**   Return a pointer to a buffer containing the CREATE INDEX statements 
-**   for all indexes that were tested (for all SQL statements). The iStmt
-**   parameter is ignored for EXPERT_REPORT_CANDIDATES calls.
-*/
-const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport);
-
-/*
-** Values for the third argument passed to sqlite3_expert_report().
-*/
-#define EXPERT_REPORT_SQL        1
-#define EXPERT_REPORT_INDEXES    2
-#define EXPERT_REPORT_PLAN       3
-#define EXPERT_REPORT_CANDIDATES 4
-
-/*
-** Free an (sqlite3expert*) handle and all associated resources. There 
-** should be one call to this function for each successful call to 
-** sqlite3-expert_new().
-*/
-void sqlite3_expert_destroy(sqlite3expert*);
-
-#endif  /* !defined(SQLITEEXPERT_H) */
-
-/************************* End ../ext/expert/sqlite3expert.h ********************/
-/************************* Begin ../ext/expert/sqlite3expert.c ******************/
-/*
-** 2017 April 09
-**
-** 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.
-**
-*************************************************************************
-*/
-/* #include "sqlite3expert.h" */
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-
-#if !defined(SQLITE_AMALGAMATION)
-#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
-# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
-#endif
-#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
-# define ALWAYS(X)      (1)
-# define NEVER(X)       (0)
-#elif !defined(NDEBUG)
-# define ALWAYS(X)      ((X)?1:(assert(0),0))
-# define NEVER(X)       ((X)?(assert(0),1):0)
-#else
-# define ALWAYS(X)      (X)
-# define NEVER(X)       (X)
-#endif
-#endif /* !defined(SQLITE_AMALGAMATION) */
-
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE 
-
-/* typedef sqlite3_int64 i64; */
-/* typedef sqlite3_uint64 u64; */
-
-typedef struct IdxColumn IdxColumn;
-typedef struct IdxConstraint IdxConstraint;
-typedef struct IdxScan IdxScan;
-typedef struct IdxStatement IdxStatement;
-typedef struct IdxTable IdxTable;
-typedef struct IdxWrite IdxWrite;
-
-#define STRLEN  (int)strlen
-
-/*
-** A temp table name that we assume no user database will actually use.
-** If this assumption proves incorrect triggers on the table with the
-** conflicting name will be ignored.
-*/
-#define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776"
-
-/*
-** A single constraint. Equivalent to either "col = ?" or "col < ?" (or
-** any other type of single-ended range constraint on a column).
-**
-** pLink:
-**   Used to temporarily link IdxConstraint objects into lists while
-**   creating candidate indexes.
-*/
-struct IdxConstraint {
-  char *zColl;                    /* Collation sequence */
-  int bRange;                     /* True for range, false for eq */
-  int iCol;                       /* Constrained table column */
-  int bFlag;                      /* Used by idxFindCompatible() */
-  int bDesc;                      /* True if ORDER BY <expr> DESC */
-  IdxConstraint *pNext;           /* Next constraint in pEq or pRange list */
-  IdxConstraint *pLink;           /* See above */
-};
-
-/*
-** A single scan of a single table.
-*/
-struct IdxScan {
-  IdxTable *pTab;                 /* Associated table object */
-  int iDb;                        /* Database containing table zTable */
-  i64 covering;                   /* Mask of columns required for cov. index */
-  IdxConstraint *pOrder;          /* ORDER BY columns */
-  IdxConstraint *pEq;             /* List of == constraints */
-  IdxConstraint *pRange;          /* List of < constraints */
-  IdxScan *pNextScan;             /* Next IdxScan object for same analysis */
-};
-
-/*
-** Information regarding a single database table. Extracted from 
-** "PRAGMA table_info" by function idxGetTableInfo().
-*/
-struct IdxColumn {
-  char *zName;
-  char *zColl;
-  int iPk;
-};
-struct IdxTable {
-  int nCol;
-  char *zName;                    /* Table name */
-  IdxColumn *aCol;
-  IdxTable *pNext;                /* Next table in linked list of all tables */
-};
-
-/*
-** An object of the following type is created for each unique table/write-op
-** seen. The objects are stored in a singly-linked list beginning at
-** sqlite3expert.pWrite.
-*/
-struct IdxWrite {
-  IdxTable *pTab;
-  int eOp;                        /* SQLITE_UPDATE, DELETE or INSERT */
-  IdxWrite *pNext;
-};
-
-/*
-** Each statement being analyzed is represented by an instance of this
-** structure.
-*/
-struct IdxStatement {
-  int iId;                        /* Statement number */
-  char *zSql;                     /* SQL statement */
-  char *zIdx;                     /* Indexes */
-  char *zEQP;                     /* Plan */
-  IdxStatement *pNext;
-};
-
-
-/*
-** A hash table for storing strings. With space for a payload string
-** with each entry. Methods are:
-**
-**   idxHashInit()
-**   idxHashClear()
-**   idxHashAdd()
-**   idxHashSearch()
-*/
-#define IDX_HASH_SIZE 1023
-typedef struct IdxHashEntry IdxHashEntry;
-typedef struct IdxHash IdxHash;
-struct IdxHashEntry {
-  char *zKey;                     /* nul-terminated key */
-  char *zVal;                     /* nul-terminated value string */
-  char *zVal2;                    /* nul-terminated value string 2 */
-  IdxHashEntry *pHashNext;        /* Next entry in same hash bucket */
-  IdxHashEntry *pNext;            /* Next entry in hash */
-};
-struct IdxHash {
-  IdxHashEntry *pFirst;
-  IdxHashEntry *aHash[IDX_HASH_SIZE];
-};
-
-/*
-** sqlite3expert object.
-*/
-struct sqlite3expert {
-  int iSample;                    /* Percentage of tables to sample for stat1 */
-  sqlite3 *db;                    /* User database */
-  sqlite3 *dbm;                   /* In-memory db for this analysis */
-  sqlite3 *dbv;                   /* Vtab schema for this analysis */
-  IdxTable *pTable;               /* List of all IdxTable objects */
-  IdxScan *pScan;                 /* List of scan objects */
-  IdxWrite *pWrite;               /* List of write objects */
-  IdxStatement *pStatement;       /* List of IdxStatement objects */
-  int bRun;                       /* True once analysis has run */
-  char **pzErrmsg;
-  int rc;                         /* Error code from whereinfo hook */
-  IdxHash hIdx;                   /* Hash containing all candidate indexes */
-  char *zCandidates;              /* For EXPERT_REPORT_CANDIDATES */
-};
-
-
-/*
-** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc(). 
-** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
-*/
-static void *idxMalloc(int *pRc, int nByte){
-  void *pRet;
-  assert( *pRc==SQLITE_OK );
-  assert( nByte>0 );
-  pRet = sqlite3_malloc(nByte);
-  if( pRet ){
-    memset(pRet, 0, nByte);
-  }else{
-    *pRc = SQLITE_NOMEM;
-  }
-  return pRet;
-}
-
-/*
-** Initialize an IdxHash hash table.
-*/
-static void idxHashInit(IdxHash *pHash){
-  memset(pHash, 0, sizeof(IdxHash));
-}
-
-/*
-** Reset an IdxHash hash table.
-*/
-static void idxHashClear(IdxHash *pHash){
-  int i;
-  for(i=0; i<IDX_HASH_SIZE; i++){
-    IdxHashEntry *pEntry;
-    IdxHashEntry *pNext;
-    for(pEntry=pHash->aHash[i]; pEntry; pEntry=pNext){
-      pNext = pEntry->pHashNext;
-      sqlite3_free(pEntry->zVal2);
-      sqlite3_free(pEntry);
-    }
-  }
-  memset(pHash, 0, sizeof(IdxHash));
-}
-
-/*
-** Return the index of the hash bucket that the string specified by the
-** arguments to this function belongs.
-*/
-static int idxHashString(const char *z, int n){
-  unsigned int ret = 0;
-  int i;
-  for(i=0; i<n; i++){
-    ret += (ret<<3) + (unsigned char)(z[i]);
-  }
-  return (int)(ret % IDX_HASH_SIZE);
-}
-
-/*
-** If zKey is already present in the hash table, return non-zero and do
-** nothing. Otherwise, add an entry with key zKey and payload string zVal to
-** the hash table passed as the second argument. 
-*/
-static int idxHashAdd(
-  int *pRc, 
-  IdxHash *pHash, 
-  const char *zKey,
-  const char *zVal
-){
-  int nKey = STRLEN(zKey);
-  int iHash = idxHashString(zKey, nKey);
-  int nVal = (zVal ? STRLEN(zVal) : 0);
-  IdxHashEntry *pEntry;
-  assert( iHash>=0 );
-  for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
-    if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
-      return 1;
-    }
-  }
-  pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
-  if( pEntry ){
-    pEntry->zKey = (char*)&pEntry[1];
-    memcpy(pEntry->zKey, zKey, nKey);
-    if( zVal ){
-      pEntry->zVal = &pEntry->zKey[nKey+1];
-      memcpy(pEntry->zVal, zVal, nVal);
-    }
-    pEntry->pHashNext = pHash->aHash[iHash];
-    pHash->aHash[iHash] = pEntry;
-
-    pEntry->pNext = pHash->pFirst;
-    pHash->pFirst = pEntry;
-  }
-  return 0;
-}
-
-/*
-** If zKey/nKey is present in the hash table, return a pointer to the 
-** hash-entry object.
-*/
-static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){
-  int iHash;
-  IdxHashEntry *pEntry;
-  if( nKey<0 ) nKey = STRLEN(zKey);
-  iHash = idxHashString(zKey, nKey);
-  assert( iHash>=0 );
-  for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
-    if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
-      return pEntry;
-    }
-  }
-  return 0;
-}
-
-/*
-** If the hash table contains an entry with a key equal to the string
-** passed as the final two arguments to this function, return a pointer
-** to the payload string. Otherwise, if zKey/nKey is not present in the
-** hash table, return NULL.
-*/
-static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){
-  IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey);
-  if( pEntry ) return pEntry->zVal;
-  return 0;
-}
-
-/*
-** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl
-** variable to point to a copy of nul-terminated string zColl.
-*/
-static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){
-  IdxConstraint *pNew;
-  int nColl = STRLEN(zColl);
-
-  assert( *pRc==SQLITE_OK );
-  pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1);
-  if( pNew ){
-    pNew->zColl = (char*)&pNew[1];
-    memcpy(pNew->zColl, zColl, nColl+1);
-  }
-  return pNew;
-}
-
-/*
-** An error associated with database handle db has just occurred. Pass
-** the error message to callback function xOut.
-*/
-static void idxDatabaseError(
-  sqlite3 *db,                    /* Database handle */
-  char **pzErrmsg                 /* Write error here */
-){
-  *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
-}
-
-/*
-** Prepare an SQL statement.
-*/
-static int idxPrepareStmt(
-  sqlite3 *db,                    /* Database handle to compile against */
-  sqlite3_stmt **ppStmt,          /* OUT: Compiled SQL statement */
-  char **pzErrmsg,                /* OUT: sqlite3_malloc()ed error message */
-  const char *zSql                /* SQL statement to compile */
-){
-  int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
-  if( rc!=SQLITE_OK ){
-    *ppStmt = 0;
-    idxDatabaseError(db, pzErrmsg);
-  }
-  return rc;
-}
-
-/*
-** Prepare an SQL statement using the results of a printf() formatting.
-*/
-static int idxPrintfPrepareStmt(
-  sqlite3 *db,                    /* Database handle to compile against */
-  sqlite3_stmt **ppStmt,          /* OUT: Compiled SQL statement */
-  char **pzErrmsg,                /* OUT: sqlite3_malloc()ed error message */
-  const char *zFmt,               /* printf() format of SQL statement */
-  ...                             /* Trailing printf() arguments */
-){
-  va_list ap;
-  int rc;
-  char *zSql;
-  va_start(ap, zFmt);
-  zSql = sqlite3_vmprintf(zFmt, ap);
-  if( zSql==0 ){
-    rc = SQLITE_NOMEM;
-  }else{
-    rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql);
-    sqlite3_free(zSql);
-  }
-  va_end(ap);
-  return rc;
-}
-
-
-/*************************************************************************
-** Beginning of virtual table implementation.
-*/
-typedef struct ExpertVtab ExpertVtab;
-struct ExpertVtab {
-  sqlite3_vtab base;
-  IdxTable *pTab;
-  sqlite3expert *pExpert;
-};
-
-typedef struct ExpertCsr ExpertCsr;
-struct ExpertCsr {
-  sqlite3_vtab_cursor base;
-  sqlite3_stmt *pData;
-};
-
-static char *expertDequote(const char *zIn){
-  int n = STRLEN(zIn);
-  char *zRet = sqlite3_malloc(n);
-
-  assert( zIn[0]=='\'' );
-  assert( zIn[n-1]=='\'' );
-
-  if( zRet ){
-    int iOut = 0;
-    int iIn = 0;
-    for(iIn=1; iIn<(n-1); iIn++){
-      if( zIn[iIn]=='\'' ){
-        assert( zIn[iIn+1]=='\'' );
-        iIn++;
-      }
-      zRet[iOut++] = zIn[iIn];
-    }
-    zRet[iOut] = '\0';
-  }
-
-  return zRet;
-}
-
-/* 
-** This function is the implementation of both the xConnect and xCreate
-** methods of the r-tree virtual table.
-**
-**   argv[0]   -> module name
-**   argv[1]   -> database name
-**   argv[2]   -> table name
-**   argv[...] -> column names...
-*/
-static int expertConnect(
-  sqlite3 *db,
-  void *pAux,
-  int argc, const char *const*argv,
-  sqlite3_vtab **ppVtab,
-  char **pzErr
-){
-  sqlite3expert *pExpert = (sqlite3expert*)pAux;
-  ExpertVtab *p = 0;
-  int rc;
-
-  if( argc!=4 ){
-    *pzErr = sqlite3_mprintf("internal error!");
-    rc = SQLITE_ERROR;
-  }else{
-    char *zCreateTable = expertDequote(argv[3]);
-    if( zCreateTable ){
-      rc = sqlite3_declare_vtab(db, zCreateTable);
-      if( rc==SQLITE_OK ){
-        p = idxMalloc(&rc, sizeof(ExpertVtab));
-      }
-      if( rc==SQLITE_OK ){
-        p->pExpert = pExpert;
-        p->pTab = pExpert->pTable;
-        assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 );
-      }
-      sqlite3_free(zCreateTable);
-    }else{
-      rc = SQLITE_NOMEM;
-    }
-  }
-
-  *ppVtab = (sqlite3_vtab*)p;
-  return rc;
-}
-
-static int expertDisconnect(sqlite3_vtab *pVtab){
-  ExpertVtab *p = (ExpertVtab*)pVtab;
-  sqlite3_free(p);
-  return SQLITE_OK;
-}
-
-static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){
-  ExpertVtab *p = (ExpertVtab*)pVtab;
-  int rc = SQLITE_OK;
-  int n = 0;
-  IdxScan *pScan;
-  const int opmask = 
-    SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT |
-    SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE |
-    SQLITE_INDEX_CONSTRAINT_LE;
-
-  pScan = idxMalloc(&rc, sizeof(IdxScan));
-  if( pScan ){
-    int i;
-
-    /* Link the new scan object into the list */
-    pScan->pTab = p->pTab;
-    pScan->pNextScan = p->pExpert->pScan;
-    p->pExpert->pScan = pScan;
-
-    /* Add the constraints to the IdxScan object */
-    for(i=0; i<pIdxInfo->nConstraint; i++){
-      struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
-      if( pCons->usable 
-       && pCons->iColumn>=0 
-       && p->pTab->aCol[pCons->iColumn].iPk==0
-       && (pCons->op & opmask) 
-      ){
-        IdxConstraint *pNew;
-        const char *zColl = sqlite3_vtab_collation(pIdxInfo, i);
-        pNew = idxNewConstraint(&rc, zColl);
-        if( pNew ){
-          pNew->iCol = pCons->iColumn;
-          if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
-            pNew->pNext = pScan->pEq;
-            pScan->pEq = pNew;
-          }else{
-            pNew->bRange = 1;
-            pNew->pNext = pScan->pRange;
-            pScan->pRange = pNew;
-          }
-        }
-        n++;
-        pIdxInfo->aConstraintUsage[i].argvIndex = n;
-      }
-    }
-
-    /* Add the ORDER BY to the IdxScan object */
-    for(i=pIdxInfo->nOrderBy-1; i>=0; i--){
-      int iCol = pIdxInfo->aOrderBy[i].iColumn;
-      if( iCol>=0 ){
-        IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl);
-        if( pNew ){
-          pNew->iCol = iCol;
-          pNew->bDesc = pIdxInfo->aOrderBy[i].desc;
-          pNew->pNext = pScan->pOrder;
-          pNew->pLink = pScan->pOrder;
-          pScan->pOrder = pNew;
-          n++;
-        }
-      }
-    }
-  }
-
-  pIdxInfo->estimatedCost = 1000000.0 / (n+1);
-  return rc;
-}
-
-static int expertUpdate(
-  sqlite3_vtab *pVtab, 
-  int nData, 
-  sqlite3_value **azData, 
-  sqlite_int64 *pRowid
-){
-  (void)pVtab;
-  (void)nData;
-  (void)azData;
-  (void)pRowid;
-  return SQLITE_OK;
-}
-
-/* 
-** Virtual table module xOpen method.
-*/
-static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
-  int rc = SQLITE_OK;
-  ExpertCsr *pCsr;
-  (void)pVTab;
-  pCsr = idxMalloc(&rc, sizeof(ExpertCsr));
-  *ppCursor = (sqlite3_vtab_cursor*)pCsr;
-  return rc;
-}
-
-/* 
-** Virtual table module xClose method.
-*/
-static int expertClose(sqlite3_vtab_cursor *cur){
-  ExpertCsr *pCsr = (ExpertCsr*)cur;
-  sqlite3_finalize(pCsr->pData);
-  sqlite3_free(pCsr);
-  return SQLITE_OK;
-}
-
-/*
-** Virtual table module xEof method.
-**
-** Return non-zero if the cursor does not currently point to a valid 
-** record (i.e if the scan has finished), or zero otherwise.
-*/
-static int expertEof(sqlite3_vtab_cursor *cur){
-  ExpertCsr *pCsr = (ExpertCsr*)cur;
-  return pCsr->pData==0;
-}
-
-/* 
-** Virtual table module xNext method.
-*/
-static int expertNext(sqlite3_vtab_cursor *cur){
-  ExpertCsr *pCsr = (ExpertCsr*)cur;
-  int rc = SQLITE_OK;
-
-  assert( pCsr->pData );
-  rc = sqlite3_step(pCsr->pData);
-  if( rc!=SQLITE_ROW ){
-    rc = sqlite3_finalize(pCsr->pData);
-    pCsr->pData = 0;
-  }else{
-    rc = SQLITE_OK;
-  }
-
-  return rc;
-}
-
-/* 
-** Virtual table module xRowid method.
-*/
-static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
-  (void)cur;
-  *pRowid = 0;
-  return SQLITE_OK;
-}
-
-/* 
-** Virtual table module xColumn method.
-*/
-static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
-  ExpertCsr *pCsr = (ExpertCsr*)cur;
-  sqlite3_value *pVal;
-  pVal = sqlite3_column_value(pCsr->pData, i);
-  if( pVal ){
-    sqlite3_result_value(ctx, pVal);
-  }
-  return SQLITE_OK;
-}
-
-/* 
-** Virtual table module xFilter method.
-*/
-static int expertFilter(
-  sqlite3_vtab_cursor *cur, 
-  int idxNum, const char *idxStr,
-  int argc, sqlite3_value **argv
-){
-  ExpertCsr *pCsr = (ExpertCsr*)cur;
-  ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab);
-  sqlite3expert *pExpert = pVtab->pExpert;
-  int rc;
-
-  (void)idxNum;
-  (void)idxStr;
-  (void)argc;
-  (void)argv;
-  rc = sqlite3_finalize(pCsr->pData);
-  pCsr->pData = 0;
-  if( rc==SQLITE_OK ){
-    rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg,
-        "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName
-    );
-  }
-
-  if( rc==SQLITE_OK ){
-    rc = expertNext(cur);
-  }
-  return rc;
-}
-
-static int idxRegisterVtab(sqlite3expert *p){
-  static sqlite3_module expertModule = {
-    2,                            /* iVersion */
-    expertConnect,                /* xCreate - create a table */
-    expertConnect,                /* xConnect - connect to an existing table */
-    expertBestIndex,              /* xBestIndex - Determine search strategy */
-    expertDisconnect,             /* xDisconnect - Disconnect from a table */
-    expertDisconnect,             /* xDestroy - Drop a table */
-    expertOpen,                   /* xOpen - open a cursor */
-    expertClose,                  /* xClose - close a cursor */
-    expertFilter,                 /* xFilter - configure scan constraints */
-    expertNext,                   /* xNext - advance a cursor */
-    expertEof,                    /* xEof */
-    expertColumn,                 /* xColumn - read data */
-    expertRowid,                  /* xRowid - read data */
-    expertUpdate,                 /* xUpdate - write data */
-    0,                            /* xBegin - begin transaction */
-    0,                            /* xSync - sync transaction */
-    0,                            /* xCommit - commit transaction */
-    0,                            /* xRollback - rollback transaction */
-    0,                            /* xFindFunction - function overloading */
-    0,                            /* xRename - rename the table */
-    0,                            /* xSavepoint */
-    0,                            /* xRelease */
-    0,                            /* xRollbackTo */
-    0,                            /* xShadowName */
-  };
-
-  return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
-}
-/*
-** End of virtual table implementation.
-*************************************************************************/
-/*
-** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function
-** is called, set it to the return value of sqlite3_finalize() before
-** returning. Otherwise, discard the sqlite3_finalize() return value.
-*/
-static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){
-  int rc = sqlite3_finalize(pStmt);
-  if( *pRc==SQLITE_OK ) *pRc = rc;
-}
-
-/*
-** Attempt to allocate an IdxTable structure corresponding to table zTab
-** in the main database of connection db. If successful, set (*ppOut) to
-** point to the new object and return SQLITE_OK. Otherwise, return an
-** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be
-** set to point to an error string.
-**
-** It is the responsibility of the caller to eventually free either the
-** IdxTable object or error message using sqlite3_free().
-*/
-static int idxGetTableInfo(
-  sqlite3 *db,                    /* Database connection to read details from */
-  const char *zTab,               /* Table name */
-  IdxTable **ppOut,               /* OUT: New object (if successful) */
-  char **pzErrmsg                 /* OUT: Error message (if not) */
-){
-  sqlite3_stmt *p1 = 0;
-  int nCol = 0;
-  int nTab;
-  int nByte;
-  IdxTable *pNew = 0;
-  int rc, rc2;
-  char *pCsr = 0;
-  int nPk = 0;
-
-  *ppOut = 0;
-  if( zTab==0 ) return SQLITE_ERROR;
-  nTab = STRLEN(zTab);
-  nByte = sizeof(IdxTable) + nTab + 1;
-  rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab);
-  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
-    const char *zCol = (const char*)sqlite3_column_text(p1, 1);
-    const char *zColSeq = 0;
-    if( zCol==0 ){
-      rc = SQLITE_ERROR;
-      break;
-    }
-    nByte += 1 + STRLEN(zCol);
-    rc = sqlite3_table_column_metadata(
-        db, "main", zTab, zCol, 0, &zColSeq, 0, 0, 0
-    );
-    if( zColSeq==0 ) zColSeq = "binary";
-    nByte += 1 + STRLEN(zColSeq);
-    nCol++;
-    nPk += (sqlite3_column_int(p1, 5)>0);
-  }
-  rc2 = sqlite3_reset(p1);
-  if( rc==SQLITE_OK ) rc = rc2;
-
-  nByte += sizeof(IdxColumn) * nCol;
-  if( rc==SQLITE_OK ){
-    pNew = idxMalloc(&rc, nByte);
-  }
-  if( rc==SQLITE_OK ){
-    pNew->aCol = (IdxColumn*)&pNew[1];
-    pNew->nCol = nCol;
-    pCsr = (char*)&pNew->aCol[nCol];
-  }
-
-  nCol = 0;
-  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
-    const char *zCol = (const char*)sqlite3_column_text(p1, 1);
-    const char *zColSeq = 0;
-    int nCopy;
-    if( zCol==0 ) continue;
-    nCopy = STRLEN(zCol) + 1;
-    pNew->aCol[nCol].zName = pCsr;
-    pNew->aCol[nCol].iPk = (sqlite3_column_int(p1, 5)==1 && nPk==1);
-    memcpy(pCsr, zCol, nCopy);
-    pCsr += nCopy;
-
-    rc = sqlite3_table_column_metadata(
-        db, "main", zTab, zCol, 0, &zColSeq, 0, 0, 0
-    );
-    if( rc==SQLITE_OK ){
-      if( zColSeq==0 ) zColSeq = "binary";
-      nCopy = STRLEN(zColSeq) + 1;
-      pNew->aCol[nCol].zColl = pCsr;
-      memcpy(pCsr, zColSeq, nCopy);
-      pCsr += nCopy;
-    }
-
-    nCol++;
-  }
-  idxFinalize(&rc, p1);
-
-  if( rc!=SQLITE_OK ){
-    sqlite3_free(pNew);
-    pNew = 0;
-  }else if( ALWAYS(pNew!=0) ){
-    pNew->zName = pCsr;
-    if( ALWAYS(pNew->zName!=0) ) memcpy(pNew->zName, zTab, nTab+1);
-  }
-
-  *ppOut = pNew;
-  return rc;
-}
-
-/*
-** This function is a no-op if *pRc is set to anything other than 
-** SQLITE_OK when it is called.
-**
-** If *pRc is initially set to SQLITE_OK, then the text specified by
-** the printf() style arguments is appended to zIn and the result returned
-** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on
-** zIn before returning.
-*/
-static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
-  va_list ap;
-  char *zAppend = 0;
-  char *zRet = 0;
-  int nIn = zIn ? STRLEN(zIn) : 0;
-  int nAppend = 0;
-  va_start(ap, zFmt);
-  if( *pRc==SQLITE_OK ){
-    zAppend = sqlite3_vmprintf(zFmt, ap);
-    if( zAppend ){
-      nAppend = STRLEN(zAppend);
-      zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
-    }
-    if( zAppend && zRet ){
-      if( nIn ) memcpy(zRet, zIn, nIn);
-      memcpy(&zRet[nIn], zAppend, nAppend+1);
-    }else{
-      sqlite3_free(zRet);
-      zRet = 0;
-      *pRc = SQLITE_NOMEM;
-    }
-    sqlite3_free(zAppend);
-    sqlite3_free(zIn);
-  }
-  va_end(ap);
-  return zRet;
-}
-
-/*
-** Return true if zId must be quoted in order to use it as an SQL
-** identifier, or false otherwise.
-*/
-static int idxIdentifierRequiresQuotes(const char *zId){
-  int i;
-  int nId = STRLEN(zId);
-  
-  if( sqlite3_keyword_check(zId, nId) ) return 1;
-
-  for(i=0; zId[i]; i++){
-    if( !(zId[i]=='_')
-     && !(zId[i]>='0' && zId[i]<='9')
-     && !(zId[i]>='a' && zId[i]<='z')
-     && !(zId[i]>='A' && zId[i]<='Z')
-    ){
-      return 1;
-    }
-  }
-  return 0;
-}
-
-/*
-** This function appends an index column definition suitable for constraint
-** pCons to the string passed as zIn and returns the result.
-*/
-static char *idxAppendColDefn(
-  int *pRc,                       /* IN/OUT: Error code */
-  char *zIn,                      /* Column defn accumulated so far */
-  IdxTable *pTab,                 /* Table index will be created on */
-  IdxConstraint *pCons
-){
-  char *zRet = zIn;
-  IdxColumn *p = &pTab->aCol[pCons->iCol];
-  if( zRet ) zRet = idxAppendText(pRc, zRet, ", ");
-
-  if( idxIdentifierRequiresQuotes(p->zName) ){
-    zRet = idxAppendText(pRc, zRet, "%Q", p->zName);
-  }else{
-    zRet = idxAppendText(pRc, zRet, "%s", p->zName);
-  }
-
-  if( sqlite3_stricmp(p->zColl, pCons->zColl) ){
-    if( idxIdentifierRequiresQuotes(pCons->zColl) ){
-      zRet = idxAppendText(pRc, zRet, " COLLATE %Q", pCons->zColl);
-    }else{
-      zRet = idxAppendText(pRc, zRet, " COLLATE %s", pCons->zColl);
-    }
-  }
-
-  if( pCons->bDesc ){
-    zRet = idxAppendText(pRc, zRet, " DESC");
-  }
-  return zRet;
-}
-
-/*
-** Search database dbm for an index compatible with the one idxCreateFromCons()
-** would create from arguments pScan, pEq and pTail. If no error occurs and 
-** such an index is found, return non-zero. Or, if no such index is found,
-** return zero.
-**
-** If an error occurs, set *pRc to an SQLite error code and return zero.
-*/
-static int idxFindCompatible(
-  int *pRc,                       /* OUT: Error code */
-  sqlite3* dbm,                   /* Database to search */
-  IdxScan *pScan,                 /* Scan for table to search for index on */
-  IdxConstraint *pEq,             /* List of == constraints */
-  IdxConstraint *pTail            /* List of range constraints */
-){
-  const char *zTbl = pScan->pTab->zName;
-  sqlite3_stmt *pIdxList = 0;
-  IdxConstraint *pIter;
-  int nEq = 0;                    /* Number of elements in pEq */
-  int rc;
-
-  /* Count the elements in list pEq */
-  for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++;
-
-  rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl);
-  while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){
-    int bMatch = 1;
-    IdxConstraint *pT = pTail;
-    sqlite3_stmt *pInfo = 0;
-    const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1);
-    if( zIdx==0 ) continue;
-
-    /* Zero the IdxConstraint.bFlag values in the pEq list */
-    for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0;
-
-    rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx);
-    while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){
-      int iIdx = sqlite3_column_int(pInfo, 0);
-      int iCol = sqlite3_column_int(pInfo, 1);
-      const char *zColl = (const char*)sqlite3_column_text(pInfo, 4);
-
-      if( iIdx<nEq ){
-        for(pIter=pEq; pIter; pIter=pIter->pLink){
-          if( pIter->bFlag ) continue;
-          if( pIter->iCol!=iCol ) continue;
-          if( sqlite3_stricmp(pIter->zColl, zColl) ) continue;
-          pIter->bFlag = 1;
-          break;
-        }
-        if( pIter==0 ){
-          bMatch = 0;
-          break;
-        }
-      }else{
-        if( pT ){
-          if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){
-            bMatch = 0;
-            break;
-          }
-          pT = pT->pLink;
-        }
-      }
-    }
-    idxFinalize(&rc, pInfo);
-
-    if( rc==SQLITE_OK && bMatch ){
-      sqlite3_finalize(pIdxList);
-      return 1;
-    }
-  }
-  idxFinalize(&rc, pIdxList);
-
-  *pRc = rc;
-  return 0;
-}
-
-/* Callback for sqlite3_exec() with query with leading count(*) column.
- * The first argument is expected to be an int*, referent to be incremented
- * if that leading column is not exactly '0'.
- */
-static int countNonzeros(void* pCount, int nc,
-                         char* azResults[], char* azColumns[]){
-  (void)azColumns;  /* Suppress unused parameter warning */
-  if( nc>0 && (azResults[0][0]!='0' || azResults[0][1]!=0) ){
-    *((int *)pCount) += 1;
-  }
-  return 0;
-}
-
-static int idxCreateFromCons(
-  sqlite3expert *p,
-  IdxScan *pScan,
-  IdxConstraint *pEq, 
-  IdxConstraint *pTail
-){
-  sqlite3 *dbm = p->dbm;
-  int rc = SQLITE_OK;
-  if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){
-    IdxTable *pTab = pScan->pTab;
-    char *zCols = 0;
-    char *zIdx = 0;
-    IdxConstraint *pCons;
-    unsigned int h = 0;
-    const char *zFmt;
-
-    for(pCons=pEq; pCons; pCons=pCons->pLink){
-      zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
-    }
-    for(pCons=pTail; pCons; pCons=pCons->pLink){
-      zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
-    }
-
-    if( rc==SQLITE_OK ){
-      /* Hash the list of columns to come up with a name for the index */
-      const char *zTable = pScan->pTab->zName;
-      int quoteTable = idxIdentifierRequiresQuotes(zTable);
-      char *zName = 0;          /* Index name */
-      int collisions = 0;
-      do{
-        int i;
-        char *zFind;
-        for(i=0; zCols[i]; i++){
-          h += ((h<<3) + zCols[i]);
-        }
-        sqlite3_free(zName);
-        zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
-        if( zName==0 ) break;
-        /* Is is unique among table, view and index names? */
-        zFmt = "SELECT count(*) FROM sqlite_schema WHERE name=%Q"
-          " AND type in ('index','table','view')";
-        zFind = sqlite3_mprintf(zFmt, zName);
-        i = 0;
-        rc = sqlite3_exec(dbm, zFind, countNonzeros, &i, 0);
-        assert(rc==SQLITE_OK);
-        sqlite3_free(zFind);
-        if( i==0 ){
-          collisions = 0;
-          break;
-        }
-        ++collisions;
-      }while( collisions<50 && zName!=0 );
-      if( collisions ){
-        /* This return means "Gave up trying to find a unique index name." */
-        rc = SQLITE_BUSY_TIMEOUT;
-      }else if( zName==0 ){
-        rc = SQLITE_NOMEM;
-      }else{
-        if( quoteTable ){
-          zFmt = "CREATE INDEX \"%w\" ON \"%w\"(%s)";
-        }else{
-          zFmt = "CREATE INDEX %s ON %s(%s)";
-        }
-        zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols);
-        if( !zIdx ){
-          rc = SQLITE_NOMEM;
-        }else{
-          rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg);
-          if( rc!=SQLITE_OK ){
-            rc = SQLITE_BUSY_TIMEOUT;
-          }else{
-            idxHashAdd(&rc, &p->hIdx, zName, zIdx);
-          }
-        }
-        sqlite3_free(zName);
-        sqlite3_free(zIdx);
-      }
-    }
-
-    sqlite3_free(zCols);
-  }
-  return rc;
-}
-
-/*
-** Return true if list pList (linked by IdxConstraint.pLink) contains
-** a constraint compatible with *p. Otherwise return false.
-*/
-static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){
-  IdxConstraint *pCmp;
-  for(pCmp=pList; pCmp; pCmp=pCmp->pLink){
-    if( p->iCol==pCmp->iCol ) return 1;
-  }
-  return 0;
-}
-
-static int idxCreateFromWhere(
-  sqlite3expert *p, 
-  IdxScan *pScan,                 /* Create indexes for this scan */
-  IdxConstraint *pTail            /* range/ORDER BY constraints for inclusion */
-){
-  IdxConstraint *p1 = 0;
-  IdxConstraint *pCon;
-  int rc;
-
-  /* Gather up all the == constraints. */
-  for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){
-    if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
-      pCon->pLink = p1;
-      p1 = pCon;
-    }
-  }
-
-  /* Create an index using the == constraints collected above. And the
-  ** range constraint/ORDER BY terms passed in by the caller, if any. */
-  rc = idxCreateFromCons(p, pScan, p1, pTail);
-
-  /* If no range/ORDER BY passed by the caller, create a version of the
-  ** index for each range constraint.  */
-  if( pTail==0 ){
-    for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){
-      assert( pCon->pLink==0 );
-      if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
-        rc = idxCreateFromCons(p, pScan, p1, pCon);
-      }
-    }
-  }
-
-  return rc;
-}
-
-/*
-** Create candidate indexes in database [dbm] based on the data in 
-** linked-list pScan.
-*/
-static int idxCreateCandidates(sqlite3expert *p){
-  int rc = SQLITE_OK;
-  IdxScan *pIter;
-
-  for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){
-    rc = idxCreateFromWhere(p, pIter, 0);
-    if( rc==SQLITE_OK && pIter->pOrder ){
-      rc = idxCreateFromWhere(p, pIter, pIter->pOrder);
-    }
-  }
-
-  return rc;
-}
-
-/*
-** Free all elements of the linked list starting at pConstraint.
-*/
-static void idxConstraintFree(IdxConstraint *pConstraint){
-  IdxConstraint *pNext;
-  IdxConstraint *p;
-
-  for(p=pConstraint; p; p=pNext){
-    pNext = p->pNext;
-    sqlite3_free(p);
-  }
-}
-
-/*
-** Free all elements of the linked list starting from pScan up until pLast
-** (pLast is not freed).
-*/
-static void idxScanFree(IdxScan *pScan, IdxScan *pLast){
-  IdxScan *p;
-  IdxScan *pNext;
-  for(p=pScan; p!=pLast; p=pNext){
-    pNext = p->pNextScan;
-    idxConstraintFree(p->pOrder);
-    idxConstraintFree(p->pEq);
-    idxConstraintFree(p->pRange);
-    sqlite3_free(p);
-  }
-}
-
-/*
-** Free all elements of the linked list starting from pStatement up 
-** until pLast (pLast is not freed).
-*/
-static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){
-  IdxStatement *p;
-  IdxStatement *pNext;
-  for(p=pStatement; p!=pLast; p=pNext){
-    pNext = p->pNext;
-    sqlite3_free(p->zEQP);
-    sqlite3_free(p->zIdx);
-    sqlite3_free(p);
-  }
-}
-
-/*
-** Free the linked list of IdxTable objects starting at pTab.
-*/
-static void idxTableFree(IdxTable *pTab){
-  IdxTable *pIter;
-  IdxTable *pNext;
-  for(pIter=pTab; pIter; pIter=pNext){
-    pNext = pIter->pNext;
-    sqlite3_free(pIter);
-  }
-}
-
-/*
-** Free the linked list of IdxWrite objects starting at pTab.
-*/
-static void idxWriteFree(IdxWrite *pTab){
-  IdxWrite *pIter;
-  IdxWrite *pNext;
-  for(pIter=pTab; pIter; pIter=pNext){
-    pNext = pIter->pNext;
-    sqlite3_free(pIter);
-  }
-}
-
-
-
-/*
-** This function is called after candidate indexes have been created. It
-** runs all the queries to see which indexes they prefer, and populates
-** IdxStatement.zIdx and IdxStatement.zEQP with the results.
-*/
-static int idxFindIndexes(
-  sqlite3expert *p,
-  char **pzErr                         /* OUT: Error message (sqlite3_malloc) */
-){
-  IdxStatement *pStmt;
-  sqlite3 *dbm = p->dbm;
-  int rc = SQLITE_OK;
-
-  IdxHash hIdx;
-  idxHashInit(&hIdx);
-
-  for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){
-    IdxHashEntry *pEntry;
-    sqlite3_stmt *pExplain = 0;
-    idxHashClear(&hIdx);
-    rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr,
-        "EXPLAIN QUERY PLAN %s", pStmt->zSql
-    );
-    while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
-      /* int iId = sqlite3_column_int(pExplain, 0); */
-      /* int iParent = sqlite3_column_int(pExplain, 1); */
-      /* int iNotUsed = sqlite3_column_int(pExplain, 2); */
-      const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
-      int nDetail;
-      int i;
-
-      if( !zDetail ) continue;
-      nDetail = STRLEN(zDetail);
-
-      for(i=0; i<nDetail; i++){
-        const char *zIdx = 0;
-        if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
-          zIdx = &zDetail[i+13];
-        }else if( i+22<nDetail 
-            && memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 
-        ){
-          zIdx = &zDetail[i+22];
-        }
-        if( zIdx ){
-          const char *zSql;
-          int nIdx = 0;
-          while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){
-            nIdx++;
-          }
-          zSql = idxHashSearch(&p->hIdx, zIdx, nIdx);
-          if( zSql ){
-            idxHashAdd(&rc, &hIdx, zSql, 0);
-            if( rc ) goto find_indexes_out;
-          }
-          break;
-        }
-      }
-
-      if( zDetail[0]!='-' ){
-        pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail);
-      }
-    }
-
-    for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
-      pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey);
-    }
-
-    idxFinalize(&rc, pExplain);
-  }
-
- find_indexes_out:
-  idxHashClear(&hIdx);
-  return rc;
-}
-
-static int idxAuthCallback(
-  void *pCtx,
-  int eOp,
-  const char *z3,
-  const char *z4,
-  const char *zDb,
-  const char *zTrigger
-){
-  int rc = SQLITE_OK;
-  (void)z4;
-  (void)zTrigger;
-  if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){
-    if( sqlite3_stricmp(zDb, "main")==0 ){
-      sqlite3expert *p = (sqlite3expert*)pCtx;
-      IdxTable *pTab;
-      for(pTab=p->pTable; pTab; pTab=pTab->pNext){
-        if( 0==sqlite3_stricmp(z3, pTab->zName) ) break;
-      }
-      if( pTab ){
-        IdxWrite *pWrite;
-        for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){
-          if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break;
-        }
-        if( pWrite==0 ){
-          pWrite = idxMalloc(&rc, sizeof(IdxWrite));
-          if( rc==SQLITE_OK ){
-            pWrite->pTab = pTab;
-            pWrite->eOp = eOp;
-            pWrite->pNext = p->pWrite;
-            p->pWrite = pWrite;
-          }
-        }
-      }
-    }
-  }
-  return rc;
-}
-
-static int idxProcessOneTrigger(
-  sqlite3expert *p, 
-  IdxWrite *pWrite, 
-  char **pzErr
-){
-  static const char *zInt = UNIQUE_TABLE_NAME;
-  static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME;
-  IdxTable *pTab = pWrite->pTab;
-  const char *zTab = pTab->zName;
-  const char *zSql = 
-    "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_schema "
-    "WHERE tbl_name = %Q AND type IN ('table', 'trigger') "
-    "ORDER BY type;";
-  sqlite3_stmt *pSelect = 0;
-  int rc = SQLITE_OK;
-  char *zWrite = 0;
-
-  /* Create the table and its triggers in the temp schema */
-  rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab);
-  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){
-    const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0);
-    if( zCreate==0 ) continue;
-    rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr);
-  }
-  idxFinalize(&rc, pSelect);
-
-  /* Rename the table in the temp schema to zInt */
-  if( rc==SQLITE_OK ){
-    char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q", zTab, zInt);
-    if( z==0 ){
-      rc = SQLITE_NOMEM;
-    }else{
-      rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr);
-      sqlite3_free(z);
-    }
-  }
-
-  switch( pWrite->eOp ){
-    case SQLITE_INSERT: {
-      int i;
-      zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(", zInt);
-      for(i=0; i<pTab->nCol; i++){
-        zWrite = idxAppendText(&rc, zWrite, "%s?", i==0 ? "" : ", ");
-      }
-      zWrite = idxAppendText(&rc, zWrite, ")");
-      break;
-    }
-    case SQLITE_UPDATE: {
-      int i;
-      zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET ", zInt);
-      for(i=0; i<pTab->nCol; i++){
-        zWrite = idxAppendText(&rc, zWrite, "%s%Q=?", i==0 ? "" : ", ", 
-            pTab->aCol[i].zName
-        );
-      }
-      break;
-    }
-    default: {
-      assert( pWrite->eOp==SQLITE_DELETE );
-      if( rc==SQLITE_OK ){
-        zWrite = sqlite3_mprintf("DELETE FROM %Q", zInt);
-        if( zWrite==0 ) rc = SQLITE_NOMEM;
-      }
-    }
-  }
-
-  if( rc==SQLITE_OK ){
-    sqlite3_stmt *pX = 0;
-    rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0);
-    idxFinalize(&rc, pX);
-    if( rc!=SQLITE_OK ){
-      idxDatabaseError(p->dbv, pzErr);
-    }
-  }
-  sqlite3_free(zWrite);
-
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr);
-  }
-
-  return rc;
-}
-
-static int idxProcessTriggers(sqlite3expert *p, char **pzErr){
-  int rc = SQLITE_OK;
-  IdxWrite *pEnd = 0;
-  IdxWrite *pFirst = p->pWrite;
-
-  while( rc==SQLITE_OK && pFirst!=pEnd ){
-    IdxWrite *pIter;
-    for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){
-      rc = idxProcessOneTrigger(p, pIter, pzErr);
-    }
-    pEnd = pFirst;
-    pFirst = p->pWrite;
-  }
-
-  return rc;
-}
-
-
-static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
-  int rc = idxRegisterVtab(p);
-  sqlite3_stmt *pSchema = 0;
-
-  /* For each table in the main db schema:
-  **
-  **   1) Add an entry to the p->pTable list, and
-  **   2) Create the equivalent virtual table in dbv.
-  */
-  rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg,
-      "SELECT type, name, sql, 1 FROM sqlite_schema "
-      "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' "
-      " UNION ALL "
-      "SELECT type, name, sql, 2 FROM sqlite_schema "
-      "WHERE type = 'trigger'"
-      "  AND tbl_name IN(SELECT name FROM sqlite_schema WHERE type = 'view') "
-      "ORDER BY 4, 1"
-  );
-  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){
-    const char *zType = (const char*)sqlite3_column_text(pSchema, 0);
-    const char *zName = (const char*)sqlite3_column_text(pSchema, 1);
-    const char *zSql = (const char*)sqlite3_column_text(pSchema, 2);
-
-    if( zType==0 || zName==0 ) continue;
-    if( zType[0]=='v' || zType[1]=='r' ){
-      if( zSql ) rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
-    }else{
-      IdxTable *pTab;
-      rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
-      if( rc==SQLITE_OK ){
-        int i;
-        char *zInner = 0;
-        char *zOuter = 0;
-        pTab->pNext = p->pTable;
-        p->pTable = pTab;
-
-        /* The statement the vtab will pass to sqlite3_declare_vtab() */
-        zInner = idxAppendText(&rc, 0, "CREATE TABLE x(");
-        for(i=0; i<pTab->nCol; i++){
-          zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s", 
-              (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl
-          );
-        }
-        zInner = idxAppendText(&rc, zInner, ")");
-
-        /* The CVT statement to create the vtab */
-        zOuter = idxAppendText(&rc, 0, 
-            "CREATE VIRTUAL TABLE %Q USING expert(%Q)", zName, zInner
-        );
-        if( rc==SQLITE_OK ){
-          rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg);
-        }
-        sqlite3_free(zInner);
-        sqlite3_free(zOuter);
-      }
-    }
-  }
-  idxFinalize(&rc, pSchema);
-  return rc;
-}
-
-struct IdxSampleCtx {
-  int iTarget;
-  double target;                  /* Target nRet/nRow value */
-  double nRow;                    /* Number of rows seen */
-  double nRet;                    /* Number of rows returned */
-};
-
-static void idxSampleFunc(
-  sqlite3_context *pCtx,
-  int argc,
-  sqlite3_value **argv
-){
-  struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx);
-  int bRet;
-
-  (void)argv;
-  assert( argc==0 );
-  if( p->nRow==0.0 ){
-    bRet = 1;
-  }else{
-    bRet = (p->nRet / p->nRow) <= p->target;
-    if( bRet==0 ){
-      unsigned short rnd;
-      sqlite3_randomness(2, (void*)&rnd);
-      bRet = ((int)rnd % 100) <= p->iTarget;
-    }
-  }
-
-  sqlite3_result_int(pCtx, bRet);
-  p->nRow += 1.0;
-  p->nRet += (double)bRet;
-}
-
-struct IdxRemCtx {
-  int nSlot;
-  struct IdxRemSlot {
-    int eType;                    /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
-    i64 iVal;                     /* SQLITE_INTEGER value */
-    double rVal;                  /* SQLITE_FLOAT value */
-    int nByte;                    /* Bytes of space allocated at z */
-    int n;                        /* Size of buffer z */
-    char *z;                      /* SQLITE_TEXT/BLOB value */
-  } aSlot[1];
-};
-
-/*
-** Implementation of scalar function rem().
-*/
-static void idxRemFunc(
-  sqlite3_context *pCtx,
-  int argc,
-  sqlite3_value **argv
-){
-  struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx);
-  struct IdxRemSlot *pSlot;
-  int iSlot;
-  assert( argc==2 );
-
-  iSlot = sqlite3_value_int(argv[0]);
-  assert( iSlot<=p->nSlot );
-  pSlot = &p->aSlot[iSlot];
-
-  switch( pSlot->eType ){
-    case SQLITE_NULL:
-      /* no-op */
-      break;
-
-    case SQLITE_INTEGER:
-      sqlite3_result_int64(pCtx, pSlot->iVal);
-      break;
-
-    case SQLITE_FLOAT:
-      sqlite3_result_double(pCtx, pSlot->rVal);
-      break;
-
-    case SQLITE_BLOB:
-      sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
-      break;
-
-    case SQLITE_TEXT:
-      sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
-      break;
-  }
-
-  pSlot->eType = sqlite3_value_type(argv[1]);
-  switch( pSlot->eType ){
-    case SQLITE_NULL:
-      /* no-op */
-      break;
-
-    case SQLITE_INTEGER:
-      pSlot->iVal = sqlite3_value_int64(argv[1]);
-      break;
-
-    case SQLITE_FLOAT:
-      pSlot->rVal = sqlite3_value_double(argv[1]);
-      break;
-
-    case SQLITE_BLOB:
-    case SQLITE_TEXT: {
-      int nByte = sqlite3_value_bytes(argv[1]);
-      const void *pData = 0;
-      if( nByte>pSlot->nByte ){
-        char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
-        if( zNew==0 ){
-          sqlite3_result_error_nomem(pCtx);
-          return;
-        }
-        pSlot->nByte = nByte*2;
-        pSlot->z = zNew;
-      }
-      pSlot->n = nByte;
-      if( pSlot->eType==SQLITE_BLOB ){
-        pData = sqlite3_value_blob(argv[1]);
-        if( pData ) memcpy(pSlot->z, pData, nByte);
-      }else{
-        pData = sqlite3_value_text(argv[1]);
-        memcpy(pSlot->z, pData, nByte);
-      }
-      break;
-    }
-  }
-}
-
-static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){
-  int rc = SQLITE_OK;
-  const char *zMax = 
-    "SELECT max(i.seqno) FROM "
-    "  sqlite_schema AS s, "
-    "  pragma_index_list(s.name) AS l, "
-    "  pragma_index_info(l.name) AS i "
-    "WHERE s.type = 'table'";
-  sqlite3_stmt *pMax = 0;
-
-  *pnMax = 0;
-  rc = idxPrepareStmt(db, &pMax, pzErr, zMax);
-  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
-    *pnMax = sqlite3_column_int(pMax, 0) + 1;
-  }
-  idxFinalize(&rc, pMax);
-
-  return rc;
-}
-
-static int idxPopulateOneStat1(
-  sqlite3expert *p,
-  sqlite3_stmt *pIndexXInfo,
-  sqlite3_stmt *pWriteStat,
-  const char *zTab,
-  const char *zIdx,
-  char **pzErr
-){
-  char *zCols = 0;
-  char *zOrder = 0;
-  char *zQuery = 0;
-  int nCol = 0;
-  int i;
-  sqlite3_stmt *pQuery = 0;
-  int *aStat = 0;
-  int rc = SQLITE_OK;
-
-  assert( p->iSample>0 );
-
-  /* Formulate the query text */
-  sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC);
-  while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){
-    const char *zComma = zCols==0 ? "" : ", ";
-    const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
-    const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
-    zCols = idxAppendText(&rc, zCols, 
-        "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl
-    );
-    zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
-  }
-  sqlite3_reset(pIndexXInfo);
-  if( rc==SQLITE_OK ){
-    if( p->iSample==100 ){
-      zQuery = sqlite3_mprintf(
-          "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder
-      );
-    }else{
-      zQuery = sqlite3_mprintf(
-          "SELECT %s FROM temp."UNIQUE_TABLE_NAME" x ORDER BY %s", zCols, zOrder
-      );
-    }
-  }
-  sqlite3_free(zCols);
-  sqlite3_free(zOrder);
-
-  /* Formulate the query text */
-  if( rc==SQLITE_OK ){
-    sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
-    rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery);
-  }
-  sqlite3_free(zQuery);
-
-  if( rc==SQLITE_OK ){
-    aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1));
-  }
-  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
-    IdxHashEntry *pEntry;
-    char *zStat = 0;
-    for(i=0; i<=nCol; i++) aStat[i] = 1;
-    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
-      aStat[0]++;
-      for(i=0; i<nCol; i++){
-        if( sqlite3_column_int(pQuery, i)==0 ) break;
-      }
-      for(/*no-op*/; i<nCol; i++){
-        aStat[i+1]++;
-      }
-    }
-
-    if( rc==SQLITE_OK ){
-      int s0 = aStat[0];
-      zStat = sqlite3_mprintf("%d", s0);
-      if( zStat==0 ) rc = SQLITE_NOMEM;
-      for(i=1; rc==SQLITE_OK && i<=nCol; i++){
-        zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]);
-      }
-    }
-
-    if( rc==SQLITE_OK ){
-      sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC);
-      sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC);
-      sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC);
-      sqlite3_step(pWriteStat);
-      rc = sqlite3_reset(pWriteStat);
-    }
-
-    pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx));
-    if( pEntry ){
-      assert( pEntry->zVal2==0 );
-      pEntry->zVal2 = zStat;
-    }else{
-      sqlite3_free(zStat);
-    }
-  }
-  sqlite3_free(aStat);
-  idxFinalize(&rc, pQuery);
-
-  return rc;
-}
-
-static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){
-  int rc;
-  char *zSql;
-
-  rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
-  if( rc!=SQLITE_OK ) return rc;
-
-  zSql = sqlite3_mprintf(
-      "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q", zTab
-  );
-  if( zSql==0 ) return SQLITE_NOMEM;
-  rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0);
-  sqlite3_free(zSql);
-
-  return rc;
-}
-
-/*
-** This function is called as part of sqlite3_expert_analyze(). Candidate
-** indexes have already been created in database sqlite3expert.dbm, this
-** function populates sqlite_stat1 table in the same database.
-**
-** The stat1 data is generated by querying the 
-*/
-static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
-  int rc = SQLITE_OK;
-  int nMax =0;
-  struct IdxRemCtx *pCtx = 0;
-  struct IdxSampleCtx samplectx; 
-  int i;
-  i64 iPrev = -100000;
-  sqlite3_stmt *pAllIndex = 0;
-  sqlite3_stmt *pIndexXInfo = 0;
-  sqlite3_stmt *pWrite = 0;
-
-  const char *zAllIndex =
-    "SELECT s.rowid, s.name, l.name FROM "
-    "  sqlite_schema AS s, "
-    "  pragma_index_list(s.name) AS l "
-    "WHERE s.type = 'table'";
-  const char *zIndexXInfo = 
-    "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key";
-  const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)";
-
-  /* If iSample==0, no sqlite_stat1 data is required. */
-  if( p->iSample==0 ) return SQLITE_OK;
-
-  rc = idxLargestIndex(p->dbm, &nMax, pzErr);
-  if( nMax<=0 || rc!=SQLITE_OK ) return rc;
-
-  rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
-
-  if( rc==SQLITE_OK ){
-    int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
-    pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
-  }
-
-  if( rc==SQLITE_OK ){
-    sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
-    rc = sqlite3_create_function(
-        dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
-    );
-  }
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_create_function(
-        p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
-    );
-  }
-
-  if( rc==SQLITE_OK ){
-    pCtx->nSlot = nMax+1;
-    rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
-  }
-  if( rc==SQLITE_OK ){
-    rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo);
-  }
-  if( rc==SQLITE_OK ){
-    rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite);
-  }
-
-  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){
-    i64 iRowid = sqlite3_column_int64(pAllIndex, 0);
-    const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1);
-    const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2);
-    if( zTab==0 || zIdx==0 ) continue;
-    if( p->iSample<100 && iPrev!=iRowid ){
-      samplectx.target = (double)p->iSample / 100.0;
-      samplectx.iTarget = p->iSample;
-      samplectx.nRow = 0.0;
-      samplectx.nRet = 0.0;
-      rc = idxBuildSampleTable(p, zTab);
-      if( rc!=SQLITE_OK ) break;
-    }
-    rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr);
-    iPrev = iRowid;
-  }
-  if( rc==SQLITE_OK && p->iSample<100 ){
-    rc = sqlite3_exec(p->dbv, 
-        "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0
-    );
-  }
-
-  idxFinalize(&rc, pAllIndex);
-  idxFinalize(&rc, pIndexXInfo);
-  idxFinalize(&rc, pWrite);
-
-  if( pCtx ){
-    for(i=0; i<pCtx->nSlot; i++){
-      sqlite3_free(pCtx->aSlot[i].z);
-    }
-    sqlite3_free(pCtx);
-  }
-
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0);
-  }
-
-  sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
-  return rc;
-}
-
-/*
-** Allocate a new sqlite3expert object.
-*/
-sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
-  int rc = SQLITE_OK;
-  sqlite3expert *pNew;
-
-  pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert));
-
-  /* Open two in-memory databases to work with. The "vtab database" (dbv)
-  ** will contain a virtual table corresponding to each real table in
-  ** the user database schema, and a copy of each view. It is used to
-  ** collect information regarding the WHERE, ORDER BY and other clauses
-  ** of the user's query.
-  */
-  if( rc==SQLITE_OK ){
-    pNew->db = db;
-    pNew->iSample = 100;
-    rc = sqlite3_open(":memory:", &pNew->dbv);
-  }
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_open(":memory:", &pNew->dbm);
-    if( rc==SQLITE_OK ){
-      sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0);
-    }
-  }
-  
-
-  /* Copy the entire schema of database [db] into [dbm]. */
-  if( rc==SQLITE_OK ){
-    sqlite3_stmt *pSql = 0;
-    rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, 
-        "SELECT sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%%'"
-        " AND sql NOT LIKE 'CREATE VIRTUAL %%'"
-    );
-    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
-      const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
-      if( zSql ) rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
-    }
-    idxFinalize(&rc, pSql);
-  }
-
-  /* Create the vtab schema */
-  if( rc==SQLITE_OK ){
-    rc = idxCreateVtabSchema(pNew, pzErrmsg);
-  }
-
-  /* Register the auth callback with dbv */
-  if( rc==SQLITE_OK ){
-    sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew);
-  }
-
-  /* If an error has occurred, free the new object and reutrn NULL. Otherwise,
-  ** return the new sqlite3expert handle.  */
-  if( rc!=SQLITE_OK ){
-    sqlite3_expert_destroy(pNew);
-    pNew = 0;
-  }
-  return pNew;
-}
-
-/*
-** Configure an sqlite3expert object.
-*/
-int sqlite3_expert_config(sqlite3expert *p, int op, ...){
-  int rc = SQLITE_OK;
-  va_list ap;
-  va_start(ap, op);
-  switch( op ){
-    case EXPERT_CONFIG_SAMPLE: {
-      int iVal = va_arg(ap, int);
-      if( iVal<0 ) iVal = 0;
-      if( iVal>100 ) iVal = 100;
-      p->iSample = iVal;
-      break;
-    }
-    default:
-      rc = SQLITE_NOTFOUND;
-      break;
-  }
-
-  va_end(ap);
-  return rc;
-}
-
-/*
-** Add an SQL statement to the analysis.
-*/
-int sqlite3_expert_sql(
-  sqlite3expert *p,               /* From sqlite3_expert_new() */
-  const char *zSql,               /* SQL statement to add */
-  char **pzErr                    /* OUT: Error message (if any) */
-){
-  IdxScan *pScanOrig = p->pScan;
-  IdxStatement *pStmtOrig = p->pStatement;
-  int rc = SQLITE_OK;
-  const char *zStmt = zSql;
-
-  if( p->bRun ) return SQLITE_MISUSE;
-
-  while( rc==SQLITE_OK && zStmt && zStmt[0] ){
-    sqlite3_stmt *pStmt = 0;
-    rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt);
-    if( rc==SQLITE_OK ){
-      if( pStmt ){
-        IdxStatement *pNew;
-        const char *z = sqlite3_sql(pStmt);
-        int n = STRLEN(z);
-        pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
-        if( rc==SQLITE_OK ){
-          pNew->zSql = (char*)&pNew[1];
-          memcpy(pNew->zSql, z, n+1);
-          pNew->pNext = p->pStatement;
-          if( p->pStatement ) pNew->iId = p->pStatement->iId+1;
-          p->pStatement = pNew;
-        }
-        sqlite3_finalize(pStmt);
-      }
-    }else{
-      idxDatabaseError(p->dbv, pzErr);
-    }
-  }
-
-  if( rc!=SQLITE_OK ){
-    idxScanFree(p->pScan, pScanOrig);
-    idxStatementFree(p->pStatement, pStmtOrig);
-    p->pScan = pScanOrig;
-    p->pStatement = pStmtOrig;
-  }
-
-  return rc;
-}
-
-int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
-  int rc;
-  IdxHashEntry *pEntry;
-
-  /* Do trigger processing to collect any extra IdxScan structures */
-  rc = idxProcessTriggers(p, pzErr);
-
-  /* Create candidate indexes within the in-memory database file */
-  if( rc==SQLITE_OK ){
-    rc = idxCreateCandidates(p);
-  }else if ( rc==SQLITE_BUSY_TIMEOUT ){
-    if( pzErr )
-      *pzErr = sqlite3_mprintf("Cannot find a unique index name to propose.");
-    return rc;
-  }
-
-  /* Generate the stat1 data */
-  if( rc==SQLITE_OK ){
-    rc = idxPopulateStat1(p, pzErr);
-  }
-
-  /* Formulate the EXPERT_REPORT_CANDIDATES text */
-  for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
-    p->zCandidates = idxAppendText(&rc, p->zCandidates, 
-        "%s;%s%s\n", pEntry->zVal, 
-        pEntry->zVal2 ? " -- stat1: " : "", pEntry->zVal2
-    );
-  }
-
-  /* Figure out which of the candidate indexes are preferred by the query
-  ** planner and report the results to the user.  */
-  if( rc==SQLITE_OK ){
-    rc = idxFindIndexes(p, pzErr);
-  }
-
-  if( rc==SQLITE_OK ){
-    p->bRun = 1;
-  }
-  return rc;
-}
-
-/*
-** Return the total number of statements that have been added to this
-** sqlite3expert using sqlite3_expert_sql().
-*/
-int sqlite3_expert_count(sqlite3expert *p){
-  int nRet = 0;
-  if( p->pStatement ) nRet = p->pStatement->iId+1;
-  return nRet;
-}
-
-/*
-** Return a component of the report.
-*/
-const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){
-  const char *zRet = 0;
-  IdxStatement *pStmt;
-
-  if( p->bRun==0 ) return 0;
-  for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext);
-  switch( eReport ){
-    case EXPERT_REPORT_SQL:
-      if( pStmt ) zRet = pStmt->zSql;
-      break;
-    case EXPERT_REPORT_INDEXES:
-      if( pStmt ) zRet = pStmt->zIdx;
-      break;
-    case EXPERT_REPORT_PLAN:
-      if( pStmt ) zRet = pStmt->zEQP;
-      break;
-    case EXPERT_REPORT_CANDIDATES:
-      zRet = p->zCandidates;
-      break;
-  }
-  return zRet;
-}
-
-/*
-** Free an sqlite3expert object.
-*/
-void sqlite3_expert_destroy(sqlite3expert *p){
-  if( p ){
-    sqlite3_close(p->dbm);
-    sqlite3_close(p->dbv);
-    idxScanFree(p->pScan, 0);
-    idxStatementFree(p->pStatement, 0);
-    idxTableFree(p->pTable);
-    idxWriteFree(p->pWrite);
-    idxHashClear(&p->hIdx);
-    sqlite3_free(p->zCandidates);
-    sqlite3_free(p);
-  }
-}
-
-#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
-
-/************************* End ../ext/expert/sqlite3expert.c ********************/
-
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
-#define SQLITE_SHELL_HAVE_RECOVER 1
-#else
-#define SQLITE_SHELL_HAVE_RECOVER 0
-#endif
-#if SQLITE_SHELL_HAVE_RECOVER
-/************************* 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.
-*/
-
-/*
-** 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.
-*/
-
-#ifndef _SQLITE_RECOVER_H
-#define _SQLITE_RECOVER_H
-
-/* #include "sqlite3.h" */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
-** 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()
-*/
-typedef struct sqlite3_recover sqlite3_recover;
-
-/* 
-** 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.
-*/
-int sqlite3_recover_config(sqlite3_recover*, int op, void *pArg);
-
-/*
-** 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
-
-/*
-** 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*);
-
-/* 
-** 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*);
-
-/*
-** 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.
-*/
-int sqlite3_recover_errcode(sqlite3_recover*);
-
-/* 
-** 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*);
-
-
-#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 ******************/
-/*
-** 2019-04-17
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-******************************************************************************
-**
-** This 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
-){
-  DbdataTable *pTab = 0;
-  int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA);
-
-  (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);
-    }
-  }
-
-  *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:
-**
-**       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 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);
-
-  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:
-      return 6;
-    case 6:
-    case 7:
-      return 8;
-    default:
-      if( eType>0 ){
-        return ((eType-12) / 2);
-      }
-      return 0;
-  }
-}
-
-/*
-** Load a value of type eType from buffer pData and use it to set the
-** result of context object pCtx.
-*/
-static void dbdataValue(
-  sqlite3_context *pCtx, 
-  u32 enc,
-  int eType, 
-  u8 *pData,
-  sqlite3_int64 nData
-){
-  if( eType>=0 && dbdataValueBytes(eType)<=nData ){
-    switch( eType ){
-      case 0: 
-      case 10: 
-      case 11: 
-        sqlite3_result_null(pCtx);
-        break;
-      
-      case 8: 
-        sqlite3_result_int(pCtx, 0);
-        break;
-      case 9:
-        sqlite3_result_int(pCtx, 1);
-        break;
-  
-      case 1: case 2: case 3: case 4: case 5: case 6: case 7: {
-        sqlite3_uint64 v = (signed char)pData[0];
-        pData++;
-        switch( eType ){
-          case 7:
-          case 6:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
-          case 5:  v = (v<<16) + (pData[0]<<8) + pData[1];  pData += 2;
-          case 4:  v = (v<<8) + pData[0];  pData++;
-          case 3:  v = (v<<8) + pData[0];  pData++;
-          case 2:  v = (v<<8) + pData[0];  pData++;
-        }
-  
-        if( eType==7 ){
-          double r;
-          memcpy(&r, &v, sizeof(r));
-          sqlite3_result_double(pCtx, r);
-        }else{
-          sqlite3_result_int64(pCtx, (sqlite3_int64)v);
-        }
-        break;
-      }
-  
-      default: {
-        int n = ((eType-12) / 2);
-        if( eType % 2 ){
-          switch( enc ){
-#ifndef SQLITE_OMIT_UTF16
-            case SQLITE_UTF16BE:
-              sqlite3_result_text16be(pCtx, (void*)pData, n, SQLITE_TRANSIENT);
-              break;
-            case SQLITE_UTF16LE:
-              sqlite3_result_text16le(pCtx, (void*)pData, n, SQLITE_TRANSIENT);
-              break;
-#endif
-            default:
-              sqlite3_result_text(pCtx, (char*)pData, n, SQLITE_TRANSIENT);
-              break;
-          }
-        }else{
-          sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT);
-        }
-      }
-    }
-  }
-}
-
-/*
-** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry.
-*/
-static int dbdataNext(sqlite3_vtab_cursor *pCursor){
-  DbdataCursor *pCsr = (DbdataCursor*)pCursor;
-  DbdataTable *pTab = (DbdataTable*)pCursor->pVtab;
-
-  pCsr->iRowid++;
-  while( 1 ){
-    int rc;
-    int iOff = (pCsr->iPgno==1 ? 100 : 0);
-    int bNextPage = 0;
-
-    if( pCsr->aPage==0 ){
-      while( 1 ){
-        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 && 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]);
-    }
-
-    if( pTab->bPtr ){
-      if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){
-        pCsr->iCell = pCsr->nCell;
-      }
-      pCsr->iCell++;
-      if( pCsr->iCell>=pCsr->nCell ){
-        sqlite3_free(pCsr->aPage);
-        pCsr->aPage = 0;
-        if( pCsr->bOnePage ) return SQLITE_OK;
-        pCsr->iPgno++;
-      }else{
-        return SQLITE_OK;
-      }
-    }else{
-      /* If there is no record loaded, load it now. */
-      if( pCsr->pRec==0 ){
-        int bHasRowid = 0;
-        int nPointer = 0;
-        sqlite3_int64 nPayload = 0;
-        sqlite3_int64 nHdr = 0;
-        int iHdr;
-        int U, X;
-        int nLocal;
-  
-        switch( pCsr->aPage[iOff] ){
-          case 0x02:
-            nPointer = 4;
-            break;
-          case 0x0a:
-            break;
-          case 0x0d:
-            bHasRowid = 1;
-            break;
-          default:
-            /* This is not a b-tree page with records on it. Continue. */
-            pCsr->iCell = pCsr->nCell;
-            break;
-        }
-
-        if( pCsr->iCell>=pCsr->nCell ){
-          bNextPage = 1;
-        }else{
-  
-          iOff += 8 + nPointer + pCsr->iCell*2;
-          if( iOff>pCsr->nPage ){
-            bNextPage = 1;
-          }else{
-            iOff = get_uint16(&pCsr->aPage[iOff]);
-          }
-    
-          /* For an interior node cell, skip past the child-page number */
-          iOff += nPointer;
-    
-          /* Load the "byte of payload including overflow" field */
-          if( bNextPage || iOff>pCsr->nPage ){
-            bNextPage = 1;
-          }else{
-            iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload);
-          }
-    
-          /* If this is a leaf intkey cell, load the rowid */
-          if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){
-            iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey);
-          }
-    
-          /* Figure out how much data to read from the local page */
-          U = pCsr->nPage;
-          if( bHasRowid ){
-            X = U-35;
-          }else{
-            X = ((U-12)*64/255)-23;
-          }
-          if( nPayload<=X ){
-            nLocal = nPayload;
-          }else{
-            int M, K;
-            M = ((U-12)*32/255)-23;
-            K = M+((nPayload-M)%(U-4));
-            if( K<=X ){
-              nLocal = K;
-            }else{
-              nLocal = M;
-            }
-          }
-
-          if( bNextPage || nLocal+iOff>pCsr->nPage ){
-            bNextPage = 1;
-          }else{
-
-            /* Allocate space for payload. And a bit more to catch small buffer
-            ** overruns caused by attempting to read a varint or similar from 
-            ** near the end of a corrupt record.  */
-            pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES);
-            if( pCsr->pRec==0 ) return SQLITE_NOMEM;
-            memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES);
-            pCsr->nRec = nPayload;
-
-            /* Load the nLocal bytes of payload */
-            memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal);
-            iOff += nLocal;
-
-            /* Load content from overflow pages */
-            if( nPayload>nLocal ){
-              sqlite3_int64 nRem = nPayload - nLocal;
-              u32 pgnoOvfl = get_uint32(&pCsr->aPage[iOff]);
-              while( nRem>0 ){
-                u8 *aOvfl = 0;
-                int nOvfl = 0;
-                int nCopy;
-                rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl);
-                assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage );
-                if( rc!=SQLITE_OK ) return rc;
-                if( aOvfl==0 ) break;
-
-                nCopy = U-4;
-                if( nCopy>nRem ) nCopy = nRem;
-                memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy);
-                nRem -= nCopy;
-
-                pgnoOvfl = get_uint32(aOvfl);
-                sqlite3_free(aOvfl);
-              }
-            }
-    
-            iHdr = dbdataGetVarintU32(pCsr->pRec, &nHdr);
-            if( nHdr>nPayload ) nHdr = 0;
-            pCsr->nHdr = nHdr;
-            pCsr->pHdrPtr = &pCsr->pRec[iHdr];
-            pCsr->pPtr = &pCsr->pRec[pCsr->nHdr];
-            pCsr->iField = (bHasRowid ? -1 : 0);
-          }
-        }
-      }else{
-        pCsr->iField++;
-        if( pCsr->iField>0 ){
-          sqlite3_int64 iType;
-          if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){
-            bNextPage = 1;
-          }else{
-            pCsr->pHdrPtr += dbdataGetVarintU32(pCsr->pHdrPtr, &iType);
-            pCsr->pPtr += dbdataValueBytes(iType);
-          }
-        }
-      }
-
-      if( bNextPage ){
-        sqlite3_free(pCsr->aPage);
-        sqlite3_free(pCsr->pRec);
-        pCsr->aPage = 0;
-        pCsr->pRec = 0;
-        if( pCsr->bOnePage ) return SQLITE_OK;
-        pCsr->iPgno++;
-      }else{
-        if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){
-          return SQLITE_OK;
-        }
-
-        /* 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);
-  if( rc==SQLITE_OK && nPg1>=(56+4) ){
-    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";
-  (void)idxStr;
-  (void)argc;
-
-  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;
-}
-
-/*
-** 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);
-  (void)pzErrMsg;
-  return sqlite3DbdataRegister(db);
-}
-
-#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
-
-/************************* End ../ext/recover/dbdata.c ********************/
-/************************* Begin ../ext/recover/sqlite3recover.c ******************/
-/*
-** 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.
-**
-*************************************************************************
-**
-*/
-
-
-/* #include "sqlite3recover.h" */
-#include <assert.h>
-#include <string.h>
-
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-
-/*
-** Declaration for public API function in file dbdata.c. This may be called
-** with NULL as the final two arguments to register the sqlite_dbptr and
-** sqlite_dbdata virtual tables with a database handle.
-*/
-#ifdef _WIN32
-
-#endif
-int sqlite3_dbdata_init(sqlite3*, char**, const sqlite3_api_routines*);
-
-/* typedef unsigned int u32; */
-/* typedef unsigned char u8; */
-/* typedef sqlite3_int64 i64; */
-
-typedef struct RecoverTable RecoverTable;
-typedef struct RecoverColumn RecoverColumn;
-
-/*
-** When recovering rows of data that can be associated with table
-** definitions recovered from the sqlite_schema table, each table is
-** represented by an instance of the following object.
-**
-** iRoot:
-**   The root page in the original database. Not necessarily (and usually
-**   not) the same in the recovered database.
-**
-** zTab:
-**   Name of the table.
-**
-** nCol/aCol[]:
-**   aCol[] is an array of nCol columns. In the order in which they appear 
-**   in the table.
-**
-** bIntkey:
-**   Set to true for intkey tables, false for WITHOUT ROWID.
-**
-** iRowidBind:
-**   Each column in the aCol[] array has associated with it the index of
-**   the bind parameter its values will be bound to in the INSERT statement
-**   used to construct the output database. If the table does has a rowid
-**   but not an INTEGER PRIMARY KEY column, then iRowidBind contains the
-**   index of the bind paramater to which the rowid value should be bound.
-**   Otherwise, it contains -1. If the table does contain an INTEGER PRIMARY 
-**   KEY column, then the rowid value should be bound to the index associated
-**   with the column.
-**
-** pNext:
-**   All RecoverTable objects used by the recovery operation are allocated
-**   and populated as part of creating the recovered database schema in
-**   the output database, before any non-schema data are recovered. They
-**   are then stored in a singly-linked list linked by this variable beginning
-**   at sqlite3_recover.pTblList.
-*/
-struct RecoverTable {
-  u32 iRoot;                      /* Root page in original database */
-  char *zTab;                     /* Name of table */
-  int nCol;                       /* Number of columns in table */
-  RecoverColumn *aCol;            /* Array of columns */
-  int bIntkey;                    /* True for intkey, false for without rowid */
-  int iRowidBind;                 /* If >0, bind rowid to INSERT here */
-  RecoverTable *pNext;
-};
-
-/*
-** Each database column is represented by an instance of the following object
-** stored in the RecoverTable.aCol[] array of the associated table.
-**
-** iField:
-**   The index of the associated field within database records. Or -1 if
-**   there is no associated field (e.g. for virtual generated columns).
-**
-** iBind:
-**   The bind index of the INSERT statement to bind this columns values
-**   to. Or 0 if there is no such index (iff (iField<0)).
-**
-** bIPK:
-**   True if this is the INTEGER PRIMARY KEY column.
-**
-** zCol:
-**   Name of column.
-**
-** eHidden:
-**   A RECOVER_EHIDDEN_* constant value (see below for interpretation of each).
-*/
-struct RecoverColumn {
-  int iField;                     /* Field in record on disk */
-  int iBind;                      /* Binding to use in INSERT */
-  int bIPK;                       /* True for IPK column */
-  char *zCol;
-  int eHidden;
-};
-
-#define RECOVER_EHIDDEN_NONE    0      /* Normal database column */
-#define RECOVER_EHIDDEN_HIDDEN  1      /* Column is __HIDDEN__ */
-#define RECOVER_EHIDDEN_VIRTUAL 2      /* Virtual generated column */
-#define RECOVER_EHIDDEN_STORED  3      /* Stored generated column */
-
-/*
-** Bitmap object used to track pages in the input database. Allocated
-** and manipulated only by the following functions:
-**
-**     recoverBitmapAlloc()
-**     recoverBitmapFree()
-**     recoverBitmapSet()
-**     recoverBitmapQuery()
-**
-** nPg:
-**   Largest page number that may be stored in the bitmap. The range
-**   of valid keys is 1 to nPg, inclusive.
-**
-** aElem[]:
-**   Array large enough to contain a bit for each key. For key value
-**   iKey, the associated bit is the bit (iKey%32) of aElem[iKey/32].
-**   In other words, the following is true if bit iKey is set, or 
-**   false if it is clear:
-**
-**       (aElem[iKey/32] & (1 << (iKey%32))) ? 1 : 0
-*/
-typedef struct RecoverBitmap RecoverBitmap;
-struct RecoverBitmap {
-  i64 nPg;                        /* Size of bitmap */
-  u32 aElem[1];                   /* Array of 32-bit bitmasks */
-};
-
-/*
-** State variables (part of the sqlite3_recover structure) used while
-** recovering data for tables identified in the recovered schema (state
-** RECOVER_STATE_WRITING).
-*/
-typedef struct RecoverStateW1 RecoverStateW1;
-struct RecoverStateW1 {
-  sqlite3_stmt *pTbls;
-  sqlite3_stmt *pSel;
-  sqlite3_stmt *pInsert;
-  int nInsert;
-
-  RecoverTable *pTab;             /* Table currently being written */
-  int nMax;                       /* Max column count in any schema table */
-  sqlite3_value **apVal;          /* Array of nMax values */
-  int nVal;                       /* Number of valid entries in apVal[] */
-  int bHaveRowid;
-  i64 iRowid;
-  i64 iPrevPage;
-  int iPrevCell;
-};
-
-/*
-** State variables (part of the sqlite3_recover structure) used while
-** recovering data destined for the lost and found table (states
-** RECOVER_STATE_LOSTANDFOUND[123]).
-*/
-typedef struct RecoverStateLAF RecoverStateLAF;
-struct RecoverStateLAF {
-  RecoverBitmap *pUsed;
-  i64 nPg;                        /* Size of db in pages */
-  sqlite3_stmt *pAllAndParent;
-  sqlite3_stmt *pMapInsert;
-  sqlite3_stmt *pMaxField;
-  sqlite3_stmt *pUsedPages;
-  sqlite3_stmt *pFindRoot;
-  sqlite3_stmt *pInsert;          /* INSERT INTO lost_and_found ... */
-  sqlite3_stmt *pAllPage;
-  sqlite3_stmt *pPageData;
-  sqlite3_value **apVal;
-  int nMaxField;
-};
-
-/*
-** Main recover handle structure.
-*/
-struct sqlite3_recover {
-  /* Copies of sqlite3_recover_init[_sql]() parameters */
-  sqlite3 *dbIn;                  /* Input database */
-  char *zDb;                      /* Name of input db ("main" etc.) */
-  char *zUri;                     /* URI for output database */
-  void *pSqlCtx;                  /* SQL callback context */
-  int (*xSql)(void*,const char*); /* Pointer to SQL callback function */
-
-  /* Values configured by sqlite3_recover_config() */
-  char *zStateDb;                 /* State database to use (or NULL) */
-  char *zLostAndFound;            /* Name of lost-and-found table (or NULL) */
-  int bFreelistCorrupt;           /* SQLITE_RECOVER_FREELIST_CORRUPT setting */
-  int bRecoverRowid;              /* SQLITE_RECOVER_ROWIDS setting */
-  int bSlowIndexes;               /* SQLITE_RECOVER_SLOWINDEXES setting */
-
-  int pgsz;
-  int detected_pgsz;
-  int nReserve;
-  u8 *pPage1Disk;
-  u8 *pPage1Cache;
-
-  /* Error code and error message */
-  int errCode;                    /* For sqlite3_recover_errcode() */
-  char *zErrMsg;                  /* For sqlite3_recover_errmsg() */
-
-  int eState;
-  int bCloseTransaction;
-
-  /* Variables used with eState==RECOVER_STATE_WRITING */
-  RecoverStateW1 w1;
-
-  /* Variables used with states RECOVER_STATE_LOSTANDFOUND[123] */
-  RecoverStateLAF laf;
-
-  /* Fields used within sqlite3_recover_run() */
-  sqlite3 *dbOut;                 /* Output database */
-  sqlite3_stmt *pGetPage;         /* SELECT against input db sqlite_dbdata */
-  RecoverTable *pTblList;         /* List of tables recovered from schema */
-};
-
-/*
-** The various states in which an sqlite3_recover object may exist:
-**
-**   RECOVER_STATE_INIT:
-**    The object is initially created in this state. sqlite3_recover_step()
-**    has yet to be called. This is the only state in which it is permitted
-**    to call sqlite3_recover_config().
-**
-**   RECOVER_STATE_WRITING:
-**
-**   RECOVER_STATE_LOSTANDFOUND1:
-**    State to populate the bitmap of pages used by other tables or the
-**    database freelist.
-**
-**   RECOVER_STATE_LOSTANDFOUND2:
-**    Populate the recovery.map table - used to figure out a "root" page
-**    for each lost page from in the database from which records are
-**    extracted.
-**
-**   RECOVER_STATE_LOSTANDFOUND3:
-**    Populate the lost-and-found table itself.
-*/
-#define RECOVER_STATE_INIT           0
-#define RECOVER_STATE_WRITING        1
-#define RECOVER_STATE_LOSTANDFOUND1  2
-#define RECOVER_STATE_LOSTANDFOUND2  3
-#define RECOVER_STATE_LOSTANDFOUND3  4
-#define RECOVER_STATE_SCHEMA2        5
-#define RECOVER_STATE_DONE           6
-
-
-/*
-** Global variables used by this extension.
-*/
-typedef struct RecoverGlobal RecoverGlobal;
-struct RecoverGlobal {
-  const sqlite3_io_methods *pMethods;
-  sqlite3_recover *p;
-};
-static RecoverGlobal recover_g;
-
-/*
-** Use this static SQLite mutex to protect the globals during the
-** first call to sqlite3_recover_step().
-*/ 
-#define RECOVER_MUTEX_ID SQLITE_MUTEX_STATIC_APP2
-
-
-/* 
-** Default value for SQLITE_RECOVER_ROWIDS (sqlite3_recover.bRecoverRowid).
-*/
-#define RECOVER_ROWID_DEFAULT 1
-
-/*
-** Mutex handling:
-**
-**    recoverEnterMutex()       -   Enter the recovery mutex
-**    recoverLeaveMutex()       -   Leave the recovery mutex
-**    recoverAssertMutexHeld()  -   Assert that the recovery mutex is held
-*/
-#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
-# define recoverEnterMutex()
-# define recoverLeaveMutex()
-#else
-static void recoverEnterMutex(void){
-  sqlite3_mutex_enter(sqlite3_mutex_alloc(RECOVER_MUTEX_ID));
-}
-static void recoverLeaveMutex(void){
-  sqlite3_mutex_leave(sqlite3_mutex_alloc(RECOVER_MUTEX_ID));
-}
-#endif
-#if SQLITE_THREADSAFE+0>=1 && defined(SQLITE_DEBUG)
-static void recoverAssertMutexHeld(void){
-  assert( sqlite3_mutex_held(sqlite3_mutex_alloc(RECOVER_MUTEX_ID)) );
-}
-#else
-# define recoverAssertMutexHeld()
-#endif
-
-
-/*
-** Like strlen(). But handles NULL pointer arguments.
-*/
-static int recoverStrlen(const char *zStr){
-  if( zStr==0 ) return 0;
-  return (int)(strlen(zStr)&0x7fffffff);
-}
-
-/*
-** This function is a no-op if the recover handle passed as the first 
-** argument already contains an error (if p->errCode!=SQLITE_OK). 
-**
-** Otherwise, an attempt is made to allocate, zero and return a buffer nByte
-** bytes in size. If successful, a pointer to the new buffer is returned. Or,
-** if an OOM error occurs, NULL is returned and the handle error code
-** (p->errCode) set to SQLITE_NOMEM.
-*/
-static void *recoverMalloc(sqlite3_recover *p, i64 nByte){
-  void *pRet = 0;
-  assert( nByte>0 );
-  if( p->errCode==SQLITE_OK ){
-    pRet = sqlite3_malloc64(nByte);
-    if( pRet ){
-      memset(pRet, 0, nByte);
-    }else{
-      p->errCode = SQLITE_NOMEM;
-    }
-  }
-  return pRet;
-}
-
-/*
-** Set the error code and error message for the recover handle passed as
-** the first argument. The error code is set to the value of parameter
-** errCode.
-**
-** Parameter zFmt must be a printf() style formatting string. The handle 
-** error message is set to the result of using any trailing arguments for 
-** parameter substitutions in the formatting string.
-**
-** For example:
-**
-**   recoverError(p, SQLITE_ERROR, "no such table: %s", zTablename);
-*/
-static int recoverError(
-  sqlite3_recover *p, 
-  int errCode, 
-  const char *zFmt, ...
-){
-  char *z = 0;
-  va_list ap;
-  va_start(ap, zFmt);
-  if( zFmt ){
-    z = sqlite3_vmprintf(zFmt, ap);
-    va_end(ap);
-  }
-  sqlite3_free(p->zErrMsg);
-  p->zErrMsg = z;
-  p->errCode = errCode;
-  return errCode;
-}
-
-
-/*
-** This function is a no-op if p->errCode is initially other than SQLITE_OK.
-** In this case it returns NULL.
-**
-** Otherwise, an attempt is made to allocate and return a bitmap object
-** large enough to store a bit for all page numbers between 1 and nPg,
-** inclusive. The bitmap is initially zeroed.
-*/
-static RecoverBitmap *recoverBitmapAlloc(sqlite3_recover *p, i64 nPg){
-  int nElem = (nPg+1+31) / 32;
-  int nByte = sizeof(RecoverBitmap) + nElem*sizeof(u32);
-  RecoverBitmap *pRet = (RecoverBitmap*)recoverMalloc(p, nByte);
-
-  if( pRet ){
-    pRet->nPg = nPg;
-  }
-  return pRet;
-}
-
-/*
-** Free a bitmap object allocated by recoverBitmapAlloc().
-*/
-static void recoverBitmapFree(RecoverBitmap *pMap){
-  sqlite3_free(pMap);
-}
-
-/*
-** Set the bit associated with page iPg in bitvec pMap.
-*/
-static void recoverBitmapSet(RecoverBitmap *pMap, i64 iPg){
-  if( iPg<=pMap->nPg ){
-    int iElem = (iPg / 32);
-    int iBit = (iPg % 32);
-    pMap->aElem[iElem] |= (((u32)1) << iBit);
-  }
-}
-
-/*
-** Query bitmap object pMap for the state of the bit associated with page
-** iPg. Return 1 if it is set, or 0 otherwise.
-*/
-static int recoverBitmapQuery(RecoverBitmap *pMap, i64 iPg){
-  int ret = 1;
-  if( iPg<=pMap->nPg && iPg>0 ){
-    int iElem = (iPg / 32);
-    int iBit = (iPg % 32);
-    ret = (pMap->aElem[iElem] & (((u32)1) << iBit)) ? 1 : 0;
-  }
-  return ret;
-}
-
-/*
-** Set the recover handle error to the error code and message returned by
-** calling sqlite3_errcode() and sqlite3_errmsg(), respectively, on database
-** handle db.
-*/
-static int recoverDbError(sqlite3_recover *p, sqlite3 *db){
-  return recoverError(p, sqlite3_errcode(db), "%s", sqlite3_errmsg(db));
-}
-
-/*
-** This function is a no-op if recover handle p already contains an error
-** (if p->errCode!=SQLITE_OK). 
-**
-** Otherwise, it attempts to prepare the SQL statement in zSql against
-** database handle db. If successful, the statement handle is returned.
-** Or, if an error occurs, NULL is returned and an error left in the
-** recover handle.
-*/
-static sqlite3_stmt *recoverPrepare(
-  sqlite3_recover *p,
-  sqlite3 *db, 
-  const char *zSql
-){
-  sqlite3_stmt *pStmt = 0;
-  if( p->errCode==SQLITE_OK ){
-    if( sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) ){
-      recoverDbError(p, db);
-    }
-  }
-  return pStmt;
-}
-
-/*
-** This function is a no-op if recover handle p already contains an error
-** (if p->errCode!=SQLITE_OK). 
-**
-** Otherwise, argument zFmt is used as a printf() style format string,
-** along with any trailing arguments, to create an SQL statement. This
-** SQL statement is prepared against database handle db and, if successful,
-** the statment handle returned. Or, if an error occurs - either during
-** the printf() formatting or when preparing the resulting SQL - an
-** error code and message are left in the recover handle.
-*/
-static sqlite3_stmt *recoverPreparePrintf(
-  sqlite3_recover *p,
-  sqlite3 *db, 
-  const char *zFmt, ...
-){
-  sqlite3_stmt *pStmt = 0;
-  if( p->errCode==SQLITE_OK ){
-    va_list ap;
-    char *z;
-    va_start(ap, zFmt);
-    z = sqlite3_vmprintf(zFmt, ap);
-    va_end(ap);
-    if( z==0 ){
-      p->errCode = SQLITE_NOMEM;
-    }else{
-      pStmt = recoverPrepare(p, db, z);
-      sqlite3_free(z);
-    }
-  }
-  return pStmt;
-}
-
-/*
-** Reset SQLite statement handle pStmt. If the call to sqlite3_reset() 
-** indicates that an error occurred, and there is not already an error
-** in the recover handle passed as the first argument, set the error
-** code and error message appropriately.
-**
-** This function returns a copy of the statement handle pointer passed
-** as the second argument.
-*/
-static sqlite3_stmt *recoverReset(sqlite3_recover *p, sqlite3_stmt *pStmt){
-  int rc = sqlite3_reset(pStmt);
-  if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT && p->errCode==SQLITE_OK ){
-    recoverDbError(p, sqlite3_db_handle(pStmt));
-  }
-  return pStmt;
-}
-
-/*
-** Finalize SQLite statement handle pStmt. If the call to sqlite3_reset() 
-** indicates that an error occurred, and there is not already an error
-** in the recover handle passed as the first argument, set the error
-** code and error message appropriately.
-*/
-static void recoverFinalize(sqlite3_recover *p, sqlite3_stmt *pStmt){
-  sqlite3 *db = sqlite3_db_handle(pStmt);
-  int rc = sqlite3_finalize(pStmt);
-  if( rc!=SQLITE_OK && p->errCode==SQLITE_OK ){
-    recoverDbError(p, db);
-  }
-}
-
-/*
-** This function is a no-op if recover handle p already contains an error
-** (if p->errCode!=SQLITE_OK). A copy of p->errCode is returned in this 
-** case.
-**
-** Otherwise, execute SQL script zSql. If successful, return SQLITE_OK.
-** Or, if an error occurs, leave an error code and message in the recover
-** handle and return a copy of the error code.
-*/
-static int recoverExec(sqlite3_recover *p, sqlite3 *db, const char *zSql){
-  if( p->errCode==SQLITE_OK ){
-    int rc = sqlite3_exec(db, zSql, 0, 0, 0);
-    if( rc ){
-      recoverDbError(p, db);
-    }
-  }
-  return p->errCode;
-}
-
-/*
-** Bind the value pVal to parameter iBind of statement pStmt. Leave an
-** error in the recover handle passed as the first argument if an error
-** (e.g. an OOM) occurs.
-*/
-static void recoverBindValue(
-  sqlite3_recover *p, 
-  sqlite3_stmt *pStmt, 
-  int iBind, 
-  sqlite3_value *pVal
-){
-  if( p->errCode==SQLITE_OK ){
-    int rc = sqlite3_bind_value(pStmt, iBind, pVal);
-    if( rc ) recoverError(p, rc, 0);
-  }
-}
-
-/*
-** This function is a no-op if recover handle p already contains an error
-** (if p->errCode!=SQLITE_OK). NULL is returned in this case.
-**
-** Otherwise, an attempt is made to interpret zFmt as a printf() style
-** formatting string and the result of using the trailing arguments for
-** parameter substitution with it written into a buffer obtained from
-** sqlite3_malloc(). If successful, a pointer to the buffer is returned.
-** It is the responsibility of the caller to eventually free the buffer
-** using sqlite3_free().
-**
-** Or, if an error occurs, an error code and message is left in the recover
-** handle and NULL returned.
-*/
-static char *recoverMPrintf(sqlite3_recover *p, const char *zFmt, ...){
-  va_list ap;
-  char *z;
-  va_start(ap, zFmt);
-  z = sqlite3_vmprintf(zFmt, ap);
-  va_end(ap);
-  if( p->errCode==SQLITE_OK ){
-    if( z==0 ) p->errCode = SQLITE_NOMEM;
-  }else{
-    sqlite3_free(z);
-    z = 0;
-  }
-  return z;
-}
-
-/*
-** This function is a no-op if recover handle p already contains an error
-** (if p->errCode!=SQLITE_OK). Zero is returned in this case.
-**
-** Otherwise, execute "PRAGMA page_count" against the input database. If
-** successful, return the integer result. Or, if an error occurs, leave an
-** error code and error message in the sqlite3_recover handle and return
-** zero.
-*/
-static i64 recoverPageCount(sqlite3_recover *p){
-  i64 nPg = 0;
-  if( p->errCode==SQLITE_OK ){
-    sqlite3_stmt *pStmt = 0;
-    pStmt = recoverPreparePrintf(p, p->dbIn, "PRAGMA %Q.page_count", p->zDb);
-    if( pStmt ){
-      sqlite3_step(pStmt);
-      nPg = sqlite3_column_int64(pStmt, 0);
-    }
-    recoverFinalize(p, pStmt);
-  }
-  return nPg;
-}
-
-/*
-** Implementation of SQL scalar function "read_i32". 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.
-**
-**     SELECT read_i32(<blob>, <idx>)
-*/
-static void recoverReadI32(
-  sqlite3_context *context, 
-  int argc, 
-  sqlite3_value **argv
-){
-  const unsigned char *pBlob;
-  int nBlob;
-  int iInt;
-
-  assert( argc==2 );
-  nBlob = sqlite3_value_bytes(argv[0]);
-  pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
-  iInt = sqlite3_value_int(argv[1]) & 0xFFFF;
-
-  if( (iInt+1)*4<=nBlob ){
-    const unsigned char *a = &pBlob[iInt*4];
-    i64 iVal = ((i64)a[0]<<24)
-             + ((i64)a[1]<<16)
-             + ((i64)a[2]<< 8)
-             + ((i64)a[3]<< 0);
-    sqlite3_result_int64(context, iVal);
-  }
-}
-
-/*
-** Implementation of SQL scalar function "page_is_used". This function
-** is used as part of the procedure for locating orphan rows for the
-** lost-and-found table, and it depends on those routines having populated
-** the sqlite3_recover.laf.pUsed variable.
-**
-** The only argument to this function is a page-number. It returns true 
-** if the page has already been used somehow during data recovery, or false
-** otherwise.
-**
-**     SELECT page_is_used(<pgno>);
-*/
-static void recoverPageIsUsed(
-  sqlite3_context *pCtx,
-  int nArg,
-  sqlite3_value **apArg
-){
-  sqlite3_recover *p = (sqlite3_recover*)sqlite3_user_data(pCtx);
-  i64 pgno = sqlite3_value_int64(apArg[0]);
-  assert( nArg==1 );
-  sqlite3_result_int(pCtx, recoverBitmapQuery(p->laf.pUsed, pgno));
-}
-
-/*
-** The implementation of a user-defined SQL function invoked by the 
-** sqlite_dbdata and sqlite_dbptr virtual table modules to access pages
-** of the database being recovered.
-**
-** This function always takes a single integer argument. If the argument
-** is zero, then the value returned is the number of pages in the db being
-** recovered. If the argument is greater than zero, it is a page number. 
-** The value returned in this case is an SQL blob containing the data for 
-** the identified page of the db being recovered. e.g.
-**
-**     SELECT getpage(0);       -- return number of pages in db
-**     SELECT getpage(4);       -- return page 4 of db as a blob of data 
-*/
-static void recoverGetPage(
-  sqlite3_context *pCtx,
-  int nArg,
-  sqlite3_value **apArg
-){
-  sqlite3_recover *p = (sqlite3_recover*)sqlite3_user_data(pCtx);
-  i64 pgno = sqlite3_value_int64(apArg[0]);
-  sqlite3_stmt *pStmt = 0;
-
-  assert( nArg==1 );
-  if( pgno==0 ){
-    i64 nPg = recoverPageCount(p);
-    sqlite3_result_int64(pCtx, nPg);
-    return;
-  }else{
-    if( p->pGetPage==0 ){
-      pStmt = p->pGetPage = recoverPreparePrintf(
-          p, p->dbIn, "SELECT data FROM sqlite_dbpage(%Q) WHERE pgno=?", p->zDb
-      );
-    }else if( p->errCode==SQLITE_OK ){
-      pStmt = p->pGetPage;
-    }
-
-    if( pStmt ){
-      sqlite3_bind_int64(pStmt, 1, pgno);
-      if( SQLITE_ROW==sqlite3_step(pStmt) ){
-        const u8 *aPg;
-        int nPg;
-        assert( p->errCode==SQLITE_OK );
-        aPg = sqlite3_column_blob(pStmt, 0);
-        nPg = sqlite3_column_bytes(pStmt, 0);
-        if( pgno==1 && nPg==p->pgsz && 0==memcmp(p->pPage1Cache, aPg, nPg) ){
-          aPg = p->pPage1Disk;
-        }
-        sqlite3_result_blob(pCtx, aPg, nPg-p->nReserve, SQLITE_TRANSIENT);
-      }
-      recoverReset(p, pStmt);
-    }
-  }
-
-  if( p->errCode ){
-    if( p->zErrMsg ) sqlite3_result_error(pCtx, p->zErrMsg, -1);
-    sqlite3_result_error_code(pCtx, p->errCode);
-  }
-}
-
-/*
-** Find a string that is not found anywhere in z[].  Return a pointer
-** to that string.
-**
-** Try to use zA and zB first.  If both of those are already found in z[]
-** then make up some string and store it in the buffer zBuf.
-*/
-static const char *recoverUnusedString(
-  const char *z,                    /* Result must not appear anywhere in z */
-  const char *zA, const char *zB,   /* Try these first */
-  char *zBuf                        /* Space to store a generated string */
-){
-  unsigned i = 0;
-  if( strstr(z, zA)==0 ) return zA;
-  if( strstr(z, zB)==0 ) return zB;
-  do{
-    sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
-  }while( strstr(z,zBuf)!=0 );
-  return zBuf;
-}
-
-/*
-** Implementation of scalar SQL function "escape_crnl".  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 recoverEscapeCrnl(
-  sqlite3_context *context, 
-  int argc, 
-  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;
-    char zBuf1[20];
-    char zBuf2[20];
-    const char *zNL = 0;
-    const char *zCR = 0;
-    int nCR = 0;
-    int nNL = 0;
-
-    for(i=0; zText[i]; i++){
-      if( zNL==0 && zText[i]=='\n' ){
-        zNL = recoverUnusedString(zText, "\\n", "\\012", zBuf1);
-        nNL = (int)strlen(zNL);
-      }
-      if( zCR==0 && zText[i]=='\r' ){
-        zCR = recoverUnusedString(zText, "\\r", "\\015", zBuf2);
-        nCR = (int)strlen(zCR);
-      }
-    }
-
-    if( zNL || zCR ){
-      int 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]);
-}
-
-/*
-** This function is a no-op if recover handle p already contains an error
-** (if p->errCode!=SQLITE_OK). A copy of the error code is returned in
-** this case. 
-**
-** Otherwise, attempt to populate temporary table "recovery.schema" with the
-** parts of the database schema that can be extracted from the input database.
-**
-** If no error occurs, SQLITE_OK is returned. Otherwise, an error code
-** and error message are left in the recover handle and a copy of the
-** error code returned. It is not considered an error if part of all of
-** the database schema cannot be recovered due to corruption.
-*/
-static int recoverCacheSchema(sqlite3_recover *p){
-  return recoverExec(p, p->dbOut,
-    "WITH RECURSIVE pages(p) AS ("
-    "  SELECT 1"
-    "    UNION"
-    "  SELECT child FROM sqlite_dbptr('getpage()'), pages WHERE pgno=p"
-    ")"
-    "INSERT INTO recovery.schema SELECT"
-    "  max(CASE WHEN field=0 THEN value ELSE NULL END),"
-    "  max(CASE WHEN field=1 THEN value ELSE NULL END),"
-    "  max(CASE WHEN field=2 THEN value ELSE NULL END),"
-    "  max(CASE WHEN field=3 THEN value ELSE NULL END),"
-    "  max(CASE WHEN field=4 THEN value ELSE NULL END)"
-    "FROM sqlite_dbdata('getpage()') WHERE pgno IN ("
-    "  SELECT p FROM pages"
-    ") GROUP BY pgno, cell"
-  );
-}
-
-/*
-** If this recover handle is not in SQL callback mode (i.e. was not created 
-** using sqlite3_recover_init_sql()) of if an error has already occurred, 
-** this function is a no-op. Otherwise, issue a callback with SQL statement
-** zSql as the parameter. 
-**
-** If the callback returns non-zero, set the recover handle error code to
-** the value returned (so that the caller will abandon processing).
-*/
-static void recoverSqlCallback(sqlite3_recover *p, const char *zSql){
-  if( p->errCode==SQLITE_OK && p->xSql ){
-    int res = p->xSql(p->pSqlCtx, zSql);
-    if( res ){
-      recoverError(p, SQLITE_ERROR, "callback returned an error - %d", res);
-    }
-  }
-}
-
-/*
-** Transfer the following settings from the input database to the output
-** database:
-**
-**   + page-size,
-**   + auto-vacuum settings,
-**   + database encoding,
-**   + user-version (PRAGMA user_version), and
-**   + application-id (PRAGMA application_id), and
-*/
-static void recoverTransferSettings(sqlite3_recover *p){
-  const char *aPragma[] = {
-    "encoding",
-    "page_size",
-    "auto_vacuum",
-    "user_version",
-    "application_id"
-  };
-  int ii;
-
-  /* Truncate the output database to 0 pages in size. This is done by 
-  ** opening a new, empty, temp db, then using the backup API to clobber 
-  ** any existing output db with a copy of it. */
-  if( p->errCode==SQLITE_OK ){
-    sqlite3 *db2 = 0;
-    int rc = sqlite3_open("", &db2);
-    if( rc!=SQLITE_OK ){
-      recoverDbError(p, db2);
-      return;
-    }
-
-    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);
-      if( p->errCode==SQLITE_OK && sqlite3_step(p1)==SQLITE_ROW ){
-        const char *zArg = (const char*)sqlite3_column_text(p1, 0);
-        char *z2 = recoverMPrintf(p, "PRAGMA %s = %Q", zPrag, zArg);
-        recoverSqlCallback(p, z2);
-        recoverExec(p, db2, z2);
-        sqlite3_free(z2);
-        if( zArg==0 ){
-          recoverError(p, SQLITE_NOMEM, 0);
-        }
-      }
-      recoverFinalize(p, p1);
-    }
-    recoverExec(p, db2, "CREATE TABLE t1(a); DROP TABLE t1;");
-
-    if( p->errCode==SQLITE_OK ){
-      sqlite3 *db = p->dbOut;
-      sqlite3_backup *pBackup = sqlite3_backup_init(db, "main", db2, "main");
-      if( pBackup ){
-        sqlite3_backup_step(pBackup, -1);
-        p->errCode = sqlite3_backup_finish(pBackup);
-      }else{
-        recoverDbError(p, db);
-      }
-    }
-
-    sqlite3_close(db2);
-  }
-}
-
-/*
-** This function is a no-op if recover handle p already contains an error
-** (if p->errCode!=SQLITE_OK). A copy of the error code is returned in
-** this case. 
-**
-** Otherwise, an attempt is made to open the output database, attach
-** and create the schema of the temporary database used to store
-** intermediate data, and to register all required user functions and
-** virtual table modules with the output handle.
-**
-** If no error occurs, SQLITE_OK is returned. Otherwise, an error code
-** and error message are left in the recover handle and a copy of the
-** error code returned.
-*/
-static int recoverOpenOutput(sqlite3_recover *p){
-  struct Func {
-    const char *zName;
-    int nArg;
-    void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
-  } aFunc[] = {
-    { "getpage", 1, recoverGetPage },
-    { "page_is_used", 1, recoverPageIsUsed },
-    { "read_i32", 2, recoverReadI32 },
-    { "escape_crnl", 1, recoverEscapeCrnl },
-  };
-
-  const int flags = SQLITE_OPEN_URI|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE;
-  sqlite3 *db = 0;                /* New database handle */
-  int ii;                         /* For iterating through aFunc[] */
-
-  assert( p->dbOut==0 );
-
-  if( sqlite3_open_v2(p->zUri, &db, flags, 0) ){
-    recoverDbError(p, db);
-  }
-
-  /* Register the sqlite_dbdata and sqlite_dbptr virtual table modules.
-  ** These two are registered with the output database handle - this
-  ** module depends on the input handle supporting the sqlite_dbpage
-  ** virtual table only.  */
-  if( p->errCode==SQLITE_OK ){
-    p->errCode = sqlite3_dbdata_init(db, 0, 0);
-  }
-
-  /* Register the custom user-functions with the output handle. */
-  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
-    );
-  }
-
-  p->dbOut = db;
-  return p->errCode;
-}
-
-/*
-** Attach the auxiliary database 'recovery' to the output database handle.
-** This temporary database is used during the recovery process and then 
-** discarded.
-*/
-static void recoverOpenRecovery(sqlite3_recover *p){
-  char *zSql = recoverMPrintf(p, "ATTACH %Q AS recovery;", p->zStateDb);
-  recoverExec(p, p->dbOut, zSql);
-  recoverExec(p, p->dbOut,
-      "PRAGMA writable_schema = 1;"
-      "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT);" 
-      "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
-  );
-  sqlite3_free(zSql);
-}
-
-
-/*
-** This function is a no-op if recover handle p already contains an error
-** (if p->errCode!=SQLITE_OK).
-**
-** Otherwise, argument zName must be the name of a table that has just been
-** created in the output database. This function queries the output db
-** for the schema of said table, and creates a RecoverTable object to
-** store the schema in memory. The new RecoverTable object is linked into
-** the list at sqlite3_recover.pTblList.
-**
-** Parameter iRoot must be the root page of table zName in the INPUT 
-** database.
-*/
-static void recoverAddTable(
-  sqlite3_recover *p, 
-  const char *zName,              /* Name of table created in output db */
-  i64 iRoot                       /* Root page of same table in INPUT db */
-){
-  sqlite3_stmt *pStmt = recoverPreparePrintf(p, p->dbOut, 
-      "PRAGMA table_xinfo(%Q)", zName
-  );
-
-  if( pStmt ){
-    int iPk = -1;
-    int iBind = 1;
-    RecoverTable *pNew = 0;
-    int nCol = 0;
-    int nName = recoverStrlen(zName);
-    int nByte = 0;
-    while( sqlite3_step(pStmt)==SQLITE_ROW ){
-      nCol++;
-      nByte += (sqlite3_column_bytes(pStmt, 1)+1);
-    }
-    nByte += sizeof(RecoverTable) + nCol*sizeof(RecoverColumn) + nName+1;
-    recoverReset(p, pStmt);
-
-    pNew = recoverMalloc(p, nByte);
-    if( pNew ){
-      int i = 0;
-      int iField = 0;
-      char *csr = 0;
-      pNew->aCol = (RecoverColumn*)&pNew[1];
-      pNew->zTab = csr = (char*)&pNew->aCol[nCol];
-      pNew->nCol = nCol;
-      pNew->iRoot = iRoot;
-      memcpy(csr, zName, nName);
-      csr += nName+1;
-
-      for(i=0; sqlite3_step(pStmt)==SQLITE_ROW; i++){
-        int iPKF = sqlite3_column_int(pStmt, 5);
-        int n = sqlite3_column_bytes(pStmt, 1);
-        const char *z = (const char*)sqlite3_column_text(pStmt, 1);
-        const char *zType = (const char*)sqlite3_column_text(pStmt, 2);
-        int eHidden = sqlite3_column_int(pStmt, 6);
-
-        if( iPk==-1 && iPKF==1 && !sqlite3_stricmp("integer", zType) ) iPk = i;
-        if( iPKF>1 ) iPk = -2;
-        pNew->aCol[i].zCol = csr;
-        pNew->aCol[i].eHidden = eHidden;
-        if( eHidden==RECOVER_EHIDDEN_VIRTUAL ){
-          pNew->aCol[i].iField = -1;
-        }else{
-          pNew->aCol[i].iField = iField++;
-        }
-        if( eHidden!=RECOVER_EHIDDEN_VIRTUAL
-         && eHidden!=RECOVER_EHIDDEN_STORED
-        ){
-          pNew->aCol[i].iBind = iBind++;
-        }
-        memcpy(csr, z, n);
-        csr += (n+1);
-      }
-
-      pNew->pNext = p->pTblList;
-      p->pTblList = pNew;
-      pNew->bIntkey = 1;
-    }
-
-    recoverFinalize(p, pStmt);
-
-    pStmt = recoverPreparePrintf(p, p->dbOut, "PRAGMA index_xinfo(%Q)", zName);
-    while( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
-      int iField = sqlite3_column_int(pStmt, 0);
-      int iCol = sqlite3_column_int(pStmt, 1);
-
-      assert( iCol<pNew->nCol );
-      pNew->aCol[iCol].iField = iField;
-
-      pNew->bIntkey = 0;
-      iPk = -2;
-    }
-    recoverFinalize(p, pStmt);
-
-    if( p->errCode==SQLITE_OK ){
-      if( iPk>=0 ){
-        pNew->aCol[iPk].bIPK = 1;
-      }else if( pNew->bIntkey ){
-        pNew->iRowidBind = iBind++;
-      }
-    }
-  }
-}
-
-/*
-** This function is called after recoverCacheSchema() has cached those parts
-** of the input database schema that could be recovered in temporary table
-** "recovery.schema". This function creates in the output database copies
-** of all parts of that schema that must be created before the tables can
-** be populated. Specifically, this means:
-**
-**     * all tables that are not VIRTUAL, and
-**     * UNIQUE indexes.
-**
-** If the recovery handle uses SQL callbacks, then callbacks containing
-** the associated "CREATE TABLE" and "CREATE INDEX" statements are made.
-**
-** Additionally, records are added to the sqlite_schema table of the
-** output database for any VIRTUAL tables. The CREATE VIRTUAL TABLE
-** records are written directly to sqlite_schema, not actually executed.
-** If the handle is in SQL callback mode, then callbacks are invoked 
-** with equivalent SQL statements.
-*/
-static int recoverWriteSchema1(sqlite3_recover *p){
-  sqlite3_stmt *pSelect = 0;
-  sqlite3_stmt *pTblname = 0;
-
-  pSelect = recoverPrepare(p, p->dbOut,
-      "WITH dbschema(rootpage, name, sql, tbl, isVirtual, isIndex) AS ("
-      "  SELECT rootpage, name, sql, "
-      "    type='table', "
-      "    sql LIKE 'create virtual%',"
-      "    (type='index' AND (sql LIKE '%unique%' OR ?1))"
-      "  FROM recovery.schema"
-      ")"
-      "SELECT rootpage, tbl, isVirtual, name, sql"
-      " FROM dbschema "
-      "  WHERE tbl OR isIndex"
-      "  ORDER BY tbl DESC, name=='sqlite_sequence' DESC"
-  );
-
-  pTblname = recoverPrepare(p, p->dbOut,
-      "SELECT name FROM sqlite_schema "
-      "WHERE type='table' ORDER BY rowid DESC LIMIT 1"
-  );
-
-  if( pSelect ){
-    sqlite3_bind_int(pSelect, 1, p->bSlowIndexes);
-    while( sqlite3_step(pSelect)==SQLITE_ROW ){
-      i64 iRoot = sqlite3_column_int64(pSelect, 0);
-      int bTable = sqlite3_column_int(pSelect, 1);
-      int bVirtual = sqlite3_column_int(pSelect, 2);
-      const char *zName = (const char*)sqlite3_column_text(pSelect, 3);
-      const char *zSql = (const char*)sqlite3_column_text(pSelect, 4);
-      char *zFree = 0;
-      int rc = SQLITE_OK;
-
-      if( bVirtual ){
-        zSql = (const char*)(zFree = recoverMPrintf(p,
-            "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
-            zName, zName, zSql
-        ));
-      }
-      rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0);
-      if( rc==SQLITE_OK ){
-        recoverSqlCallback(p, zSql);
-        if( bTable && !bVirtual ){
-          if( SQLITE_ROW==sqlite3_step(pTblname) ){
-            const char *zTbl = (const char*)sqlite3_column_text(pTblname, 0);
-            recoverAddTable(p, zTbl, iRoot);
-          }
-          recoverReset(p, pTblname);
-        }
-      }else if( rc!=SQLITE_ERROR ){
-        recoverDbError(p, p->dbOut);
-      }
-      sqlite3_free(zFree);
-    }
-  }
-  recoverFinalize(p, pSelect);
-  recoverFinalize(p, pTblname);
-
-  return p->errCode;
-}
-
-/*
-** This function is called after the output database has been populated. It
-** adds all recovered schema elements that were not created in the output
-** database by recoverWriteSchema1() - everything except for tables and
-** UNIQUE indexes. Specifically:
-**
-**     * views,
-**     * triggers,
-**     * non-UNIQUE indexes.
-**
-** If the recover handle is in SQL callback mode, then equivalent callbacks
-** are issued to create the schema elements.
-*/
-static int recoverWriteSchema2(sqlite3_recover *p){
-  sqlite3_stmt *pSelect = 0;
-
-  pSelect = recoverPrepare(p, p->dbOut,
-      p->bSlowIndexes ?
-      "SELECT rootpage, sql FROM recovery.schema "
-      "  WHERE type!='table' AND type!='index'"
-      :
-      "SELECT rootpage, sql FROM recovery.schema "
-      "  WHERE type!='table' AND (type!='index' OR sql NOT LIKE '%unique%')"
-  );
-
-  if( pSelect ){
-    while( sqlite3_step(pSelect)==SQLITE_ROW ){
-      const char *zSql = (const char*)sqlite3_column_text(pSelect, 1);
-      int rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0);
-      if( rc==SQLITE_OK ){
-        recoverSqlCallback(p, zSql);
-      }else if( rc!=SQLITE_ERROR ){
-        recoverDbError(p, p->dbOut);
-      }
-    }
-  }
-  recoverFinalize(p, pSelect);
-
-  return p->errCode;
-}
-
-/*
-** This function is a no-op if recover handle p already contains an error
-** (if p->errCode!=SQLITE_OK). In this case it returns NULL.
-**
-** Otherwise, if the recover handle is configured to create an output
-** database (was created by sqlite3_recover_init()), then this function
-** prepares and returns an SQL statement to INSERT a new record into table
-** pTab, assuming the first nField fields of a record extracted from disk
-** are valid.
-**
-** For example, if table pTab is:
-**
-**     CREATE TABLE name(a, b GENERATED ALWAYS AS (a+1) STORED, c, d, e);
-**
-** And nField is 4, then the SQL statement prepared and returned is:
-**
-**     INSERT INTO (a, c, d) VALUES (?1, ?2, ?3);
-**
-** In this case even though 4 values were extracted from the input db,
-** only 3 are written to the output, as the generated STORED column 
-** cannot be written.
-**
-** If the recover handle is in SQL callback mode, then the SQL statement
-** prepared is such that evaluating it returns a single row containing
-** a single text value - itself an SQL statement similar to the above,
-** except with SQL literals in place of the variables. For example:
-**
-**     SELECT 'INSERT INTO (a, c, d) VALUES (' 
-**          || quote(?1) || ', '
-**          || quote(?2) || ', '
-**          || quote(?3) || ')';
-**
-** In either case, it is the responsibility of the caller to eventually
-** free the statement handle using sqlite3_finalize().
-*/
-static sqlite3_stmt *recoverInsertStmt(
-  sqlite3_recover *p, 
-  RecoverTable *pTab,
-  int nField
-){
-  sqlite3_stmt *pRet = 0;
-  const char *zSep = "";
-  const char *zSqlSep = "";
-  char *zSql = 0;
-  char *zFinal = 0;
-  char *zBind = 0;
-  int ii;
-  int bSql = p->xSql ? 1 : 0;
-
-  if( nField<=0 ) return 0;
-
-  assert( nField<=pTab->nCol );
-
-  zSql = recoverMPrintf(p, "INSERT OR IGNORE INTO %Q(", pTab->zTab);
-
-  if( pTab->iRowidBind ){
-    assert( pTab->bIntkey );
-    zSql = recoverMPrintf(p, "%z_rowid_", zSql);
-    if( bSql ){
-      zBind = recoverMPrintf(p, "%zquote(?%d)", zBind, pTab->iRowidBind);
-    }else{
-      zBind = recoverMPrintf(p, "%z?%d", zBind, pTab->iRowidBind);
-    }
-    zSqlSep = "||', '||";
-    zSep = ", ";
-  }
-
-  for(ii=0; ii<nField; ii++){
-    int eHidden = pTab->aCol[ii].eHidden;
-    if( eHidden!=RECOVER_EHIDDEN_VIRTUAL
-     && eHidden!=RECOVER_EHIDDEN_STORED
-    ){
-      assert( pTab->aCol[ii].iField>=0 && pTab->aCol[ii].iBind>=1 );
-      zSql = recoverMPrintf(p, "%z%s%Q", zSql, zSep, pTab->aCol[ii].zCol);
-
-      if( bSql ){
-        zBind = recoverMPrintf(p, 
-            "%z%sescape_crnl(quote(?%d))", zBind, zSqlSep, pTab->aCol[ii].iBind
-        );
-        zSqlSep = "||', '||";
-      }else{
-        zBind = recoverMPrintf(p, "%z%s?%d", zBind, zSep, pTab->aCol[ii].iBind);
-      }
-      zSep = ", ";
-    }
-  }
-
-  if( bSql ){
-    zFinal = recoverMPrintf(p, "SELECT %Q || ') VALUES (' || %s || ')'", 
-        zSql, zBind
-    );
-  }else{
-    zFinal = recoverMPrintf(p, "%s) VALUES (%s)", zSql, zBind);
-  }
-
-  pRet = recoverPrepare(p, p->dbOut, zFinal);
-  sqlite3_free(zSql);
-  sqlite3_free(zBind);
-  sqlite3_free(zFinal);
-  
-  return pRet;
-}
-
-
-/*
-** Search the list of RecoverTable objects at p->pTblList for one that
-** has root page iRoot in the input database. If such an object is found,
-** return a pointer to it. Otherwise, return NULL.
-*/
-static RecoverTable *recoverFindTable(sqlite3_recover *p, u32 iRoot){
-  RecoverTable *pRet = 0;
-  for(pRet=p->pTblList; pRet && pRet->iRoot!=iRoot; pRet=pRet->pNext);
-  return pRet;
-}
-
-/*
-** This function attempts to create a lost and found table within the 
-** output db. If successful, it returns a pointer to a buffer containing
-** the name of the new table. It is the responsibility of the caller to
-** eventually free this buffer using sqlite3_free().
-**
-** If an error occurs, NULL is returned and an error code and error 
-** message left in the recover handle.
-*/
-static char *recoverLostAndFoundCreate(
-  sqlite3_recover *p,             /* Recover object */
-  int nField                      /* Number of column fields in new table */
-){
-  char *zTbl = 0;
-  sqlite3_stmt *pProbe = 0;
-  int ii = 0;
-
-  pProbe = recoverPrepare(p, p->dbOut,
-    "SELECT 1 FROM sqlite_schema WHERE name=?"
-  );
-  for(ii=-1; zTbl==0 && p->errCode==SQLITE_OK && ii<1000; ii++){
-    int bFail = 0;
-    if( ii<0 ){
-      zTbl = recoverMPrintf(p, "%s", p->zLostAndFound);
-    }else{
-      zTbl = recoverMPrintf(p, "%s_%d", p->zLostAndFound, ii);
-    }
-
-    if( p->errCode==SQLITE_OK ){
-      sqlite3_bind_text(pProbe, 1, zTbl, -1, SQLITE_STATIC);
-      if( SQLITE_ROW==sqlite3_step(pProbe) ){
-        bFail = 1;
-      }
-      recoverReset(p, pProbe);
-    }
-
-    if( bFail ){
-      sqlite3_clear_bindings(pProbe);
-      sqlite3_free(zTbl);
-      zTbl = 0;
-    }
-  }
-  recoverFinalize(p, pProbe);
-
-  if( zTbl ){
-    const char *zSep = 0;
-    char *zField = 0;
-    char *zSql = 0;
-
-    zSep = "rootpgno INTEGER, pgno INTEGER, nfield INTEGER, id INTEGER, ";
-    for(ii=0; p->errCode==SQLITE_OK && ii<nField; ii++){
-      zField = recoverMPrintf(p, "%z%sc%d", zField, zSep, ii);
-      zSep = ", ";
-    }
-
-    zSql = recoverMPrintf(p, "CREATE TABLE %s(%s)", zTbl, zField);
-    sqlite3_free(zField);
-
-    recoverExec(p, p->dbOut, zSql);
-    recoverSqlCallback(p, zSql);
-    sqlite3_free(zSql);
-  }else if( p->errCode==SQLITE_OK ){
-    recoverError(
-        p, SQLITE_ERROR, "failed to create %s output table", p->zLostAndFound
-    );
-  }
-
-  return zTbl;
-}
-
-/*
-** Synthesize and prepare an INSERT statement to write to the lost_and_found
-** table in the output database. The name of the table is zTab, and it has
-** nField c* fields.
-*/
-static sqlite3_stmt *recoverLostAndFoundInsert(
-  sqlite3_recover *p,
-  const char *zTab,
-  int nField
-){
-  int nTotal = nField + 4;
-  int ii;
-  char *zBind = 0;
-  sqlite3_stmt *pRet = 0;
-
-  if( p->xSql==0 ){
-    for(ii=0; ii<nTotal; ii++){
-      zBind = recoverMPrintf(p, "%z%s?", zBind, zBind?", ":"", ii);
-    }
-    pRet = recoverPreparePrintf(
-        p, p->dbOut, "INSERT INTO %s VALUES(%s)", zTab, zBind
-    );
-  }else{
-    const char *zSep = "";
-    for(ii=0; ii<nTotal; ii++){
-      zBind = recoverMPrintf(p, "%z%squote(?)", zBind, zSep);
-      zSep = "|| ', ' ||";
-    }
-    pRet = recoverPreparePrintf(
-        p, p->dbOut, "SELECT 'INSERT INTO %s VALUES(' || %s || ')'", zTab, zBind
-    );
-  }
-
-  sqlite3_free(zBind);
-  return pRet;
-}
-
-/*
-** Input database page iPg contains data that will be written to the
-** lost-and-found table of the output database. This function attempts
-** to identify the root page of the tree that page iPg belonged to.
-** If successful, it sets output variable (*piRoot) to the page number
-** of the root page and returns SQLITE_OK. Otherwise, if an error occurs,
-** an SQLite error code is returned and the final value of *piRoot 
-** undefined.
-*/
-static int recoverLostAndFoundFindRoot(
-  sqlite3_recover *p, 
-  i64 iPg,
-  i64 *piRoot
-){
-  RecoverStateLAF *pLaf = &p->laf;
-
-  if( pLaf->pFindRoot==0 ){
-    pLaf->pFindRoot = recoverPrepare(p, p->dbOut,
-        "WITH RECURSIVE p(pgno) AS ("
-        "  SELECT ?"
-        "    UNION"
-        "  SELECT parent FROM recovery.map AS m, p WHERE m.pgno=p.pgno"
-        ") "
-        "SELECT p.pgno FROM p, recovery.map m WHERE m.pgno=p.pgno "
-        "    AND m.parent IS NULL"
-    );
-  }
-  if( p->errCode==SQLITE_OK ){
-    sqlite3_bind_int64(pLaf->pFindRoot, 1, iPg);
-    if( sqlite3_step(pLaf->pFindRoot)==SQLITE_ROW ){
-      *piRoot = sqlite3_column_int64(pLaf->pFindRoot, 0);
-    }else{
-      *piRoot = iPg;
-    }
-    recoverReset(p, pLaf->pFindRoot);
-  }
-  return p->errCode;
-}
-
-/*
-** Recover data from page iPage of the input database and write it to
-** the lost-and-found table in the output database.
-*/
-static void recoverLostAndFoundOnePage(sqlite3_recover *p, i64 iPage){
-  RecoverStateLAF *pLaf = &p->laf;
-  sqlite3_value **apVal = pLaf->apVal;
-  sqlite3_stmt *pPageData = pLaf->pPageData;
-  sqlite3_stmt *pInsert = pLaf->pInsert;
-
-  int nVal = -1;
-  int iPrevCell = 0;
-  i64 iRoot = 0;
-  int bHaveRowid = 0;
-  i64 iRowid = 0;
-  int ii = 0;
-
-  if( recoverLostAndFoundFindRoot(p, iPage, &iRoot) ) return;
-  sqlite3_bind_int64(pPageData, 1, iPage);
-  while( p->errCode==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPageData) ){
-    int iCell = sqlite3_column_int64(pPageData, 0);
-    int iField = sqlite3_column_int64(pPageData, 1);
-
-    if( iPrevCell!=iCell && nVal>=0 ){
-      /* Insert the new row */
-      sqlite3_bind_int64(pInsert, 1, iRoot);      /* rootpgno */
-      sqlite3_bind_int64(pInsert, 2, iPage);      /* pgno */
-      sqlite3_bind_int(pInsert, 3, nVal);         /* nfield */
-      if( bHaveRowid ){
-        sqlite3_bind_int64(pInsert, 4, iRowid);   /* id */
-      }
-      for(ii=0; ii<nVal; ii++){
-        recoverBindValue(p, pInsert, 5+ii, apVal[ii]);
-      }
-      if( sqlite3_step(pInsert)==SQLITE_ROW ){
-        recoverSqlCallback(p, (const char*)sqlite3_column_text(pInsert, 0));
-      }
-      recoverReset(p, pInsert);
-
-      /* Discard the accumulated row data */
-      for(ii=0; ii<nVal; ii++){
-        sqlite3_value_free(apVal[ii]);
-        apVal[ii] = 0;
-      }
-      sqlite3_clear_bindings(pInsert);
-      bHaveRowid = 0;
-      nVal = -1;
-    }
-
-    if( iCell<0 ) break;
-
-    if( iField<0 ){
-      assert( nVal==-1 );
-      iRowid = sqlite3_column_int64(pPageData, 2);
-      bHaveRowid = 1;
-      nVal = 0;
-    }else if( iField<pLaf->nMaxField ){
-      sqlite3_value *pVal = sqlite3_column_value(pPageData, 2);
-      apVal[iField] = sqlite3_value_dup(pVal);
-      assert( iField==nVal || (nVal==-1 && iField==0) );
-      nVal = iField+1;
-      if( apVal[iField]==0 ){
-        recoverError(p, SQLITE_NOMEM, 0);
-      }
-    }
-
-    iPrevCell = iCell;
-  }
-  recoverReset(p, pPageData);
-
-  for(ii=0; ii<nVal; ii++){
-    sqlite3_value_free(apVal[ii]);
-    apVal[ii] = 0;
-  }
-}
-
-/*
-** Perform one step (sqlite3_recover_step()) of work for the connection 
-** passed as the only argument, which is guaranteed to be in
-** RECOVER_STATE_LOSTANDFOUND3 state - during which the lost-and-found 
-** table of the output database is populated with recovered data that can 
-** not be assigned to any recovered schema object.
-*/ 
-static int recoverLostAndFound3Step(sqlite3_recover *p){
-  RecoverStateLAF *pLaf = &p->laf;
-  if( p->errCode==SQLITE_OK ){
-    if( pLaf->pInsert==0 ){
-      return SQLITE_DONE;
-    }else{
-      if( p->errCode==SQLITE_OK ){
-        int res = sqlite3_step(pLaf->pAllPage);
-        if( res==SQLITE_ROW ){
-          i64 iPage = sqlite3_column_int64(pLaf->pAllPage, 0);
-          if( recoverBitmapQuery(pLaf->pUsed, iPage)==0 ){
-            recoverLostAndFoundOnePage(p, iPage);
-          }
-        }else{
-          recoverReset(p, pLaf->pAllPage);
-          return SQLITE_DONE;
-        }
-      }
-    }
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Initialize resources required in RECOVER_STATE_LOSTANDFOUND3 
-** state - during which the lost-and-found table of the output database 
-** is populated with recovered data that can not be assigned to any 
-** recovered schema object.
-*/ 
-static void recoverLostAndFound3Init(sqlite3_recover *p){
-  RecoverStateLAF *pLaf = &p->laf;
-
-  if( pLaf->nMaxField>0 ){
-    char *zTab = 0;               /* Name of lost_and_found table */
-
-    zTab = recoverLostAndFoundCreate(p, pLaf->nMaxField);
-    pLaf->pInsert = recoverLostAndFoundInsert(p, zTab, pLaf->nMaxField);
-    sqlite3_free(zTab);
-
-    pLaf->pAllPage = recoverPreparePrintf(p, p->dbOut,
-        "WITH RECURSIVE seq(ii) AS ("
-        "  SELECT 1 UNION ALL SELECT ii+1 FROM seq WHERE ii<%lld"
-        ")"
-        "SELECT ii FROM seq" , p->laf.nPg
-    );
-    pLaf->pPageData = recoverPrepare(p, p->dbOut,
-        "SELECT cell, field, value "
-        "FROM sqlite_dbdata('getpage()') d WHERE d.pgno=? "
-        "UNION ALL "
-        "SELECT -1, -1, -1"
-    );
-
-    pLaf->apVal = (sqlite3_value**)recoverMalloc(p, 
-        pLaf->nMaxField*sizeof(sqlite3_value*)
-    );
-  }
-}
-
-/*
-** Initialize resources required in RECOVER_STATE_WRITING state - during which
-** tables recovered from the schema of the input database are populated with
-** recovered data.
-*/ 
-static int recoverWriteDataInit(sqlite3_recover *p){
-  RecoverStateW1 *p1 = &p->w1;
-  RecoverTable *pTbl = 0;
-  int nByte = 0;
-
-  /* Figure out the maximum number of columns for any table in the schema */
-  assert( p1->nMax==0 );
-  for(pTbl=p->pTblList; pTbl; pTbl=pTbl->pNext){
-    if( pTbl->nCol>p1->nMax ) p1->nMax = pTbl->nCol;
-  }
-
-  /* Allocate an array of (sqlite3_value*) in which to accumulate the values
-  ** that will be written to the output database in a single row. */
-  nByte = sizeof(sqlite3_value*) * (p1->nMax+1);
-  p1->apVal = (sqlite3_value**)recoverMalloc(p, nByte);
-  if( p1->apVal==0 ) return p->errCode;
-
-  /* Prepare the SELECT to loop through schema tables (pTbls) and the SELECT
-  ** to loop through cells that appear to belong to a single table (pSel). */
-  p1->pTbls = recoverPrepare(p, p->dbOut,
-      "SELECT rootpage FROM recovery.schema "
-      "  WHERE type='table' AND (sql NOT LIKE 'create virtual%')"
-      "  ORDER BY (tbl_name='sqlite_sequence') ASC"
-  );
-  p1->pSel = recoverPrepare(p, p->dbOut, 
-      "WITH RECURSIVE pages(page) AS ("
-      "  SELECT ?1"
-      "    UNION"
-      "  SELECT child FROM sqlite_dbptr('getpage()'), pages "
-      "    WHERE pgno=page"
-      ") "
-      "SELECT page, cell, field, value "
-      "FROM sqlite_dbdata('getpage()') d, pages p WHERE p.page=d.pgno "
-      "UNION ALL "
-      "SELECT 0, 0, 0, 0"
-  );
-
-  return p->errCode;
-}
-
-/*
-** Clean up resources allocated by recoverWriteDataInit() (stuff in 
-** sqlite3_recover.w1).
-*/
-static void recoverWriteDataCleanup(sqlite3_recover *p){
-  RecoverStateW1 *p1 = &p->w1;
-  int ii;
-  for(ii=0; ii<p1->nVal; ii++){
-    sqlite3_value_free(p1->apVal[ii]);
-  }
-  sqlite3_free(p1->apVal);
-  recoverFinalize(p, p1->pInsert);
-  recoverFinalize(p, p1->pTbls);
-  recoverFinalize(p, p1->pSel);
-  memset(p1, 0, sizeof(*p1));
-}
-
-/*
-** Perform one step (sqlite3_recover_step()) of work for the connection 
-** passed as the only argument, which is guaranteed to be in
-** RECOVER_STATE_WRITING state - during which tables recovered from the
-** schema of the input database are populated with recovered data.
-*/ 
-static int recoverWriteDataStep(sqlite3_recover *p){
-  RecoverStateW1 *p1 = &p->w1;
-  sqlite3_stmt *pSel = p1->pSel;
-  sqlite3_value **apVal = p1->apVal;
-
-  if( p->errCode==SQLITE_OK && p1->pTab==0 ){
-    if( sqlite3_step(p1->pTbls)==SQLITE_ROW ){
-      i64 iRoot = sqlite3_column_int64(p1->pTbls, 0);
-      p1->pTab = recoverFindTable(p, iRoot);
-
-      recoverFinalize(p, p1->pInsert);
-      p1->pInsert = 0;
-
-      /* If this table is unknown, return early. The caller will invoke this
-      ** function again and it will move on to the next table.  */
-      if( p1->pTab==0 ) return p->errCode;
-
-      /* If this is the sqlite_sequence table, delete any rows added by
-      ** earlier INSERT statements on tables with AUTOINCREMENT primary
-      ** keys before recovering its contents. The p1->pTbls SELECT statement
-      ** is rigged to deliver "sqlite_sequence" last of all, so we don't
-      ** worry about it being modified after it is recovered. */
-      if( sqlite3_stricmp("sqlite_sequence", p1->pTab->zTab)==0 ){
-        recoverExec(p, p->dbOut, "DELETE FROM sqlite_sequence");
-        recoverSqlCallback(p, "DELETE FROM sqlite_sequence");
-      }
-
-      /* Bind the root page of this table within the original database to 
-      ** SELECT statement p1->pSel. The SELECT statement will then iterate
-      ** through cells that look like they belong to table pTab.  */
-      sqlite3_bind_int64(pSel, 1, iRoot);
-
-      p1->nVal = 0;
-      p1->bHaveRowid = 0;
-      p1->iPrevPage = -1;
-      p1->iPrevCell = -1;
-    }else{
-      return SQLITE_DONE;
-    }
-  }
-  assert( p->errCode!=SQLITE_OK || p1->pTab );
-
-  if( p->errCode==SQLITE_OK && sqlite3_step(pSel)==SQLITE_ROW ){
-    RecoverTable *pTab = p1->pTab;
-
-    i64 iPage = sqlite3_column_int64(pSel, 0);
-    int iCell = sqlite3_column_int(pSel, 1);
-    int iField = sqlite3_column_int(pSel, 2);
-    sqlite3_value *pVal = sqlite3_column_value(pSel, 3);
-    int bNewCell = (p1->iPrevPage!=iPage || p1->iPrevCell!=iCell);
-
-    assert( bNewCell==0 || (iField==-1 || iField==0) );
-    assert( bNewCell || iField==p1->nVal || p1->nVal==pTab->nCol );
-
-    if( bNewCell ){
-      int ii = 0;
-      if( p1->nVal>=0 ){
-        if( p1->pInsert==0 || p1->nVal!=p1->nInsert ){
-          recoverFinalize(p, p1->pInsert);
-          p1->pInsert = recoverInsertStmt(p, pTab, p1->nVal);
-          p1->nInsert = p1->nVal;
-        }
-        if( p1->nVal>0 ){
-          sqlite3_stmt *pInsert = p1->pInsert;
-          for(ii=0; ii<pTab->nCol; ii++){
-            RecoverColumn *pCol = &pTab->aCol[ii];
-            int iBind = pCol->iBind;
-            if( iBind>0 ){
-              if( pCol->bIPK ){
-                sqlite3_bind_int64(pInsert, iBind, p1->iRowid);
-              }else if( pCol->iField<p1->nVal ){
-                recoverBindValue(p, pInsert, iBind, apVal[pCol->iField]);
-              }
-            }
-          }
-          if( p->bRecoverRowid && pTab->iRowidBind>0 && p1->bHaveRowid ){
-            sqlite3_bind_int64(pInsert, pTab->iRowidBind, p1->iRowid);
-          }
-          if( SQLITE_ROW==sqlite3_step(pInsert) ){
-            const char *z = (const char*)sqlite3_column_text(pInsert, 0);
-            recoverSqlCallback(p, z);
-          }
-          recoverReset(p, pInsert);
-          assert( p->errCode || pInsert );
-          if( pInsert ) sqlite3_clear_bindings(pInsert);
-        }
-      }
-
-      for(ii=0; ii<p1->nVal; ii++){
-        sqlite3_value_free(apVal[ii]);
-        apVal[ii] = 0;
-      }
-      p1->nVal = -1;
-      p1->bHaveRowid = 0;
-    }
-
-    if( iPage!=0 ){
-      if( iField<0 ){
-        p1->iRowid = sqlite3_column_int64(pSel, 3);
-        assert( p1->nVal==-1 );
-        p1->nVal = 0;
-        p1->bHaveRowid = 1;
-      }else if( iField<pTab->nCol ){
-        assert( apVal[iField]==0 );
-        apVal[iField] = sqlite3_value_dup( pVal );
-        if( apVal[iField]==0 ){
-          recoverError(p, SQLITE_NOMEM, 0);
-        }
-        p1->nVal = iField+1;
-      }
-      p1->iPrevCell = iCell;
-      p1->iPrevPage = iPage;
-    }
-  }else{
-    recoverReset(p, pSel);
-    p1->pTab = 0;
-  }
-
-  return p->errCode;
-}
-
-/*
-** Initialize resources required by sqlite3_recover_step() in
-** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not
-** already allocated to a recovered schema element is determined.
-*/ 
-static void recoverLostAndFound1Init(sqlite3_recover *p){
-  RecoverStateLAF *pLaf = &p->laf;
-  sqlite3_stmt *pStmt = 0;
-
-  assert( p->laf.pUsed==0 );
-  pLaf->nPg = recoverPageCount(p);
-  pLaf->pUsed = recoverBitmapAlloc(p, pLaf->nPg);
-
-  /* Prepare a statement to iterate through all pages that are part of any tree
-  ** in the recoverable part of the input database schema to the bitmap. And,
-  ** if !p->bFreelistCorrupt, add all pages that appear to be part of the
-  ** freelist.  */
-  pStmt = recoverPrepare(
-      p, p->dbOut,
-      "WITH trunk(pgno) AS ("
-      "  SELECT read_i32(getpage(1), 8) AS x WHERE x>0"
-      "    UNION"
-      "  SELECT read_i32(getpage(trunk.pgno), 0) AS x FROM trunk WHERE x>0"
-      "),"
-      "trunkdata(pgno, data) AS ("
-      "  SELECT pgno, getpage(pgno) FROM trunk"
-      "),"
-      "freelist(data, n, freepgno) AS ("
-      "  SELECT data, min(16384, read_i32(data, 1)-1), pgno FROM trunkdata"
-      "    UNION ALL"
-      "  SELECT data, n-1, read_i32(data, 2+n) FROM freelist WHERE n>=0"
-      "),"
-      ""
-      "roots(r) AS ("
-      "  SELECT 1 UNION ALL"
-      "  SELECT rootpage FROM recovery.schema WHERE rootpage>0"
-      "),"
-      "used(page) AS ("
-      "  SELECT r FROM roots"
-      "    UNION"
-      "  SELECT child FROM sqlite_dbptr('getpage()'), used "
-      "    WHERE pgno=page"
-      ") "
-      "SELECT page FROM used"
-      " UNION ALL "
-      "SELECT freepgno FROM freelist WHERE NOT ?"
-  );
-  if( pStmt ) sqlite3_bind_int(pStmt, 1, p->bFreelistCorrupt);
-  pLaf->pUsedPages = pStmt;
-}
-
-/*
-** Perform one step (sqlite3_recover_step()) of work for the connection 
-** passed as the only argument, which is guaranteed to be in
-** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not
-** already allocated to a recovered schema element is determined.
-*/ 
-static int recoverLostAndFound1Step(sqlite3_recover *p){
-  RecoverStateLAF *pLaf = &p->laf;
-  int rc = p->errCode;
-  if( rc==SQLITE_OK ){
-    rc = sqlite3_step(pLaf->pUsedPages);
-    if( rc==SQLITE_ROW ){
-      i64 iPg = sqlite3_column_int64(pLaf->pUsedPages, 0);
-      recoverBitmapSet(pLaf->pUsed, iPg);
-      rc = SQLITE_OK;
-    }else{
-      recoverFinalize(p, pLaf->pUsedPages);
-      pLaf->pUsedPages = 0;
-    }
-  }
-  return rc;
-}
-
-/*
-** Initialize resources required by RECOVER_STATE_LOSTANDFOUND2 
-** state - during which the pages identified in RECOVER_STATE_LOSTANDFOUND1
-** are sorted into sets that likely belonged to the same database tree.
-*/ 
-static void recoverLostAndFound2Init(sqlite3_recover *p){
-  RecoverStateLAF *pLaf = &p->laf;
-
-  assert( p->laf.pAllAndParent==0 );
-  assert( p->laf.pMapInsert==0 );
-  assert( p->laf.pMaxField==0 );
-  assert( p->laf.nMaxField==0 );
-
-  pLaf->pMapInsert = recoverPrepare(p, p->dbOut,
-      "INSERT OR IGNORE INTO recovery.map(pgno, parent) VALUES(?, ?)"
-  );
-  pLaf->pAllAndParent = recoverPreparePrintf(p, p->dbOut,
-      "WITH RECURSIVE seq(ii) AS ("
-      "  SELECT 1 UNION ALL SELECT ii+1 FROM seq WHERE ii<%lld"
-      ")"
-      "SELECT pgno, child FROM sqlite_dbptr('getpage()') "
-      " UNION ALL "
-      "SELECT NULL, ii FROM seq", p->laf.nPg
-  );
-  pLaf->pMaxField = recoverPreparePrintf(p, p->dbOut,
-      "SELECT max(field)+1 FROM sqlite_dbdata('getpage') WHERE pgno = ?"
-  );
-}
-
-/*
-** Perform one step (sqlite3_recover_step()) of work for the connection 
-** passed as the only argument, which is guaranteed to be in
-** RECOVER_STATE_LOSTANDFOUND2 state - during which the pages identified 
-** in RECOVER_STATE_LOSTANDFOUND1 are sorted into sets that likely belonged 
-** to the same database tree.
-*/ 
-static int recoverLostAndFound2Step(sqlite3_recover *p){
-  RecoverStateLAF *pLaf = &p->laf;
-  if( p->errCode==SQLITE_OK ){
-    int res = sqlite3_step(pLaf->pAllAndParent);
-    if( res==SQLITE_ROW ){
-      i64 iChild = sqlite3_column_int(pLaf->pAllAndParent, 1);
-      if( recoverBitmapQuery(pLaf->pUsed, iChild)==0 ){
-        sqlite3_bind_int64(pLaf->pMapInsert, 1, iChild);
-        sqlite3_bind_value(pLaf->pMapInsert, 2, 
-            sqlite3_column_value(pLaf->pAllAndParent, 0)
-        );
-        sqlite3_step(pLaf->pMapInsert);
-        recoverReset(p, pLaf->pMapInsert);
-        sqlite3_bind_int64(pLaf->pMaxField, 1, iChild);
-        if( SQLITE_ROW==sqlite3_step(pLaf->pMaxField) ){
-          int nMax = sqlite3_column_int(pLaf->pMaxField, 0);
-          if( nMax>pLaf->nMaxField ) pLaf->nMaxField = nMax;
-        }
-        recoverReset(p, pLaf->pMaxField);
-      }
-    }else{
-      recoverFinalize(p, pLaf->pAllAndParent);
-      pLaf->pAllAndParent =0;
-      return SQLITE_DONE;
-    }
-  }
-  return p->errCode;
-}
-
-/*
-** Free all resources allocated as part of sqlite3_recover_step() calls
-** in one of the RECOVER_STATE_LOSTANDFOUND[123] states.
-*/
-static void recoverLostAndFoundCleanup(sqlite3_recover *p){
-  recoverBitmapFree(p->laf.pUsed);
-  p->laf.pUsed = 0;
-  sqlite3_finalize(p->laf.pUsedPages);
-  sqlite3_finalize(p->laf.pAllAndParent);
-  sqlite3_finalize(p->laf.pMapInsert);
-  sqlite3_finalize(p->laf.pMaxField);
-  sqlite3_finalize(p->laf.pFindRoot);
-  sqlite3_finalize(p->laf.pInsert);
-  sqlite3_finalize(p->laf.pAllPage);
-  sqlite3_finalize(p->laf.pPageData);
-  p->laf.pUsedPages = 0;
-  p->laf.pAllAndParent = 0;
-  p->laf.pMapInsert = 0;
-  p->laf.pMaxField = 0;
-  p->laf.pFindRoot = 0;
-  p->laf.pInsert = 0;
-  p->laf.pAllPage = 0;
-  p->laf.pPageData = 0;
-  sqlite3_free(p->laf.apVal);
-  p->laf.apVal = 0;
-}
-
-/*
-** Free all resources allocated as part of sqlite3_recover_step() calls.
-*/
-static void recoverFinalCleanup(sqlite3_recover *p){
-  RecoverTable *pTab = 0;
-  RecoverTable *pNext = 0;
-
-  recoverWriteDataCleanup(p);
-  recoverLostAndFoundCleanup(p);
-
-  for(pTab=p->pTblList; pTab; pTab=pNext){
-    pNext = pTab->pNext;
-    sqlite3_free(pTab);
-  }
-  p->pTblList = 0;
-  sqlite3_finalize(p->pGetPage);
-  p->pGetPage = 0;
-  sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0);
-
-  {
-#ifndef NDEBUG
-    int res = 
<