blob: 789a464d09125038ee0fdd12ebeeff1273e3263c [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
mistachkin2318d332015-01-12 18:02:52 +000021** If requested, include the SQLite compiler options file for MSVC.
22*/
23#if defined(INCLUDE_MSVC_H)
24#include "msvc.h"
25#endif
26
27/*
drh8cd5b252015-03-02 22:06:43 +000028** No support for loadable extensions in VxWorks.
29*/
drhada3f2b2015-03-23 21:32:50 +000030#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
drh8cd5b252015-03-02 22:06:43 +000031# define SQLITE_OMIT_LOAD_EXTENSION 1
32#endif
33
34/*
drh36f7dd32011-10-13 16:02:17 +000035** Enable large-file support for fopen() and friends on unix.
36*/
37#ifndef SQLITE_DISABLE_LFS
38# define _LARGE_FILE 1
39# ifndef _FILE_OFFSET_BITS
40# define _FILE_OFFSET_BITS 64
41# endif
42# define _LARGEFILE_SOURCE 1
43#endif
44
drh75897232000-05-29 14:26:00 +000045#include <stdlib.h>
46#include <string.h>
47#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000048#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000049#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000050#if SQLITE_USER_AUTHENTICATION
51# include "sqlite3userauth.h"
52#endif
drh75897232000-05-29 14:26:00 +000053#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000054#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000055
drh83905c92012-06-21 13:00:37 +000056#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000057# include <signal.h>
chw97185482008-11-17 08:05:31 +000058# if !defined(__RTP__) && !defined(_WRS_KERNEL)
59# include <pwd.h>
60# endif
drhdd45df82002-04-18 12:39:03 +000061# include <unistd.h>
62# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000063#endif
drh75897232000-05-29 14:26:00 +000064
drh0ede9eb2015-01-10 16:49:23 +000065#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000066# include <readline/readline.h>
67# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000068#endif
danfd34d6d2015-02-25 10:54:53 +000069
drh0ede9eb2015-01-10 16:49:23 +000070#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000071# include <editline/readline.h>
72#endif
danfd34d6d2015-02-25 10:54:53 +000073
74#if HAVE_EDITLINE || HAVE_READLINE
75
76# define shell_add_history(X) add_history(X)
77# define shell_read_history(X) read_history(X)
78# define shell_write_history(X) write_history(X)
79# define shell_stifle_history(X) stifle_history(X)
80# define shell_readline(X) readline(X)
81
82#elif HAVE_LINENOISE
83
84# include "linenoise.h"
85# define shell_add_history(X) linenoiseHistoryAdd(X)
86# define shell_read_history(X) linenoiseHistoryLoad(X)
87# define shell_write_history(X) linenoiseHistorySave(X)
88# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
89# define shell_readline(X) linenoise(X)
90
91#else
92
93# define shell_read_history(X)
94# define shell_write_history(X)
95# define shell_stifle_history(X)
96
97# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000098#endif
99
danfd34d6d2015-02-25 10:54:53 +0000100
adamd2e8464a2006-09-06 21:39:40 +0000101#if defined(_WIN32) || defined(WIN32)
102# include <io.h>
drh6976c212014-07-24 12:09:47 +0000103# include <fcntl.h>
mistachkin073664d2015-06-17 18:57:37 +0000104# define isatty(h) _isatty(h)
105# ifndef access
106# define access(f,m) _access((f),(m))
107# endif
108# undef popen
109# define popen _popen
110# undef pclose
111# define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
mistachkin073664d2015-06-17 18:57:37 +0000113 /* Make sure isatty() has a prototype. */
114 extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000115
mistachkin073664d2015-06-17 18:57:37 +0000116# if !defined(__RTP__) && !defined(_WRS_KERNEL)
117 /* popen and pclose are not C89 functions and so are
118 ** sometimes omitted from the <stdio.h> header */
119 extern FILE *popen(const char*,const char*);
120 extern int pclose(FILE*);
121# else
122# define SQLITE_OMIT_POPEN 1
123# endif
mistachkinf6418892013-08-28 01:54:12 +0000124#endif
drh53371f92013-07-25 17:07:03 +0000125
chw65d3c132007-11-12 21:09:10 +0000126#if defined(_WIN32_WCE)
127/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
128 * thus we always assume that we have a console. That can be
129 * overridden with the -batch command line option.
130 */
131#define isatty(x) 1
132#endif
133
drhf0693c82011-10-11 20:41:54 +0000134/* ctype macros that work with signed characters */
135#define IsSpace(X) isspace((unsigned char)X)
136#define IsDigit(X) isdigit((unsigned char)X)
137#define ToLower(X) (char)tolower((unsigned char)X)
138
drh047d4532015-01-18 20:30:23 +0000139/* On Windows, we normally run with output mode of TEXT so that \n characters
140** are automatically translated into \r\n. However, this behavior needs
141** to be disabled in some cases (ex: when generating CSV output and when
142** rendering quoted strings that contain \n characters). The following
143** routines take care of that.
144*/
145#if defined(_WIN32) || defined(WIN32)
mistachkine4a0d792015-01-27 21:24:33 +0000146static void setBinaryMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000147 fflush(out);
148 _setmode(_fileno(out), _O_BINARY);
149}
mistachkine4a0d792015-01-27 21:24:33 +0000150static void setTextMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000151 fflush(out);
152 _setmode(_fileno(out), _O_TEXT);
153}
154#else
155# define setBinaryMode(X)
156# define setTextMode(X)
157#endif
158
drh43408312013-10-30 12:43:36 +0000159
160/* True if the timer is enabled */
161static int enableTimer = 0;
162
163/* Return the current wall-clock time */
164static sqlite3_int64 timeOfDay(void){
165 static sqlite3_vfs *clockVfs = 0;
166 sqlite3_int64 t;
167 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
dan3fd415b2015-11-16 08:54:10 +0000168 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drh43408312013-10-30 12:43:36 +0000169 clockVfs->xCurrentTimeInt64(clockVfs, &t);
170 }else{
171 double r;
172 clockVfs->xCurrentTime(clockVfs, &r);
173 t = (sqlite3_int64)(r*86400000.0);
174 }
175 return t;
176}
177
drh91eb93c2015-03-03 19:56:20 +0000178#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000179#include <sys/time.h>
180#include <sys/resource.h>
181
drh91eb93c2015-03-03 19:56:20 +0000182/* VxWorks does not support getrusage() as far as we can determine */
183#if defined(_WRS_KERNEL) || defined(__RTP__)
184struct rusage {
185 struct timeval ru_utime; /* user CPU time used */
186 struct timeval ru_stime; /* system CPU time used */
187};
188#define getrusage(A,B) memset(B,0,sizeof(*B))
189#endif
190
drhda108222009-02-25 19:07:24 +0000191/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000192static struct rusage sBegin; /* CPU time at start */
193static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000194
drhda108222009-02-25 19:07:24 +0000195/*
196** Begin timing an operation
197*/
198static void beginTimer(void){
199 if( enableTimer ){
200 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000201 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000202 }
203}
204
205/* Return the difference of two time_structs in seconds */
206static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
207 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
208 (double)(pEnd->tv_sec - pStart->tv_sec);
209}
210
211/*
212** Print the timing results.
213*/
214static void endTimer(void){
215 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000216 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000217 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000218 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000219 printf("Run Time: real %.3f user %f sys %f\n",
220 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000221 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
222 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
223 }
224}
shaneb320ccd2009-10-21 03:42:58 +0000225
drhda108222009-02-25 19:07:24 +0000226#define BEGIN_TIMER beginTimer()
227#define END_TIMER endTimer()
228#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000229
230#elif (defined(_WIN32) || defined(WIN32))
231
232#include <windows.h>
233
234/* Saved resource information for the beginning of an operation */
235static HANDLE hProcess;
236static FILETIME ftKernelBegin;
237static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000238static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000239typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
240 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000241static GETPROCTIMES getProcessTimesAddr = NULL;
242
shaneb320ccd2009-10-21 03:42:58 +0000243/*
244** Check to see if we have timer support. Return 1 if necessary
245** support found (or found previously).
246*/
247static int hasTimer(void){
248 if( getProcessTimesAddr ){
249 return 1;
250 } else {
drh4ace5362014-11-10 14:42:28 +0000251 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
252 ** versions. See if the version we are running on has it, and if it
253 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000254 */
255 hProcess = GetCurrentProcess();
256 if( hProcess ){
257 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
258 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000259 getProcessTimesAddr =
260 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000261 if( NULL != getProcessTimesAddr ){
262 return 1;
263 }
264 FreeLibrary(hinstLib);
265 }
266 }
267 }
268 return 0;
269}
270
271/*
272** Begin timing an operation
273*/
274static void beginTimer(void){
275 if( enableTimer && getProcessTimesAddr ){
276 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000277 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
278 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000279 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000280 }
281}
282
283/* Return the difference of two FILETIME structs in seconds */
284static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
285 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
286 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
287 return (double) ((i64End - i64Start) / 10000000.0);
288}
289
290/*
291** Print the timing results.
292*/
293static void endTimer(void){
294 if( enableTimer && getProcessTimesAddr){
295 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000296 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000297 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000298 printf("Run Time: real %.3f user %f sys %f\n",
299 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000300 timeDiff(&ftUserBegin, &ftUserEnd),
301 timeDiff(&ftKernelBegin, &ftKernelEnd));
302 }
303}
304
305#define BEGIN_TIMER beginTimer()
306#define END_TIMER endTimer()
307#define HAS_TIMER hasTimer()
308
drhda108222009-02-25 19:07:24 +0000309#else
310#define BEGIN_TIMER
311#define END_TIMER
312#define HAS_TIMER 0
313#endif
314
shanec0688ea2009-03-05 03:48:06 +0000315/*
316** Used to prevent warnings about unused parameters
317*/
318#define UNUSED_PARAMETER(x) (void)(x)
319
drhe91d16b2008-12-08 18:27:31 +0000320/*
drhc49f44e2006-10-26 18:15:42 +0000321** If the following flag is set, then command execution stops
322** at an error if we are not interactive.
323*/
324static int bail_on_error = 0;
325
326/*
drhc28490c2006-10-26 14:25:58 +0000327** Threat stdin as an interactive input if the following variable
328** is true. Otherwise, assume stdin is connected to a file or pipe.
329*/
330static int stdin_is_interactive = 1;
331
332/*
drhe05461c2015-12-30 13:36:57 +0000333** On Windows systems we have to know if standard output is a console
334** in order to translate UTF-8 into MBCS. The following variable is
335** true if translation is required.
336*/
337static int stdout_is_console = 1;
338
339/*
drh4c504392000-10-16 22:06:40 +0000340** The following is the open SQLite database. We make a pointer
341** to this database a static variable so that it can be accessed
342** by the SIGINT handler to interrupt database processing.
343*/
mistachkin8e189222015-04-19 21:43:16 +0000344static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000345
346/*
drh67505e72002-04-19 12:34:06 +0000347** True if an interrupt (Control-C) has been received.
348*/
drh43617e92006-03-06 20:55:46 +0000349static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000350
351/*
persicom7e2dfdd2002-04-18 02:46:52 +0000352** This is the name of our program. It is set in main(), used
353** in a number of other places, mostly for error messages.
354*/
355static char *Argv0;
356
357/*
358** Prompt strings. Initialized in main. Settable with
359** .prompt main continue
360*/
361static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
362static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
363
drhb0603412007-02-28 04:47:26 +0000364/*
365** Write I/O traces to the following stream.
366*/
rsebe0a9092007-07-30 18:24:38 +0000367#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000368static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000369#endif
drhb0603412007-02-28 04:47:26 +0000370
371/*
372** This routine works like printf in that its first argument is a
373** format string and subsequent arguments are values to be substituted
374** in place of % fields. The result of formatting this string
375** is written to iotrace.
376*/
rsebe0a9092007-07-30 18:24:38 +0000377#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000378static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000379 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000380 char *z;
drhb0603412007-02-28 04:47:26 +0000381 if( iotrace==0 ) return;
382 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000383 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000384 va_end(ap);
drh41d0ba72016-01-03 11:27:47 +0000385 fprintf(iotrace, "%s", z);
drhf075cd02007-02-28 06:14:25 +0000386 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000387}
rsebe0a9092007-07-30 18:24:38 +0000388#endif
drhb0603412007-02-28 04:47:26 +0000389
drh44c2eb12003-04-30 11:38:26 +0000390
persicom7e2dfdd2002-04-18 02:46:52 +0000391/*
drh83965662003-04-17 02:54:13 +0000392** Determines if a string is a number of not.
393*/
danielk19772e588c72005-12-09 14:25:08 +0000394static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000395 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000396 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000397 return 0;
398 }
399 z++;
400 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000401 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000402 if( *z=='.' ){
403 z++;
drhf0693c82011-10-11 20:41:54 +0000404 if( !IsDigit(*z) ) return 0;
405 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000406 if( realnum ) *realnum = 1;
407 }
408 if( *z=='e' || *z=='E' ){
409 z++;
410 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000411 if( !IsDigit(*z) ) return 0;
412 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000413 if( realnum ) *realnum = 1;
414 }
415 return *z==0;
416}
drh83965662003-04-17 02:54:13 +0000417
418/*
danielk1977bc6ada42004-06-30 08:20:16 +0000419** A global char* and an SQL function to access its current value
420** from within an SQL statement. This program used to use the
421** sqlite_exec_printf() API to substitue a string into an SQL statement.
422** The correct way to do this with sqlite3 is to use the bind API, but
423** since the shell is built around the callback paradigm it would be a lot
424** of work. Instead just use this hack, which is quite harmless.
425*/
426static const char *zShellStatic = 0;
427static void shellstaticFunc(
428 sqlite3_context *context,
429 int argc,
430 sqlite3_value **argv
431){
432 assert( 0==argc );
433 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000434 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000435 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000436 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
437}
438
439
440/*
drhe05461c2015-12-30 13:36:57 +0000441** Compute a string length that is limited to what can be stored in
442** lower 30 bits of a 32-bit signed integer.
443*/
444static int strlen30(const char *z){
445 const char *z2 = z;
446 while( *z2 ){ z2++; }
447 return 0x3fffffff & (int)(z2 - z);
448}
449
450/*
drhfeac5f82004-08-01 00:10:45 +0000451** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000452** the text in memory obtained from malloc() and returns a pointer
453** to the text. NULL is returned at end of file, or if malloc()
454** fails.
455**
drh9f099fd2013-08-06 14:01:46 +0000456** If zLine is not NULL then it is a malloced buffer returned from
457** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000458*/
drh9f099fd2013-08-06 14:01:46 +0000459static char *local_getline(char *zLine, FILE *in){
460 int nLine = zLine==0 ? 0 : 100;
461 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000462
drhb07028f2011-10-14 21:49:18 +0000463 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000464 if( n+100>nLine ){
465 nLine = nLine*2 + 100;
466 zLine = realloc(zLine, nLine);
467 if( zLine==0 ) return 0;
468 }
drhdaffd0e2001-04-11 14:28:42 +0000469 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000470 if( n==0 ){
471 free(zLine);
472 return 0;
473 }
474 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000475 break;
476 }
drh9f099fd2013-08-06 14:01:46 +0000477 while( zLine[n] ) n++;
478 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000479 n--;
shaneh13b36022009-12-17 21:07:15 +0000480 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000481 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000482 break;
drh8e7e7a22000-05-30 18:45:23 +0000483 }
484 }
drhe05461c2015-12-30 13:36:57 +0000485#if defined(_WIN32) || defined(WIN32)
486 /* For interactive input on Windows systems, translate the
487 ** multi-byte characterset characters into UTF-8. */
488 if( stdin_is_interactive ){
489 extern char *sqlite3_win32_mbcs_to_utf8(const char*);
490 char *zTrans = sqlite3_win32_mbcs_to_utf8(zLine);
491 if( zTrans ){
492 int nTrans = strlen30(zTrans)+1;
493 if( nTrans>nLine ){
494 zLine = realloc(zLine, nTrans);
495 if( zLine==0 ){
496 sqlite3_free(zTrans);
497 return 0;
498 }
499 }
500 memcpy(zLine, zTrans, nTrans);
501 sqlite3_free(zTrans);
502 }
503 }
504#endif /* defined(_WIN32) || defined(WIN32) */
drh8e7e7a22000-05-30 18:45:23 +0000505 return zLine;
506}
507
508/*
drhc28490c2006-10-26 14:25:58 +0000509** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000510**
drh9f099fd2013-08-06 14:01:46 +0000511** If in==0 then read from standard input and prompt before each line.
512** If isContinuation is true, then a continuation prompt is appropriate.
513** If isContinuation is zero, then the main prompt should be used.
514**
515** If zPrior is not NULL then it is a buffer from a prior call to this
516** routine that can be reused.
517**
518** The result is stored in space obtained from malloc() and must either
519** be freed by the caller or else passed back into this routine via the
520** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000521*/
drh9f099fd2013-08-06 14:01:46 +0000522static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000523 char *zPrompt;
524 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000525 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000526 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000527 }else{
drh9f099fd2013-08-06 14:01:46 +0000528 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000529#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000530 printf("%s", zPrompt);
531 fflush(stdout);
532 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000533#else
534 free(zPrior);
535 zResult = shell_readline(zPrompt);
536 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000537#endif
drh9f099fd2013-08-06 14:01:46 +0000538 }
drh8e7e7a22000-05-30 18:45:23 +0000539 return zResult;
540}
541
drhdcd87a92014-08-18 13:45:42 +0000542/*
drhe05461c2015-12-30 13:36:57 +0000543** Render output like fprintf(). Except, if the output is going to the
544** console and if this is running on a Windows machine, translate the
545** output from UTF-8 into MBCS.
546*/
547#if defined(_WIN32) || defined(WIN32)
548void utf8_printf(FILE *out, const char *zFormat, ...){
549 va_list ap;
550 va_start(ap, zFormat);
mistachkinaae280e2015-12-31 19:06:24 +0000551 if( stdout_is_console && (out==stdout || out==stderr) ){
drhe05461c2015-12-30 13:36:57 +0000552 extern char *sqlite3_win32_utf8_to_mbcs(const char*);
553 char *z1 = sqlite3_vmprintf(zFormat, ap);
554 char *z2 = sqlite3_win32_utf8_to_mbcs(z1);
555 sqlite3_free(z1);
556 fputs(z2, out);
557 sqlite3_free(z2);
558 }else{
559 vfprintf(out, zFormat, ap);
560 }
561 va_end(ap);
562}
mistachkinaae280e2015-12-31 19:06:24 +0000563#elif !defined(utf8_printf)
drhe05461c2015-12-30 13:36:57 +0000564# define utf8_printf fprintf
565#endif
566
567/*
mistachkinaae280e2015-12-31 19:06:24 +0000568** Render output like fprintf(). This should not be used on anything that
569** includes string formatting (e.g. "%s").
570*/
571#if !defined(raw_printf)
572# define raw_printf fprintf
573#endif
574
575/*
drhdcd87a92014-08-18 13:45:42 +0000576** Shell output mode information from before ".explain on",
577** saved so that it can be restored by ".explain off"
578*/
579typedef struct SavedModeInfo SavedModeInfo;
580struct SavedModeInfo {
581 int valid; /* Is there legit data in here? */
582 int mode; /* Mode prior to ".explain on" */
583 int showHeader; /* The ".header" setting prior to ".explain on" */
584 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000585};
drh45e29d82006-11-20 16:21:10 +0000586
drh8e7e7a22000-05-30 18:45:23 +0000587/*
drhdcd87a92014-08-18 13:45:42 +0000588** State information about the database connection is contained in an
589** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000590*/
drhdcd87a92014-08-18 13:45:42 +0000591typedef struct ShellState ShellState;
592struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000593 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000594 int echoOn; /* True to echo input commands */
drh700c2522016-02-09 18:39:25 +0000595 int autoExplain; /* Automatically turn on .explain mode */
drhc2ce0be2014-05-29 12:36:14 +0000596 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000597 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000598 int scanstatsOn; /* True to display scan stats before each finalize */
drhdf12f1c2015-12-07 21:46:19 +0000599 int countChanges; /* True to display change counts */
drh9569f602015-04-16 15:05:04 +0000600 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000601 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000602 int cnt; /* Number of records displayed so far */
603 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000604 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000605 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000606 int mode; /* An output mode setting */
drh700c2522016-02-09 18:39:25 +0000607 int cMode; /* temporary output mode for the current query */
608 int normalMode; /* Output mode before ".explain on" */
drh45e29d82006-11-20 16:21:10 +0000609 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000610 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000611 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000612 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000613 char colSeparator[20]; /* Column separator character for several modes */
614 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000615 int colWidth[100]; /* Requested width of each column when in column mode*/
616 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000617 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000618 ** the database */
drh44c2eb12003-04-30 11:38:26 +0000619 char outfile[FILENAME_MAX]; /* Filename for *out */
620 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000621 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000622 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000623 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000624 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000625 int *aiIndent; /* Array of indents used in MODE_Explain */
626 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000627 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000628};
629
630/*
drh44dec872014-08-30 15:49:25 +0000631** These are the allowed shellFlgs values
632*/
633#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
634#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
635#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
636
637/*
drh75897232000-05-29 14:26:00 +0000638** These are the allowed modes.
639*/
drh967e8b72000-06-21 13:59:10 +0000640#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000641#define MODE_Column 1 /* One record per line in neat columns */
642#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000643#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
644#define MODE_Html 4 /* Generate an XHTML table */
645#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000646#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000647#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000648#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000649#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000650
drh66ce4d02008-02-15 17:38:06 +0000651static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000652 "line",
653 "column",
654 "list",
655 "semi",
656 "html",
drhfeac5f82004-08-01 00:10:45 +0000657 "insert",
658 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000659 "csv",
drh66ce4d02008-02-15 17:38:06 +0000660 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000661 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000662};
drh75897232000-05-29 14:26:00 +0000663
664/*
mistachkinfad42082014-07-24 22:13:12 +0000665** These are the column/row/line separators used by the various
666** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000667*/
mistachkinfad42082014-07-24 22:13:12 +0000668#define SEP_Column "|"
669#define SEP_Row "\n"
670#define SEP_Tab "\t"
671#define SEP_Space " "
672#define SEP_Comma ","
673#define SEP_CrLf "\r\n"
674#define SEP_Unit "\x1F"
675#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000676
677/*
drh75897232000-05-29 14:26:00 +0000678** Number of elements in an array
679*/
drh902b9ee2008-12-05 17:17:07 +0000680#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000681
682/*
drh127f9d72010-02-23 01:47:00 +0000683** A callback for the sqlite3_log() interface.
684*/
685static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000686 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000687 if( p->pLog==0 ) return;
mistachkinaae280e2015-12-31 19:06:24 +0000688 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
drh127f9d72010-02-23 01:47:00 +0000689 fflush(p->pLog);
690}
691
692/*
shane626a6e42009-10-22 17:30:15 +0000693** Output the given string as a hex-encoded blob (eg. X'1234' )
694*/
695static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
696 int i;
697 char *zBlob = (char *)pBlob;
mistachkinaae280e2015-12-31 19:06:24 +0000698 raw_printf(out,"X'");
699 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
700 raw_printf(out,"'");
shane626a6e42009-10-22 17:30:15 +0000701}
702
703/*
drh28bd4bc2000-06-15 15:57:22 +0000704** Output the given string as a quoted string using SQL quoting conventions.
705*/
706static void output_quoted_string(FILE *out, const char *z){
707 int i;
708 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000709 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000710 for(i=0; z[i]; i++){
711 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000712 }
713 if( nSingle==0 ){
drhe05461c2015-12-30 13:36:57 +0000714 utf8_printf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000715 }else{
mistachkinaae280e2015-12-31 19:06:24 +0000716 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000717 while( *z ){
718 for(i=0; z[i] && z[i]!='\''; i++){}
719 if( i==0 ){
mistachkinaae280e2015-12-31 19:06:24 +0000720 raw_printf(out,"''");
drh28bd4bc2000-06-15 15:57:22 +0000721 z++;
722 }else if( z[i]=='\'' ){
drhe05461c2015-12-30 13:36:57 +0000723 utf8_printf(out,"%.*s''",i,z);
drh28bd4bc2000-06-15 15:57:22 +0000724 z += i+1;
725 }else{
drhe05461c2015-12-30 13:36:57 +0000726 utf8_printf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000727 break;
728 }
729 }
mistachkinaae280e2015-12-31 19:06:24 +0000730 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000731 }
drh047d4532015-01-18 20:30:23 +0000732 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000733}
734
735/*
drhfeac5f82004-08-01 00:10:45 +0000736** Output the given string as a quoted according to C or TCL quoting rules.
737*/
738static void output_c_string(FILE *out, const char *z){
739 unsigned int c;
740 fputc('"', out);
741 while( (c = *(z++))!=0 ){
742 if( c=='\\' ){
743 fputc(c, out);
744 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000745 }else if( c=='"' ){
746 fputc('\\', out);
747 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000748 }else if( c=='\t' ){
749 fputc('\\', out);
750 fputc('t', out);
751 }else if( c=='\n' ){
752 fputc('\\', out);
753 fputc('n', out);
754 }else if( c=='\r' ){
755 fputc('\\', out);
756 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000757 }else if( !isprint(c&0xff) ){
mistachkinaae280e2015-12-31 19:06:24 +0000758 raw_printf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000759 }else{
760 fputc(c, out);
761 }
762 }
763 fputc('"', out);
764}
765
766/*
drhc08a4f12000-06-15 16:49:48 +0000767** Output the given string with characters that are special to
768** HTML escaped.
769*/
770static void output_html_string(FILE *out, const char *z){
771 int i;
drhc3d6ba42014-01-13 20:38:35 +0000772 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000773 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000774 for(i=0; z[i]
775 && z[i]!='<'
776 && z[i]!='&'
777 && z[i]!='>'
778 && z[i]!='\"'
779 && z[i]!='\'';
780 i++){}
drhc08a4f12000-06-15 16:49:48 +0000781 if( i>0 ){
drhe05461c2015-12-30 13:36:57 +0000782 utf8_printf(out,"%.*s",i,z);
drhc08a4f12000-06-15 16:49:48 +0000783 }
784 if( z[i]=='<' ){
mistachkinaae280e2015-12-31 19:06:24 +0000785 raw_printf(out,"&lt;");
drhc08a4f12000-06-15 16:49:48 +0000786 }else if( z[i]=='&' ){
mistachkinaae280e2015-12-31 19:06:24 +0000787 raw_printf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000788 }else if( z[i]=='>' ){
mistachkinaae280e2015-12-31 19:06:24 +0000789 raw_printf(out,"&gt;");
shane43d9cb22009-10-21 14:11:48 +0000790 }else if( z[i]=='\"' ){
mistachkinaae280e2015-12-31 19:06:24 +0000791 raw_printf(out,"&quot;");
shane43d9cb22009-10-21 14:11:48 +0000792 }else if( z[i]=='\'' ){
mistachkinaae280e2015-12-31 19:06:24 +0000793 raw_printf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000794 }else{
795 break;
796 }
797 z += i + 1;
798 }
799}
800
801/*
drhc49f44e2006-10-26 18:15:42 +0000802** If a field contains any character identified by a 1 in the following
803** array, then the string must be quoted for CSV.
804*/
805static const char needCsvQuote[] = {
806 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
807 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
808 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
809 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
811 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
812 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
814 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
815 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
816 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
817 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
818 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
819 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
820 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
821 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
822};
823
824/*
mistachkindd11f2d2014-12-11 04:49:46 +0000825** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000826** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000827** the null value. Strings are quoted if necessary. The separator
828** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000829*/
drhdcd87a92014-08-18 13:45:42 +0000830static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000831 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000832 if( z==0 ){
drhe05461c2015-12-30 13:36:57 +0000833 utf8_printf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000834 }else{
drhc49f44e2006-10-26 18:15:42 +0000835 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000836 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000837 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000838 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000839 || (z[i]==p->colSeparator[0] &&
840 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000841 i = 0;
842 break;
843 }
844 }
845 if( i==0 ){
846 putc('"', out);
847 for(i=0; z[i]; i++){
848 if( z[i]=='"' ) putc('"', out);
849 putc(z[i], out);
850 }
851 putc('"', out);
852 }else{
drhe05461c2015-12-30 13:36:57 +0000853 utf8_printf(out, "%s", z);
drhc49f44e2006-10-26 18:15:42 +0000854 }
drh8e64d1c2004-10-07 00:32:39 +0000855 }
856 if( bSep ){
drhe05461c2015-12-30 13:36:57 +0000857 utf8_printf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000858 }
859}
860
danielk19774af00c62005-01-23 23:43:21 +0000861#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000862/*
drh4c504392000-10-16 22:06:40 +0000863** This routine runs when the user presses Ctrl-C
864*/
865static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000866 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000867 seenInterrupt++;
868 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000869 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000870}
danielk19774af00c62005-01-23 23:43:21 +0000871#endif
drh4c504392000-10-16 22:06:40 +0000872
873/*
shane626a6e42009-10-22 17:30:15 +0000874** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000875** invokes for each row of a query result.
876*/
drh4ace5362014-11-10 14:42:28 +0000877static int shell_callback(
878 void *pArg,
879 int nArg, /* Number of result columns */
880 char **azArg, /* Text of each result column */
881 char **azCol, /* Column names */
882 int *aiType /* Column types */
883){
drh75897232000-05-29 14:26:00 +0000884 int i;
drhdcd87a92014-08-18 13:45:42 +0000885 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000886
drh700c2522016-02-09 18:39:25 +0000887 switch( p->cMode ){
drh75897232000-05-29 14:26:00 +0000888 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000889 int w = 5;
drh6a535342001-10-19 16:44:56 +0000890 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000891 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000892 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000893 if( len>w ) w = len;
894 }
drhe05461c2015-12-30 13:36:57 +0000895 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000896 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000897 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000898 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000899 }
900 break;
901 }
danielk19770d78bae2008-01-03 07:09:48 +0000902 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000903 case MODE_Column: {
drh700c2522016-02-09 18:39:25 +0000904 static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
905 const int *colWidth;
906 int showHdr;
907 char *rowSep;
908 if( p->cMode==MODE_Column ){
909 colWidth = p->colWidth;
910 showHdr = p->showHeader;
911 rowSep = p->rowSeparator;
912 }else{
913 colWidth = aExplainWidths;
914 showHdr = 1;
mistachkin6d945552016-02-09 20:31:50 +0000915 rowSep = SEP_Row;
drh700c2522016-02-09 18:39:25 +0000916 }
drha0c66f52000-07-29 13:20:21 +0000917 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000918 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000919 int w, n;
920 if( i<ArraySize(p->colWidth) ){
drh700c2522016-02-09 18:39:25 +0000921 w = colWidth[i];
drh75897232000-05-29 14:26:00 +0000922 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000923 w = 0;
drh75897232000-05-29 14:26:00 +0000924 }
drh078b1fd2012-09-21 13:40:02 +0000925 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000926 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000927 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000928 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000929 if( w<n ) w = n;
930 }
931 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000932 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000933 }
drh700c2522016-02-09 18:39:25 +0000934 if( showHdr ){
drh078b1fd2012-09-21 13:40:02 +0000935 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +0000936 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
drh700c2522016-02-09 18:39:25 +0000937 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +0000938 }else{
drhe05461c2015-12-30 13:36:57 +0000939 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
drh700c2522016-02-09 18:39:25 +0000940 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +0000941 }
drha0c66f52000-07-29 13:20:21 +0000942 }
943 }
drh700c2522016-02-09 18:39:25 +0000944 if( showHdr ){
drha0c66f52000-07-29 13:20:21 +0000945 for(i=0; i<nArg; i++){
946 int w;
947 if( i<ArraySize(p->actualWidth) ){
948 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000949 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000950 }else{
951 w = 10;
952 }
mistachkinaae280e2015-12-31 19:06:24 +0000953 utf8_printf(p->out,"%-*.*s%s",w,w,
drhe05461c2015-12-30 13:36:57 +0000954 "----------------------------------------------------------"
drha0c66f52000-07-29 13:20:21 +0000955 "----------------------------------------------------------",
drh700c2522016-02-09 18:39:25 +0000956 i==nArg-1 ? rowSep : " ");
drha0c66f52000-07-29 13:20:21 +0000957 }
drh75897232000-05-29 14:26:00 +0000958 }
959 }
drh6a535342001-10-19 16:44:56 +0000960 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000961 for(i=0; i<nArg; i++){
962 int w;
drha0c66f52000-07-29 13:20:21 +0000963 if( i<ArraySize(p->actualWidth) ){
964 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000965 }else{
966 w = 10;
967 }
drh700c2522016-02-09 18:39:25 +0000968 if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000969 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000970 }
dana98bf362013-11-13 18:35:01 +0000971 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000972 if( p->iIndent<p->nIndent ){
mistachkinaae280e2015-12-31 19:06:24 +0000973 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000974 }
danc4650bb2013-11-18 08:41:06 +0000975 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000976 }
drh078b1fd2012-09-21 13:40:02 +0000977 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +0000978 utf8_printf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000979 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +0000980 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +0000981 }else{
drhe05461c2015-12-30 13:36:57 +0000982 utf8_printf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000983 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +0000984 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +0000985 }
drh75897232000-05-29 14:26:00 +0000986 }
987 break;
988 }
drhe3710332000-09-29 13:30:53 +0000989 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000990 case MODE_List: {
991 if( p->cnt++==0 && p->showHeader ){
992 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000993 utf8_printf(p->out,"%s%s",azCol[i],
mistachkin636bf9f2014-07-19 20:15:16 +0000994 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000995 }
996 }
drh6a535342001-10-19 16:44:56 +0000997 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000998 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000999 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +00001000 if( z==0 ) z = p->nullValue;
drhe05461c2015-12-30 13:36:57 +00001001 utf8_printf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001002 if( i<nArg-1 ){
drhe05461c2015-12-30 13:36:57 +00001003 utf8_printf(p->out, "%s", p->colSeparator);
drh700c2522016-02-09 18:39:25 +00001004 }else if( p->cMode==MODE_Semi ){
drhe05461c2015-12-30 13:36:57 +00001005 utf8_printf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001006 }else{
drhe05461c2015-12-30 13:36:57 +00001007 utf8_printf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001008 }
drh75897232000-05-29 14:26:00 +00001009 }
1010 break;
1011 }
drh1e5d0e92000-05-31 23:33:17 +00001012 case MODE_Html: {
1013 if( p->cnt++==0 && p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001014 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001015 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001016 raw_printf(p->out,"<TH>");
shane43d9cb22009-10-21 14:11:48 +00001017 output_html_string(p->out, azCol[i]);
mistachkinaae280e2015-12-31 19:06:24 +00001018 raw_printf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001019 }
mistachkinaae280e2015-12-31 19:06:24 +00001020 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001021 }
drh6a535342001-10-19 16:44:56 +00001022 if( azArg==0 ) break;
mistachkinaae280e2015-12-31 19:06:24 +00001023 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001024 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001025 raw_printf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +00001026 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00001027 raw_printf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001028 }
mistachkinaae280e2015-12-31 19:06:24 +00001029 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001030 break;
1031 }
drhfeac5f82004-08-01 00:10:45 +00001032 case MODE_Tcl: {
1033 if( p->cnt++==0 && p->showHeader ){
1034 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001035 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhe05461c2015-12-30 13:36:57 +00001036 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001037 }
drhe05461c2015-12-30 13:36:57 +00001038 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001039 }
1040 if( azArg==0 ) break;
1041 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +00001042 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
drhe05461c2015-12-30 13:36:57 +00001043 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001044 }
drhe05461c2015-12-30 13:36:57 +00001045 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001046 break;
1047 }
drh8e64d1c2004-10-07 00:32:39 +00001048 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +00001049 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +00001050 if( p->cnt++==0 && p->showHeader ){
1051 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001052 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001053 }
drhe05461c2015-12-30 13:36:57 +00001054 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001055 }
drh40253262014-10-17 21:35:05 +00001056 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +00001057 for(i=0; i<nArg; i++){
1058 output_csv(p, azArg[i], i<nArg-1);
1059 }
drhe05461c2015-12-30 13:36:57 +00001060 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001061 }
drh047d4532015-01-18 20:30:23 +00001062 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +00001063 break;
1064 }
drh28bd4bc2000-06-15 15:57:22 +00001065 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001066 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001067 if( azArg==0 ) break;
drhe05461c2015-12-30 13:36:57 +00001068 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
mistachkin151c75a2015-04-07 21:16:40 +00001069 if( p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001070 raw_printf(p->out,"(");
mistachkin151c75a2015-04-07 21:16:40 +00001071 for(i=0; i<nArg; i++){
1072 char *zSep = i>0 ? ",": "";
drhe05461c2015-12-30 13:36:57 +00001073 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
mistachkin151c75a2015-04-07 21:16:40 +00001074 }
mistachkinaae280e2015-12-31 19:06:24 +00001075 raw_printf(p->out,")");
mistachkin151c75a2015-04-07 21:16:40 +00001076 }
mistachkinaae280e2015-12-31 19:06:24 +00001077 raw_printf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001078 for(i=0; i<nArg; i++){
1079 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001080 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
mistachkinaae280e2015-12-31 19:06:24 +00001081 utf8_printf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001082 }else if( aiType && aiType[i]==SQLITE_TEXT ){
mistachkinaae280e2015-12-31 19:06:24 +00001083 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shanead6b8d02009-10-22 18:12:58 +00001084 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001085 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1086 || aiType[i]==SQLITE_FLOAT) ){
drhe05461c2015-12-30 13:36:57 +00001087 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001088 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1089 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1090 int nBlob = sqlite3_column_bytes(p->pStmt, i);
mistachkinaae280e2015-12-31 19:06:24 +00001091 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shane626a6e42009-10-22 17:30:15 +00001092 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001093 }else if( isNumber(azArg[i], 0) ){
drhe05461c2015-12-30 13:36:57 +00001094 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
drh28bd4bc2000-06-15 15:57:22 +00001095 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001096 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
drh28bd4bc2000-06-15 15:57:22 +00001097 output_quoted_string(p->out, azArg[i]);
1098 }
1099 }
mistachkinaae280e2015-12-31 19:06:24 +00001100 raw_printf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001101 break;
drh28bd4bc2000-06-15 15:57:22 +00001102 }
mistachkin636bf9f2014-07-19 20:15:16 +00001103 case MODE_Ascii: {
1104 if( p->cnt++==0 && p->showHeader ){
1105 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001106 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1107 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +00001108 }
drhe05461c2015-12-30 13:36:57 +00001109 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001110 }
1111 if( azArg==0 ) break;
1112 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001113 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1114 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001115 }
drhe05461c2015-12-30 13:36:57 +00001116 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001117 break;
1118 }
persicom1d0b8722002-04-18 02:53:04 +00001119 }
drh75897232000-05-29 14:26:00 +00001120 return 0;
1121}
1122
1123/*
shane626a6e42009-10-22 17:30:15 +00001124** This is the callback routine that the SQLite library
1125** invokes for each row of a query result.
1126*/
1127static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1128 /* since we don't have type info, call the shell_callback with a NULL value */
1129 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1130}
1131
1132/*
drhdcd87a92014-08-18 13:45:42 +00001133** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001134** the name of the table given. Escape any quote characters in the
1135** table name.
1136*/
drhdcd87a92014-08-18 13:45:42 +00001137static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001138 int i, n;
1139 int needQuote;
1140 char *z;
1141
1142 if( p->zDestTable ){
1143 free(p->zDestTable);
1144 p->zDestTable = 0;
1145 }
1146 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001147 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001148 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001149 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001150 needQuote = 1;
1151 if( zName[i]=='\'' ) n++;
1152 }
1153 }
1154 if( needQuote ) n += 2;
1155 z = p->zDestTable = malloc( n+1 );
1156 if( z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001157 raw_printf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001158 exit(1);
1159 }
1160 n = 0;
1161 if( needQuote ) z[n++] = '\'';
1162 for(i=0; zName[i]; i++){
1163 z[n++] = zName[i];
1164 if( zName[i]=='\'' ) z[n++] = '\'';
1165 }
1166 if( needQuote ) z[n++] = '\'';
1167 z[n] = 0;
1168}
1169
danielk19772a02e332004-06-05 08:04:36 +00001170/* zIn is either a pointer to a NULL-terminated string in memory obtained
1171** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1172** added to zIn, and the result returned in memory obtained from malloc().
1173** zIn, if it was not NULL, is freed.
1174**
1175** If the third argument, quote, is not '\0', then it is used as a
1176** quote character for zAppend.
1177*/
drhc28490c2006-10-26 14:25:58 +00001178static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001179 int len;
1180 int i;
drh4f21c4a2008-12-10 22:15:00 +00001181 int nAppend = strlen30(zAppend);
1182 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001183
1184 len = nAppend+nIn+1;
1185 if( quote ){
1186 len += 2;
1187 for(i=0; i<nAppend; i++){
1188 if( zAppend[i]==quote ) len++;
1189 }
1190 }
1191
1192 zIn = (char *)realloc(zIn, len);
1193 if( !zIn ){
1194 return 0;
1195 }
1196
1197 if( quote ){
1198 char *zCsr = &zIn[nIn];
1199 *zCsr++ = quote;
1200 for(i=0; i<nAppend; i++){
1201 *zCsr++ = zAppend[i];
1202 if( zAppend[i]==quote ) *zCsr++ = quote;
1203 }
1204 *zCsr++ = quote;
1205 *zCsr++ = '\0';
1206 assert( (zCsr-zIn)==len );
1207 }else{
1208 memcpy(&zIn[nIn], zAppend, nAppend);
1209 zIn[len-1] = '\0';
1210 }
1211
1212 return zIn;
1213}
1214
drhdd3d4592004-08-30 01:54:05 +00001215
1216/*
drhb21a8e42012-01-28 21:08:51 +00001217** Execute a query statement that will generate SQL output. Print
1218** the result columns, comma-separated, on a line and then add a
1219** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001220**
drhb21a8e42012-01-28 21:08:51 +00001221** If the number of columns is 1 and that column contains text "--"
1222** then write the semicolon on a separate line. That way, if a
1223** "--" comment occurs at the end of the statement, the comment
1224** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001225*/
drh157e29a2009-05-21 15:15:00 +00001226static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001227 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001228 const char *zSelect, /* SELECT statement to extract content */
1229 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001230){
drhdd3d4592004-08-30 01:54:05 +00001231 sqlite3_stmt *pSelect;
1232 int rc;
drhb21a8e42012-01-28 21:08:51 +00001233 int nResult;
1234 int i;
1235 const char *z;
drhc7181902014-02-27 15:04:13 +00001236 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001237 if( rc!=SQLITE_OK || !pSelect ){
mistachkinaae280e2015-12-31 19:06:24 +00001238 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1239 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001240 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001241 return rc;
1242 }
1243 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001244 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001245 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001246 if( zFirstRow ){
drhe05461c2015-12-30 13:36:57 +00001247 utf8_printf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001248 zFirstRow = 0;
1249 }
drhb21a8e42012-01-28 21:08:51 +00001250 z = (const char*)sqlite3_column_text(pSelect, 0);
drhe05461c2015-12-30 13:36:57 +00001251 utf8_printf(p->out, "%s", z);
drhb21a8e42012-01-28 21:08:51 +00001252 for(i=1; i<nResult; i++){
drhe05461c2015-12-30 13:36:57 +00001253 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
drhb21a8e42012-01-28 21:08:51 +00001254 }
1255 if( z==0 ) z = "";
1256 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1257 if( z[0] ){
mistachkinaae280e2015-12-31 19:06:24 +00001258 raw_printf(p->out, "\n;\n");
drhb21a8e42012-01-28 21:08:51 +00001259 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001260 raw_printf(p->out, ";\n");
drhb21a8e42012-01-28 21:08:51 +00001261 }
drhdd3d4592004-08-30 01:54:05 +00001262 rc = sqlite3_step(pSelect);
1263 }
drh2f464a02011-10-13 00:41:49 +00001264 rc = sqlite3_finalize(pSelect);
1265 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00001266 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1267 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001268 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001269 }
1270 return rc;
drhdd3d4592004-08-30 01:54:05 +00001271}
1272
shane626a6e42009-10-22 17:30:15 +00001273/*
1274** Allocate space and save off current error string.
1275*/
1276static char *save_err_msg(
1277 sqlite3 *db /* Database to query */
1278){
1279 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001280 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001281 if( zErrMsg ){
1282 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1283 }
1284 return zErrMsg;
1285}
1286
drh34784902016-02-27 17:12:36 +00001287#ifdef __linux__
1288/*
1289** Attempt to display I/O stats on Linux using /proc/PID/io
1290*/
1291static void displayLinuxIoStats(FILE *out){
1292 FILE *in;
1293 char z[200];
1294 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
1295 in = fopen(z, "rb");
1296 if( in==0 ) return;
1297 while( fgets(z, sizeof(z), in)!=0 ){
1298 static const struct {
1299 const char *zPattern;
1300 const char *zDesc;
1301 } aTrans[] = {
drhfc1a84c2016-02-27 19:19:22 +00001302 { "rchar: ", "Bytes received by read():" },
1303 { "wchar: ", "Bytes sent to write():" },
1304 { "syscr: ", "Read() system calls:" },
1305 { "syscw: ", "Write() system calls:" },
1306 { "read_bytes: ", "Bytes read from storage:" },
1307 { "write_bytes: ", "Bytes written to storage:" },
1308 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
drh34784902016-02-27 17:12:36 +00001309 };
1310 int i;
1311 for(i=0; i<ArraySize(aTrans); i++){
1312 int n = (int)strlen(aTrans[i].zPattern);
1313 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
1314 raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
1315 break;
1316 }
1317 }
1318 }
1319 fclose(in);
1320}
1321#endif
1322
1323
shane626a6e42009-10-22 17:30:15 +00001324/*
shaneh642d8b82010-07-28 16:05:34 +00001325** Display memory stats.
1326*/
1327static int display_stats(
1328 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001329 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001330 int bReset /* True to reset the stats */
1331){
1332 int iCur;
1333 int iHiwtr;
1334
1335 if( pArg && pArg->out ){
1336
1337 iHiwtr = iCur = -1;
1338 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001339 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001340 "Memory Used: %d (max %d) bytes\n",
1341 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001342 iHiwtr = iCur = -1;
1343 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001344 raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001345 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001346 if( pArg->shellFlgs & SHFLG_Pagecache ){
1347 iHiwtr = iCur = -1;
1348 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001349 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001350 "Number of Pcache Pages Used: %d (max %d) pages\n",
1351 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001352 }
shaneh642d8b82010-07-28 16:05:34 +00001353 iHiwtr = iCur = -1;
1354 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001355 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001356 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1357 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001358 if( pArg->shellFlgs & SHFLG_Scratch ){
1359 iHiwtr = iCur = -1;
1360 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001361 raw_printf(pArg->out,
1362 "Number of Scratch Allocations Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001363 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001364 }
shaneh642d8b82010-07-28 16:05:34 +00001365 iHiwtr = iCur = -1;
1366 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001367 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001368 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1369 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001370 iHiwtr = iCur = -1;
1371 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001372 raw_printf(pArg->out, "Largest Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001373 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001374 iHiwtr = iCur = -1;
1375 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001376 raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001377 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001378 iHiwtr = iCur = -1;
1379 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001380 raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001381 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001382#ifdef YYTRACKMAXSTACKDEPTH
1383 iHiwtr = iCur = -1;
1384 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001385 raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001386 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001387#endif
1388 }
1389
1390 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001391 if( pArg->shellFlgs & SHFLG_Lookaside ){
1392 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001393 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1394 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001395 raw_printf(pArg->out,
1396 "Lookaside Slots Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001397 iCur, iHiwtr);
1398 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1399 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001400 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
1401 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001402 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1403 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001404 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
1405 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001406 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1407 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001408 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
1409 iHiwtr);
drh44dec872014-08-30 15:49:25 +00001410 }
shaneh642d8b82010-07-28 16:05:34 +00001411 iHiwtr = iCur = -1;
1412 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001413 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
1414 iCur);
drh4ace5362014-11-10 14:42:28 +00001415 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001416 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001417 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
drhc78e6e42011-09-23 18:58:23 +00001418 iHiwtr = iCur = -1;
1419 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001420 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001421 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001422 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001423 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
drhfbbcd5d2012-03-24 20:09:33 +00001424 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001425 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001426 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
1427 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001428 iHiwtr = iCur = -1;
1429 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001430 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
1431 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001432 }
1433
1434 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001435 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1436 bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001437 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001438 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001439 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001440 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001441 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001442 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001443 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001444 }
1445
drh34784902016-02-27 17:12:36 +00001446#ifdef __linux__
1447 displayLinuxIoStats(pArg->out);
1448#endif
1449
dan5a790282015-08-07 20:06:14 +00001450 /* Do not remove this machine readable comment: extra-stats-output-here */
1451
shaneh642d8b82010-07-28 16:05:34 +00001452 return 0;
1453}
1454
1455/*
dan8d1edb92014-11-05 09:07:28 +00001456** Display scan stats.
1457*/
1458static void display_scanstats(
1459 sqlite3 *db, /* Database to query */
1460 ShellState *pArg /* Pointer to ShellState */
1461){
drhf5ed7ad2015-06-15 14:43:25 +00001462#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1463 UNUSED_PARAMETER(db);
1464 UNUSED_PARAMETER(pArg);
1465#else
drh15f23c22014-11-06 12:46:16 +00001466 int i, k, n, mx;
mistachkinaae280e2015-12-31 19:06:24 +00001467 raw_printf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001468 mx = 0;
1469 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001470 double rEstLoop = 1.0;
1471 for(i=n=0; 1; i++){
1472 sqlite3_stmt *p = pArg->pStmt;
1473 sqlite3_int64 nLoop, nVisit;
1474 double rEst;
1475 int iSid;
1476 const char *zExplain;
1477 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1478 break;
1479 }
1480 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001481 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001482 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001483 if( n==0 ){
1484 rEstLoop = (double)nLoop;
mistachkinaae280e2015-12-31 19:06:24 +00001485 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001486 }
drh42f30bc2014-11-06 12:08:21 +00001487 n++;
1488 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1489 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1490 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
drhe05461c2015-12-30 13:36:57 +00001491 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
drh42f30bc2014-11-06 12:08:21 +00001492 rEstLoop *= rEst;
mistachkinaae280e2015-12-31 19:06:24 +00001493 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001494 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001495 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001496 );
dan8d1edb92014-11-05 09:07:28 +00001497 }
dan8d1edb92014-11-05 09:07:28 +00001498 }
mistachkinaae280e2015-12-31 19:06:24 +00001499 raw_printf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001500#endif
dan8d1edb92014-11-05 09:07:28 +00001501}
1502
1503/*
dana98bf362013-11-13 18:35:01 +00001504** Parameter azArray points to a zero-terminated array of strings. zStr
1505** points to a single nul-terminated string. Return non-zero if zStr
1506** is equal, according to strcmp(), to any of the strings in the array.
1507** Otherwise, return zero.
1508*/
1509static int str_in_array(const char *zStr, const char **azArray){
1510 int i;
1511 for(i=0; azArray[i]; i++){
1512 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1513 }
1514 return 0;
1515}
1516
1517/*
1518** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001519** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001520** spaces each opcode should be indented before it is output.
1521**
1522** The indenting rules are:
1523**
1524** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1525** all opcodes that occur between the p2 jump destination and the opcode
1526** itself by 2 spaces.
1527**
drh01752bc2013-11-14 23:59:33 +00001528** * For each "Goto", if the jump destination is earlier in the program
1529** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001530** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001531** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001532** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001533** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001534*/
drhdcd87a92014-08-18 13:45:42 +00001535static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001536 const char *zSql; /* The text of the SQL statement */
1537 const char *z; /* Used to check if this is an EXPLAIN */
1538 int *abYield = 0; /* True if op is an OP_Yield */
1539 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001540 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001541
drh8ad0de32014-03-20 18:45:27 +00001542 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1543 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001544 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1545 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001546 const char *azGoto[] = { "Goto", 0 };
1547
1548 /* Try to figure out if this is really an EXPLAIN statement. If this
1549 ** cannot be verified, return early. */
drh87a24aa2016-02-09 20:04:07 +00001550 if( sqlite3_column_count(pSql)!=8 ){
1551 p->cMode = p->mode;
1552 return;
1553 }
dana98bf362013-11-13 18:35:01 +00001554 zSql = sqlite3_sql(pSql);
1555 if( zSql==0 ) return;
1556 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
drh87a24aa2016-02-09 20:04:07 +00001557 if( sqlite3_strnicmp(z, "explain", 7) ){
1558 p->cMode = p->mode;
1559 return;
1560 }
dana98bf362013-11-13 18:35:01 +00001561
1562 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1563 int i;
danc4650bb2013-11-18 08:41:06 +00001564 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001565 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001566
1567 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1568 ** p2 is an instruction address, set variable p2op to the index of that
1569 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1570 ** the current instruction is part of a sub-program generated by an
1571 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001572 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001573 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001574
1575 /* Grow the p->aiIndent array as required */
1576 if( iOp>=nAlloc ){
drh87a24aa2016-02-09 20:04:07 +00001577 if( iOp==0 ){
1578 /* Do further verfication that this is explain output. Abort if
1579 ** it is not */
1580 static const char *explainCols[] = {
1581 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
1582 int jj;
1583 for(jj=0; jj<ArraySize(explainCols); jj++){
1584 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
1585 p->cMode = p->mode;
1586 sqlite3_reset(pSql);
1587 return;
1588 }
1589 }
1590 }
dana98bf362013-11-13 18:35:01 +00001591 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001592 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1593 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001594 }
1595 abYield[iOp] = str_in_array(zOp, azYield);
1596 p->aiIndent[iOp] = 0;
1597 p->nIndent = iOp+1;
1598
1599 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001600 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001601 }
drhfe705102014-03-06 13:38:37 +00001602 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1603 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1604 ){
drhe73f0592014-01-21 22:25:45 +00001605 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001606 }
1607 }
1608
danc4650bb2013-11-18 08:41:06 +00001609 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001610 sqlite3_free(abYield);
1611 sqlite3_reset(pSql);
1612}
1613
1614/*
1615** Free the array allocated by explain_data_prepare().
1616*/
drhdcd87a92014-08-18 13:45:42 +00001617static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001618 sqlite3_free(p->aiIndent);
1619 p->aiIndent = 0;
1620 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001621 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001622}
1623
1624/*
shane626a6e42009-10-22 17:30:15 +00001625** Execute a statement or set of statements. Print
1626** any result rows/columns depending on the current mode
1627** set via the supplied callback.
1628**
1629** This is very similar to SQLite's built-in sqlite3_exec()
1630** function except it takes a slightly different callback
1631** and callback data argument.
1632*/
1633static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001634 sqlite3 *db, /* An open database */
1635 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001636 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001637 /* (not the same as sqlite3_exec) */
1638 ShellState *pArg, /* Pointer to ShellState */
1639 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001640){
dan4564ced2010-01-05 04:59:56 +00001641 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1642 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001643 int rc2;
dan4564ced2010-01-05 04:59:56 +00001644 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001645
1646 if( pzErrMsg ){
1647 *pzErrMsg = NULL;
1648 }
1649
shaneb9fc17d2009-10-22 21:23:35 +00001650 while( zSql[0] && (SQLITE_OK == rc) ){
1651 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1652 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001653 if( pzErrMsg ){
1654 *pzErrMsg = save_err_msg(db);
1655 }
1656 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001657 if( !pStmt ){
1658 /* this happens for a comment or white-space */
1659 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001660 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001661 continue;
1662 }
shane626a6e42009-10-22 17:30:15 +00001663
shaneh642d8b82010-07-28 16:05:34 +00001664 /* save off the prepared statment handle and reset row count */
1665 if( pArg ){
1666 pArg->pStmt = pStmt;
1667 pArg->cnt = 0;
1668 }
1669
shanehb7977c52010-01-18 18:17:10 +00001670 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001671 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001672 const char *zStmtSql = sqlite3_sql(pStmt);
drhe05461c2015-12-30 13:36:57 +00001673 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001674 }
shanehb7977c52010-01-18 18:17:10 +00001675
drhefbf3b12014-02-28 20:47:24 +00001676 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1677 if( pArg && pArg->autoEQP ){
1678 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001679 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1680 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001681 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1682 if( rc==SQLITE_OK ){
1683 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001684 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1685 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1686 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001687 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001688 }
1689 }
1690 sqlite3_finalize(pExplain);
1691 sqlite3_free(zEQP);
1692 }
1693
drh700c2522016-02-09 18:39:25 +00001694 if( pArg ){
1695 pArg->cMode = pArg->mode;
drh87a24aa2016-02-09 20:04:07 +00001696 if( pArg->autoExplain
1697 && sqlite3_column_count(pStmt)==8
drh700c2522016-02-09 18:39:25 +00001698 && sqlite3_strlike("%EXPLAIN%", sqlite3_sql(pStmt),0)==0
drh700c2522016-02-09 18:39:25 +00001699 ){
1700 pArg->cMode = MODE_Explain;
1701 }
1702
1703 /* If the shell is currently in ".explain" mode, gather the extra
1704 ** data required to add indents to the output.*/
1705 if( pArg->cMode==MODE_Explain ){
1706 explain_data_prepare(pArg, pStmt);
1707 }
dana98bf362013-11-13 18:35:01 +00001708 }
1709
shaneb9fc17d2009-10-22 21:23:35 +00001710 /* perform the first step. this will tell us if we
1711 ** have a result set or not and how wide it is.
1712 */
1713 rc = sqlite3_step(pStmt);
1714 /* if we have a result set... */
1715 if( SQLITE_ROW == rc ){
1716 /* if we have a callback... */
1717 if( xCallback ){
1718 /* allocate space for col name ptr, value ptr, and type */
1719 int nCol = sqlite3_column_count(pStmt);
drhf3cdcdc2015-04-29 16:50:28 +00001720 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
shaneb9fc17d2009-10-22 21:23:35 +00001721 if( !pData ){
1722 rc = SQLITE_NOMEM;
1723 }else{
1724 char **azCols = (char **)pData; /* Names of result columns */
1725 char **azVals = &azCols[nCol]; /* Results */
1726 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001727 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001728 assert(sizeof(int) <= sizeof(char *));
1729 /* save off ptrs to column names */
1730 for(i=0; i<nCol; i++){
1731 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1732 }
shaneb9fc17d2009-10-22 21:23:35 +00001733 do{
1734 /* extract the data and data types */
1735 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001736 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh700c2522016-02-09 18:39:25 +00001737 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001738 azVals[i] = "";
1739 }else{
1740 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1741 }
shaneb9fc17d2009-10-22 21:23:35 +00001742 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1743 rc = SQLITE_NOMEM;
1744 break; /* from for */
1745 }
1746 } /* end for */
1747
1748 /* if data and types extracted successfully... */
1749 if( SQLITE_ROW == rc ){
1750 /* call the supplied callback with the result row data */
1751 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1752 rc = SQLITE_ABORT;
1753 }else{
1754 rc = sqlite3_step(pStmt);
1755 }
1756 }
1757 } while( SQLITE_ROW == rc );
1758 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001759 }
1760 }else{
1761 do{
1762 rc = sqlite3_step(pStmt);
1763 } while( rc == SQLITE_ROW );
1764 }
1765 }
1766
dana98bf362013-11-13 18:35:01 +00001767 explain_data_delete(pArg);
1768
shaneh642d8b82010-07-28 16:05:34 +00001769 /* print usage stats if stats on */
1770 if( pArg && pArg->statsOn ){
1771 display_stats(db, pArg, 0);
1772 }
1773
dan8d1edb92014-11-05 09:07:28 +00001774 /* print loop-counters if required */
1775 if( pArg && pArg->scanstatsOn ){
1776 display_scanstats(db, pArg);
1777 }
1778
dan4564ced2010-01-05 04:59:56 +00001779 /* Finalize the statement just executed. If this fails, save a
1780 ** copy of the error message. Otherwise, set zSql to point to the
1781 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001782 rc2 = sqlite3_finalize(pStmt);
1783 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001784 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001785 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001786 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001787 }else if( pzErrMsg ){
1788 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001789 }
shaneh642d8b82010-07-28 16:05:34 +00001790
1791 /* clear saved stmt handle */
1792 if( pArg ){
1793 pArg->pStmt = NULL;
1794 }
shane626a6e42009-10-22 17:30:15 +00001795 }
shaneb9fc17d2009-10-22 21:23:35 +00001796 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001797
1798 return rc;
1799}
1800
drhdd3d4592004-08-30 01:54:05 +00001801
drh33048c02001-10-01 14:29:22 +00001802/*
drh4c653a02000-06-07 01:27:47 +00001803** This is a different callback routine used for dumping the database.
1804** Each row received by this callback consists of a table name,
1805** the table type ("index" or "table") and SQL to create the table.
1806** This routine should print text sufficient to recreate the table.
1807*/
1808static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001809 int rc;
1810 const char *zTable;
1811 const char *zType;
1812 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001813 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001814 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001815
drh902b9ee2008-12-05 17:17:07 +00001816 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001817 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001818 zTable = azArg[0];
1819 zType = azArg[1];
1820 zSql = azArg[2];
1821
drh00b950d2005-09-11 02:03:03 +00001822 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001823 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001824 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001825 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00001826 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1827 return 0;
drh45e29d82006-11-20 16:21:10 +00001828 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1829 char *zIns;
1830 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00001831 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00001832 p->writableSchema = 1;
1833 }
1834 zIns = sqlite3_mprintf(
1835 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1836 "VALUES('table','%q','%q',0,'%q');",
1837 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00001838 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00001839 sqlite3_free(zIns);
1840 return 0;
drh00b950d2005-09-11 02:03:03 +00001841 }else{
drhe05461c2015-12-30 13:36:57 +00001842 utf8_printf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001843 }
danielk19772a02e332004-06-05 08:04:36 +00001844
1845 if( strcmp(zType, "table")==0 ){
1846 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001847 char *zSelect = 0;
1848 char *zTableInfo = 0;
1849 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001850 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001851
1852 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1853 zTableInfo = appendText(zTableInfo, zTable, '"');
1854 zTableInfo = appendText(zTableInfo, ");", 0);
1855
drhc7181902014-02-27 15:04:13 +00001856 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001857 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001858 if( rc!=SQLITE_OK || !pTableInfo ){
1859 return 1;
1860 }
1861
1862 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001863 /* Always quote the table name, even if it appears to be pure ascii,
1864 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1865 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001866 if( zTmp ){
1867 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001868 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001869 }
1870 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1871 rc = sqlite3_step(pTableInfo);
1872 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001873 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001874 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001875 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001876 rc = sqlite3_step(pTableInfo);
1877 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001878 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001879 }else{
1880 zSelect = appendText(zSelect, ") ", 0);
1881 }
drh157e29a2009-05-21 15:15:00 +00001882 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001883 }
1884 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001885 if( rc!=SQLITE_OK || nRow==0 ){
1886 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001887 return 1;
1888 }
1889 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1890 zSelect = appendText(zSelect, zTable, '"');
1891
drh2f464a02011-10-13 00:41:49 +00001892 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001893 if( rc==SQLITE_CORRUPT ){
1894 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001895 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001896 }
drh85e72432012-04-11 11:38:53 +00001897 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001898 }
drh4c653a02000-06-07 01:27:47 +00001899 return 0;
1900}
1901
1902/*
drh45e29d82006-11-20 16:21:10 +00001903** Run zQuery. Use dump_callback() as the callback routine so that
1904** the contents of the query are output as SQL statements.
1905**
drhdd3d4592004-08-30 01:54:05 +00001906** If we get a SQLITE_CORRUPT error, rerun the query after appending
1907** "ORDER BY rowid DESC" to the end.
1908*/
1909static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001910 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001911 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001912){
1913 int rc;
drh2f464a02011-10-13 00:41:49 +00001914 char *zErr = 0;
1915 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001916 if( rc==SQLITE_CORRUPT ){
1917 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001918 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00001919 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00001920 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00001921 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00001922 sqlite3_free(zErr);
1923 zErr = 0;
1924 }
drhdd3d4592004-08-30 01:54:05 +00001925 zQ2 = malloc( len+100 );
1926 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001927 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001928 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1929 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00001930 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00001931 }else{
1932 rc = SQLITE_CORRUPT;
1933 }
1934 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001935 free(zQ2);
1936 }
1937 return rc;
1938}
1939
1940/*
drh75897232000-05-29 14:26:00 +00001941** Text of a help message
1942*/
persicom1d0b8722002-04-18 02:53:04 +00001943static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001944 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001945 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00001946 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00001947 ".changes on|off Show number of rows changed by SQL\n"
drh4bbcf102014-02-06 02:46:08 +00001948 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001949 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001950 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001951 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001952 " If TABLE specified, only dump tables matching\n"
1953 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001954 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001955 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001956 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00001957 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drhc1971542014-06-23 23:28:13 +00001958 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001959 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001960 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001961 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001962 ".indexes ?TABLE? Show names of all indexes\n"
1963 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001964 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001965#ifdef SQLITE_ENABLE_IOTRACE
1966 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1967#endif
drh1a513372015-05-02 17:40:23 +00001968 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00001969#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001970 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001971#endif
drh127f9d72010-02-23 01:47:00 +00001972 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001973 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001974 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001975 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001976 " column Left-aligned columns. (See .width)\n"
1977 " html HTML <table> code\n"
1978 " insert SQL insert statements for TABLE\n"
1979 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001980 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001981 " tabs Tab-separated values\n"
1982 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001983 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001984 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001985 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001986 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001987 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001988 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001989 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001990 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001991 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001992 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001993 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001994 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001995 " If TABLE specified, only show tables matching\n"
1996 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001997 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1998 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001999 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00002000 ".show Show the current values for various settings\n"
drh34784902016-02-27 17:12:36 +00002001 ".stats ?on|off? Show stats or turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00002002 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00002003 ".tables ?TABLE? List names of tables\n"
2004 " If TABLE specified, only list tables matching\n"
2005 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00002006 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00002007 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00002008 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00002009 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00002010 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00002011 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00002012 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00002013 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00002014;
2015
drhdaffd0e2001-04-11 14:28:42 +00002016/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00002017static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00002018/*
2019** Implementation of the "readfile(X)" SQL function. The entire content
2020** of the file named X is read and returned as a BLOB. NULL is returned
2021** if the file does not exist or is unreadable.
2022*/
2023static void readfileFunc(
2024 sqlite3_context *context,
2025 int argc,
2026 sqlite3_value **argv
2027){
2028 const char *zName;
2029 FILE *in;
2030 long nIn;
2031 void *pBuf;
2032
drhf5ed7ad2015-06-15 14:43:25 +00002033 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002034 zName = (const char*)sqlite3_value_text(argv[0]);
2035 if( zName==0 ) return;
2036 in = fopen(zName, "rb");
2037 if( in==0 ) return;
2038 fseek(in, 0, SEEK_END);
2039 nIn = ftell(in);
2040 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00002041 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00002042 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
2043 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
2044 }else{
2045 sqlite3_free(pBuf);
2046 }
2047 fclose(in);
2048}
2049
2050/*
2051** Implementation of the "writefile(X,Y)" SQL function. The argument Y
2052** is written into file X. The number of bytes written is returned. Or
2053** NULL is returned if something goes wrong, such as being unable to open
2054** file X for writing.
2055*/
2056static void writefileFunc(
2057 sqlite3_context *context,
2058 int argc,
2059 sqlite3_value **argv
2060){
2061 FILE *out;
2062 const char *z;
drhba5b0932014-07-24 12:39:59 +00002063 sqlite3_int64 rc;
2064 const char *zFile;
2065
drhf5ed7ad2015-06-15 14:43:25 +00002066 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002067 zFile = (const char*)sqlite3_value_text(argv[0]);
2068 if( zFile==0 ) return;
2069 out = fopen(zFile, "wb");
2070 if( out==0 ) return;
2071 z = (const char*)sqlite3_value_blob(argv[1]);
2072 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002073 rc = 0;
2074 }else{
drh490fe862014-08-11 14:21:32 +00002075 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002076 }
2077 fclose(out);
2078 sqlite3_result_int64(context, rc);
2079}
drhdaffd0e2001-04-11 14:28:42 +00002080
drh75897232000-05-29 14:26:00 +00002081/*
drh44c2eb12003-04-30 11:38:26 +00002082** Make sure the database is open. If it is not, then open it. If
2083** the database fails to open, print an error message and exit.
2084*/
drhdcd87a92014-08-18 13:45:42 +00002085static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002086 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002087 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002088 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002089 globalDb = p->db;
2090 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2091 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002092 shellstaticFunc, 0, 0);
2093 }
mistachkin8e189222015-04-19 21:43:16 +00002094 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkinaae280e2015-12-31 19:06:24 +00002095 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002096 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002097 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002098 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002099 }
drhc2e87a32006-06-27 15:16:14 +00002100#ifndef SQLITE_OMIT_LOAD_EXTENSION
2101 sqlite3_enable_load_extension(p->db, 1);
2102#endif
mistachkin8e189222015-04-19 21:43:16 +00002103 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002104 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002105 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002106 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002107 }
2108}
2109
2110/*
drhfeac5f82004-08-01 00:10:45 +00002111** Do C-language style dequoting.
2112**
mistachkinf21979d2015-01-18 05:35:01 +00002113** \a -> alarm
2114** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002115** \t -> tab
2116** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002117** \v -> vertical tab
2118** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002119** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002120** \s -> space
drh4c56b992013-06-27 13:26:55 +00002121** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002122** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002123** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002124** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002125*/
2126static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002127 int i, j;
2128 char c;
drhc2ce0be2014-05-29 12:36:14 +00002129 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002130 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002131 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002132 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002133 if( c=='a' ){
2134 c = '\a';
2135 }else if( c=='b' ){
2136 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002137 }else if( c=='t' ){
2138 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002139 }else if( c=='n' ){
2140 c = '\n';
2141 }else if( c=='v' ){
2142 c = '\v';
2143 }else if( c=='f' ){
2144 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002145 }else if( c=='r' ){
2146 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002147 }else if( c=='"' ){
2148 c = '"';
2149 }else if( c=='\'' ){
2150 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002151 }else if( c=='\\' ){
2152 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002153 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002154 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002155 if( z[i+1]>='0' && z[i+1]<='7' ){
2156 i++;
2157 c = (c<<3) + z[i] - '0';
2158 if( z[i+1]>='0' && z[i+1]<='7' ){
2159 i++;
2160 c = (c<<3) + z[i] - '0';
2161 }
2162 }
2163 }
2164 }
2165 z[j] = c;
2166 }
drhc2ce0be2014-05-29 12:36:14 +00002167 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002168}
2169
2170/*
drh348d19c2013-06-03 12:47:43 +00002171** Return the value of a hexadecimal digit. Return -1 if the input
2172** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002173*/
drh348d19c2013-06-03 12:47:43 +00002174static int hexDigitValue(char c){
2175 if( c>='0' && c<='9' ) return c - '0';
2176 if( c>='a' && c<='f' ) return c - 'a' + 10;
2177 if( c>='A' && c<='F' ) return c - 'A' + 10;
2178 return -1;
drhc28490c2006-10-26 14:25:58 +00002179}
2180
2181/*
drh7d9f3942013-04-03 01:26:54 +00002182** Interpret zArg as an integer value, possibly with suffixes.
2183*/
2184static sqlite3_int64 integerValue(const char *zArg){
2185 sqlite3_int64 v = 0;
2186 static const struct { char *zSuffix; int iMult; } aMult[] = {
2187 { "KiB", 1024 },
2188 { "MiB", 1024*1024 },
2189 { "GiB", 1024*1024*1024 },
2190 { "KB", 1000 },
2191 { "MB", 1000000 },
2192 { "GB", 1000000000 },
2193 { "K", 1000 },
2194 { "M", 1000000 },
2195 { "G", 1000000000 },
2196 };
2197 int i;
2198 int isNeg = 0;
2199 if( zArg[0]=='-' ){
2200 isNeg = 1;
2201 zArg++;
2202 }else if( zArg[0]=='+' ){
2203 zArg++;
2204 }
drh348d19c2013-06-03 12:47:43 +00002205 if( zArg[0]=='0' && zArg[1]=='x' ){
2206 int x;
2207 zArg += 2;
2208 while( (x = hexDigitValue(zArg[0]))>=0 ){
2209 v = (v<<4) + x;
2210 zArg++;
2211 }
2212 }else{
2213 while( IsDigit(zArg[0]) ){
2214 v = v*10 + zArg[0] - '0';
2215 zArg++;
2216 }
drh7d9f3942013-04-03 01:26:54 +00002217 }
drhc2bed0a2013-05-24 11:57:50 +00002218 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002219 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2220 v *= aMult[i].iMult;
2221 break;
2222 }
2223 }
2224 return isNeg? -v : v;
2225}
2226
2227/*
drh348d19c2013-06-03 12:47:43 +00002228** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2229** for TRUE and FALSE. Return the integer value if appropriate.
2230*/
2231static int booleanValue(char *zArg){
2232 int i;
2233 if( zArg[0]=='0' && zArg[1]=='x' ){
2234 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2235 }else{
2236 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2237 }
2238 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2239 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2240 return 1;
2241 }
2242 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2243 return 0;
2244 }
mistachkinaae280e2015-12-31 19:06:24 +00002245 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002246 zArg);
2247 return 0;
2248}
2249
2250/*
drh42f64e52012-04-04 16:56:23 +00002251** Close an output file, assuming it is not stderr or stdout
2252*/
2253static void output_file_close(FILE *f){
2254 if( f && f!=stdout && f!=stderr ) fclose(f);
2255}
2256
2257/*
2258** Try to open an output file. The names "stdout" and "stderr" are
2259** recognized and do the right thing. NULL is returned if the output
2260** filename is "off".
2261*/
2262static FILE *output_file_open(const char *zFile){
2263 FILE *f;
2264 if( strcmp(zFile,"stdout")==0 ){
2265 f = stdout;
2266 }else if( strcmp(zFile, "stderr")==0 ){
2267 f = stderr;
2268 }else if( strcmp(zFile, "off")==0 ){
2269 f = 0;
2270 }else{
2271 f = fopen(zFile, "wb");
2272 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002273 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002274 }
2275 }
2276 return f;
2277}
2278
2279/*
2280** A routine for handling output from sqlite3_trace().
2281*/
2282static void sql_trace_callback(void *pArg, const char *z){
2283 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002284 if( f ){
2285 int i = (int)strlen(z);
2286 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002287 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002288 }
drh42f64e52012-04-04 16:56:23 +00002289}
2290
2291/*
drhd8621b92012-04-17 09:09:33 +00002292** A no-op routine that runs with the ".breakpoint" doc-command. This is
2293** a useful spot to set a debugger breakpoint.
2294*/
2295static void test_breakpoint(void){
2296 static int nCall = 0;
2297 nCall++;
2298}
2299
2300/*
mistachkin636bf9f2014-07-19 20:15:16 +00002301** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002302*/
mistachkin636bf9f2014-07-19 20:15:16 +00002303typedef struct ImportCtx ImportCtx;
2304struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002305 const char *zFile; /* Name of the input file */
2306 FILE *in; /* Read the CSV text from this input stream */
2307 char *z; /* Accumulated text for a field */
2308 int n; /* Number of bytes in z */
2309 int nAlloc; /* Space allocated for z[] */
2310 int nLine; /* Current line number */
2311 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002312 int cColSep; /* The column separator character. (Usually ",") */
2313 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002314};
2315
2316/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002317static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002318 if( p->n+1>=p->nAlloc ){
2319 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002320 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002321 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002322 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002323 exit(1);
2324 }
2325 }
2326 p->z[p->n++] = (char)c;
2327}
2328
2329/* Read a single field of CSV text. Compatible with rfc4180 and extended
2330** with the option of having a separator other than ",".
2331**
2332** + Input comes from p->in.
2333** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002334** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002335** + Use p->cSep as the column separator. The default is ",".
2336** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002337** + Keep track of the line number in p->nLine.
2338** + Store the character that terminates the field in p->cTerm. Store
2339** EOF on end-of-file.
2340** + Report syntax errors on stderr
2341*/
mistachkin44723ce2015-03-21 02:22:37 +00002342static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002343 int c;
2344 int cSep = p->cColSep;
2345 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002346 p->n = 0;
2347 c = fgetc(p->in);
2348 if( c==EOF || seenInterrupt ){
2349 p->cTerm = EOF;
2350 return 0;
2351 }
2352 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002353 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002354 int startLine = p->nLine;
2355 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002356 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002357 while( 1 ){
2358 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002359 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002360 if( c==cQuote ){
2361 if( pc==cQuote ){
2362 pc = 0;
2363 continue;
2364 }
2365 }
2366 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002367 || (c==rSep && pc==cQuote)
2368 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002369 || (c==EOF && pc==cQuote)
2370 ){
2371 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002372 p->cTerm = c;
2373 break;
2374 }
2375 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002376 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002377 p->zFile, p->nLine, cQuote);
2378 }
2379 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002380 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002381 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002382 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002383 break;
2384 }
mistachkin636bf9f2014-07-19 20:15:16 +00002385 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002386 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002387 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002388 }
drhdb95f682013-06-26 22:46:00 +00002389 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002390 while( c!=EOF && c!=cSep && c!=rSep ){
2391 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002392 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002393 }
mistachkin636bf9f2014-07-19 20:15:16 +00002394 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002395 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002396 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002397 }
drhdb95f682013-06-26 22:46:00 +00002398 p->cTerm = c;
2399 }
drh8dd675e2013-07-12 21:09:24 +00002400 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002401 return p->z;
2402}
2403
mistachkin636bf9f2014-07-19 20:15:16 +00002404/* Read a single field of ASCII delimited text.
2405**
2406** + Input comes from p->in.
2407** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002408** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002409** + Use p->cSep as the column separator. The default is "\x1F".
2410** + Use p->rSep as the row separator. The default is "\x1E".
2411** + Keep track of the row number in p->nLine.
2412** + Store the character that terminates the field in p->cTerm. Store
2413** EOF on end-of-file.
2414** + Report syntax errors on stderr
2415*/
mistachkin44723ce2015-03-21 02:22:37 +00002416static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002417 int c;
2418 int cSep = p->cColSep;
2419 int rSep = p->cRowSep;
2420 p->n = 0;
2421 c = fgetc(p->in);
2422 if( c==EOF || seenInterrupt ){
2423 p->cTerm = EOF;
2424 return 0;
2425 }
2426 while( c!=EOF && c!=cSep && c!=rSep ){
2427 import_append_char(p, c);
2428 c = fgetc(p->in);
2429 }
2430 if( c==rSep ){
2431 p->nLine++;
2432 }
2433 p->cTerm = c;
2434 if( p->z ) p->z[p->n] = 0;
2435 return p->z;
2436}
2437
drhdb95f682013-06-26 22:46:00 +00002438/*
drh4bbcf102014-02-06 02:46:08 +00002439** Try to transfer data for table zTable. If an error is seen while
2440** moving forward, try to go backwards. The backwards movement won't
2441** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002442*/
mistachkine31ae902014-02-06 01:15:29 +00002443static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002444 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002445 sqlite3 *newDb,
2446 const char *zTable
2447){
2448 sqlite3_stmt *pQuery = 0;
2449 sqlite3_stmt *pInsert = 0;
2450 char *zQuery = 0;
2451 char *zInsert = 0;
2452 int rc;
2453 int i, j, n;
2454 int nTable = (int)strlen(zTable);
2455 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002456 int cnt = 0;
2457 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002458
2459 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2460 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2461 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002462 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002463 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2464 zQuery);
2465 goto end_data_xfer;
2466 }
2467 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002468 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002469 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002470 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002471 goto end_data_xfer;
2472 }
2473 sqlite3_snprintf(200+nTable,zInsert,
2474 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2475 i = (int)strlen(zInsert);
2476 for(j=1; j<n; j++){
2477 memcpy(zInsert+i, ",?", 2);
2478 i += 2;
2479 }
2480 memcpy(zInsert+i, ");", 3);
2481 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2482 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002483 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002484 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2485 zQuery);
2486 goto end_data_xfer;
2487 }
2488 for(k=0; k<2; k++){
2489 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2490 for(i=0; i<n; i++){
2491 switch( sqlite3_column_type(pQuery, i) ){
2492 case SQLITE_NULL: {
2493 sqlite3_bind_null(pInsert, i+1);
2494 break;
2495 }
2496 case SQLITE_INTEGER: {
2497 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2498 break;
2499 }
2500 case SQLITE_FLOAT: {
2501 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2502 break;
2503 }
2504 case SQLITE_TEXT: {
2505 sqlite3_bind_text(pInsert, i+1,
2506 (const char*)sqlite3_column_text(pQuery,i),
2507 -1, SQLITE_STATIC);
2508 break;
2509 }
2510 case SQLITE_BLOB: {
2511 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2512 sqlite3_column_bytes(pQuery,i),
2513 SQLITE_STATIC);
2514 break;
2515 }
2516 }
2517 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002518 rc = sqlite3_step(pInsert);
2519 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002520 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002521 sqlite3_errmsg(newDb));
2522 }
drh3350ce92014-02-06 00:49:12 +00002523 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002524 cnt++;
2525 if( (cnt%spinRate)==0 ){
2526 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2527 fflush(stdout);
2528 }
drh3350ce92014-02-06 00:49:12 +00002529 } /* End while */
2530 if( rc==SQLITE_DONE ) break;
2531 sqlite3_finalize(pQuery);
2532 sqlite3_free(zQuery);
2533 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2534 zTable);
2535 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2536 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002537 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002538 break;
drh3350ce92014-02-06 00:49:12 +00002539 }
2540 } /* End for(k=0...) */
2541
2542end_data_xfer:
2543 sqlite3_finalize(pQuery);
2544 sqlite3_finalize(pInsert);
2545 sqlite3_free(zQuery);
2546 sqlite3_free(zInsert);
2547}
2548
2549
2550/*
2551** Try to transfer all rows of the schema that match zWhere. For
2552** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002553** If an error is encountered while moving forward through the
2554** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002555*/
mistachkine31ae902014-02-06 01:15:29 +00002556static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002557 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002558 sqlite3 *newDb,
2559 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002560 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002561){
2562 sqlite3_stmt *pQuery = 0;
2563 char *zQuery = 0;
2564 int rc;
2565 const unsigned char *zName;
2566 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002567 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002568
2569 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2570 " WHERE %s", zWhere);
2571 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2572 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002573 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002574 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2575 zQuery);
2576 goto end_schema_xfer;
2577 }
2578 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2579 zName = sqlite3_column_text(pQuery, 0);
2580 zSql = sqlite3_column_text(pQuery, 1);
2581 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002582 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2583 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002584 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002585 sqlite3_free(zErrMsg);
2586 zErrMsg = 0;
2587 }
drh3350ce92014-02-06 00:49:12 +00002588 if( xForEach ){
2589 xForEach(p, newDb, (const char*)zName);
2590 }
2591 printf("done\n");
2592 }
2593 if( rc!=SQLITE_DONE ){
2594 sqlite3_finalize(pQuery);
2595 sqlite3_free(zQuery);
2596 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2597 " WHERE %s ORDER BY rowid DESC", zWhere);
2598 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2599 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002600 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002601 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2602 zQuery);
2603 goto end_schema_xfer;
2604 }
2605 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2606 zName = sqlite3_column_text(pQuery, 0);
2607 zSql = sqlite3_column_text(pQuery, 1);
2608 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002609 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2610 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002611 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002612 sqlite3_free(zErrMsg);
2613 zErrMsg = 0;
2614 }
drh3350ce92014-02-06 00:49:12 +00002615 if( xForEach ){
2616 xForEach(p, newDb, (const char*)zName);
2617 }
2618 printf("done\n");
2619 }
2620 }
2621end_schema_xfer:
2622 sqlite3_finalize(pQuery);
2623 sqlite3_free(zQuery);
2624}
2625
2626/*
2627** Open a new database file named "zNewDb". Try to recover as much information
2628** as possible out of the main database (which might be corrupt) and write it
2629** into zNewDb.
2630*/
drhdcd87a92014-08-18 13:45:42 +00002631static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002632 int rc;
2633 sqlite3 *newDb = 0;
2634 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002635 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002636 return;
2637 }
2638 rc = sqlite3_open(zNewDb, &newDb);
2639 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002640 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002641 sqlite3_errmsg(newDb));
2642 }else{
drh54d0d2d2014-04-03 00:32:13 +00002643 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002644 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002645 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2646 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002647 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002648 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002649 }
2650 sqlite3_close(newDb);
2651}
2652
2653/*
drhc2ce0be2014-05-29 12:36:14 +00002654** Change the output file back to stdout
2655*/
drhdcd87a92014-08-18 13:45:42 +00002656static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002657 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002658#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002659 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002660#endif
drhc2ce0be2014-05-29 12:36:14 +00002661 }else{
2662 output_file_close(p->out);
2663 }
2664 p->outfile[0] = 0;
2665 p->out = stdout;
2666}
2667
2668/*
drhf7502f02015-02-06 14:19:44 +00002669** Run an SQL command and return the single integer result.
2670*/
2671static int db_int(ShellState *p, const char *zSql){
2672 sqlite3_stmt *pStmt;
2673 int res = 0;
2674 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2675 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2676 res = sqlite3_column_int(pStmt,0);
2677 }
2678 sqlite3_finalize(pStmt);
2679 return res;
2680}
2681
2682/*
2683** Convert a 2-byte or 4-byte big-endian integer into a native integer
2684*/
2685unsigned int get2byteInt(unsigned char *a){
2686 return (a[0]<<8) + a[1];
2687}
2688unsigned int get4byteInt(unsigned char *a){
2689 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2690}
2691
2692/*
2693** Implementation of the ".info" command.
2694**
2695** Return 1 on error, 2 to exit, and 0 otherwise.
2696*/
drh0e55db12015-02-06 14:51:13 +00002697static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002698 static const struct { const char *zName; int ofst; } aField[] = {
2699 { "file change counter:", 24 },
2700 { "database page count:", 28 },
2701 { "freelist page count:", 36 },
2702 { "schema cookie:", 40 },
2703 { "schema format:", 44 },
2704 { "default cache size:", 48 },
2705 { "autovacuum top root:", 52 },
2706 { "incremental vacuum:", 64 },
2707 { "text encoding:", 56 },
2708 { "user version:", 60 },
2709 { "application id:", 68 },
2710 { "software version:", 96 },
2711 };
drh0e55db12015-02-06 14:51:13 +00002712 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2713 { "number of tables:",
2714 "SELECT count(*) FROM %s WHERE type='table'" },
2715 { "number of indexes:",
2716 "SELECT count(*) FROM %s WHERE type='index'" },
2717 { "number of triggers:",
2718 "SELECT count(*) FROM %s WHERE type='trigger'" },
2719 { "number of views:",
2720 "SELECT count(*) FROM %s WHERE type='view'" },
2721 { "schema size:",
2722 "SELECT total(length(sql)) FROM %s" },
2723 };
mistachkinbfe8bd52015-11-17 19:17:14 +00002724 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00002725 int i;
2726 char *zSchemaTab;
2727 char *zDb = nArg>=2 ? azArg[1] : "main";
2728 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002729 open_db(p, 0);
2730 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002731 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002732 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2733 return 1;
2734 }
2735 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2736 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00002737 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00002738 return 1;
2739 }
2740 i = get2byteInt(aHdr+16);
2741 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00002742 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
2743 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2744 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2745 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00002746 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00002747 int ofst = aField[i].ofst;
2748 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00002749 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00002750 switch( ofst ){
2751 case 56: {
mistachkinaae280e2015-12-31 19:06:24 +00002752 if( val==1 ) raw_printf(p->out, " (utf8)");
2753 if( val==2 ) raw_printf(p->out, " (utf16le)");
2754 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00002755 }
2756 }
mistachkinaae280e2015-12-31 19:06:24 +00002757 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00002758 }
drh0e55db12015-02-06 14:51:13 +00002759 if( zDb==0 ){
2760 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2761 }else if( strcmp(zDb,"temp")==0 ){
2762 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2763 }else{
2764 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2765 }
drhf5ed7ad2015-06-15 14:43:25 +00002766 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00002767 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2768 int val = db_int(p, zSql);
2769 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00002770 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00002771 }
2772 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002773 return 0;
2774}
2775
dand95bb392015-09-30 11:19:05 +00002776/*
2777** Print the current sqlite3_errmsg() value to stderr and return 1.
2778*/
2779static int shellDatabaseError(sqlite3 *db){
2780 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00002781 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00002782 return 1;
2783}
2784
2785/*
2786** Print an out-of-memory message to stderr and return 1.
2787*/
2788static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00002789 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00002790 return 1;
2791}
drhf7502f02015-02-06 14:19:44 +00002792
2793/*
drh75897232000-05-29 14:26:00 +00002794** If an input line begins with "." then invoke this routine to
2795** process that line.
drh67505e72002-04-19 12:34:06 +00002796**
drh47ad6842006-11-08 12:25:42 +00002797** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002798*/
drhdcd87a92014-08-18 13:45:42 +00002799static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00002800 int h = 1;
drh75897232000-05-29 14:26:00 +00002801 int nArg = 0;
2802 int n, c;
drh67505e72002-04-19 12:34:06 +00002803 int rc = 0;
drh75897232000-05-29 14:26:00 +00002804 char *azArg[50];
2805
2806 /* Parse the input line into tokens.
2807 */
mistachkin8e189222015-04-19 21:43:16 +00002808 while( zLine[h] && nArg<ArraySize(azArg) ){
2809 while( IsSpace(zLine[h]) ){ h++; }
2810 if( zLine[h]==0 ) break;
2811 if( zLine[h]=='\'' || zLine[h]=='"' ){
2812 int delim = zLine[h++];
2813 azArg[nArg++] = &zLine[h];
2814 while( zLine[h] && zLine[h]!=delim ){
2815 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
2816 h++;
drh4c56b992013-06-27 13:26:55 +00002817 }
mistachkin8e189222015-04-19 21:43:16 +00002818 if( zLine[h]==delim ){
2819 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00002820 }
drhfeac5f82004-08-01 00:10:45 +00002821 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002822 }else{
mistachkin8e189222015-04-19 21:43:16 +00002823 azArg[nArg++] = &zLine[h];
2824 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
2825 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002826 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002827 }
2828 }
2829
2830 /* Process the input line.
2831 */
shane9bd1b442009-10-23 01:27:39 +00002832 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002833 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002834 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002835 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2836 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2837 ){
drhbc46f022013-01-23 18:53:23 +00002838 const char *zDestFile = 0;
2839 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002840 sqlite3 *pDest;
2841 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002842 int j;
2843 for(j=1; j<nArg; j++){
2844 const char *z = azArg[j];
2845 if( z[0]=='-' ){
2846 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002847 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002848 {
mistachkinaae280e2015-12-31 19:06:24 +00002849 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00002850 return 1;
2851 }
2852 }else if( zDestFile==0 ){
2853 zDestFile = azArg[j];
2854 }else if( zDb==0 ){
2855 zDb = zDestFile;
2856 zDestFile = azArg[j];
2857 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002858 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00002859 return 1;
2860 }
drh9ff849f2009-02-04 20:55:57 +00002861 }
drhbc46f022013-01-23 18:53:23 +00002862 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002863 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00002864 return 1;
2865 }
2866 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002867 rc = sqlite3_open(zDestFile, &pDest);
2868 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00002869 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002870 sqlite3_close(pDest);
2871 return 1;
2872 }
drh05782482013-10-24 15:20:20 +00002873 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002874 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2875 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002876 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00002877 sqlite3_close(pDest);
2878 return 1;
2879 }
2880 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2881 sqlite3_backup_finish(pBackup);
2882 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002883 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002884 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002885 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002886 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002887 }
2888 sqlite3_close(pDest);
2889 }else
2890
drhc2ce0be2014-05-29 12:36:14 +00002891 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2892 if( nArg==2 ){
2893 bail_on_error = booleanValue(azArg[1]);
2894 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002895 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00002896 rc = 1;
2897 }
drhc49f44e2006-10-26 18:15:42 +00002898 }else
2899
mistachkinf21979d2015-01-18 05:35:01 +00002900 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
2901 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00002902 if( booleanValue(azArg[1]) ){
2903 setBinaryMode(p->out);
2904 }else{
2905 setTextMode(p->out);
2906 }
mistachkinf21979d2015-01-18 05:35:01 +00002907 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002908 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00002909 rc = 1;
2910 }
2911 }else
2912
drhd8621b92012-04-17 09:09:33 +00002913 /* The undocumented ".breakpoint" command causes a call to the no-op
2914 ** routine named test_breakpoint().
2915 */
2916 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2917 test_breakpoint();
2918 }else
2919
drhdf12f1c2015-12-07 21:46:19 +00002920 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
2921 if( nArg==2 ){
2922 p->countChanges = booleanValue(azArg[1]);
2923 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002924 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00002925 rc = 1;
2926 }
2927 }else
2928
drhc2ce0be2014-05-29 12:36:14 +00002929 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2930 if( nArg==2 ){
2931 tryToClone(p, azArg[1]);
2932 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002933 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00002934 rc = 1;
2935 }
mistachkine31ae902014-02-06 01:15:29 +00002936 }else
2937
drhc2ce0be2014-05-29 12:36:14 +00002938 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002939 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002940 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002941 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002942 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002943 data.showHeader = 1;
drh700c2522016-02-09 18:39:25 +00002944 data.cMode = data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002945 data.colWidth[0] = 3;
2946 data.colWidth[1] = 15;
2947 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002948 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002949 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002950 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002951 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002952 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002953 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002954 }
2955 }else
2956
drh0e55db12015-02-06 14:51:13 +00002957 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2958 rc = shell_dbinfo_command(p, nArg, azArg);
2959 }else
2960
drhc2ce0be2014-05-29 12:36:14 +00002961 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002962 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002963 /* When playing back a "dump", the content might appear in an order
2964 ** which causes immediate foreign key constraints to be violated.
2965 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002966 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00002967 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00002968 rc = 1;
2969 goto meta_command_exit;
2970 }
mistachkinaae280e2015-12-31 19:06:24 +00002971 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
2972 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002973 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002974 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002975 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002976 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002977 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002978 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002979 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002980 );
2981 run_schema_dump_query(p,
2982 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002983 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002984 );
drh2f464a02011-10-13 00:41:49 +00002985 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002986 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002987 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002988 );
drh4c653a02000-06-07 01:27:47 +00002989 }else{
2990 int i;
drhdd3d4592004-08-30 01:54:05 +00002991 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002992 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002993 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002994 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002995 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002996 " AND sql NOT NULL");
2997 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002998 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002999 "WHERE sql NOT NULL"
3000 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00003001 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00003002 );
danielk1977bc6ada42004-06-30 08:20:16 +00003003 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00003004 }
3005 }
drh45e29d82006-11-20 16:21:10 +00003006 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00003007 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00003008 p->writableSchema = 0;
3009 }
drh56197952011-10-13 16:30:13 +00003010 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
3011 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00003012 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00003013 }else
drh75897232000-05-29 14:26:00 +00003014
drhc2ce0be2014-05-29 12:36:14 +00003015 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
3016 if( nArg==2 ){
3017 p->echoOn = booleanValue(azArg[1]);
3018 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003019 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003020 rc = 1;
3021 }
drhdaffd0e2001-04-11 14:28:42 +00003022 }else
3023
drhc2ce0be2014-05-29 12:36:14 +00003024 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
3025 if( nArg==2 ){
3026 p->autoEQP = booleanValue(azArg[1]);
3027 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003028 raw_printf(stderr, "Usage: .eqp on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003029 rc = 1;
3030 }
drhefbf3b12014-02-28 20:47:24 +00003031 }else
3032
drhd3ac7d92013-01-25 18:33:43 +00003033 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00003034 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00003035 rc = 2;
drh75897232000-05-29 14:26:00 +00003036 }else
3037
drhc2ce0be2014-05-29 12:36:14 +00003038 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00003039 int val = 1;
3040 if( nArg>=2 ){
3041 if( strcmp(azArg[1],"auto")==0 ){
3042 val = 99;
3043 }else{
3044 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003045 }
drh700c2522016-02-09 18:39:25 +00003046 }
3047 if( val==1 && p->mode!=MODE_Explain ){
3048 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003049 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003050 p->autoExplain = 0;
3051 }else if( val==0 ){
3052 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3053 p->autoExplain = 0;
3054 }else if( val==99 ){
3055 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3056 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003057 }
drh75897232000-05-29 14:26:00 +00003058 }else
3059
drhc1971542014-06-23 23:28:13 +00003060 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003061 ShellState data;
drhc1971542014-06-23 23:28:13 +00003062 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003063 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00003064 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003065 raw_printf(stderr, "Usage: .fullschema\n");
drhc1971542014-06-23 23:28:13 +00003066 rc = 1;
3067 goto meta_command_exit;
3068 }
3069 open_db(p, 0);
3070 memcpy(&data, p, sizeof(data));
3071 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003072 data.cMode = data.mode = MODE_Semi;
drhc1971542014-06-23 23:28:13 +00003073 rc = sqlite3_exec(p->db,
3074 "SELECT sql FROM"
3075 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3076 " FROM sqlite_master UNION ALL"
3077 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003078 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003079 "ORDER BY rowid",
3080 callback, &data, &zErrMsg
3081 );
drh56f674c2014-07-18 14:43:29 +00003082 if( rc==SQLITE_OK ){
3083 sqlite3_stmt *pStmt;
3084 rc = sqlite3_prepare_v2(p->db,
3085 "SELECT rowid FROM sqlite_master"
3086 " WHERE name GLOB 'sqlite_stat[134]'",
3087 -1, &pStmt, 0);
3088 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3089 sqlite3_finalize(pStmt);
3090 }
3091 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003092 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003093 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003094 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003095 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3096 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003097 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003098 data.zDestTable = "sqlite_stat1";
3099 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3100 shell_callback, &data,&zErrMsg);
3101 data.zDestTable = "sqlite_stat3";
3102 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3103 shell_callback, &data,&zErrMsg);
3104 data.zDestTable = "sqlite_stat4";
3105 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3106 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003107 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003108 }
drhc1971542014-06-23 23:28:13 +00003109 }else
3110
drhc2ce0be2014-05-29 12:36:14 +00003111 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3112 if( nArg==2 ){
3113 p->showHeader = booleanValue(azArg[1]);
3114 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003115 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003116 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003117 }
drh75897232000-05-29 14:26:00 +00003118 }else
3119
drhc2ce0be2014-05-29 12:36:14 +00003120 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003121 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003122 }else
3123
3124 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003125 char *zTable; /* Insert data into this table */
3126 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003127 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003128 int nCol; /* Number of columns in the table */
3129 int nByte; /* Number of bytes in an SQL string */
3130 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003131 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003132 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003133 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003134 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003135 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3136 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003137
drhc2ce0be2014-05-29 12:36:14 +00003138 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003139 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003140 goto meta_command_exit;
3141 }
drh01f37542014-05-31 15:43:33 +00003142 zFile = azArg[1];
3143 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003144 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003145 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003146 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003147 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003148 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003149 raw_printf(stderr,
3150 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003151 return 1;
drhfeac5f82004-08-01 00:10:45 +00003152 }
drhdb95f682013-06-26 22:46:00 +00003153 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003154 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003155 " for import\n");
3156 return 1;
3157 }
mistachkin636bf9f2014-07-19 20:15:16 +00003158 nSep = strlen30(p->rowSeparator);
3159 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003160 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003161 return 1;
3162 }
mistachkine0d68852014-12-11 03:12:33 +00003163 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3164 /* When importing CSV (only), if the row separator is set to the
3165 ** default output row separator, change it to the default input
3166 ** row separator. This avoids having to maintain different input
3167 ** and output row separators. */
3168 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3169 nSep = strlen30(p->rowSeparator);
3170 }
mistachkin636bf9f2014-07-19 20:15:16 +00003171 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003172 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003173 " for import\n");
3174 return 1;
3175 }
3176 sCtx.zFile = zFile;
3177 sCtx.nLine = 1;
3178 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003179#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003180 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003181 return 1;
3182#else
mistachkin636bf9f2014-07-19 20:15:16 +00003183 sCtx.in = popen(sCtx.zFile+1, "r");
3184 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003185 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003186#endif
drh5bde8162013-06-27 14:07:53 +00003187 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003188 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003189 xCloser = fclose;
3190 }
mistachkin636bf9f2014-07-19 20:15:16 +00003191 if( p->mode==MODE_Ascii ){
3192 xRead = ascii_read_one_field;
3193 }else{
3194 xRead = csv_read_one_field;
3195 }
3196 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003197 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003198 return 1;
3199 }
mistachkin636bf9f2014-07-19 20:15:16 +00003200 sCtx.cColSep = p->colSeparator[0];
3201 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003202 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003203 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003204 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003205 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003206 return 1;
3207 }
drh4f21c4a2008-12-10 22:15:00 +00003208 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003209 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003210 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003211 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003212 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3213 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003214 while( xRead(&sCtx) ){
drhd8c22ac2016-02-25 13:33:02 +00003215 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003216 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003217 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003218 }
drh5bde8162013-06-27 14:07:53 +00003219 if( cSep=='(' ){
3220 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003221 sqlite3_free(sCtx.z);
3222 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003223 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003224 return 1;
3225 }
drhdb95f682013-06-26 22:46:00 +00003226 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3227 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3228 sqlite3_free(zCreate);
3229 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003230 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003231 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003232 sqlite3_free(sCtx.z);
3233 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003234 return 1;
3235 }
drhc7181902014-02-27 15:04:13 +00003236 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003237 }
drhfeac5f82004-08-01 00:10:45 +00003238 sqlite3_free(zSql);
3239 if( rc ){
shane916f9612009-10-23 00:37:15 +00003240 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00003241 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003242 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003243 return 1;
drhfeac5f82004-08-01 00:10:45 +00003244 }
shane916f9612009-10-23 00:37:15 +00003245 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003246 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003247 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003248 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003249 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003250 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003251 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003252 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003253 return 1;
3254 }
drhdb95f682013-06-26 22:46:00 +00003255 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003256 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003257 for(i=1; i<nCol; i++){
3258 zSql[j++] = ',';
3259 zSql[j++] = '?';
3260 }
3261 zSql[j++] = ')';
3262 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003263 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003264 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003265 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003266 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003267 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003268 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003269 return 1;
drhfeac5f82004-08-01 00:10:45 +00003270 }
mistachkin8e189222015-04-19 21:43:16 +00003271 needCommit = sqlite3_get_autocommit(p->db);
3272 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003273 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003274 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003275 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003276 char *z = xRead(&sCtx);
3277 /*
3278 ** Did we reach end-of-file before finding any columns?
3279 ** If so, stop instead of NULL filling the remaining columns.
3280 */
drhdb95f682013-06-26 22:46:00 +00003281 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003282 /*
3283 ** Did we reach end-of-file OR end-of-line before finding any
3284 ** columns in ASCII mode? If so, stop instead of NULL filling
3285 ** the remaining columns.
3286 */
3287 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003288 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003289 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00003290 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003291 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003292 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003293 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003294 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003295 }
drhfeac5f82004-08-01 00:10:45 +00003296 }
mistachkin636bf9f2014-07-19 20:15:16 +00003297 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003298 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003299 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003300 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003301 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00003302 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003303 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003304 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003305 }
drhdb95f682013-06-26 22:46:00 +00003306 if( i>=nCol ){
3307 sqlite3_step(pStmt);
3308 rc = sqlite3_reset(pStmt);
3309 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003310 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
3311 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003312 }
3313 }
mistachkin636bf9f2014-07-19 20:15:16 +00003314 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003315
mistachkin636bf9f2014-07-19 20:15:16 +00003316 xCloser(sCtx.in);
3317 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003318 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003319 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003320 }else
3321
drh0e55db12015-02-06 14:51:13 +00003322 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3323 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003324 ShellState data;
drh75897232000-05-29 14:26:00 +00003325 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003326 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003327 memcpy(&data, p, sizeof(data));
3328 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003329 data.cMode = data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003330 if( nArg==1 ){
3331 rc = sqlite3_exec(p->db,
3332 "SELECT name FROM sqlite_master "
3333 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3334 "UNION ALL "
3335 "SELECT name FROM sqlite_temp_master "
3336 "WHERE type='index' "
3337 "ORDER BY 1",
3338 callback, &data, &zErrMsg
3339 );
drhc2ce0be2014-05-29 12:36:14 +00003340 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003341 zShellStatic = azArg[1];
3342 rc = sqlite3_exec(p->db,
3343 "SELECT name FROM sqlite_master "
3344 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3345 "UNION ALL "
3346 "SELECT name FROM sqlite_temp_master "
3347 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3348 "ORDER BY 1",
3349 callback, &data, &zErrMsg
3350 );
3351 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003352 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003353 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003354 rc = 1;
3355 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003356 }
drh75897232000-05-29 14:26:00 +00003357 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003358 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003359 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003360 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003361 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003362 raw_printf(stderr,
3363 "Error: querying sqlite_master and sqlite_temp_master\n");
shane86f5bdb2009-10-24 02:00:07 +00003364 rc = 1;
drh75897232000-05-29 14:26:00 +00003365 }
3366 }else
3367
drhae5e4452007-05-03 17:18:36 +00003368#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003369 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003370 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003371 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3372 iotrace = 0;
3373 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003374 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003375 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003376 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003377 iotrace = stdout;
3378 }else{
3379 iotrace = fopen(azArg[1], "w");
3380 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003381 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003382 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003383 rc = 1;
drhb0603412007-02-28 04:47:26 +00003384 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003385 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003386 }
3387 }
3388 }else
drhae5e4452007-05-03 17:18:36 +00003389#endif
drh1a513372015-05-02 17:40:23 +00003390 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3391 static const struct {
3392 const char *zLimitName; /* Name of a limit */
3393 int limitCode; /* Integer code for that limit */
3394 } aLimit[] = {
3395 { "length", SQLITE_LIMIT_LENGTH },
3396 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3397 { "column", SQLITE_LIMIT_COLUMN },
3398 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3399 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3400 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3401 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3402 { "attached", SQLITE_LIMIT_ATTACHED },
3403 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3404 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3405 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3406 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3407 };
3408 int i, n2;
3409 open_db(p, 0);
3410 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003411 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003412 printf("%20s %d\n", aLimit[i].zLimitName,
3413 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3414 }
3415 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003416 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00003417 rc = 1;
3418 goto meta_command_exit;
3419 }else{
3420 int iLimit = -1;
3421 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003422 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003423 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3424 if( iLimit<0 ){
3425 iLimit = i;
3426 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003427 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00003428 rc = 1;
3429 goto meta_command_exit;
3430 }
3431 }
3432 }
3433 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003434 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00003435 "enter \".limits\" with no arguments for a list.\n",
3436 azArg[1]);
3437 rc = 1;
3438 goto meta_command_exit;
3439 }
3440 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003441 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3442 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003443 }
3444 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3445 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3446 }
3447 }else
drhb0603412007-02-28 04:47:26 +00003448
drh70df4fe2006-06-13 15:12:21 +00003449#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003450 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003451 const char *zFile, *zProc;
3452 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003453 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003454 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00003455 rc = 1;
3456 goto meta_command_exit;
3457 }
drh1e397f82006-06-08 15:28:43 +00003458 zFile = azArg[1];
3459 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003460 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003461 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3462 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003463 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003464 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003465 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003466 }
3467 }else
drh70df4fe2006-06-13 15:12:21 +00003468#endif
drh1e397f82006-06-08 15:28:43 +00003469
drhc2ce0be2014-05-29 12:36:14 +00003470 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3471 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003472 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003473 rc = 1;
3474 }else{
3475 const char *zFile = azArg[1];
3476 output_file_close(p->pLog);
3477 p->pLog = output_file_open(zFile);
3478 }
drh127f9d72010-02-23 01:47:00 +00003479 }else
3480
drhc2ce0be2014-05-29 12:36:14 +00003481 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3482 const char *zMode = nArg>=2 ? azArg[1] : "";
3483 int n2 = (int)strlen(zMode);
3484 int c2 = zMode[0];
3485 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003486 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003487 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003488 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003489 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003490 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003491 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003492 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003493 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003494 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003495 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003496 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003497 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003498 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003499 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003500 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003501 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003502 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003503 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003504 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003505 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003506 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3507 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003508 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3509 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003510 }else {
mistachkinaae280e2015-12-31 19:06:24 +00003511 raw_printf(stderr, "Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003512 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003513 rc = 1;
drh75897232000-05-29 14:26:00 +00003514 }
drh700c2522016-02-09 18:39:25 +00003515 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00003516 }else
3517
drhc2ce0be2014-05-29 12:36:14 +00003518 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3519 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003520 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3521 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003522 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003523 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003524 rc = 1;
3525 }
3526 }else
3527
drh05782482013-10-24 15:20:20 +00003528 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3529 sqlite3 *savedDb = p->db;
3530 const char *zSavedFilename = p->zDbFilename;
3531 char *zNewFilename = 0;
3532 p->db = 0;
drhbbe031f2015-06-17 17:08:22 +00003533 if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3534 p->zDbFilename = zNewFilename;
drh05782482013-10-24 15:20:20 +00003535 open_db(p, 1);
3536 if( p->db!=0 ){
3537 sqlite3_close(savedDb);
3538 sqlite3_free(p->zFreeOnClose);
3539 p->zFreeOnClose = zNewFilename;
3540 }else{
3541 sqlite3_free(zNewFilename);
3542 p->db = savedDb;
3543 p->zDbFilename = zSavedFilename;
3544 }
3545 }else
3546
drhc2ce0be2014-05-29 12:36:14 +00003547 if( c=='o'
3548 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3549 ){
3550 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3551 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003552 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00003553 rc = 1;
3554 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003555 }
drhc2ce0be2014-05-29 12:36:14 +00003556 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3557 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003558 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003559 rc = 1;
3560 goto meta_command_exit;
3561 }
3562 p->outCount = 2;
3563 }else{
3564 p->outCount = 0;
3565 }
3566 output_reset(p);
3567 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003568#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003569 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003570 rc = 1;
3571 p->out = stdout;
3572#else
drhc2ce0be2014-05-29 12:36:14 +00003573 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003574 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003575 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003576 p->out = stdout;
3577 rc = 1;
3578 }else{
drhc2ce0be2014-05-29 12:36:14 +00003579 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003580 }
drh8cd5b252015-03-02 22:06:43 +00003581#endif
drh75897232000-05-29 14:26:00 +00003582 }else{
drhc2ce0be2014-05-29 12:36:14 +00003583 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003584 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003585 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003586 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003587 }
drh75897232000-05-29 14:26:00 +00003588 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003589 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003590 } else {
drhc2ce0be2014-05-29 12:36:14 +00003591 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003592 }
3593 }
3594 }else
3595
drh078b1fd2012-09-21 13:40:02 +00003596 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3597 int i;
3598 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00003599 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00003600 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00003601 }
mistachkinaae280e2015-12-31 19:06:24 +00003602 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00003603 }else
3604
drhc2ce0be2014-05-29 12:36:14 +00003605 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003606 if( nArg >= 2) {
3607 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3608 }
3609 if( nArg >= 3) {
3610 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3611 }
3612 }else
3613
drhc2ce0be2014-05-29 12:36:14 +00003614 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003615 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003616 }else
3617
drhc2ce0be2014-05-29 12:36:14 +00003618 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3619 FILE *alt;
3620 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003621 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003622 rc = 1;
3623 goto meta_command_exit;
3624 }
3625 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003626 if( alt==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003627 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
shane9bd1b442009-10-23 01:27:39 +00003628 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003629 }else{
shane9bd1b442009-10-23 01:27:39 +00003630 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003631 fclose(alt);
3632 }
3633 }else
3634
drhc2ce0be2014-05-29 12:36:14 +00003635 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003636 const char *zSrcFile;
3637 const char *zDb;
3638 sqlite3 *pSrc;
3639 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003640 int nTimeout = 0;
3641
drh9ff849f2009-02-04 20:55:57 +00003642 if( nArg==2 ){
3643 zSrcFile = azArg[1];
3644 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003645 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003646 zSrcFile = azArg[2];
3647 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003648 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003649 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003650 rc = 1;
3651 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003652 }
3653 rc = sqlite3_open(zSrcFile, &pSrc);
3654 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003655 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003656 sqlite3_close(pSrc);
3657 return 1;
3658 }
drh05782482013-10-24 15:20:20 +00003659 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003660 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3661 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003662 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00003663 sqlite3_close(pSrc);
3664 return 1;
3665 }
drhdc2c4912009-02-04 22:46:47 +00003666 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3667 || rc==SQLITE_BUSY ){
3668 if( rc==SQLITE_BUSY ){
3669 if( nTimeout++ >= 3 ) break;
3670 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003671 }
3672 }
3673 sqlite3_backup_finish(pBackup);
3674 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003675 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003676 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00003677 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00003678 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003679 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003680 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003681 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003682 }
3683 sqlite3_close(pSrc);
3684 }else
3685
dan8d1edb92014-11-05 09:07:28 +00003686
3687 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3688 if( nArg==2 ){
3689 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003690#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00003691 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00003692#endif
dan8d1edb92014-11-05 09:07:28 +00003693 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003694 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00003695 rc = 1;
3696 }
3697 }else
3698
drhc2ce0be2014-05-29 12:36:14 +00003699 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003700 ShellState data;
drh75897232000-05-29 14:26:00 +00003701 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003702 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003703 memcpy(&data, p, sizeof(data));
3704 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003705 data.cMode = data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003706 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003707 int i;
drhf0693c82011-10-11 20:41:54 +00003708 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003709 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003710 char *new_argv[2], *new_colv[2];
3711 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3712 " type text,\n"
3713 " name text,\n"
3714 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003715 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003716 " sql text\n"
3717 ")";
3718 new_argv[1] = 0;
3719 new_colv[0] = "sql";
3720 new_colv[1] = 0;
3721 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003722 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003723 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003724 char *new_argv[2], *new_colv[2];
3725 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3726 " type text,\n"
3727 " name text,\n"
3728 " tbl_name text,\n"
3729 " rootpage integer,\n"
3730 " sql text\n"
3731 ")";
3732 new_argv[1] = 0;
3733 new_colv[0] = "sql";
3734 new_colv[1] = 0;
3735 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003736 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003737 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003738 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003739 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003740 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003741 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003742 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003743 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003744 "WHERE lower(tbl_name) LIKE shellstatic()"
3745 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003746 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003747 callback, &data, &zErrMsg);
3748 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003749 }
drhc2ce0be2014-05-29 12:36:14 +00003750 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003751 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003752 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003753 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003754 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003755 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003756 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003757 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003758 callback, &data, &zErrMsg
3759 );
drhc2ce0be2014-05-29 12:36:14 +00003760 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003761 raw_printf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003762 rc = 1;
3763 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003764 }
drh75897232000-05-29 14:26:00 +00003765 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003766 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003767 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003768 rc = 1;
3769 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003770 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00003771 rc = 1;
3772 }else{
3773 rc = 0;
drh75897232000-05-29 14:26:00 +00003774 }
3775 }else
3776
drhabd4c722014-09-20 18:18:33 +00003777
3778#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3779 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3780 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003781 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003782 }else
3783#endif
3784
3785
drh340f5822013-06-27 13:01:21 +00003786#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003787 /* Undocumented commands for internal testing. Subject to change
3788 ** without notice. */
3789 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3790 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3791 int i, v;
3792 for(i=1; i<nArg; i++){
3793 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00003794 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00003795 }
3796 }
3797 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3798 int i; sqlite3_int64 v;
3799 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003800 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003801 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003802 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00003803 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003804 }
3805 }
3806 }else
drh340f5822013-06-27 13:01:21 +00003807#endif
drh348d19c2013-06-03 12:47:43 +00003808
drhc2ce0be2014-05-29 12:36:14 +00003809 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003810 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003811 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003812 rc = 1;
3813 }
drh6976c212014-07-24 12:09:47 +00003814 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003815 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003816 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003817 }
3818 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003819 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3820 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003821 }
drh75897232000-05-29 14:26:00 +00003822 }else
3823
drh62cdde52014-05-28 20:22:28 +00003824 if( c=='s'
3825 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003826 ){
3827 char *zCmd;
drh54027102014-08-06 14:36:53 +00003828 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003829 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003830 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00003831 rc = 1;
3832 goto meta_command_exit;
3833 }
drhdcb3e3d2014-05-29 03:17:29 +00003834 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003835 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003836 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3837 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003838 }
drh54027102014-08-06 14:36:53 +00003839 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003840 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00003841 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003842 }else
3843
drhc2ce0be2014-05-29 12:36:14 +00003844 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003845 int i;
drhc2ce0be2014-05-29 12:36:14 +00003846 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003847 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00003848 rc = 1;
3849 goto meta_command_exit;
3850 }
mistachkinaae280e2015-12-31 19:06:24 +00003851 utf8_printf(p->out, "%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3852 utf8_printf(p->out, "%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drh700c2522016-02-09 18:39:25 +00003853 utf8_printf(p->out, "%12.12s: %s\n","explain",
3854 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
mistachkinaae280e2015-12-31 19:06:24 +00003855 utf8_printf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3856 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
3857 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003858 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00003859 raw_printf(p->out, "\n");
3860 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003861 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00003862 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00003863 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00003864 raw_printf(p->out, "\n");
3865 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00003866 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00003867 raw_printf(p->out, "\n");
3868 utf8_printf(p->out, "%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3869 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00003870 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00003871 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003872 }
mistachkinaae280e2015-12-31 19:06:24 +00003873 raw_printf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003874 }else
3875
drhc2ce0be2014-05-29 12:36:14 +00003876 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3877 if( nArg==2 ){
3878 p->statsOn = booleanValue(azArg[1]);
drh34784902016-02-27 17:12:36 +00003879 }else if( nArg==1 ){
3880 display_stats(p->db, p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003881 }else{
drh34784902016-02-27 17:12:36 +00003882 raw_printf(stderr, "Usage: .stats ?on|off?\n");
drhc2ce0be2014-05-29 12:36:14 +00003883 rc = 1;
3884 }
shaneh642d8b82010-07-28 16:05:34 +00003885 }else
3886
drhc2ce0be2014-05-29 12:36:14 +00003887 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003888 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003889 char **azResult;
drh98781232012-04-23 12:38:05 +00003890 int nRow, nAlloc;
3891 char *zSql = 0;
3892 int ii;
drh05782482013-10-24 15:20:20 +00003893 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003894 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00003895 if( rc ) return shellDatabaseError(p->db);
3896
3897 /* Create an SQL statement to query for the list of tables in the
3898 ** main and all attached databases where the table name matches the
3899 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00003900 zSql = sqlite3_mprintf(
3901 "SELECT name FROM sqlite_master"
3902 " WHERE type IN ('table','view')"
3903 " AND name NOT LIKE 'sqlite_%%'"
3904 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00003905 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00003906 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3907 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3908 if( strcmp(zDbName,"temp")==0 ){
3909 zSql = sqlite3_mprintf(
3910 "%z UNION ALL "
3911 "SELECT 'temp.' || name FROM sqlite_temp_master"
3912 " WHERE type IN ('table','view')"
3913 " AND name NOT LIKE 'sqlite_%%'"
3914 " AND name LIKE ?1", zSql);
3915 }else{
3916 zSql = sqlite3_mprintf(
3917 "%z UNION ALL "
3918 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3919 " WHERE type IN ('table','view')"
3920 " AND name NOT LIKE 'sqlite_%%'"
3921 " AND name LIKE ?1", zSql, zDbName, zDbName);
3922 }
drha50da102000-08-08 20:19:09 +00003923 }
dand95bb392015-09-30 11:19:05 +00003924 rc = sqlite3_finalize(pStmt);
3925 if( zSql && rc==SQLITE_OK ){
3926 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3927 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3928 }
drh98781232012-04-23 12:38:05 +00003929 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00003930 if( !zSql ) return shellNomemError();
3931 if( rc ) return shellDatabaseError(p->db);
3932
3933 /* Run the SQL statement prepared by the above block. Store the results
3934 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00003935 nRow = nAlloc = 0;
3936 azResult = 0;
3937 if( nArg>1 ){
3938 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003939 }else{
drh98781232012-04-23 12:38:05 +00003940 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3941 }
3942 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3943 if( nRow>=nAlloc ){
3944 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00003945 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00003946 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00003947 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00003948 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00003949 break;
3950 }
mistachkin8e189222015-04-19 21:43:16 +00003951 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00003952 azResult = azNew;
3953 }
3954 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00003955 if( 0==azResult[nRow] ){
3956 rc = shellNomemError();
3957 break;
3958 }
3959 nRow++;
drh98781232012-04-23 12:38:05 +00003960 }
dand95bb392015-09-30 11:19:05 +00003961 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
3962 rc = shellDatabaseError(p->db);
3963 }
3964
3965 /* Pretty-print the contents of array azResult[] to the output */
3966 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003967 int len, maxlen = 0;
3968 int i, j;
3969 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003970 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003971 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003972 if( len>maxlen ) maxlen = len;
3973 }
3974 nPrintCol = 80/(maxlen+2);
3975 if( nPrintCol<1 ) nPrintCol = 1;
3976 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3977 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003978 for(j=i; j<nRow; j+=nPrintRow){
3979 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00003980 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
3981 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003982 }
mistachkinaae280e2015-12-31 19:06:24 +00003983 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003984 }
3985 }
dand95bb392015-09-30 11:19:05 +00003986
drh98781232012-04-23 12:38:05 +00003987 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3988 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003989 }else
3990
shaneh96887e12011-02-10 21:08:58 +00003991 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003992 static const struct {
3993 const char *zCtrlName; /* Name of a test-control option */
3994 int ctrlCode; /* Integer code for that option */
3995 } aCtrl[] = {
3996 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3997 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3998 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3999 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
4000 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
4001 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
4002 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
4003 { "assert", SQLITE_TESTCTRL_ASSERT },
4004 { "always", SQLITE_TESTCTRL_ALWAYS },
4005 { "reserve", SQLITE_TESTCTRL_RESERVE },
4006 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
4007 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00004008 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00004009 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00004010 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00004011 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00004012 };
shaneh96887e12011-02-10 21:08:58 +00004013 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00004014 int rc2 = 0;
4015 int i, n2;
drh05782482013-10-24 15:20:20 +00004016 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00004017
drhd416fe72011-03-17 16:45:50 +00004018 /* convert testctrl text option to value. allow any unique prefix
4019 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00004020 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00004021 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00004022 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00004023 if( testctrl<0 ){
4024 testctrl = aCtrl[i].ctrlCode;
4025 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004026 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00004027 testctrl = -1;
4028 break;
4029 }
4030 }
4031 }
drh348d19c2013-06-03 12:47:43 +00004032 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004033 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00004034 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004035 }else{
4036 switch(testctrl){
4037
4038 /* sqlite3_test_control(int, db, int) */
4039 case SQLITE_TESTCTRL_OPTIMIZATIONS:
4040 case SQLITE_TESTCTRL_RESERVE:
4041 if( nArg==3 ){
4042 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00004043 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004044 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004045 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004046 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004047 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004048 }
4049 break;
4050
4051 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004052 case SQLITE_TESTCTRL_PRNG_SAVE:
4053 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004054 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004055 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004056 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00004057 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00004058 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004059 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004060 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
4061 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004062 }
4063 break;
4064
4065 /* sqlite3_test_control(int, uint) */
4066 case SQLITE_TESTCTRL_PENDING_BYTE:
4067 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004068 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004069 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004070 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004071 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004072 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00004073 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004074 }
4075 break;
4076
4077 /* sqlite3_test_control(int, int) */
4078 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00004079 case SQLITE_TESTCTRL_ALWAYS:
4080 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004081 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00004082 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004083 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004084 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004085 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004086 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004087 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004088 }
4089 break;
4090
4091 /* sqlite3_test_control(int, char *) */
4092#ifdef SQLITE_N_KEYWORD
4093 case SQLITE_TESTCTRL_ISKEYWORD:
4094 if( nArg==3 ){
4095 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004096 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004097 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004098 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004099 utf8_printf(stderr,
4100 "Error: testctrl %s takes a single char * option\n",
4101 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004102 }
4103 break;
4104#endif
4105
drh1ffede82015-01-30 20:59:27 +00004106 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004107 if( nArg==5 ){
mistachkin8e189222015-04-19 21:43:16 +00004108 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004109 azArg[2],
drh8964b342015-01-29 17:54:52 +00004110 integerValue(azArg[3]),
4111 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00004112 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004113 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004114 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004115 }
4116 break;
4117
shaneh96887e12011-02-10 21:08:58 +00004118 case SQLITE_TESTCTRL_BITVEC_TEST:
4119 case SQLITE_TESTCTRL_FAULT_INSTALL:
4120 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4121 case SQLITE_TESTCTRL_SCRATCHMALLOC:
4122 default:
mistachkinaae280e2015-12-31 19:06:24 +00004123 utf8_printf(stderr,
4124 "Error: CLI support for testctrl %s not implemented\n",
4125 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004126 break;
4127 }
4128 }
4129 }else
4130
drhc2ce0be2014-05-29 12:36:14 +00004131 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004132 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004133 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004134 }else
4135
drhc2ce0be2014-05-29 12:36:14 +00004136 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4137 if( nArg==2 ){
4138 enableTimer = booleanValue(azArg[1]);
4139 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00004140 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00004141 enableTimer = 0;
4142 }
4143 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004144 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004145 rc = 1;
4146 }
shanehe2aa9d72009-11-06 17:20:17 +00004147 }else
4148
drhc2ce0be2014-05-29 12:36:14 +00004149 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004150 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004151 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004152 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004153 rc = 1;
4154 goto meta_command_exit;
4155 }
drh657b4a82015-03-19 13:30:41 +00004156 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004157 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004158#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004159 if( p->traceOut==0 ){
4160 sqlite3_trace(p->db, 0, 0);
4161 }else{
4162 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
4163 }
4164#endif
4165 }else
4166
drhf442e332014-09-10 19:01:14 +00004167#if SQLITE_USER_AUTHENTICATION
4168 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4169 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004170 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00004171 rc = 1;
4172 goto meta_command_exit;
4173 }
drh7883ecf2014-09-11 16:19:31 +00004174 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004175 if( strcmp(azArg[1],"login")==0 ){
4176 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00004177 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00004178 rc = 1;
4179 goto meta_command_exit;
4180 }
drhd39c40f2014-09-11 00:27:53 +00004181 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4182 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004183 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004184 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00004185 rc = 1;
4186 }
4187 }else if( strcmp(azArg[1],"add")==0 ){
4188 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004189 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004190 rc = 1;
4191 goto meta_command_exit;
4192 }
drhd39c40f2014-09-11 00:27:53 +00004193 rc = sqlite3_user_add(p->db, azArg[2],
4194 azArg[3], (int)strlen(azArg[3]),
4195 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004196 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004197 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004198 rc = 1;
4199 }
4200 }else if( strcmp(azArg[1],"edit")==0 ){
4201 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004202 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004203 rc = 1;
4204 goto meta_command_exit;
4205 }
drhd39c40f2014-09-11 00:27:53 +00004206 rc = sqlite3_user_change(p->db, azArg[2],
4207 azArg[3], (int)strlen(azArg[3]),
4208 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004209 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004210 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004211 rc = 1;
4212 }
4213 }else if( strcmp(azArg[1],"delete")==0 ){
4214 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004215 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00004216 rc = 1;
4217 goto meta_command_exit;
4218 }
4219 rc = sqlite3_user_delete(p->db, azArg[2]);
4220 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004221 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004222 rc = 1;
4223 }
4224 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004225 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00004226 rc = 1;
4227 goto meta_command_exit;
4228 }
4229 }else
4230#endif /* SQLITE_USER_AUTHENTICATION */
4231
drh9fd301b2011-06-03 13:28:22 +00004232 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004233 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004234 sqlite3_libversion(), sqlite3_sourceid());
4235 }else
4236
drh790f2872015-11-28 18:06:36 +00004237 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
4238 const char *zDbName = nArg==2 ? azArg[1] : "main";
4239 sqlite3_vfs *pVfs;
4240 if( p->db ){
4241 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
4242 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00004243 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
4244 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4245 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4246 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00004247 }
4248 }
4249 }else
4250
drhb19e7352016-01-12 19:37:20 +00004251 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
4252 sqlite3_vfs *pVfs;
4253 sqlite3_vfs *pCurrent = 0;
4254 if( p->db ){
4255 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
4256 }
4257 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
4258 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
4259 pVfs==pCurrent ? " <--- CURRENT" : "");
4260 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4261 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4262 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
4263 if( pVfs->pNext ){
4264 raw_printf(p->out, "-----------------------------------\n");
4265 }
4266 }
4267 }else
4268
drhde60fc22011-12-14 17:53:36 +00004269 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4270 const char *zDbName = nArg==2 ? azArg[1] : "main";
4271 char *zVfsName = 0;
4272 if( p->db ){
4273 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4274 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00004275 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004276 sqlite3_free(zVfsName);
4277 }
4278 }
4279 }else
4280
drhcef4fc82012-09-21 22:50:45 +00004281#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4282 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
4283 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00004284 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004285 }else
4286#endif
4287
drhc2ce0be2014-05-29 12:36:14 +00004288 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004289 int j;
drh43617e92006-03-06 20:55:46 +00004290 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004291 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004292 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004293 }
4294 }else
4295
4296 {
mistachkinaae280e2015-12-31 19:06:24 +00004297 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004298 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004299 rc = 1;
drh75897232000-05-29 14:26:00 +00004300 }
drh67505e72002-04-19 12:34:06 +00004301
drhc2ce0be2014-05-29 12:36:14 +00004302meta_command_exit:
4303 if( p->outCount ){
4304 p->outCount--;
4305 if( p->outCount==0 ) output_reset(p);
4306 }
drh67505e72002-04-19 12:34:06 +00004307 return rc;
drh75897232000-05-29 14:26:00 +00004308}
4309
drh67505e72002-04-19 12:34:06 +00004310/*
drh91a66392007-09-07 01:12:32 +00004311** Return TRUE if a semicolon occurs anywhere in the first N characters
4312** of string z[].
drh324ccef2003-02-05 14:06:20 +00004313*/
drh9f099fd2013-08-06 14:01:46 +00004314static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004315 int i;
4316 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4317 return 0;
drh324ccef2003-02-05 14:06:20 +00004318}
4319
4320/*
drh70c7a4b2003-04-26 03:03:06 +00004321** Test to see if a line consists entirely of whitespace.
4322*/
4323static int _all_whitespace(const char *z){
4324 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004325 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004326 if( *z=='/' && z[1]=='*' ){
4327 z += 2;
4328 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4329 if( *z==0 ) return 0;
4330 z++;
4331 continue;
4332 }
4333 if( *z=='-' && z[1]=='-' ){
4334 z += 2;
4335 while( *z && *z!='\n' ){ z++; }
4336 if( *z==0 ) return 1;
4337 continue;
4338 }
4339 return 0;
4340 }
4341 return 1;
4342}
4343
4344/*
drha9b17162003-04-29 18:01:28 +00004345** Return TRUE if the line typed in is an SQL command terminator other
4346** than a semi-colon. The SQL Server style "go" command is understood
4347** as is the Oracle "/".
4348*/
drh9f099fd2013-08-06 14:01:46 +00004349static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004350 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004351 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4352 return 1; /* Oracle */
4353 }
drhf0693c82011-10-11 20:41:54 +00004354 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004355 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004356 return 1; /* SQL Server */
4357 }
4358 return 0;
4359}
4360
4361/*
drh233a5312008-12-18 22:25:13 +00004362** Return true if zSql is a complete SQL statement. Return false if it
4363** ends in the middle of a string literal or C-style comment.
4364*/
drh9f099fd2013-08-06 14:01:46 +00004365static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004366 int rc;
4367 if( zSql==0 ) return 1;
4368 zSql[nSql] = ';';
4369 zSql[nSql+1] = 0;
4370 rc = sqlite3_complete(zSql);
4371 zSql[nSql] = 0;
4372 return rc;
4373}
4374
4375/*
drh67505e72002-04-19 12:34:06 +00004376** Read input from *in and process it. If *in==0 then input
4377** is interactive - the user is typing it it. Otherwise, input
4378** is coming from a file or device. A prompt is issued and history
4379** is saved only if input is interactive. An interrupt signal will
4380** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004381**
4382** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004383*/
drhdcd87a92014-08-18 13:45:42 +00004384static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004385 char *zLine = 0; /* A single input line */
4386 char *zSql = 0; /* Accumulated SQL text */
4387 int nLine; /* Length of current line */
4388 int nSql = 0; /* Bytes of zSql[] used */
4389 int nAlloc = 0; /* Allocated zSql[] space */
4390 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4391 char *zErrMsg; /* Error message returned */
4392 int rc; /* Error code */
4393 int errCnt = 0; /* Number of errors seen */
4394 int lineno = 0; /* Current line number */
4395 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004396
4397 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4398 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004399 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004400 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004401 /* End of input */
4402 if( stdin_is_interactive ) printf("\n");
4403 break;
drhc49f44e2006-10-26 18:15:42 +00004404 }
drh67505e72002-04-19 12:34:06 +00004405 if( seenInterrupt ){
4406 if( in!=0 ) break;
4407 seenInterrupt = 0;
4408 }
drhc28490c2006-10-26 14:25:58 +00004409 lineno++;
drh849a9d92013-12-21 15:46:06 +00004410 if( nSql==0 && _all_whitespace(zLine) ){
4411 if( p->echoOn ) printf("%s\n", zLine);
4412 continue;
4413 }
drh2af0b2d2002-02-21 02:25:02 +00004414 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004415 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004416 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004417 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004418 break;
4419 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004420 errCnt++;
4421 }
drhdaffd0e2001-04-11 14:28:42 +00004422 continue;
4423 }
drh9f099fd2013-08-06 14:01:46 +00004424 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004425 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004426 }
drh9f099fd2013-08-06 14:01:46 +00004427 nLine = strlen30(zLine);
4428 if( nSql+nLine+2>=nAlloc ){
4429 nAlloc = nSql+nLine+100;
4430 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004431 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004432 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004433 exit(1);
4434 }
drhdaffd0e2001-04-11 14:28:42 +00004435 }
drh9f099fd2013-08-06 14:01:46 +00004436 nSqlPrior = nSql;
4437 if( nSql==0 ){
4438 int i;
4439 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004440 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004441 memcpy(zSql, zLine+i, nLine+1-i);
4442 startline = lineno;
4443 nSql = nLine-i;
4444 }else{
4445 zSql[nSql++] = '\n';
4446 memcpy(zSql+nSql, zLine, nLine+1);
4447 nSql += nLine;
4448 }
4449 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004450 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004451 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004452 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004453 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004454 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004455 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004456 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004457 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004458 char zPrefix[100];
4459 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004460 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004461 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004462 }else{
shane9bd1b442009-10-23 01:27:39 +00004463 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004464 }
drh7f953e22002-07-13 17:33:45 +00004465 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004466 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004467 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004468 zErrMsg = 0;
4469 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004470 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004471 }
drhc49f44e2006-10-26 18:15:42 +00004472 errCnt++;
drhdf12f1c2015-12-07 21:46:19 +00004473 }else if( p->countChanges ){
mistachkinaae280e2015-12-31 19:06:24 +00004474 raw_printf(p->out, "changes: %3d total_changes: %d\n",
drhdf12f1c2015-12-07 21:46:19 +00004475 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
drhdaffd0e2001-04-11 14:28:42 +00004476 }
drhdaffd0e2001-04-11 14:28:42 +00004477 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004478 if( p->outCount ){
4479 output_reset(p);
4480 p->outCount = 0;
4481 }
drh9f099fd2013-08-06 14:01:46 +00004482 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004483 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004484 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004485 }
4486 }
drh9f099fd2013-08-06 14:01:46 +00004487 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004488 if( !_all_whitespace(zSql) ){
mistachkinaae280e2015-12-31 19:06:24 +00004489 utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004490 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004491 }
drhdaffd0e2001-04-11 14:28:42 +00004492 }
drh1f9ca2c2015-08-25 16:57:52 +00004493 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00004494 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004495 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004496}
4497
drh67505e72002-04-19 12:34:06 +00004498/*
4499** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004500** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004501*/
4502static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004503 static char *home_dir = NULL;
4504 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004505
drh4ace5362014-11-10 14:42:28 +00004506#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4507 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004508 {
4509 struct passwd *pwent;
4510 uid_t uid = getuid();
4511 if( (pwent=getpwuid(uid)) != NULL) {
4512 home_dir = pwent->pw_dir;
4513 }
drh67505e72002-04-19 12:34:06 +00004514 }
4515#endif
4516
chw65d3c132007-11-12 21:09:10 +00004517#if defined(_WIN32_WCE)
4518 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4519 */
drh85e72432012-04-11 11:38:53 +00004520 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004521#else
4522
drh83905c92012-06-21 13:00:37 +00004523#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004524 if (!home_dir) {
4525 home_dir = getenv("USERPROFILE");
4526 }
4527#endif
4528
drh67505e72002-04-19 12:34:06 +00004529 if (!home_dir) {
4530 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004531 }
4532
drh83905c92012-06-21 13:00:37 +00004533#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004534 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004535 char *zDrive, *zPath;
4536 int n;
4537 zDrive = getenv("HOMEDRIVE");
4538 zPath = getenv("HOMEPATH");
4539 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004540 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004541 home_dir = malloc( n );
4542 if( home_dir==0 ) return 0;
4543 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4544 return home_dir;
4545 }
4546 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004547 }
4548#endif
4549
chw65d3c132007-11-12 21:09:10 +00004550#endif /* !_WIN32_WCE */
4551
drh67505e72002-04-19 12:34:06 +00004552 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004553 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004554 char *z = malloc( n );
4555 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004556 home_dir = z;
4557 }
drhe98d4fa2002-04-21 19:06:22 +00004558
drh67505e72002-04-19 12:34:06 +00004559 return home_dir;
4560}
4561
4562/*
4563** Read input from the file given by sqliterc_override. Or if that
4564** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004565**
4566** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004567*/
drh534f4df2015-02-28 14:03:35 +00004568static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004569 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004570 const char *sqliterc_override /* Name of config file. NULL to use default */
4571){
persicom7e2dfdd2002-04-18 02:46:52 +00004572 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004573 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004574 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004575 FILE *in = NULL;
4576
4577 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004578 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004579 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004580 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00004581 " cannot read ~/.sqliterc\n");
4582 return;
drhe98d4fa2002-04-21 19:06:22 +00004583 }
drh2f3de322012-06-27 16:41:31 +00004584 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004585 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4586 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004587 }
drha1f9b5e2004-02-14 16:31:02 +00004588 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004589 if( in ){
drhc28490c2006-10-26 14:25:58 +00004590 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00004591 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004592 }
drh534f4df2015-02-28 14:03:35 +00004593 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004594 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004595 }
drh85e72432012-04-11 11:38:53 +00004596 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004597}
4598
drh67505e72002-04-19 12:34:06 +00004599/*
drhe1e38c42003-05-04 18:30:59 +00004600** Show available command line options
4601*/
4602static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004603 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004604 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004605 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004606 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004607 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004608 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004609 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004610 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004611 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004612#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4613 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4614#endif
drhcc3b4f82012-02-07 14:13:50 +00004615 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004616 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004617 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004618 " -line set output mode to 'line'\n"
4619 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004620 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004621 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004622#ifdef SQLITE_ENABLE_MULTIPLEX
4623 " -multiplex enable the multiplexor VFS\n"
4624#endif
mistachkine0d68852014-12-11 03:12:33 +00004625 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004626 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004627 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4628 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004629 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004630 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004631 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004632 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004633#ifdef SQLITE_ENABLE_VFSTRACE
4634 " -vfstrace enable tracing of all VFS calls\n"
4635#endif
drhe1e38c42003-05-04 18:30:59 +00004636;
4637static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00004638 utf8_printf(stderr,
drh80e8be92006-08-29 12:04:19 +00004639 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4640 "FILENAME is the name of an SQLite database. A new database is created\n"
4641 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004642 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00004643 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004644 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004645 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00004646 }
4647 exit(1);
4648}
4649
4650/*
drh67505e72002-04-19 12:34:06 +00004651** Initialize the state information in data
4652*/
drhdcd87a92014-08-18 13:45:42 +00004653static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004654 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00004655 data->normalMode = data->cMode = data->mode = MODE_List;
4656 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00004657 memcpy(data->colSeparator,SEP_Column, 2);
4658 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004659 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004660 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004661 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004662 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004663 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004664 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4665 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004666}
4667
drh98d312f2012-10-25 15:23:14 +00004668/*
drh5c7976f2014-02-10 19:59:27 +00004669** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004670*/
4671#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004672static void printBold(const char *zText){
4673 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4674 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4675 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4676 SetConsoleTextAttribute(out,
4677 FOREGROUND_RED|FOREGROUND_INTENSITY
4678 );
4679 printf("%s", zText);
4680 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004681}
4682#else
drh5c7976f2014-02-10 19:59:27 +00004683static void printBold(const char *zText){
4684 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004685}
4686#endif
4687
4688/*
drh98d312f2012-10-25 15:23:14 +00004689** Get the argument to an --option. Throw an error and die if no argument
4690** is available.
4691*/
4692static char *cmdline_option_value(int argc, char **argv, int i){
4693 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00004694 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00004695 argv[0], argv[argc-1]);
4696 exit(1);
4697 }
4698 return argv[i];
4699}
4700
mistachkin44723ce2015-03-21 02:22:37 +00004701int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004702 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004703 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004704 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004705 int i;
drhc28490c2006-10-26 14:25:58 +00004706 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004707 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004708 int readStdin = 1;
4709 int nCmd = 0;
4710 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004711
drh69b30ab2014-02-27 15:11:52 +00004712#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004713 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004714 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00004715 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4716 exit(1);
4717 }
drhc7181902014-02-27 15:04:13 +00004718#endif
drh047d4532015-01-18 20:30:23 +00004719 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004720 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004721 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004722 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004723 stdin_is_interactive = isatty(0);
drhe05461c2015-12-30 13:36:57 +00004724 stdout_is_console = isatty(1);
persicom7e2dfdd2002-04-18 02:46:52 +00004725
drh44c2eb12003-04-30 11:38:26 +00004726 /* Make sure we have a valid signal handler early, before anything
4727 ** else is done.
4728 */
drh4c504392000-10-16 22:06:40 +00004729#ifdef SIGINT
4730 signal(SIGINT, interrupt_handler);
4731#endif
drh44c2eb12003-04-30 11:38:26 +00004732
drhac5649a2014-11-28 13:35:03 +00004733#ifdef SQLITE_SHELL_DBNAME_PROC
4734 {
4735 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4736 ** of a C-function that will provide the name of the database file. Use
4737 ** this compile-time option to embed this shell program in larger
4738 ** applications. */
4739 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4740 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4741 warnInmemoryDb = 0;
4742 }
4743#endif
4744
drh22fbcb82004-02-01 01:22:50 +00004745 /* Do an initial pass through the command-line argument to locate
4746 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004747 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004748 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004749 */
drh98d312f2012-10-25 15:23:14 +00004750 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004751 char *z;
drhc28490c2006-10-26 14:25:58 +00004752 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004753 if( z[0]!='-' ){
4754 if( data.zDbFilename==0 ){
4755 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004756 }else{
4757 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4758 ** mean that nothing is read from stdin */
4759 readStdin = 0;
4760 nCmd++;
4761 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4762 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004763 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00004764 exit(1);
4765 }
4766 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004767 }
drh98d312f2012-10-25 15:23:14 +00004768 }
drhcc3b4f82012-02-07 14:13:50 +00004769 if( z[1]=='-' ) z++;
4770 if( strcmp(z,"-separator")==0
4771 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004772 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004773 || strcmp(z,"-cmd")==0
4774 ){
drh98d312f2012-10-25 15:23:14 +00004775 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004776 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004777 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004778 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004779 /* Need to check for batch mode here to so we can avoid printing
4780 ** informational messages (like from process_sqliterc) before
4781 ** we do the actual processing of arguments later in a second pass.
4782 */
shanef69573d2009-10-24 02:06:14 +00004783 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004784 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004785#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004786 const char *zSize;
4787 sqlite3_int64 szHeap;
4788
drh98d312f2012-10-25 15:23:14 +00004789 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004790 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004791 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004792 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4793#endif
drh44dec872014-08-30 15:49:25 +00004794 }else if( strcmp(z,"-scratch")==0 ){
4795 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004796 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004797 if( sz>400000 ) sz = 400000;
4798 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004799 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004800 if( n>10 ) n = 10;
4801 if( n<1 ) n = 1;
4802 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4803 data.shellFlgs |= SHFLG_Scratch;
4804 }else if( strcmp(z,"-pagecache")==0 ){
4805 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004806 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004807 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00004808 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004809 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00004810 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
4811 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00004812 data.shellFlgs |= SHFLG_Pagecache;
4813 }else if( strcmp(z,"-lookaside")==0 ){
4814 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004815 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004816 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004817 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004818 if( n<0 ) n = 0;
4819 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4820 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004821#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004822 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004823 extern int vfstrace_register(
4824 const char *zTraceName,
4825 const char *zOldVfsName,
4826 int (*xOut)(const char*,void*),
4827 void *pOutArg,
4828 int makeDefault
4829 );
drh2b625e22011-03-16 17:05:28 +00004830 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004831#endif
drh6f25e892011-07-08 17:02:57 +00004832#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004833 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004834 extern int sqlite3_multiple_initialize(const char*,int);
4835 sqlite3_multiplex_initialize(0, 1);
4836#endif
drh7d9f3942013-04-03 01:26:54 +00004837 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004838 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4839 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004840 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004841 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004842 if( pVfs ){
4843 sqlite3_vfs_register(pVfs, 1);
4844 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004845 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00004846 exit(1);
4847 }
drh44c2eb12003-04-30 11:38:26 +00004848 }
4849 }
drh98d312f2012-10-25 15:23:14 +00004850 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004851#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004852 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004853 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004854#else
mistachkinaae280e2015-12-31 19:06:24 +00004855 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00004856 return 1;
drh01b41712005-08-29 23:06:23 +00004857#endif
drh98d312f2012-10-25 15:23:14 +00004858 }
4859 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004860
drh44c2eb12003-04-30 11:38:26 +00004861 /* Go ahead and open the database file if it already exists. If the
4862 ** file does not exist, delay opening it. This prevents empty database
4863 ** files from being created if a user mistypes the database name argument
4864 ** to the sqlite command-line tool.
4865 */
drhc8d74412004-08-31 23:41:26 +00004866 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004867 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004868 }
4869
drh22fbcb82004-02-01 01:22:50 +00004870 /* Process the initialization file if there is one. If no -init option
4871 ** is given on the command line, look for a file named ~/.sqliterc and
4872 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004873 */
drh534f4df2015-02-28 14:03:35 +00004874 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004875
drh22fbcb82004-02-01 01:22:50 +00004876 /* Make a second pass through the command-line argument and set
4877 ** options. This second pass is delayed until after the initialization
4878 ** file is processed so that the command-line arguments will override
4879 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004880 */
drh98d312f2012-10-25 15:23:14 +00004881 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004882 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004883 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004884 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004885 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004886 i++;
4887 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004888 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004889 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004890 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004891 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004892 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004893 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004894 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004895 }else if( strcmp(z,"-csv")==0 ){
4896 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004897 memcpy(data.colSeparator,",",2);
4898 }else if( strcmp(z,"-ascii")==0 ){
4899 data.mode = MODE_Ascii;
4900 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004901 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004902 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004903 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004904 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004905 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4906 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004907 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004908 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004909 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004910 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004911 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004912 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004913 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004914 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004915 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004916 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004917 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004918 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004919 }else if( strcmp(z,"-eqp")==0 ){
4920 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004921 }else if( strcmp(z,"-stats")==0 ){
4922 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004923 }else if( strcmp(z,"-scanstats")==0 ){
4924 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00004925 }else if( strcmp(z,"-backslash")==0 ){
4926 /* Undocumented command-line option: -backslash
4927 ** Causes C-style backslash escapes to be evaluated in SQL statements
4928 ** prior to sending the SQL into SQLite. Useful for injecting
4929 ** crazy bytes in the middle of SQL statements for testing and debugging.
4930 */
4931 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004932 }else if( strcmp(z,"-bail")==0 ){
4933 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004934 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004935 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004936 return 0;
drhc28490c2006-10-26 14:25:58 +00004937 }else if( strcmp(z,"-interactive")==0 ){
4938 stdin_is_interactive = 1;
4939 }else if( strcmp(z,"-batch")==0 ){
4940 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004941 }else if( strcmp(z,"-heap")==0 ){
4942 i++;
drh44dec872014-08-30 15:49:25 +00004943 }else if( strcmp(z,"-scratch")==0 ){
4944 i+=2;
4945 }else if( strcmp(z,"-pagecache")==0 ){
4946 i+=2;
4947 }else if( strcmp(z,"-lookaside")==0 ){
4948 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004949 }else if( strcmp(z,"-mmap")==0 ){
4950 i++;
drha7e61d82011-03-12 17:02:57 +00004951 }else if( strcmp(z,"-vfs")==0 ){
4952 i++;
drh6f25e892011-07-08 17:02:57 +00004953#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004954 }else if( strcmp(z,"-vfstrace")==0 ){
4955 i++;
drh6f25e892011-07-08 17:02:57 +00004956#endif
4957#ifdef SQLITE_ENABLE_MULTIPLEX
4958 }else if( strcmp(z,"-multiplex")==0 ){
4959 i++;
4960#endif
drhcc3b4f82012-02-07 14:13:50 +00004961 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004962 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004963 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004964 /* Run commands that follow -cmd first and separately from commands
4965 ** that simply appear on the command-line. This seems goofy. It would
4966 ** be better if all commands ran in the order that they appear. But
4967 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004968 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004969 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004970 if( z[0]=='.' ){
4971 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004972 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004973 }else{
drh05782482013-10-24 15:20:20 +00004974 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004975 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4976 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004977 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00004978 if( bail_on_error ) return rc!=0 ? rc : 1;
4979 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004980 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00004981 if( bail_on_error ) return rc;
4982 }
4983 }
drh1e5d0e92000-05-31 23:33:17 +00004984 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004985 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
4986 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004987 return 1;
4988 }
drh700c2522016-02-09 18:39:25 +00004989 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00004990 }
drh44c2eb12003-04-30 11:38:26 +00004991
drhac5649a2014-11-28 13:35:03 +00004992 if( !readStdin ){
4993 /* Run all arguments that do not begin with '-' as if they were separate
4994 ** command-line inputs, except for the argToSkip argument which contains
4995 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004996 */
drhac5649a2014-11-28 13:35:03 +00004997 for(i=0; i<nCmd; i++){
4998 if( azCmd[i][0]=='.' ){
4999 rc = do_meta_command(azCmd[i], &data);
5000 if( rc ) return rc==2 ? 0 : rc;
5001 }else{
5002 open_db(&data, 0);
5003 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
5004 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005005 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00005006 return rc!=0 ? rc : 1;
5007 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005008 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00005009 return rc;
5010 }
drh6ff13852001-11-25 13:18:23 +00005011 }
drh75897232000-05-29 14:26:00 +00005012 }
drhac5649a2014-11-28 13:35:03 +00005013 free(azCmd);
drh75897232000-05-29 14:26:00 +00005014 }else{
drh44c2eb12003-04-30 11:38:26 +00005015 /* Run commands received from standard input
5016 */
drhc28490c2006-10-26 14:25:58 +00005017 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00005018 char *zHome;
5019 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00005020 int nHistory;
drh75897232000-05-29 14:26:00 +00005021 printf(
drh743e0032011-12-12 16:51:50 +00005022 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00005023 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00005024 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00005025 );
drhb3735912014-02-10 16:13:42 +00005026 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00005027 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00005028 printBold("transient in-memory database");
5029 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00005030 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00005031 }
drh67505e72002-04-19 12:34:06 +00005032 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00005033 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00005034 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00005035 if( (zHistory = malloc(nHistory))!=0 ){
5036 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
5037 }
drh67505e72002-04-19 12:34:06 +00005038 }
drhf5ed7ad2015-06-15 14:43:25 +00005039 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00005040 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00005041 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00005042 shell_stifle_history(100);
5043 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00005044 free(zHistory);
drh67505e72002-04-19 12:34:06 +00005045 }
drhdaffd0e2001-04-11 14:28:42 +00005046 }else{
drhc28490c2006-10-26 14:25:58 +00005047 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00005048 }
5049 }
drh33048c02001-10-01 14:29:22 +00005050 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00005051 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00005052 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00005053 }
drh05782482013-10-24 15:20:20 +00005054 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00005055 return rc;
drh75897232000-05-29 14:26:00 +00005056}