blob: e6f592640efdfc2e54829417b0b5d4ad1e102139 [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>
shane18e526c2008-12-10 22:30:24 +0000104#define isatty(h) _isatty(h)
drh07901eb2014-02-28 19:37:45 +0000105#ifndef access
106# define access(f,m) _access((f),(m))
107#endif
drh67ceaa62012-08-27 21:19:03 +0000108#undef popen
drh53371f92013-07-25 17:07:03 +0000109#define popen _popen
drh67ceaa62012-08-27 21:19:03 +0000110#undef pclose
drh12cd6cf2013-06-29 15:40:22 +0000111#define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
drh4328c8b2003-04-26 02:50:11 +0000113/* Make sure isatty() has a prototype.
114*/
drhb2acc3b2011-10-13 16:36:29 +0000115extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000116
drh8cd5b252015-03-02 22:06:43 +0000117#if !defined(__RTP__) && !defined(_WRS_KERNEL)
118 /* popen and pclose are not C89 functions and so are sometimes omitted from
119 ** the <stdio.h> header */
120 extern FILE *popen(const char*,const char*);
121 extern int pclose(FILE*);
122#else
123# define SQLITE_OMIT_POPEN 1
124#endif
125
mistachkinf6418892013-08-28 01:54:12 +0000126#endif
drh53371f92013-07-25 17:07:03 +0000127
chw65d3c132007-11-12 21:09:10 +0000128#if defined(_WIN32_WCE)
129/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
130 * thus we always assume that we have a console. That can be
131 * overridden with the -batch command line option.
132 */
133#define isatty(x) 1
134#endif
135
drhf0693c82011-10-11 20:41:54 +0000136/* ctype macros that work with signed characters */
137#define IsSpace(X) isspace((unsigned char)X)
138#define IsDigit(X) isdigit((unsigned char)X)
139#define ToLower(X) (char)tolower((unsigned char)X)
140
drh047d4532015-01-18 20:30:23 +0000141/* On Windows, we normally run with output mode of TEXT so that \n characters
142** are automatically translated into \r\n. However, this behavior needs
143** to be disabled in some cases (ex: when generating CSV output and when
144** rendering quoted strings that contain \n characters). The following
145** routines take care of that.
146*/
147#if defined(_WIN32) || defined(WIN32)
mistachkine4a0d792015-01-27 21:24:33 +0000148static void setBinaryMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000149 fflush(out);
150 _setmode(_fileno(out), _O_BINARY);
151}
mistachkine4a0d792015-01-27 21:24:33 +0000152static void setTextMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000153 fflush(out);
154 _setmode(_fileno(out), _O_TEXT);
155}
156#else
157# define setBinaryMode(X)
158# define setTextMode(X)
159#endif
160
drh43408312013-10-30 12:43:36 +0000161
162/* True if the timer is enabled */
163static int enableTimer = 0;
164
165/* Return the current wall-clock time */
166static sqlite3_int64 timeOfDay(void){
167 static sqlite3_vfs *clockVfs = 0;
168 sqlite3_int64 t;
169 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
170 if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
171 clockVfs->xCurrentTimeInt64(clockVfs, &t);
172 }else{
173 double r;
174 clockVfs->xCurrentTime(clockVfs, &r);
175 t = (sqlite3_int64)(r*86400000.0);
176 }
177 return t;
178}
179
drh91eb93c2015-03-03 19:56:20 +0000180#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000181#include <sys/time.h>
182#include <sys/resource.h>
183
drh91eb93c2015-03-03 19:56:20 +0000184/* VxWorks does not support getrusage() as far as we can determine */
185#if defined(_WRS_KERNEL) || defined(__RTP__)
186struct rusage {
187 struct timeval ru_utime; /* user CPU time used */
188 struct timeval ru_stime; /* system CPU time used */
189};
190#define getrusage(A,B) memset(B,0,sizeof(*B))
191#endif
192
drhda108222009-02-25 19:07:24 +0000193/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000194static struct rusage sBegin; /* CPU time at start */
195static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000196
drhda108222009-02-25 19:07:24 +0000197/*
198** Begin timing an operation
199*/
200static void beginTimer(void){
201 if( enableTimer ){
202 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000203 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000204 }
205}
206
207/* Return the difference of two time_structs in seconds */
208static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
209 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
210 (double)(pEnd->tv_sec - pStart->tv_sec);
211}
212
213/*
214** Print the timing results.
215*/
216static void endTimer(void){
217 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000218 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000219 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000220 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000221 printf("Run Time: real %.3f user %f sys %f\n",
222 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000223 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
224 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
225 }
226}
shaneb320ccd2009-10-21 03:42:58 +0000227
drhda108222009-02-25 19:07:24 +0000228#define BEGIN_TIMER beginTimer()
229#define END_TIMER endTimer()
230#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000231
232#elif (defined(_WIN32) || defined(WIN32))
233
234#include <windows.h>
235
236/* Saved resource information for the beginning of an operation */
237static HANDLE hProcess;
238static FILETIME ftKernelBegin;
239static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000240static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000241typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
242 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000243static GETPROCTIMES getProcessTimesAddr = NULL;
244
shaneb320ccd2009-10-21 03:42:58 +0000245/*
246** Check to see if we have timer support. Return 1 if necessary
247** support found (or found previously).
248*/
249static int hasTimer(void){
250 if( getProcessTimesAddr ){
251 return 1;
252 } else {
drh4ace5362014-11-10 14:42:28 +0000253 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
254 ** versions. See if the version we are running on has it, and if it
255 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000256 */
257 hProcess = GetCurrentProcess();
258 if( hProcess ){
259 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
260 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000261 getProcessTimesAddr =
262 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000263 if( NULL != getProcessTimesAddr ){
264 return 1;
265 }
266 FreeLibrary(hinstLib);
267 }
268 }
269 }
270 return 0;
271}
272
273/*
274** Begin timing an operation
275*/
276static void beginTimer(void){
277 if( enableTimer && getProcessTimesAddr ){
278 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000279 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
280 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000281 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000282 }
283}
284
285/* Return the difference of two FILETIME structs in seconds */
286static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
287 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
288 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
289 return (double) ((i64End - i64Start) / 10000000.0);
290}
291
292/*
293** Print the timing results.
294*/
295static void endTimer(void){
296 if( enableTimer && getProcessTimesAddr){
297 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000298 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000299 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000300 printf("Run Time: real %.3f user %f sys %f\n",
301 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000302 timeDiff(&ftUserBegin, &ftUserEnd),
303 timeDiff(&ftKernelBegin, &ftKernelEnd));
304 }
305}
306
307#define BEGIN_TIMER beginTimer()
308#define END_TIMER endTimer()
309#define HAS_TIMER hasTimer()
310
drhda108222009-02-25 19:07:24 +0000311#else
312#define BEGIN_TIMER
313#define END_TIMER
314#define HAS_TIMER 0
315#endif
316
shanec0688ea2009-03-05 03:48:06 +0000317/*
318** Used to prevent warnings about unused parameters
319*/
320#define UNUSED_PARAMETER(x) (void)(x)
321
drhe91d16b2008-12-08 18:27:31 +0000322/*
drhc49f44e2006-10-26 18:15:42 +0000323** If the following flag is set, then command execution stops
324** at an error if we are not interactive.
325*/
326static int bail_on_error = 0;
327
328/*
drhc28490c2006-10-26 14:25:58 +0000329** Threat stdin as an interactive input if the following variable
330** is true. Otherwise, assume stdin is connected to a file or pipe.
331*/
332static int stdin_is_interactive = 1;
333
334/*
drh4c504392000-10-16 22:06:40 +0000335** The following is the open SQLite database. We make a pointer
336** to this database a static variable so that it can be accessed
337** by the SIGINT handler to interrupt database processing.
338*/
danielk197792f9a1b2004-06-19 09:08:16 +0000339static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000340
341/*
drh67505e72002-04-19 12:34:06 +0000342** True if an interrupt (Control-C) has been received.
343*/
drh43617e92006-03-06 20:55:46 +0000344static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000345
346/*
persicom7e2dfdd2002-04-18 02:46:52 +0000347** This is the name of our program. It is set in main(), used
348** in a number of other places, mostly for error messages.
349*/
350static char *Argv0;
351
352/*
353** Prompt strings. Initialized in main. Settable with
354** .prompt main continue
355*/
356static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
357static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
358
drhb0603412007-02-28 04:47:26 +0000359/*
360** Write I/O traces to the following stream.
361*/
rsebe0a9092007-07-30 18:24:38 +0000362#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000363static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000364#endif
drhb0603412007-02-28 04:47:26 +0000365
366/*
367** This routine works like printf in that its first argument is a
368** format string and subsequent arguments are values to be substituted
369** in place of % fields. The result of formatting this string
370** is written to iotrace.
371*/
rsebe0a9092007-07-30 18:24:38 +0000372#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000373static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000374 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000375 char *z;
drhb0603412007-02-28 04:47:26 +0000376 if( iotrace==0 ) return;
377 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000378 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000379 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000380 fprintf(iotrace, "%s", z);
381 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000382}
rsebe0a9092007-07-30 18:24:38 +0000383#endif
drhb0603412007-02-28 04:47:26 +0000384
drh44c2eb12003-04-30 11:38:26 +0000385
persicom7e2dfdd2002-04-18 02:46:52 +0000386/*
drh83965662003-04-17 02:54:13 +0000387** Determines if a string is a number of not.
388*/
danielk19772e588c72005-12-09 14:25:08 +0000389static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000390 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000391 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000392 return 0;
393 }
394 z++;
395 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000396 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000397 if( *z=='.' ){
398 z++;
drhf0693c82011-10-11 20:41:54 +0000399 if( !IsDigit(*z) ) return 0;
400 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000401 if( realnum ) *realnum = 1;
402 }
403 if( *z=='e' || *z=='E' ){
404 z++;
405 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000406 if( !IsDigit(*z) ) return 0;
407 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000408 if( realnum ) *realnum = 1;
409 }
410 return *z==0;
411}
drh83965662003-04-17 02:54:13 +0000412
413/*
danielk1977bc6ada42004-06-30 08:20:16 +0000414** A global char* and an SQL function to access its current value
415** from within an SQL statement. This program used to use the
416** sqlite_exec_printf() API to substitue a string into an SQL statement.
417** The correct way to do this with sqlite3 is to use the bind API, but
418** since the shell is built around the callback paradigm it would be a lot
419** of work. Instead just use this hack, which is quite harmless.
420*/
421static const char *zShellStatic = 0;
422static void shellstaticFunc(
423 sqlite3_context *context,
424 int argc,
425 sqlite3_value **argv
426){
427 assert( 0==argc );
428 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000429 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000430 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000431 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
432}
433
434
435/*
drhfeac5f82004-08-01 00:10:45 +0000436** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000437** the text in memory obtained from malloc() and returns a pointer
438** to the text. NULL is returned at end of file, or if malloc()
439** fails.
440**
drh9f099fd2013-08-06 14:01:46 +0000441** If zLine is not NULL then it is a malloced buffer returned from
442** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000443*/
drh9f099fd2013-08-06 14:01:46 +0000444static char *local_getline(char *zLine, FILE *in){
445 int nLine = zLine==0 ? 0 : 100;
446 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000447
drhb07028f2011-10-14 21:49:18 +0000448 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000449 if( n+100>nLine ){
450 nLine = nLine*2 + 100;
451 zLine = realloc(zLine, nLine);
452 if( zLine==0 ) return 0;
453 }
drhdaffd0e2001-04-11 14:28:42 +0000454 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000455 if( n==0 ){
456 free(zLine);
457 return 0;
458 }
459 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000460 break;
461 }
drh9f099fd2013-08-06 14:01:46 +0000462 while( zLine[n] ) n++;
463 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000464 n--;
shaneh13b36022009-12-17 21:07:15 +0000465 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000466 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000467 break;
drh8e7e7a22000-05-30 18:45:23 +0000468 }
469 }
drh8e7e7a22000-05-30 18:45:23 +0000470 return zLine;
471}
472
473/*
drhc28490c2006-10-26 14:25:58 +0000474** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000475**
drh9f099fd2013-08-06 14:01:46 +0000476** If in==0 then read from standard input and prompt before each line.
477** If isContinuation is true, then a continuation prompt is appropriate.
478** If isContinuation is zero, then the main prompt should be used.
479**
480** If zPrior is not NULL then it is a buffer from a prior call to this
481** routine that can be reused.
482**
483** The result is stored in space obtained from malloc() and must either
484** be freed by the caller or else passed back into this routine via the
485** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000486*/
drh9f099fd2013-08-06 14:01:46 +0000487static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000488 char *zPrompt;
489 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000490 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000491 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000492 }else{
drh9f099fd2013-08-06 14:01:46 +0000493 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000494#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000495 printf("%s", zPrompt);
496 fflush(stdout);
497 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000498#else
499 free(zPrior);
500 zResult = shell_readline(zPrompt);
501 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000502#endif
drh9f099fd2013-08-06 14:01:46 +0000503 }
drh8e7e7a22000-05-30 18:45:23 +0000504 return zResult;
505}
506
drhe6229612014-08-18 15:08:26 +0000507#if defined(SQLITE_ENABLE_SESSION)
508/*
509** State information for a single open session
510*/
511typedef struct OpenSession OpenSession;
512struct OpenSession {
513 char *zName; /* Symbolic name for this session */
514 int nFilter; /* Number of xFilter rejection GLOB patterns */
515 char **azFilter; /* Array of xFilter rejection GLOB patterns */
516 sqlite3_session *p; /* The open session */
517};
518#endif
519
drhdcd87a92014-08-18 13:45:42 +0000520/*
521** Shell output mode information from before ".explain on",
522** saved so that it can be restored by ".explain off"
523*/
524typedef struct SavedModeInfo SavedModeInfo;
525struct SavedModeInfo {
526 int valid; /* Is there legit data in here? */
527 int mode; /* Mode prior to ".explain on" */
528 int showHeader; /* The ".header" setting prior to ".explain on" */
529 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000530};
drh45e29d82006-11-20 16:21:10 +0000531
drh8e7e7a22000-05-30 18:45:23 +0000532/*
drhdcd87a92014-08-18 13:45:42 +0000533** State information about the database connection is contained in an
534** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000535*/
drhdcd87a92014-08-18 13:45:42 +0000536typedef struct ShellState ShellState;
537struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000538 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000539 int echoOn; /* True to echo input commands */
drhc2ce0be2014-05-29 12:36:14 +0000540 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000541 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000542 int scanstatsOn; /* True to display scan stats before each finalize */
drhc2ce0be2014-05-29 12:36:14 +0000543 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000544 int cnt; /* Number of records displayed so far */
545 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000546 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000547 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000548 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000549 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000550 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000551 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000552 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000553 char colSeparator[20]; /* Column separator character for several modes */
554 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000555 int colWidth[100]; /* Requested width of each column when in column mode*/
556 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000557 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000558 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000559 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000560 char outfile[FILENAME_MAX]; /* Filename for *out */
561 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000562 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000563 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000564 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000565 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000566 int *aiIndent; /* Array of indents used in MODE_Explain */
567 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000568 int iIndent; /* Index of current op in aiIndent[] */
drhe6229612014-08-18 15:08:26 +0000569#if defined(SQLITE_ENABLE_SESSION)
570 int nSession; /* Number of active sessions */
571 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
572#endif
drh75897232000-05-29 14:26:00 +0000573};
574
575/*
drh44dec872014-08-30 15:49:25 +0000576** These are the allowed shellFlgs values
577*/
578#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
579#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
580#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
581
582/*
drh75897232000-05-29 14:26:00 +0000583** These are the allowed modes.
584*/
drh967e8b72000-06-21 13:59:10 +0000585#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000586#define MODE_Column 1 /* One record per line in neat columns */
587#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000588#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
589#define MODE_Html 4 /* Generate an XHTML table */
590#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000591#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000592#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000593#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000594#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000595
drh66ce4d02008-02-15 17:38:06 +0000596static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000597 "line",
598 "column",
599 "list",
600 "semi",
601 "html",
drhfeac5f82004-08-01 00:10:45 +0000602 "insert",
603 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000604 "csv",
drh66ce4d02008-02-15 17:38:06 +0000605 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000606 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000607};
drh75897232000-05-29 14:26:00 +0000608
609/*
mistachkinfad42082014-07-24 22:13:12 +0000610** These are the column/row/line separators used by the various
611** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000612*/
mistachkinfad42082014-07-24 22:13:12 +0000613#define SEP_Column "|"
614#define SEP_Row "\n"
615#define SEP_Tab "\t"
616#define SEP_Space " "
617#define SEP_Comma ","
618#define SEP_CrLf "\r\n"
619#define SEP_Unit "\x1F"
620#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000621
622/*
drh75897232000-05-29 14:26:00 +0000623** Number of elements in an array
624*/
drh902b9ee2008-12-05 17:17:07 +0000625#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000626
627/*
drhea678832008-12-10 19:26:22 +0000628** Compute a string length that is limited to what can be stored in
629** lower 30 bits of a 32-bit signed integer.
630*/
drh4f21c4a2008-12-10 22:15:00 +0000631static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000632 const char *z2 = z;
633 while( *z2 ){ z2++; }
634 return 0x3fffffff & (int)(z2 - z);
635}
636
637/*
drh127f9d72010-02-23 01:47:00 +0000638** A callback for the sqlite3_log() interface.
639*/
640static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000641 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000642 if( p->pLog==0 ) return;
643 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
644 fflush(p->pLog);
645}
646
647/*
shane626a6e42009-10-22 17:30:15 +0000648** Output the given string as a hex-encoded blob (eg. X'1234' )
649*/
650static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
651 int i;
652 char *zBlob = (char *)pBlob;
653 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000654 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000655 fprintf(out,"'");
656}
657
658/*
drh28bd4bc2000-06-15 15:57:22 +0000659** Output the given string as a quoted string using SQL quoting conventions.
660*/
661static void output_quoted_string(FILE *out, const char *z){
662 int i;
663 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000664 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000665 for(i=0; z[i]; i++){
666 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000667 }
668 if( nSingle==0 ){
669 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000670 }else{
671 fprintf(out,"'");
672 while( *z ){
673 for(i=0; z[i] && z[i]!='\''; i++){}
674 if( i==0 ){
675 fprintf(out,"''");
676 z++;
677 }else if( z[i]=='\'' ){
678 fprintf(out,"%.*s''",i,z);
679 z += i+1;
680 }else{
drhcd7d2732002-02-26 23:24:26 +0000681 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000682 break;
683 }
684 }
drhcd7d2732002-02-26 23:24:26 +0000685 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000686 }
drh047d4532015-01-18 20:30:23 +0000687 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000688}
689
690/*
drhfeac5f82004-08-01 00:10:45 +0000691** Output the given string as a quoted according to C or TCL quoting rules.
692*/
693static void output_c_string(FILE *out, const char *z){
694 unsigned int c;
695 fputc('"', out);
696 while( (c = *(z++))!=0 ){
697 if( c=='\\' ){
698 fputc(c, out);
699 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000700 }else if( c=='"' ){
701 fputc('\\', out);
702 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000703 }else if( c=='\t' ){
704 fputc('\\', out);
705 fputc('t', out);
706 }else if( c=='\n' ){
707 fputc('\\', out);
708 fputc('n', out);
709 }else if( c=='\r' ){
710 fputc('\\', out);
711 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000712 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000713 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000714 }else{
715 fputc(c, out);
716 }
717 }
718 fputc('"', out);
719}
720
721/*
drhc08a4f12000-06-15 16:49:48 +0000722** Output the given string with characters that are special to
723** HTML escaped.
724*/
725static void output_html_string(FILE *out, const char *z){
726 int i;
drhc3d6ba42014-01-13 20:38:35 +0000727 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000728 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000729 for(i=0; z[i]
730 && z[i]!='<'
731 && z[i]!='&'
732 && z[i]!='>'
733 && z[i]!='\"'
734 && z[i]!='\'';
735 i++){}
drhc08a4f12000-06-15 16:49:48 +0000736 if( i>0 ){
737 fprintf(out,"%.*s",i,z);
738 }
739 if( z[i]=='<' ){
740 fprintf(out,"&lt;");
741 }else if( z[i]=='&' ){
742 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000743 }else if( z[i]=='>' ){
744 fprintf(out,"&gt;");
745 }else if( z[i]=='\"' ){
746 fprintf(out,"&quot;");
747 }else if( z[i]=='\'' ){
748 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000749 }else{
750 break;
751 }
752 z += i + 1;
753 }
754}
755
756/*
drhc49f44e2006-10-26 18:15:42 +0000757** If a field contains any character identified by a 1 in the following
758** array, then the string must be quoted for CSV.
759*/
760static const char needCsvQuote[] = {
761 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
762 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
763 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
764 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
765 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
766 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
767 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
768 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
769 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
770 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
771 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
772 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
773 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
774 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
775 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
776 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
777};
778
779/*
mistachkindd11f2d2014-12-11 04:49:46 +0000780** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000781** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000782** the null value. Strings are quoted if necessary. The separator
783** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000784*/
drhdcd87a92014-08-18 13:45:42 +0000785static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000786 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000787 if( z==0 ){
mistachkin44b99f72014-12-11 03:29:14 +0000788 fprintf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000789 }else{
drhc49f44e2006-10-26 18:15:42 +0000790 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000791 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000792 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000793 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000794 || (z[i]==p->colSeparator[0] &&
795 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000796 i = 0;
797 break;
798 }
799 }
800 if( i==0 ){
801 putc('"', out);
802 for(i=0; z[i]; i++){
803 if( z[i]=='"' ) putc('"', out);
804 putc(z[i], out);
805 }
806 putc('"', out);
807 }else{
808 fprintf(out, "%s", z);
809 }
drh8e64d1c2004-10-07 00:32:39 +0000810 }
811 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000812 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000813 }
814}
815
danielk19774af00c62005-01-23 23:43:21 +0000816#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000817/*
drh4c504392000-10-16 22:06:40 +0000818** This routine runs when the user presses Ctrl-C
819*/
820static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000821 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000822 seenInterrupt++;
823 if( seenInterrupt>2 ) exit(1);
danielk19776f8a5032004-05-10 10:34:51 +0000824 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000825}
danielk19774af00c62005-01-23 23:43:21 +0000826#endif
drh4c504392000-10-16 22:06:40 +0000827
828/*
shane626a6e42009-10-22 17:30:15 +0000829** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000830** invokes for each row of a query result.
831*/
drh4ace5362014-11-10 14:42:28 +0000832static int shell_callback(
833 void *pArg,
834 int nArg, /* Number of result columns */
835 char **azArg, /* Text of each result column */
836 char **azCol, /* Column names */
837 int *aiType /* Column types */
838){
drh75897232000-05-29 14:26:00 +0000839 int i;
drhdcd87a92014-08-18 13:45:42 +0000840 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000841
drh75897232000-05-29 14:26:00 +0000842 switch( p->mode ){
843 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000844 int w = 5;
drh6a535342001-10-19 16:44:56 +0000845 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000846 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000847 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000848 if( len>w ) w = len;
849 }
mistachkin636bf9f2014-07-19 20:15:16 +0000850 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000851 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000852 fprintf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000853 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000854 }
855 break;
856 }
danielk19770d78bae2008-01-03 07:09:48 +0000857 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000858 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000859 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000860 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000861 int w, n;
862 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000863 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000864 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000865 w = 0;
drh75897232000-05-29 14:26:00 +0000866 }
drh078b1fd2012-09-21 13:40:02 +0000867 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000868 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000869 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000870 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000871 if( w<n ) w = n;
872 }
873 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000874 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000875 }
876 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000877 if( w<0 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000878 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
879 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000880 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000881 fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
882 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000883 }
drha0c66f52000-07-29 13:20:21 +0000884 }
885 }
886 if( p->showHeader ){
887 for(i=0; i<nArg; i++){
888 int w;
889 if( i<ArraySize(p->actualWidth) ){
890 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000891 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000892 }else{
893 w = 10;
894 }
895 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
896 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000897 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000898 }
drh75897232000-05-29 14:26:00 +0000899 }
900 }
drh6a535342001-10-19 16:44:56 +0000901 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000902 for(i=0; i<nArg; i++){
903 int w;
drha0c66f52000-07-29 13:20:21 +0000904 if( i<ArraySize(p->actualWidth) ){
905 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000906 }else{
907 w = 10;
908 }
dana98bf362013-11-13 18:35:01 +0000909 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000910 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000911 }
dana98bf362013-11-13 18:35:01 +0000912 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000913 if( p->iIndent<p->nIndent ){
914 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000915 }
danc4650bb2013-11-18 08:41:06 +0000916 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000917 }
drh078b1fd2012-09-21 13:40:02 +0000918 if( w<0 ){
919 fprintf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000920 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000921 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000922 }else{
923 fprintf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000924 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000925 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000926 }
drh75897232000-05-29 14:26:00 +0000927 }
928 break;
929 }
drhe3710332000-09-29 13:30:53 +0000930 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000931 case MODE_List: {
932 if( p->cnt++==0 && p->showHeader ){
933 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000934 fprintf(p->out,"%s%s",azCol[i],
935 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000936 }
937 }
drh6a535342001-10-19 16:44:56 +0000938 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000939 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000940 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +0000941 if( z==0 ) z = p->nullValue;
drh71172c52002-01-24 00:00:21 +0000942 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000943 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000944 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000945 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000946 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000947 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000948 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000949 }
drh75897232000-05-29 14:26:00 +0000950 }
951 break;
952 }
drh1e5d0e92000-05-31 23:33:17 +0000953 case MODE_Html: {
954 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000955 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000956 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000957 fprintf(p->out,"<TH>");
958 output_html_string(p->out, azCol[i]);
959 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000960 }
mihailim57c591a2008-06-23 21:26:05 +0000961 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000962 }
drh6a535342001-10-19 16:44:56 +0000963 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000964 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000965 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000966 fprintf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +0000967 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mihailim57c591a2008-06-23 21:26:05 +0000968 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000969 }
mihailim57c591a2008-06-23 21:26:05 +0000970 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000971 break;
972 }
drhfeac5f82004-08-01 00:10:45 +0000973 case MODE_Tcl: {
974 if( p->cnt++==0 && p->showHeader ){
975 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000976 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000977 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000978 }
mistachkin636bf9f2014-07-19 20:15:16 +0000979 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000980 }
981 if( azArg==0 ) break;
982 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +0000983 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000984 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000985 }
mistachkin636bf9f2014-07-19 20:15:16 +0000986 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000987 break;
988 }
drh8e64d1c2004-10-07 00:32:39 +0000989 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +0000990 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000991 if( p->cnt++==0 && p->showHeader ){
992 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000993 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000994 }
mistachkine0d68852014-12-11 03:12:33 +0000995 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000996 }
drh40253262014-10-17 21:35:05 +0000997 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000998 for(i=0; i<nArg; i++){
999 output_csv(p, azArg[i], i<nArg-1);
1000 }
mistachkine0d68852014-12-11 03:12:33 +00001001 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001002 }
drh047d4532015-01-18 20:30:23 +00001003 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +00001004 break;
1005 }
drh28bd4bc2000-06-15 15:57:22 +00001006 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001007 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001008 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +00001009 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +00001010 for(i=0; i<nArg; i++){
1011 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001012 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +00001013 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001014 }else if( aiType && aiType[i]==SQLITE_TEXT ){
1015 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1016 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001017 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1018 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +00001019 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001020 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1021 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1022 int nBlob = sqlite3_column_bytes(p->pStmt, i);
1023 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1024 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001025 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001026 fprintf(p->out,"%s%s",zSep, azArg[i]);
1027 }else{
1028 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1029 output_quoted_string(p->out, azArg[i]);
1030 }
1031 }
1032 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001033 break;
drh28bd4bc2000-06-15 15:57:22 +00001034 }
mistachkin636bf9f2014-07-19 20:15:16 +00001035 case MODE_Ascii: {
1036 if( p->cnt++==0 && p->showHeader ){
1037 for(i=0; i<nArg; i++){
1038 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
1039 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
1040 }
1041 fprintf(p->out, "%s", p->rowSeparator);
1042 }
1043 if( azArg==0 ) break;
1044 for(i=0; i<nArg; i++){
1045 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
mistachkin44b99f72014-12-11 03:29:14 +00001046 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001047 }
1048 fprintf(p->out, "%s", p->rowSeparator);
1049 break;
1050 }
persicom1d0b8722002-04-18 02:53:04 +00001051 }
drh75897232000-05-29 14:26:00 +00001052 return 0;
1053}
1054
1055/*
shane626a6e42009-10-22 17:30:15 +00001056** This is the callback routine that the SQLite library
1057** invokes for each row of a query result.
1058*/
1059static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1060 /* since we don't have type info, call the shell_callback with a NULL value */
1061 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1062}
1063
1064/*
drhdcd87a92014-08-18 13:45:42 +00001065** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001066** the name of the table given. Escape any quote characters in the
1067** table name.
1068*/
drhdcd87a92014-08-18 13:45:42 +00001069static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001070 int i, n;
1071 int needQuote;
1072 char *z;
1073
1074 if( p->zDestTable ){
1075 free(p->zDestTable);
1076 p->zDestTable = 0;
1077 }
1078 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001079 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001080 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001081 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001082 needQuote = 1;
1083 if( zName[i]=='\'' ) n++;
1084 }
1085 }
1086 if( needQuote ) n += 2;
1087 z = p->zDestTable = malloc( n+1 );
1088 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001089 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001090 exit(1);
1091 }
1092 n = 0;
1093 if( needQuote ) z[n++] = '\'';
1094 for(i=0; zName[i]; i++){
1095 z[n++] = zName[i];
1096 if( zName[i]=='\'' ) z[n++] = '\'';
1097 }
1098 if( needQuote ) z[n++] = '\'';
1099 z[n] = 0;
1100}
1101
danielk19772a02e332004-06-05 08:04:36 +00001102/* zIn is either a pointer to a NULL-terminated string in memory obtained
1103** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1104** added to zIn, and the result returned in memory obtained from malloc().
1105** zIn, if it was not NULL, is freed.
1106**
1107** If the third argument, quote, is not '\0', then it is used as a
1108** quote character for zAppend.
1109*/
drhc28490c2006-10-26 14:25:58 +00001110static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001111 int len;
1112 int i;
drh4f21c4a2008-12-10 22:15:00 +00001113 int nAppend = strlen30(zAppend);
1114 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001115
1116 len = nAppend+nIn+1;
1117 if( quote ){
1118 len += 2;
1119 for(i=0; i<nAppend; i++){
1120 if( zAppend[i]==quote ) len++;
1121 }
1122 }
1123
1124 zIn = (char *)realloc(zIn, len);
1125 if( !zIn ){
1126 return 0;
1127 }
1128
1129 if( quote ){
1130 char *zCsr = &zIn[nIn];
1131 *zCsr++ = quote;
1132 for(i=0; i<nAppend; i++){
1133 *zCsr++ = zAppend[i];
1134 if( zAppend[i]==quote ) *zCsr++ = quote;
1135 }
1136 *zCsr++ = quote;
1137 *zCsr++ = '\0';
1138 assert( (zCsr-zIn)==len );
1139 }else{
1140 memcpy(&zIn[nIn], zAppend, nAppend);
1141 zIn[len-1] = '\0';
1142 }
1143
1144 return zIn;
1145}
1146
drhdd3d4592004-08-30 01:54:05 +00001147
1148/*
drhb21a8e42012-01-28 21:08:51 +00001149** Execute a query statement that will generate SQL output. Print
1150** the result columns, comma-separated, on a line and then add a
1151** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001152**
drhb21a8e42012-01-28 21:08:51 +00001153** If the number of columns is 1 and that column contains text "--"
1154** then write the semicolon on a separate line. That way, if a
1155** "--" comment occurs at the end of the statement, the comment
1156** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001157*/
drh157e29a2009-05-21 15:15:00 +00001158static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001159 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001160 const char *zSelect, /* SELECT statement to extract content */
1161 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001162){
drhdd3d4592004-08-30 01:54:05 +00001163 sqlite3_stmt *pSelect;
1164 int rc;
drhb21a8e42012-01-28 21:08:51 +00001165 int nResult;
1166 int i;
1167 const char *z;
drhc7181902014-02-27 15:04:13 +00001168 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001169 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001170 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001171 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001172 return rc;
1173 }
1174 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001175 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001176 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001177 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001178 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001179 zFirstRow = 0;
1180 }
drhb21a8e42012-01-28 21:08:51 +00001181 z = (const char*)sqlite3_column_text(pSelect, 0);
1182 fprintf(p->out, "%s", z);
1183 for(i=1; i<nResult; i++){
1184 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1185 }
1186 if( z==0 ) z = "";
1187 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1188 if( z[0] ){
1189 fprintf(p->out, "\n;\n");
1190 }else{
1191 fprintf(p->out, ";\n");
1192 }
drhdd3d4592004-08-30 01:54:05 +00001193 rc = sqlite3_step(pSelect);
1194 }
drh2f464a02011-10-13 00:41:49 +00001195 rc = sqlite3_finalize(pSelect);
1196 if( rc!=SQLITE_OK ){
1197 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001198 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001199 }
1200 return rc;
drhdd3d4592004-08-30 01:54:05 +00001201}
1202
shane626a6e42009-10-22 17:30:15 +00001203/*
1204** Allocate space and save off current error string.
1205*/
1206static char *save_err_msg(
1207 sqlite3 *db /* Database to query */
1208){
1209 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1210 char *zErrMsg = sqlite3_malloc(nErrMsg);
1211 if( zErrMsg ){
1212 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1213 }
1214 return zErrMsg;
1215}
1216
1217/*
shaneh642d8b82010-07-28 16:05:34 +00001218** Display memory stats.
1219*/
1220static int display_stats(
1221 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001222 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001223 int bReset /* True to reset the stats */
1224){
1225 int iCur;
1226 int iHiwtr;
1227
1228 if( pArg && pArg->out ){
1229
1230 iHiwtr = iCur = -1;
1231 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001232 fprintf(pArg->out,
1233 "Memory Used: %d (max %d) bytes\n",
1234 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001235 iHiwtr = iCur = -1;
1236 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001237 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1238 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001239 if( pArg->shellFlgs & SHFLG_Pagecache ){
1240 iHiwtr = iCur = -1;
1241 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001242 fprintf(pArg->out,
1243 "Number of Pcache Pages Used: %d (max %d) pages\n",
1244 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001245 }
shaneh642d8b82010-07-28 16:05:34 +00001246 iHiwtr = iCur = -1;
1247 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001248 fprintf(pArg->out,
1249 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1250 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001251 if( pArg->shellFlgs & SHFLG_Scratch ){
1252 iHiwtr = iCur = -1;
1253 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001254 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1255 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001256 }
shaneh642d8b82010-07-28 16:05:34 +00001257 iHiwtr = iCur = -1;
1258 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001259 fprintf(pArg->out,
1260 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1261 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001262 iHiwtr = iCur = -1;
1263 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001264 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1265 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001266 iHiwtr = iCur = -1;
1267 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001268 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1269 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001270 iHiwtr = iCur = -1;
1271 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001272 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1273 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001274#ifdef YYTRACKMAXSTACKDEPTH
1275 iHiwtr = iCur = -1;
1276 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001277 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1278 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001279#endif
1280 }
1281
1282 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001283 if( pArg->shellFlgs & SHFLG_Lookaside ){
1284 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001285 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1286 &iCur, &iHiwtr, bReset);
1287 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1288 iCur, iHiwtr);
1289 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1290 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001291 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001292 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1293 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001294 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001295 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1296 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001297 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1298 }
shaneh642d8b82010-07-28 16:05:34 +00001299 iHiwtr = iCur = -1;
1300 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001301 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1302 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001303 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1304 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1305 iHiwtr = iCur = -1;
1306 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1307 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001308 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001309 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1310 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1311 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001312 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001313 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001314 iHiwtr = iCur = -1;
1315 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001316 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001317 }
1318
1319 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001320 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1321 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001322 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1323 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1324 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001325 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001326 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001327 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1328 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001329 }
1330
1331 return 0;
1332}
1333
1334/*
dan8d1edb92014-11-05 09:07:28 +00001335** Display scan stats.
1336*/
1337static void display_scanstats(
1338 sqlite3 *db, /* Database to query */
1339 ShellState *pArg /* Pointer to ShellState */
1340){
1341#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
drh15f23c22014-11-06 12:46:16 +00001342 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001343 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001344 mx = 0;
1345 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001346 double rEstLoop = 1.0;
1347 for(i=n=0; 1; i++){
1348 sqlite3_stmt *p = pArg->pStmt;
1349 sqlite3_int64 nLoop, nVisit;
1350 double rEst;
1351 int iSid;
1352 const char *zExplain;
1353 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1354 break;
1355 }
1356 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001357 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001358 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001359 if( n==0 ){
1360 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001361 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001362 }
drh42f30bc2014-11-06 12:08:21 +00001363 n++;
1364 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1365 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1366 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1367 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1368 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001369 fprintf(pArg->out,
1370 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001371 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001372 );
dan8d1edb92014-11-05 09:07:28 +00001373 }
dan8d1edb92014-11-05 09:07:28 +00001374 }
dan8d1edb92014-11-05 09:07:28 +00001375 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001376#endif
dan8d1edb92014-11-05 09:07:28 +00001377}
1378
1379/*
dana98bf362013-11-13 18:35:01 +00001380** Parameter azArray points to a zero-terminated array of strings. zStr
1381** points to a single nul-terminated string. Return non-zero if zStr
1382** is equal, according to strcmp(), to any of the strings in the array.
1383** Otherwise, return zero.
1384*/
1385static int str_in_array(const char *zStr, const char **azArray){
1386 int i;
1387 for(i=0; azArray[i]; i++){
1388 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1389 }
1390 return 0;
1391}
1392
1393/*
1394** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001395** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001396** spaces each opcode should be indented before it is output.
1397**
1398** The indenting rules are:
1399**
1400** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1401** all opcodes that occur between the p2 jump destination and the opcode
1402** itself by 2 spaces.
1403**
drh01752bc2013-11-14 23:59:33 +00001404** * For each "Goto", if the jump destination is earlier in the program
1405** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001406** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001407** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001408** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001409** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001410*/
drhdcd87a92014-08-18 13:45:42 +00001411static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001412 const char *zSql; /* The text of the SQL statement */
1413 const char *z; /* Used to check if this is an EXPLAIN */
1414 int *abYield = 0; /* True if op is an OP_Yield */
1415 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001416 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001417
drh8ad0de32014-03-20 18:45:27 +00001418 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1419 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001420 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1421 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001422 const char *azGoto[] = { "Goto", 0 };
1423
1424 /* Try to figure out if this is really an EXPLAIN statement. If this
1425 ** cannot be verified, return early. */
1426 zSql = sqlite3_sql(pSql);
1427 if( zSql==0 ) return;
1428 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1429 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1430
1431 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1432 int i;
danc4650bb2013-11-18 08:41:06 +00001433 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001434 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001435
1436 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1437 ** p2 is an instruction address, set variable p2op to the index of that
1438 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1439 ** the current instruction is part of a sub-program generated by an
1440 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001441 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001442 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001443
1444 /* Grow the p->aiIndent array as required */
1445 if( iOp>=nAlloc ){
1446 nAlloc += 100;
1447 p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
1448 abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
1449 }
1450 abYield[iOp] = str_in_array(zOp, azYield);
1451 p->aiIndent[iOp] = 0;
1452 p->nIndent = iOp+1;
1453
1454 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001455 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001456 }
drhfe705102014-03-06 13:38:37 +00001457 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1458 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1459 ){
drhe73f0592014-01-21 22:25:45 +00001460 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001461 }
1462 }
1463
danc4650bb2013-11-18 08:41:06 +00001464 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001465 sqlite3_free(abYield);
1466 sqlite3_reset(pSql);
1467}
1468
1469/*
1470** Free the array allocated by explain_data_prepare().
1471*/
drhdcd87a92014-08-18 13:45:42 +00001472static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001473 sqlite3_free(p->aiIndent);
1474 p->aiIndent = 0;
1475 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001476 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001477}
1478
1479/*
shane626a6e42009-10-22 17:30:15 +00001480** Execute a statement or set of statements. Print
1481** any result rows/columns depending on the current mode
1482** set via the supplied callback.
1483**
1484** This is very similar to SQLite's built-in sqlite3_exec()
1485** function except it takes a slightly different callback
1486** and callback data argument.
1487*/
1488static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001489 sqlite3 *db, /* An open database */
1490 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001491 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001492 /* (not the same as sqlite3_exec) */
1493 ShellState *pArg, /* Pointer to ShellState */
1494 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001495){
dan4564ced2010-01-05 04:59:56 +00001496 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1497 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001498 int rc2;
dan4564ced2010-01-05 04:59:56 +00001499 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001500
1501 if( pzErrMsg ){
1502 *pzErrMsg = NULL;
1503 }
1504
shaneb9fc17d2009-10-22 21:23:35 +00001505 while( zSql[0] && (SQLITE_OK == rc) ){
1506 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1507 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001508 if( pzErrMsg ){
1509 *pzErrMsg = save_err_msg(db);
1510 }
1511 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001512 if( !pStmt ){
1513 /* this happens for a comment or white-space */
1514 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001515 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001516 continue;
1517 }
shane626a6e42009-10-22 17:30:15 +00001518
shaneh642d8b82010-07-28 16:05:34 +00001519 /* save off the prepared statment handle and reset row count */
1520 if( pArg ){
1521 pArg->pStmt = pStmt;
1522 pArg->cnt = 0;
1523 }
1524
shanehb7977c52010-01-18 18:17:10 +00001525 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001526 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001527 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001528 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001529 }
shanehb7977c52010-01-18 18:17:10 +00001530
drhefbf3b12014-02-28 20:47:24 +00001531 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1532 if( pArg && pArg->autoEQP ){
1533 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001534 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1535 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001536 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1537 if( rc==SQLITE_OK ){
1538 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1539 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1540 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1541 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1542 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1543 }
1544 }
1545 sqlite3_finalize(pExplain);
1546 sqlite3_free(zEQP);
1547 }
1548
dana98bf362013-11-13 18:35:01 +00001549 /* If the shell is currently in ".explain" mode, gather the extra
1550 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001551 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001552 explain_data_prepare(pArg, pStmt);
1553 }
1554
shaneb9fc17d2009-10-22 21:23:35 +00001555 /* perform the first step. this will tell us if we
1556 ** have a result set or not and how wide it is.
1557 */
1558 rc = sqlite3_step(pStmt);
1559 /* if we have a result set... */
1560 if( SQLITE_ROW == rc ){
1561 /* if we have a callback... */
1562 if( xCallback ){
1563 /* allocate space for col name ptr, value ptr, and type */
1564 int nCol = sqlite3_column_count(pStmt);
1565 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1566 if( !pData ){
1567 rc = SQLITE_NOMEM;
1568 }else{
1569 char **azCols = (char **)pData; /* Names of result columns */
1570 char **azVals = &azCols[nCol]; /* Results */
1571 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001572 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001573 assert(sizeof(int) <= sizeof(char *));
1574 /* save off ptrs to column names */
1575 for(i=0; i<nCol; i++){
1576 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1577 }
shaneb9fc17d2009-10-22 21:23:35 +00001578 do{
1579 /* extract the data and data types */
1580 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001581 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001582 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001583 azVals[i] = "";
1584 }else{
1585 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1586 }
shaneb9fc17d2009-10-22 21:23:35 +00001587 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1588 rc = SQLITE_NOMEM;
1589 break; /* from for */
1590 }
1591 } /* end for */
1592
1593 /* if data and types extracted successfully... */
1594 if( SQLITE_ROW == rc ){
1595 /* call the supplied callback with the result row data */
1596 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1597 rc = SQLITE_ABORT;
1598 }else{
1599 rc = sqlite3_step(pStmt);
1600 }
1601 }
1602 } while( SQLITE_ROW == rc );
1603 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001604 }
1605 }else{
1606 do{
1607 rc = sqlite3_step(pStmt);
1608 } while( rc == SQLITE_ROW );
1609 }
1610 }
1611
dana98bf362013-11-13 18:35:01 +00001612 explain_data_delete(pArg);
1613
shaneh642d8b82010-07-28 16:05:34 +00001614 /* print usage stats if stats on */
1615 if( pArg && pArg->statsOn ){
1616 display_stats(db, pArg, 0);
1617 }
1618
dan8d1edb92014-11-05 09:07:28 +00001619 /* print loop-counters if required */
1620 if( pArg && pArg->scanstatsOn ){
1621 display_scanstats(db, pArg);
1622 }
1623
dan4564ced2010-01-05 04:59:56 +00001624 /* Finalize the statement just executed. If this fails, save a
1625 ** copy of the error message. Otherwise, set zSql to point to the
1626 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001627 rc2 = sqlite3_finalize(pStmt);
1628 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001629 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001630 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001631 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001632 }else if( pzErrMsg ){
1633 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001634 }
shaneh642d8b82010-07-28 16:05:34 +00001635
1636 /* clear saved stmt handle */
1637 if( pArg ){
1638 pArg->pStmt = NULL;
1639 }
shane626a6e42009-10-22 17:30:15 +00001640 }
shaneb9fc17d2009-10-22 21:23:35 +00001641 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001642
1643 return rc;
1644}
1645
drhdd3d4592004-08-30 01:54:05 +00001646
drh33048c02001-10-01 14:29:22 +00001647/*
drh4c653a02000-06-07 01:27:47 +00001648** This is a different callback routine used for dumping the database.
1649** Each row received by this callback consists of a table name,
1650** the table type ("index" or "table") and SQL to create the table.
1651** This routine should print text sufficient to recreate the table.
1652*/
1653static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001654 int rc;
1655 const char *zTable;
1656 const char *zType;
1657 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001658 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001659 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001660
drh902b9ee2008-12-05 17:17:07 +00001661 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001662 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001663 zTable = azArg[0];
1664 zType = azArg[1];
1665 zSql = azArg[2];
1666
drh00b950d2005-09-11 02:03:03 +00001667 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001668 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001669 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001670 fprintf(p->out, "ANALYZE sqlite_master;\n");
1671 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1672 return 0;
drh45e29d82006-11-20 16:21:10 +00001673 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1674 char *zIns;
1675 if( !p->writableSchema ){
1676 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1677 p->writableSchema = 1;
1678 }
1679 zIns = sqlite3_mprintf(
1680 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1681 "VALUES('table','%q','%q',0,'%q');",
1682 zTable, zTable, zSql);
1683 fprintf(p->out, "%s\n", zIns);
1684 sqlite3_free(zIns);
1685 return 0;
drh00b950d2005-09-11 02:03:03 +00001686 }else{
1687 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001688 }
danielk19772a02e332004-06-05 08:04:36 +00001689
1690 if( strcmp(zType, "table")==0 ){
1691 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001692 char *zSelect = 0;
1693 char *zTableInfo = 0;
1694 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001695 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001696
1697 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1698 zTableInfo = appendText(zTableInfo, zTable, '"');
1699 zTableInfo = appendText(zTableInfo, ");", 0);
1700
drhc7181902014-02-27 15:04:13 +00001701 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001702 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001703 if( rc!=SQLITE_OK || !pTableInfo ){
1704 return 1;
1705 }
1706
1707 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001708 /* Always quote the table name, even if it appears to be pure ascii,
1709 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1710 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001711 if( zTmp ){
1712 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001713 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001714 }
1715 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1716 rc = sqlite3_step(pTableInfo);
1717 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001718 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001719 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001720 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001721 rc = sqlite3_step(pTableInfo);
1722 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001723 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001724 }else{
1725 zSelect = appendText(zSelect, ") ", 0);
1726 }
drh157e29a2009-05-21 15:15:00 +00001727 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001728 }
1729 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001730 if( rc!=SQLITE_OK || nRow==0 ){
1731 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001732 return 1;
1733 }
1734 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1735 zSelect = appendText(zSelect, zTable, '"');
1736
drh2f464a02011-10-13 00:41:49 +00001737 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001738 if( rc==SQLITE_CORRUPT ){
1739 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001740 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001741 }
drh85e72432012-04-11 11:38:53 +00001742 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001743 }
drh4c653a02000-06-07 01:27:47 +00001744 return 0;
1745}
1746
1747/*
drh45e29d82006-11-20 16:21:10 +00001748** Run zQuery. Use dump_callback() as the callback routine so that
1749** the contents of the query are output as SQL statements.
1750**
drhdd3d4592004-08-30 01:54:05 +00001751** If we get a SQLITE_CORRUPT error, rerun the query after appending
1752** "ORDER BY rowid DESC" to the end.
1753*/
1754static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001755 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001756 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001757){
1758 int rc;
drh2f464a02011-10-13 00:41:49 +00001759 char *zErr = 0;
1760 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001761 if( rc==SQLITE_CORRUPT ){
1762 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001763 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001764 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1765 if( zErr ){
1766 fprintf(p->out, "/****** %s ******/\n", zErr);
1767 sqlite3_free(zErr);
1768 zErr = 0;
1769 }
drhdd3d4592004-08-30 01:54:05 +00001770 zQ2 = malloc( len+100 );
1771 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001772 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001773 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1774 if( rc ){
1775 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1776 }else{
1777 rc = SQLITE_CORRUPT;
1778 }
1779 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001780 free(zQ2);
1781 }
1782 return rc;
1783}
1784
1785/*
drh75897232000-05-29 14:26:00 +00001786** Text of a help message
1787*/
persicom1d0b8722002-04-18 02:53:04 +00001788static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001789 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001790 ".bail on|off Stop after hitting an error. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001791 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001792 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001793 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001794 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001795 " If TABLE specified, only dump tables matching\n"
1796 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001797 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001798 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001799 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001800 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001801 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001802 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001803 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001804 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001805 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001806 ".indexes ?TABLE? Show names of all indexes\n"
1807 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001808 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001809#ifdef SQLITE_ENABLE_IOTRACE
1810 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1811#endif
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"
drhe6229612014-08-18 15:08:26 +00001842#if defined(SQLITE_ENABLE_SESSION)
1843 ".session CMD ... Create or control sessions\n"
1844#endif
drh62cdde52014-05-28 20:22:28 +00001845 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001846 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001847 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001848 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001849 ".tables ?TABLE? List names of tables\n"
1850 " If TABLE specified, only list tables matching\n"
1851 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001852 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001853 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001854 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001855 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001856 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001857 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001858;
1859
drhe6229612014-08-18 15:08:26 +00001860#if defined(SQLITE_ENABLE_SESSION)
1861/*
1862** Print help information for the ".sessions" command
1863*/
1864void session_help(ShellState *p){
1865 fprintf(p->out,
1866 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
1867 "If ?NAME? is omitted, the first defined session is used.\n"
1868 "Subcommands:\n"
1869 " attach TABLE Attach TABLE\n"
1870 " changeset FILE Write a changeset into FILE\n"
1871 " close Close one session\n"
1872 " enable ?BOOLEAN? Set or query the enable bit\n"
1873 " filter GLOB... Reject tables matching GLOBs\n"
1874 " indirect ?BOOLEAN? Mark or query the indirect status\n"
1875 " isempty Query whether the session is empty\n"
1876 " list List currently open session names\n"
1877 " open DB NAME Open a new session on DB\n"
1878 " patchset FILE Write a patchset into FILE\n"
1879 );
1880}
1881#endif
1882
1883
drhdaffd0e2001-04-11 14:28:42 +00001884/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001885static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001886/*
1887** Implementation of the "readfile(X)" SQL function. The entire content
1888** of the file named X is read and returned as a BLOB. NULL is returned
1889** if the file does not exist or is unreadable.
1890*/
1891static void readfileFunc(
1892 sqlite3_context *context,
1893 int argc,
1894 sqlite3_value **argv
1895){
1896 const char *zName;
1897 FILE *in;
1898 long nIn;
1899 void *pBuf;
1900
1901 zName = (const char*)sqlite3_value_text(argv[0]);
1902 if( zName==0 ) return;
1903 in = fopen(zName, "rb");
1904 if( in==0 ) return;
1905 fseek(in, 0, SEEK_END);
1906 nIn = ftell(in);
1907 rewind(in);
1908 pBuf = sqlite3_malloc( nIn );
1909 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1910 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1911 }else{
1912 sqlite3_free(pBuf);
1913 }
1914 fclose(in);
1915}
1916
1917/*
1918** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1919** is written into file X. The number of bytes written is returned. Or
1920** NULL is returned if something goes wrong, such as being unable to open
1921** file X for writing.
1922*/
1923static void writefileFunc(
1924 sqlite3_context *context,
1925 int argc,
1926 sqlite3_value **argv
1927){
1928 FILE *out;
1929 const char *z;
drhba5b0932014-07-24 12:39:59 +00001930 sqlite3_int64 rc;
1931 const char *zFile;
1932
1933 zFile = (const char*)sqlite3_value_text(argv[0]);
1934 if( zFile==0 ) return;
1935 out = fopen(zFile, "wb");
1936 if( out==0 ) return;
1937 z = (const char*)sqlite3_value_blob(argv[1]);
1938 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001939 rc = 0;
1940 }else{
drh490fe862014-08-11 14:21:32 +00001941 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001942 }
1943 fclose(out);
1944 sqlite3_result_int64(context, rc);
1945}
drhdaffd0e2001-04-11 14:28:42 +00001946
drhe6229612014-08-18 15:08:26 +00001947#if defined(SQLITE_ENABLE_SESSION)
1948/*
1949** Close a single OpenSession object and release all of its associated
1950** resources.
1951*/
1952static void session_close(OpenSession *pSession){
1953 int i;
1954 sqlite3session_delete(pSession->p);
1955 sqlite3_free(pSession->zName);
1956 for(i=0; i<pSession->nFilter; i++){
1957 sqlite3_free(pSession->azFilter[i]);
1958 }
1959 sqlite3_free(pSession->azFilter);
1960 memset(pSession, 0, sizeof(OpenSession));
1961}
1962#endif
1963
1964/*
1965** Close all OpenSession objects and release all assocaited resources.
1966*/
1967static void session_close_all(ShellState *p){
1968#if defined(SQLITE_ENABLE_SESSION)
1969 int i;
1970 for(i=0; i<p->nSession; i++){
1971 session_close(&p->aSession[i]);
1972 }
1973 p->nSession = 0;
1974#endif
1975}
1976
drh75897232000-05-29 14:26:00 +00001977/*
drh03168ca2014-08-18 20:01:31 +00001978** Implementation of the xFilter function for an open session. Omit
1979** any tables named by ".session filter" but let all other table through.
1980*/
1981#if defined(SQLITE_ENABLE_SESSION)
1982static int session_filter(void *pCtx, const char *zTab){
1983 OpenSession *pSession = (OpenSession*)pCtx;
1984 int i;
1985 for(i=0; i<pSession->nFilter; i++){
1986 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
1987 }
1988 return 1;
1989}
1990#endif
1991
1992/*
drh44c2eb12003-04-30 11:38:26 +00001993** Make sure the database is open. If it is not, then open it. If
1994** the database fails to open, print an error message and exit.
1995*/
drhdcd87a92014-08-18 13:45:42 +00001996static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001997 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001998 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001999 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00002000 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00002001 if( db && sqlite3_errcode(db)==SQLITE_OK ){
2002 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
2003 shellstaticFunc, 0, 0);
2004 }
2005 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00002006 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00002007 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00002008 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002009 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002010 }
drhc2e87a32006-06-27 15:16:14 +00002011#ifndef SQLITE_OMIT_LOAD_EXTENSION
2012 sqlite3_enable_load_extension(p->db, 1);
2013#endif
drhba5b0932014-07-24 12:39:59 +00002014 sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
2015 readfileFunc, 0, 0);
2016 sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
2017 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002018 }
2019}
2020
2021/*
drhfeac5f82004-08-01 00:10:45 +00002022** Do C-language style dequoting.
2023**
2024** \t -> tab
2025** \n -> newline
2026** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00002027** \" -> "
drhfeac5f82004-08-01 00:10:45 +00002028** \NNN -> ascii character NNN in octal
2029** \\ -> backslash
2030*/
2031static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002032 int i, j;
2033 char c;
drhc2ce0be2014-05-29 12:36:14 +00002034 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002035 for(i=j=0; (c = z[i])!=0; i++, j++){
2036 if( c=='\\' ){
2037 c = z[++i];
2038 if( c=='n' ){
2039 c = '\n';
2040 }else if( c=='t' ){
2041 c = '\t';
2042 }else if( c=='r' ){
2043 c = '\r';
drh4c56b992013-06-27 13:26:55 +00002044 }else if( c=='\\' ){
2045 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002046 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002047 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002048 if( z[i+1]>='0' && z[i+1]<='7' ){
2049 i++;
2050 c = (c<<3) + z[i] - '0';
2051 if( z[i+1]>='0' && z[i+1]<='7' ){
2052 i++;
2053 c = (c<<3) + z[i] - '0';
2054 }
2055 }
2056 }
2057 }
2058 z[j] = c;
2059 }
drhc2ce0be2014-05-29 12:36:14 +00002060 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002061}
2062
2063/*
drh348d19c2013-06-03 12:47:43 +00002064** Return the value of a hexadecimal digit. Return -1 if the input
2065** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002066*/
drh348d19c2013-06-03 12:47:43 +00002067static int hexDigitValue(char c){
2068 if( c>='0' && c<='9' ) return c - '0';
2069 if( c>='a' && c<='f' ) return c - 'a' + 10;
2070 if( c>='A' && c<='F' ) return c - 'A' + 10;
2071 return -1;
drhc28490c2006-10-26 14:25:58 +00002072}
2073
2074/*
drh7d9f3942013-04-03 01:26:54 +00002075** Interpret zArg as an integer value, possibly with suffixes.
2076*/
2077static sqlite3_int64 integerValue(const char *zArg){
2078 sqlite3_int64 v = 0;
2079 static const struct { char *zSuffix; int iMult; } aMult[] = {
2080 { "KiB", 1024 },
2081 { "MiB", 1024*1024 },
2082 { "GiB", 1024*1024*1024 },
2083 { "KB", 1000 },
2084 { "MB", 1000000 },
2085 { "GB", 1000000000 },
2086 { "K", 1000 },
2087 { "M", 1000000 },
2088 { "G", 1000000000 },
2089 };
2090 int i;
2091 int isNeg = 0;
2092 if( zArg[0]=='-' ){
2093 isNeg = 1;
2094 zArg++;
2095 }else if( zArg[0]=='+' ){
2096 zArg++;
2097 }
drh348d19c2013-06-03 12:47:43 +00002098 if( zArg[0]=='0' && zArg[1]=='x' ){
2099 int x;
2100 zArg += 2;
2101 while( (x = hexDigitValue(zArg[0]))>=0 ){
2102 v = (v<<4) + x;
2103 zArg++;
2104 }
2105 }else{
2106 while( IsDigit(zArg[0]) ){
2107 v = v*10 + zArg[0] - '0';
2108 zArg++;
2109 }
drh7d9f3942013-04-03 01:26:54 +00002110 }
drhc2bed0a2013-05-24 11:57:50 +00002111 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002112 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2113 v *= aMult[i].iMult;
2114 break;
2115 }
2116 }
2117 return isNeg? -v : v;
2118}
2119
2120/*
drh348d19c2013-06-03 12:47:43 +00002121** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2122** for TRUE and FALSE. Return the integer value if appropriate.
2123*/
2124static int booleanValue(char *zArg){
2125 int i;
2126 if( zArg[0]=='0' && zArg[1]=='x' ){
2127 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2128 }else{
2129 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2130 }
2131 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2132 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2133 return 1;
2134 }
2135 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2136 return 0;
2137 }
2138 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2139 zArg);
2140 return 0;
2141}
2142
2143/*
drh42f64e52012-04-04 16:56:23 +00002144** Close an output file, assuming it is not stderr or stdout
2145*/
2146static void output_file_close(FILE *f){
2147 if( f && f!=stdout && f!=stderr ) fclose(f);
2148}
2149
2150/*
2151** Try to open an output file. The names "stdout" and "stderr" are
2152** recognized and do the right thing. NULL is returned if the output
2153** filename is "off".
2154*/
2155static FILE *output_file_open(const char *zFile){
2156 FILE *f;
2157 if( strcmp(zFile,"stdout")==0 ){
2158 f = stdout;
2159 }else if( strcmp(zFile, "stderr")==0 ){
2160 f = stderr;
2161 }else if( strcmp(zFile, "off")==0 ){
2162 f = 0;
2163 }else{
2164 f = fopen(zFile, "wb");
2165 if( f==0 ){
2166 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2167 }
2168 }
2169 return f;
2170}
2171
2172/*
2173** A routine for handling output from sqlite3_trace().
2174*/
2175static void sql_trace_callback(void *pArg, const char *z){
2176 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002177 if( f ){
2178 int i = (int)strlen(z);
2179 while( i>0 && z[i-1]==';' ){ i--; }
2180 fprintf(f, "%.*s;\n", i, z);
2181 }
drh42f64e52012-04-04 16:56:23 +00002182}
2183
2184/*
drhd8621b92012-04-17 09:09:33 +00002185** A no-op routine that runs with the ".breakpoint" doc-command. This is
2186** a useful spot to set a debugger breakpoint.
2187*/
2188static void test_breakpoint(void){
2189 static int nCall = 0;
2190 nCall++;
2191}
2192
2193/*
mistachkin636bf9f2014-07-19 20:15:16 +00002194** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002195*/
mistachkin636bf9f2014-07-19 20:15:16 +00002196typedef struct ImportCtx ImportCtx;
2197struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002198 const char *zFile; /* Name of the input file */
2199 FILE *in; /* Read the CSV text from this input stream */
2200 char *z; /* Accumulated text for a field */
2201 int n; /* Number of bytes in z */
2202 int nAlloc; /* Space allocated for z[] */
2203 int nLine; /* Current line number */
2204 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002205 int cColSep; /* The column separator character. (Usually ",") */
2206 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002207};
2208
2209/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002210static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002211 if( p->n+1>=p->nAlloc ){
2212 p->nAlloc += p->nAlloc + 100;
2213 p->z = sqlite3_realloc(p->z, p->nAlloc);
2214 if( p->z==0 ){
2215 fprintf(stderr, "out of memory\n");
2216 exit(1);
2217 }
2218 }
2219 p->z[p->n++] = (char)c;
2220}
2221
2222/* Read a single field of CSV text. Compatible with rfc4180 and extended
2223** with the option of having a separator other than ",".
2224**
2225** + Input comes from p->in.
2226** + Store results in p->z of length p->n. Space to hold p->z comes
2227** from sqlite3_malloc().
mistachkin636bf9f2014-07-19 20:15:16 +00002228** + Use p->cSep as the column separator. The default is ",".
2229** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002230** + Keep track of the line number in p->nLine.
2231** + Store the character that terminates the field in p->cTerm. Store
2232** EOF on end-of-file.
2233** + Report syntax errors on stderr
2234*/
mistachkin44723ce2015-03-21 02:22:37 +00002235static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002236 int c;
2237 int cSep = p->cColSep;
2238 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002239 p->n = 0;
2240 c = fgetc(p->in);
2241 if( c==EOF || seenInterrupt ){
2242 p->cTerm = EOF;
2243 return 0;
2244 }
2245 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002246 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002247 int startLine = p->nLine;
2248 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002249 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002250 while( 1 ){
2251 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002252 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002253 if( c==cQuote ){
2254 if( pc==cQuote ){
2255 pc = 0;
2256 continue;
2257 }
2258 }
2259 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002260 || (c==rSep && pc==cQuote)
2261 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002262 || (c==EOF && pc==cQuote)
2263 ){
2264 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002265 p->cTerm = c;
2266 break;
2267 }
2268 if( pc==cQuote && c!='\r' ){
2269 fprintf(stderr, "%s:%d: unescaped %c character\n",
2270 p->zFile, p->nLine, cQuote);
2271 }
2272 if( c==EOF ){
2273 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2274 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002275 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002276 break;
2277 }
mistachkin636bf9f2014-07-19 20:15:16 +00002278 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002279 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002280 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002281 }
drhdb95f682013-06-26 22:46:00 +00002282 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002283 while( c!=EOF && c!=cSep && c!=rSep ){
2284 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002285 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002286 }
mistachkin636bf9f2014-07-19 20:15:16 +00002287 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002288 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002289 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002290 }
drhdb95f682013-06-26 22:46:00 +00002291 p->cTerm = c;
2292 }
drh8dd675e2013-07-12 21:09:24 +00002293 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002294 return p->z;
2295}
2296
mistachkin636bf9f2014-07-19 20:15:16 +00002297/* Read a single field of ASCII delimited text.
2298**
2299** + Input comes from p->in.
2300** + Store results in p->z of length p->n. Space to hold p->z comes
2301** from sqlite3_malloc().
2302** + Use p->cSep as the column separator. The default is "\x1F".
2303** + Use p->rSep as the row separator. The default is "\x1E".
2304** + Keep track of the row number in p->nLine.
2305** + Store the character that terminates the field in p->cTerm. Store
2306** EOF on end-of-file.
2307** + Report syntax errors on stderr
2308*/
mistachkin44723ce2015-03-21 02:22:37 +00002309static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002310 int c;
2311 int cSep = p->cColSep;
2312 int rSep = p->cRowSep;
2313 p->n = 0;
2314 c = fgetc(p->in);
2315 if( c==EOF || seenInterrupt ){
2316 p->cTerm = EOF;
2317 return 0;
2318 }
2319 while( c!=EOF && c!=cSep && c!=rSep ){
2320 import_append_char(p, c);
2321 c = fgetc(p->in);
2322 }
2323 if( c==rSep ){
2324 p->nLine++;
2325 }
2326 p->cTerm = c;
2327 if( p->z ) p->z[p->n] = 0;
2328 return p->z;
2329}
2330
drhdb95f682013-06-26 22:46:00 +00002331/*
drh4bbcf102014-02-06 02:46:08 +00002332** Try to transfer data for table zTable. If an error is seen while
2333** moving forward, try to go backwards. The backwards movement won't
2334** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002335*/
mistachkine31ae902014-02-06 01:15:29 +00002336static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002337 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002338 sqlite3 *newDb,
2339 const char *zTable
2340){
2341 sqlite3_stmt *pQuery = 0;
2342 sqlite3_stmt *pInsert = 0;
2343 char *zQuery = 0;
2344 char *zInsert = 0;
2345 int rc;
2346 int i, j, n;
2347 int nTable = (int)strlen(zTable);
2348 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002349 int cnt = 0;
2350 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002351
2352 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2353 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2354 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002355 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002356 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2357 zQuery);
2358 goto end_data_xfer;
2359 }
2360 n = sqlite3_column_count(pQuery);
2361 zInsert = sqlite3_malloc(200 + nTable + n*3);
2362 if( zInsert==0 ){
2363 fprintf(stderr, "out of memory\n");
2364 goto end_data_xfer;
2365 }
2366 sqlite3_snprintf(200+nTable,zInsert,
2367 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2368 i = (int)strlen(zInsert);
2369 for(j=1; j<n; j++){
2370 memcpy(zInsert+i, ",?", 2);
2371 i += 2;
2372 }
2373 memcpy(zInsert+i, ");", 3);
2374 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2375 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002376 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002377 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2378 zQuery);
2379 goto end_data_xfer;
2380 }
2381 for(k=0; k<2; k++){
2382 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2383 for(i=0; i<n; i++){
2384 switch( sqlite3_column_type(pQuery, i) ){
2385 case SQLITE_NULL: {
2386 sqlite3_bind_null(pInsert, i+1);
2387 break;
2388 }
2389 case SQLITE_INTEGER: {
2390 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2391 break;
2392 }
2393 case SQLITE_FLOAT: {
2394 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2395 break;
2396 }
2397 case SQLITE_TEXT: {
2398 sqlite3_bind_text(pInsert, i+1,
2399 (const char*)sqlite3_column_text(pQuery,i),
2400 -1, SQLITE_STATIC);
2401 break;
2402 }
2403 case SQLITE_BLOB: {
2404 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2405 sqlite3_column_bytes(pQuery,i),
2406 SQLITE_STATIC);
2407 break;
2408 }
2409 }
2410 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002411 rc = sqlite3_step(pInsert);
2412 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2413 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2414 sqlite3_errmsg(newDb));
2415 }
drh3350ce92014-02-06 00:49:12 +00002416 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002417 cnt++;
2418 if( (cnt%spinRate)==0 ){
2419 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2420 fflush(stdout);
2421 }
drh3350ce92014-02-06 00:49:12 +00002422 } /* End while */
2423 if( rc==SQLITE_DONE ) break;
2424 sqlite3_finalize(pQuery);
2425 sqlite3_free(zQuery);
2426 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2427 zTable);
2428 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2429 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002430 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2431 break;
drh3350ce92014-02-06 00:49:12 +00002432 }
2433 } /* End for(k=0...) */
2434
2435end_data_xfer:
2436 sqlite3_finalize(pQuery);
2437 sqlite3_finalize(pInsert);
2438 sqlite3_free(zQuery);
2439 sqlite3_free(zInsert);
2440}
2441
2442
2443/*
2444** Try to transfer all rows of the schema that match zWhere. For
2445** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002446** If an error is encountered while moving forward through the
2447** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002448*/
mistachkine31ae902014-02-06 01:15:29 +00002449static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002450 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002451 sqlite3 *newDb,
2452 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002453 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002454){
2455 sqlite3_stmt *pQuery = 0;
2456 char *zQuery = 0;
2457 int rc;
2458 const unsigned char *zName;
2459 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002460 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002461
2462 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2463 " WHERE %s", zWhere);
2464 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2465 if( rc ){
2466 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2467 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2468 zQuery);
2469 goto end_schema_xfer;
2470 }
2471 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2472 zName = sqlite3_column_text(pQuery, 0);
2473 zSql = sqlite3_column_text(pQuery, 1);
2474 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002475 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2476 if( zErrMsg ){
2477 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2478 sqlite3_free(zErrMsg);
2479 zErrMsg = 0;
2480 }
drh3350ce92014-02-06 00:49:12 +00002481 if( xForEach ){
2482 xForEach(p, newDb, (const char*)zName);
2483 }
2484 printf("done\n");
2485 }
2486 if( rc!=SQLITE_DONE ){
2487 sqlite3_finalize(pQuery);
2488 sqlite3_free(zQuery);
2489 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2490 " WHERE %s ORDER BY rowid DESC", zWhere);
2491 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2492 if( rc ){
2493 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2494 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2495 zQuery);
2496 goto end_schema_xfer;
2497 }
2498 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2499 zName = sqlite3_column_text(pQuery, 0);
2500 zSql = sqlite3_column_text(pQuery, 1);
2501 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002502 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2503 if( zErrMsg ){
2504 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2505 sqlite3_free(zErrMsg);
2506 zErrMsg = 0;
2507 }
drh3350ce92014-02-06 00:49:12 +00002508 if( xForEach ){
2509 xForEach(p, newDb, (const char*)zName);
2510 }
2511 printf("done\n");
2512 }
2513 }
2514end_schema_xfer:
2515 sqlite3_finalize(pQuery);
2516 sqlite3_free(zQuery);
2517}
2518
2519/*
2520** Open a new database file named "zNewDb". Try to recover as much information
2521** as possible out of the main database (which might be corrupt) and write it
2522** into zNewDb.
2523*/
drhdcd87a92014-08-18 13:45:42 +00002524static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002525 int rc;
2526 sqlite3 *newDb = 0;
2527 if( access(zNewDb,0)==0 ){
2528 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2529 return;
2530 }
2531 rc = sqlite3_open(zNewDb, &newDb);
2532 if( rc ){
2533 fprintf(stderr, "Cannot create output database: %s\n",
2534 sqlite3_errmsg(newDb));
2535 }else{
drh54d0d2d2014-04-03 00:32:13 +00002536 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002537 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002538 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2539 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002540 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002541 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002542 }
2543 sqlite3_close(newDb);
2544}
2545
2546/*
drhc2ce0be2014-05-29 12:36:14 +00002547** Change the output file back to stdout
2548*/
drhdcd87a92014-08-18 13:45:42 +00002549static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002550 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002551#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002552 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002553#endif
drhc2ce0be2014-05-29 12:36:14 +00002554 }else{
2555 output_file_close(p->out);
2556 }
2557 p->outfile[0] = 0;
2558 p->out = stdout;
2559}
2560
2561/*
drhf7502f02015-02-06 14:19:44 +00002562** Run an SQL command and return the single integer result.
2563*/
2564static int db_int(ShellState *p, const char *zSql){
2565 sqlite3_stmt *pStmt;
2566 int res = 0;
2567 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2568 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2569 res = sqlite3_column_int(pStmt,0);
2570 }
2571 sqlite3_finalize(pStmt);
2572 return res;
2573}
2574
2575/*
2576** Convert a 2-byte or 4-byte big-endian integer into a native integer
2577*/
2578unsigned int get2byteInt(unsigned char *a){
2579 return (a[0]<<8) + a[1];
2580}
2581unsigned int get4byteInt(unsigned char *a){
2582 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2583}
2584
2585/*
2586** Implementation of the ".info" command.
2587**
2588** Return 1 on error, 2 to exit, and 0 otherwise.
2589*/
drh0e55db12015-02-06 14:51:13 +00002590static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002591 static const struct { const char *zName; int ofst; } aField[] = {
2592 { "file change counter:", 24 },
2593 { "database page count:", 28 },
2594 { "freelist page count:", 36 },
2595 { "schema cookie:", 40 },
2596 { "schema format:", 44 },
2597 { "default cache size:", 48 },
2598 { "autovacuum top root:", 52 },
2599 { "incremental vacuum:", 64 },
2600 { "text encoding:", 56 },
2601 { "user version:", 60 },
2602 { "application id:", 68 },
2603 { "software version:", 96 },
2604 };
drh0e55db12015-02-06 14:51:13 +00002605 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2606 { "number of tables:",
2607 "SELECT count(*) FROM %s WHERE type='table'" },
2608 { "number of indexes:",
2609 "SELECT count(*) FROM %s WHERE type='index'" },
2610 { "number of triggers:",
2611 "SELECT count(*) FROM %s WHERE type='trigger'" },
2612 { "number of views:",
2613 "SELECT count(*) FROM %s WHERE type='view'" },
2614 { "schema size:",
2615 "SELECT total(length(sql)) FROM %s" },
2616 };
2617 sqlite3_file *pFile;
2618 int i;
2619 char *zSchemaTab;
2620 char *zDb = nArg>=2 ? azArg[1] : "main";
2621 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002622 open_db(p, 0);
2623 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002624 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002625 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2626 return 1;
2627 }
2628 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2629 if( i!=SQLITE_OK ){
2630 fprintf(stderr, "unable to read database header\n");
2631 return 1;
2632 }
2633 i = get2byteInt(aHdr+16);
2634 if( i==1 ) i = 65536;
2635 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2636 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2637 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2638 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
2639 for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
2640 int ofst = aField[i].ofst;
2641 unsigned int val = get4byteInt(aHdr + ofst);
2642 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2643 switch( ofst ){
2644 case 56: {
2645 if( val==1 ) fprintf(p->out, " (utf8)");
2646 if( val==2 ) fprintf(p->out, " (utf16le)");
2647 if( val==3 ) fprintf(p->out, " (utf16be)");
2648 }
2649 }
2650 fprintf(p->out, "\n");
2651 }
drh0e55db12015-02-06 14:51:13 +00002652 if( zDb==0 ){
2653 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2654 }else if( strcmp(zDb,"temp")==0 ){
2655 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2656 }else{
2657 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2658 }
2659 for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
2660 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2661 int val = db_int(p, zSql);
2662 sqlite3_free(zSql);
2663 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2664 }
2665 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002666 return 0;
2667}
2668
2669
2670/*
drh75897232000-05-29 14:26:00 +00002671** If an input line begins with "." then invoke this routine to
2672** process that line.
drh67505e72002-04-19 12:34:06 +00002673**
drh47ad6842006-11-08 12:25:42 +00002674** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002675*/
drhdcd87a92014-08-18 13:45:42 +00002676static int do_meta_command(char *zLine, ShellState *p){
drh75897232000-05-29 14:26:00 +00002677 int i = 1;
2678 int nArg = 0;
2679 int n, c;
drh67505e72002-04-19 12:34:06 +00002680 int rc = 0;
drh75897232000-05-29 14:26:00 +00002681 char *azArg[50];
2682
2683 /* Parse the input line into tokens.
2684 */
2685 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00002686 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002687 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002688 if( zLine[i]=='\'' || zLine[i]=='"' ){
2689 int delim = zLine[i++];
2690 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00002691 while( zLine[i] && zLine[i]!=delim ){
2692 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2693 i++;
2694 }
drh75897232000-05-29 14:26:00 +00002695 if( zLine[i]==delim ){
2696 zLine[i++] = 0;
2697 }
drhfeac5f82004-08-01 00:10:45 +00002698 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002699 }else{
2700 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00002701 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002702 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002703 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002704 }
2705 }
2706
2707 /* Process the input line.
2708 */
shane9bd1b442009-10-23 01:27:39 +00002709 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002710 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002711 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002712 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2713 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2714 ){
drhbc46f022013-01-23 18:53:23 +00002715 const char *zDestFile = 0;
2716 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002717 sqlite3 *pDest;
2718 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002719 int j;
2720 for(j=1; j<nArg; j++){
2721 const char *z = azArg[j];
2722 if( z[0]=='-' ){
2723 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002724 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002725 {
2726 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2727 return 1;
2728 }
2729 }else if( zDestFile==0 ){
2730 zDestFile = azArg[j];
2731 }else if( zDb==0 ){
2732 zDb = zDestFile;
2733 zDestFile = azArg[j];
2734 }else{
2735 fprintf(stderr, "too many arguments to .backup\n");
2736 return 1;
2737 }
drh9ff849f2009-02-04 20:55:57 +00002738 }
drhbc46f022013-01-23 18:53:23 +00002739 if( zDestFile==0 ){
2740 fprintf(stderr, "missing FILENAME argument on .backup\n");
2741 return 1;
2742 }
2743 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002744 rc = sqlite3_open(zDestFile, &pDest);
2745 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002746 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002747 sqlite3_close(pDest);
2748 return 1;
2749 }
drh05782482013-10-24 15:20:20 +00002750 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002751 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2752 if( pBackup==0 ){
2753 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2754 sqlite3_close(pDest);
2755 return 1;
2756 }
2757 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2758 sqlite3_backup_finish(pBackup);
2759 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002760 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002761 }else{
2762 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002763 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002764 }
2765 sqlite3_close(pDest);
2766 }else
2767
drhc2ce0be2014-05-29 12:36:14 +00002768 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2769 if( nArg==2 ){
2770 bail_on_error = booleanValue(azArg[1]);
2771 }else{
2772 fprintf(stderr, "Usage: .bail on|off\n");
2773 rc = 1;
2774 }
drhc49f44e2006-10-26 18:15:42 +00002775 }else
2776
drhd8621b92012-04-17 09:09:33 +00002777 /* The undocumented ".breakpoint" command causes a call to the no-op
2778 ** routine named test_breakpoint().
2779 */
2780 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2781 test_breakpoint();
2782 }else
2783
drhc2ce0be2014-05-29 12:36:14 +00002784 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2785 if( nArg==2 ){
2786 tryToClone(p, azArg[1]);
2787 }else{
2788 fprintf(stderr, "Usage: .clone FILENAME\n");
2789 rc = 1;
2790 }
mistachkine31ae902014-02-06 01:15:29 +00002791 }else
2792
drhc2ce0be2014-05-29 12:36:14 +00002793 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002794 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002795 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002796 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002797 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002798 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002799 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002800 data.colWidth[0] = 3;
2801 data.colWidth[1] = 15;
2802 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002803 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002804 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002805 if( zErrMsg ){
2806 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002807 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002808 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002809 }
2810 }else
2811
drh0e55db12015-02-06 14:51:13 +00002812 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2813 rc = shell_dbinfo_command(p, nArg, azArg);
2814 }else
2815
drhc2ce0be2014-05-29 12:36:14 +00002816 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002817 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002818 /* When playing back a "dump", the content might appear in an order
2819 ** which causes immediate foreign key constraints to be violated.
2820 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002821 if( nArg!=1 && nArg!=2 ){
2822 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2823 rc = 1;
2824 goto meta_command_exit;
2825 }
drhf1dfc4f2009-09-23 15:51:35 +00002826 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002827 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002828 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002829 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002830 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002831 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002832 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002833 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002834 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002835 );
2836 run_schema_dump_query(p,
2837 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002838 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002839 );
drh2f464a02011-10-13 00:41:49 +00002840 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002841 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002842 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002843 );
drh4c653a02000-06-07 01:27:47 +00002844 }else{
2845 int i;
drhdd3d4592004-08-30 01:54:05 +00002846 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002847 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002848 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002849 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002850 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002851 " AND sql NOT NULL");
2852 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002853 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002854 "WHERE sql NOT NULL"
2855 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002856 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002857 );
danielk1977bc6ada42004-06-30 08:20:16 +00002858 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002859 }
2860 }
drh45e29d82006-11-20 16:21:10 +00002861 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002862 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002863 p->writableSchema = 0;
2864 }
drh56197952011-10-13 16:30:13 +00002865 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2866 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002867 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002868 }else
drh75897232000-05-29 14:26:00 +00002869
drhc2ce0be2014-05-29 12:36:14 +00002870 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2871 if( nArg==2 ){
2872 p->echoOn = booleanValue(azArg[1]);
2873 }else{
2874 fprintf(stderr, "Usage: .echo on|off\n");
2875 rc = 1;
2876 }
drhdaffd0e2001-04-11 14:28:42 +00002877 }else
2878
drhc2ce0be2014-05-29 12:36:14 +00002879 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2880 if( nArg==2 ){
2881 p->autoEQP = booleanValue(azArg[1]);
2882 }else{
2883 fprintf(stderr, "Usage: .eqp on|off\n");
2884 rc = 1;
2885 }
drhefbf3b12014-02-28 20:47:24 +00002886 }else
2887
drhd3ac7d92013-01-25 18:33:43 +00002888 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002889 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002890 rc = 2;
drh75897232000-05-29 14:26:00 +00002891 }else
2892
drhc2ce0be2014-05-29 12:36:14 +00002893 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002894 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002895 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002896 if(!p->normalMode.valid) {
2897 p->normalMode.valid = 1;
2898 p->normalMode.mode = p->mode;
2899 p->normalMode.showHeader = p->showHeader;
2900 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002901 }
2902 /* We could put this code under the !p->explainValid
2903 ** condition so that it does not execute if we are already in
2904 ** explain mode. However, always executing it allows us an easy
2905 ** was to reset to explain mode in case the user previously
2906 ** did an .explain followed by a .width, .mode or .header
2907 ** command.
2908 */
danielk19770d78bae2008-01-03 07:09:48 +00002909 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002910 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002911 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002912 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002913 p->colWidth[1] = 13; /* opcode */
2914 p->colWidth[2] = 4; /* P1 */
2915 p->colWidth[3] = 4; /* P2 */
2916 p->colWidth[4] = 4; /* P3 */
2917 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002918 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002919 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002920 }else if (p->normalMode.valid) {
2921 p->normalMode.valid = 0;
2922 p->mode = p->normalMode.mode;
2923 p->showHeader = p->normalMode.showHeader;
2924 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002925 }
drh75897232000-05-29 14:26:00 +00002926 }else
2927
drhc1971542014-06-23 23:28:13 +00002928 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002929 ShellState data;
drhc1971542014-06-23 23:28:13 +00002930 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002931 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002932 if( nArg!=1 ){
2933 fprintf(stderr, "Usage: .fullschema\n");
2934 rc = 1;
2935 goto meta_command_exit;
2936 }
2937 open_db(p, 0);
2938 memcpy(&data, p, sizeof(data));
2939 data.showHeader = 0;
2940 data.mode = MODE_Semi;
2941 rc = sqlite3_exec(p->db,
2942 "SELECT sql FROM"
2943 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2944 " FROM sqlite_master UNION ALL"
2945 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002946 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002947 "ORDER BY rowid",
2948 callback, &data, &zErrMsg
2949 );
drh56f674c2014-07-18 14:43:29 +00002950 if( rc==SQLITE_OK ){
2951 sqlite3_stmt *pStmt;
2952 rc = sqlite3_prepare_v2(p->db,
2953 "SELECT rowid FROM sqlite_master"
2954 " WHERE name GLOB 'sqlite_stat[134]'",
2955 -1, &pStmt, 0);
2956 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2957 sqlite3_finalize(pStmt);
2958 }
2959 if( doStats==0 ){
2960 fprintf(p->out, "/* No STAT tables available */\n");
2961 }else{
2962 fprintf(p->out, "ANALYZE sqlite_master;\n");
2963 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2964 callback, &data, &zErrMsg);
2965 data.mode = MODE_Insert;
2966 data.zDestTable = "sqlite_stat1";
2967 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2968 shell_callback, &data,&zErrMsg);
2969 data.zDestTable = "sqlite_stat3";
2970 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2971 shell_callback, &data,&zErrMsg);
2972 data.zDestTable = "sqlite_stat4";
2973 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2974 shell_callback, &data, &zErrMsg);
2975 fprintf(p->out, "ANALYZE sqlite_master;\n");
2976 }
drhc1971542014-06-23 23:28:13 +00002977 }else
2978
drhc2ce0be2014-05-29 12:36:14 +00002979 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2980 if( nArg==2 ){
2981 p->showHeader = booleanValue(azArg[1]);
2982 }else{
2983 fprintf(stderr, "Usage: .headers on|off\n");
2984 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002985 }
drh75897232000-05-29 14:26:00 +00002986 }else
2987
drhc2ce0be2014-05-29 12:36:14 +00002988 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2989 fprintf(p->out, "%s", zHelp);
2990 }else
2991
2992 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002993 char *zTable; /* Insert data into this table */
2994 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002995 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002996 int nCol; /* Number of columns in the table */
2997 int nByte; /* Number of bytes in an SQL string */
2998 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002999 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003000 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003001 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003002 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003003 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3004 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003005
drhc2ce0be2014-05-29 12:36:14 +00003006 if( nArg!=3 ){
3007 fprintf(stderr, "Usage: .import FILE TABLE\n");
3008 goto meta_command_exit;
3009 }
drh01f37542014-05-31 15:43:33 +00003010 zFile = azArg[1];
3011 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003012 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003013 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003014 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003015 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003016 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003017 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003018 return 1;
drhfeac5f82004-08-01 00:10:45 +00003019 }
drhdb95f682013-06-26 22:46:00 +00003020 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003021 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003022 " for import\n");
3023 return 1;
3024 }
mistachkin636bf9f2014-07-19 20:15:16 +00003025 nSep = strlen30(p->rowSeparator);
3026 if( nSep==0 ){
3027 fprintf(stderr, "Error: non-null row separator required for import\n");
3028 return 1;
3029 }
mistachkine0d68852014-12-11 03:12:33 +00003030 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3031 /* When importing CSV (only), if the row separator is set to the
3032 ** default output row separator, change it to the default input
3033 ** row separator. This avoids having to maintain different input
3034 ** and output row separators. */
3035 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3036 nSep = strlen30(p->rowSeparator);
3037 }
mistachkin636bf9f2014-07-19 20:15:16 +00003038 if( nSep>1 ){
3039 fprintf(stderr, "Error: multi-character row separators not allowed"
3040 " for import\n");
3041 return 1;
3042 }
3043 sCtx.zFile = zFile;
3044 sCtx.nLine = 1;
3045 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003046#ifdef SQLITE_OMIT_POPEN
mistachkinba132c72015-03-19 14:48:38 +00003047 fprintf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003048 return 1;
3049#else
mistachkin636bf9f2014-07-19 20:15:16 +00003050 sCtx.in = popen(sCtx.zFile+1, "r");
3051 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003052 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003053#endif
drh5bde8162013-06-27 14:07:53 +00003054 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003055 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003056 xCloser = fclose;
3057 }
mistachkin636bf9f2014-07-19 20:15:16 +00003058 if( p->mode==MODE_Ascii ){
3059 xRead = ascii_read_one_field;
3060 }else{
3061 xRead = csv_read_one_field;
3062 }
3063 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00003064 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003065 return 1;
3066 }
mistachkin636bf9f2014-07-19 20:15:16 +00003067 sCtx.cColSep = p->colSeparator[0];
3068 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003069 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003070 if( zSql==0 ){
3071 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003072 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003073 return 1;
3074 }
drh4f21c4a2008-12-10 22:15:00 +00003075 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003076 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003077 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
drhdb95f682013-06-26 22:46:00 +00003078 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
3079 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3080 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003081 while( xRead(&sCtx) ){
3082 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003083 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003084 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003085 }
drh5bde8162013-06-27 14:07:53 +00003086 if( cSep=='(' ){
3087 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003088 sqlite3_free(sCtx.z);
3089 xCloser(sCtx.in);
3090 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003091 return 1;
3092 }
drhdb95f682013-06-26 22:46:00 +00003093 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3094 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3095 sqlite3_free(zCreate);
3096 if( rc ){
3097 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
3098 sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00003099 sqlite3_free(sCtx.z);
3100 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003101 return 1;
3102 }
drhc7181902014-02-27 15:04:13 +00003103 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003104 }
drhfeac5f82004-08-01 00:10:45 +00003105 sqlite3_free(zSql);
3106 if( rc ){
shane916f9612009-10-23 00:37:15 +00003107 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003108 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00003109 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003110 return 1;
drhfeac5f82004-08-01 00:10:45 +00003111 }
shane916f9612009-10-23 00:37:15 +00003112 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003113 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003114 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003115 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00003116 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003117 if( zSql==0 ){
3118 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003119 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003120 return 1;
3121 }
drhdb95f682013-06-26 22:46:00 +00003122 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003123 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003124 for(i=1; i<nCol; i++){
3125 zSql[j++] = ',';
3126 zSql[j++] = '?';
3127 }
3128 zSql[j++] = ')';
3129 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003130 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003131 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003132 if( rc ){
3133 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00003134 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003135 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003136 return 1;
drhfeac5f82004-08-01 00:10:45 +00003137 }
drh2d463112013-08-06 14:36:36 +00003138 needCommit = sqlite3_get_autocommit(db);
3139 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003140 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003141 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003142 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003143 char *z = xRead(&sCtx);
3144 /*
3145 ** Did we reach end-of-file before finding any columns?
3146 ** If so, stop instead of NULL filling the remaining columns.
3147 */
drhdb95f682013-06-26 22:46:00 +00003148 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003149 /*
3150 ** Did we reach end-of-file OR end-of-line before finding any
3151 ** columns in ASCII mode? If so, stop instead of NULL filling
3152 ** the remaining columns.
3153 */
3154 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003155 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003156 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003157 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3158 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003159 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003160 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003161 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003162 }
drhfeac5f82004-08-01 00:10:45 +00003163 }
mistachkin636bf9f2014-07-19 20:15:16 +00003164 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003165 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003166 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003167 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003168 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003169 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3170 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003171 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003172 }
drhdb95f682013-06-26 22:46:00 +00003173 if( i>=nCol ){
3174 sqlite3_step(pStmt);
3175 rc = sqlite3_reset(pStmt);
3176 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003177 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
drhdb95f682013-06-26 22:46:00 +00003178 sqlite3_errmsg(db));
3179 }
3180 }
mistachkin636bf9f2014-07-19 20:15:16 +00003181 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003182
mistachkin636bf9f2014-07-19 20:15:16 +00003183 xCloser(sCtx.in);
3184 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003185 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00003186 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003187 }else
3188
drh0e55db12015-02-06 14:51:13 +00003189 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3190 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003191 ShellState data;
drh75897232000-05-29 14:26:00 +00003192 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003193 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003194 memcpy(&data, p, sizeof(data));
3195 data.showHeader = 0;
3196 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003197 if( nArg==1 ){
3198 rc = sqlite3_exec(p->db,
3199 "SELECT name FROM sqlite_master "
3200 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3201 "UNION ALL "
3202 "SELECT name FROM sqlite_temp_master "
3203 "WHERE type='index' "
3204 "ORDER BY 1",
3205 callback, &data, &zErrMsg
3206 );
drhc2ce0be2014-05-29 12:36:14 +00003207 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003208 zShellStatic = azArg[1];
3209 rc = sqlite3_exec(p->db,
3210 "SELECT name FROM sqlite_master "
3211 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3212 "UNION ALL "
3213 "SELECT name FROM sqlite_temp_master "
3214 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3215 "ORDER BY 1",
3216 callback, &data, &zErrMsg
3217 );
3218 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003219 }else{
drh0e55db12015-02-06 14:51:13 +00003220 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003221 rc = 1;
3222 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003223 }
drh75897232000-05-29 14:26:00 +00003224 if( zErrMsg ){
3225 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003226 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003227 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003228 }else if( rc != SQLITE_OK ){
3229 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3230 rc = 1;
drh75897232000-05-29 14:26:00 +00003231 }
3232 }else
3233
drhae5e4452007-05-03 17:18:36 +00003234#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003235 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003236 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003237 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3238 iotrace = 0;
3239 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003240 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003241 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003242 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003243 iotrace = stdout;
3244 }else{
3245 iotrace = fopen(azArg[1], "w");
3246 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003247 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003248 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003249 rc = 1;
drhb0603412007-02-28 04:47:26 +00003250 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003251 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003252 }
3253 }
3254 }else
drhae5e4452007-05-03 17:18:36 +00003255#endif
drhb0603412007-02-28 04:47:26 +00003256
drh70df4fe2006-06-13 15:12:21 +00003257#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003258 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003259 const char *zFile, *zProc;
3260 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003261 if( nArg<2 ){
3262 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3263 rc = 1;
3264 goto meta_command_exit;
3265 }
drh1e397f82006-06-08 15:28:43 +00003266 zFile = azArg[1];
3267 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003268 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003269 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3270 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003271 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003272 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003273 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003274 }
3275 }else
drh70df4fe2006-06-13 15:12:21 +00003276#endif
drh1e397f82006-06-08 15:28:43 +00003277
drhc2ce0be2014-05-29 12:36:14 +00003278 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3279 if( nArg!=2 ){
3280 fprintf(stderr, "Usage: .log FILENAME\n");
3281 rc = 1;
3282 }else{
3283 const char *zFile = azArg[1];
3284 output_file_close(p->pLog);
3285 p->pLog = output_file_open(zFile);
3286 }
drh127f9d72010-02-23 01:47:00 +00003287 }else
3288
drhc2ce0be2014-05-29 12:36:14 +00003289 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3290 const char *zMode = nArg>=2 ? azArg[1] : "";
3291 int n2 = (int)strlen(zMode);
3292 int c2 = zMode[0];
3293 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003294 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003295 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003296 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003297 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003298 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003299 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003300 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003301 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003302 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003303 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003304 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003305 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003306 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003307 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003308 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003309 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003310 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003311 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003312 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003313 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003314 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3315 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003316 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3317 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003318 }else {
shane9bd1b442009-10-23 01:27:39 +00003319 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003320 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003321 rc = 1;
drh75897232000-05-29 14:26:00 +00003322 }
3323 }else
3324
drhc2ce0be2014-05-29 12:36:14 +00003325 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3326 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003327 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3328 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003329 }else{
3330 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003331 rc = 1;
3332 }
3333 }else
3334
drh05782482013-10-24 15:20:20 +00003335 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3336 sqlite3 *savedDb = p->db;
3337 const char *zSavedFilename = p->zDbFilename;
3338 char *zNewFilename = 0;
3339 p->db = 0;
3340 if( nArg>=2 ){
3341 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3342 }
3343 open_db(p, 1);
3344 if( p->db!=0 ){
drhe6229612014-08-18 15:08:26 +00003345 session_close_all(p);
drh05782482013-10-24 15:20:20 +00003346 sqlite3_close(savedDb);
3347 sqlite3_free(p->zFreeOnClose);
3348 p->zFreeOnClose = zNewFilename;
3349 }else{
3350 sqlite3_free(zNewFilename);
3351 p->db = savedDb;
3352 p->zDbFilename = zSavedFilename;
3353 }
3354 }else
3355
drhc2ce0be2014-05-29 12:36:14 +00003356 if( c=='o'
3357 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3358 ){
3359 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3360 if( nArg>2 ){
3361 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3362 rc = 1;
3363 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003364 }
drhc2ce0be2014-05-29 12:36:14 +00003365 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3366 if( nArg<2 ){
3367 fprintf(stderr, "Usage: .once FILE\n");
3368 rc = 1;
3369 goto meta_command_exit;
3370 }
3371 p->outCount = 2;
3372 }else{
3373 p->outCount = 0;
3374 }
3375 output_reset(p);
3376 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003377#ifdef SQLITE_OMIT_POPEN
3378 fprintf(stderr,"Error: pipes are not supported in this OS\n");
3379 rc = 1;
3380 p->out = stdout;
3381#else
drhc2ce0be2014-05-29 12:36:14 +00003382 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003383 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003384 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003385 p->out = stdout;
3386 rc = 1;
3387 }else{
drhc2ce0be2014-05-29 12:36:14 +00003388 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003389 }
drh8cd5b252015-03-02 22:06:43 +00003390#endif
drh75897232000-05-29 14:26:00 +00003391 }else{
drhc2ce0be2014-05-29 12:36:14 +00003392 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003393 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003394 if( strcmp(zFile,"off")!=0 ){
3395 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003396 }
drh75897232000-05-29 14:26:00 +00003397 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003398 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003399 } else {
drhc2ce0be2014-05-29 12:36:14 +00003400 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003401 }
3402 }
3403 }else
3404
drh078b1fd2012-09-21 13:40:02 +00003405 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3406 int i;
3407 for(i=1; i<nArg; i++){
3408 if( i>1 ) fprintf(p->out, " ");
3409 fprintf(p->out, "%s", azArg[i]);
3410 }
3411 fprintf(p->out, "\n");
3412 }else
3413
drhc2ce0be2014-05-29 12:36:14 +00003414 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003415 if( nArg >= 2) {
3416 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3417 }
3418 if( nArg >= 3) {
3419 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3420 }
3421 }else
3422
drhc2ce0be2014-05-29 12:36:14 +00003423 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003424 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003425 }else
3426
drhc2ce0be2014-05-29 12:36:14 +00003427 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3428 FILE *alt;
3429 if( nArg!=2 ){
3430 fprintf(stderr, "Usage: .read FILE\n");
3431 rc = 1;
3432 goto meta_command_exit;
3433 }
3434 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003435 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003436 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3437 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003438 }else{
shane9bd1b442009-10-23 01:27:39 +00003439 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003440 fclose(alt);
3441 }
3442 }else
3443
drhc2ce0be2014-05-29 12:36:14 +00003444 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003445 const char *zSrcFile;
3446 const char *zDb;
3447 sqlite3 *pSrc;
3448 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003449 int nTimeout = 0;
3450
drh9ff849f2009-02-04 20:55:57 +00003451 if( nArg==2 ){
3452 zSrcFile = azArg[1];
3453 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003454 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003455 zSrcFile = azArg[2];
3456 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003457 }else{
3458 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3459 rc = 1;
3460 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003461 }
3462 rc = sqlite3_open(zSrcFile, &pSrc);
3463 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003464 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003465 sqlite3_close(pSrc);
3466 return 1;
3467 }
drh05782482013-10-24 15:20:20 +00003468 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003469 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3470 if( pBackup==0 ){
3471 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3472 sqlite3_close(pSrc);
3473 return 1;
3474 }
drhdc2c4912009-02-04 22:46:47 +00003475 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3476 || rc==SQLITE_BUSY ){
3477 if( rc==SQLITE_BUSY ){
3478 if( nTimeout++ >= 3 ) break;
3479 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003480 }
3481 }
3482 sqlite3_backup_finish(pBackup);
3483 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003484 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003485 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003486 fprintf(stderr, "Error: source database is busy\n");
3487 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003488 }else{
3489 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003490 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003491 }
3492 sqlite3_close(pSrc);
3493 }else
3494
dan8d1edb92014-11-05 09:07:28 +00003495
3496 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3497 if( nArg==2 ){
3498 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003499#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3500 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3501#endif
dan8d1edb92014-11-05 09:07:28 +00003502 }else{
3503 fprintf(stderr, "Usage: .scanstats on|off\n");
3504 rc = 1;
3505 }
3506 }else
3507
drhc2ce0be2014-05-29 12:36:14 +00003508 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003509 ShellState data;
drh75897232000-05-29 14:26:00 +00003510 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003511 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003512 memcpy(&data, p, sizeof(data));
3513 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003514 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003515 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003516 int i;
drhf0693c82011-10-11 20:41:54 +00003517 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003518 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003519 char *new_argv[2], *new_colv[2];
3520 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3521 " type text,\n"
3522 " name text,\n"
3523 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003524 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003525 " sql text\n"
3526 ")";
3527 new_argv[1] = 0;
3528 new_colv[0] = "sql";
3529 new_colv[1] = 0;
3530 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003531 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003532 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003533 char *new_argv[2], *new_colv[2];
3534 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3535 " type text,\n"
3536 " name text,\n"
3537 " tbl_name text,\n"
3538 " rootpage integer,\n"
3539 " sql text\n"
3540 ")";
3541 new_argv[1] = 0;
3542 new_colv[0] = "sql";
3543 new_colv[1] = 0;
3544 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003545 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003546 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003547 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003548 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003549 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003550 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003551 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003552 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003553 "WHERE lower(tbl_name) LIKE shellstatic()"
3554 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003555 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003556 callback, &data, &zErrMsg);
3557 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003558 }
drhc2ce0be2014-05-29 12:36:14 +00003559 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003560 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003561 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003562 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003563 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003564 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003565 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003566 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003567 callback, &data, &zErrMsg
3568 );
drhc2ce0be2014-05-29 12:36:14 +00003569 }else{
3570 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3571 rc = 1;
3572 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003573 }
drh75897232000-05-29 14:26:00 +00003574 if( zErrMsg ){
3575 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003576 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003577 rc = 1;
3578 }else if( rc != SQLITE_OK ){
3579 fprintf(stderr,"Error: querying schema information\n");
3580 rc = 1;
3581 }else{
3582 rc = 0;
drh75897232000-05-29 14:26:00 +00003583 }
3584 }else
3585
drhabd4c722014-09-20 18:18:33 +00003586#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3587 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3588 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003589 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003590 }else
3591#endif
3592
drhe6229612014-08-18 15:08:26 +00003593#if defined(SQLITE_ENABLE_SESSION)
3594 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
3595 OpenSession *pSession = &p->aSession[0];
3596 char **azCmd = &azArg[1];
3597 int iSes = 0;
3598 int nCmd = nArg - 1;
3599 int i;
3600 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00003601 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00003602 if( nArg>=3 ){
3603 for(iSes=0; iSes<p->nSession; iSes++){
3604 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
3605 }
3606 if( iSes<p->nSession ){
3607 pSession = &p->aSession[iSes];
3608 azCmd++;
3609 nCmd--;
3610 }else{
3611 pSession = &p->aSession[0];
3612 iSes = 0;
3613 }
3614 }
3615
drh3a67b042014-08-18 17:56:31 +00003616 /* .session attach TABLE
3617 ** Invoke the sqlite3session_attach() interface to attach a particular
3618 ** table so that it is never filtered.
3619 */
3620 if( strcmp(azCmd[0],"attach")==0 ){
3621 if( nCmd!=2 ) goto session_syntax_error;
3622 if( pSession->p==0 ){
3623 session_not_open:
3624 fprintf(stderr, "ERROR: No sessions are open\n");
3625 }else{
3626 rc = sqlite3session_attach(pSession->p, azCmd[1]);
3627 if( rc ){
3628 fprintf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
3629 rc = 0;
3630 }
3631 }
3632 }else
3633
3634 /* .session changeset FILE
3635 ** .session patchset FILE
3636 ** Write a changeset or patchset into a file. The file is overwritten.
3637 */
3638 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
3639 FILE *out = 0;
3640 if( nCmd!=2 ) goto session_syntax_error;
3641 if( pSession->p==0 ) goto session_not_open;
3642 out = fopen(azCmd[1], "wb");
3643 if( out==0 ){
3644 fprintf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
3645 }else{
3646 int szChng;
3647 void *pChng;
3648 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00003649 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00003650 }else{
drh2967e0c2014-08-19 00:26:17 +00003651 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
3652 }
3653 if( rc ){
3654 printf("Error: error code %d\n", rc);
3655 rc = 0;
drh3a67b042014-08-18 17:56:31 +00003656 }
3657 if( pChng
3658 && fwrite(pChng, szChng, 1, out)!=1 ){
3659 fprintf(stderr, "ERROR: Failed to write entire %d-byte output\n",
3660 szChng);
3661 }
3662 sqlite3_free(pChng);
3663 fclose(out);
3664 }
3665 }else
3666
drhe6229612014-08-18 15:08:26 +00003667 /* .session close
3668 ** Close the identified session
3669 */
3670 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00003671 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00003672 if( p->nSession ){
3673 session_close(pSession);
3674 p->aSession[iSes] = p->aSession[--p->nSession];
3675 }
3676 }else
3677
drh03168ca2014-08-18 20:01:31 +00003678 /* .session enable ?BOOLEAN?
3679 ** Query or set the enable flag
3680 */
3681 if( strcmp(azCmd[0], "enable")==0 ){
3682 int ii;
3683 if( nCmd>2 ) goto session_syntax_error;
3684 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
3685 if( p->nSession ){
3686 ii = sqlite3session_enable(pSession->p, ii);
3687 fprintf(p->out, "session %s enable flag = %d\n", pSession->zName, ii);
3688 }
3689 }else
3690
3691 /* .session filter GLOB ....
3692 ** Set a list of GLOB patterns of table names to be excluded.
3693 */
3694 if( strcmp(azCmd[0], "filter")==0 ){
3695 int ii, nByte;
3696 if( nCmd<2 ) goto session_syntax_error;
3697 if( p->nSession ){
3698 for(ii=0; ii<pSession->nFilter; ii++){
3699 sqlite3_free(pSession->azFilter[ii]);
3700 }
3701 sqlite3_free(pSession->azFilter);
3702 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
3703 pSession->azFilter = sqlite3_malloc( nByte );
3704 if( pSession->azFilter==0 ){
3705 fprintf(stderr, "Error: out or memory\n");
3706 exit(1);
3707 }
3708 for(ii=1; ii<nCmd; ii++){
3709 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
3710 }
3711 pSession->nFilter = ii-1;
3712 }
3713 }else
3714
3715 /* .session indirect ?BOOLEAN?
3716 ** Query or set the indirect flag
3717 */
3718 if( strcmp(azCmd[0], "indirect")==0 ){
3719 int ii;
3720 if( nCmd>2 ) goto session_syntax_error;
3721 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
3722 if( p->nSession ){
3723 ii = sqlite3session_indirect(pSession->p, ii);
3724 fprintf(p->out, "session %s indirect flag = %d\n", pSession->zName,ii);
3725 }
3726 }else
3727
3728 /* .session isempty
3729 ** Determine if the session is empty
3730 */
3731 if( strcmp(azCmd[0], "isempty")==0 ){
3732 int ii;
3733 if( nCmd!=1 ) goto session_syntax_error;
3734 if( p->nSession ){
3735 ii = sqlite3session_isempty(pSession->p);
3736 fprintf(p->out, "session %s isempty flag = %d\n", pSession->zName, ii);
3737 }
3738 }else
3739
drhe6229612014-08-18 15:08:26 +00003740 /* .session list
3741 ** List all currently open sessions
3742 */
3743 if( strcmp(azCmd[0],"list")==0 ){
3744 for(i=0; i<p->nSession; i++){
3745 fprintf(p->out, "%d %s\n", i, p->aSession[i].zName);
3746 }
3747 }else
3748
3749 /* .session open DB NAME
3750 ** Open a new session called NAME on the attached database DB.
3751 ** DB is normally "main".
3752 */
3753 if( strcmp(azCmd[0],"open")==0 ){
3754 char *zName;
3755 if( nCmd!=3 ) goto session_syntax_error;
3756 zName = azCmd[2];
3757 if( zName[0]==0 ) goto session_syntax_error;
3758 for(i=0; i<p->nSession; i++){
3759 if( strcmp(p->aSession[i].zName,zName)==0 ){
3760 fprintf(stderr, "Session \"%s\" already exists\n", zName);
3761 goto meta_command_exit;
3762 }
3763 }
3764 if( p->nSession>=ArraySize(p->aSession) ){
3765 fprintf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
3766 goto meta_command_exit;
3767 }
3768 pSession = &p->aSession[p->nSession];
3769 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
3770 if( rc ){
3771 fprintf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00003772 rc = 0;
drhe6229612014-08-18 15:08:26 +00003773 goto meta_command_exit;
3774 }
drh03168ca2014-08-18 20:01:31 +00003775 pSession->nFilter = 0;
3776 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00003777 p->nSession++;
3778 pSession->zName = sqlite3_mprintf("%s", zName);
3779 }else
3780 /* If no command name matches, show a syntax error */
3781 session_syntax_error:
3782 session_help(p);
3783 }else
3784#endif
3785
drh340f5822013-06-27 13:01:21 +00003786#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003787 /* Undocumented commands for internal testing. Subject to change
3788 ** without notice. */
3789 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3790 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3791 int i, v;
3792 for(i=1; i<nArg; i++){
3793 v = booleanValue(azArg[i]);
3794 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3795 }
3796 }
3797 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3798 int i; sqlite3_int64 v;
3799 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003800 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003801 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003802 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003803 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003804 }
3805 }
3806 }else
drh340f5822013-06-27 13:01:21 +00003807#endif
drh348d19c2013-06-03 12:47:43 +00003808
drhc2ce0be2014-05-29 12:36:14 +00003809 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003810 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003811 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003812 rc = 1;
3813 }
drh6976c212014-07-24 12:09:47 +00003814 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003815 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003816 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003817 }
3818 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003819 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3820 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00003821 }
drh75897232000-05-29 14:26:00 +00003822 }else
3823
drh62cdde52014-05-28 20:22:28 +00003824 if( c=='s'
3825 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003826 ){
3827 char *zCmd;
drh54027102014-08-06 14:36:53 +00003828 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003829 if( nArg<2 ){
3830 fprintf(stderr, "Usage: .system COMMAND\n");
3831 rc = 1;
3832 goto meta_command_exit;
3833 }
drhdcb3e3d2014-05-29 03:17:29 +00003834 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003835 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003836 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3837 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003838 }
drh54027102014-08-06 14:36:53 +00003839 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003840 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003841 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003842 }else
3843
drhc2ce0be2014-05-29 12:36:14 +00003844 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003845 int i;
drhc2ce0be2014-05-29 12:36:14 +00003846 if( nArg!=1 ){
3847 fprintf(stderr, "Usage: .show\n");
3848 rc = 1;
3849 goto meta_command_exit;
3850 }
mistachkin636bf9f2014-07-19 20:15:16 +00003851 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3852 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003853 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003854 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3855 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3856 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003857 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003858 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003859 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003860 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003861 fprintf(p->out,"%12.12s: ", "colseparator");
3862 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003863 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003864 fprintf(p->out,"%12.12s: ", "rowseparator");
3865 output_c_string(p->out, p->rowSeparator);
3866 fprintf(p->out, "\n");
3867 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3868 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003869 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003870 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003871 }
drhfeac5f82004-08-01 00:10:45 +00003872 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003873 }else
3874
drhc2ce0be2014-05-29 12:36:14 +00003875 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3876 if( nArg==2 ){
3877 p->statsOn = booleanValue(azArg[1]);
3878 }else{
3879 fprintf(stderr, "Usage: .stats on|off\n");
3880 rc = 1;
3881 }
shaneh642d8b82010-07-28 16:05:34 +00003882 }else
3883
drhc2ce0be2014-05-29 12:36:14 +00003884 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003885 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003886 char **azResult;
drh98781232012-04-23 12:38:05 +00003887 int nRow, nAlloc;
3888 char *zSql = 0;
3889 int ii;
drh05782482013-10-24 15:20:20 +00003890 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003891 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3892 if( rc ) return rc;
3893 zSql = sqlite3_mprintf(
3894 "SELECT name FROM sqlite_master"
3895 " WHERE type IN ('table','view')"
3896 " AND name NOT LIKE 'sqlite_%%'"
3897 " AND name LIKE ?1");
3898 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3899 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3900 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3901 if( strcmp(zDbName,"temp")==0 ){
3902 zSql = sqlite3_mprintf(
3903 "%z UNION ALL "
3904 "SELECT 'temp.' || name FROM sqlite_temp_master"
3905 " WHERE type IN ('table','view')"
3906 " AND name NOT LIKE 'sqlite_%%'"
3907 " AND name LIKE ?1", zSql);
3908 }else{
3909 zSql = sqlite3_mprintf(
3910 "%z UNION ALL "
3911 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3912 " WHERE type IN ('table','view')"
3913 " AND name NOT LIKE 'sqlite_%%'"
3914 " AND name LIKE ?1", zSql, zDbName, zDbName);
3915 }
drha50da102000-08-08 20:19:09 +00003916 }
drh98781232012-04-23 12:38:05 +00003917 sqlite3_finalize(pStmt);
3918 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3919 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3920 sqlite3_free(zSql);
3921 if( rc ) return rc;
3922 nRow = nAlloc = 0;
3923 azResult = 0;
3924 if( nArg>1 ){
3925 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003926 }else{
drh98781232012-04-23 12:38:05 +00003927 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3928 }
3929 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3930 if( nRow>=nAlloc ){
3931 char **azNew;
3932 int n = nAlloc*2 + 10;
3933 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3934 if( azNew==0 ){
3935 fprintf(stderr, "Error: out of memory\n");
3936 break;
3937 }
3938 nAlloc = n;
3939 azResult = azNew;
3940 }
3941 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3942 if( azResult[nRow] ) nRow++;
3943 }
3944 sqlite3_finalize(pStmt);
3945 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003946 int len, maxlen = 0;
3947 int i, j;
3948 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003949 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003950 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003951 if( len>maxlen ) maxlen = len;
3952 }
3953 nPrintCol = 80/(maxlen+2);
3954 if( nPrintCol<1 ) nPrintCol = 1;
3955 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3956 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003957 for(j=i; j<nRow; j+=nPrintRow){
3958 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003959 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003960 }
drh151b7d52013-05-06 20:28:54 +00003961 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003962 }
3963 }
drh98781232012-04-23 12:38:05 +00003964 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3965 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003966 }else
3967
shaneh96887e12011-02-10 21:08:58 +00003968 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003969 static const struct {
3970 const char *zCtrlName; /* Name of a test-control option */
3971 int ctrlCode; /* Integer code for that option */
3972 } aCtrl[] = {
3973 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3974 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3975 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3976 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3977 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3978 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3979 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3980 { "assert", SQLITE_TESTCTRL_ASSERT },
3981 { "always", SQLITE_TESTCTRL_ALWAYS },
3982 { "reserve", SQLITE_TESTCTRL_RESERVE },
3983 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3984 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003985 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003986 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003987 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003988 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003989 };
shaneh96887e12011-02-10 21:08:58 +00003990 int testctrl = -1;
3991 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00003992 int i, n;
drh05782482013-10-24 15:20:20 +00003993 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003994
drhd416fe72011-03-17 16:45:50 +00003995 /* convert testctrl text option to value. allow any unique prefix
3996 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00003997 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003998 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00003999 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
4000 if( testctrl<0 ){
4001 testctrl = aCtrl[i].ctrlCode;
4002 }else{
drhb07028f2011-10-14 21:49:18 +00004003 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00004004 testctrl = -1;
4005 break;
4006 }
4007 }
4008 }
drh348d19c2013-06-03 12:47:43 +00004009 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004010 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
4011 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
4012 }else{
4013 switch(testctrl){
4014
4015 /* sqlite3_test_control(int, db, int) */
4016 case SQLITE_TESTCTRL_OPTIMIZATIONS:
4017 case SQLITE_TESTCTRL_RESERVE:
4018 if( nArg==3 ){
4019 int opt = (int)strtol(azArg[2], 0, 0);
4020 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00004021 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00004022 } else {
drhd416fe72011-03-17 16:45:50 +00004023 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
4024 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004025 }
4026 break;
4027
4028 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004029 case SQLITE_TESTCTRL_PRNG_SAVE:
4030 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004031 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004032 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004033 if( nArg==2 ){
4034 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00004035 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00004036 } else {
4037 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
4038 }
4039 break;
4040
4041 /* sqlite3_test_control(int, uint) */
4042 case SQLITE_TESTCTRL_PENDING_BYTE:
4043 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004044 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00004045 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00004046 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00004047 } else {
drhd416fe72011-03-17 16:45:50 +00004048 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
4049 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004050 }
4051 break;
4052
4053 /* sqlite3_test_control(int, int) */
4054 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00004055 case SQLITE_TESTCTRL_ALWAYS:
4056 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004057 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00004058 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00004059 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00004060 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00004061 } else {
drhd416fe72011-03-17 16:45:50 +00004062 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
4063 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004064 }
4065 break;
4066
4067 /* sqlite3_test_control(int, char *) */
4068#ifdef SQLITE_N_KEYWORD
4069 case SQLITE_TESTCTRL_ISKEYWORD:
4070 if( nArg==3 ){
4071 const char *opt = azArg[2];
4072 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00004073 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00004074 } else {
drhd416fe72011-03-17 16:45:50 +00004075 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
4076 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004077 }
4078 break;
4079#endif
4080
drh1ffede82015-01-30 20:59:27 +00004081 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004082 if( nArg==5 ){
4083 rc = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004084 azArg[2],
drh8964b342015-01-29 17:54:52 +00004085 integerValue(azArg[3]),
4086 integerValue(azArg[4]));
drh6f5a37a2015-03-27 02:27:20 +00004087 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
drh8964b342015-01-29 17:54:52 +00004088 }else{
drh6f5a37a2015-03-27 02:27:20 +00004089 fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004090 }
4091 break;
4092
shaneh96887e12011-02-10 21:08:58 +00004093 case SQLITE_TESTCTRL_BITVEC_TEST:
4094 case SQLITE_TESTCTRL_FAULT_INSTALL:
4095 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4096 case SQLITE_TESTCTRL_SCRATCHMALLOC:
4097 default:
drhd416fe72011-03-17 16:45:50 +00004098 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
4099 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004100 break;
4101 }
4102 }
4103 }else
4104
drhc2ce0be2014-05-29 12:36:14 +00004105 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004106 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004107 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004108 }else
4109
drhc2ce0be2014-05-29 12:36:14 +00004110 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4111 if( nArg==2 ){
4112 enableTimer = booleanValue(azArg[1]);
4113 if( enableTimer && !HAS_TIMER ){
4114 fprintf(stderr, "Error: timer not available on this system.\n");
4115 enableTimer = 0;
4116 }
4117 }else{
4118 fprintf(stderr, "Usage: .timer on|off\n");
4119 rc = 1;
4120 }
shanehe2aa9d72009-11-06 17:20:17 +00004121 }else
4122
drhc2ce0be2014-05-29 12:36:14 +00004123 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004124 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004125 if( nArg!=2 ){
4126 fprintf(stderr, "Usage: .trace FILE|off\n");
4127 rc = 1;
4128 goto meta_command_exit;
4129 }
drh657b4a82015-03-19 13:30:41 +00004130 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004131 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004132#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004133 if( p->traceOut==0 ){
4134 sqlite3_trace(p->db, 0, 0);
4135 }else{
4136 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
4137 }
4138#endif
4139 }else
4140
drhf442e332014-09-10 19:01:14 +00004141#if SQLITE_USER_AUTHENTICATION
4142 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4143 if( nArg<2 ){
4144 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
4145 rc = 1;
4146 goto meta_command_exit;
4147 }
drh7883ecf2014-09-11 16:19:31 +00004148 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004149 if( strcmp(azArg[1],"login")==0 ){
4150 if( nArg!=4 ){
4151 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
4152 rc = 1;
4153 goto meta_command_exit;
4154 }
drhd39c40f2014-09-11 00:27:53 +00004155 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4156 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004157 if( rc ){
4158 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
4159 rc = 1;
4160 }
4161 }else if( strcmp(azArg[1],"add")==0 ){
4162 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00004163 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004164 rc = 1;
4165 goto meta_command_exit;
4166 }
drhd39c40f2014-09-11 00:27:53 +00004167 rc = sqlite3_user_add(p->db, azArg[2],
4168 azArg[3], (int)strlen(azArg[3]),
4169 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004170 if( rc ){
4171 fprintf(stderr, "User-Add failed: %d\n", rc);
4172 rc = 1;
4173 }
4174 }else if( strcmp(azArg[1],"edit")==0 ){
4175 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00004176 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004177 rc = 1;
4178 goto meta_command_exit;
4179 }
drhd39c40f2014-09-11 00:27:53 +00004180 rc = sqlite3_user_change(p->db, azArg[2],
4181 azArg[3], (int)strlen(azArg[3]),
4182 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004183 if( rc ){
4184 fprintf(stderr, "User-Edit failed: %d\n", rc);
4185 rc = 1;
4186 }
4187 }else if( strcmp(azArg[1],"delete")==0 ){
4188 if( nArg!=3 ){
4189 fprintf(stderr, "Usage: .user delete USER\n");
4190 rc = 1;
4191 goto meta_command_exit;
4192 }
4193 rc = sqlite3_user_delete(p->db, azArg[2]);
4194 if( rc ){
4195 fprintf(stderr, "User-Delete failed: %d\n", rc);
4196 rc = 1;
4197 }
4198 }else{
4199 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
4200 rc = 1;
4201 goto meta_command_exit;
4202 }
4203 }else
4204#endif /* SQLITE_USER_AUTHENTICATION */
4205
drh9fd301b2011-06-03 13:28:22 +00004206 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00004207 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004208 sqlite3_libversion(), sqlite3_sourceid());
4209 }else
4210
drhde60fc22011-12-14 17:53:36 +00004211 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4212 const char *zDbName = nArg==2 ? azArg[1] : "main";
4213 char *zVfsName = 0;
4214 if( p->db ){
4215 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4216 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00004217 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004218 sqlite3_free(zVfsName);
4219 }
4220 }
4221 }else
4222
drhcef4fc82012-09-21 22:50:45 +00004223#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4224 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
4225 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00004226 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004227 }else
4228#endif
4229
drhc2ce0be2014-05-29 12:36:14 +00004230 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004231 int j;
drh43617e92006-03-06 20:55:46 +00004232 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004233 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004234 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004235 }
4236 }else
4237
4238 {
shane9bd1b442009-10-23 01:27:39 +00004239 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004240 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004241 rc = 1;
drh75897232000-05-29 14:26:00 +00004242 }
drh67505e72002-04-19 12:34:06 +00004243
drhc2ce0be2014-05-29 12:36:14 +00004244meta_command_exit:
4245 if( p->outCount ){
4246 p->outCount--;
4247 if( p->outCount==0 ) output_reset(p);
4248 }
drh67505e72002-04-19 12:34:06 +00004249 return rc;
drh75897232000-05-29 14:26:00 +00004250}
4251
drh67505e72002-04-19 12:34:06 +00004252/*
drh91a66392007-09-07 01:12:32 +00004253** Return TRUE if a semicolon occurs anywhere in the first N characters
4254** of string z[].
drh324ccef2003-02-05 14:06:20 +00004255*/
drh9f099fd2013-08-06 14:01:46 +00004256static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004257 int i;
4258 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4259 return 0;
drh324ccef2003-02-05 14:06:20 +00004260}
4261
4262/*
drh70c7a4b2003-04-26 03:03:06 +00004263** Test to see if a line consists entirely of whitespace.
4264*/
4265static int _all_whitespace(const char *z){
4266 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004267 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004268 if( *z=='/' && z[1]=='*' ){
4269 z += 2;
4270 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4271 if( *z==0 ) return 0;
4272 z++;
4273 continue;
4274 }
4275 if( *z=='-' && z[1]=='-' ){
4276 z += 2;
4277 while( *z && *z!='\n' ){ z++; }
4278 if( *z==0 ) return 1;
4279 continue;
4280 }
4281 return 0;
4282 }
4283 return 1;
4284}
4285
4286/*
drha9b17162003-04-29 18:01:28 +00004287** Return TRUE if the line typed in is an SQL command terminator other
4288** than a semi-colon. The SQL Server style "go" command is understood
4289** as is the Oracle "/".
4290*/
drh9f099fd2013-08-06 14:01:46 +00004291static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004292 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004293 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4294 return 1; /* Oracle */
4295 }
drhf0693c82011-10-11 20:41:54 +00004296 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004297 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004298 return 1; /* SQL Server */
4299 }
4300 return 0;
4301}
4302
4303/*
drh233a5312008-12-18 22:25:13 +00004304** Return true if zSql is a complete SQL statement. Return false if it
4305** ends in the middle of a string literal or C-style comment.
4306*/
drh9f099fd2013-08-06 14:01:46 +00004307static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004308 int rc;
4309 if( zSql==0 ) return 1;
4310 zSql[nSql] = ';';
4311 zSql[nSql+1] = 0;
4312 rc = sqlite3_complete(zSql);
4313 zSql[nSql] = 0;
4314 return rc;
4315}
4316
4317/*
drh67505e72002-04-19 12:34:06 +00004318** Read input from *in and process it. If *in==0 then input
4319** is interactive - the user is typing it it. Otherwise, input
4320** is coming from a file or device. A prompt is issued and history
4321** is saved only if input is interactive. An interrupt signal will
4322** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004323**
4324** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004325*/
drhdcd87a92014-08-18 13:45:42 +00004326static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004327 char *zLine = 0; /* A single input line */
4328 char *zSql = 0; /* Accumulated SQL text */
4329 int nLine; /* Length of current line */
4330 int nSql = 0; /* Bytes of zSql[] used */
4331 int nAlloc = 0; /* Allocated zSql[] space */
4332 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4333 char *zErrMsg; /* Error message returned */
4334 int rc; /* Error code */
4335 int errCnt = 0; /* Number of errors seen */
4336 int lineno = 0; /* Current line number */
4337 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004338
4339 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4340 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004341 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004342 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004343 /* End of input */
4344 if( stdin_is_interactive ) printf("\n");
4345 break;
drhc49f44e2006-10-26 18:15:42 +00004346 }
drh67505e72002-04-19 12:34:06 +00004347 if( seenInterrupt ){
4348 if( in!=0 ) break;
4349 seenInterrupt = 0;
4350 }
drhc28490c2006-10-26 14:25:58 +00004351 lineno++;
drh849a9d92013-12-21 15:46:06 +00004352 if( nSql==0 && _all_whitespace(zLine) ){
4353 if( p->echoOn ) printf("%s\n", zLine);
4354 continue;
4355 }
drh2af0b2d2002-02-21 02:25:02 +00004356 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004357 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004358 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004359 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004360 break;
4361 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004362 errCnt++;
4363 }
drhdaffd0e2001-04-11 14:28:42 +00004364 continue;
4365 }
drh9f099fd2013-08-06 14:01:46 +00004366 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004367 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004368 }
drh9f099fd2013-08-06 14:01:46 +00004369 nLine = strlen30(zLine);
4370 if( nSql+nLine+2>=nAlloc ){
4371 nAlloc = nSql+nLine+100;
4372 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004373 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004374 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004375 exit(1);
4376 }
drhdaffd0e2001-04-11 14:28:42 +00004377 }
drh9f099fd2013-08-06 14:01:46 +00004378 nSqlPrior = nSql;
4379 if( nSql==0 ){
4380 int i;
4381 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004382 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004383 memcpy(zSql, zLine+i, nLine+1-i);
4384 startline = lineno;
4385 nSql = nLine-i;
4386 }else{
4387 zSql[nSql++] = '\n';
4388 memcpy(zSql+nSql, zLine, nLine+1);
4389 nSql += nLine;
4390 }
4391 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004392 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004393 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004394 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00004395 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004396 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004397 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004398 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004399 char zPrefix[100];
4400 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004401 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004402 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004403 }else{
shane9bd1b442009-10-23 01:27:39 +00004404 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004405 }
drh7f953e22002-07-13 17:33:45 +00004406 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004407 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004408 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004409 zErrMsg = 0;
4410 }else{
shaned2bed1c2009-10-21 03:56:54 +00004411 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004412 }
drhc49f44e2006-10-26 18:15:42 +00004413 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00004414 }
drhdaffd0e2001-04-11 14:28:42 +00004415 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004416 if( p->outCount ){
4417 output_reset(p);
4418 p->outCount = 0;
4419 }
drh9f099fd2013-08-06 14:01:46 +00004420 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004421 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004422 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004423 }
4424 }
drh9f099fd2013-08-06 14:01:46 +00004425 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004426 if( !_all_whitespace(zSql) ){
4427 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004428 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004429 }
drhdaffd0e2001-04-11 14:28:42 +00004430 free(zSql);
4431 }
danielk19772ac27622007-07-03 05:31:16 +00004432 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004433 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004434}
4435
drh67505e72002-04-19 12:34:06 +00004436/*
4437** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004438** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004439*/
4440static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004441 static char *home_dir = NULL;
4442 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004443
drh4ace5362014-11-10 14:42:28 +00004444#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4445 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004446 {
4447 struct passwd *pwent;
4448 uid_t uid = getuid();
4449 if( (pwent=getpwuid(uid)) != NULL) {
4450 home_dir = pwent->pw_dir;
4451 }
drh67505e72002-04-19 12:34:06 +00004452 }
4453#endif
4454
chw65d3c132007-11-12 21:09:10 +00004455#if defined(_WIN32_WCE)
4456 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4457 */
drh85e72432012-04-11 11:38:53 +00004458 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004459#else
4460
drh83905c92012-06-21 13:00:37 +00004461#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004462 if (!home_dir) {
4463 home_dir = getenv("USERPROFILE");
4464 }
4465#endif
4466
drh67505e72002-04-19 12:34:06 +00004467 if (!home_dir) {
4468 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004469 }
4470
drh83905c92012-06-21 13:00:37 +00004471#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004472 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004473 char *zDrive, *zPath;
4474 int n;
4475 zDrive = getenv("HOMEDRIVE");
4476 zPath = getenv("HOMEPATH");
4477 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004478 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004479 home_dir = malloc( n );
4480 if( home_dir==0 ) return 0;
4481 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4482 return home_dir;
4483 }
4484 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004485 }
4486#endif
4487
chw65d3c132007-11-12 21:09:10 +00004488#endif /* !_WIN32_WCE */
4489
drh67505e72002-04-19 12:34:06 +00004490 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004491 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004492 char *z = malloc( n );
4493 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004494 home_dir = z;
4495 }
drhe98d4fa2002-04-21 19:06:22 +00004496
drh67505e72002-04-19 12:34:06 +00004497 return home_dir;
4498}
4499
4500/*
4501** Read input from the file given by sqliterc_override. Or if that
4502** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004503**
4504** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004505*/
drh534f4df2015-02-28 14:03:35 +00004506static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004507 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004508 const char *sqliterc_override /* Name of config file. NULL to use default */
4509){
persicom7e2dfdd2002-04-18 02:46:52 +00004510 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004511 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004512 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004513 FILE *in = NULL;
4514
4515 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004516 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004517 if( home_dir==0 ){
drh534f4df2015-02-28 14:03:35 +00004518 fprintf(stderr, "-- warning: cannot find home directory;"
4519 " cannot read ~/.sqliterc\n");
4520 return;
drhe98d4fa2002-04-21 19:06:22 +00004521 }
drh2f3de322012-06-27 16:41:31 +00004522 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004523 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4524 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004525 }
drha1f9b5e2004-02-14 16:31:02 +00004526 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004527 if( in ){
drhc28490c2006-10-26 14:25:58 +00004528 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004529 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004530 }
drh534f4df2015-02-28 14:03:35 +00004531 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004532 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004533 }
drh85e72432012-04-11 11:38:53 +00004534 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004535}
4536
drh67505e72002-04-19 12:34:06 +00004537/*
drhe1e38c42003-05-04 18:30:59 +00004538** Show available command line options
4539*/
4540static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004541 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004542 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004543 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004544 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004545 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004546 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004547 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004548 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004549 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004550#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4551 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4552#endif
drhcc3b4f82012-02-07 14:13:50 +00004553 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004554 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004555 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004556 " -line set output mode to 'line'\n"
4557 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004558 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004559 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004560#ifdef SQLITE_ENABLE_MULTIPLEX
4561 " -multiplex enable the multiplexor VFS\n"
4562#endif
mistachkine0d68852014-12-11 03:12:33 +00004563 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004564 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004565 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4566 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004567 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004568 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004569 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004570 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004571#ifdef SQLITE_ENABLE_VFSTRACE
4572 " -vfstrace enable tracing of all VFS calls\n"
4573#endif
drhe1e38c42003-05-04 18:30:59 +00004574;
4575static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004576 fprintf(stderr,
4577 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4578 "FILENAME is the name of an SQLite database. A new database is created\n"
4579 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004580 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004581 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004582 }else{
4583 fprintf(stderr, "Use the -help option for additional information\n");
4584 }
4585 exit(1);
4586}
4587
4588/*
drh67505e72002-04-19 12:34:06 +00004589** Initialize the state information in data
4590*/
drhdcd87a92014-08-18 13:45:42 +00004591static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004592 memset(data, 0, sizeof(*data));
4593 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004594 memcpy(data->colSeparator,SEP_Column, 2);
4595 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004596 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004597 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004598 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004599 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004600 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004601 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4602 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004603}
4604
drh98d312f2012-10-25 15:23:14 +00004605/*
drh5c7976f2014-02-10 19:59:27 +00004606** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004607*/
4608#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004609static void printBold(const char *zText){
4610 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4611 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4612 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4613 SetConsoleTextAttribute(out,
4614 FOREGROUND_RED|FOREGROUND_INTENSITY
4615 );
4616 printf("%s", zText);
4617 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004618}
4619#else
drh5c7976f2014-02-10 19:59:27 +00004620static void printBold(const char *zText){
4621 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004622}
4623#endif
4624
4625/*
drh98d312f2012-10-25 15:23:14 +00004626** Get the argument to an --option. Throw an error and die if no argument
4627** is available.
4628*/
4629static char *cmdline_option_value(int argc, char **argv, int i){
4630 if( i==argc ){
4631 fprintf(stderr, "%s: Error: missing argument to %s\n",
4632 argv[0], argv[argc-1]);
4633 exit(1);
4634 }
4635 return argv[i];
4636}
4637
mistachkin44723ce2015-03-21 02:22:37 +00004638int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004639 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004640 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004641 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004642 int i;
drhc28490c2006-10-26 14:25:58 +00004643 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004644 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004645 int readStdin = 1;
4646 int nCmd = 0;
4647 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004648
drh69b30ab2014-02-27 15:11:52 +00004649#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004650 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4651 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4652 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4653 exit(1);
4654 }
drhc7181902014-02-27 15:04:13 +00004655#endif
drh047d4532015-01-18 20:30:23 +00004656 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004657 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004658 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004659 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004660 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004661
drh44c2eb12003-04-30 11:38:26 +00004662 /* Make sure we have a valid signal handler early, before anything
4663 ** else is done.
4664 */
drh4c504392000-10-16 22:06:40 +00004665#ifdef SIGINT
4666 signal(SIGINT, interrupt_handler);
4667#endif
drh44c2eb12003-04-30 11:38:26 +00004668
drhac5649a2014-11-28 13:35:03 +00004669#ifdef SQLITE_SHELL_DBNAME_PROC
4670 {
4671 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4672 ** of a C-function that will provide the name of the database file. Use
4673 ** this compile-time option to embed this shell program in larger
4674 ** applications. */
4675 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4676 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4677 warnInmemoryDb = 0;
4678 }
4679#endif
4680
drh22fbcb82004-02-01 01:22:50 +00004681 /* Do an initial pass through the command-line argument to locate
4682 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004683 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004684 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004685 */
drh98d312f2012-10-25 15:23:14 +00004686 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004687 char *z;
drhc28490c2006-10-26 14:25:58 +00004688 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004689 if( z[0]!='-' ){
4690 if( data.zDbFilename==0 ){
4691 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004692 }else{
4693 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4694 ** mean that nothing is read from stdin */
4695 readStdin = 0;
4696 nCmd++;
4697 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4698 if( azCmd==0 ){
4699 fprintf(stderr, "out of memory\n");
4700 exit(1);
4701 }
4702 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004703 }
drh98d312f2012-10-25 15:23:14 +00004704 }
drhcc3b4f82012-02-07 14:13:50 +00004705 if( z[1]=='-' ) z++;
4706 if( strcmp(z,"-separator")==0
4707 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004708 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004709 || strcmp(z,"-cmd")==0
4710 ){
drh98d312f2012-10-25 15:23:14 +00004711 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004712 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004713 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004714 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004715 /* Need to check for batch mode here to so we can avoid printing
4716 ** informational messages (like from process_sqliterc) before
4717 ** we do the actual processing of arguments later in a second pass.
4718 */
shanef69573d2009-10-24 02:06:14 +00004719 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004720 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004721#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004722 const char *zSize;
4723 sqlite3_int64 szHeap;
4724
drh98d312f2012-10-25 15:23:14 +00004725 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004726 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004727 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004728 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4729#endif
drh44dec872014-08-30 15:49:25 +00004730 }else if( strcmp(z,"-scratch")==0 ){
4731 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004732 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004733 if( sz>400000 ) sz = 400000;
4734 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004735 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004736 if( n>10 ) n = 10;
4737 if( n<1 ) n = 1;
4738 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4739 data.shellFlgs |= SHFLG_Scratch;
4740 }else if( strcmp(z,"-pagecache")==0 ){
4741 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004742 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004743 if( sz>70000 ) sz = 70000;
4744 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004745 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004746 if( n<10 ) n = 10;
4747 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4748 data.shellFlgs |= SHFLG_Pagecache;
4749 }else if( strcmp(z,"-lookaside")==0 ){
4750 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004751 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004752 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004753 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004754 if( n<0 ) n = 0;
4755 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4756 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004757#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004758 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004759 extern int vfstrace_register(
4760 const char *zTraceName,
4761 const char *zOldVfsName,
4762 int (*xOut)(const char*,void*),
4763 void *pOutArg,
4764 int makeDefault
4765 );
drh2b625e22011-03-16 17:05:28 +00004766 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004767#endif
drh6f25e892011-07-08 17:02:57 +00004768#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004769 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004770 extern int sqlite3_multiple_initialize(const char*,int);
4771 sqlite3_multiplex_initialize(0, 1);
4772#endif
drh7d9f3942013-04-03 01:26:54 +00004773 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004774 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4775 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004776 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004777 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004778 if( pVfs ){
4779 sqlite3_vfs_register(pVfs, 1);
4780 }else{
4781 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4782 exit(1);
4783 }
drh44c2eb12003-04-30 11:38:26 +00004784 }
4785 }
drh98d312f2012-10-25 15:23:14 +00004786 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004787#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004788 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004789 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004790#else
shane86f5bdb2009-10-24 02:00:07 +00004791 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4792 return 1;
drh01b41712005-08-29 23:06:23 +00004793#endif
drh98d312f2012-10-25 15:23:14 +00004794 }
4795 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004796
drh44c2eb12003-04-30 11:38:26 +00004797 /* Go ahead and open the database file if it already exists. If the
4798 ** file does not exist, delay opening it. This prevents empty database
4799 ** files from being created if a user mistypes the database name argument
4800 ** to the sqlite command-line tool.
4801 */
drhc8d74412004-08-31 23:41:26 +00004802 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004803 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004804 }
4805
drh22fbcb82004-02-01 01:22:50 +00004806 /* Process the initialization file if there is one. If no -init option
4807 ** is given on the command line, look for a file named ~/.sqliterc and
4808 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004809 */
drh534f4df2015-02-28 14:03:35 +00004810 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004811
drh22fbcb82004-02-01 01:22:50 +00004812 /* Make a second pass through the command-line argument and set
4813 ** options. This second pass is delayed until after the initialization
4814 ** file is processed so that the command-line arguments will override
4815 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004816 */
drh98d312f2012-10-25 15:23:14 +00004817 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004818 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004819 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004820 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004821 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004822 i++;
4823 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004824 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004825 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004826 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004827 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004828 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004829 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004830 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004831 }else if( strcmp(z,"-csv")==0 ){
4832 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004833 memcpy(data.colSeparator,",",2);
4834 }else if( strcmp(z,"-ascii")==0 ){
4835 data.mode = MODE_Ascii;
4836 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004837 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004838 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004839 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00004840 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004841 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00004842 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004843 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004844 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004845 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004846 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004847 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004848 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004849 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004850 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004851 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004852 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004853 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004854 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004855 }else if( strcmp(z,"-eqp")==0 ){
4856 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004857 }else if( strcmp(z,"-stats")==0 ){
4858 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004859 }else if( strcmp(z,"-scanstats")==0 ){
4860 data.scanstatsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004861 }else if( strcmp(z,"-bail")==0 ){
4862 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004863 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004864 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004865 return 0;
drhc28490c2006-10-26 14:25:58 +00004866 }else if( strcmp(z,"-interactive")==0 ){
4867 stdin_is_interactive = 1;
4868 }else if( strcmp(z,"-batch")==0 ){
4869 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004870 }else if( strcmp(z,"-heap")==0 ){
4871 i++;
drh44dec872014-08-30 15:49:25 +00004872 }else if( strcmp(z,"-scratch")==0 ){
4873 i+=2;
4874 }else if( strcmp(z,"-pagecache")==0 ){
4875 i+=2;
4876 }else if( strcmp(z,"-lookaside")==0 ){
4877 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004878 }else if( strcmp(z,"-mmap")==0 ){
4879 i++;
drha7e61d82011-03-12 17:02:57 +00004880 }else if( strcmp(z,"-vfs")==0 ){
4881 i++;
drh6f25e892011-07-08 17:02:57 +00004882#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004883 }else if( strcmp(z,"-vfstrace")==0 ){
4884 i++;
drh6f25e892011-07-08 17:02:57 +00004885#endif
4886#ifdef SQLITE_ENABLE_MULTIPLEX
4887 }else if( strcmp(z,"-multiplex")==0 ){
4888 i++;
4889#endif
drhcc3b4f82012-02-07 14:13:50 +00004890 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004891 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004892 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004893 /* Run commands that follow -cmd first and separately from commands
4894 ** that simply appear on the command-line. This seems goofy. It would
4895 ** be better if all commands ran in the order that they appear. But
4896 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004897 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004898 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004899 if( z[0]=='.' ){
4900 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004901 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004902 }else{
drh05782482013-10-24 15:20:20 +00004903 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004904 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4905 if( zErrMsg!=0 ){
4906 fprintf(stderr,"Error: %s\n", zErrMsg);
4907 if( bail_on_error ) return rc!=0 ? rc : 1;
4908 }else if( rc!=0 ){
4909 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4910 if( bail_on_error ) return rc;
4911 }
4912 }
drh1e5d0e92000-05-31 23:33:17 +00004913 }else{
shane86f5bdb2009-10-24 02:00:07 +00004914 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004915 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004916 return 1;
4917 }
4918 }
drh44c2eb12003-04-30 11:38:26 +00004919
drhac5649a2014-11-28 13:35:03 +00004920 if( !readStdin ){
4921 /* Run all arguments that do not begin with '-' as if they were separate
4922 ** command-line inputs, except for the argToSkip argument which contains
4923 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004924 */
drhac5649a2014-11-28 13:35:03 +00004925 for(i=0; i<nCmd; i++){
4926 if( azCmd[i][0]=='.' ){
4927 rc = do_meta_command(azCmd[i], &data);
4928 if( rc ) return rc==2 ? 0 : rc;
4929 }else{
4930 open_db(&data, 0);
4931 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4932 if( zErrMsg!=0 ){
4933 fprintf(stderr,"Error: %s\n", zErrMsg);
4934 return rc!=0 ? rc : 1;
4935 }else if( rc!=0 ){
4936 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4937 return rc;
4938 }
drh6ff13852001-11-25 13:18:23 +00004939 }
drh75897232000-05-29 14:26:00 +00004940 }
drhac5649a2014-11-28 13:35:03 +00004941 free(azCmd);
drh75897232000-05-29 14:26:00 +00004942 }else{
drh44c2eb12003-04-30 11:38:26 +00004943 /* Run commands received from standard input
4944 */
drhc28490c2006-10-26 14:25:58 +00004945 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004946 char *zHome;
4947 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004948 int nHistory;
drh75897232000-05-29 14:26:00 +00004949 printf(
drh743e0032011-12-12 16:51:50 +00004950 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004951 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004952 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004953 );
drhb3735912014-02-10 16:13:42 +00004954 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004955 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004956 printBold("transient in-memory database");
4957 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004958 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004959 }
drh67505e72002-04-19 12:34:06 +00004960 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004961 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004962 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004963 if( (zHistory = malloc(nHistory))!=0 ){
4964 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4965 }
drh67505e72002-04-19 12:34:06 +00004966 }
danfd34d6d2015-02-25 10:54:53 +00004967 if( zHistory ) shell_read_history(zHistory);
drhc28490c2006-10-26 14:25:58 +00004968 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004969 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004970 shell_stifle_history(100);
4971 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004972 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004973 }
drhdaffd0e2001-04-11 14:28:42 +00004974 }else{
drhc28490c2006-10-26 14:25:58 +00004975 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004976 }
4977 }
drh33048c02001-10-01 14:29:22 +00004978 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004979 if( data.db ){
drhe6229612014-08-18 15:08:26 +00004980 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00004981 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004982 }
drh05782482013-10-24 15:20:20 +00004983 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004984 return rc;
drh75897232000-05-29 14:26:00 +00004985}