Diff for /elwix/files/sqlite/dist/shell.c between versions 1.5 and 1.6

version 1.5, 2021/03/11 13:59:51 version 1.6, 2021/07/16 18:35:51
Line 571  static void utf8_width_print(FILE *pOut, int w, const  Line 571  static void utf8_width_print(FILE *pOut, int w, const 
   int i;    int i;
   int n;    int n;
   int aw = w<0 ? -w : w;    int aw = w<0 ? -w : w;
   char zBuf[1000];  
   if( aw>(int)sizeof(zBuf)/3 ) aw = (int)sizeof(zBuf)/3;  
   for(i=n=0; zUtf[i]; i++){    for(i=n=0; zUtf[i]; i++){
     if( (zUtf[i]&0xc0)!=0x80 ){      if( (zUtf[i]&0xc0)!=0x80 ){
       n++;        n++;
Line 1426  SQLITE_EXTENSION_INIT1 Line 1424  SQLITE_EXTENSION_INIT1
 #include <assert.h>  #include <assert.h>
 #include <string.h>  #include <string.h>
 #include <stdarg.h>  #include <stdarg.h>
   
   #ifndef SQLITE_AMALGAMATION
 /* typedef sqlite3_uint64 u64; */  /* typedef sqlite3_uint64 u64; */
   #endif /* SQLITE_AMALGAMATION */
   
 /******************************************************************************  /******************************************************************************
 ** The Hash Engine  ** The Hash Engine
Line 2016  static void sha3QueryFunc( Line 2017  static void sha3QueryFunc(
     }      }
     nCol = sqlite3_column_count(pStmt);      nCol = sqlite3_column_count(pStmt);
     z = sqlite3_sql(pStmt);      z = sqlite3_sql(pStmt);
    n = (int)strlen(z);    if( z ){
    hash_step_vformat(&cx,"S%d:",n);      n = (int)strlen(z);
    SHA3Update(&cx,(unsigned char*)z,n);      hash_step_vformat(&cx,"S%d:",n);
       SHA3Update(&cx,(unsigned char*)z,n);
     }
   
     /* Compute a hash over the result of the query */      /* Compute a hash over the result of the query */
     while( SQLITE_ROW==sqlite3_step(pStmt) ){      while( SQLITE_ROW==sqlite3_step(pStmt) ){
Line 3637  int sqlite3_completion_init( Line 3640  int sqlite3_completion_init(
 ** appended onto the end of some other file, such as an executable.  ** 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  ** A special record must appear at the end of the file that identifies the
** file as an appended database and provides an offset to page 1.  For** file as an appended database and provides the offset to the first page
** best performance page 1 should be located at a disk page boundary, though** of the exposed content. (Or, it is the length of the content prefix.)
** that is not required.** 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  ** When opening a database using this VFS, the connection might treat
** the file as an ordinary SQLite database, or it might treat is as a** the file as an ordinary SQLite database, or it might treat it as a
** database appended onto some other file.  Here are the rules:** database appended onto some other file.  The decision is made by
 ** applying the following rules in order:
 **  **
**  (1)  When opening a new empty file, that file is treated as an ordinary**  (1)  An empty file is an ordinary database.
**       database. 
 **  **
**  (2)  When opening a file that begins with the standard SQLite prefix**  (2)  If the file ends with the appendvfs trailer string
**       string "SQLite format 3", that file is treated as an ordinary**       "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
**       database. 
 **  **
**  (3)  When opening a file that ends with the appendvfs trailer string**  (3)  If the file begins with the standard SQLite prefix string
**       "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended**       "SQLite format 3", that file is an ordinary database.
**       database. 
 **  **
 **  (4)  If none of the above apply and the SQLITE_OPEN_CREATE flag is  **  (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.  **       set, then a new database is appended to the already existing file.
Line 3662  int sqlite3_completion_init( Line 3664  int sqlite3_completion_init(
 **  (5)  Otherwise, SQLITE_CANTOPEN is returned.  **  (5)  Otherwise, SQLITE_CANTOPEN is returned.
 **  **
 ** To avoid unnecessary complications with the PENDING_BYTE, the size of  ** To avoid unnecessary complications with the PENDING_BYTE, the size of
** the file containing the database is limited to 1GB.  This VFS will refuse** the file containing the database is limited to 1GB. (1000013824 bytes)
** to read or write past the 1GB mark.  This restriction might be lifted in** This VFS will not read or write past the 1GB mark.  This restriction
** future versions.  For now, if you need a large database, then keep the** might be lifted in future versions.  For now, if you need a larger
** database in a separate file.** database, then keep it in a separate file.
 **  **
** If the file being opened is not an appended database, then this shim is** If the file being opened is a plain database (not an appended one), then
** a pass-through into the default underlying VFS.** this shim is a pass-through into the default underlying VFS. (rule 3)
 **/  **/
 /* #include "sqlite3ext.h" */  /* #include "sqlite3ext.h" */
 SQLITE_EXTENSION_INIT1  SQLITE_EXTENSION_INIT1
Line 3681  SQLITE_EXTENSION_INIT1 Line 3683  SQLITE_EXTENSION_INIT1
 **     123456789 123456789 12345  **     123456789 123456789 12345
 **  **
 ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is  ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
** the offset to page 1.** the offset to page 1, and also the length of the prefix content.
 */  */
 #define APND_MARK_PREFIX     "Start-Of-SQLite3-"  #define APND_MARK_PREFIX     "Start-Of-SQLite3-"
 #define APND_MARK_PREFIX_SZ  17  #define APND_MARK_PREFIX_SZ  17
#define APND_MARK_SIZE       25#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  ** Maximum size of the combined prefix + database + append-mark.  This
Line 3694  SQLITE_EXTENSION_INIT1 Line 3697  SQLITE_EXTENSION_INIT1
 #define APND_MAX_SIZE  (65536*15259)  #define APND_MAX_SIZE  (65536*15259)
   
 /*  /*
   ** Size of storage page upon which to align appendvfs portion.
   */
   #ifndef APND_ROUNDUP_BITS
   #define APND_ROUNDUP_BITS 12
   #endif
   
   /*
 ** Forward declaration of objects used by this utility  ** Forward declaration of objects used by this utility
 */  */
 typedef struct sqlite3_vfs ApndVfs;  typedef struct sqlite3_vfs ApndVfs;
Line 3705  typedef struct ApndFile ApndFile; Line 3715  typedef struct ApndFile ApndFile;
 #define ORIGVFS(p)  ((sqlite3_vfs*)((p)->pAppData))  #define ORIGVFS(p)  ((sqlite3_vfs*)((p)->pAppData))
 #define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))  #define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
   
/* An open file *//* Invariants for an open appendvfs file:
  * Once an appendvfs file is opened, it will be in one of three states:
  * State 0: Never written. Underlying file (if any) is unaltered.
  * State 1: Append mark is persisted, content write is in progress.
  * State 2: Append mark is persisted, content writes are complete.
  * 
  * State 0 is persistent in the sense that nothing will have been done
  * to the underlying file, including any attempt to convert it to an
  * appendvfs file.
  *
  * State 1 is normally transitory. However, if a write operation ends
  * abnormally (disk full, power loss, process kill, etc.), then State 1
  * may be persistent on disk with an incomplete content write-out. This
  * is logically equivalent to an interrupted write to an ordinary file,
  * where some unknown portion of to-be-written data is persisted while
  * the remainder is not. Database integrity in such cases is maintained
  * (or not) by the same measures available for ordinary file access.
  *
  * State 2 is persistent under normal circumstances (when there is no
  * abnormal termination of a write operation such that data provided
  * to the underlying VFS write method has not yet reached storage.)
  *
  * In order to maintain the state invariant, the append mark is written
  * in advance of content writes where any part of such content would
  * overwrite an existing (or yet to be written) append mark.
  */
 struct ApndFile {  struct ApndFile {
  sqlite3_file base;              /* IO methods */  /* Access to IO methods of the underlying file */
  sqlite3_int64 iPgOne;           /* File offset to page 1 */  sqlite3_file base;
  sqlite3_int64 iMark;            /* Start of the append-mark */  /* File offset to beginning of appended content (unchanging) */
   sqlite3_int64 iPgOne;
   /* File offset of written append-mark, or -1 if unwritten */
   sqlite3_int64 iMark;
 };  };
   
 /*  /*
Line 3801  static const sqlite3_io_methods apnd_io_methods = { Line 3839  static const sqlite3_io_methods apnd_io_methods = {
   apndUnfetch                     /* xUnfetch */    apndUnfetch                     /* xUnfetch */
 };  };
   
   
   
 /*  /*
 ** Close an apnd-file.  ** Close an apnd-file.
 */  */
Line 3820  static int apndRead( Line 3856  static int apndRead(
   int iAmt,     int iAmt, 
   sqlite_int64 iOfst    sqlite_int64 iOfst
 ){  ){
  ApndFile *p = (ApndFile *)pFile;  ApndFile *paf = (ApndFile *)pFile;
   pFile = ORIGFILE(pFile);    pFile = ORIGFILE(pFile);
  return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne);  return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
 }  }
   
 /*  /*
** Add the append-mark onto the end of the file.** 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 *p, sqlite3_file *pFile){static int apndWriteMark(
  int i;  ApndFile *paf,
   sqlite3_file *pFile,
   sqlite_int64 iWriteEnd
 ){
   sqlite_int64 iPgOne = paf->iPgOne;
   unsigned char a[APND_MARK_SIZE];    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);    memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
  for(i=0; i<8; i++){  while (--i >= 0) {
    a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff;    a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
     iPgOne >>= 8;
   }    }
  return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark);  iWriteEnd += paf->iPgOne;
   if( SQLITE_OK==(rc = pFile->pMethods->xWrite
                   (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
     paf->iMark = iWriteEnd;
   }
   return rc;
 }  }
   
 /*  /*
Line 3847  static int apndWrite( Line 3898  static int apndWrite(
   int iAmt,    int iAmt,
   sqlite_int64 iOfst    sqlite_int64 iOfst
 ){  ){
  int rc;  ApndFile *paf = (ApndFile *)pFile;
  ApndFile *p = (ApndFile *)pFile;  sqlite_int64 iWriteEnd = iOfst + iAmt;
   if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
   pFile = ORIGFILE(pFile);    pFile = ORIGFILE(pFile);
  if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL;  /* If append-mark is absent or will be overwritten, write it. */
  rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne);  if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
  if( rc==SQLITE_OK &&  iOfst + iAmt + p->iPgOne > p->iMark ){    int rc = apndWriteMark(paf, pFile, iWriteEnd);
    sqlite3_int64 sz = 0;    if( SQLITE_OK!=rc )
    rc = pFile->pMethods->xFileSize(pFile, &sz);      return rc;
    if( rc==SQLITE_OK ){ 
      p->iMark = sz - APND_MARK_SIZE; 
      if( iOfst + iAmt + p->iPgOne > p->iMark ){ 
        p->iMark = p->iPgOne + iOfst + iAmt; 
        rc = apndWriteMark(p, pFile); 
      } 
    } 
   }    }
  return rc;  return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
 }  }
   
 /*  /*
 ** Truncate an apnd-file.  ** Truncate an apnd-file.
 */  */
 static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){  static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
  int rc;  ApndFile *paf = (ApndFile *)pFile;
  ApndFile *p = (ApndFile *)pFile; 
   pFile = ORIGFILE(pFile);    pFile = ORIGFILE(pFile);
  rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE);  /* The append mark goes out first so truncate failure does not lose it. */
  if( rc==SQLITE_OK ){  if( SQLITE_OK!=apndWriteMark(paf, pFile, size) )
    p->iMark = p->iPgOne+size;    return SQLITE_IOERR;
    rc = apndWriteMark(p, pFile);  /* Truncate underlying file just past append mark */
  }  return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
  return rc; 
 }  }
   
 /*  /*
Line 3891  static int apndSync(sqlite3_file *pFile, int flags){ Line 3934  static int apndSync(sqlite3_file *pFile, int flags){
   
 /*  /*
 ** Return the current file-size of an apnd-file.  ** 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){  static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
  ApndFile *p = (ApndFile *)pFile;  ApndFile *paf = (ApndFile *)pFile;
  int rc;  *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;
  pFile = ORIGFILE(p);  return SQLITE_OK;
  rc = pFile->pMethods->xFileSize(pFile, pSize); 
  if( rc==SQLITE_OK && p->iPgOne ){ 
    *pSize -= p->iPgOne + APND_MARK_SIZE; 
  } 
  return rc; 
 }  }
   
 /*  /*
Line 3931  static int apndCheckReservedLock(sqlite3_file *pFile,  Line 3970  static int apndCheckReservedLock(sqlite3_file *pFile, 
 ** File control method. For custom operations on an apnd-file.  ** File control method. For custom operations on an apnd-file.
 */  */
 static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){  static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
  ApndFile *p = (ApndFile *)pFile;  ApndFile *paf = (ApndFile *)pFile;
   int rc;    int rc;
   pFile = ORIGFILE(pFile);    pFile = ORIGFILE(pFile);
     if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne;
   rc = pFile->pMethods->xFileControl(pFile, op, pArg);    rc = pFile->pMethods->xFileControl(pFile, op, pArg);
   if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){    if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
    *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg);    *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
   }    }
   return rc;    return rc;
 }  }
