svn commit: r282326 - vendor/sqlite3/dist

Baptiste Daroussin bapt at FreeBSD.org
Fri May 1 21:53:57 UTC 2015


Author: bapt
Date: Fri May  1 21:53:55 2015
New Revision: 282326
URL: https://svnweb.freebsd.org/changeset/base/282326

Log:
  Import sqlite3 3.8.9

Modified:
  vendor/sqlite3/dist/configure
  vendor/sqlite3/dist/configure.ac
  vendor/sqlite3/dist/shell.c
  vendor/sqlite3/dist/sqlite3.1
  vendor/sqlite3/dist/sqlite3.c
  vendor/sqlite3/dist/sqlite3.h

Modified: vendor/sqlite3/dist/configure
==============================================================================
--- vendor/sqlite3/dist/configure	Fri May  1 21:39:04 2015	(r282325)
+++ vendor/sqlite3/dist/configure	Fri May  1 21:53:55 2015	(r282326)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sqlite 3.8.7.2.
+# Generated by GNU Autoconf 2.69 for sqlite 3.8.9.
 #
 # Report bugs to <http://www.sqlite.org>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='sqlite'
 PACKAGE_TARNAME='sqlite'
-PACKAGE_VERSION='3.8.7.2'
-PACKAGE_STRING='sqlite 3.8.7.2'
+PACKAGE_VERSION='3.8.9'
+PACKAGE_STRING='sqlite 3.8.9'
 PACKAGE_BUGREPORT='http://www.sqlite.org'
 PACKAGE_URL=''
 
