blob: ff1336a4b764426e29248573c44a3e9ac9467069 [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/*
drh4c504392000-10-16 22:06:40 +0000333** The following is the open SQLite database. We make a pointer
334** to this database a static variable so that it can be accessed
335** by the SIGINT handler to interrupt database processing.
336*/
mistachkin8e189222015-04-19 21:43:16 +0000337static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000338
339/*
drh67505e72002-04-19 12:34:06 +0000340** True if an interrupt (Control-C) has been received.
341*/
drh43617e92006-03-06 20:55:46 +0000342static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000343
344/*
persicom7e2dfdd2002-04-18 02:46:52 +0000345** This is the name of our program. It is set in main(), used
346** in a number of other places, mostly for error messages.
347*/
348static char *Argv0;
349
350/*
351** Prompt strings. Initialized in main. Settable with
352** .prompt main continue
353*/
354static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
355static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
356
drhb0603412007-02-28 04:47:26 +0000357/*
358** Write I/O traces to the following stream.
359*/
rsebe0a9092007-07-30 18:24:38 +0000360#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000361static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000362#endif
drhb0603412007-02-28 04:47:26 +0000363
364/*
365** This routine works like printf in that its first argument is a
366** format string and subsequent arguments are values to be substituted
367** in place of % fields. The result of formatting this string
368** is written to iotrace.
369*/
rsebe0a9092007-07-30 18:24:38 +0000370#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000371static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000372 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000373 char *z;
drhb0603412007-02-28 04:47:26 +0000374 if( iotrace==0 ) return;
375 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000376 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000377 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000378 fprintf(iotrace, "%s", z);
379 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000380}
rsebe0a9092007-07-30 18:24:38 +0000381#endif
drhb0603412007-02-28 04:47:26 +0000382
drh44c2eb12003-04-30 11:38:26 +0000383
persicom7e2dfdd2002-04-18 02:46:52 +0000384/*
drh83965662003-04-17 02:54:13 +0000385** Determines if a string is a number of not.
386*/
danielk19772e588c72005-12-09 14:25:08 +0000387static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000388 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000389 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000390 return 0;
391 }
392 z++;
393 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000394 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000395 if( *z=='.' ){
396 z++;
drhf0693c82011-10-11 20:41:54 +0000397 if( !IsDigit(*z) ) return 0;
398 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000399 if( realnum ) *realnum = 1;
400 }
401 if( *z=='e' || *z=='E' ){
402 z++;
403 if( *z=='+' || *z=='-' ) 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 return *z==0;
409}
drh83965662003-04-17 02:54:13 +0000410
411/*
danielk1977bc6ada42004-06-30 08:20:16 +0000412** A global char* and an SQL function to access its current value
413** from within an SQL statement. This program used to use the
414** sqlite_exec_printf() API to substitue a string into an SQL statement.
415** The correct way to do this with sqlite3 is to use the bind API, but
416** since the shell is built around the callback paradigm it would be a lot
417** of work. Instead just use this hack, which is quite harmless.
418*/
419static const char *zShellStatic = 0;
420static void shellstaticFunc(
421 sqlite3_context *context,
422 int argc,
423 sqlite3_value **argv
424){
425 assert( 0==argc );
426 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000427 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000428 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000429 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
430}
431
432
433/*
drhfeac5f82004-08-01 00:10:45 +0000434** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000435** the text in memory obtained from malloc() and returns a pointer
436** to the text. NULL is returned at end of file, or if malloc()
437** fails.
438**
drh9f099fd2013-08-06 14:01:46 +0000439** If zLine is not NULL then it is a malloced buffer returned from
440** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000441*/
drh9f099fd2013-08-06 14:01:46 +0000442static char *local_getline(char *zLine, FILE *in){
443 int nLine = zLine==0 ? 0 : 100;
444 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000445
drhb07028f2011-10-14 21:49:18 +0000446 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000447 if( n+100>nLine ){
448 nLine = nLine*2 + 100;
449 zLine = realloc(zLine, nLine);
450 if( zLine==0 ) return 0;
451 }
drhdaffd0e2001-04-11 14:28:42 +0000452 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000453 if( n==0 ){
454 free(zLine);
455 return 0;
456 }
457 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000458 break;
459 }
drh9f099fd2013-08-06 14:01:46 +0000460 while( zLine[n] ) n++;
461 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000462 n--;
shaneh13b36022009-12-17 21:07:15 +0000463 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000464 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000465 break;
drh8e7e7a22000-05-30 18:45:23 +0000466 }
467 }
drh8e7e7a22000-05-30 18:45:23 +0000468 return zLine;
469}
470
471/*
drhc28490c2006-10-26 14:25:58 +0000472** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000473**
drh9f099fd2013-08-06 14:01:46 +0000474** If in==0 then read from standard input and prompt before each line.
475** If isContinuation is true, then a continuation prompt is appropriate.
476** If isContinuation is zero, then the main prompt should be used.
477**
478** If zPrior is not NULL then it is a buffer from a prior call to this
479** routine that can be reused.
480**
481** The result is stored in space obtained from malloc() and must either
482** be freed by the caller or else passed back into this routine via the
483** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000484*/
drh9f099fd2013-08-06 14:01:46 +0000485static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000486 char *zPrompt;
487 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000488 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000489 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000490 }else{
drh9f099fd2013-08-06 14:01:46 +0000491 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000492#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000493 printf("%s", zPrompt);
494 fflush(stdout);
495 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000496#else
497 free(zPrior);
498 zResult = shell_readline(zPrompt);
499 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000500#endif
drh9f099fd2013-08-06 14:01:46 +0000501 }
drh8e7e7a22000-05-30 18:45:23 +0000502 return zResult;
503}
504
drhdcd87a92014-08-18 13:45:42 +0000505/*
506** Shell output mode information from before ".explain on",
507** saved so that it can be restored by ".explain off"
508*/
509typedef struct SavedModeInfo SavedModeInfo;
510struct SavedModeInfo {
511 int valid; /* Is there legit data in here? */
512 int mode; /* Mode prior to ".explain on" */
513 int showHeader; /* The ".header" setting prior to ".explain on" */
514 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000515};
drh45e29d82006-11-20 16:21:10 +0000516
drh8e7e7a22000-05-30 18:45:23 +0000517/*
drhdcd87a92014-08-18 13:45:42 +0000518** State information about the database connection is contained in an
519** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000520*/
drhdcd87a92014-08-18 13:45:42 +0000521typedef struct ShellState ShellState;
522struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000523 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000524 int echoOn; /* True to echo input commands */
drhc2ce0be2014-05-29 12:36:14 +0000525 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000526 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000527 int scanstatsOn; /* True to display scan stats before each finalize */
drhdf12f1c2015-12-07 21:46:19 +0000528 int countChanges; /* True to display change counts */
drh9569f602015-04-16 15:05:04 +0000529 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000530 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000531 int cnt; /* Number of records displayed so far */
532 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000533 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000534 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000535 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000536 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000537 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000538 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000539 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000540 char colSeparator[20]; /* Column separator character for several modes */
541 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000542 int colWidth[100]; /* Requested width of each column when in column mode*/
543 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000544 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000545 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000546 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000547 char outfile[FILENAME_MAX]; /* Filename for *out */
548 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000549 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000550 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000551 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000552 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000553 int *aiIndent; /* Array of indents used in MODE_Explain */
554 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000555 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000556};
557
558/*
drh44dec872014-08-30 15:49:25 +0000559** These are the allowed shellFlgs values
560*/
561#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
562#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
563#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
564
565/*
drh75897232000-05-29 14:26:00 +0000566** These are the allowed modes.
567*/
drh967e8b72000-06-21 13:59:10 +0000568#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000569#define MODE_Column 1 /* One record per line in neat columns */
570#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000571#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
572#define MODE_Html 4 /* Generate an XHTML table */
573#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000574#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000575#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000576#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000577#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000578
drh66ce4d02008-02-15 17:38:06 +0000579static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000580 "line",
581 "column",
582 "list",
583 "semi",
584 "html",
drhfeac5f82004-08-01 00:10:45 +0000585 "insert",
586 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000587 "csv",
drh66ce4d02008-02-15 17:38:06 +0000588 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000589 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000590};
drh75897232000-05-29 14:26:00 +0000591
592/*
mistachkinfad42082014-07-24 22:13:12 +0000593** These are the column/row/line separators used by the various
594** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000595*/
mistachkinfad42082014-07-24 22:13:12 +0000596#define SEP_Column "|"
597#define SEP_Row "\n"
598#define SEP_Tab "\t"
599#define SEP_Space " "
600#define SEP_Comma ","
601#define SEP_CrLf "\r\n"
602#define SEP_Unit "\x1F"
603#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000604
605/*
drh75897232000-05-29 14:26:00 +0000606** Number of elements in an array
607*/
drh902b9ee2008-12-05 17:17:07 +0000608#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000609
610/*
drhea678832008-12-10 19:26:22 +0000611** Compute a string length that is limited to what can be stored in
612** lower 30 bits of a 32-bit signed integer.
613*/
drh4f21c4a2008-12-10 22:15:00 +0000614static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000615 const char *z2 = z;
616 while( *z2 ){ z2++; }
617 return 0x3fffffff & (int)(z2 - z);
618}
619
620/*
drh127f9d72010-02-23 01:47:00 +0000621** A callback for the sqlite3_log() interface.
622*/
623static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000624 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000625 if( p->pLog==0 ) return;
626 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
627 fflush(p->pLog);
628}
629
630/*
shane626a6e42009-10-22 17:30:15 +0000631** Output the given string as a hex-encoded blob (eg. X'1234' )
632*/
633static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
634 int i;
635 char *zBlob = (char *)pBlob;
636 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000637 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000638 fprintf(out,"'");
639}
640
641/*
drh28bd4bc2000-06-15 15:57:22 +0000642** Output the given string as a quoted string using SQL quoting conventions.
643*/
644static void output_quoted_string(FILE *out, const char *z){
645 int i;
646 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000647 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000648 for(i=0; z[i]; i++){
649 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000650 }
651 if( nSingle==0 ){
652 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000653 }else{
654 fprintf(out,"'");
655 while( *z ){
656 for(i=0; z[i] && z[i]!='\''; i++){}
657 if( i==0 ){
658 fprintf(out,"''");
659 z++;
660 }else if( z[i]=='\'' ){
661 fprintf(out,"%.*s''",i,z);
662 z += i+1;
663 }else{
drhcd7d2732002-02-26 23:24:26 +0000664 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000665 break;
666 }
667 }
drhcd7d2732002-02-26 23:24:26 +0000668 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000669 }
drh047d4532015-01-18 20:30:23 +0000670 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000671}
672
673/*
drhfeac5f82004-08-01 00:10:45 +0000674** Output the given string as a quoted according to C or TCL quoting rules.
675*/
676static void output_c_string(FILE *out, const char *z){
677 unsigned int c;
678 fputc('"', out);
679 while( (c = *(z++))!=0 ){
680 if( c=='\\' ){
681 fputc(c, out);
682 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000683 }else if( c=='"' ){
684 fputc('\\', out);
685 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000686 }else if( c=='\t' ){
687 fputc('\\', out);
688 fputc('t', out);
689 }else if( c=='\n' ){
690 fputc('\\', out);
691 fputc('n', out);
692 }else if( c=='\r' ){
693 fputc('\\', out);
694 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000695 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000696 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000697 }else{
698 fputc(c, out);
699 }
700 }
701 fputc('"', out);
702}
703
704/*
drhc08a4f12000-06-15 16:49:48 +0000705** Output the given string with characters that are special to
706** HTML escaped.
707*/
708static void output_html_string(FILE *out, const char *z){
709 int i;
drhc3d6ba42014-01-13 20:38:35 +0000710 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000711 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000712 for(i=0; z[i]
713 && z[i]!='<'
714 && z[i]!='&'
715 && z[i]!='>'
716 && z[i]!='\"'
717 && z[i]!='\'';
718 i++){}
drhc08a4f12000-06-15 16:49:48 +0000719 if( i>0 ){
720 fprintf(out,"%.*s",i,z);
721 }
722 if( z[i]=='<' ){
723 fprintf(out,"&lt;");
724 }else if( z[i]=='&' ){
725 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000726 }else if( z[i]=='>' ){
727 fprintf(out,"&gt;");
728 }else if( z[i]=='\"' ){
729 fprintf(out,"&quot;");
730 }else if( z[i]=='\'' ){
731 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000732 }else{
733 break;
734 }
735 z += i + 1;
736 }
737}
738
739/*
drhc49f44e2006-10-26 18:15:42 +0000740** If a field contains any character identified by a 1 in the following
741** array, then the string must be quoted for CSV.
742*/
743static const char needCsvQuote[] = {
744 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
745 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
746 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
747 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
748 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
749 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
750 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
751 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
752 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
753 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
754 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
755 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
756 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
757 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
758 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
759 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
760};
761
762/*
mistachkindd11f2d2014-12-11 04:49:46 +0000763** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000764** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000765** the null value. Strings are quoted if necessary. The separator
766** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000767*/
drhdcd87a92014-08-18 13:45:42 +0000768static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000769 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000770 if( z==0 ){
mistachkin44b99f72014-12-11 03:29:14 +0000771 fprintf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000772 }else{
drhc49f44e2006-10-26 18:15:42 +0000773 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000774 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000775 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000776 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000777 || (z[i]==p->colSeparator[0] &&
778 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000779 i = 0;
780 break;
781 }
782 }
783 if( i==0 ){
784 putc('"', out);
785 for(i=0; z[i]; i++){
786 if( z[i]=='"' ) putc('"', out);
787 putc(z[i], out);
788 }
789 putc('"', out);
790 }else{
791 fprintf(out, "%s", z);
792 }
drh8e64d1c2004-10-07 00:32:39 +0000793 }
794 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000795 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000796 }
797}
798
danielk19774af00c62005-01-23 23:43:21 +0000799#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000800/*
drh4c504392000-10-16 22:06:40 +0000801** This routine runs when the user presses Ctrl-C
802*/
803static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000804 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000805 seenInterrupt++;
806 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000807 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000808}
danielk19774af00c62005-01-23 23:43:21 +0000809#endif
drh4c504392000-10-16 22:06:40 +0000810
811/*
shane626a6e42009-10-22 17:30:15 +0000812** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000813** invokes for each row of a query result.
814*/
drh4ace5362014-11-10 14:42:28 +0000815static int shell_callback(
816 void *pArg,
817 int nArg, /* Number of result columns */
818 char **azArg, /* Text of each result column */
819 char **azCol, /* Column names */
820 int *aiType /* Column types */
821){
drh75897232000-05-29 14:26:00 +0000822 int i;
drhdcd87a92014-08-18 13:45:42 +0000823 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000824
drh75897232000-05-29 14:26:00 +0000825 switch( p->mode ){
826 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000827 int w = 5;
drh6a535342001-10-19 16:44:56 +0000828 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000829 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000830 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000831 if( len>w ) w = len;
832 }
mistachkin636bf9f2014-07-19 20:15:16 +0000833 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000834 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000835 fprintf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000836 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000837 }
838 break;
839 }
danielk19770d78bae2008-01-03 07:09:48 +0000840 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000841 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000842 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000843 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000844 int w, n;
845 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000846 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000847 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000848 w = 0;
drh75897232000-05-29 14:26:00 +0000849 }
drh078b1fd2012-09-21 13:40:02 +0000850 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000851 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000852 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000853 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000854 if( w<n ) w = n;
855 }
856 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000857 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000858 }
859 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000860 if( w<0 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000861 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
862 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000863 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000864 fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
865 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000866 }
drha0c66f52000-07-29 13:20:21 +0000867 }
868 }
869 if( p->showHeader ){
870 for(i=0; i<nArg; i++){
871 int w;
872 if( i<ArraySize(p->actualWidth) ){
873 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000874 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000875 }else{
876 w = 10;
877 }
878 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
879 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000880 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000881 }
drh75897232000-05-29 14:26:00 +0000882 }
883 }
drh6a535342001-10-19 16:44:56 +0000884 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000885 for(i=0; i<nArg; i++){
886 int w;
drha0c66f52000-07-29 13:20:21 +0000887 if( i<ArraySize(p->actualWidth) ){
888 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000889 }else{
890 w = 10;
891 }
dana98bf362013-11-13 18:35:01 +0000892 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000893 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000894 }
dana98bf362013-11-13 18:35:01 +0000895 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000896 if( p->iIndent<p->nIndent ){
897 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000898 }
danc4650bb2013-11-18 08:41:06 +0000899 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000900 }
drh078b1fd2012-09-21 13:40:02 +0000901 if( w<0 ){
902 fprintf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000903 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000904 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000905 }else{
906 fprintf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000907 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000908 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000909 }
drh75897232000-05-29 14:26:00 +0000910 }
911 break;
912 }
drhe3710332000-09-29 13:30:53 +0000913 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000914 case MODE_List: {
915 if( p->cnt++==0 && p->showHeader ){
916 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000917 fprintf(p->out,"%s%s",azCol[i],
918 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000919 }
920 }
drh6a535342001-10-19 16:44:56 +0000921 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000922 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000923 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +0000924 if( z==0 ) z = p->nullValue;
drh71172c52002-01-24 00:00:21 +0000925 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000926 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000927 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000928 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000929 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000930 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000931 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000932 }
drh75897232000-05-29 14:26:00 +0000933 }
934 break;
935 }
drh1e5d0e92000-05-31 23:33:17 +0000936 case MODE_Html: {
937 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000938 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000939 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000940 fprintf(p->out,"<TH>");
941 output_html_string(p->out, azCol[i]);
942 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000943 }
mihailim57c591a2008-06-23 21:26:05 +0000944 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000945 }
drh6a535342001-10-19 16:44:56 +0000946 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000947 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000948 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000949 fprintf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +0000950 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mihailim57c591a2008-06-23 21:26:05 +0000951 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000952 }
mihailim57c591a2008-06-23 21:26:05 +0000953 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000954 break;
955 }
drhfeac5f82004-08-01 00:10:45 +0000956 case MODE_Tcl: {
957 if( p->cnt++==0 && p->showHeader ){
958 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000959 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000960 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000961 }
mistachkin636bf9f2014-07-19 20:15:16 +0000962 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000963 }
964 if( azArg==0 ) break;
965 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +0000966 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000967 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000968 }
mistachkin636bf9f2014-07-19 20:15:16 +0000969 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000970 break;
971 }
drh8e64d1c2004-10-07 00:32:39 +0000972 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +0000973 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000974 if( p->cnt++==0 && p->showHeader ){
975 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000976 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000977 }
mistachkine0d68852014-12-11 03:12:33 +0000978 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000979 }
drh40253262014-10-17 21:35:05 +0000980 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000981 for(i=0; i<nArg; i++){
982 output_csv(p, azArg[i], i<nArg-1);
983 }
mistachkine0d68852014-12-11 03:12:33 +0000984 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000985 }
drh047d4532015-01-18 20:30:23 +0000986 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000987 break;
988 }
drh28bd4bc2000-06-15 15:57:22 +0000989 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000990 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000991 if( azArg==0 ) break;
mistachkin151c75a2015-04-07 21:16:40 +0000992 fprintf(p->out,"INSERT INTO %s",p->zDestTable);
993 if( p->showHeader ){
994 fprintf(p->out,"(");
995 for(i=0; i<nArg; i++){
996 char *zSep = i>0 ? ",": "";
997 fprintf(p->out, "%s%s", zSep, azCol[i]);
998 }
999 fprintf(p->out,")");
1000 }
1001 fprintf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001002 for(i=0; i<nArg; i++){
1003 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001004 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +00001005 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001006 }else if( aiType && aiType[i]==SQLITE_TEXT ){
1007 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1008 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001009 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1010 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +00001011 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001012 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1013 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1014 int nBlob = sqlite3_column_bytes(p->pStmt, i);
1015 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1016 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001017 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001018 fprintf(p->out,"%s%s",zSep, azArg[i]);
1019 }else{
1020 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1021 output_quoted_string(p->out, azArg[i]);
1022 }
1023 }
1024 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001025 break;
drh28bd4bc2000-06-15 15:57:22 +00001026 }
mistachkin636bf9f2014-07-19 20:15:16 +00001027 case MODE_Ascii: {
1028 if( p->cnt++==0 && p->showHeader ){
1029 for(i=0; i<nArg; i++){
1030 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
1031 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
1032 }
1033 fprintf(p->out, "%s", p->rowSeparator);
1034 }
1035 if( azArg==0 ) break;
1036 for(i=0; i<nArg; i++){
1037 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
mistachkin44b99f72014-12-11 03:29:14 +00001038 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001039 }
1040 fprintf(p->out, "%s", p->rowSeparator);
1041 break;
1042 }
persicom1d0b8722002-04-18 02:53:04 +00001043 }
drh75897232000-05-29 14:26:00 +00001044 return 0;
1045}
1046
1047/*
shane626a6e42009-10-22 17:30:15 +00001048** This is the callback routine that the SQLite library
1049** invokes for each row of a query result.
1050*/
1051static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1052 /* since we don't have type info, call the shell_callback with a NULL value */
1053 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1054}
1055
1056/*
drhdcd87a92014-08-18 13:45:42 +00001057** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001058** the name of the table given. Escape any quote characters in the
1059** table name.
1060*/
drhdcd87a92014-08-18 13:45:42 +00001061static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001062 int i, n;
1063 int needQuote;
1064 char *z;
1065
1066 if( p->zDestTable ){
1067 free(p->zDestTable);
1068 p->zDestTable = 0;
1069 }
1070 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001071 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001072 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001073 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001074 needQuote = 1;
1075 if( zName[i]=='\'' ) n++;
1076 }
1077 }
1078 if( needQuote ) n += 2;
1079 z = p->zDestTable = malloc( n+1 );
1080 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001081 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001082 exit(1);
1083 }
1084 n = 0;
1085 if( needQuote ) z[n++] = '\'';
1086 for(i=0; zName[i]; i++){
1087 z[n++] = zName[i];
1088 if( zName[i]=='\'' ) z[n++] = '\'';
1089 }
1090 if( needQuote ) z[n++] = '\'';
1091 z[n] = 0;
1092}
1093
danielk19772a02e332004-06-05 08:04:36 +00001094/* zIn is either a pointer to a NULL-terminated string in memory obtained
1095** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1096** added to zIn, and the result returned in memory obtained from malloc().
1097** zIn, if it was not NULL, is freed.
1098**
1099** If the third argument, quote, is not '\0', then it is used as a
1100** quote character for zAppend.
1101*/
drhc28490c2006-10-26 14:25:58 +00001102static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001103 int len;
1104 int i;
drh4f21c4a2008-12-10 22:15:00 +00001105 int nAppend = strlen30(zAppend);
1106 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001107
1108 len = nAppend+nIn+1;
1109 if( quote ){
1110 len += 2;
1111 for(i=0; i<nAppend; i++){
1112 if( zAppend[i]==quote ) len++;
1113 }
1114 }
1115
1116 zIn = (char *)realloc(zIn, len);
1117 if( !zIn ){
1118 return 0;
1119 }
1120
1121 if( quote ){
1122 char *zCsr = &zIn[nIn];
1123 *zCsr++ = quote;
1124 for(i=0; i<nAppend; i++){
1125 *zCsr++ = zAppend[i];
1126 if( zAppend[i]==quote ) *zCsr++ = quote;
1127 }
1128 *zCsr++ = quote;
1129 *zCsr++ = '\0';
1130 assert( (zCsr-zIn)==len );
1131 }else{
1132 memcpy(&zIn[nIn], zAppend, nAppend);
1133 zIn[len-1] = '\0';
1134 }
1135
1136 return zIn;
1137}
1138
drhdd3d4592004-08-30 01:54:05 +00001139
1140/*
drhb21a8e42012-01-28 21:08:51 +00001141** Execute a query statement that will generate SQL output. Print
1142** the result columns, comma-separated, on a line and then add a
1143** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001144**
drhb21a8e42012-01-28 21:08:51 +00001145** If the number of columns is 1 and that column contains text "--"
1146** then write the semicolon on a separate line. That way, if a
1147** "--" comment occurs at the end of the statement, the comment
1148** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001149*/
drh157e29a2009-05-21 15:15:00 +00001150static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001151 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001152 const char *zSelect, /* SELECT statement to extract content */
1153 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001154){
drhdd3d4592004-08-30 01:54:05 +00001155 sqlite3_stmt *pSelect;
1156 int rc;
drhb21a8e42012-01-28 21:08:51 +00001157 int nResult;
1158 int i;
1159 const char *z;
drhc7181902014-02-27 15:04:13 +00001160 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001161 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001162 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001163 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001164 return rc;
1165 }
1166 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001167 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001168 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001169 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001170 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001171 zFirstRow = 0;
1172 }
drhb21a8e42012-01-28 21:08:51 +00001173 z = (const char*)sqlite3_column_text(pSelect, 0);
1174 fprintf(p->out, "%s", z);
1175 for(i=1; i<nResult; i++){
1176 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1177 }
1178 if( z==0 ) z = "";
1179 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1180 if( z[0] ){
1181 fprintf(p->out, "\n;\n");
1182 }else{
1183 fprintf(p->out, ";\n");
1184 }
drhdd3d4592004-08-30 01:54:05 +00001185 rc = sqlite3_step(pSelect);
1186 }
drh2f464a02011-10-13 00:41:49 +00001187 rc = sqlite3_finalize(pSelect);
1188 if( rc!=SQLITE_OK ){
1189 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001190 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001191 }
1192 return rc;
drhdd3d4592004-08-30 01:54:05 +00001193}
1194
shane626a6e42009-10-22 17:30:15 +00001195/*
1196** Allocate space and save off current error string.
1197*/
1198static char *save_err_msg(
1199 sqlite3 *db /* Database to query */
1200){
1201 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001202 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001203 if( zErrMsg ){
1204 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1205 }
1206 return zErrMsg;
1207}
1208
1209/*
shaneh642d8b82010-07-28 16:05:34 +00001210** Display memory stats.
1211*/
1212static int display_stats(
1213 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001214 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001215 int bReset /* True to reset the stats */
1216){
1217 int iCur;
1218 int iHiwtr;
1219
1220 if( pArg && pArg->out ){
1221
1222 iHiwtr = iCur = -1;
1223 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001224 fprintf(pArg->out,
1225 "Memory Used: %d (max %d) bytes\n",
1226 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001227 iHiwtr = iCur = -1;
1228 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001229 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1230 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001231 if( pArg->shellFlgs & SHFLG_Pagecache ){
1232 iHiwtr = iCur = -1;
1233 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001234 fprintf(pArg->out,
1235 "Number of Pcache Pages Used: %d (max %d) pages\n",
1236 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001237 }
shaneh642d8b82010-07-28 16:05:34 +00001238 iHiwtr = iCur = -1;
1239 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001240 fprintf(pArg->out,
1241 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1242 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001243 if( pArg->shellFlgs & SHFLG_Scratch ){
1244 iHiwtr = iCur = -1;
1245 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001246 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1247 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001248 }
shaneh642d8b82010-07-28 16:05:34 +00001249 iHiwtr = iCur = -1;
1250 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001251 fprintf(pArg->out,
1252 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1253 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001254 iHiwtr = iCur = -1;
1255 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001256 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1257 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001258 iHiwtr = iCur = -1;
1259 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001260 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1261 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001262 iHiwtr = iCur = -1;
1263 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001264 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1265 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001266#ifdef YYTRACKMAXSTACKDEPTH
1267 iHiwtr = iCur = -1;
1268 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001269 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1270 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001271#endif
1272 }
1273
1274 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001275 if( pArg->shellFlgs & SHFLG_Lookaside ){
1276 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001277 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1278 &iCur, &iHiwtr, bReset);
1279 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1280 iCur, iHiwtr);
1281 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1282 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001283 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001284 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1285 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001286 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001287 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1288 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001289 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1290 }
shaneh642d8b82010-07-28 16:05:34 +00001291 iHiwtr = iCur = -1;
1292 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001293 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1294 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001295 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1296 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1297 iHiwtr = iCur = -1;
1298 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1299 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001300 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001301 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1302 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1303 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001304 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001305 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001306 iHiwtr = iCur = -1;
1307 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001308 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001309 }
1310
1311 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001312 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1313 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001314 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1315 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1316 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001317 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001318 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001319 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1320 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001321 }
1322
dan5a790282015-08-07 20:06:14 +00001323 /* Do not remove this machine readable comment: extra-stats-output-here */
1324
shaneh642d8b82010-07-28 16:05:34 +00001325 return 0;
1326}
1327
1328/*
dan8d1edb92014-11-05 09:07:28 +00001329** Display scan stats.
1330*/
1331static void display_scanstats(
1332 sqlite3 *db, /* Database to query */
1333 ShellState *pArg /* Pointer to ShellState */
1334){
drhf5ed7ad2015-06-15 14:43:25 +00001335#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1336 UNUSED_PARAMETER(db);
1337 UNUSED_PARAMETER(pArg);
1338#else
drh15f23c22014-11-06 12:46:16 +00001339 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001340 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001341 mx = 0;
1342 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001343 double rEstLoop = 1.0;
1344 for(i=n=0; 1; i++){
1345 sqlite3_stmt *p = pArg->pStmt;
1346 sqlite3_int64 nLoop, nVisit;
1347 double rEst;
1348 int iSid;
1349 const char *zExplain;
1350 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1351 break;
1352 }
1353 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001354 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001355 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001356 if( n==0 ){
1357 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001358 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001359 }
drh42f30bc2014-11-06 12:08:21 +00001360 n++;
1361 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1362 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1363 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1364 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1365 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001366 fprintf(pArg->out,
1367 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001368 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001369 );
dan8d1edb92014-11-05 09:07:28 +00001370 }
dan8d1edb92014-11-05 09:07:28 +00001371 }
dan8d1edb92014-11-05 09:07:28 +00001372 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001373#endif
dan8d1edb92014-11-05 09:07:28 +00001374}
1375
1376/*
dana98bf362013-11-13 18:35:01 +00001377** Parameter azArray points to a zero-terminated array of strings. zStr
1378** points to a single nul-terminated string. Return non-zero if zStr
1379** is equal, according to strcmp(), to any of the strings in the array.
1380** Otherwise, return zero.
1381*/
1382static int str_in_array(const char *zStr, const char **azArray){
1383 int i;
1384 for(i=0; azArray[i]; i++){
1385 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1386 }
1387 return 0;
1388}
1389
1390/*
1391** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001392** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001393** spaces each opcode should be indented before it is output.
1394**
1395** The indenting rules are:
1396**
1397** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1398** all opcodes that occur between the p2 jump destination and the opcode
1399** itself by 2 spaces.
1400**
drh01752bc2013-11-14 23:59:33 +00001401** * For each "Goto", if the jump destination is earlier in the program
1402** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001403** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001404** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001405** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001406** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001407*/
drhdcd87a92014-08-18 13:45:42 +00001408static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001409 const char *zSql; /* The text of the SQL statement */
1410 const char *z; /* Used to check if this is an EXPLAIN */
1411 int *abYield = 0; /* True if op is an OP_Yield */
1412 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001413 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001414
drh8ad0de32014-03-20 18:45:27 +00001415 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1416 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001417 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1418 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001419 const char *azGoto[] = { "Goto", 0 };
1420
1421 /* Try to figure out if this is really an EXPLAIN statement. If this
1422 ** cannot be verified, return early. */
1423 zSql = sqlite3_sql(pSql);
1424 if( zSql==0 ) return;
1425 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1426 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1427
1428 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1429 int i;
danc4650bb2013-11-18 08:41:06 +00001430 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001431 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001432
1433 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1434 ** p2 is an instruction address, set variable p2op to the index of that
1435 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1436 ** the current instruction is part of a sub-program generated by an
1437 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001438 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001439 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001440
1441 /* Grow the p->aiIndent array as required */
1442 if( iOp>=nAlloc ){
1443 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001444 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1445 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001446 }
1447 abYield[iOp] = str_in_array(zOp, azYield);
1448 p->aiIndent[iOp] = 0;
1449 p->nIndent = iOp+1;
1450
1451 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001452 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001453 }
drhfe705102014-03-06 13:38:37 +00001454 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1455 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1456 ){
drhe73f0592014-01-21 22:25:45 +00001457 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001458 }
1459 }
1460
danc4650bb2013-11-18 08:41:06 +00001461 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001462 sqlite3_free(abYield);
1463 sqlite3_reset(pSql);
1464}
1465
1466/*
1467** Free the array allocated by explain_data_prepare().
1468*/
drhdcd87a92014-08-18 13:45:42 +00001469static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001470 sqlite3_free(p->aiIndent);
1471 p->aiIndent = 0;
1472 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001473 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001474}
1475
1476/*
shane626a6e42009-10-22 17:30:15 +00001477** Execute a statement or set of statements. Print
1478** any result rows/columns depending on the current mode
1479** set via the supplied callback.
1480**
1481** This is very similar to SQLite's built-in sqlite3_exec()
1482** function except it takes a slightly different callback
1483** and callback data argument.
1484*/
1485static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001486 sqlite3 *db, /* An open database */
1487 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001488 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001489 /* (not the same as sqlite3_exec) */
1490 ShellState *pArg, /* Pointer to ShellState */
1491 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001492){
dan4564ced2010-01-05 04:59:56 +00001493 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1494 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001495 int rc2;
dan4564ced2010-01-05 04:59:56 +00001496 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001497
1498 if( pzErrMsg ){
1499 *pzErrMsg = NULL;
1500 }
1501
shaneb9fc17d2009-10-22 21:23:35 +00001502 while( zSql[0] && (SQLITE_OK == rc) ){
1503 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1504 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001505 if( pzErrMsg ){
1506 *pzErrMsg = save_err_msg(db);
1507 }
1508 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001509 if( !pStmt ){
1510 /* this happens for a comment or white-space */
1511 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001512 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001513 continue;
1514 }
shane626a6e42009-10-22 17:30:15 +00001515
shaneh642d8b82010-07-28 16:05:34 +00001516 /* save off the prepared statment handle and reset row count */
1517 if( pArg ){
1518 pArg->pStmt = pStmt;
1519 pArg->cnt = 0;
1520 }
1521
shanehb7977c52010-01-18 18:17:10 +00001522 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001523 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001524 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001525 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001526 }
shanehb7977c52010-01-18 18:17:10 +00001527
drhefbf3b12014-02-28 20:47:24 +00001528 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1529 if( pArg && pArg->autoEQP ){
1530 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001531 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1532 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001533 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1534 if( rc==SQLITE_OK ){
1535 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1536 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1537 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1538 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1539 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1540 }
1541 }
1542 sqlite3_finalize(pExplain);
1543 sqlite3_free(zEQP);
1544 }
1545
dana98bf362013-11-13 18:35:01 +00001546 /* If the shell is currently in ".explain" mode, gather the extra
1547 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001548 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001549 explain_data_prepare(pArg, pStmt);
1550 }
1551
shaneb9fc17d2009-10-22 21:23:35 +00001552 /* perform the first step. this will tell us if we
1553 ** have a result set or not and how wide it is.
1554 */
1555 rc = sqlite3_step(pStmt);
1556 /* if we have a result set... */
1557 if( SQLITE_ROW == rc ){
1558 /* if we have a callback... */
1559 if( xCallback ){
1560 /* allocate space for col name ptr, value ptr, and type */
1561 int nCol = sqlite3_column_count(pStmt);
drhf3cdcdc2015-04-29 16:50:28 +00001562 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
shaneb9fc17d2009-10-22 21:23:35 +00001563 if( !pData ){
1564 rc = SQLITE_NOMEM;
1565 }else{
1566 char **azCols = (char **)pData; /* Names of result columns */
1567 char **azVals = &azCols[nCol]; /* Results */
1568 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001569 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001570 assert(sizeof(int) <= sizeof(char *));
1571 /* save off ptrs to column names */
1572 for(i=0; i<nCol; i++){
1573 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1574 }
shaneb9fc17d2009-10-22 21:23:35 +00001575 do{
1576 /* extract the data and data types */
1577 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001578 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001579 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001580 azVals[i] = "";
1581 }else{
1582 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1583 }
shaneb9fc17d2009-10-22 21:23:35 +00001584 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1585 rc = SQLITE_NOMEM;
1586 break; /* from for */
1587 }
1588 } /* end for */
1589
1590 /* if data and types extracted successfully... */
1591 if( SQLITE_ROW == rc ){
1592 /* call the supplied callback with the result row data */
1593 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1594 rc = SQLITE_ABORT;
1595 }else{
1596 rc = sqlite3_step(pStmt);
1597 }
1598 }
1599 } while( SQLITE_ROW == rc );
1600 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001601 }
1602 }else{
1603 do{
1604 rc = sqlite3_step(pStmt);
1605 } while( rc == SQLITE_ROW );
1606 }
1607 }
1608
dana98bf362013-11-13 18:35:01 +00001609 explain_data_delete(pArg);
1610
shaneh642d8b82010-07-28 16:05:34 +00001611 /* print usage stats if stats on */
1612 if( pArg && pArg->statsOn ){
1613 display_stats(db, pArg, 0);
1614 }
1615
dan8d1edb92014-11-05 09:07:28 +00001616 /* print loop-counters if required */
1617 if( pArg && pArg->scanstatsOn ){
1618 display_scanstats(db, pArg);
1619 }
1620
dan4564ced2010-01-05 04:59:56 +00001621 /* Finalize the statement just executed. If this fails, save a
1622 ** copy of the error message. Otherwise, set zSql to point to the
1623 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001624 rc2 = sqlite3_finalize(pStmt);
1625 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001626 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001627 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001628 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001629 }else if( pzErrMsg ){
1630 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001631 }
shaneh642d8b82010-07-28 16:05:34 +00001632
1633 /* clear saved stmt handle */
1634 if( pArg ){
1635 pArg->pStmt = NULL;
1636 }
shane626a6e42009-10-22 17:30:15 +00001637 }
shaneb9fc17d2009-10-22 21:23:35 +00001638 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001639
1640 return rc;
1641}
1642
drhdd3d4592004-08-30 01:54:05 +00001643
drh33048c02001-10-01 14:29:22 +00001644/*
drh4c653a02000-06-07 01:27:47 +00001645** This is a different callback routine used for dumping the database.
1646** Each row received by this callback consists of a table name,
1647** the table type ("index" or "table") and SQL to create the table.
1648** This routine should print text sufficient to recreate the table.
1649*/
1650static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001651 int rc;
1652 const char *zTable;
1653 const char *zType;
1654 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001655 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001656 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001657
drh902b9ee2008-12-05 17:17:07 +00001658 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001659 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001660 zTable = azArg[0];
1661 zType = azArg[1];
1662 zSql = azArg[2];
1663
drh00b950d2005-09-11 02:03:03 +00001664 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001665 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001666 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001667 fprintf(p->out, "ANALYZE sqlite_master;\n");
1668 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1669 return 0;
drh45e29d82006-11-20 16:21:10 +00001670 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1671 char *zIns;
1672 if( !p->writableSchema ){
1673 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1674 p->writableSchema = 1;
1675 }
1676 zIns = sqlite3_mprintf(
1677 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1678 "VALUES('table','%q','%q',0,'%q');",
1679 zTable, zTable, zSql);
1680 fprintf(p->out, "%s\n", zIns);
1681 sqlite3_free(zIns);
1682 return 0;
drh00b950d2005-09-11 02:03:03 +00001683 }else{
1684 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001685 }
danielk19772a02e332004-06-05 08:04:36 +00001686
1687 if( strcmp(zType, "table")==0 ){
1688 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001689 char *zSelect = 0;
1690 char *zTableInfo = 0;
1691 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001692 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001693
1694 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1695 zTableInfo = appendText(zTableInfo, zTable, '"');
1696 zTableInfo = appendText(zTableInfo, ");", 0);
1697
drhc7181902014-02-27 15:04:13 +00001698 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001699 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001700 if( rc!=SQLITE_OK || !pTableInfo ){
1701 return 1;
1702 }
1703
1704 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001705 /* Always quote the table name, even if it appears to be pure ascii,
1706 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1707 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001708 if( zTmp ){
1709 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001710 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001711 }
1712 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1713 rc = sqlite3_step(pTableInfo);
1714 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001715 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001716 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001717 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001718 rc = sqlite3_step(pTableInfo);
1719 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001720 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001721 }else{
1722 zSelect = appendText(zSelect, ") ", 0);
1723 }
drh157e29a2009-05-21 15:15:00 +00001724 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001725 }
1726 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001727 if( rc!=SQLITE_OK || nRow==0 ){
1728 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001729 return 1;
1730 }
1731 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1732 zSelect = appendText(zSelect, zTable, '"');
1733
drh2f464a02011-10-13 00:41:49 +00001734 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001735 if( rc==SQLITE_CORRUPT ){
1736 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001737 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001738 }
drh85e72432012-04-11 11:38:53 +00001739 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001740 }
drh4c653a02000-06-07 01:27:47 +00001741 return 0;
1742}
1743
1744/*
drh45e29d82006-11-20 16:21:10 +00001745** Run zQuery. Use dump_callback() as the callback routine so that
1746** the contents of the query are output as SQL statements.
1747**
drhdd3d4592004-08-30 01:54:05 +00001748** If we get a SQLITE_CORRUPT error, rerun the query after appending
1749** "ORDER BY rowid DESC" to the end.
1750*/
1751static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001752 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001753 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001754){
1755 int rc;
drh2f464a02011-10-13 00:41:49 +00001756 char *zErr = 0;
1757 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001758 if( rc==SQLITE_CORRUPT ){
1759 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001760 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001761 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1762 if( zErr ){
1763 fprintf(p->out, "/****** %s ******/\n", zErr);
1764 sqlite3_free(zErr);
1765 zErr = 0;
1766 }
drhdd3d4592004-08-30 01:54:05 +00001767 zQ2 = malloc( len+100 );
1768 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001769 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001770 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1771 if( rc ){
1772 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1773 }else{
1774 rc = SQLITE_CORRUPT;
1775 }
1776 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001777 free(zQ2);
1778 }
1779 return rc;
1780}
1781
1782/*
drh75897232000-05-29 14:26:00 +00001783** Text of a help message
1784*/
persicom1d0b8722002-04-18 02:53:04 +00001785static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001786 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001787 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00001788 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00001789 ".changes on|off Show number of rows changed by SQL\n"
drh4bbcf102014-02-06 02:46:08 +00001790 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001791 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001792 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001793 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001794 " If TABLE specified, only dump tables matching\n"
1795 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001796 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001797 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001798 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001799 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001800 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001801 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001802 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001803 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001804 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001805 ".indexes ?TABLE? Show names of all indexes\n"
1806 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001807 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001808#ifdef SQLITE_ENABLE_IOTRACE
1809 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1810#endif
drh1a513372015-05-02 17:40:23 +00001811 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00001812#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001813 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001814#endif
drh127f9d72010-02-23 01:47:00 +00001815 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001816 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001817 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001818 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001819 " column Left-aligned columns. (See .width)\n"
1820 " html HTML <table> code\n"
1821 " insert SQL insert statements for TABLE\n"
1822 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001823 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001824 " tabs Tab-separated values\n"
1825 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001826 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001827 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001828 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001829 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001830 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001831 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001832 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001833 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001834 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001835 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001836 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001837 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001838 " If TABLE specified, only show tables matching\n"
1839 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001840 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1841 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001842 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001843 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001844 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001845 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001846 ".tables ?TABLE? List names of tables\n"
1847 " If TABLE specified, only list tables matching\n"
1848 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001849 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001850 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001851 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00001852 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhde60fc22011-12-14 17:53:36 +00001853 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001854 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001855 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001856;
1857
drhdaffd0e2001-04-11 14:28:42 +00001858/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001859static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001860/*
1861** Implementation of the "readfile(X)" SQL function. The entire content
1862** of the file named X is read and returned as a BLOB. NULL is returned
1863** if the file does not exist or is unreadable.
1864*/
1865static void readfileFunc(
1866 sqlite3_context *context,
1867 int argc,
1868 sqlite3_value **argv
1869){
1870 const char *zName;
1871 FILE *in;
1872 long nIn;
1873 void *pBuf;
1874
drhf5ed7ad2015-06-15 14:43:25 +00001875 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00001876 zName = (const char*)sqlite3_value_text(argv[0]);
1877 if( zName==0 ) return;
1878 in = fopen(zName, "rb");
1879 if( in==0 ) return;
1880 fseek(in, 0, SEEK_END);
1881 nIn = ftell(in);
1882 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00001883 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00001884 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1885 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1886 }else{
1887 sqlite3_free(pBuf);
1888 }
1889 fclose(in);
1890}
1891
1892/*
1893** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1894** is written into file X. The number of bytes written is returned. Or
1895** NULL is returned if something goes wrong, such as being unable to open
1896** file X for writing.
1897*/
1898static void writefileFunc(
1899 sqlite3_context *context,
1900 int argc,
1901 sqlite3_value **argv
1902){
1903 FILE *out;
1904 const char *z;
drhba5b0932014-07-24 12:39:59 +00001905 sqlite3_int64 rc;
1906 const char *zFile;
1907
drhf5ed7ad2015-06-15 14:43:25 +00001908 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00001909 zFile = (const char*)sqlite3_value_text(argv[0]);
1910 if( zFile==0 ) return;
1911 out = fopen(zFile, "wb");
1912 if( out==0 ) return;
1913 z = (const char*)sqlite3_value_blob(argv[1]);
1914 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001915 rc = 0;
1916 }else{
drh490fe862014-08-11 14:21:32 +00001917 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001918 }
1919 fclose(out);
1920 sqlite3_result_int64(context, rc);
1921}
drhdaffd0e2001-04-11 14:28:42 +00001922
drh75897232000-05-29 14:26:00 +00001923/*
drh44c2eb12003-04-30 11:38:26 +00001924** Make sure the database is open. If it is not, then open it. If
1925** the database fails to open, print an error message and exit.
1926*/
drhdcd87a92014-08-18 13:45:42 +00001927static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001928 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001929 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001930 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00001931 globalDb = p->db;
1932 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
1933 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00001934 shellstaticFunc, 0, 0);
1935 }
mistachkin8e189222015-04-19 21:43:16 +00001936 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
shane86f5bdb2009-10-24 02:00:07 +00001937 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00001938 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00001939 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001940 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001941 }
drhc2e87a32006-06-27 15:16:14 +00001942#ifndef SQLITE_OMIT_LOAD_EXTENSION
1943 sqlite3_enable_load_extension(p->db, 1);
1944#endif
mistachkin8e189222015-04-19 21:43:16 +00001945 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00001946 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00001947 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00001948 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001949 }
1950}
1951
1952/*
drhfeac5f82004-08-01 00:10:45 +00001953** Do C-language style dequoting.
1954**
mistachkinf21979d2015-01-18 05:35:01 +00001955** \a -> alarm
1956** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00001957** \t -> tab
1958** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00001959** \v -> vertical tab
1960** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00001961** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00001962** \s -> space
drh4c56b992013-06-27 13:26:55 +00001963** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00001964** \' -> '
drhfeac5f82004-08-01 00:10:45 +00001965** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00001966** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00001967*/
1968static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001969 int i, j;
1970 char c;
drhc2ce0be2014-05-29 12:36:14 +00001971 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001972 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00001973 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00001974 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00001975 if( c=='a' ){
1976 c = '\a';
1977 }else if( c=='b' ){
1978 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00001979 }else if( c=='t' ){
1980 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00001981 }else if( c=='n' ){
1982 c = '\n';
1983 }else if( c=='v' ){
1984 c = '\v';
1985 }else if( c=='f' ){
1986 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00001987 }else if( c=='r' ){
1988 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00001989 }else if( c=='"' ){
1990 c = '"';
1991 }else if( c=='\'' ){
1992 c = '\'';
drh4c56b992013-06-27 13:26:55 +00001993 }else if( c=='\\' ){
1994 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001995 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001996 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001997 if( z[i+1]>='0' && z[i+1]<='7' ){
1998 i++;
1999 c = (c<<3) + z[i] - '0';
2000 if( z[i+1]>='0' && z[i+1]<='7' ){
2001 i++;
2002 c = (c<<3) + z[i] - '0';
2003 }
2004 }
2005 }
2006 }
2007 z[j] = c;
2008 }
drhc2ce0be2014-05-29 12:36:14 +00002009 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002010}
2011
2012/*
drh348d19c2013-06-03 12:47:43 +00002013** Return the value of a hexadecimal digit. Return -1 if the input
2014** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002015*/
drh348d19c2013-06-03 12:47:43 +00002016static int hexDigitValue(char c){
2017 if( c>='0' && c<='9' ) return c - '0';
2018 if( c>='a' && c<='f' ) return c - 'a' + 10;
2019 if( c>='A' && c<='F' ) return c - 'A' + 10;
2020 return -1;
drhc28490c2006-10-26 14:25:58 +00002021}
2022
2023/*
drh7d9f3942013-04-03 01:26:54 +00002024** Interpret zArg as an integer value, possibly with suffixes.
2025*/
2026static sqlite3_int64 integerValue(const char *zArg){
2027 sqlite3_int64 v = 0;
2028 static const struct { char *zSuffix; int iMult; } aMult[] = {
2029 { "KiB", 1024 },
2030 { "MiB", 1024*1024 },
2031 { "GiB", 1024*1024*1024 },
2032 { "KB", 1000 },
2033 { "MB", 1000000 },
2034 { "GB", 1000000000 },
2035 { "K", 1000 },
2036 { "M", 1000000 },
2037 { "G", 1000000000 },
2038 };
2039 int i;
2040 int isNeg = 0;
2041 if( zArg[0]=='-' ){
2042 isNeg = 1;
2043 zArg++;
2044 }else if( zArg[0]=='+' ){
2045 zArg++;
2046 }
drh348d19c2013-06-03 12:47:43 +00002047 if( zArg[0]=='0' && zArg[1]=='x' ){
2048 int x;
2049 zArg += 2;
2050 while( (x = hexDigitValue(zArg[0]))>=0 ){
2051 v = (v<<4) + x;
2052 zArg++;
2053 }
2054 }else{
2055 while( IsDigit(zArg[0]) ){
2056 v = v*10 + zArg[0] - '0';
2057 zArg++;
2058 }
drh7d9f3942013-04-03 01:26:54 +00002059 }
drhc2bed0a2013-05-24 11:57:50 +00002060 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002061 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2062 v *= aMult[i].iMult;
2063 break;
2064 }
2065 }
2066 return isNeg? -v : v;
2067}
2068
2069/*
drh348d19c2013-06-03 12:47:43 +00002070** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2071** for TRUE and FALSE. Return the integer value if appropriate.
2072*/
2073static int booleanValue(char *zArg){
2074 int i;
2075 if( zArg[0]=='0' && zArg[1]=='x' ){
2076 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2077 }else{
2078 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2079 }
2080 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2081 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2082 return 1;
2083 }
2084 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2085 return 0;
2086 }
2087 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2088 zArg);
2089 return 0;
2090}
2091
2092/*
drh42f64e52012-04-04 16:56:23 +00002093** Close an output file, assuming it is not stderr or stdout
2094*/
2095static void output_file_close(FILE *f){
2096 if( f && f!=stdout && f!=stderr ) fclose(f);
2097}
2098
2099/*
2100** Try to open an output file. The names "stdout" and "stderr" are
2101** recognized and do the right thing. NULL is returned if the output
2102** filename is "off".
2103*/
2104static FILE *output_file_open(const char *zFile){
2105 FILE *f;
2106 if( strcmp(zFile,"stdout")==0 ){
2107 f = stdout;
2108 }else if( strcmp(zFile, "stderr")==0 ){
2109 f = stderr;
2110 }else if( strcmp(zFile, "off")==0 ){
2111 f = 0;
2112 }else{
2113 f = fopen(zFile, "wb");
2114 if( f==0 ){
2115 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2116 }
2117 }
2118 return f;
2119}
2120
2121/*
2122** A routine for handling output from sqlite3_trace().
2123*/
2124static void sql_trace_callback(void *pArg, const char *z){
2125 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002126 if( f ){
2127 int i = (int)strlen(z);
2128 while( i>0 && z[i-1]==';' ){ i--; }
2129 fprintf(f, "%.*s;\n", i, z);
2130 }
drh42f64e52012-04-04 16:56:23 +00002131}
2132
2133/*
drhd8621b92012-04-17 09:09:33 +00002134** A no-op routine that runs with the ".breakpoint" doc-command. This is
2135** a useful spot to set a debugger breakpoint.
2136*/
2137static void test_breakpoint(void){
2138 static int nCall = 0;
2139 nCall++;
2140}
2141
2142/*
mistachkin636bf9f2014-07-19 20:15:16 +00002143** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002144*/
mistachkin636bf9f2014-07-19 20:15:16 +00002145typedef struct ImportCtx ImportCtx;
2146struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002147 const char *zFile; /* Name of the input file */
2148 FILE *in; /* Read the CSV text from this input stream */
2149 char *z; /* Accumulated text for a field */
2150 int n; /* Number of bytes in z */
2151 int nAlloc; /* Space allocated for z[] */
2152 int nLine; /* Current line number */
2153 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002154 int cColSep; /* The column separator character. (Usually ",") */
2155 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002156};
2157
2158/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002159static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002160 if( p->n+1>=p->nAlloc ){
2161 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002162 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002163 if( p->z==0 ){
2164 fprintf(stderr, "out of memory\n");
2165 exit(1);
2166 }
2167 }
2168 p->z[p->n++] = (char)c;
2169}
2170
2171/* Read a single field of CSV text. Compatible with rfc4180 and extended
2172** with the option of having a separator other than ",".
2173**
2174** + Input comes from p->in.
2175** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002176** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002177** + Use p->cSep as the column separator. The default is ",".
2178** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002179** + Keep track of the line number in p->nLine.
2180** + Store the character that terminates the field in p->cTerm. Store
2181** EOF on end-of-file.
2182** + Report syntax errors on stderr
2183*/
mistachkin44723ce2015-03-21 02:22:37 +00002184static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002185 int c;
2186 int cSep = p->cColSep;
2187 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002188 p->n = 0;
2189 c = fgetc(p->in);
2190 if( c==EOF || seenInterrupt ){
2191 p->cTerm = EOF;
2192 return 0;
2193 }
2194 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002195 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002196 int startLine = p->nLine;
2197 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002198 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002199 while( 1 ){
2200 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002201 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002202 if( c==cQuote ){
2203 if( pc==cQuote ){
2204 pc = 0;
2205 continue;
2206 }
2207 }
2208 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002209 || (c==rSep && pc==cQuote)
2210 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002211 || (c==EOF && pc==cQuote)
2212 ){
2213 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002214 p->cTerm = c;
2215 break;
2216 }
2217 if( pc==cQuote && c!='\r' ){
2218 fprintf(stderr, "%s:%d: unescaped %c character\n",
2219 p->zFile, p->nLine, cQuote);
2220 }
2221 if( c==EOF ){
2222 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2223 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002224 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002225 break;
2226 }
mistachkin636bf9f2014-07-19 20:15:16 +00002227 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002228 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002229 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002230 }
drhdb95f682013-06-26 22:46:00 +00002231 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002232 while( c!=EOF && c!=cSep && c!=rSep ){
2233 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002234 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002235 }
mistachkin636bf9f2014-07-19 20:15:16 +00002236 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002237 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002238 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002239 }
drhdb95f682013-06-26 22:46:00 +00002240 p->cTerm = c;
2241 }
drh8dd675e2013-07-12 21:09:24 +00002242 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002243 return p->z;
2244}
2245
mistachkin636bf9f2014-07-19 20:15:16 +00002246/* Read a single field of ASCII delimited text.
2247**
2248** + Input comes from p->in.
2249** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002250** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002251** + Use p->cSep as the column separator. The default is "\x1F".
2252** + Use p->rSep as the row separator. The default is "\x1E".
2253** + Keep track of the row number in p->nLine.
2254** + Store the character that terminates the field in p->cTerm. Store
2255** EOF on end-of-file.
2256** + Report syntax errors on stderr
2257*/
mistachkin44723ce2015-03-21 02:22:37 +00002258static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002259 int c;
2260 int cSep = p->cColSep;
2261 int rSep = p->cRowSep;
2262 p->n = 0;
2263 c = fgetc(p->in);
2264 if( c==EOF || seenInterrupt ){
2265 p->cTerm = EOF;
2266 return 0;
2267 }
2268 while( c!=EOF && c!=cSep && c!=rSep ){
2269 import_append_char(p, c);
2270 c = fgetc(p->in);
2271 }
2272 if( c==rSep ){
2273 p->nLine++;
2274 }
2275 p->cTerm = c;
2276 if( p->z ) p->z[p->n] = 0;
2277 return p->z;
2278}
2279
drhdb95f682013-06-26 22:46:00 +00002280/*
drh4bbcf102014-02-06 02:46:08 +00002281** Try to transfer data for table zTable. If an error is seen while
2282** moving forward, try to go backwards. The backwards movement won't
2283** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002284*/
mistachkine31ae902014-02-06 01:15:29 +00002285static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002286 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002287 sqlite3 *newDb,
2288 const char *zTable
2289){
2290 sqlite3_stmt *pQuery = 0;
2291 sqlite3_stmt *pInsert = 0;
2292 char *zQuery = 0;
2293 char *zInsert = 0;
2294 int rc;
2295 int i, j, n;
2296 int nTable = (int)strlen(zTable);
2297 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002298 int cnt = 0;
2299 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002300
2301 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2302 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2303 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002304 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002305 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2306 zQuery);
2307 goto end_data_xfer;
2308 }
2309 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002310 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002311 if( zInsert==0 ){
2312 fprintf(stderr, "out of memory\n");
2313 goto end_data_xfer;
2314 }
2315 sqlite3_snprintf(200+nTable,zInsert,
2316 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2317 i = (int)strlen(zInsert);
2318 for(j=1; j<n; j++){
2319 memcpy(zInsert+i, ",?", 2);
2320 i += 2;
2321 }
2322 memcpy(zInsert+i, ");", 3);
2323 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2324 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002325 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002326 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2327 zQuery);
2328 goto end_data_xfer;
2329 }
2330 for(k=0; k<2; k++){
2331 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2332 for(i=0; i<n; i++){
2333 switch( sqlite3_column_type(pQuery, i) ){
2334 case SQLITE_NULL: {
2335 sqlite3_bind_null(pInsert, i+1);
2336 break;
2337 }
2338 case SQLITE_INTEGER: {
2339 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2340 break;
2341 }
2342 case SQLITE_FLOAT: {
2343 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2344 break;
2345 }
2346 case SQLITE_TEXT: {
2347 sqlite3_bind_text(pInsert, i+1,
2348 (const char*)sqlite3_column_text(pQuery,i),
2349 -1, SQLITE_STATIC);
2350 break;
2351 }
2352 case SQLITE_BLOB: {
2353 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2354 sqlite3_column_bytes(pQuery,i),
2355 SQLITE_STATIC);
2356 break;
2357 }
2358 }
2359 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002360 rc = sqlite3_step(pInsert);
2361 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2362 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2363 sqlite3_errmsg(newDb));
2364 }
drh3350ce92014-02-06 00:49:12 +00002365 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002366 cnt++;
2367 if( (cnt%spinRate)==0 ){
2368 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2369 fflush(stdout);
2370 }
drh3350ce92014-02-06 00:49:12 +00002371 } /* End while */
2372 if( rc==SQLITE_DONE ) break;
2373 sqlite3_finalize(pQuery);
2374 sqlite3_free(zQuery);
2375 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2376 zTable);
2377 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2378 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002379 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2380 break;
drh3350ce92014-02-06 00:49:12 +00002381 }
2382 } /* End for(k=0...) */
2383
2384end_data_xfer:
2385 sqlite3_finalize(pQuery);
2386 sqlite3_finalize(pInsert);
2387 sqlite3_free(zQuery);
2388 sqlite3_free(zInsert);
2389}
2390
2391
2392/*
2393** Try to transfer all rows of the schema that match zWhere. For
2394** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002395** If an error is encountered while moving forward through the
2396** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002397*/
mistachkine31ae902014-02-06 01:15:29 +00002398static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002399 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002400 sqlite3 *newDb,
2401 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002402 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002403){
2404 sqlite3_stmt *pQuery = 0;
2405 char *zQuery = 0;
2406 int rc;
2407 const unsigned char *zName;
2408 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002409 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002410
2411 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2412 " WHERE %s", zWhere);
2413 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2414 if( rc ){
2415 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2416 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2417 zQuery);
2418 goto end_schema_xfer;
2419 }
2420 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2421 zName = sqlite3_column_text(pQuery, 0);
2422 zSql = sqlite3_column_text(pQuery, 1);
2423 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002424 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2425 if( zErrMsg ){
2426 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2427 sqlite3_free(zErrMsg);
2428 zErrMsg = 0;
2429 }
drh3350ce92014-02-06 00:49:12 +00002430 if( xForEach ){
2431 xForEach(p, newDb, (const char*)zName);
2432 }
2433 printf("done\n");
2434 }
2435 if( rc!=SQLITE_DONE ){
2436 sqlite3_finalize(pQuery);
2437 sqlite3_free(zQuery);
2438 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2439 " WHERE %s ORDER BY rowid DESC", zWhere);
2440 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2441 if( rc ){
2442 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2443 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2444 zQuery);
2445 goto end_schema_xfer;
2446 }
2447 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2448 zName = sqlite3_column_text(pQuery, 0);
2449 zSql = sqlite3_column_text(pQuery, 1);
2450 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002451 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2452 if( zErrMsg ){
2453 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2454 sqlite3_free(zErrMsg);
2455 zErrMsg = 0;
2456 }
drh3350ce92014-02-06 00:49:12 +00002457 if( xForEach ){
2458 xForEach(p, newDb, (const char*)zName);
2459 }
2460 printf("done\n");
2461 }
2462 }
2463end_schema_xfer:
2464 sqlite3_finalize(pQuery);
2465 sqlite3_free(zQuery);
2466}
2467
2468/*
2469** Open a new database file named "zNewDb". Try to recover as much information
2470** as possible out of the main database (which might be corrupt) and write it
2471** into zNewDb.
2472*/
drhdcd87a92014-08-18 13:45:42 +00002473static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002474 int rc;
2475 sqlite3 *newDb = 0;
2476 if( access(zNewDb,0)==0 ){
2477 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2478 return;
2479 }
2480 rc = sqlite3_open(zNewDb, &newDb);
2481 if( rc ){
2482 fprintf(stderr, "Cannot create output database: %s\n",
2483 sqlite3_errmsg(newDb));
2484 }else{
drh54d0d2d2014-04-03 00:32:13 +00002485 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002486 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002487 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2488 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002489 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002490 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002491 }
2492 sqlite3_close(newDb);
2493}
2494
2495/*
drhc2ce0be2014-05-29 12:36:14 +00002496** Change the output file back to stdout
2497*/
drhdcd87a92014-08-18 13:45:42 +00002498static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002499 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002500#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002501 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002502#endif
drhc2ce0be2014-05-29 12:36:14 +00002503 }else{
2504 output_file_close(p->out);
2505 }
2506 p->outfile[0] = 0;
2507 p->out = stdout;
2508}
2509
2510/*
drhf7502f02015-02-06 14:19:44 +00002511** Run an SQL command and return the single integer result.
2512*/
2513static int db_int(ShellState *p, const char *zSql){
2514 sqlite3_stmt *pStmt;
2515 int res = 0;
2516 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2517 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2518 res = sqlite3_column_int(pStmt,0);
2519 }
2520 sqlite3_finalize(pStmt);
2521 return res;
2522}
2523
2524/*
2525** Convert a 2-byte or 4-byte big-endian integer into a native integer
2526*/
2527unsigned int get2byteInt(unsigned char *a){
2528 return (a[0]<<8) + a[1];
2529}
2530unsigned int get4byteInt(unsigned char *a){
2531 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2532}
2533
2534/*
2535** Implementation of the ".info" command.
2536**
2537** Return 1 on error, 2 to exit, and 0 otherwise.
2538*/
drh0e55db12015-02-06 14:51:13 +00002539static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002540 static const struct { const char *zName; int ofst; } aField[] = {
2541 { "file change counter:", 24 },
2542 { "database page count:", 28 },
2543 { "freelist page count:", 36 },
2544 { "schema cookie:", 40 },
2545 { "schema format:", 44 },
2546 { "default cache size:", 48 },
2547 { "autovacuum top root:", 52 },
2548 { "incremental vacuum:", 64 },
2549 { "text encoding:", 56 },
2550 { "user version:", 60 },
2551 { "application id:", 68 },
2552 { "software version:", 96 },
2553 };
drh0e55db12015-02-06 14:51:13 +00002554 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2555 { "number of tables:",
2556 "SELECT count(*) FROM %s WHERE type='table'" },
2557 { "number of indexes:",
2558 "SELECT count(*) FROM %s WHERE type='index'" },
2559 { "number of triggers:",
2560 "SELECT count(*) FROM %s WHERE type='trigger'" },
2561 { "number of views:",
2562 "SELECT count(*) FROM %s WHERE type='view'" },
2563 { "schema size:",
2564 "SELECT total(length(sql)) FROM %s" },
2565 };
mistachkinbfe8bd52015-11-17 19:17:14 +00002566 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00002567 int i;
2568 char *zSchemaTab;
2569 char *zDb = nArg>=2 ? azArg[1] : "main";
2570 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002571 open_db(p, 0);
2572 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002573 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002574 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2575 return 1;
2576 }
2577 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2578 if( i!=SQLITE_OK ){
2579 fprintf(stderr, "unable to read database header\n");
2580 return 1;
2581 }
2582 i = get2byteInt(aHdr+16);
2583 if( i==1 ) i = 65536;
2584 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2585 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2586 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2587 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00002588 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00002589 int ofst = aField[i].ofst;
2590 unsigned int val = get4byteInt(aHdr + ofst);
2591 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2592 switch( ofst ){
2593 case 56: {
2594 if( val==1 ) fprintf(p->out, " (utf8)");
2595 if( val==2 ) fprintf(p->out, " (utf16le)");
2596 if( val==3 ) fprintf(p->out, " (utf16be)");
2597 }
2598 }
2599 fprintf(p->out, "\n");
2600 }
drh0e55db12015-02-06 14:51:13 +00002601 if( zDb==0 ){
2602 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2603 }else if( strcmp(zDb,"temp")==0 ){
2604 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2605 }else{
2606 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2607 }
drhf5ed7ad2015-06-15 14:43:25 +00002608 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00002609 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2610 int val = db_int(p, zSql);
2611 sqlite3_free(zSql);
2612 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2613 }
2614 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002615 return 0;
2616}
2617
dand95bb392015-09-30 11:19:05 +00002618/*
2619** Print the current sqlite3_errmsg() value to stderr and return 1.
2620*/
2621static int shellDatabaseError(sqlite3 *db){
2622 const char *zErr = sqlite3_errmsg(db);
2623 fprintf(stderr, "Error: %s\n", zErr);
2624 return 1;
2625}
2626
2627/*
2628** Print an out-of-memory message to stderr and return 1.
2629*/
2630static int shellNomemError(void){
2631 fprintf(stderr, "Error: out of memory\n");
2632 return 1;
2633}
drhf7502f02015-02-06 14:19:44 +00002634
2635/*
drh75897232000-05-29 14:26:00 +00002636** If an input line begins with "." then invoke this routine to
2637** process that line.
drh67505e72002-04-19 12:34:06 +00002638**
drh47ad6842006-11-08 12:25:42 +00002639** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002640*/
drhdcd87a92014-08-18 13:45:42 +00002641static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00002642 int h = 1;
drh75897232000-05-29 14:26:00 +00002643 int nArg = 0;
2644 int n, c;
drh67505e72002-04-19 12:34:06 +00002645 int rc = 0;
drh75897232000-05-29 14:26:00 +00002646 char *azArg[50];
2647
2648 /* Parse the input line into tokens.
2649 */
mistachkin8e189222015-04-19 21:43:16 +00002650 while( zLine[h] && nArg<ArraySize(azArg) ){
2651 while( IsSpace(zLine[h]) ){ h++; }
2652 if( zLine[h]==0 ) break;
2653 if( zLine[h]=='\'' || zLine[h]=='"' ){
2654 int delim = zLine[h++];
2655 azArg[nArg++] = &zLine[h];
2656 while( zLine[h] && zLine[h]!=delim ){
2657 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
2658 h++;
drh4c56b992013-06-27 13:26:55 +00002659 }
mistachkin8e189222015-04-19 21:43:16 +00002660 if( zLine[h]==delim ){
2661 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00002662 }
drhfeac5f82004-08-01 00:10:45 +00002663 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002664 }else{
mistachkin8e189222015-04-19 21:43:16 +00002665 azArg[nArg++] = &zLine[h];
2666 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
2667 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002668 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002669 }
2670 }
2671
2672 /* Process the input line.
2673 */
shane9bd1b442009-10-23 01:27:39 +00002674 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002675 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002676 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002677 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2678 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2679 ){
drhbc46f022013-01-23 18:53:23 +00002680 const char *zDestFile = 0;
2681 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002682 sqlite3 *pDest;
2683 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002684 int j;
2685 for(j=1; j<nArg; j++){
2686 const char *z = azArg[j];
2687 if( z[0]=='-' ){
2688 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002689 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002690 {
2691 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2692 return 1;
2693 }
2694 }else if( zDestFile==0 ){
2695 zDestFile = azArg[j];
2696 }else if( zDb==0 ){
2697 zDb = zDestFile;
2698 zDestFile = azArg[j];
2699 }else{
2700 fprintf(stderr, "too many arguments to .backup\n");
2701 return 1;
2702 }
drh9ff849f2009-02-04 20:55:57 +00002703 }
drhbc46f022013-01-23 18:53:23 +00002704 if( zDestFile==0 ){
2705 fprintf(stderr, "missing FILENAME argument on .backup\n");
2706 return 1;
2707 }
2708 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002709 rc = sqlite3_open(zDestFile, &pDest);
2710 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002711 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002712 sqlite3_close(pDest);
2713 return 1;
2714 }
drh05782482013-10-24 15:20:20 +00002715 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002716 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2717 if( pBackup==0 ){
2718 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2719 sqlite3_close(pDest);
2720 return 1;
2721 }
2722 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2723 sqlite3_backup_finish(pBackup);
2724 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002725 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002726 }else{
2727 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002728 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002729 }
2730 sqlite3_close(pDest);
2731 }else
2732
drhc2ce0be2014-05-29 12:36:14 +00002733 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2734 if( nArg==2 ){
2735 bail_on_error = booleanValue(azArg[1]);
2736 }else{
2737 fprintf(stderr, "Usage: .bail on|off\n");
2738 rc = 1;
2739 }
drhc49f44e2006-10-26 18:15:42 +00002740 }else
2741
mistachkinf21979d2015-01-18 05:35:01 +00002742 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
2743 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00002744 if( booleanValue(azArg[1]) ){
2745 setBinaryMode(p->out);
2746 }else{
2747 setTextMode(p->out);
2748 }
mistachkinf21979d2015-01-18 05:35:01 +00002749 }else{
2750 fprintf(stderr, "Usage: .binary on|off\n");
2751 rc = 1;
2752 }
2753 }else
2754
drhd8621b92012-04-17 09:09:33 +00002755 /* The undocumented ".breakpoint" command causes a call to the no-op
2756 ** routine named test_breakpoint().
2757 */
2758 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2759 test_breakpoint();
2760 }else
2761
drhdf12f1c2015-12-07 21:46:19 +00002762 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
2763 if( nArg==2 ){
2764 p->countChanges = booleanValue(azArg[1]);
2765 }else{
2766 fprintf(stderr, "Usage: .changes on|off\n");
2767 rc = 1;
2768 }
2769 }else
2770
drhc2ce0be2014-05-29 12:36:14 +00002771 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2772 if( nArg==2 ){
2773 tryToClone(p, azArg[1]);
2774 }else{
2775 fprintf(stderr, "Usage: .clone FILENAME\n");
2776 rc = 1;
2777 }
mistachkine31ae902014-02-06 01:15:29 +00002778 }else
2779
drhc2ce0be2014-05-29 12:36:14 +00002780 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002781 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002782 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002783 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002784 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002785 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002786 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002787 data.colWidth[0] = 3;
2788 data.colWidth[1] = 15;
2789 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002790 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002791 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002792 if( zErrMsg ){
2793 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002794 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002795 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002796 }
2797 }else
2798
drh0e55db12015-02-06 14:51:13 +00002799 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2800 rc = shell_dbinfo_command(p, nArg, azArg);
2801 }else
2802
drhc2ce0be2014-05-29 12:36:14 +00002803 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002804 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002805 /* When playing back a "dump", the content might appear in an order
2806 ** which causes immediate foreign key constraints to be violated.
2807 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002808 if( nArg!=1 && nArg!=2 ){
2809 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2810 rc = 1;
2811 goto meta_command_exit;
2812 }
drhf1dfc4f2009-09-23 15:51:35 +00002813 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002814 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002815 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002816 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002817 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002818 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002819 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002820 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002821 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002822 );
2823 run_schema_dump_query(p,
2824 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002825 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002826 );
drh2f464a02011-10-13 00:41:49 +00002827 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002828 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002829 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002830 );
drh4c653a02000-06-07 01:27:47 +00002831 }else{
2832 int i;
drhdd3d4592004-08-30 01:54:05 +00002833 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002834 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002835 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002836 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002837 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002838 " AND sql NOT NULL");
2839 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002840 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002841 "WHERE sql NOT NULL"
2842 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002843 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002844 );
danielk1977bc6ada42004-06-30 08:20:16 +00002845 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002846 }
2847 }
drh45e29d82006-11-20 16:21:10 +00002848 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002849 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002850 p->writableSchema = 0;
2851 }
drh56197952011-10-13 16:30:13 +00002852 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2853 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002854 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002855 }else
drh75897232000-05-29 14:26:00 +00002856
drhc2ce0be2014-05-29 12:36:14 +00002857 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2858 if( nArg==2 ){
2859 p->echoOn = booleanValue(azArg[1]);
2860 }else{
2861 fprintf(stderr, "Usage: .echo on|off\n");
2862 rc = 1;
2863 }
drhdaffd0e2001-04-11 14:28:42 +00002864 }else
2865
drhc2ce0be2014-05-29 12:36:14 +00002866 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2867 if( nArg==2 ){
2868 p->autoEQP = booleanValue(azArg[1]);
2869 }else{
2870 fprintf(stderr, "Usage: .eqp on|off\n");
2871 rc = 1;
2872 }
drhefbf3b12014-02-28 20:47:24 +00002873 }else
2874
drhd3ac7d92013-01-25 18:33:43 +00002875 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002876 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002877 rc = 2;
drh75897232000-05-29 14:26:00 +00002878 }else
2879
drhc2ce0be2014-05-29 12:36:14 +00002880 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002881 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002882 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002883 if(!p->normalMode.valid) {
2884 p->normalMode.valid = 1;
2885 p->normalMode.mode = p->mode;
2886 p->normalMode.showHeader = p->showHeader;
2887 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002888 }
2889 /* We could put this code under the !p->explainValid
2890 ** condition so that it does not execute if we are already in
2891 ** explain mode. However, always executing it allows us an easy
2892 ** was to reset to explain mode in case the user previously
2893 ** did an .explain followed by a .width, .mode or .header
2894 ** command.
2895 */
danielk19770d78bae2008-01-03 07:09:48 +00002896 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002897 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002898 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002899 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002900 p->colWidth[1] = 13; /* opcode */
2901 p->colWidth[2] = 4; /* P1 */
2902 p->colWidth[3] = 4; /* P2 */
2903 p->colWidth[4] = 4; /* P3 */
2904 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002905 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002906 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002907 }else if (p->normalMode.valid) {
2908 p->normalMode.valid = 0;
2909 p->mode = p->normalMode.mode;
2910 p->showHeader = p->normalMode.showHeader;
2911 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002912 }
drh75897232000-05-29 14:26:00 +00002913 }else
2914
drhc1971542014-06-23 23:28:13 +00002915 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002916 ShellState data;
drhc1971542014-06-23 23:28:13 +00002917 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002918 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002919 if( nArg!=1 ){
2920 fprintf(stderr, "Usage: .fullschema\n");
2921 rc = 1;
2922 goto meta_command_exit;
2923 }
2924 open_db(p, 0);
2925 memcpy(&data, p, sizeof(data));
2926 data.showHeader = 0;
2927 data.mode = MODE_Semi;
2928 rc = sqlite3_exec(p->db,
2929 "SELECT sql FROM"
2930 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2931 " FROM sqlite_master UNION ALL"
2932 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002933 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002934 "ORDER BY rowid",
2935 callback, &data, &zErrMsg
2936 );
drh56f674c2014-07-18 14:43:29 +00002937 if( rc==SQLITE_OK ){
2938 sqlite3_stmt *pStmt;
2939 rc = sqlite3_prepare_v2(p->db,
2940 "SELECT rowid FROM sqlite_master"
2941 " WHERE name GLOB 'sqlite_stat[134]'",
2942 -1, &pStmt, 0);
2943 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2944 sqlite3_finalize(pStmt);
2945 }
2946 if( doStats==0 ){
2947 fprintf(p->out, "/* No STAT tables available */\n");
2948 }else{
2949 fprintf(p->out, "ANALYZE sqlite_master;\n");
2950 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2951 callback, &data, &zErrMsg);
2952 data.mode = MODE_Insert;
2953 data.zDestTable = "sqlite_stat1";
2954 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2955 shell_callback, &data,&zErrMsg);
2956 data.zDestTable = "sqlite_stat3";
2957 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2958 shell_callback, &data,&zErrMsg);
2959 data.zDestTable = "sqlite_stat4";
2960 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2961 shell_callback, &data, &zErrMsg);
2962 fprintf(p->out, "ANALYZE sqlite_master;\n");
2963 }
drhc1971542014-06-23 23:28:13 +00002964 }else
2965
drhc2ce0be2014-05-29 12:36:14 +00002966 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2967 if( nArg==2 ){
2968 p->showHeader = booleanValue(azArg[1]);
2969 }else{
2970 fprintf(stderr, "Usage: .headers on|off\n");
2971 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002972 }
drh75897232000-05-29 14:26:00 +00002973 }else
2974
drhc2ce0be2014-05-29 12:36:14 +00002975 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2976 fprintf(p->out, "%s", zHelp);
2977 }else
2978
2979 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002980 char *zTable; /* Insert data into this table */
2981 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002982 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002983 int nCol; /* Number of columns in the table */
2984 int nByte; /* Number of bytes in an SQL string */
2985 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002986 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002987 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002988 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002989 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00002990 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
2991 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00002992
drhc2ce0be2014-05-29 12:36:14 +00002993 if( nArg!=3 ){
2994 fprintf(stderr, "Usage: .import FILE TABLE\n");
2995 goto meta_command_exit;
2996 }
drh01f37542014-05-31 15:43:33 +00002997 zFile = azArg[1];
2998 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002999 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003000 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003001 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003002 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003003 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003004 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003005 return 1;
drhfeac5f82004-08-01 00:10:45 +00003006 }
drhdb95f682013-06-26 22:46:00 +00003007 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003008 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003009 " for import\n");
3010 return 1;
3011 }
mistachkin636bf9f2014-07-19 20:15:16 +00003012 nSep = strlen30(p->rowSeparator);
3013 if( nSep==0 ){
3014 fprintf(stderr, "Error: non-null row separator required for import\n");
3015 return 1;
3016 }
mistachkine0d68852014-12-11 03:12:33 +00003017 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3018 /* When importing CSV (only), if the row separator is set to the
3019 ** default output row separator, change it to the default input
3020 ** row separator. This avoids having to maintain different input
3021 ** and output row separators. */
3022 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3023 nSep = strlen30(p->rowSeparator);
3024 }
mistachkin636bf9f2014-07-19 20:15:16 +00003025 if( nSep>1 ){
3026 fprintf(stderr, "Error: multi-character row separators not allowed"
3027 " for import\n");
3028 return 1;
3029 }
3030 sCtx.zFile = zFile;
3031 sCtx.nLine = 1;
3032 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003033#ifdef SQLITE_OMIT_POPEN
mistachkinba132c72015-03-19 14:48:38 +00003034 fprintf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003035 return 1;
3036#else
mistachkin636bf9f2014-07-19 20:15:16 +00003037 sCtx.in = popen(sCtx.zFile+1, "r");
3038 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003039 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003040#endif
drh5bde8162013-06-27 14:07:53 +00003041 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003042 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003043 xCloser = fclose;
3044 }
mistachkin636bf9f2014-07-19 20:15:16 +00003045 if( p->mode==MODE_Ascii ){
3046 xRead = ascii_read_one_field;
3047 }else{
3048 xRead = csv_read_one_field;
3049 }
3050 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00003051 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003052 return 1;
3053 }
mistachkin636bf9f2014-07-19 20:15:16 +00003054 sCtx.cColSep = p->colSeparator[0];
3055 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003056 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003057 if( zSql==0 ){
3058 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003059 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003060 return 1;
3061 }
drh4f21c4a2008-12-10 22:15:00 +00003062 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003063 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003064 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003065 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003066 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3067 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003068 while( xRead(&sCtx) ){
3069 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003070 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003071 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003072 }
drh5bde8162013-06-27 14:07:53 +00003073 if( cSep=='(' ){
3074 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003075 sqlite3_free(sCtx.z);
3076 xCloser(sCtx.in);
3077 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003078 return 1;
3079 }
drhdb95f682013-06-26 22:46:00 +00003080 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3081 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3082 sqlite3_free(zCreate);
3083 if( rc ){
3084 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003085 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003086 sqlite3_free(sCtx.z);
3087 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003088 return 1;
3089 }
drhc7181902014-02-27 15:04:13 +00003090 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003091 }
drhfeac5f82004-08-01 00:10:45 +00003092 sqlite3_free(zSql);
3093 if( rc ){
shane916f9612009-10-23 00:37:15 +00003094 if (pStmt) sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003095 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003096 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003097 return 1;
drhfeac5f82004-08-01 00:10:45 +00003098 }
shane916f9612009-10-23 00:37:15 +00003099 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003100 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003101 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003102 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003103 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003104 if( zSql==0 ){
3105 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003106 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003107 return 1;
3108 }
drhdb95f682013-06-26 22:46:00 +00003109 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003110 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003111 for(i=1; i<nCol; i++){
3112 zSql[j++] = ',';
3113 zSql[j++] = '?';
3114 }
3115 zSql[j++] = ')';
3116 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003117 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003118 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003119 if( rc ){
mistachkin8e189222015-04-19 21:43:16 +00003120 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003121 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003122 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003123 return 1;
drhfeac5f82004-08-01 00:10:45 +00003124 }
mistachkin8e189222015-04-19 21:43:16 +00003125 needCommit = sqlite3_get_autocommit(p->db);
3126 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003127 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003128 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003129 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003130 char *z = xRead(&sCtx);
3131 /*
3132 ** Did we reach end-of-file before finding any columns?
3133 ** If so, stop instead of NULL filling the remaining columns.
3134 */
drhdb95f682013-06-26 22:46:00 +00003135 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003136 /*
3137 ** Did we reach end-of-file OR end-of-line before finding any
3138 ** columns in ASCII mode? If so, stop instead of NULL filling
3139 ** the remaining columns.
3140 */
3141 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003142 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003143 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003144 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3145 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003146 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003147 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003148 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003149 }
drhfeac5f82004-08-01 00:10:45 +00003150 }
mistachkin636bf9f2014-07-19 20:15:16 +00003151 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003152 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003153 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003154 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003155 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003156 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3157 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003158 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003159 }
drhdb95f682013-06-26 22:46:00 +00003160 if( i>=nCol ){
3161 sqlite3_step(pStmt);
3162 rc = sqlite3_reset(pStmt);
3163 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003164 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
mistachkin8e189222015-04-19 21:43:16 +00003165 sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003166 }
3167 }
mistachkin636bf9f2014-07-19 20:15:16 +00003168 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003169
mistachkin636bf9f2014-07-19 20:15:16 +00003170 xCloser(sCtx.in);
3171 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003172 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003173 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003174 }else
3175
drh0e55db12015-02-06 14:51:13 +00003176 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3177 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003178 ShellState data;
drh75897232000-05-29 14:26:00 +00003179 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003180 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003181 memcpy(&data, p, sizeof(data));
3182 data.showHeader = 0;
3183 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003184 if( nArg==1 ){
3185 rc = sqlite3_exec(p->db,
3186 "SELECT name FROM sqlite_master "
3187 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3188 "UNION ALL "
3189 "SELECT name FROM sqlite_temp_master "
3190 "WHERE type='index' "
3191 "ORDER BY 1",
3192 callback, &data, &zErrMsg
3193 );
drhc2ce0be2014-05-29 12:36:14 +00003194 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003195 zShellStatic = azArg[1];
3196 rc = sqlite3_exec(p->db,
3197 "SELECT name FROM sqlite_master "
3198 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3199 "UNION ALL "
3200 "SELECT name FROM sqlite_temp_master "
3201 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3202 "ORDER BY 1",
3203 callback, &data, &zErrMsg
3204 );
3205 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003206 }else{
drh0e55db12015-02-06 14:51:13 +00003207 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003208 rc = 1;
3209 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003210 }
drh75897232000-05-29 14:26:00 +00003211 if( zErrMsg ){
3212 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003213 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003214 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003215 }else if( rc != SQLITE_OK ){
3216 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3217 rc = 1;
drh75897232000-05-29 14:26:00 +00003218 }
3219 }else
3220
drhae5e4452007-05-03 17:18:36 +00003221#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003222 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003223 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003224 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3225 iotrace = 0;
3226 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003227 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003228 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003229 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003230 iotrace = stdout;
3231 }else{
3232 iotrace = fopen(azArg[1], "w");
3233 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003234 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003235 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003236 rc = 1;
drhb0603412007-02-28 04:47:26 +00003237 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003238 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003239 }
3240 }
3241 }else
drhae5e4452007-05-03 17:18:36 +00003242#endif
drh1a513372015-05-02 17:40:23 +00003243 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3244 static const struct {
3245 const char *zLimitName; /* Name of a limit */
3246 int limitCode; /* Integer code for that limit */
3247 } aLimit[] = {
3248 { "length", SQLITE_LIMIT_LENGTH },
3249 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3250 { "column", SQLITE_LIMIT_COLUMN },
3251 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3252 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3253 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3254 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3255 { "attached", SQLITE_LIMIT_ATTACHED },
3256 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3257 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3258 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3259 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3260 };
3261 int i, n2;
3262 open_db(p, 0);
3263 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003264 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003265 printf("%20s %d\n", aLimit[i].zLimitName,
3266 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3267 }
3268 }else if( nArg>3 ){
3269 fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
3270 rc = 1;
3271 goto meta_command_exit;
3272 }else{
3273 int iLimit = -1;
3274 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003275 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003276 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3277 if( iLimit<0 ){
3278 iLimit = i;
3279 }else{
3280 fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
3281 rc = 1;
3282 goto meta_command_exit;
3283 }
3284 }
3285 }
3286 if( iLimit<0 ){
3287 fprintf(stderr, "unknown limit: \"%s\"\n"
3288 "enter \".limits\" with no arguments for a list.\n",
3289 azArg[1]);
3290 rc = 1;
3291 goto meta_command_exit;
3292 }
3293 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003294 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3295 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003296 }
3297 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3298 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3299 }
3300 }else
drhb0603412007-02-28 04:47:26 +00003301
drh70df4fe2006-06-13 15:12:21 +00003302#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003303 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003304 const char *zFile, *zProc;
3305 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003306 if( nArg<2 ){
3307 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3308 rc = 1;
3309 goto meta_command_exit;
3310 }
drh1e397f82006-06-08 15:28:43 +00003311 zFile = azArg[1];
3312 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003313 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003314 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3315 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003316 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003317 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003318 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003319 }
3320 }else
drh70df4fe2006-06-13 15:12:21 +00003321#endif
drh1e397f82006-06-08 15:28:43 +00003322
drhc2ce0be2014-05-29 12:36:14 +00003323 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3324 if( nArg!=2 ){
3325 fprintf(stderr, "Usage: .log FILENAME\n");
3326 rc = 1;
3327 }else{
3328 const char *zFile = azArg[1];
3329 output_file_close(p->pLog);
3330 p->pLog = output_file_open(zFile);
3331 }
drh127f9d72010-02-23 01:47:00 +00003332 }else
3333
drhc2ce0be2014-05-29 12:36:14 +00003334 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3335 const char *zMode = nArg>=2 ? azArg[1] : "";
3336 int n2 = (int)strlen(zMode);
3337 int c2 = zMode[0];
3338 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003339 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003340 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003341 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003342 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003343 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003344 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003345 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003346 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003347 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003348 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003349 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003350 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003351 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003352 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003353 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003354 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003355 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003356 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003357 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003358 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003359 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3360 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003361 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3362 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003363 }else {
shane9bd1b442009-10-23 01:27:39 +00003364 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003365 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003366 rc = 1;
drh75897232000-05-29 14:26:00 +00003367 }
3368 }else
3369
drhc2ce0be2014-05-29 12:36:14 +00003370 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3371 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003372 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3373 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003374 }else{
3375 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003376 rc = 1;
3377 }
3378 }else
3379
drh05782482013-10-24 15:20:20 +00003380 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3381 sqlite3 *savedDb = p->db;
3382 const char *zSavedFilename = p->zDbFilename;
3383 char *zNewFilename = 0;
3384 p->db = 0;
drhbbe031f2015-06-17 17:08:22 +00003385 if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3386 p->zDbFilename = zNewFilename;
drh05782482013-10-24 15:20:20 +00003387 open_db(p, 1);
3388 if( p->db!=0 ){
3389 sqlite3_close(savedDb);
3390 sqlite3_free(p->zFreeOnClose);
3391 p->zFreeOnClose = zNewFilename;
3392 }else{
3393 sqlite3_free(zNewFilename);
3394 p->db = savedDb;
3395 p->zDbFilename = zSavedFilename;
3396 }
3397 }else
3398
drhc2ce0be2014-05-29 12:36:14 +00003399 if( c=='o'
3400 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3401 ){
3402 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3403 if( nArg>2 ){
3404 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3405 rc = 1;
3406 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003407 }
drhc2ce0be2014-05-29 12:36:14 +00003408 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3409 if( nArg<2 ){
3410 fprintf(stderr, "Usage: .once FILE\n");
3411 rc = 1;
3412 goto meta_command_exit;
3413 }
3414 p->outCount = 2;
3415 }else{
3416 p->outCount = 0;
3417 }
3418 output_reset(p);
3419 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003420#ifdef SQLITE_OMIT_POPEN
3421 fprintf(stderr,"Error: pipes are not supported in this OS\n");
3422 rc = 1;
3423 p->out = stdout;
3424#else
drhc2ce0be2014-05-29 12:36:14 +00003425 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003426 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003427 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003428 p->out = stdout;
3429 rc = 1;
3430 }else{
drhc2ce0be2014-05-29 12:36:14 +00003431 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003432 }
drh8cd5b252015-03-02 22:06:43 +00003433#endif
drh75897232000-05-29 14:26:00 +00003434 }else{
drhc2ce0be2014-05-29 12:36:14 +00003435 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003436 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003437 if( strcmp(zFile,"off")!=0 ){
3438 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003439 }
drh75897232000-05-29 14:26:00 +00003440 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003441 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003442 } else {
drhc2ce0be2014-05-29 12:36:14 +00003443 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003444 }
3445 }
3446 }else
3447
drh078b1fd2012-09-21 13:40:02 +00003448 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3449 int i;
3450 for(i=1; i<nArg; i++){
3451 if( i>1 ) fprintf(p->out, " ");
3452 fprintf(p->out, "%s", azArg[i]);
3453 }
3454 fprintf(p->out, "\n");
3455 }else
3456
drhc2ce0be2014-05-29 12:36:14 +00003457 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003458 if( nArg >= 2) {
3459 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3460 }
3461 if( nArg >= 3) {
3462 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3463 }
3464 }else
3465
drhc2ce0be2014-05-29 12:36:14 +00003466 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003467 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003468 }else
3469
drhc2ce0be2014-05-29 12:36:14 +00003470 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3471 FILE *alt;
3472 if( nArg!=2 ){
3473 fprintf(stderr, "Usage: .read FILE\n");
3474 rc = 1;
3475 goto meta_command_exit;
3476 }
3477 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003478 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003479 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3480 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003481 }else{
shane9bd1b442009-10-23 01:27:39 +00003482 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003483 fclose(alt);
3484 }
3485 }else
3486
drhc2ce0be2014-05-29 12:36:14 +00003487 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003488 const char *zSrcFile;
3489 const char *zDb;
3490 sqlite3 *pSrc;
3491 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003492 int nTimeout = 0;
3493
drh9ff849f2009-02-04 20:55:57 +00003494 if( nArg==2 ){
3495 zSrcFile = azArg[1];
3496 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003497 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003498 zSrcFile = azArg[2];
3499 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003500 }else{
3501 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3502 rc = 1;
3503 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003504 }
3505 rc = sqlite3_open(zSrcFile, &pSrc);
3506 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003507 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003508 sqlite3_close(pSrc);
3509 return 1;
3510 }
drh05782482013-10-24 15:20:20 +00003511 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003512 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3513 if( pBackup==0 ){
3514 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3515 sqlite3_close(pSrc);
3516 return 1;
3517 }
drhdc2c4912009-02-04 22:46:47 +00003518 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3519 || rc==SQLITE_BUSY ){
3520 if( rc==SQLITE_BUSY ){
3521 if( nTimeout++ >= 3 ) break;
3522 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003523 }
3524 }
3525 sqlite3_backup_finish(pBackup);
3526 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003527 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003528 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003529 fprintf(stderr, "Error: source database is busy\n");
3530 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003531 }else{
3532 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003533 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003534 }
3535 sqlite3_close(pSrc);
3536 }else
3537
dan8d1edb92014-11-05 09:07:28 +00003538
3539 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3540 if( nArg==2 ){
3541 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003542#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3543 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3544#endif
dan8d1edb92014-11-05 09:07:28 +00003545 }else{
3546 fprintf(stderr, "Usage: .scanstats on|off\n");
3547 rc = 1;
3548 }
3549 }else
3550
drhc2ce0be2014-05-29 12:36:14 +00003551 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003552 ShellState data;
drh75897232000-05-29 14:26:00 +00003553 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003554 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003555 memcpy(&data, p, sizeof(data));
3556 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003557 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003558 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003559 int i;
drhf0693c82011-10-11 20:41:54 +00003560 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003561 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003562 char *new_argv[2], *new_colv[2];
3563 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3564 " type text,\n"
3565 " name text,\n"
3566 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003567 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003568 " sql text\n"
3569 ")";
3570 new_argv[1] = 0;
3571 new_colv[0] = "sql";
3572 new_colv[1] = 0;
3573 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003574 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003575 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003576 char *new_argv[2], *new_colv[2];
3577 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3578 " type text,\n"
3579 " name text,\n"
3580 " tbl_name text,\n"
3581 " rootpage integer,\n"
3582 " sql text\n"
3583 ")";
3584 new_argv[1] = 0;
3585 new_colv[0] = "sql";
3586 new_colv[1] = 0;
3587 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003588 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003589 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003590 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003591 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003592 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003593 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003594 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003595 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003596 "WHERE lower(tbl_name) LIKE shellstatic()"
3597 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003598 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003599 callback, &data, &zErrMsg);
3600 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003601 }
drhc2ce0be2014-05-29 12:36:14 +00003602 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003603 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003604 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003605 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003606 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003607 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003608 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003609 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003610 callback, &data, &zErrMsg
3611 );
drhc2ce0be2014-05-29 12:36:14 +00003612 }else{
3613 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3614 rc = 1;
3615 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003616 }
drh75897232000-05-29 14:26:00 +00003617 if( zErrMsg ){
3618 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003619 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003620 rc = 1;
3621 }else if( rc != SQLITE_OK ){
3622 fprintf(stderr,"Error: querying schema information\n");
3623 rc = 1;
3624 }else{
3625 rc = 0;
drh75897232000-05-29 14:26:00 +00003626 }
3627 }else
3628
drhabd4c722014-09-20 18:18:33 +00003629
3630#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3631 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3632 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003633 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003634 }else
3635#endif
3636
3637
drh340f5822013-06-27 13:01:21 +00003638#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003639 /* Undocumented commands for internal testing. Subject to change
3640 ** without notice. */
3641 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3642 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3643 int i, v;
3644 for(i=1; i<nArg; i++){
3645 v = booleanValue(azArg[i]);
3646 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3647 }
3648 }
3649 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3650 int i; sqlite3_int64 v;
3651 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003652 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003653 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003654 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003655 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003656 }
3657 }
3658 }else
drh340f5822013-06-27 13:01:21 +00003659#endif
drh348d19c2013-06-03 12:47:43 +00003660
drhc2ce0be2014-05-29 12:36:14 +00003661 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003662 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003663 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003664 rc = 1;
3665 }
drh6976c212014-07-24 12:09:47 +00003666 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003667 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003668 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003669 }
3670 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003671 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3672 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003673 }
drh75897232000-05-29 14:26:00 +00003674 }else
3675
drh62cdde52014-05-28 20:22:28 +00003676 if( c=='s'
3677 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003678 ){
3679 char *zCmd;
drh54027102014-08-06 14:36:53 +00003680 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003681 if( nArg<2 ){
3682 fprintf(stderr, "Usage: .system COMMAND\n");
3683 rc = 1;
3684 goto meta_command_exit;
3685 }
drhdcb3e3d2014-05-29 03:17:29 +00003686 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003687 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003688 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3689 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003690 }
drh54027102014-08-06 14:36:53 +00003691 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003692 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003693 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003694 }else
3695
drhc2ce0be2014-05-29 12:36:14 +00003696 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003697 int i;
drhc2ce0be2014-05-29 12:36:14 +00003698 if( nArg!=1 ){
3699 fprintf(stderr, "Usage: .show\n");
3700 rc = 1;
3701 goto meta_command_exit;
3702 }
mistachkin636bf9f2014-07-19 20:15:16 +00003703 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3704 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003705 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003706 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3707 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3708 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003709 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003710 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003711 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003712 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003713 fprintf(p->out,"%12.12s: ", "colseparator");
3714 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003715 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003716 fprintf(p->out,"%12.12s: ", "rowseparator");
3717 output_c_string(p->out, p->rowSeparator);
3718 fprintf(p->out, "\n");
3719 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3720 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003721 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003722 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003723 }
drhfeac5f82004-08-01 00:10:45 +00003724 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003725 }else
3726
drhc2ce0be2014-05-29 12:36:14 +00003727 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3728 if( nArg==2 ){
3729 p->statsOn = booleanValue(azArg[1]);
3730 }else{
3731 fprintf(stderr, "Usage: .stats on|off\n");
3732 rc = 1;
3733 }
shaneh642d8b82010-07-28 16:05:34 +00003734 }else
3735
drhc2ce0be2014-05-29 12:36:14 +00003736 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003737 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003738 char **azResult;
drh98781232012-04-23 12:38:05 +00003739 int nRow, nAlloc;
3740 char *zSql = 0;
3741 int ii;
drh05782482013-10-24 15:20:20 +00003742 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003743 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00003744 if( rc ) return shellDatabaseError(p->db);
3745
3746 /* Create an SQL statement to query for the list of tables in the
3747 ** main and all attached databases where the table name matches the
3748 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00003749 zSql = sqlite3_mprintf(
3750 "SELECT name FROM sqlite_master"
3751 " WHERE type IN ('table','view')"
3752 " AND name NOT LIKE 'sqlite_%%'"
3753 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00003754 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00003755 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3756 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3757 if( strcmp(zDbName,"temp")==0 ){
3758 zSql = sqlite3_mprintf(
3759 "%z UNION ALL "
3760 "SELECT 'temp.' || name FROM sqlite_temp_master"
3761 " WHERE type IN ('table','view')"
3762 " AND name NOT LIKE 'sqlite_%%'"
3763 " AND name LIKE ?1", zSql);
3764 }else{
3765 zSql = sqlite3_mprintf(
3766 "%z UNION ALL "
3767 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3768 " WHERE type IN ('table','view')"
3769 " AND name NOT LIKE 'sqlite_%%'"
3770 " AND name LIKE ?1", zSql, zDbName, zDbName);
3771 }
drha50da102000-08-08 20:19:09 +00003772 }
dand95bb392015-09-30 11:19:05 +00003773 rc = sqlite3_finalize(pStmt);
3774 if( zSql && rc==SQLITE_OK ){
3775 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3776 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3777 }
drh98781232012-04-23 12:38:05 +00003778 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00003779 if( !zSql ) return shellNomemError();
3780 if( rc ) return shellDatabaseError(p->db);
3781
3782 /* Run the SQL statement prepared by the above block. Store the results
3783 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00003784 nRow = nAlloc = 0;
3785 azResult = 0;
3786 if( nArg>1 ){
3787 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003788 }else{
drh98781232012-04-23 12:38:05 +00003789 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3790 }
3791 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3792 if( nRow>=nAlloc ){
3793 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00003794 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00003795 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00003796 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00003797 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00003798 break;
3799 }
mistachkin8e189222015-04-19 21:43:16 +00003800 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00003801 azResult = azNew;
3802 }
3803 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00003804 if( 0==azResult[nRow] ){
3805 rc = shellNomemError();
3806 break;
3807 }
3808 nRow++;
drh98781232012-04-23 12:38:05 +00003809 }
dand95bb392015-09-30 11:19:05 +00003810 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
3811 rc = shellDatabaseError(p->db);
3812 }
3813
3814 /* Pretty-print the contents of array azResult[] to the output */
3815 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003816 int len, maxlen = 0;
3817 int i, j;
3818 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003819 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003820 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003821 if( len>maxlen ) maxlen = len;
3822 }
3823 nPrintCol = 80/(maxlen+2);
3824 if( nPrintCol<1 ) nPrintCol = 1;
3825 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3826 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003827 for(j=i; j<nRow; j+=nPrintRow){
3828 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003829 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003830 }
drh151b7d52013-05-06 20:28:54 +00003831 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003832 }
3833 }
dand95bb392015-09-30 11:19:05 +00003834
drh98781232012-04-23 12:38:05 +00003835 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3836 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003837 }else
3838
shaneh96887e12011-02-10 21:08:58 +00003839 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003840 static const struct {
3841 const char *zCtrlName; /* Name of a test-control option */
3842 int ctrlCode; /* Integer code for that option */
3843 } aCtrl[] = {
3844 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3845 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3846 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3847 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3848 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3849 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3850 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3851 { "assert", SQLITE_TESTCTRL_ASSERT },
3852 { "always", SQLITE_TESTCTRL_ALWAYS },
3853 { "reserve", SQLITE_TESTCTRL_RESERVE },
3854 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3855 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003856 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003857 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003858 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003859 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003860 };
shaneh96887e12011-02-10 21:08:58 +00003861 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00003862 int rc2 = 0;
3863 int i, n2;
drh05782482013-10-24 15:20:20 +00003864 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003865
drhd416fe72011-03-17 16:45:50 +00003866 /* convert testctrl text option to value. allow any unique prefix
3867 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00003868 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003869 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00003870 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00003871 if( testctrl<0 ){
3872 testctrl = aCtrl[i].ctrlCode;
3873 }else{
drhb07028f2011-10-14 21:49:18 +00003874 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003875 testctrl = -1;
3876 break;
3877 }
3878 }
3879 }
drh348d19c2013-06-03 12:47:43 +00003880 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003881 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3882 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3883 }else{
3884 switch(testctrl){
3885
3886 /* sqlite3_test_control(int, db, int) */
3887 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3888 case SQLITE_TESTCTRL_RESERVE:
3889 if( nArg==3 ){
3890 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00003891 rc2 = sqlite3_test_control(testctrl, p->db, opt);
3892 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003893 } else {
drhd416fe72011-03-17 16:45:50 +00003894 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3895 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003896 }
3897 break;
3898
3899 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003900 case SQLITE_TESTCTRL_PRNG_SAVE:
3901 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003902 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003903 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003904 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00003905 rc2 = sqlite3_test_control(testctrl);
3906 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003907 } else {
3908 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3909 }
3910 break;
3911
3912 /* sqlite3_test_control(int, uint) */
3913 case SQLITE_TESTCTRL_PENDING_BYTE:
3914 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003915 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00003916 rc2 = sqlite3_test_control(testctrl, opt);
3917 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003918 } else {
drhd416fe72011-03-17 16:45:50 +00003919 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3920 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003921 }
3922 break;
3923
3924 /* sqlite3_test_control(int, int) */
3925 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00003926 case SQLITE_TESTCTRL_ALWAYS:
3927 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00003928 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003929 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00003930 rc2 = sqlite3_test_control(testctrl, opt);
3931 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003932 } else {
drhd416fe72011-03-17 16:45:50 +00003933 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3934 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003935 }
3936 break;
3937
3938 /* sqlite3_test_control(int, char *) */
3939#ifdef SQLITE_N_KEYWORD
3940 case SQLITE_TESTCTRL_ISKEYWORD:
3941 if( nArg==3 ){
3942 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00003943 rc2 = sqlite3_test_control(testctrl, opt);
3944 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003945 } else {
drhd416fe72011-03-17 16:45:50 +00003946 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3947 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003948 }
3949 break;
3950#endif
3951
drh1ffede82015-01-30 20:59:27 +00003952 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00003953 if( nArg==5 ){
mistachkin8e189222015-04-19 21:43:16 +00003954 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00003955 azArg[2],
drh8964b342015-01-29 17:54:52 +00003956 integerValue(azArg[3]),
3957 integerValue(azArg[4]));
mistachkin8e189222015-04-19 21:43:16 +00003958 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00003959 }else{
drh6f5a37a2015-03-27 02:27:20 +00003960 fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00003961 }
3962 break;
3963
shaneh96887e12011-02-10 21:08:58 +00003964 case SQLITE_TESTCTRL_BITVEC_TEST:
3965 case SQLITE_TESTCTRL_FAULT_INSTALL:
3966 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3967 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3968 default:
drhd416fe72011-03-17 16:45:50 +00003969 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3970 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003971 break;
3972 }
3973 }
3974 }else
3975
drhc2ce0be2014-05-29 12:36:14 +00003976 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003977 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003978 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003979 }else
3980
drhc2ce0be2014-05-29 12:36:14 +00003981 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3982 if( nArg==2 ){
3983 enableTimer = booleanValue(azArg[1]);
3984 if( enableTimer && !HAS_TIMER ){
3985 fprintf(stderr, "Error: timer not available on this system.\n");
3986 enableTimer = 0;
3987 }
3988 }else{
3989 fprintf(stderr, "Usage: .timer on|off\n");
3990 rc = 1;
3991 }
shanehe2aa9d72009-11-06 17:20:17 +00003992 }else
3993
drhc2ce0be2014-05-29 12:36:14 +00003994 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003995 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003996 if( nArg!=2 ){
3997 fprintf(stderr, "Usage: .trace FILE|off\n");
3998 rc = 1;
3999 goto meta_command_exit;
4000 }
drh657b4a82015-03-19 13:30:41 +00004001 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004002 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004003#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004004 if( p->traceOut==0 ){
4005 sqlite3_trace(p->db, 0, 0);
4006 }else{
4007 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
4008 }
4009#endif
4010 }else
4011
drhf442e332014-09-10 19:01:14 +00004012#if SQLITE_USER_AUTHENTICATION
4013 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4014 if( nArg<2 ){
4015 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
4016 rc = 1;
4017 goto meta_command_exit;
4018 }
drh7883ecf2014-09-11 16:19:31 +00004019 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004020 if( strcmp(azArg[1],"login")==0 ){
4021 if( nArg!=4 ){
4022 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
4023 rc = 1;
4024 goto meta_command_exit;
4025 }
drhd39c40f2014-09-11 00:27:53 +00004026 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4027 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004028 if( rc ){
4029 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
4030 rc = 1;
4031 }
4032 }else if( strcmp(azArg[1],"add")==0 ){
4033 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00004034 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004035 rc = 1;
4036 goto meta_command_exit;
4037 }
drhd39c40f2014-09-11 00:27:53 +00004038 rc = sqlite3_user_add(p->db, azArg[2],
4039 azArg[3], (int)strlen(azArg[3]),
4040 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004041 if( rc ){
4042 fprintf(stderr, "User-Add failed: %d\n", rc);
4043 rc = 1;
4044 }
4045 }else if( strcmp(azArg[1],"edit")==0 ){
4046 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00004047 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004048 rc = 1;
4049 goto meta_command_exit;
4050 }
drhd39c40f2014-09-11 00:27:53 +00004051 rc = sqlite3_user_change(p->db, azArg[2],
4052 azArg[3], (int)strlen(azArg[3]),
4053 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004054 if( rc ){
4055 fprintf(stderr, "User-Edit failed: %d\n", rc);
4056 rc = 1;
4057 }
4058 }else if( strcmp(azArg[1],"delete")==0 ){
4059 if( nArg!=3 ){
4060 fprintf(stderr, "Usage: .user delete USER\n");
4061 rc = 1;
4062 goto meta_command_exit;
4063 }
4064 rc = sqlite3_user_delete(p->db, azArg[2]);
4065 if( rc ){
4066 fprintf(stderr, "User-Delete failed: %d\n", rc);
4067 rc = 1;
4068 }
4069 }else{
4070 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
4071 rc = 1;
4072 goto meta_command_exit;
4073 }
4074 }else
4075#endif /* SQLITE_USER_AUTHENTICATION */
4076
drh9fd301b2011-06-03 13:28:22 +00004077 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00004078 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004079 sqlite3_libversion(), sqlite3_sourceid());
4080 }else
4081
drh790f2872015-11-28 18:06:36 +00004082 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
4083 const char *zDbName = nArg==2 ? azArg[1] : "main";
4084 sqlite3_vfs *pVfs;
4085 if( p->db ){
4086 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
4087 if( pVfs ){
4088 fprintf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
4089 fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4090 fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4091 fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
4092 }
4093 }
4094 }else
4095
drhde60fc22011-12-14 17:53:36 +00004096 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4097 const char *zDbName = nArg==2 ? azArg[1] : "main";
4098 char *zVfsName = 0;
4099 if( p->db ){
4100 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4101 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00004102 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004103 sqlite3_free(zVfsName);
4104 }
4105 }
4106 }else
4107
drhcef4fc82012-09-21 22:50:45 +00004108#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4109 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
4110 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00004111 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004112 }else
4113#endif
4114
drhc2ce0be2014-05-29 12:36:14 +00004115 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004116 int j;
drh43617e92006-03-06 20:55:46 +00004117 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004118 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004119 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004120 }
4121 }else
4122
4123 {
shane9bd1b442009-10-23 01:27:39 +00004124 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004125 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004126 rc = 1;
drh75897232000-05-29 14:26:00 +00004127 }
drh67505e72002-04-19 12:34:06 +00004128
drhc2ce0be2014-05-29 12:36:14 +00004129meta_command_exit:
4130 if( p->outCount ){
4131 p->outCount--;
4132 if( p->outCount==0 ) output_reset(p);
4133 }
drh67505e72002-04-19 12:34:06 +00004134 return rc;
drh75897232000-05-29 14:26:00 +00004135}
4136
drh67505e72002-04-19 12:34:06 +00004137/*
drh91a66392007-09-07 01:12:32 +00004138** Return TRUE if a semicolon occurs anywhere in the first N characters
4139** of string z[].
drh324ccef2003-02-05 14:06:20 +00004140*/
drh9f099fd2013-08-06 14:01:46 +00004141static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004142 int i;
4143 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4144 return 0;
drh324ccef2003-02-05 14:06:20 +00004145}
4146
4147/*
drh70c7a4b2003-04-26 03:03:06 +00004148** Test to see if a line consists entirely of whitespace.
4149*/
4150static int _all_whitespace(const char *z){
4151 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004152 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004153 if( *z=='/' && z[1]=='*' ){
4154 z += 2;
4155 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4156 if( *z==0 ) return 0;
4157 z++;
4158 continue;
4159 }
4160 if( *z=='-' && z[1]=='-' ){
4161 z += 2;
4162 while( *z && *z!='\n' ){ z++; }
4163 if( *z==0 ) return 1;
4164 continue;
4165 }
4166 return 0;
4167 }
4168 return 1;
4169}
4170
4171/*
drha9b17162003-04-29 18:01:28 +00004172** Return TRUE if the line typed in is an SQL command terminator other
4173** than a semi-colon. The SQL Server style "go" command is understood
4174** as is the Oracle "/".
4175*/
drh9f099fd2013-08-06 14:01:46 +00004176static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004177 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004178 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4179 return 1; /* Oracle */
4180 }
drhf0693c82011-10-11 20:41:54 +00004181 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004182 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004183 return 1; /* SQL Server */
4184 }
4185 return 0;
4186}
4187
4188/*
drh233a5312008-12-18 22:25:13 +00004189** Return true if zSql is a complete SQL statement. Return false if it
4190** ends in the middle of a string literal or C-style comment.
4191*/
drh9f099fd2013-08-06 14:01:46 +00004192static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004193 int rc;
4194 if( zSql==0 ) return 1;
4195 zSql[nSql] = ';';
4196 zSql[nSql+1] = 0;
4197 rc = sqlite3_complete(zSql);
4198 zSql[nSql] = 0;
4199 return rc;
4200}
4201
4202/*
drh67505e72002-04-19 12:34:06 +00004203** Read input from *in and process it. If *in==0 then input
4204** is interactive - the user is typing it it. Otherwise, input
4205** is coming from a file or device. A prompt is issued and history
4206** is saved only if input is interactive. An interrupt signal will
4207** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004208**
4209** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004210*/
drhdcd87a92014-08-18 13:45:42 +00004211static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004212 char *zLine = 0; /* A single input line */
4213 char *zSql = 0; /* Accumulated SQL text */
4214 int nLine; /* Length of current line */
4215 int nSql = 0; /* Bytes of zSql[] used */
4216 int nAlloc = 0; /* Allocated zSql[] space */
4217 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4218 char *zErrMsg; /* Error message returned */
4219 int rc; /* Error code */
4220 int errCnt = 0; /* Number of errors seen */
4221 int lineno = 0; /* Current line number */
4222 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004223
4224 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4225 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004226 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004227 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004228 /* End of input */
4229 if( stdin_is_interactive ) printf("\n");
4230 break;
drhc49f44e2006-10-26 18:15:42 +00004231 }
drh67505e72002-04-19 12:34:06 +00004232 if( seenInterrupt ){
4233 if( in!=0 ) break;
4234 seenInterrupt = 0;
4235 }
drhc28490c2006-10-26 14:25:58 +00004236 lineno++;
drh849a9d92013-12-21 15:46:06 +00004237 if( nSql==0 && _all_whitespace(zLine) ){
4238 if( p->echoOn ) printf("%s\n", zLine);
4239 continue;
4240 }
drh2af0b2d2002-02-21 02:25:02 +00004241 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004242 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004243 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004244 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004245 break;
4246 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004247 errCnt++;
4248 }
drhdaffd0e2001-04-11 14:28:42 +00004249 continue;
4250 }
drh9f099fd2013-08-06 14:01:46 +00004251 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004252 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004253 }
drh9f099fd2013-08-06 14:01:46 +00004254 nLine = strlen30(zLine);
4255 if( nSql+nLine+2>=nAlloc ){
4256 nAlloc = nSql+nLine+100;
4257 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004258 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004259 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004260 exit(1);
4261 }
drhdaffd0e2001-04-11 14:28:42 +00004262 }
drh9f099fd2013-08-06 14:01:46 +00004263 nSqlPrior = nSql;
4264 if( nSql==0 ){
4265 int i;
4266 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004267 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004268 memcpy(zSql, zLine+i, nLine+1-i);
4269 startline = lineno;
4270 nSql = nLine-i;
4271 }else{
4272 zSql[nSql++] = '\n';
4273 memcpy(zSql+nSql, zLine, nLine+1);
4274 nSql += nLine;
4275 }
4276 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004277 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004278 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004279 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004280 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004281 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004282 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004283 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004284 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004285 char zPrefix[100];
4286 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004287 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004288 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004289 }else{
shane9bd1b442009-10-23 01:27:39 +00004290 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004291 }
drh7f953e22002-07-13 17:33:45 +00004292 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004293 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004294 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004295 zErrMsg = 0;
4296 }else{
shaned2bed1c2009-10-21 03:56:54 +00004297 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004298 }
drhc49f44e2006-10-26 18:15:42 +00004299 errCnt++;
drhdf12f1c2015-12-07 21:46:19 +00004300 }else if( p->countChanges ){
4301 fprintf(p->out, "changes: %3d total_changes: %d\n",
4302 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
drhdaffd0e2001-04-11 14:28:42 +00004303 }
drhdaffd0e2001-04-11 14:28:42 +00004304 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004305 if( p->outCount ){
4306 output_reset(p);
4307 p->outCount = 0;
4308 }
drh9f099fd2013-08-06 14:01:46 +00004309 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004310 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004311 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004312 }
4313 }
drh9f099fd2013-08-06 14:01:46 +00004314 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004315 if( !_all_whitespace(zSql) ){
4316 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004317 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004318 }
drhdaffd0e2001-04-11 14:28:42 +00004319 }
drh1f9ca2c2015-08-25 16:57:52 +00004320 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00004321 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004322 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004323}
4324
drh67505e72002-04-19 12:34:06 +00004325/*
4326** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004327** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004328*/
4329static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004330 static char *home_dir = NULL;
4331 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004332
drh4ace5362014-11-10 14:42:28 +00004333#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4334 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004335 {
4336 struct passwd *pwent;
4337 uid_t uid = getuid();
4338 if( (pwent=getpwuid(uid)) != NULL) {
4339 home_dir = pwent->pw_dir;
4340 }
drh67505e72002-04-19 12:34:06 +00004341 }
4342#endif
4343
chw65d3c132007-11-12 21:09:10 +00004344#if defined(_WIN32_WCE)
4345 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4346 */
drh85e72432012-04-11 11:38:53 +00004347 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004348#else
4349
drh83905c92012-06-21 13:00:37 +00004350#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004351 if (!home_dir) {
4352 home_dir = getenv("USERPROFILE");
4353 }
4354#endif
4355
drh67505e72002-04-19 12:34:06 +00004356 if (!home_dir) {
4357 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004358 }
4359
drh83905c92012-06-21 13:00:37 +00004360#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004361 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004362 char *zDrive, *zPath;
4363 int n;
4364 zDrive = getenv("HOMEDRIVE");
4365 zPath = getenv("HOMEPATH");
4366 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004367 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004368 home_dir = malloc( n );
4369 if( home_dir==0 ) return 0;
4370 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4371 return home_dir;
4372 }
4373 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004374 }
4375#endif
4376
chw65d3c132007-11-12 21:09:10 +00004377#endif /* !_WIN32_WCE */
4378
drh67505e72002-04-19 12:34:06 +00004379 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004380 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004381 char *z = malloc( n );
4382 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004383 home_dir = z;
4384 }
drhe98d4fa2002-04-21 19:06:22 +00004385
drh67505e72002-04-19 12:34:06 +00004386 return home_dir;
4387}
4388
4389/*
4390** Read input from the file given by sqliterc_override. Or if that
4391** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004392**
4393** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004394*/
drh534f4df2015-02-28 14:03:35 +00004395static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004396 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004397 const char *sqliterc_override /* Name of config file. NULL to use default */
4398){
persicom7e2dfdd2002-04-18 02:46:52 +00004399 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004400 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004401 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004402 FILE *in = NULL;
4403
4404 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004405 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004406 if( home_dir==0 ){
drh534f4df2015-02-28 14:03:35 +00004407 fprintf(stderr, "-- warning: cannot find home directory;"
4408 " cannot read ~/.sqliterc\n");
4409 return;
drhe98d4fa2002-04-21 19:06:22 +00004410 }
drh2f3de322012-06-27 16:41:31 +00004411 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004412 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4413 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004414 }
drha1f9b5e2004-02-14 16:31:02 +00004415 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004416 if( in ){
drhc28490c2006-10-26 14:25:58 +00004417 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004418 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004419 }
drh534f4df2015-02-28 14:03:35 +00004420 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004421 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004422 }
drh85e72432012-04-11 11:38:53 +00004423 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004424}
4425
drh67505e72002-04-19 12:34:06 +00004426/*
drhe1e38c42003-05-04 18:30:59 +00004427** Show available command line options
4428*/
4429static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004430 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004431 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004432 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004433 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004434 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004435 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004436 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004437 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004438 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004439#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4440 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4441#endif
drhcc3b4f82012-02-07 14:13:50 +00004442 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004443 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004444 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004445 " -line set output mode to 'line'\n"
4446 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004447 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004448 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004449#ifdef SQLITE_ENABLE_MULTIPLEX
4450 " -multiplex enable the multiplexor VFS\n"
4451#endif
mistachkine0d68852014-12-11 03:12:33 +00004452 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004453 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004454 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4455 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004456 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004457 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004458 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004459 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004460#ifdef SQLITE_ENABLE_VFSTRACE
4461 " -vfstrace enable tracing of all VFS calls\n"
4462#endif
drhe1e38c42003-05-04 18:30:59 +00004463;
4464static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004465 fprintf(stderr,
4466 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4467 "FILENAME is the name of an SQLite database. A new database is created\n"
4468 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004469 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004470 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004471 }else{
4472 fprintf(stderr, "Use the -help option for additional information\n");
4473 }
4474 exit(1);
4475}
4476
4477/*
drh67505e72002-04-19 12:34:06 +00004478** Initialize the state information in data
4479*/
drhdcd87a92014-08-18 13:45:42 +00004480static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004481 memset(data, 0, sizeof(*data));
4482 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004483 memcpy(data->colSeparator,SEP_Column, 2);
4484 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004485 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004486 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004487 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004488 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004489 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004490 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4491 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004492}
4493
drh98d312f2012-10-25 15:23:14 +00004494/*
drh5c7976f2014-02-10 19:59:27 +00004495** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004496*/
4497#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004498static void printBold(const char *zText){
4499 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4500 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4501 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4502 SetConsoleTextAttribute(out,
4503 FOREGROUND_RED|FOREGROUND_INTENSITY
4504 );
4505 printf("%s", zText);
4506 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004507}
4508#else
drh5c7976f2014-02-10 19:59:27 +00004509static void printBold(const char *zText){
4510 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004511}
4512#endif
4513
4514/*
drh98d312f2012-10-25 15:23:14 +00004515** Get the argument to an --option. Throw an error and die if no argument
4516** is available.
4517*/
4518static char *cmdline_option_value(int argc, char **argv, int i){
4519 if( i==argc ){
4520 fprintf(stderr, "%s: Error: missing argument to %s\n",
4521 argv[0], argv[argc-1]);
4522 exit(1);
4523 }
4524 return argv[i];
4525}
4526
mistachkin44723ce2015-03-21 02:22:37 +00004527int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004528 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004529 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004530 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004531 int i;
drhc28490c2006-10-26 14:25:58 +00004532 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004533 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004534 int readStdin = 1;
4535 int nCmd = 0;
4536 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004537
drh69b30ab2014-02-27 15:11:52 +00004538#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004539 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4540 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4541 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4542 exit(1);
4543 }
drhc7181902014-02-27 15:04:13 +00004544#endif
drh047d4532015-01-18 20:30:23 +00004545 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004546 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004547 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004548 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004549 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004550
drh44c2eb12003-04-30 11:38:26 +00004551 /* Make sure we have a valid signal handler early, before anything
4552 ** else is done.
4553 */
drh4c504392000-10-16 22:06:40 +00004554#ifdef SIGINT
4555 signal(SIGINT, interrupt_handler);
4556#endif
drh44c2eb12003-04-30 11:38:26 +00004557
drhac5649a2014-11-28 13:35:03 +00004558#ifdef SQLITE_SHELL_DBNAME_PROC
4559 {
4560 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4561 ** of a C-function that will provide the name of the database file. Use
4562 ** this compile-time option to embed this shell program in larger
4563 ** applications. */
4564 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4565 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4566 warnInmemoryDb = 0;
4567 }
4568#endif
4569
drh22fbcb82004-02-01 01:22:50 +00004570 /* Do an initial pass through the command-line argument to locate
4571 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004572 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004573 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004574 */
drh98d312f2012-10-25 15:23:14 +00004575 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004576 char *z;
drhc28490c2006-10-26 14:25:58 +00004577 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004578 if( z[0]!='-' ){
4579 if( data.zDbFilename==0 ){
4580 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004581 }else{
4582 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4583 ** mean that nothing is read from stdin */
4584 readStdin = 0;
4585 nCmd++;
4586 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4587 if( azCmd==0 ){
4588 fprintf(stderr, "out of memory\n");
4589 exit(1);
4590 }
4591 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004592 }
drh98d312f2012-10-25 15:23:14 +00004593 }
drhcc3b4f82012-02-07 14:13:50 +00004594 if( z[1]=='-' ) z++;
4595 if( strcmp(z,"-separator")==0
4596 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004597 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004598 || strcmp(z,"-cmd")==0
4599 ){
drh98d312f2012-10-25 15:23:14 +00004600 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004601 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004602 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004603 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004604 /* Need to check for batch mode here to so we can avoid printing
4605 ** informational messages (like from process_sqliterc) before
4606 ** we do the actual processing of arguments later in a second pass.
4607 */
shanef69573d2009-10-24 02:06:14 +00004608 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004609 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004610#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004611 const char *zSize;
4612 sqlite3_int64 szHeap;
4613
drh98d312f2012-10-25 15:23:14 +00004614 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004615 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004616 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004617 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4618#endif
drh44dec872014-08-30 15:49:25 +00004619 }else if( strcmp(z,"-scratch")==0 ){
4620 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004621 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004622 if( sz>400000 ) sz = 400000;
4623 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004624 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004625 if( n>10 ) n = 10;
4626 if( n<1 ) n = 1;
4627 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4628 data.shellFlgs |= SHFLG_Scratch;
4629 }else if( strcmp(z,"-pagecache")==0 ){
4630 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004631 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004632 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00004633 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004634 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00004635 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
4636 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00004637 data.shellFlgs |= SHFLG_Pagecache;
4638 }else if( strcmp(z,"-lookaside")==0 ){
4639 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004640 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004641 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004642 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004643 if( n<0 ) n = 0;
4644 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4645 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004646#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004647 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004648 extern int vfstrace_register(
4649 const char *zTraceName,
4650 const char *zOldVfsName,
4651 int (*xOut)(const char*,void*),
4652 void *pOutArg,
4653 int makeDefault
4654 );
drh2b625e22011-03-16 17:05:28 +00004655 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004656#endif
drh6f25e892011-07-08 17:02:57 +00004657#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004658 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004659 extern int sqlite3_multiple_initialize(const char*,int);
4660 sqlite3_multiplex_initialize(0, 1);
4661#endif
drh7d9f3942013-04-03 01:26:54 +00004662 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004663 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4664 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004665 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004666 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004667 if( pVfs ){
4668 sqlite3_vfs_register(pVfs, 1);
4669 }else{
4670 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4671 exit(1);
4672 }
drh44c2eb12003-04-30 11:38:26 +00004673 }
4674 }
drh98d312f2012-10-25 15:23:14 +00004675 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004676#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004677 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004678 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004679#else
shane86f5bdb2009-10-24 02:00:07 +00004680 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4681 return 1;
drh01b41712005-08-29 23:06:23 +00004682#endif
drh98d312f2012-10-25 15:23:14 +00004683 }
4684 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004685
drh44c2eb12003-04-30 11:38:26 +00004686 /* Go ahead and open the database file if it already exists. If the
4687 ** file does not exist, delay opening it. This prevents empty database
4688 ** files from being created if a user mistypes the database name argument
4689 ** to the sqlite command-line tool.
4690 */
drhc8d74412004-08-31 23:41:26 +00004691 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004692 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004693 }
4694
drh22fbcb82004-02-01 01:22:50 +00004695 /* Process the initialization file if there is one. If no -init option
4696 ** is given on the command line, look for a file named ~/.sqliterc and
4697 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004698 */
drh534f4df2015-02-28 14:03:35 +00004699 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004700
drh22fbcb82004-02-01 01:22:50 +00004701 /* Make a second pass through the command-line argument and set
4702 ** options. This second pass is delayed until after the initialization
4703 ** file is processed so that the command-line arguments will override
4704 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004705 */
drh98d312f2012-10-25 15:23:14 +00004706 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004707 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004708 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004709 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004710 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004711 i++;
4712 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004713 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004714 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004715 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004716 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004717 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004718 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004719 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004720 }else if( strcmp(z,"-csv")==0 ){
4721 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004722 memcpy(data.colSeparator,",",2);
4723 }else if( strcmp(z,"-ascii")==0 ){
4724 data.mode = MODE_Ascii;
4725 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004726 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004727 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004728 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004729 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004730 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4731 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004732 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004733 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004734 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004735 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004736 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004737 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004738 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004739 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004740 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004741 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004742 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004743 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004744 }else if( strcmp(z,"-eqp")==0 ){
4745 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004746 }else if( strcmp(z,"-stats")==0 ){
4747 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004748 }else if( strcmp(z,"-scanstats")==0 ){
4749 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00004750 }else if( strcmp(z,"-backslash")==0 ){
4751 /* Undocumented command-line option: -backslash
4752 ** Causes C-style backslash escapes to be evaluated in SQL statements
4753 ** prior to sending the SQL into SQLite. Useful for injecting
4754 ** crazy bytes in the middle of SQL statements for testing and debugging.
4755 */
4756 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004757 }else if( strcmp(z,"-bail")==0 ){
4758 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004759 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004760 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004761 return 0;
drhc28490c2006-10-26 14:25:58 +00004762 }else if( strcmp(z,"-interactive")==0 ){
4763 stdin_is_interactive = 1;
4764 }else if( strcmp(z,"-batch")==0 ){
4765 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004766 }else if( strcmp(z,"-heap")==0 ){
4767 i++;
drh44dec872014-08-30 15:49:25 +00004768 }else if( strcmp(z,"-scratch")==0 ){
4769 i+=2;
4770 }else if( strcmp(z,"-pagecache")==0 ){
4771 i+=2;
4772 }else if( strcmp(z,"-lookaside")==0 ){
4773 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004774 }else if( strcmp(z,"-mmap")==0 ){
4775 i++;
drha7e61d82011-03-12 17:02:57 +00004776 }else if( strcmp(z,"-vfs")==0 ){
4777 i++;
drh6f25e892011-07-08 17:02:57 +00004778#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004779 }else if( strcmp(z,"-vfstrace")==0 ){
4780 i++;
drh6f25e892011-07-08 17:02:57 +00004781#endif
4782#ifdef SQLITE_ENABLE_MULTIPLEX
4783 }else if( strcmp(z,"-multiplex")==0 ){
4784 i++;
4785#endif
drhcc3b4f82012-02-07 14:13:50 +00004786 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004787 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004788 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004789 /* Run commands that follow -cmd first and separately from commands
4790 ** that simply appear on the command-line. This seems goofy. It would
4791 ** be better if all commands ran in the order that they appear. But
4792 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004793 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004794 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004795 if( z[0]=='.' ){
4796 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004797 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004798 }else{
drh05782482013-10-24 15:20:20 +00004799 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004800 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4801 if( zErrMsg!=0 ){
4802 fprintf(stderr,"Error: %s\n", zErrMsg);
4803 if( bail_on_error ) return rc!=0 ? rc : 1;
4804 }else if( rc!=0 ){
4805 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4806 if( bail_on_error ) return rc;
4807 }
4808 }
drh1e5d0e92000-05-31 23:33:17 +00004809 }else{
shane86f5bdb2009-10-24 02:00:07 +00004810 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004811 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004812 return 1;
4813 }
4814 }
drh44c2eb12003-04-30 11:38:26 +00004815
drhac5649a2014-11-28 13:35:03 +00004816 if( !readStdin ){
4817 /* Run all arguments that do not begin with '-' as if they were separate
4818 ** command-line inputs, except for the argToSkip argument which contains
4819 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004820 */
drhac5649a2014-11-28 13:35:03 +00004821 for(i=0; i<nCmd; i++){
4822 if( azCmd[i][0]=='.' ){
4823 rc = do_meta_command(azCmd[i], &data);
4824 if( rc ) return rc==2 ? 0 : rc;
4825 }else{
4826 open_db(&data, 0);
4827 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4828 if( zErrMsg!=0 ){
4829 fprintf(stderr,"Error: %s\n", zErrMsg);
4830 return rc!=0 ? rc : 1;
4831 }else if( rc!=0 ){
4832 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4833 return rc;
4834 }
drh6ff13852001-11-25 13:18:23 +00004835 }
drh75897232000-05-29 14:26:00 +00004836 }
drhac5649a2014-11-28 13:35:03 +00004837 free(azCmd);
drh75897232000-05-29 14:26:00 +00004838 }else{
drh44c2eb12003-04-30 11:38:26 +00004839 /* Run commands received from standard input
4840 */
drhc28490c2006-10-26 14:25:58 +00004841 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004842 char *zHome;
4843 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004844 int nHistory;
drh75897232000-05-29 14:26:00 +00004845 printf(
drh743e0032011-12-12 16:51:50 +00004846 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004847 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004848 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004849 );
drhb3735912014-02-10 16:13:42 +00004850 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004851 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004852 printBold("transient in-memory database");
4853 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004854 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004855 }
drh67505e72002-04-19 12:34:06 +00004856 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004857 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004858 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004859 if( (zHistory = malloc(nHistory))!=0 ){
4860 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4861 }
drh67505e72002-04-19 12:34:06 +00004862 }
drhf5ed7ad2015-06-15 14:43:25 +00004863 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00004864 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004865 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004866 shell_stifle_history(100);
4867 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004868 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004869 }
drhdaffd0e2001-04-11 14:28:42 +00004870 }else{
drhc28490c2006-10-26 14:25:58 +00004871 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004872 }
4873 }
drh33048c02001-10-01 14:29:22 +00004874 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004875 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004876 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004877 }
drh05782482013-10-24 15:20:20 +00004878 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004879 return rc;
drh75897232000-05-29 14:26:00 +00004880}