Line 3995  static int apndFetch( Line 4035  static int apndFetch(
   void **pp    void **pp
 ){  ){
   ApndFile *p = (ApndFile *)pFile;    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);    pFile = ORIGFILE(pFile);
   return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);    return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
 }  }
Line 4007  static int apndUnfetch(sqlite3_file *pFile, sqlite3_in Line 4049  static int apndUnfetch(sqlite3_file *pFile, sqlite3_in
 }  }
   
 /*  /*
 ** Check to see if the file is an ordinary SQLite database file.  
 */  
 static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){  
   int rc;  
   char zHdr[16];  
   static const char aSqliteHdr[] = "SQLite format 3";  
   if( sz<512 ) return 0;  
   rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0);  
   if( rc ) return 0;  
   return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0;  
 }  
   
 /*  
 ** Try to read the append-mark off the end of a file.  Return the  ** 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** start of the appended database if the append-mark is present.
** there is no append-mark, return -1;** 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){  static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
   int rc, i;    int rc, i;
   sqlite3_int64 iMark;    sqlite3_int64 iMark;
     int msbs = 8 * (APND_MARK_FOS_SZ-1);
   unsigned char a[APND_MARK_SIZE];    unsigned char a[APND_MARK_SIZE];
   
  if( sz<=APND_MARK_SIZE ) return -1;  if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
   rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);    rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
   if( rc ) return -1;    if( rc ) return -1;
   if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;    if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
  iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56;  iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
  for(i=1; i<8; i++){      for(i=1; i<8; i++){
    iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-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;    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 right end-marker, the expected odd size, and the
        * SQLite DB type marker where the end-marker puts it, then it
        * is an appendvfs database (to be treated as such.)
        */
       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;
     }
   }
   
   /* Round-up used to get appendvfs portion to begin at a page boundary. */
   #define APND_ALIGN_MASK(nbits) ((1<<nbits)-1)
   #define APND_START_ROUNDUP(fsz, nbits) \
    ( ((fsz)+APND_ALIGN_MASK(nbits)) & ~(sqlite3_int64)APND_ALIGN_MASK(nbits) )
   
   /*
 ** Open an apnd file handle.  ** Open an apnd file handle.
 */  */
 static int apndOpen(  static int apndOpen(
Line 4057  static int apndOpen( Line 4138  static int apndOpen(
   sqlite3_int64 sz;    sqlite3_int64 sz;
   pSubVfs = ORIGVFS(pVfs);    pSubVfs = ORIGVFS(pVfs);
   if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){    if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
       /* The appendvfs is not to be used for transient or temporary databases. */
     return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);      return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
   }    }
   p = (ApndFile*)pFile;    p = (ApndFile*)pFile;
Line 4074  static int apndOpen( Line 4156  static int apndOpen(
     memmove(pFile, pSubFile, pSubVfs->szOsFile);      memmove(pFile, pSubFile, pSubVfs->szOsFile);
     return SQLITE_OK;      return SQLITE_OK;
   }    }
  p->iMark = 0;  /* Record that append mark has not been written until seen otherwise. */
   p->iMark = -1;
   p->iPgOne = apndReadMark(sz, pFile);    p->iPgOne = apndReadMark(sz, pFile);
  if( p->iPgOne>0 ){  if( p->iPgOne>=0 ){
     /* Append mark was found, infer its offset */
     p->iMark = sz - p->iPgOne - APND_MARK_SIZE;
     return SQLITE_OK;      return SQLITE_OK;
   }    }
   if( (flags & SQLITE_OPEN_CREATE)==0 ){    if( (flags & SQLITE_OPEN_CREATE)==0 ){
     pSubFile->pMethods->xClose(pSubFile);      pSubFile->pMethods->xClose(pSubFile);
     rc = SQLITE_CANTOPEN;      rc = SQLITE_CANTOPEN;
   }    }
  p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff;  /* 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, the p->iMark value indicates it is not yet written.
    */
   p->iPgOne = APND_START_ROUNDUP(sz, APND_ROUNDUP_BITS);
 apnd_open_done:  apnd_open_done:
   if( rc ) pFile->pMethods = 0;    if( rc ) pFile->pMethods = 0;
   return rc;    return rc;
 }  }
   
 /*  /*
** All other VFS methods are pass-thrus.** 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){  static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);    return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
 }  }
   
   /*
   ** All other VFS methods are pass-thrus.
   */
 static int apndAccess(  static int apndAccess(
   sqlite3_vfs *pVfs,     sqlite3_vfs *pVfs, 
   const char *zPath,     const char *zPath, 
Line 5201  static void ieee754func( Line 5298  static void ieee754func(
     int isNeg = 0;      int isNeg = 0;
     m = sqlite3_value_int64(argv[0]);      m = sqlite3_value_int64(argv[0]);
     e = sqlite3_value_int64(argv[1]);      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 ){      if( m<0 ){
       isNeg = 1;        isNeg = 1;
       m = -m;        m = -m;
Line 5315  int sqlite3_ieee_init( Line 5420  int sqlite3_ieee_init(
 }  }
   
 /************************* End ../ext/misc/ieee754.c ********************/  /************************* End ../ext/misc/ieee754.c ********************/
   /************************* Begin ../ext/misc/series.c ******************/
   /*
   ** 2015-08-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 file demonstrates how to create a table-valued-function using
   ** a virtual table.  This demo implements the generate_series() function
   ** which gives similar results to the eponymous function in PostgreSQL.
   ** Examples:
   **
   **      SELECT * FROM generate_series(0,100,5);
   **
   ** The query above returns integers from 0 through 100 counting by steps
   ** of 5.
   **
   **      SELECT * FROM generate_series(0,100);
   **
   ** Integers from 0 through 100 with a step size of 1.
   **
   **      SELECT * FROM generate_series(20) LIMIT 10;
   **
   ** Integers 20 through 29.
   **
   ** HOW IT WORKS
   **
   ** The generate_series "function" is really a virtual table with the
   ** following schema:
   **
   **     CREATE TABLE generate_series(
   **       value,
   **       start HIDDEN,
   **       stop HIDDEN,
   **       step HIDDEN
   **     );
   **
   ** 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>
   
   #ifndef SQLITE_OMIT_VIRTUALTABLE
   
   
   /* series_cursor is a subclass of sqlite3_vtab_cursor which will
   ** serve as the underlying representation of a cursor that scans
   ** over rows of the result
   */
   typedef struct series_cursor series_cursor;
   struct series_cursor {
     sqlite3_vtab_cursor base;  /* Base class - must be first */
     int isDesc;                /* True to count down rather than up */
     sqlite3_int64 iRowid;      /* The rowid */
     sqlite3_int64 iValue;      /* Current value ("value") */
     sqlite3_int64 mnValue;     /* Mimimum value ("start") */
     sqlite3_int64 mxValue;     /* Maximum value ("stop") */
     sqlite3_int64 iStep;       /* Increment ("step") */
   };
   
   /*
   ** 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;
     if( pCur->isDesc ){
       pCur->iValue -= pCur->iStep;
     }else{
       pCur->iValue += pCur->iStep;
     }
     pCur->iRowid++;
     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->mnValue; break;
       case SERIES_COLUMN_STOP:   x = pCur->mxValue; break;
       case SERIES_COLUMN_STEP:   x = pCur->iStep;   break;
       default:                   x = pCur->iValue;  break;
     }
     sqlite3_result_int64(ctx, x);
     return SQLITE_OK;
   }
   
   /*
   ** 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 seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
     series_cursor *pCur = (series_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 seriesEof(sqlite3_vtab_cursor *cur){
     series_cursor *pCur = (series_cursor*)cur;
     if( pCur->isDesc ){
       return pCur->iValue < pCur->mnValue;
     }else{
       return pCur->iValue > pCur->mxValue;
     }
   }
   
   /* 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->mnValue = sqlite3_value_int64(argv[i++]);
     }else{
       pCur->mnValue = 0;
     }
     if( idxNum & 2 ){
       pCur->mxValue = sqlite3_value_int64(argv[i++]);
     }else{
       pCur->mxValue = 0xffffffff;
     }
     if( idxNum & 4 ){
       pCur->iStep = sqlite3_value_int64(argv[i++]);
       if( pCur->iStep==0 ){
         pCur->iStep = 1;
       }else if( pCur->iStep<0 ){
         pCur->iStep = -pCur->iStep;
         if( (idxNum & 16)==0 ) idxNum |= 8;
       }
     }else{
       pCur->iStep = 1;
     }
     for(i=0; i<argc; i++){
       if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
         /* If any of the constraints have a NULL value, then return no rows.
         ** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
         pCur->mnValue = 1;
         pCur->mxValue = 0;
         break;
       }
     }
     if( idxNum & 8 ){
       pCur->isDesc = 1;
       pCur->iValue = pCur->mxValue;
       if( pCur->iStep>0 ){
         pCur->iValue -= (pCur->mxValue - pCur->mnValue)%pCur->iStep;
       }
     }else{
       pCur->isDesc = 0;
       pCur->iValue = pCur->mnValue;
     }
     pCur->iRowid = 1;
     return SQLITE_OK;
   }
   
   /*
   ** 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 *tabUnused,
     sqlite3_index_info *pIdxInfo
   ){
     int i, j;              /* Loop over constraints */
     int idxNum = 0;        /* The query plan bitmask */
     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 );
     (void)tabUnused;
     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( pConstraint->usable==0 ){
         unusableMask |=  iMask;
         continue;
       }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
         idxNum |= iMask;
         aIdx[iCol] = i;
       }
     }
     for(i=0; i<3; i++){
       if( (j = aIdx[i])>=0 ){
         pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
         pIdxInfo->aConstraintUsage[j].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
       }
     }
     if( (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 ){
         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 = 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 ********************/
 #ifdef SQLITE_HAVE_ZLIB  #ifdef SQLITE_HAVE_ZLIB
 /************************* Begin ../ext/misc/zipfile.c ******************/  /************************* Begin ../ext/misc/zipfile.c ******************/
 /*  /*
Line 5842  static int zipfileAppendData( Line 6395  static int zipfileAppendData(
   const u8 *aWrite,    const u8 *aWrite,
   int nWrite    int nWrite
 ){  ){
  size_t n;  if( nWrite>0 ){
  fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);    size_t n = nWrite;
  n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);    fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
  if( (int)n!=nWrite ){    n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
    pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");    if( (int)n!=nWrite ){
    return SQLITE_ERROR;      pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
       return SQLITE_ERROR;
     }
     pTab->szCurrent += nWrite;
   }    }
   pTab->szCurrent += nWrite;  
   return SQLITE_OK;    return SQLITE_OK;
 }  }
   
Line 8494  static int idxGetTableInfo( Line 9049  static int idxGetTableInfo(
   IdxTable *pNew = 0;    IdxTable *pNew = 0;
   int rc, rc2;    int rc, rc2;
   char *pCsr = 0;    char *pCsr = 0;
     int nPk = 0;
   
  rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);  rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab);
   while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
     const char *zCol = (const char*)sqlite3_column_text(p1, 1);      const char *zCol = (const char*)sqlite3_column_text(p1, 1);
     nByte += 1 + STRLEN(zCol);      nByte += 1 + STRLEN(zCol);
Line 8504  static int idxGetTableInfo( Line 9060  static int idxGetTableInfo(
     );      );
     nByte += 1 + STRLEN(zCol);      nByte += 1 + STRLEN(zCol);
     nCol++;      nCol++;
       nPk += (sqlite3_column_int(p1, 5)>0);
   }    }
   rc2 = sqlite3_reset(p1);    rc2 = sqlite3_reset(p1);
   if( rc==SQLITE_OK ) rc = rc2;    if( rc==SQLITE_OK ) rc = rc2;
Line 8523  static int idxGetTableInfo( Line 9080  static int idxGetTableInfo(
     const char *zCol = (const char*)sqlite3_column_text(p1, 1);      const char *zCol = (const char*)sqlite3_column_text(p1, 1);
     int nCopy = STRLEN(zCol) + 1;      int nCopy = STRLEN(zCol) + 1;
     pNew->aCol[nCol].zName = pCsr;      pNew->aCol[nCol].zName = pCsr;
    pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);    pNew->aCol[nCol].iPk = (sqlite3_column_int(p1, 5)==1 && nPk==1);
     memcpy(pCsr, zCol, nCopy);      memcpy(pCsr, zCol, nCopy);
     pCsr += nCopy;      pCsr += nCopy;
   
Line 9528  static int idxPopulateStat1(sqlite3expert *p, char **p Line 10085  static int idxPopulateStat1(sqlite3expert *p, char **p
   idxFinalize(&rc, pIndexXInfo);    idxFinalize(&rc, pIndexXInfo);
   idxFinalize(&rc, pWrite);    idxFinalize(&rc, pWrite);
   
  for(i=0; i<pCtx->nSlot; i++){  if( pCtx ){
    sqlite3_free(pCtx->aSlot[i].z);    for(i=0; i<pCtx->nSlot; i++){
       sqlite3_free(pCtx->aSlot[i].z);
     }
     sqlite3_free(pCtx);
   }    }
   sqlite3_free(pCtx);  
   
   if( rc==SQLITE_OK ){    if( rc==SQLITE_OK ){
     rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0);      rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0);
Line 10672  struct ShellState { Line 11231  struct ShellState {
   u8 autoEQP;            /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */    u8 autoEQP;            /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
   u8 autoEQPtest;        /* autoEQP is in test mode */    u8 autoEQPtest;        /* autoEQP is in test mode */
   u8 autoEQPtrace;       /* autoEQP is in trace mode */    u8 autoEQPtrace;       /* autoEQP is in trace mode */
   u8 statsOn;            /* True to display memory stats before each finalize */  
   u8 scanstatsOn;        /* True to display scan stats before each finalize */    u8 scanstatsOn;        /* True to display scan stats before each finalize */
   u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */    u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
   u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */    u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
   u8 nEqpLevel;          /* Depth of the EQP output graph */    u8 nEqpLevel;          /* Depth of the EQP output graph */
   u8 eTraceType;         /* SHELL_TRACE_* value for type of trace */    u8 eTraceType;         /* SHELL_TRACE_* value for type of trace */
     unsigned statsOn;      /* True to display memory stats before each finalize */
   unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */    unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */
   int outCount;          /* Revert to stdout when reaching zero */    int outCount;          /* Revert to stdout when reaching zero */
   int cnt;               /* Number of records displayed so far */    int cnt;               /* Number of records displayed so far */
Line 10771  struct ShellState { Line 11330  struct ShellState {
 #define SHFLG_CountChanges   0x00000020 /* .changes setting */  #define SHFLG_CountChanges   0x00000020 /* .changes setting */
 #define SHFLG_Echo           0x00000040 /* .echo or --echo setting */  #define SHFLG_Echo           0x00000040 /* .echo or --echo setting */
 #define SHFLG_HeaderSet      0x00000080 /* .header has been used */  #define SHFLG_HeaderSet      0x00000080 /* .header has been used */
   #define SHFLG_DumpDataOnly   0x00000100 /* .dump show data only */
   #define SHFLG_DumpNoSys      0x00000200 /* .dump omits system tables */
   
 /*  /*
 ** Macros for testing and setting shellFlgs  ** Macros for testing and setting shellFlgs
Line 11612  static int shell_callback( Line 12173  static int shell_callback(
       if( azArg==0 ) break;        if( azArg==0 ) break;
       for(i=0; i<nArg; i++){        for(i=0; i<nArg; i++){
         int w = aExplainWidth[i];          int w = aExplainWidth[i];
           if( i==nArg-1 ) w = 0;
         if( azArg[i] && strlenChar(azArg[i])>w ){          if( azArg[i] && strlenChar(azArg[i])>w ){
           w = strlenChar(azArg[i]);            w = strlenChar(azArg[i]);
         }          }
Line 12176  static int display_stats( Line 12738  static int display_stats(
   if( pArg==0 || pArg->out==0 ) return 0;    if( pArg==0 || pArg->out==0 ) return 0;
   out = pArg->out;    out = pArg->out;
   
  if( pArg->pStmt && (pArg->statsOn & 2) ){  if( pArg->pStmt && pArg->statsOn==2 ){
     int nCol, i, x;      int nCol, i, x;
     sqlite3_stmt *pStmt = pArg->pStmt;      sqlite3_stmt *pStmt = pArg->pStmt;
     char z[100];      char z[100];
Line 12200  static int display_stats( Line 12762  static int display_stats(
     }      }
   }    }
   
     if( pArg->statsOn==3 ){
       if( pArg->pStmt ){
         iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
         raw_printf(pArg->out, "VM-steps: %d\n", iCur);
       }
       return 0;
     }
   
   displayStatLine(pArg, "Memory Used:",    displayStatLine(pArg, "Memory Used:",
      "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);       "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
   displayStatLine(pArg, "Number of Outstanding Allocations:",    displayStatLine(pArg, "Number of Outstanding Allocations:",
Line 12466  static void explain_data_delete(ShellState *p){ Line 13036  static void explain_data_delete(ShellState *p){
 /*  /*
 ** Disable and restore .wheretrace and .selecttrace settings.  ** Disable and restore .wheretrace and .selecttrace settings.
 */  */
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)static unsigned int savedSelectTrace;
extern unsigned int sqlite3_unsupported_selecttrace;static unsigned int savedWhereTrace;
static int savedSelectTrace; 
#endif 
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) 
extern int sqlite3WhereTrace; 
static int savedWhereTrace; 
#endif 
 static void disable_debug_trace_modes(void){  static void disable_debug_trace_modes(void){
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)  unsigned int zero = 0;
  savedSelectTrace = sqlite3_unsupported_selecttrace;  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &savedSelectTrace);
  sqlite3_unsupported_selecttrace = 0;  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &zero);
#endif  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &savedWhereTrace);
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &zero);
  savedWhereTrace = sqlite3WhereTrace; 
  sqlite3WhereTrace = 0; 
#endif 
 }  }
 static void restore_debug_trace_modes(void){  static void restore_debug_trace_modes(void){
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace);
  sqlite3_unsupported_selecttrace = savedSelectTrace;  sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &savedWhereTrace);