@@ -1313,7 +1313,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures sqlite 3.8.7.2 to adapt to many kinds of systems.
+\`configure' configures sqlite 3.8.9 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1383,7 +1383,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of sqlite 3.8.7.2:";;
+     short | recursive ) echo "Configuration of sqlite 3.8.9:";;
    esac
   cat <<\_ACEOF
 
@@ -1489,7 +1489,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-sqlite configure 3.8.7.2
+sqlite configure 3.8.9
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1813,7 +1813,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by sqlite $as_me 3.8.7.2, which was
+It was created by sqlite $as_me 3.8.9, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2631,7 +2631,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='sqlite'
- VERSION='3.8.7.2'
+ VERSION='3.8.9'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -13196,7 +13196,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_wri
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by sqlite $as_me 3.8.7.2, which was
+This file was extended by sqlite $as_me 3.8.9, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -13253,7 +13253,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-sqlite config.status 3.8.7.2
+sqlite config.status 3.8.9
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

Modified: vendor/sqlite3/dist/configure.ac
==============================================================================
--- vendor/sqlite3/dist/configure.ac	Fri May  1 21:39:04 2015	(r282325)
+++ vendor/sqlite3/dist/configure.ac	Fri May  1 21:53:55 2015	(r282326)
@@ -8,7 +8,7 @@
 #
 
 AC_PREREQ(2.61)
-AC_INIT(sqlite, 3.8.7.2, http://www.sqlite.org)
+AC_INIT(sqlite, 3.8.9, http://www.sqlite.org)
 AC_CONFIG_SRCDIR([sqlite3.c])
 
 # Use automake.

Modified: vendor/sqlite3/dist/shell.c
==============================================================================
--- vendor/sqlite3/dist/shell.c	Fri May  1 21:39:04 2015	(r282325)
+++ vendor/sqlite3/dist/shell.c	Fri May  1 21:53:55 2015	(r282326)
@@ -18,6 +18,20 @@
 #endif
 
 /*
+** If requested, include the SQLite compiler options file for MSVC.
+*/
+#if defined(INCLUDE_MSVC_H)
+#include "msvc.h"
+#endif
+
+/*
+** 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
@@ -48,23 +62,42 @@
 # include <sys/types.h>
 #endif
 
-#if defined(HAVE_READLINE) && HAVE_READLINE!=0
+#if HAVE_READLINE
 # include <readline/readline.h>
 # include <readline/history.h>
-#else
-# undef HAVE_READLINE
 #endif
-#if defined(HAVE_EDITLINE) && !defined(HAVE_READLINE)
-# define HAVE_READLINE 1
+
+#if HAVE_EDITLINE
 # include <editline/readline.h>
 #endif
-#if !defined(HAVE_READLINE)
-# define add_history(X)
-# define read_history(X)
-# define write_history(X)
-# define stifle_history(X)
+
+#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
 
+
 #if defined(_WIN32) || defined(WIN32)
 # include <io.h>
 # include <fcntl.h>
@@ -81,10 +114,15 @@
 */
 extern int isatty(int);
 
-/* 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*);
+#if !defined(__RTP__) && !defined(_WRS_KERNEL)
+  /* 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)
@@ -100,6 +138,26 @@ extern int pclose(FILE*);
 #define IsDigit(X)  isdigit((unsigned char)X)
 #define ToLower(X)  (char)tolower((unsigned char)X)
 
+/* 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)
+static void setBinaryMode(FILE *out){
+  fflush(out);
+  _setmode(_fileno(out), _O_BINARY);
+}
+static void setTextMode(FILE *out){
+  fflush(out);
+  _setmode(_fileno(out), _O_TEXT);
+}
+#else
+# define setBinaryMode(X)
+# define setTextMode(X)
+#endif
+
 
 /* True if the timer is enabled */
 static int enableTimer = 0;
@@ -119,11 +177,19 @@ static sqlite3_int64 timeOfDay(void){
   return t;
 }
 
-#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
- && !defined(__minux)
+#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 */
@@ -149,8 +215,8 @@ static double timeDiff(struct timeval *p
 */
 static void endTimer(void){
   if( enableTimer ){
-    struct rusage sEnd;
     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,
@@ -172,7 +238,8 @@ static HANDLE hProcess;
 static FILETIME ftKernelBegin;
 static FILETIME ftUserBegin;
 static sqlite3_int64 ftWallBegin;
-typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME);
+typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
+                                    LPFILETIME, LPFILETIME);
 static GETPROCTIMES getProcessTimesAddr = NULL;
 
 /*
@@ -183,15 +250,16 @@ static int hasTimer(void){
   if( getProcessTimesAddr ){
     return 1;
   } else {
-    /* 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.
+    /* 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");
+        getProcessTimesAddr =
+            (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
         if( NULL != getProcessTimesAddr ){
           return 1;
         }
@@ -208,7 +276,8 @@ static int hasTimer(void){
 static void beginTimer(void){
   if( enableTimer && getProcessTimesAddr ){
     FILETIME ftCreation, ftExit;
-    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelBegin, &ftUserBegin);
+    getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
+                        &ftKernelBegin,&ftUserBegin);
     ftWallBegin = timeOfDay();
   }
 }
@@ -227,7 +296,7 @@ static void endTimer(void){
   if( enableTimer && getProcessTimesAddr){
     FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
     sqlite3_int64 ftWallEnd = timeOfDay();
-    getProcessTimesAddr(hProcess, &ftCreation, &ftExit, &ftKernelEnd, &ftUserEnd);
+    getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
     printf("Run Time: real %.3f user %f sys %f\n",
        (ftWallEnd - ftWallBegin)*0.001,
        timeDiff(&ftUserBegin, &ftUserEnd),
@@ -301,7 +370,7 @@ static FILE *iotrace = 0;
 ** is written to iotrace.
 */
 #ifdef SQLITE_ENABLE_IOTRACE
-static void iotracePrintf(const char *zFormat, ...){
+static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
   va_list ap;
   char *z;
   if( iotrace==0 ) return;
@@ -422,14 +491,14 @@ static char *one_input_line(FILE *in, ch
     zResult = local_getline(zPrior, in);
   }else{
     zPrompt = isContinuation ? continuePrompt : mainPrompt;
-#if defined(HAVE_READLINE)
-    free(zPrior);
-    zResult = readline(zPrompt);
-    if( zResult && *zResult ) add_history(zResult);
-#else
+#if SHELL_USE_LOCAL_GETLINE
     printf("%s", zPrompt);
     fflush(stdout);
     zResult = local_getline(zPrior, stdin);
+#else
+    free(zPrior);
+    zResult = shell_readline(zPrompt);
+    if( zResult && *zResult ) shell_add_history(zResult);
 #endif
   }
   return zResult;
@@ -457,6 +526,7 @@ struct ShellState {
   int echoOn;            /* True to echo input commands */
   int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
   int statsOn;           /* True to display memory stats before each finalize */
+  int scanstatsOn;       /* True to display scan stats before each finalize */
   int outCount;          /* Revert to stdout when reaching zero */
   int cnt;               /* Number of records displayed so far */
   FILE *out;             /* Write results here */
@@ -467,11 +537,11 @@ struct ShellState {
   int showHeader;        /* True to show column names in List or Column mode */
   unsigned shellFlgs;    /* Various flags */
   char *zDestTable;      /* Name of destination table when MODE_Insert */
-  char separator[20];    /* Separator character for MODE_List */
-  char newline[20];      /* Record separator in MODE_Csv */
+  char colSeparator[20]; /* Column separator character for several modes */
+  char rowSeparator[20]; /* Row separator character for MODE_Ascii */
   int colWidth[100];     /* Requested width of each column when in column mode*/
   int actualWidth[100];  /* Actual width of each column */
-  char nullvalue[20];    /* The text to print when a NULL comes back from
+  char nullValue[20];    /* The text to print when a NULL comes back from
                          ** the database */
   SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
   char outfile[FILENAME_MAX]; /* Filename for *out */
@@ -504,6 +574,7 @@ struct ShellState {
 #define MODE_Tcl      6  /* Generate ANSI-C or TCL quoted elements */
 #define MODE_Csv      7  /* Quote strings, numbers are plain */
 #define MODE_Explain  8  /* Like MODE_Column, but do not truncate data */
+#define MODE_Ascii    9  /* Use ASCII unit and record separators (0x1F/0x1E) */
 
 static const char *modeDescr[] = {
   "line",
@@ -515,9 +586,23 @@ static const char *modeDescr[] = {
   "tcl",
   "csv",
   "explain",
+  "ascii",
 };
 
 /*
+** These are the column/row/line separators used by the various
+** import/export modes.
+*/
+#define SEP_Column    "|"
+#define SEP_Row       "\n"
+#define SEP_Tab       "\t"
+#define SEP_Space     " "
+#define SEP_Comma     ","
+#define SEP_CrLf      "\r\n"
+#define SEP_Unit      "\x1F"
+#define SEP_Record    "\x1E"
+
+/*
 ** Number of elements in an array
 */
 #define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
@@ -559,6 +644,7 @@ static void output_hex_blob(FILE *out, c
 static void output_quoted_string(FILE *out, const char *z){
   int i;
   int nSingle = 0;
+  setBinaryMode(out);
   for(i=0; z[i]; i++){
     if( z[i]=='\'' ) nSingle++;
   }
@@ -581,6 +667,7 @@ static void output_quoted_string(FILE *o
     }
     fprintf(out,"'");
   }
+  setTextMode(out);
 }
 
 /*
@@ -673,22 +760,22 @@ static const char needCsvQuote[] = {
 };
 
 /*
-** Output a single term of CSV.  Actually, p->separator is used for
-** the separator, which may or may not be a comma.  p->nullvalue is
+** Output a single term of CSV.  Actually, p->colSeparator is used for
+** the separator, which may or may not be a comma.  p->nullValue is
 ** the null value.  Strings are quoted if necessary.  The separator
 ** is only issued if bSep is true.
 */
 static void output_csv(ShellState *p, const char *z, int bSep){
   FILE *out = p->out;
   if( z==0 ){
-    fprintf(out,"%s",p->nullvalue);
+    fprintf(out,"%s",p->nullValue);
   }else{
     int i;
-    int nSep = strlen30(p->separator);
+    int nSep = strlen30(p->colSeparator);
     for(i=0; z[i]; i++){
       if( needCsvQuote[((unsigned char*)z)[i]] 
-         || (z[i]==p->separator[0] && 
-             (nSep==1 || memcmp(z, p->separator, nSep)==0)) ){
+         || (z[i]==p->colSeparator[0] && 
+             (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
         i = 0;
         break;
       }
@@ -705,7 +792,7 @@ static void output_csv(ShellState *p, co
     }
   }
   if( bSep ){
-    fprintf(p->out, "%s", p->separator);
+    fprintf(p->out, "%s", p->colSeparator);
   }
 }
 
@@ -725,7 +812,13 @@ static void interrupt_handler(int NotUse
 ** This is the callback routine that the shell
 ** invokes for each row of a query result.
 */
-static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int *aiType){
+static int shell_callback(
+  void *pArg,
+  int nArg,        /* Number of result columns */
+  char **azArg,    /* Text of each result column */
+  char **azCol,    /* Column names */
+  int *aiType      /* Column types */
+){
   int i;
   ShellState *p = (ShellState*)pArg;
 
@@ -737,10 +830,10 @@ static int shell_callback(void *pArg, in
         int len = strlen30(azCol[i] ? azCol[i] : "");
         if( len>w ) w = len;
       }
-      if( p->cnt++>0 ) fprintf(p->out,"\n");
+      if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
       for(i=0; i<nArg; i++){
-        fprintf(p->out,"%*s = %s\n", w, azCol[i],
-                azArg[i] ? azArg[i] : p->nullvalue);
+        fprintf(p->out,"%*s = %s%s", w, azCol[i],
+                azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
       }
       break;
     }
@@ -757,7 +850,7 @@ static int shell_callback(void *pArg, in
           if( w==0 ){
             w = strlen30(azCol[i] ? azCol[i] : "");
             if( w<10 ) w = 10;
-            n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullvalue);
+            n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
             if( w<n ) w = n;
           }
           if( i<ArraySize(p->actualWidth) ){
@@ -765,9 +858,11 @@ static int shell_callback(void *pArg, in
           }
           if( p->showHeader ){
             if( w<0 ){
-              fprintf(p->out,"%*.*s%s",-w,-w,azCol[i], i==nArg-1 ? "\n": "  ");
+              fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
+                      i==nArg-1 ? p->rowSeparator : "  ");
             }else{
-              fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": "  ");
+              fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
+                      i==nArg-1 ? p->rowSeparator : "  ");
             }
           }
         }
@@ -782,7 +877,7 @@ static int shell_callback(void *pArg, in
             }
             fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
                    "----------------------------------------------------------",
-                    i==nArg-1 ? "\n": "  ");
+                    i==nArg-1 ? p->rowSeparator : "  ");
           }
         }
       }
@@ -805,10 +900,12 @@ static int shell_callback(void *pArg, in
         }
         if( w<0 ){
           fprintf(p->out,"%*.*s%s",-w,-w,
-              azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
+              azArg[i] ? azArg[i] : p->nullValue,
+              i==nArg-1 ? p->rowSeparator : "  ");
         }else{
           fprintf(p->out,"%-*.*s%s",w,w,
-              azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": "  ");
+              azArg[i] ? azArg[i] : p->nullValue,
+              i==nArg-1 ? p->rowSeparator : "  ");
         }
       }
       break;
@@ -817,20 +914,21 @@ static int shell_callback(void *pArg, in
     case MODE_List: {
       if( p->cnt++==0 && p->showHeader ){
         for(i=0; i<nArg; i++){
-          fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
+          fprintf(p->out,"%s%s",azCol[i],
+                  i==nArg-1 ? p->rowSeparator : p->colSeparator);
         }
       }
       if( azArg==0 ) break;
       for(i=0; i<nArg; i++){
         char *z = azArg[i];
-        if( z==0 ) z = p->nullvalue;
+        if( z==0 ) z = p->nullValue;
         fprintf(p->out, "%s", z);
         if( i<nArg-1 ){
-          fprintf(p->out, "%s", p->separator);
+          fprintf(p->out, "%s", p->colSeparator);
         }else if( p->mode==MODE_Semi ){
-          fprintf(p->out, ";\n");
+          fprintf(p->out, ";%s", p->rowSeparator);
         }else{
-          fprintf(p->out, "\n");
+          fprintf(p->out, "%s", p->rowSeparator);
         }
       }
       break;
@@ -849,7 +947,7 @@ static int shell_callback(void *pArg, in
       fprintf(p->out,"<TR>");
       for(i=0; i<nArg; i++){
         fprintf(p->out,"<TD>");
-        output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
+        output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
         fprintf(p->out,"</TD>\n");
       }
       fprintf(p->out,"</TR>\n");
@@ -859,39 +957,33 @@ static int shell_callback(void *pArg, in
       if( p->cnt++==0 && p->showHeader ){
         for(i=0; i<nArg; i++){
           output_c_string(p->out,azCol[i] ? azCol[i] : "");
-          if(i<nArg-1) fprintf(p->out, "%s", p->separator);
+          if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
         }
-        fprintf(p->out,"\n");
+        fprintf(p->out, "%s", p->rowSeparator);
       }
       if( azArg==0 ) break;
       for(i=0; i<nArg; i++){
-        output_c_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
-        if(i<nArg-1) fprintf(p->out, "%s", p->separator);
+        output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
+        if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
       }
-      fprintf(p->out,"\n");
+      fprintf(p->out, "%s", p->rowSeparator);
       break;
     }
     case MODE_Csv: {
-#if defined(WIN32) || defined(_WIN32)
-      fflush(p->out);
-      _setmode(_fileno(p->out), _O_BINARY);
-#endif
+      setBinaryMode(p->out);
       if( p->cnt++==0 && p->showHeader ){
         for(i=0; i<nArg; i++){
           output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
         }
-        fprintf(p->out,"%s",p->newline);
+        fprintf(p->out, "%s", p->rowSeparator);
       }
-      if( azArg>0 ){
+      if( nArg>0 ){
         for(i=0; i<nArg; i++){
           output_csv(p, azArg[i], i<nArg-1);
         }
-        fprintf(p->out,"%s",p->newline);
+        fprintf(p->out, "%s", p->rowSeparator);
       }
-#if defined(WIN32) || defined(_WIN32)
-      fflush(p->out);
-      _setmode(_fileno(p->out), _O_TEXT);
-#endif
+      setTextMode(p->out);
       break;
     }
     case MODE_Insert: {
@@ -923,6 +1015,22 @@ static int shell_callback(void *pArg, in
       fprintf(p->out,");\n");
       break;
     }
+    case MODE_Ascii: {
+      if( p->cnt++==0 && p->showHeader ){
+        for(i=0; i<nArg; i++){
+          if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
+          fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
+        }
+        fprintf(p->out, "%s", p->rowSeparator);
+      }
+      if( azArg==0 ) break;
+      for(i=0; i<nArg; i++){
+        if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
+        fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
+      }
+      fprintf(p->out, "%s", p->rowSeparator);
+      break;
+    }
   }
   return 0;
 }
@@ -1104,57 +1212,77 @@ static int display_stats(
     
     iHiwtr = iCur = -1;
     sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Memory Used:                         %d (max %d) bytes\n", iCur, iHiwtr);
+    fprintf(pArg->out,
+            "Memory Used:                         %d (max %d) bytes\n",
+            iCur, iHiwtr);
     iHiwtr = iCur = -1;
     sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Number of Outstanding Allocations:   %d (max %d)\n", iCur, iHiwtr);
+    fprintf(pArg->out, "Number of Outstanding Allocations:   %d (max %d)\n",
+            iCur, iHiwtr);
     if( pArg->shellFlgs & SHFLG_Pagecache ){
       iHiwtr = iCur = -1;
       sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
-      fprintf(pArg->out, "Number of Pcache Pages Used:         %d (max %d) pages\n", iCur, iHiwtr);
+      fprintf(pArg->out,
+              "Number of Pcache Pages Used:         %d (max %d) pages\n",
+              iCur, iHiwtr);
     }
     iHiwtr = iCur = -1;
     sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Number of Pcache Overflow Bytes:     %d (max %d) bytes\n", iCur, iHiwtr);
+    fprintf(pArg->out,
+            "Number of Pcache Overflow Bytes:     %d (max %d) bytes\n",
+            iCur, iHiwtr);
     if( pArg->shellFlgs & SHFLG_Scratch ){
       iHiwtr = iCur = -1;
       sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
-      fprintf(pArg->out, "Number of Scratch Allocations Used:  %d (max %d)\n", iCur, iHiwtr);
+      fprintf(pArg->out, "Number of Scratch Allocations Used:  %d (max %d)\n",
+              iCur, iHiwtr);
     }
     iHiwtr = iCur = -1;
     sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Number of Scratch Overflow Bytes:    %d (max %d) bytes\n", iCur, iHiwtr);
+    fprintf(pArg->out,
+            "Number of Scratch Overflow Bytes:    %d (max %d) bytes\n",
+            iCur, iHiwtr);
     iHiwtr = iCur = -1;
     sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Largest Allocation:                  %d bytes\n", iHiwtr);
+    fprintf(pArg->out, "Largest Allocation:                  %d bytes\n",
+            iHiwtr);
     iHiwtr = iCur = -1;
     sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Largest Pcache Allocation:           %d bytes\n", iHiwtr);
+    fprintf(pArg->out, "Largest Pcache Allocation:           %d bytes\n",
+            iHiwtr);
     iHiwtr = iCur = -1;
     sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Largest Scratch Allocation:          %d bytes\n", iHiwtr);
+    fprintf(pArg->out, "Largest Scratch Allocation:          %d bytes\n",
+            iHiwtr);
 #ifdef YYTRACKMAXSTACKDEPTH
     iHiwtr = iCur = -1;
     sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Deepest Parser Stack:                %d (max %d)\n", iCur, iHiwtr);
+    fprintf(pArg->out, "Deepest Parser Stack:                %d (max %d)\n",
+            iCur, iHiwtr);
 #endif
   }
 
   if( pArg && pArg->out && db ){
     if( pArg->shellFlgs & SHFLG_Lookaside ){
       iHiwtr = iCur = -1;
-      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
-      fprintf(pArg->out, "Lookaside Slots Used:                %d (max %d)\n", iCur, iHiwtr);
-      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
+      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
+                        &iCur, &iHiwtr, bReset);
+      fprintf(pArg->out, "Lookaside Slots Used:                %d (max %d)\n",
+              iCur, iHiwtr);
+      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
+                        &iCur, &iHiwtr, bReset);
       fprintf(pArg->out, "Successful lookaside attempts:       %d\n", iHiwtr);
-      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
+      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
+                        &iCur, &iHiwtr, bReset);
       fprintf(pArg->out, "Lookaside failures due to size:      %d\n", iHiwtr);
-      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
+      sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
+                        &iCur, &iHiwtr, bReset);
       fprintf(pArg->out, "Lookaside failures due to OOM:       %d\n", iHiwtr);
     }
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Pager Heap Usage:                    %d bytes\n", iCur);    iHiwtr = iCur = -1;
+    fprintf(pArg->out, "Pager Heap Usage:                    %d bytes\n",iCur);
+    iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
     fprintf(pArg->out, "Page cache hits:                     %d\n", iCur);
     iHiwtr = iCur = -1;
@@ -1165,18 +1293,19 @@ static int display_stats(
     fprintf(pArg->out, "Page cache writes:                   %d\n", iCur); 
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Schema Heap Usage:                   %d bytes\n", iCur); 
+    fprintf(pArg->out, "Schema Heap Usage:                   %d bytes\n",iCur); 
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
-    fprintf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n", iCur); 
+    fprintf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n",iCur); 
   }
 
   if( pArg && pArg->out && db && pArg->pStmt ){
-    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
+    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
+                               bReset);
     fprintf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
     fprintf(pArg->out, "Sort Operations:                     %d\n", iCur);
-    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
+    iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
     fprintf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
     fprintf(pArg->out, "Virtual Machine Steps:               %d\n", iCur);
@@ -1186,6 +1315,51 @@ static int display_stats(
 }
 
 /*
+** Display scan stats.
+*/
+static void display_scanstats(
+  sqlite3 *db,                    /* Database to query */
+  ShellState *pArg                /* Pointer to ShellState */
+){
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+  int i, k, n, mx;
+  fprintf(pArg->out, "-------- scanstats --------\n");
+  mx = 0;
+  for(k=0; k<=mx; k++){
+    double rEstLoop = 1.0;
+    for(i=n=0; 1; i++){
+      sqlite3_stmt *p = pArg->pStmt;
+      sqlite3_int64 nLoop, nVisit;
+      double rEst;
+      int iSid;
+      const char *zExplain;
+      if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
+        break;
+      }
+      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
+      if( iSid>mx ) mx = iSid;
+      if( iSid!=k ) continue;
+      if( n==0 ){
+        rEstLoop = (double)nLoop;
+        if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
+      }
+      n++;
+      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
+      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
+      sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
+      fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
+      rEstLoop *= rEst;
+      fprintf(pArg->out, 
+          "         nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
+          nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
+      );
+    }
+  }
+  fprintf(pArg->out, "---------------------------\n");
+#endif
+}
+
+/*
 ** Parameter azArray points to a zero-terminated array of strings. zStr
 ** points to a single nul-terminated string. Return non-zero if zStr
 ** is equal, according to strcmp(), to any of the strings in the array.
@@ -1226,7 +1400,8 @@ static void explain_data_prepare(ShellSt
 
   const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
                            "NextIfOpen", "PrevIfOpen", 0 };
-  const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", "Rewind", 0 };
+  const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
+                            "Rewind", 0 };
   const char *azGoto[] = { "Goto", 0 };
 
   /* Try to figure out if this is really an EXPLAIN statement. If this
@@ -1339,7 +1514,8 @@ static int shell_exec(
       /* Show the EXPLAIN QUERY PLAN if .eqp is on */
       if( pArg && pArg->autoEQP ){
         sqlite3_stmt *pExplain;
-        char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", sqlite3_sql(pStmt));
+        char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
+                                     sqlite3_sql(pStmt));
         rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
         if( rc==SQLITE_OK ){
           while( sqlite3_step(pExplain)==SQLITE_ROW ){
@@ -1423,6 +1599,11 @@ static int shell_exec(
         display_stats(db, pArg, 0);
       }
 
+      /* print loop-counters if required */
+      if( pArg && pArg->scanstatsOn ){
+        display_scanstats(db, pArg);
+      }
+
       /* Finalize the statement just executed. If this fails, save a 
       ** copy of the error message. Otherwise, set zSql to point to the
       ** next statement to execute. */
@@ -1592,6 +1773,7 @@ static char zHelp[] =
   ".bail on|off           Stop after hitting an error.  Default OFF\n"
   ".clone NEWDB           Clone data into NEWDB from the existing database\n"
   ".databases             List names and files of attached databases\n"
+  ".dbinfo ?DB?           Show status information about the database\n"
   ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
   "                         If TABLE specified, only dump tables matching\n"
   "                         LIKE pattern TABLE.\n"
@@ -1604,8 +1786,8 @@ static char zHelp[] =
   ".headers on|off        Turn display of headers on or off\n"
   ".help                  Show this message\n"
   ".import FILE TABLE     Import data from FILE into TABLE\n"
-  ".indices ?TABLE?       Show names of all indices\n"
-  "                         If TABLE specified, only show indices for tables\n"
+  ".indexes ?TABLE?       Show names of all indexes\n"
+  "                         If TABLE specified, only show indexes for tables\n"
   "                         matching LIKE pattern TABLE.\n"
 #ifdef SQLITE_ENABLE_IOTRACE
   ".iotrace FILE          Enable I/O diagnostic logging to FILE\n"
@@ -1615,12 +1797,13 @@ static char zHelp[] =
 #endif
   ".log FILE|off          Turn logging on or off.  FILE can be stderr/stdout\n"
   ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
+  "                         ascii    Columns/rows delimited by 0x1F and 0x1E\n"
   "                         csv      Comma-separated values\n"
   "                         column   Left-aligned columns.  (See .width)\n"
   "                         html     HTML <table> code\n"
   "                         insert   SQL insert statements for TABLE\n"
   "                         line     One value per line\n"
-  "                         list     Values delimited by .separator string\n"
+  "                         list     Values delimited by .separator strings\n"
   "                         tabs     Tab-separated values\n"
   "                         tcl      TCL list elements\n"
   ".nullvalue STRING      Use STRING in place of NULL values\n"
@@ -1633,11 +1816,12 @@ static char zHelp[] =
   ".read FILENAME         Execute SQL in FILENAME\n"
   ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
   ".save FILE             Write in-memory database into FILE\n"
+  ".scanstats on|off      Turn sqlite3_stmt_scanstatus() metrics on or off\n"
   ".schema ?TABLE?        Show the CREATE statements\n"
   "                         If TABLE specified, only show tables matching\n"
   "                         LIKE pattern TABLE.\n"
-  ".separator STRING ?NL? Change separator used by output mode and .import\n"
-  "                         NL is the end-of-line mark for CSV\n"
+  ".separator COL ?ROW?   Change the column separator and optionally the row\n"
+  "                         separator for both the output mode and .import\n"
   ".shell CMD ARGS...     Run CMD ARGS... in a system shell\n"
   ".show                  Show the current values for various settings\n"
   ".stats on|off          Turn stats on or off\n"
@@ -1918,10 +2102,10 @@ static void test_breakpoint(void){
 }
 
 /*
-** An object used to read a CSV file
+** An object used to read a CSV and other files for import.
 */
-typedef struct CSVReader CSVReader;
-struct CSVReader {
+typedef struct ImportCtx ImportCtx;
+struct ImportCtx {
   const char *zFile;  /* Name of the input file */
   FILE *in;           /* Read the CSV text from this input stream */
   char *z;            /* Accumulated text for a field */
@@ -1929,11 +2113,12 @@ struct CSVReader {
   int nAlloc;         /* Space allocated for z[] */
   int nLine;          /* Current line number */
   int cTerm;          /* Character that terminated the most recent field */
-  int cSeparator;     /* The separator character.  (Usually ",") */
+  int cColSep;        /* The column separator character.  (Usually ",") */
+  int cRowSep;        /* The row separator character.  (Usually "\n") */
 };
 
 /* Append a single byte to z[] */
-static void csv_append_char(CSVReader *p, int c){
+static void import_append_char(ImportCtx *p, int c){
   if( p->n+1>=p->nAlloc ){
     p->nAlloc += p->nAlloc + 100;
     p->z = sqlite3_realloc(p->z, p->nAlloc);
@@ -1951,15 +2136,17 @@ static void csv_append_char(CSVReader *p
 **   +  Input comes from p->in.
 **   +  Store results in p->z of length p->n.  Space to hold p->z comes
 **      from sqlite3_malloc().
-**   +  Use p->cSep as the separator.  The default is ",".
+**   +  Use p->cSep as the column separator.  The default is ",".
+**   +  Use p->rSep as the row separator.  The default is "\n".
 **   +  Keep track of the line number in p->nLine.
 **   +  Store the character that terminates the field in p->cTerm.  Store
 **      EOF on end-of-file.
 **   +  Report syntax errors on stderr
 */
-static char *csv_read_one_field(CSVReader *p){
-  int c, pc, ppc;
-  int cSep = p->cSeparator;
+static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
+  int c;
+  int cSep = p->cColSep;
+  int rSep = p->cRowSep;
   p->n = 0;
   c = fgetc(p->in);
   if( c==EOF || seenInterrupt ){
@@ -1967,12 +2154,13 @@ static char *csv_read_one_field(CSVReade
     return 0;
   }
   if( c=='"' ){
+    int pc, ppc;
     int startLine = p->nLine;
     int cQuote = c;
     pc = ppc = 0;
     while( 1 ){
       c = fgetc(p->in);
-      if( c=='\n' ) p->nLine++;
+      if( c==rSep ) p->nLine++;
       if( c==cQuote ){
         if( pc==cQuote ){
           pc = 0;
@@ -1980,8 +2168,8 @@ static char *csv_read_one_field(CSVReade
         }
       }
       if( (c==cSep && pc==cQuote)
-       || (c=='\n' && pc==cQuote)
-       || (c=='\n' && pc=='\r' && ppc==cQuote)
+       || (c==rSep && pc==cQuote)
+       || (c==rSep && pc=='\r' && ppc==cQuote)
        || (c==EOF && pc==cQuote)
       ){
         do{ p->n--; }while( p->z[p->n]!=cQuote );
@@ -1995,19 +2183,19 @@ static char *csv_read_one_field(CSVReade
       if( c==EOF ){
         fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
                 p->zFile, startLine, cQuote);
-        p->cTerm = EOF;
+        p->cTerm = c;
         break;
       }
-      csv_append_char(p, c);
+      import_append_char(p, c);
       ppc = pc;
       pc = c;
     }
   }else{
-    while( c!=EOF && c!=cSep && c!='\n' ){
-      csv_append_char(p, c);
+    while( c!=EOF && c!=cSep && c!=rSep ){
+      import_append_char(p, c);
       c = fgetc(p->in);
     }
-    if( c=='\n' ){
+    if( c==rSep ){
       p->nLine++;
       if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
     }
@@ -2017,6 +2205,40 @@ static char *csv_read_one_field(CSVReade
   return p->z;
 }
 
+/* Read a single field of ASCII delimited text.
+**
+**   +  Input comes from p->in.
+**   +  Store results in p->z of length p->n.  Space to hold p->z comes
+**      from sqlite3_malloc().
+**   +  Use p->cSep as the column separator.  The default is "\x1F".
+**   +  Use p->rSep as the row separator.  The default is "\x1E".
+**   +  Keep track of the row number in p->nLine.
+**   +  Store the character that terminates the field in p->cTerm.  Store
+**      EOF on end-of-file.
+**   +  Report syntax errors on stderr
+*/
+static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
+  int c;
+  int cSep = p->cColSep;
+  int rSep = p->cRowSep;
+  p->n = 0;
+  c = fgetc(p->in);
+  if( c==EOF || seenInterrupt ){
+    p->cTerm = EOF;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list