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-vendor
mailing list