#endif 
#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE) 
  sqlite3WhereTrace = savedWhereTrace; 
#endif 
 }  }
   
 /* Create the TEMP table used to store parameter bindings */  /* Create the TEMP table used to store parameter bindings */
Line 13291  static int dump_callback(void *pArg, int nArg, char ** Line 13848  static int dump_callback(void *pArg, int nArg, char **
   const char *zType;    const char *zType;
   const char *zSql;    const char *zSql;
   ShellState *p = (ShellState *)pArg;    ShellState *p = (ShellState *)pArg;
     int dataOnly;
     int noSys;
   
   UNUSED_PARAMETER(azNotUsed);    UNUSED_PARAMETER(azNotUsed);
   if( nArg!=3 || azArg==0 ) return 0;    if( nArg!=3 || azArg==0 ) return 0;
   zTable = azArg[0];    zTable = azArg[0];
   zType = azArg[1];    zType = azArg[1];
   zSql = azArg[2];    zSql = azArg[2];
     dataOnly = (p->shellFlgs & SHFLG_DumpDataOnly)!=0;
     noSys    = (p->shellFlgs & SHFLG_DumpNoSys)!=0;
   
  if( strcmp(zTable, "sqlite_sequence")==0 ){  if( strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
    raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");    if( !dataOnly ) raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
  }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){  }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
    raw_printf(p->out, "ANALYZE sqlite_schema;\n");    if( !dataOnly ) raw_printf(p->out, "ANALYZE sqlite_schema;\n");
   }else if( strncmp(zTable, "sqlite_", 7)==0 ){    }else if( strncmp(zTable, "sqlite_", 7)==0 ){
     return 0;      return 0;
     }else if( dataOnly ){
       /* no-op */
   }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){    }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
     char *zIns;      char *zIns;
     if( !p->writableSchema ){      if( !p->writableSchema ){
Line 13474  static const char *(azHelp[]) = { Line 14037  static const char *(azHelp[]) = {
   ".databases               List names and files of attached databases",    ".databases               List names and files of attached databases",
   ".dbconfig ?op? ?val?     List or change sqlite3_db_config() options",    ".dbconfig ?op? ?val?     List or change sqlite3_db_config() options",
   ".dbinfo ?DB?             Show status information about the database",    ".dbinfo ?DB?             Show status information about the database",
  ".dump ?TABLE?            Render database content as SQL",  ".dump ?OBJECTS?          Render database content as SQL",
   "   Options:",    "   Options:",
  "     --preserve-rowids      Include ROWID values in the output",  "     --data-only            Output only INSERT statements",
   "     --newlines             Allow unescaped newline characters in output",    "     --newlines             Allow unescaped newline characters in output",
  "   TABLE is a LIKE pattern for the tables to dump",  "     --nosys                Omit system tables (ex: \"sqlite_stat1\")",
   "     --preserve-rowids      Include ROWID values in the output",
   "   OBJECTS is a LIKE pattern for tables, indexes, triggers or views to dump",
   "   Additional LIKE patterns can be given in subsequent arguments",    "   Additional LIKE patterns can be given in subsequent arguments",
   ".echo on|off             Turn command echo on or off",    ".echo on|off             Turn command echo on or off",
   ".eqp on|off|full|...     Enable or disable automatic EXPLAIN QUERY PLAN",    ".eqp on|off|full|...     Enable or disable automatic EXPLAIN QUERY PLAN",
Line 13602  static const char *(azHelp[]) = { Line 14167  static const char *(azHelp[]) = {
   ".save FILE               Write in-memory database into FILE",    ".save FILE               Write in-memory database into FILE",
   ".scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off",    ".scanstats on|off        Turn sqlite3_stmt_scanstatus() metrics on or off",
   ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",    ".schema ?PATTERN?        Show the CREATE statements matching PATTERN",
  "     Options:",  "   Options:",
  "         --indent            Try to pretty-print the schema",  "      --indent             Try to pretty-print the schema",
   "      --nosys              Omit objects whose names start with \"sqlite_\"",
   ".selftest ?OPTIONS?      Run tests defined in the SELFTEST table",    ".selftest ?OPTIONS?      Run tests defined in the SELFTEST table",
   "    Options:",    "    Options:",
   "       --init               Create a new SELFTEST table",    "       --init               Create a new SELFTEST table",
Line 13636  static const char *(azHelp[]) = { Line 14202  static const char *(azHelp[]) = {
   ".shell CMD ARGS...       Run CMD ARGS... in a system shell",    ".shell CMD ARGS...       Run CMD ARGS... in a system shell",
 #endif  #endif
   ".show                    Show the current values for various settings",    ".show                    Show the current values for various settings",
  ".stats ?on|off?          Show stats or turn stats on or off",  ".stats ?ARG?             Show stats or turn stats on or off",
   "   off                      Turn off automatic stat display",
   "   on                       Turn on automatic stat display",
   "   stmt                     Show statement stats",
   "   vmstep                   Show the virtual machine step count only",
 #ifndef SQLITE_NOHAVE_SYSTEM  #ifndef SQLITE_NOHAVE_SYSTEM
   ".system CMD ARGS...      Run CMD ARGS... in a system shell",    ".system CMD ARGS...      Run CMD ARGS... in a system shell",
 #endif  #endif
Line 14013  static void shellIdQuote( Line 14583  static void shellIdQuote(
 }  }
   
 /*  /*
   ** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X.
   */
   static void shellUSleepFunc(
     sqlite3_context *context, 
     int argcUnused, 
     sqlite3_value **argv
   ){
     int sleep = sqlite3_value_int(argv[0]);
     (void)argcUnused;
     sqlite3_sleep(sleep/1000);
     sqlite3_result_int(context, sleep);
   }
   
   /*
 ** Scalar function "shell_escape_crnl" used by the .recover command.  ** Scalar function "shell_escape_crnl" used by the .recover command.
 ** The argument passed to this function is the output of built-in  ** The argument passed to this function is the output of built-in
 ** function quote(). If the first character of the input is "'",   ** function quote(). If the first character of the input is "'", 
Line 14176  static void open_db(ShellState *p, int openFlags){ Line 14760  static void open_db(ShellState *p, int openFlags){
     sqlite3_uint_init(p->db, 0, 0);      sqlite3_uint_init(p->db, 0, 0);
     sqlite3_decimal_init(p->db, 0, 0);      sqlite3_decimal_init(p->db, 0, 0);
     sqlite3_ieee_init(p->db, 0, 0);      sqlite3_ieee_init(p->db, 0, 0);
       sqlite3_series_init(p->db, 0, 0);
 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)  #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
     sqlite3_dbdata_init(p->db, 0, 0);      sqlite3_dbdata_init(p->db, 0, 0);
 #endif  #endif
Line 14195  static void open_db(ShellState *p, int openFlags){ Line 14780  static void open_db(ShellState *p, int openFlags){
                             shellInt32, 0, 0);                              shellInt32, 0, 0);
     sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,      sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,
                             shellIdQuote, 0, 0);                              shellIdQuote, 0, 0);
       sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
                               shellUSleepFunc, 0, 0);
 #ifndef SQLITE_NOHAVE_SYSTEM  #ifndef SQLITE_NOHAVE_SYSTEM
     sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,      sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
                             editFunc, 0, 0);                              editFunc, 0, 0);
Line 17169  static int do_meta_command(char *zLine, ShellState *p) Line 17756  static int do_meta_command(char *zLine, ShellState *p)
   }else    }else
   
   if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){    if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
    ShellState data;    char **azName = 0;
    char *zErrMsg = 0;    int nName = 0;
     sqlite3_stmt *pStmt;
     int i;
     open_db(p, 0);      open_db(p, 0);
    memcpy(&data, p, sizeof(data));    rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
    data.showHeader = 0;    if( rc ){
    data.cMode = data.mode = MODE_List;      utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
    sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": "); 
    data.cnt = 0; 
    sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list", 
                 callback, &data, &zErrMsg); 
    if( zErrMsg ){ 
      utf8_printf(stderr,"Error: %s\n", zErrMsg); 
      sqlite3_free(zErrMsg); 
       rc = 1;        rc = 1;
       }else{
         while( sqlite3_step(pStmt)==SQLITE_ROW ){
           const char *zSchema = (const char *)sqlite3_column_text(pStmt,1);
           const char *zFile = (const char*)sqlite3_column_text(pStmt,2);
           azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*));
           if( azName==0 ){ shell_out_of_memory();  /* Does not return */ }
           azName[nName*2] = strdup(zSchema);
           azName[nName*2+1] = strdup(zFile);
           nName++;
         }
     }      }
       sqlite3_finalize(pStmt);
       for(i=0; i<nName; i++){
         int eTxn = sqlite3_txn_state(p->db, azName[i*2]);
         int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]);
         const char *z = azName[i*2+1];
         utf8_printf(p->out, "%s: %s %s%s\n",
            azName[i*2],
            z && z[0] ? z : "\"\"",
            bRdonly ? "r/o" : "r/w",
            eTxn==SQLITE_TXN_NONE ? "" :
               eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn");
         free(azName[i*2]);
         free(azName[i*2+1]);
       }
       sqlite3_free(azName);
   }else    }else
   
   if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){    if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
Line 17242  static int do_meta_command(char *zLine, ShellState *p) Line 17849  static int do_meta_command(char *zLine, ShellState *p)
     int i;      int i;
     int savedShowHeader = p->showHeader;      int savedShowHeader = p->showHeader;
     int savedShellFlags = p->shellFlgs;      int savedShellFlags = p->shellFlgs;
    ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo);    ShellClearFlag(p, 
        SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
        |SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
     for(i=1; i<nArg; i++){      for(i=1; i<nArg; i++){
       if( azArg[i][0]=='-' ){        if( azArg[i][0]=='-' ){
         const char *z = azArg[i]+1;          const char *z = azArg[i]+1;
Line 17261  static int do_meta_command(char *zLine, ShellState *p) Line 17870  static int do_meta_command(char *zLine, ShellState *p)
         if( strcmp(z,"newlines")==0 ){          if( strcmp(z,"newlines")==0 ){
           ShellSetFlag(p, SHFLG_Newlines);            ShellSetFlag(p, SHFLG_Newlines);
         }else          }else
           if( strcmp(z,"data-only")==0 ){
             ShellSetFlag(p, SHFLG_DumpDataOnly);
           }else
           if( strcmp(z,"nosys")==0 ){
             ShellSetFlag(p, SHFLG_DumpNoSys);
           }else
         {          {
           raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);            raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
           rc = 1;            rc = 1;
Line 17277  static int do_meta_command(char *zLine, ShellState *p) Line 17892  static int do_meta_command(char *zLine, ShellState *p)
   
     open_db(p, 0);      open_db(p, 0);
   
    /* When playing back a "dump", the content might appear in an order    if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
    ** which causes immediate foreign key constraints to be violated.      /* When playing back a "dump", the content might appear in an order
    ** So disable foreign-key constraint enforcement to prevent problems. */      ** which causes immediate foreign key constraints to be violated.
    raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");      ** So disable foreign-key constraint enforcement to prevent problems. */
    raw_printf(p->out, "BEGIN TRANSACTION;\n");      raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
       raw_printf(p->out, "BEGIN TRANSACTION;\n");
     }
     p->writableSchema = 0;      p->writableSchema = 0;
     p->showHeader = 0;      p->showHeader = 0;
     /* Set writable_schema=ON since doing so forces SQLite to initialize      /* Set writable_schema=ON since doing so forces SQLite to initialize
Line 17299  static int do_meta_command(char *zLine, ShellState *p) Line 17916  static int do_meta_command(char *zLine, ShellState *p)
     );      );
     run_schema_dump_query(p,zSql);      run_schema_dump_query(p,zSql);
     sqlite3_free(zSql);      sqlite3_free(zSql);
    zSql = sqlite3_mprintf(    if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
      "SELECT sql FROM sqlite_schema "      zSql = sqlite3_mprintf(
      "WHERE (%s) AND sql NOT NULL"        "SELECT sql FROM sqlite_schema "
      "  AND type IN ('index','trigger','view')",        "WHERE (%s) AND sql NOT NULL"
      zLike        "  AND type IN ('index','trigger','view')",
    );        zLike
    run_table_dump_query(p, zSql);      );
    sqlite3_free(zSql);      run_table_dump_query(p, zSql);
       sqlite3_free(zSql);
     }
     sqlite3_free(zLike);      sqlite3_free(zLike);
     if( p->writableSchema ){      if( p->writableSchema ){
       raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");        raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
Line 17314  static int do_meta_command(char *zLine, ShellState *p) Line 17933  static int do_meta_command(char *zLine, ShellState *p)
     }      }
     sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);      sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
     sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);      sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
    raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");    if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
       raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
     }
     p->showHeader = savedShowHeader;      p->showHeader = savedShowHeader;
     p->shellFlgs = savedShellFlags;      p->shellFlgs = savedShellFlags;
   }else    }else
Line 17401  static int do_meta_command(char *zLine, ShellState *p) Line 18022  static int do_meta_command(char *zLine, ShellState *p)
        int ctrlCode;            /* Integer code for that option */         int ctrlCode;            /* Integer code for that option */
        const char *zUsage;      /* Usage notes */         const char *zUsage;      /* Usage notes */
     } aCtrl[] = {      } aCtrl[] = {
       { "size_limit",     SQLITE_FCNTL_SIZE_LIMIT,      "[LIMIT]"        },  
       { "chunk_size",     SQLITE_FCNTL_CHUNK_SIZE,      "SIZE"           },        { "chunk_size",     SQLITE_FCNTL_CHUNK_SIZE,      "SIZE"           },
   /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY,  "COUNT DELAY"    },*/      { "data_version",   SQLITE_FCNTL_DATA_VERSION,    ""               },
      { "persist_wal",    SQLITE_FCNTL_PERSIST_WAL,     "[BOOLEAN]"      }, 
      { "psow",       SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]"      }, 
   /* { "pragma",         SQLITE_FCNTL_PRAGMA,          "NAME ARG"       },*/ 
      { "tempfilename",   SQLITE_FCNTL_TEMPFILENAME,    ""               }, 
       { "has_moved",      SQLITE_FCNTL_HAS_MOVED,       ""               },          { "has_moved",      SQLITE_FCNTL_HAS_MOVED,       ""               },  
       { "lock_timeout",   SQLITE_FCNTL_LOCK_TIMEOUT,    "MILLISEC"       },        { "lock_timeout",   SQLITE_FCNTL_LOCK_TIMEOUT,    "MILLISEC"       },
         { "persist_wal",    SQLITE_FCNTL_PERSIST_WAL,     "[BOOLEAN]"      },
      /* { "pragma",         SQLITE_FCNTL_PRAGMA,          "NAME ARG"       },*/
         { "psow",       SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]"      },
       { "reserve_bytes",  SQLITE_FCNTL_RESERVE_BYTES,   "[N]"            },        { "reserve_bytes",  SQLITE_FCNTL_RESERVE_BYTES,   "[N]"            },
         { "size_limit",     SQLITE_FCNTL_SIZE_LIMIT,      "[LIMIT]"        },
         { "tempfilename",   SQLITE_FCNTL_TEMPFILENAME,    ""               },
      /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY,  "COUNT DELAY"    },*/
     };      };
     int filectrl = -1;      int filectrl = -1;
     int iCtrl = -1;      int iCtrl = -1;
Line 17497  static int do_meta_command(char *zLine, ShellState *p) Line 18119  static int do_meta_command(char *zLine, ShellState *p)
           isOk = 1;            isOk = 1;
           break;            break;
         }          }
           case SQLITE_FCNTL_DATA_VERSION:
         case SQLITE_FCNTL_HAS_MOVED: {          case SQLITE_FCNTL_HAS_MOVED: {
           int x;            int x;
           if( nArg!=2 ) break;            if( nArg!=2 ) break;
Line 17753  static int do_meta_command(char *zLine, ShellState *p) Line 18376  static int do_meta_command(char *zLine, ShellState *p)
     while( (nSkip--)>0 ){      while( (nSkip--)>0 ){
       while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}        while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
     }      }
    zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);    zSql = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
     if( zSql==0 ){      if( zSql==0 ){
       import_cleanup(&sCtx);        import_cleanup(&sCtx);
       shell_out_of_memory();        shell_out_of_memory();
Line 17762  static int do_meta_command(char *zLine, ShellState *p) Line 18385  static int do_meta_command(char *zLine, ShellState *p)
     rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
     import_append_char(&sCtx, 0);    /* To ensure sCtx.z is allocated */      import_append_char(&sCtx, 0);    /* To ensure sCtx.z is allocated */
     if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){      if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
      char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);      char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\"", zTable);
       char cSep = '(';        char cSep = '(';
       while( xRead(&sCtx) ){        while( xRead(&sCtx) ){
         zCreate = sqlite3_mprintf("%z%c\n  \"%w\" TEXT", zCreate, cSep, sCtx.z);          zCreate = sqlite3_mprintf("%z%c\n  \"%w\" TEXT", zCreate, cSep, sCtx.z);
Line 17783  static int do_meta_command(char *zLine, ShellState *p) Line 18406  static int do_meta_command(char *zLine, ShellState *p)
       rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);        rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
       sqlite3_free(zCreate);        sqlite3_free(zCreate);
       if( rc ){        if( rc ){
        utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,        utf8_printf(stderr, "CREATE TABLE \"%s\"(...) failed: %s\n", zTable,
                 sqlite3_errmsg(p->db));                  sqlite3_errmsg(p->db));
         import_cleanup(&sCtx);          import_cleanup(&sCtx);
         rc = 1;          rc = 1;
Line 18205  static int do_meta_command(char *zLine, ShellState *p) Line 18828  static int do_meta_command(char *zLine, ShellState *p)
 #endif /* SQLITE_DEBUG */  #endif /* SQLITE_DEBUG */
   
   if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){    if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
    char *zNewFilename;  /* Name of the database file to open */    char *zNewFilename = 0;  /* Name of the database file to open */
    int iName = 1;       /* Index in azArg[] of the filename */    int iName = 1;           /* Index in azArg[] of the filename */
    int newFlag = 0;     /* True to delete file before opening */    int newFlag = 0;         /* True to delete file before opening */
     /* Close the existing database */      /* Close the existing database */
     session_close_all(p);      session_close_all(p);
     close_db(p->db);      close_db(p->db);
Line 18219  static int do_meta_command(char *zLine, ShellState *p) Line 18842  static int do_meta_command(char *zLine, ShellState *p)
     p->openFlags = 0;      p->openFlags = 0;
     p->szMax = 0;      p->szMax = 0;
     /* Check for command-line arguments */      /* Check for command-line arguments */
    for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){    for(iName=1; iName<nArg; iName++){
       const char *z = azArg[iName];        const char *z = azArg[iName];
       if( optionMatch(z,"new") ){        if( optionMatch(z,"new") ){
         newFlag = 1;          newFlag = 1;
Line 18245  static int do_meta_command(char *zLine, ShellState *p) Line 18868  static int do_meta_command(char *zLine, ShellState *p)
         utf8_printf(stderr, "unknown option: %s\n", z);          utf8_printf(stderr, "unknown option: %s\n", z);
         rc = 1;          rc = 1;
         goto meta_command_exit;          goto meta_command_exit;
         }else if( zNewFilename ){
           utf8_printf(stderr, "extra argument: \"%s\"\n", z);
           rc = 1;
           goto meta_command_exit;
         }else{
           zNewFilename = sqlite3_mprintf("%s", z);
       }        }
     }      }
     /* If a filename is specified, try to open it first */      /* If a filename is specified, try to open it first */
     zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;  
     if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){      if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
       if( newFlag ) shellDeleteFile(zNewFilename);        if( newFlag ) shellDeleteFile(zNewFilename);
       p->zDbFilename = zNewFilename;        p->zDbFilename = zNewFilename;
Line 18271  static int do_meta_command(char *zLine, ShellState *p) Line 18899  static int do_meta_command(char *zLine, ShellState *p)
         && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))          && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
    || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)     || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
   ){    ){
    const char *zFile = 0;    char *zFile = 0;
     int bTxtMode = 0;      int bTxtMode = 0;
     int i;      int i;
     int eMode = 0;      int eMode = 0;
Line 18301  static int do_meta_command(char *zLine, ShellState *p) Line 18929  static int do_meta_command(char *zLine, ShellState *p)
           rc = 1;            rc = 1;
           goto meta_command_exit;            goto meta_command_exit;
         }          }
      }else if( zFile==0 ){      }else if( zFile==0 && eMode!='e' && eMode!='x' ){
        zFile = z;        zFile = sqlite3_mprintf("%s", z);
         if( zFile[0]=='|' ){
           while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]);
           break;
         }
       }else{        }else{
         utf8_printf(p->out,"ERROR: extra parameter: \"%s\".  Usage:\n",          utf8_printf(p->out,"ERROR: extra parameter: \"%s\".  Usage:\n",
                     azArg[i]);                      azArg[i]);
         showHelp(p->out, azArg[0]);          showHelp(p->out, azArg[0]);
         rc = 1;          rc = 1;
           sqlite3_free(zFile);
         goto meta_command_exit;          goto meta_command_exit;
       }        }
     }      }
    if( zFile==0 ) zFile = "stdout";    if( zFile==0 ) zFile = sqlite3_mprintf("stdout");
     if( bOnce ){      if( bOnce ){
       p->outCount = 2;        p->outCount = 2;
     }else{      }else{
Line 18334  static int do_meta_command(char *zLine, ShellState *p) Line 18967  static int do_meta_command(char *zLine, ShellState *p)
         newTempFile(p, "txt");          newTempFile(p, "txt");
         bTxtMode = 1;          bTxtMode = 1;
       }        }
      zFile = p->zTempFile;      sqlite3_free(zFile);
       zFile = sqlite3_mprintf("%s", p->zTempFile);
     }      }
 #endif /* SQLITE_NOHAVE_SYSTEM */  #endif /* SQLITE_NOHAVE_SYSTEM */
     if( zFile[0]=='|' ){      if( zFile[0]=='|' ){
Line 18366  static int do_meta_command(char *zLine, ShellState *p) Line 19000  static int do_meta_command(char *zLine, ShellState *p)
         sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);          sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
       }        }
     }      }
       sqlite3_free(zFile);
   }else    }else
   
   if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){    if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
Line 18548  static int do_meta_command(char *zLine, ShellState *p) Line 19183  static int do_meta_command(char *zLine, ShellState *p)
       rc = 1;        rc = 1;
       goto meta_command_exit;        goto meta_command_exit;
     }      }
    if( notNormalFile(azArg[1])    if( azArg[1][0]=='|' ){
     || (p->in = fopen(azArg[1], "rb"))==0#ifdef SQLITE_OMIT_POPEN
    ){      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
       rc = 1;
       p->out = stdout;
 #else
       p->in = popen(azArg[1]+1, "r");
       if( p->in==0 ){
         utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
         rc = 1;
       }else{
         rc = process_input(p);
         pclose(p->in);
       }
 #endif
     }else if( notNormalFile(azArg[1]) || (p->in = fopen(azArg[1], "rb"))==0 ){
       utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);        utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
       rc = 1;        rc = 1;
     }else{      }else{
Line 18632  static int do_meta_command(char *zLine, ShellState *p) Line 19280  static int do_meta_command(char *zLine, ShellState *p)
     const char *zName = 0;      const char *zName = 0;
     int iSchema = 0;      int iSchema = 0;
     int bDebug = 0;      int bDebug = 0;
       int bNoSystemTabs = 0;
     int ii;      int ii;
   
     open_db(p, 0);      open_db(p, 0);
Line 18644  static int do_meta_command(char *zLine, ShellState *p) Line 19293  static int do_meta_command(char *zLine, ShellState *p)
         data.cMode = data.mode = MODE_Pretty;          data.cMode = data.mode = MODE_Pretty;
       }else if( optionMatch(azArg[ii],"debug") ){        }else if( optionMatch(azArg[ii],"debug") ){
         bDebug = 1;          bDebug = 1;
         }else if( optionMatch(azArg[ii],"nosys") ){
           bNoSystemTabs = 1;
         }else if( azArg[ii][0]=='-' ){
           utf8_printf(stderr, "Unknown option: \"%s\"\n", azArg[ii]);
           rc = 1;
           goto meta_command_exit;
       }else if( zName==0 ){        }else if( zName==0 ){
         zName = azArg[ii];          zName = azArg[ii];
       }else{        }else{
        raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");        raw_printf(stderr, "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
         rc = 1;          rc = 1;
         goto meta_command_exit;          goto meta_command_exit;
       }        }
Line 18733  static int do_meta_command(char *zLine, ShellState *p) Line 19388  static int do_meta_command(char *zLine, ShellState *p)
         appendText(&sSelect, " AND ", 0);          appendText(&sSelect, " AND ", 0);
         sqlite3_free(zQarg);          sqlite3_free(zQarg);
       }        }
      appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"      if( bNoSystemTabs ){
         appendText(&sSelect, "name NOT LIKE 'sqlite_%%' AND ", 0);
       }
       appendText(&sSelect, "sql IS NOT NULL"
                            " ORDER BY snum, rowid", 0);                             " ORDER BY snum, rowid", 0);
       if( bDebug ){        if( bDebug ){
         utf8_printf(p->out, "SQL: %s;\n", sSelect.z);          utf8_printf(p->out, "SQL: %s;\n", sSelect.z);
Line 18754  static int do_meta_command(char *zLine, ShellState *p) Line 19412  static int do_meta_command(char *zLine, ShellState *p)
     }      }
   }else    }else
   
 #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)  
   if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){    if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
    sqlite3_unsupported_selecttrace = nArg>=2 ? (int)integerValue(azArg[1]) : 0xffff;    unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
     sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
   }else    }else
 #endif  
   
 #if defined(SQLITE_ENABLE_SESSION)  #if defined(SQLITE_ENABLE_SESSION)
   if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){    if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
Line 19239  static int do_meta_command(char *zLine, ShellState *p) Line 19896  static int do_meta_command(char *zLine, ShellState *p)
   
   if( c=='s' && strncmp(azArg[0], "show", n)==0 ){    if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
     static const char *azBool[] = { "off", "on", "trigger", "full"};      static const char *azBool[] = { "off", "on", "trigger", "full"};
       const char *zOut;
     int i;      int i;
     if( nArg!=1 ){      if( nArg!=1 ){
       raw_printf(stderr, "Usage: .show\n");        raw_printf(stderr, "Usage: .show\n");
Line 19263  static int do_meta_command(char *zLine, ShellState *p) Line 19921  static int do_meta_command(char *zLine, ShellState *p)
     utf8_printf(p->out,"%12.12s: ", "rowseparator");      utf8_printf(p->out,"%12.12s: ", "rowseparator");
       output_c_string(p->out, p->rowSeparator);        output_c_string(p->out, p->rowSeparator);
       raw_printf(p->out, "\n");        raw_printf(p->out, "\n");
    utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);    switch( p->statsOn ){
       case 0:  zOut = "off";     break;
       default: zOut = "on";      break;
       case 2:  zOut = "stmt";    break;
       case 3:  zOut = "vmstep";  break;
     }
     utf8_printf(p->out, "%12.12s: %s\n","stats", zOut);
     utf8_printf(p->out, "%12.12s: ", "width");      utf8_printf(p->out, "%12.12s: ", "width");
     for (i=0;i<p->nWidth;i++) {      for (i=0;i<p->nWidth;i++) {
       raw_printf(p->out, "%d ", p->colWidth[i]);        raw_printf(p->out, "%d ", p->colWidth[i]);
Line 19275  static int do_meta_command(char *zLine, ShellState *p) Line 19939  static int do_meta_command(char *zLine, ShellState *p)
   
   if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){    if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
     if( nArg==2 ){      if( nArg==2 ){
      p->statsOn = (u8)booleanValue(azArg[1]);      if( strcmp(azArg[1],"stmt")==0 ){
         p->statsOn = 2;
       }else if( strcmp(azArg[1],"vmstep")==0 ){
         p->statsOn = 3;
       }else{
         p->statsOn = (u8)booleanValue(azArg[1]);
       }
     }else if( nArg==1 ){      }else if( nArg==1 ){
       display_stats(p->db, p, 0);        display_stats(p->db, p, 0);
     }else{      }else{
      raw_printf(stderr, "Usage: .stats ?on|off?\n");      raw_printf(stderr, "Usage: .stats ?on|off|stmt|vmstep?\n");
       rc = 1;        rc = 1;
     }      }
   }else    }else
Line 19430  static int do_meta_command(char *zLine, ShellState *p) Line 20100  static int do_meta_command(char *zLine, ShellState *p)
       { "prng_restore",       SQLITE_TESTCTRL_PRNG_RESTORE,  ""               },        { "prng_restore",       SQLITE_TESTCTRL_PRNG_RESTORE,  ""               },
       { "prng_save",          SQLITE_TESTCTRL_PRNG_SAVE,     ""               },        { "prng_save",          SQLITE_TESTCTRL_PRNG_SAVE,     ""               },
       { "prng_seed",          SQLITE_TESTCTRL_PRNG_SEED,     "SEED ?db?"      },        { "prng_seed",          SQLITE_TESTCTRL_PRNG_SEED,     "SEED ?db?"      },
         { "seek_count",         SQLITE_TESTCTRL_SEEK_COUNT,    ""               },
     };      };
     int testctrl = -1;      int testctrl = -1;
     int iCtrl = -1;      int iCtrl = -1;
Line 19483  static int do_meta_command(char *zLine, ShellState *p) Line 20154  static int do_meta_command(char *zLine, ShellState *p)
         /* sqlite3_test_control(int, db, int) */          /* sqlite3_test_control(int, db, int) */
         case SQLITE_TESTCTRL_OPTIMIZATIONS:          case SQLITE_TESTCTRL_OPTIMIZATIONS:
           if( nArg==3 ){            if( nArg==3 ){
            int opt = (int)strtol(azArg[2], 0, 0);            unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0);
             rc2 = sqlite3_test_control(testctrl, p->db, opt);              rc2 = sqlite3_test_control(testctrl, p->db, opt);
             isOk = 3;              isOk = 3;
           }            }
Line 19492  static int do_meta_command(char *zLine, ShellState *p) Line 20163  static int do_meta_command(char *zLine, ShellState *p)
         /* sqlite3_test_control(int) */          /* sqlite3_test_control(int) */
         case SQLITE_TESTCTRL_PRNG_SAVE:          case SQLITE_TESTCTRL_PRNG_SAVE:
         case SQLITE_TESTCTRL_PRNG_RESTORE:          case SQLITE_TESTCTRL_PRNG_RESTORE:
         case SQLITE_TESTCTRL_PRNG_RESET:  
         case SQLITE_TESTCTRL_BYTEORDER:          case SQLITE_TESTCTRL_BYTEORDER:
           if( nArg==2 ){            if( nArg==2 ){
             rc2 = sqlite3_test_control(testctrl);              rc2 = sqlite3_test_control(testctrl);
Line 19566  static int do_meta_command(char *zLine, ShellState *p) Line 20236  static int do_meta_command(char *zLine, ShellState *p)
           }            }
           break;            break;
   
           case SQLITE_TESTCTRL_SEEK_COUNT: {
             u64 x = 0;
             rc2 = sqlite3_test_control(testctrl, p->db, &x);
             utf8_printf(p->out, "%llu\n", x);
             isOk = 3;
             break;
           }
   
 #ifdef YYCOVERAGE  #ifdef YYCOVERAGE
         case SQLITE_TESTCTRL_PARSER_COVERAGE:          case SQLITE_TESTCTRL_PARSER_COVERAGE:
           if( nArg==2 ){            if( nArg==2 ){
Line 19805  static int do_meta_command(char *zLine, ShellState *p) Line 20483  static int do_meta_command(char *zLine, ShellState *p)
     }      }
   }else    }else
   
 #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)  
   if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){    if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
    sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;    unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
     sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
   }else    }else
 #endif  
   
   if( c=='w' && strncmp(azArg[0], "width", n)==0 ){    if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
     int j;      int j;
Line 20144  static void process_sqliterc( Line 20821  static void process_sqliterc(
     if( stdin_is_interactive ){      if( stdin_is_interactive ){
       utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);        utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
     }      }
    process_input(p);    if( process_input(p) && bail_on_error ) exit(1);
     fclose(p->in);      fclose(p->in);
     }else if( sqliterc_override!=0 ){
       utf8_printf(stderr,"cannot open: \"%s\"\n", sqliterc);
       if( bail_on_error ) exit(1);
   }    }
   p->in = inSaved;    p->in = inSaved;
   p->lineno = savedLineno;    p->lineno = savedLineno;
Line 20204  static const char zOptions[] = Line 20884  static const char zOptions[] =
 #endif  #endif
   "   -stats               print memory stats before each finalize\n"    "   -stats               print memory stats before each finalize\n"
   "   -table               set output mode to 'table'\n"    "   -table               set output mode to 'table'\n"
     "   -tabs                set output mode to 'tabs'\n"
   "   -version             show SQLite version\n"    "   -version             show SQLite version\n"
   "   -vfs NAME            use NAME as the default VFS\n"    "   -vfs NAME            use NAME as the default VFS\n"
 #ifdef SQLITE_ENABLE_VFSTRACE  #ifdef SQLITE_ENABLE_VFSTRACE
Line 20294  static char *cmdline_option_value(int argc, char **arg Line 20975  static char *cmdline_option_value(int argc, char **arg
 }  }
   
 #ifndef SQLITE_SHELL_IS_UTF8  #ifndef SQLITE_SHELL_IS_UTF8
#  if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)#  if (defined(_WIN32) || defined(WIN32)) \
    && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__)))
 #    define SQLITE_SHELL_IS_UTF8          (0)  #    define SQLITE_SHELL_IS_UTF8          (0)
 #  else  #  else
 #    define SQLITE_SHELL_IS_UTF8          (1)  #    define SQLITE_SHELL_IS_UTF8          (1)
Line 20461  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ Line 21143  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
       (void)cmdline_option_value(argc, argv, ++i);        (void)cmdline_option_value(argc, argv, ++i);
 #endif  #endif
     }else if( strcmp(z,"-pagecache")==0 ){      }else if( strcmp(z,"-pagecache")==0 ){
      int n, sz;      sqlite3_int64 n, sz;
      sz = (int)integerValue(cmdline_option_value(argc,argv,++i));      sz = integerValue(cmdline_option_value(argc,argv,++i));
       if( sz>70000 ) sz = 70000;        if( sz>70000 ) sz = 70000;
       if( sz<0 ) sz = 0;        if( sz<0 ) sz = 0;
      n = (int)integerValue(cmdline_option_value(argc,argv,++i));      n = integerValue(cmdline_option_value(argc,argv,++i));
       if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){
         n = 0xffffffffffffLL/sz;
       }
       sqlite3_config(SQLITE_CONFIG_PAGECACHE,        sqlite3_config(SQLITE_CONFIG_PAGECACHE,
                     (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);                      (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
       data.shellFlgs |= SHFLG_Pagecache;        data.shellFlgs |= SHFLG_Pagecache;
Line 20527  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ Line 21212  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
 #endif  #endif
     }else if( strcmp(z, "-memtrace")==0 ){      }else if( strcmp(z, "-memtrace")==0 ){
       sqlite3MemTraceActivate(stderr);        sqlite3MemTraceActivate(stderr);
       }else if( strcmp(z,"-bail")==0 ){
         bail_on_error = 1;
     }      }
   }    }
   verify_uninitialized();    verify_uninitialized();
Line 20601  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ Line 21288  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
       data.mode = MODE_List;        data.mode = MODE_List;
     }else if( strcmp(z,"-quote")==0 ){      }else if( strcmp(z,"-quote")==0 ){
       data.mode = MODE_Quote;        data.mode = MODE_Quote;
         sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Comma);
         sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
     }else if( strcmp(z,"-line")==0 ){      }else if( strcmp(z,"-line")==0 ){
       data.mode = MODE_Line;        data.mode = MODE_Line;
     }else if( strcmp(z,"-column")==0 ){      }else if( strcmp(z,"-column")==0 ){
Line 20634  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ Line 21323  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
       data.openFlags |= SQLITE_OPEN_NOFOLLOW;        data.openFlags |= SQLITE_OPEN_NOFOLLOW;
     }else if( strcmp(z,"-ascii")==0 ){      }else if( strcmp(z,"-ascii")==0 ){
       data.mode = MODE_Ascii;        data.mode = MODE_Ascii;
      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,      sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Unit);
                       SEP_Unit);      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Record);
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,    }else if( strcmp(z,"-tabs")==0 ){
                       SEP_Record);      data.mode = MODE_List;
       sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Tab);
       sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
     }else if( strcmp(z,"-separator")==0 ){      }else if( strcmp(z,"-separator")==0 ){
       sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,        sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
                        "%s",cmdline_option_value(argc,argv,++i));                         "%s",cmdline_option_value(argc,argv,++i));
Line 20669  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ Line 21360  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
       */        */
       ShellSetFlag(&data, SHFLG_Backslash);        ShellSetFlag(&data, SHFLG_Backslash);
     }else if( strcmp(z,"-bail")==0 ){      }else if( strcmp(z,"-bail")==0 ){
      bail_on_error = 1;      /* No-op.  The bail_on_error flag should already be set. */
     }else if( strcmp(z,"-version")==0 ){      }else if( strcmp(z,"-version")==0 ){
       printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());        printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
       return 0;        return 0;
Line 20757  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ Line 21448  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
     for(i=0; i<nCmd; i++){      for(i=0; i<nCmd; i++){
       if( azCmd[i][0]=='.' ){        if( azCmd[i][0]=='.' ){
         rc = do_meta_command(azCmd[i], &data);          rc = do_meta_command(azCmd[i], &data);
        if( rc ) return rc==2 ? 0 : rc;        if( rc ){
           free(azCmd);
           return rc==2 ? 0 : rc;
         }
       }else{        }else{
         open_db(&data, 0);          open_db(&data, 0);
         rc = shell_exec(&data, azCmd[i], &zErrMsg);          rc = shell_exec(&data, azCmd[i], &zErrMsg);
        if( zErrMsg!=0 ){        if( zErrMsg || rc ){
          utf8_printf(stderr,"Error: %s\n", zErrMsg);          if( zErrMsg!=0 ){
             utf8_printf(stderr,"Error: %s\n", zErrMsg);
           }else{
             utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
           }
           sqlite3_free(zErrMsg);
           free(azCmd);
           return rc!=0 ? rc : 1;            return rc!=0 ? rc : 1;
         }else if( rc!=0 ){  
           utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);  
           return rc;  
         }          }
       }        }
     }      }
     free(azCmd);  
   }else{    }else{
     /* Run commands received from standard input      /* Run commands received from standard input
     */      */
Line 20816  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ Line 21512  int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
       rc = process_input(&data);        rc = process_input(&data);
     }      }
   }    }
     free(azCmd);
   set_table_name(&data, 0);    set_table_name(&data, 0);
   if( data.db ){    if( data.db ){
     session_close_all(&data);      session_close_all(&data);

Removed from v.1.5  
changed lines
  Added in v.1.6


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>