blob: c6317e99fd348843f5fbdc64cc0b1d350a2778b0 [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*/
mistachkin8e189222015-04-19 21:43:16 +0000339static sqlite3 *globalDb = 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 */
drh9569f602015-04-16 15:05:04 +0000543 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000544 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000545 int cnt; /* Number of records displayed so far */
546 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000547 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000548 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000549 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000550 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000551 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000552 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000553 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000554 char colSeparator[20]; /* Column separator character for several modes */
555 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000556 int colWidth[100]; /* Requested width of each column when in column mode*/
557 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000558 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000559 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000560 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000561 char outfile[FILENAME_MAX]; /* Filename for *out */
562 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000563 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000564 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000565 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000566 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000567 int *aiIndent; /* Array of indents used in MODE_Explain */
568 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000569 int iIndent; /* Index of current op in aiIndent[] */
drhe6229612014-08-18 15:08:26 +0000570#if defined(SQLITE_ENABLE_SESSION)
571 int nSession; /* Number of active sessions */
572 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
573#endif
drh75897232000-05-29 14:26:00 +0000574};
575
576/*
drh44dec872014-08-30 15:49:25 +0000577** These are the allowed shellFlgs values
578*/
579#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
580#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
581#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
582
583/*
drh75897232000-05-29 14:26:00 +0000584** These are the allowed modes.
585*/
drh967e8b72000-06-21 13:59:10 +0000586#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000587#define MODE_Column 1 /* One record per line in neat columns */
588#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000589#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
590#define MODE_Html 4 /* Generate an XHTML table */
591#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000592#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000593#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000594#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000595#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000596
drh66ce4d02008-02-15 17:38:06 +0000597static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000598 "line",
599 "column",
600 "list",
601 "semi",
602 "html",
drhfeac5f82004-08-01 00:10:45 +0000603 "insert",
604 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000605 "csv",
drh66ce4d02008-02-15 17:38:06 +0000606 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000607 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000608};
drh75897232000-05-29 14:26:00 +0000609
610/*
mistachkinfad42082014-07-24 22:13:12 +0000611** These are the column/row/line separators used by the various
612** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000613*/
mistachkinfad42082014-07-24 22:13:12 +0000614#define SEP_Column "|"
615#define SEP_Row "\n"
616#define SEP_Tab "\t"
617#define SEP_Space " "
618#define SEP_Comma ","
619#define SEP_CrLf "\r\n"
620#define SEP_Unit "\x1F"
621#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000622
623/*
drh75897232000-05-29 14:26:00 +0000624** Number of elements in an array
625*/
drh902b9ee2008-12-05 17:17:07 +0000626#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000627
628/*
drhea678832008-12-10 19:26:22 +0000629** Compute a string length that is limited to what can be stored in
630** lower 30 bits of a 32-bit signed integer.
631*/
drh4f21c4a2008-12-10 22:15:00 +0000632static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000633 const char *z2 = z;
634 while( *z2 ){ z2++; }
635 return 0x3fffffff & (int)(z2 - z);
636}
637
638/*
drh127f9d72010-02-23 01:47:00 +0000639** A callback for the sqlite3_log() interface.
640*/
641static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000642 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000643 if( p->pLog==0 ) return;
644 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
645 fflush(p->pLog);
646}
647
648/*
shane626a6e42009-10-22 17:30:15 +0000649** Output the given string as a hex-encoded blob (eg. X'1234' )
650*/
651static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
652 int i;
653 char *zBlob = (char *)pBlob;
654 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000655 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000656 fprintf(out,"'");
657}
658
659/*
drh28bd4bc2000-06-15 15:57:22 +0000660** Output the given string as a quoted string using SQL quoting conventions.
661*/
662static void output_quoted_string(FILE *out, const char *z){
663 int i;
664 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000665 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000666 for(i=0; z[i]; i++){
667 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000668 }
669 if( nSingle==0 ){
670 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000671 }else{
672 fprintf(out,"'");
673 while( *z ){
674 for(i=0; z[i] && z[i]!='\''; i++){}
675 if( i==0 ){
676 fprintf(out,"''");
677 z++;
678 }else if( z[i]=='\'' ){
679 fprintf(out,"%.*s''",i,z);
680 z += i+1;
681 }else{
drhcd7d2732002-02-26 23:24:26 +0000682 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000683 break;
684 }
685 }
drhcd7d2732002-02-26 23:24:26 +0000686 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000687 }
drh047d4532015-01-18 20:30:23 +0000688 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000689}
690
691/*
drhfeac5f82004-08-01 00:10:45 +0000692** Output the given string as a quoted according to C or TCL quoting rules.
693*/
694static void output_c_string(FILE *out, const char *z){
695 unsigned int c;
696 fputc('"', out);
697 while( (c = *(z++))!=0 ){
698 if( c=='\\' ){
699 fputc(c, out);
700 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000701 }else if( c=='"' ){
702 fputc('\\', out);
703 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000704 }else if( c=='\t' ){
705 fputc('\\', out);
706 fputc('t', out);
707 }else if( c=='\n' ){
708 fputc('\\', out);
709 fputc('n', out);
710 }else if( c=='\r' ){
711 fputc('\\', out);
712 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000713 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000714 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000715 }else{
716 fputc(c, out);
717 }
718 }
719 fputc('"', out);
720}
721
722/*
drhc08a4f12000-06-15 16:49:48 +0000723** Output the given string with characters that are special to
724** HTML escaped.
725*/
726static void output_html_string(FILE *out, const char *z){
727 int i;
drhc3d6ba42014-01-13 20:38:35 +0000728 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000729 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000730 for(i=0; z[i]
731 && z[i]!='<'
732 && z[i]!='&'
733 && z[i]!='>'
734 && z[i]!='\"'
735 && z[i]!='\'';
736 i++){}
drhc08a4f12000-06-15 16:49:48 +0000737 if( i>0 ){
738 fprintf(out,"%.*s",i,z);
739 }
740 if( z[i]=='<' ){
741 fprintf(out,"&lt;");
742 }else if( z[i]=='&' ){
743 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000744 }else if( z[i]=='>' ){
745 fprintf(out,"&gt;");
746 }else if( z[i]=='\"' ){
747 fprintf(out,"&quot;");
748 }else if( z[i]=='\'' ){
749 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000750 }else{
751 break;
752 }
753 z += i + 1;
754 }
755}
756
757/*
drhc49f44e2006-10-26 18:15:42 +0000758** If a field contains any character identified by a 1 in the following
759** array, then the string must be quoted for CSV.
760*/
761static const char needCsvQuote[] = {
762 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
763 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
764 1, 0, 1, 0, 0, 0, 0, 1, 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, 0,
769 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
778};
779
780/*
mistachkindd11f2d2014-12-11 04:49:46 +0000781** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000782** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000783** the null value. Strings are quoted if necessary. The separator
784** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000785*/
drhdcd87a92014-08-18 13:45:42 +0000786static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000787 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000788 if( z==0 ){
mistachkin44b99f72014-12-11 03:29:14 +0000789 fprintf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000790 }else{
drhc49f44e2006-10-26 18:15:42 +0000791 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000792 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000793 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000794 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000795 || (z[i]==p->colSeparator[0] &&
796 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000797 i = 0;
798 break;
799 }
800 }
801 if( i==0 ){
802 putc('"', out);
803 for(i=0; z[i]; i++){
804 if( z[i]=='"' ) putc('"', out);
805 putc(z[i], out);
806 }
807 putc('"', out);
808 }else{
809 fprintf(out, "%s", z);
810 }
drh8e64d1c2004-10-07 00:32:39 +0000811 }
812 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000813 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000814 }
815}
816
danielk19774af00c62005-01-23 23:43:21 +0000817#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000818/*
drh4c504392000-10-16 22:06:40 +0000819** This routine runs when the user presses Ctrl-C
820*/
821static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000822 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000823 seenInterrupt++;
824 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000825 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000826}
danielk19774af00c62005-01-23 23:43:21 +0000827#endif
drh4c504392000-10-16 22:06:40 +0000828
829/*
shane626a6e42009-10-22 17:30:15 +0000830** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000831** invokes for each row of a query result.
832*/
drh4ace5362014-11-10 14:42:28 +0000833static int shell_callback(
834 void *pArg,
835 int nArg, /* Number of result columns */
836 char **azArg, /* Text of each result column */
837 char **azCol, /* Column names */
838 int *aiType /* Column types */
839){
drh75897232000-05-29 14:26:00 +0000840 int i;
drhdcd87a92014-08-18 13:45:42 +0000841 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000842
drh75897232000-05-29 14:26:00 +0000843 switch( p->mode ){
844 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000845 int w = 5;
drh6a535342001-10-19 16:44:56 +0000846 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000847 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000848 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000849 if( len>w ) w = len;
850 }
mistachkin636bf9f2014-07-19 20:15:16 +0000851 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000852 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000853 fprintf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000854 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000855 }
856 break;
857 }
danielk19770d78bae2008-01-03 07:09:48 +0000858 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000859 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000860 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000861 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000862 int w, n;
863 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000864 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000865 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000866 w = 0;
drh75897232000-05-29 14:26:00 +0000867 }
drh078b1fd2012-09-21 13:40:02 +0000868 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000869 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000870 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000871 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000872 if( w<n ) w = n;
873 }
874 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000875 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000876 }
877 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000878 if( w<0 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000879 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
880 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000881 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000882 fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
883 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000884 }
drha0c66f52000-07-29 13:20:21 +0000885 }
886 }
887 if( p->showHeader ){
888 for(i=0; i<nArg; i++){
889 int w;
890 if( i<ArraySize(p->actualWidth) ){
891 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000892 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000893 }else{
894 w = 10;
895 }
896 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
897 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000898 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000899 }
drh75897232000-05-29 14:26:00 +0000900 }
901 }
drh6a535342001-10-19 16:44:56 +0000902 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000903 for(i=0; i<nArg; i++){
904 int w;
drha0c66f52000-07-29 13:20:21 +0000905 if( i<ArraySize(p->actualWidth) ){
906 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000907 }else{
908 w = 10;
909 }
dana98bf362013-11-13 18:35:01 +0000910 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000911 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000912 }
dana98bf362013-11-13 18:35:01 +0000913 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000914 if( p->iIndent<p->nIndent ){
915 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000916 }
danc4650bb2013-11-18 08:41:06 +0000917 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000918 }
drh078b1fd2012-09-21 13:40:02 +0000919 if( w<0 ){
920 fprintf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000921 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000922 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000923 }else{
924 fprintf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000925 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000926 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000927 }
drh75897232000-05-29 14:26:00 +0000928 }
929 break;
930 }
drhe3710332000-09-29 13:30:53 +0000931 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000932 case MODE_List: {
933 if( p->cnt++==0 && p->showHeader ){
934 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000935 fprintf(p->out,"%s%s",azCol[i],
936 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000937 }
938 }
drh6a535342001-10-19 16:44:56 +0000939 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000940 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000941 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +0000942 if( z==0 ) z = p->nullValue;
drh71172c52002-01-24 00:00:21 +0000943 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000944 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000945 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000946 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000947 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000948 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000949 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000950 }
drh75897232000-05-29 14:26:00 +0000951 }
952 break;
953 }
drh1e5d0e92000-05-31 23:33:17 +0000954 case MODE_Html: {
955 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000956 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000957 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000958 fprintf(p->out,"<TH>");
959 output_html_string(p->out, azCol[i]);
960 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000961 }
mihailim57c591a2008-06-23 21:26:05 +0000962 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000963 }
drh6a535342001-10-19 16:44:56 +0000964 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000965 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000966 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000967 fprintf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +0000968 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mihailim57c591a2008-06-23 21:26:05 +0000969 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000970 }
mihailim57c591a2008-06-23 21:26:05 +0000971 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000972 break;
973 }
drhfeac5f82004-08-01 00:10:45 +0000974 case MODE_Tcl: {
975 if( p->cnt++==0 && p->showHeader ){
976 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000977 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000978 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000979 }
mistachkin636bf9f2014-07-19 20:15:16 +0000980 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000981 }
982 if( azArg==0 ) break;
983 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +0000984 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000985 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000986 }
mistachkin636bf9f2014-07-19 20:15:16 +0000987 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000988 break;
989 }
drh8e64d1c2004-10-07 00:32:39 +0000990 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +0000991 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000992 if( p->cnt++==0 && p->showHeader ){
993 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000994 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000995 }
mistachkine0d68852014-12-11 03:12:33 +0000996 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000997 }
drh40253262014-10-17 21:35:05 +0000998 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000999 for(i=0; i<nArg; i++){
1000 output_csv(p, azArg[i], i<nArg-1);
1001 }
mistachkine0d68852014-12-11 03:12:33 +00001002 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001003 }
drh047d4532015-01-18 20:30:23 +00001004 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +00001005 break;
1006 }
drh28bd4bc2000-06-15 15:57:22 +00001007 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001008 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001009 if( azArg==0 ) break;
mistachkin151c75a2015-04-07 21:16:40 +00001010 fprintf(p->out,"INSERT INTO %s",p->zDestTable);
1011 if( p->showHeader ){
1012 fprintf(p->out,"(");
1013 for(i=0; i<nArg; i++){
1014 char *zSep = i>0 ? ",": "";
1015 fprintf(p->out, "%s%s", zSep, azCol[i]);
1016 }
1017 fprintf(p->out,")");
1018 }
1019 fprintf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001020 for(i=0; i<nArg; i++){
1021 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001022 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +00001023 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001024 }else if( aiType && aiType[i]==SQLITE_TEXT ){
1025 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1026 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001027 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1028 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +00001029 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001030 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1031 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1032 int nBlob = sqlite3_column_bytes(p->pStmt, i);
1033 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1034 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001035 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +00001036 fprintf(p->out,"%s%s",zSep, azArg[i]);
1037 }else{
1038 if( zSep[0] ) fprintf(p->out,"%s",zSep);
1039 output_quoted_string(p->out, azArg[i]);
1040 }
1041 }
1042 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001043 break;
drh28bd4bc2000-06-15 15:57:22 +00001044 }
mistachkin636bf9f2014-07-19 20:15:16 +00001045 case MODE_Ascii: {
1046 if( p->cnt++==0 && p->showHeader ){
1047 for(i=0; i<nArg; i++){
1048 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
1049 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
1050 }
1051 fprintf(p->out, "%s", p->rowSeparator);
1052 }
1053 if( azArg==0 ) break;
1054 for(i=0; i<nArg; i++){
1055 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
mistachkin44b99f72014-12-11 03:29:14 +00001056 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001057 }
1058 fprintf(p->out, "%s", p->rowSeparator);
1059 break;
1060 }
persicom1d0b8722002-04-18 02:53:04 +00001061 }
drh75897232000-05-29 14:26:00 +00001062 return 0;
1063}
1064
1065/*
shane626a6e42009-10-22 17:30:15 +00001066** This is the callback routine that the SQLite library
1067** invokes for each row of a query result.
1068*/
1069static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1070 /* since we don't have type info, call the shell_callback with a NULL value */
1071 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1072}
1073
1074/*
drhdcd87a92014-08-18 13:45:42 +00001075** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001076** the name of the table given. Escape any quote characters in the
1077** table name.
1078*/
drhdcd87a92014-08-18 13:45:42 +00001079static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001080 int i, n;
1081 int needQuote;
1082 char *z;
1083
1084 if( p->zDestTable ){
1085 free(p->zDestTable);
1086 p->zDestTable = 0;
1087 }
1088 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001089 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001090 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001091 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001092 needQuote = 1;
1093 if( zName[i]=='\'' ) n++;
1094 }
1095 }
1096 if( needQuote ) n += 2;
1097 z = p->zDestTable = malloc( n+1 );
1098 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001099 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001100 exit(1);
1101 }
1102 n = 0;
1103 if( needQuote ) z[n++] = '\'';
1104 for(i=0; zName[i]; i++){
1105 z[n++] = zName[i];
1106 if( zName[i]=='\'' ) z[n++] = '\'';
1107 }
1108 if( needQuote ) z[n++] = '\'';
1109 z[n] = 0;
1110}
1111
danielk19772a02e332004-06-05 08:04:36 +00001112/* zIn is either a pointer to a NULL-terminated string in memory obtained
1113** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1114** added to zIn, and the result returned in memory obtained from malloc().
1115** zIn, if it was not NULL, is freed.
1116**
1117** If the third argument, quote, is not '\0', then it is used as a
1118** quote character for zAppend.
1119*/
drhc28490c2006-10-26 14:25:58 +00001120static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001121 int len;
1122 int i;
drh4f21c4a2008-12-10 22:15:00 +00001123 int nAppend = strlen30(zAppend);
1124 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001125
1126 len = nAppend+nIn+1;
1127 if( quote ){
1128 len += 2;
1129 for(i=0; i<nAppend; i++){
1130 if( zAppend[i]==quote ) len++;
1131 }
1132 }
1133
1134 zIn = (char *)realloc(zIn, len);
1135 if( !zIn ){
1136 return 0;
1137 }
1138
1139 if( quote ){
1140 char *zCsr = &zIn[nIn];
1141 *zCsr++ = quote;
1142 for(i=0; i<nAppend; i++){
1143 *zCsr++ = zAppend[i];
1144 if( zAppend[i]==quote ) *zCsr++ = quote;
1145 }
1146 *zCsr++ = quote;
1147 *zCsr++ = '\0';
1148 assert( (zCsr-zIn)==len );
1149 }else{
1150 memcpy(&zIn[nIn], zAppend, nAppend);
1151 zIn[len-1] = '\0';
1152 }
1153
1154 return zIn;
1155}
1156
drhdd3d4592004-08-30 01:54:05 +00001157
1158/*
drhb21a8e42012-01-28 21:08:51 +00001159** Execute a query statement that will generate SQL output. Print
1160** the result columns, comma-separated, on a line and then add a
1161** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001162**
drhb21a8e42012-01-28 21:08:51 +00001163** If the number of columns is 1 and that column contains text "--"
1164** then write the semicolon on a separate line. That way, if a
1165** "--" comment occurs at the end of the statement, the comment
1166** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001167*/
drh157e29a2009-05-21 15:15:00 +00001168static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001169 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001170 const char *zSelect, /* SELECT statement to extract content */
1171 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001172){
drhdd3d4592004-08-30 01:54:05 +00001173 sqlite3_stmt *pSelect;
1174 int rc;
drhb21a8e42012-01-28 21:08:51 +00001175 int nResult;
1176 int i;
1177 const char *z;
drhc7181902014-02-27 15:04:13 +00001178 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001179 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001180 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001181 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001182 return rc;
1183 }
1184 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001185 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001186 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001187 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001188 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001189 zFirstRow = 0;
1190 }
drhb21a8e42012-01-28 21:08:51 +00001191 z = (const char*)sqlite3_column_text(pSelect, 0);
1192 fprintf(p->out, "%s", z);
1193 for(i=1; i<nResult; i++){
1194 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1195 }
1196 if( z==0 ) z = "";
1197 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1198 if( z[0] ){
1199 fprintf(p->out, "\n;\n");
1200 }else{
1201 fprintf(p->out, ";\n");
1202 }
drhdd3d4592004-08-30 01:54:05 +00001203 rc = sqlite3_step(pSelect);
1204 }
drh2f464a02011-10-13 00:41:49 +00001205 rc = sqlite3_finalize(pSelect);
1206 if( rc!=SQLITE_OK ){
1207 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001208 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001209 }
1210 return rc;
drhdd3d4592004-08-30 01:54:05 +00001211}
1212
shane626a6e42009-10-22 17:30:15 +00001213/*
1214** Allocate space and save off current error string.
1215*/
1216static char *save_err_msg(
1217 sqlite3 *db /* Database to query */
1218){
1219 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001220 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001221 if( zErrMsg ){
1222 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1223 }
1224 return zErrMsg;
1225}
1226
1227/*
shaneh642d8b82010-07-28 16:05:34 +00001228** Display memory stats.
1229*/
1230static int display_stats(
1231 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001232 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001233 int bReset /* True to reset the stats */
1234){
1235 int iCur;
1236 int iHiwtr;
1237
1238 if( pArg && pArg->out ){
1239
1240 iHiwtr = iCur = -1;
1241 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001242 fprintf(pArg->out,
1243 "Memory Used: %d (max %d) bytes\n",
1244 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001245 iHiwtr = iCur = -1;
1246 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001247 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1248 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001249 if( pArg->shellFlgs & SHFLG_Pagecache ){
1250 iHiwtr = iCur = -1;
1251 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001252 fprintf(pArg->out,
1253 "Number of Pcache Pages Used: %d (max %d) pages\n",
1254 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001255 }
shaneh642d8b82010-07-28 16:05:34 +00001256 iHiwtr = iCur = -1;
1257 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001258 fprintf(pArg->out,
1259 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1260 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001261 if( pArg->shellFlgs & SHFLG_Scratch ){
1262 iHiwtr = iCur = -1;
1263 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001264 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1265 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001266 }
shaneh642d8b82010-07-28 16:05:34 +00001267 iHiwtr = iCur = -1;
1268 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001269 fprintf(pArg->out,
1270 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1271 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001272 iHiwtr = iCur = -1;
1273 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001274 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1275 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001276 iHiwtr = iCur = -1;
1277 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001278 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1279 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001280 iHiwtr = iCur = -1;
1281 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001282 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1283 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001284#ifdef YYTRACKMAXSTACKDEPTH
1285 iHiwtr = iCur = -1;
1286 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001287 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1288 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001289#endif
1290 }
1291
1292 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001293 if( pArg->shellFlgs & SHFLG_Lookaside ){
1294 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001295 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1296 &iCur, &iHiwtr, bReset);
1297 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1298 iCur, iHiwtr);
1299 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1300 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001301 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001302 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1303 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001304 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001305 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1306 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001307 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1308 }
shaneh642d8b82010-07-28 16:05:34 +00001309 iHiwtr = iCur = -1;
1310 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001311 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1312 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001313 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1314 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1315 iHiwtr = iCur = -1;
1316 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1317 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001318 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001319 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1320 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1321 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001322 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001323 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001324 iHiwtr = iCur = -1;
1325 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001326 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001327 }
1328
1329 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001330 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1331 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001332 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1333 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1334 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001335 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001336 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001337 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1338 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001339 }
1340
1341 return 0;
1342}
1343
1344/*
dan8d1edb92014-11-05 09:07:28 +00001345** Display scan stats.
1346*/
1347static void display_scanstats(
1348 sqlite3 *db, /* Database to query */
1349 ShellState *pArg /* Pointer to ShellState */
1350){
1351#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
drh15f23c22014-11-06 12:46:16 +00001352 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001353 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001354 mx = 0;
1355 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001356 double rEstLoop = 1.0;
1357 for(i=n=0; 1; i++){
1358 sqlite3_stmt *p = pArg->pStmt;
1359 sqlite3_int64 nLoop, nVisit;
1360 double rEst;
1361 int iSid;
1362 const char *zExplain;
1363 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1364 break;
1365 }
1366 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001367 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001368 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001369 if( n==0 ){
1370 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001371 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001372 }
drh42f30bc2014-11-06 12:08:21 +00001373 n++;
1374 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1375 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1376 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1377 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1378 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001379 fprintf(pArg->out,
1380 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001381 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001382 );
dan8d1edb92014-11-05 09:07:28 +00001383 }
dan8d1edb92014-11-05 09:07:28 +00001384 }
dan8d1edb92014-11-05 09:07:28 +00001385 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001386#endif
dan8d1edb92014-11-05 09:07:28 +00001387}
1388
1389/*
dana98bf362013-11-13 18:35:01 +00001390** Parameter azArray points to a zero-terminated array of strings. zStr
1391** points to a single nul-terminated string. Return non-zero if zStr
1392** is equal, according to strcmp(), to any of the strings in the array.
1393** Otherwise, return zero.
1394*/
1395static int str_in_array(const char *zStr, const char **azArray){
1396 int i;
1397 for(i=0; azArray[i]; i++){
1398 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1399 }
1400 return 0;
1401}
1402
1403/*
1404** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001405** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001406** spaces each opcode should be indented before it is output.
1407**
1408** The indenting rules are:
1409**
1410** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1411** all opcodes that occur between the p2 jump destination and the opcode
1412** itself by 2 spaces.
1413**
drh01752bc2013-11-14 23:59:33 +00001414** * For each "Goto", if the jump destination is earlier in the program
1415** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001416** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001417** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001418** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001419** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001420*/
drhdcd87a92014-08-18 13:45:42 +00001421static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001422 const char *zSql; /* The text of the SQL statement */
1423 const char *z; /* Used to check if this is an EXPLAIN */
1424 int *abYield = 0; /* True if op is an OP_Yield */
1425 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001426 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001427
drh8ad0de32014-03-20 18:45:27 +00001428 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1429 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001430 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1431 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001432 const char *azGoto[] = { "Goto", 0 };
1433
1434 /* Try to figure out if this is really an EXPLAIN statement. If this
1435 ** cannot be verified, return early. */
1436 zSql = sqlite3_sql(pSql);
1437 if( zSql==0 ) return;
1438 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1439 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1440
1441 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1442 int i;
danc4650bb2013-11-18 08:41:06 +00001443 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001444 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001445
1446 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1447 ** p2 is an instruction address, set variable p2op to the index of that
1448 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1449 ** the current instruction is part of a sub-program generated by an
1450 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001451 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001452 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001453
1454 /* Grow the p->aiIndent array as required */
1455 if( iOp>=nAlloc ){
1456 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001457 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1458 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001459 }
1460 abYield[iOp] = str_in_array(zOp, azYield);
1461 p->aiIndent[iOp] = 0;
1462 p->nIndent = iOp+1;
1463
1464 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001465 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001466 }
drhfe705102014-03-06 13:38:37 +00001467 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1468 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1469 ){
drhe73f0592014-01-21 22:25:45 +00001470 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001471 }
1472 }
1473
danc4650bb2013-11-18 08:41:06 +00001474 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001475 sqlite3_free(abYield);
1476 sqlite3_reset(pSql);
1477}
1478
1479/*
1480** Free the array allocated by explain_data_prepare().
1481*/
drhdcd87a92014-08-18 13:45:42 +00001482static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001483 sqlite3_free(p->aiIndent);
1484 p->aiIndent = 0;
1485 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001486 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001487}
1488
1489/*
shane626a6e42009-10-22 17:30:15 +00001490** Execute a statement or set of statements. Print
1491** any result rows/columns depending on the current mode
1492** set via the supplied callback.
1493**
1494** This is very similar to SQLite's built-in sqlite3_exec()
1495** function except it takes a slightly different callback
1496** and callback data argument.
1497*/
1498static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001499 sqlite3 *db, /* An open database */
1500 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001501 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001502 /* (not the same as sqlite3_exec) */
1503 ShellState *pArg, /* Pointer to ShellState */
1504 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001505){
dan4564ced2010-01-05 04:59:56 +00001506 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1507 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001508 int rc2;
dan4564ced2010-01-05 04:59:56 +00001509 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001510
1511 if( pzErrMsg ){
1512 *pzErrMsg = NULL;
1513 }
1514
shaneb9fc17d2009-10-22 21:23:35 +00001515 while( zSql[0] && (SQLITE_OK == rc) ){
1516 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1517 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001518 if( pzErrMsg ){
1519 *pzErrMsg = save_err_msg(db);
1520 }
1521 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001522 if( !pStmt ){
1523 /* this happens for a comment or white-space */
1524 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001525 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001526 continue;
1527 }
shane626a6e42009-10-22 17:30:15 +00001528
shaneh642d8b82010-07-28 16:05:34 +00001529 /* save off the prepared statment handle and reset row count */
1530 if( pArg ){
1531 pArg->pStmt = pStmt;
1532 pArg->cnt = 0;
1533 }
1534
shanehb7977c52010-01-18 18:17:10 +00001535 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001536 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001537 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001538 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001539 }
shanehb7977c52010-01-18 18:17:10 +00001540
drhefbf3b12014-02-28 20:47:24 +00001541 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1542 if( pArg && pArg->autoEQP ){
1543 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001544 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1545 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001546 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1547 if( rc==SQLITE_OK ){
1548 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1549 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1550 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1551 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1552 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1553 }
1554 }
1555 sqlite3_finalize(pExplain);
1556 sqlite3_free(zEQP);
1557 }
1558
dana98bf362013-11-13 18:35:01 +00001559 /* If the shell is currently in ".explain" mode, gather the extra
1560 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001561 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001562 explain_data_prepare(pArg, pStmt);
1563 }
1564
shaneb9fc17d2009-10-22 21:23:35 +00001565 /* perform the first step. this will tell us if we
1566 ** have a result set or not and how wide it is.
1567 */
1568 rc = sqlite3_step(pStmt);
1569 /* if we have a result set... */
1570 if( SQLITE_ROW == rc ){
1571 /* if we have a callback... */
1572 if( xCallback ){
1573 /* allocate space for col name ptr, value ptr, and type */
1574 int nCol = sqlite3_column_count(pStmt);
drhf3cdcdc2015-04-29 16:50:28 +00001575 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
shaneb9fc17d2009-10-22 21:23:35 +00001576 if( !pData ){
1577 rc = SQLITE_NOMEM;
1578 }else{
1579 char **azCols = (char **)pData; /* Names of result columns */
1580 char **azVals = &azCols[nCol]; /* Results */
1581 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001582 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001583 assert(sizeof(int) <= sizeof(char *));
1584 /* save off ptrs to column names */
1585 for(i=0; i<nCol; i++){
1586 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1587 }
shaneb9fc17d2009-10-22 21:23:35 +00001588 do{
1589 /* extract the data and data types */
1590 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001591 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001592 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001593 azVals[i] = "";
1594 }else{
1595 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1596 }
shaneb9fc17d2009-10-22 21:23:35 +00001597 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1598 rc = SQLITE_NOMEM;
1599 break; /* from for */
1600 }
1601 } /* end for */
1602
1603 /* if data and types extracted successfully... */
1604 if( SQLITE_ROW == rc ){
1605 /* call the supplied callback with the result row data */
1606 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1607 rc = SQLITE_ABORT;
1608 }else{
1609 rc = sqlite3_step(pStmt);
1610 }
1611 }
1612 } while( SQLITE_ROW == rc );
1613 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001614 }
1615 }else{
1616 do{
1617 rc = sqlite3_step(pStmt);
1618 } while( rc == SQLITE_ROW );
1619 }
1620 }
1621
dana98bf362013-11-13 18:35:01 +00001622 explain_data_delete(pArg);
1623
shaneh642d8b82010-07-28 16:05:34 +00001624 /* print usage stats if stats on */
1625 if( pArg && pArg->statsOn ){
1626 display_stats(db, pArg, 0);
1627 }
1628
dan8d1edb92014-11-05 09:07:28 +00001629 /* print loop-counters if required */
1630 if( pArg && pArg->scanstatsOn ){
1631 display_scanstats(db, pArg);
1632 }
1633
dan4564ced2010-01-05 04:59:56 +00001634 /* Finalize the statement just executed. If this fails, save a
1635 ** copy of the error message. Otherwise, set zSql to point to the
1636 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001637 rc2 = sqlite3_finalize(pStmt);
1638 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001639 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001640 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001641 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001642 }else if( pzErrMsg ){
1643 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001644 }
shaneh642d8b82010-07-28 16:05:34 +00001645
1646 /* clear saved stmt handle */
1647 if( pArg ){
1648 pArg->pStmt = NULL;
1649 }
shane626a6e42009-10-22 17:30:15 +00001650 }
shaneb9fc17d2009-10-22 21:23:35 +00001651 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001652
1653 return rc;
1654}
1655
drhdd3d4592004-08-30 01:54:05 +00001656
drh33048c02001-10-01 14:29:22 +00001657/*
drh4c653a02000-06-07 01:27:47 +00001658** This is a different callback routine used for dumping the database.
1659** Each row received by this callback consists of a table name,
1660** the table type ("index" or "table") and SQL to create the table.
1661** This routine should print text sufficient to recreate the table.
1662*/
1663static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001664 int rc;
1665 const char *zTable;
1666 const char *zType;
1667 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001668 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001669 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001670
drh902b9ee2008-12-05 17:17:07 +00001671 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001672 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001673 zTable = azArg[0];
1674 zType = azArg[1];
1675 zSql = azArg[2];
1676
drh00b950d2005-09-11 02:03:03 +00001677 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001678 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001679 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001680 fprintf(p->out, "ANALYZE sqlite_master;\n");
1681 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1682 return 0;
drh45e29d82006-11-20 16:21:10 +00001683 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1684 char *zIns;
1685 if( !p->writableSchema ){
1686 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1687 p->writableSchema = 1;
1688 }
1689 zIns = sqlite3_mprintf(
1690 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1691 "VALUES('table','%q','%q',0,'%q');",
1692 zTable, zTable, zSql);
1693 fprintf(p->out, "%s\n", zIns);
1694 sqlite3_free(zIns);
1695 return 0;
drh00b950d2005-09-11 02:03:03 +00001696 }else{
1697 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001698 }
danielk19772a02e332004-06-05 08:04:36 +00001699
1700 if( strcmp(zType, "table")==0 ){
1701 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001702 char *zSelect = 0;
1703 char *zTableInfo = 0;
1704 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001705 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001706
1707 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1708 zTableInfo = appendText(zTableInfo, zTable, '"');
1709 zTableInfo = appendText(zTableInfo, ");", 0);
1710
drhc7181902014-02-27 15:04:13 +00001711 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001712 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001713 if( rc!=SQLITE_OK || !pTableInfo ){
1714 return 1;
1715 }
1716
1717 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001718 /* Always quote the table name, even if it appears to be pure ascii,
1719 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1720 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001721 if( zTmp ){
1722 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001723 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001724 }
1725 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1726 rc = sqlite3_step(pTableInfo);
1727 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001728 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001729 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001730 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001731 rc = sqlite3_step(pTableInfo);
1732 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001733 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001734 }else{
1735 zSelect = appendText(zSelect, ") ", 0);
1736 }
drh157e29a2009-05-21 15:15:00 +00001737 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001738 }
1739 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001740 if( rc!=SQLITE_OK || nRow==0 ){
1741 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001742 return 1;
1743 }
1744 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1745 zSelect = appendText(zSelect, zTable, '"');
1746
drh2f464a02011-10-13 00:41:49 +00001747 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001748 if( rc==SQLITE_CORRUPT ){
1749 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001750 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001751 }
drh85e72432012-04-11 11:38:53 +00001752 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001753 }
drh4c653a02000-06-07 01:27:47 +00001754 return 0;
1755}
1756
1757/*
drh45e29d82006-11-20 16:21:10 +00001758** Run zQuery. Use dump_callback() as the callback routine so that
1759** the contents of the query are output as SQL statements.
1760**
drhdd3d4592004-08-30 01:54:05 +00001761** If we get a SQLITE_CORRUPT error, rerun the query after appending
1762** "ORDER BY rowid DESC" to the end.
1763*/
1764static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001765 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001766 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001767){
1768 int rc;
drh2f464a02011-10-13 00:41:49 +00001769 char *zErr = 0;
1770 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001771 if( rc==SQLITE_CORRUPT ){
1772 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001773 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001774 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1775 if( zErr ){
1776 fprintf(p->out, "/****** %s ******/\n", zErr);
1777 sqlite3_free(zErr);
1778 zErr = 0;
1779 }
drhdd3d4592004-08-30 01:54:05 +00001780 zQ2 = malloc( len+100 );
1781 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001782 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001783 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1784 if( rc ){
1785 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1786 }else{
1787 rc = SQLITE_CORRUPT;
1788 }
1789 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001790 free(zQ2);
1791 }
1792 return rc;
1793}
1794
1795/*
drh75897232000-05-29 14:26:00 +00001796** Text of a help message
1797*/
persicom1d0b8722002-04-18 02:53:04 +00001798static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001799 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001800 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00001801 ".binary on|off Turn binary output on or off. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001802 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001803 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001804 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001805 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001806 " If TABLE specified, only dump tables matching\n"
1807 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001808 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001809 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001810 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001811 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001812 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001813 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001814 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001815 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001816 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001817 ".indexes ?TABLE? Show names of all indexes\n"
1818 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001819 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001820#ifdef SQLITE_ENABLE_IOTRACE
1821 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1822#endif
drh1a513372015-05-02 17:40:23 +00001823 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00001824#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001825 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001826#endif
drh127f9d72010-02-23 01:47:00 +00001827 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001828 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001829 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001830 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001831 " column Left-aligned columns. (See .width)\n"
1832 " html HTML <table> code\n"
1833 " insert SQL insert statements for TABLE\n"
1834 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001835 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001836 " tabs Tab-separated values\n"
1837 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001838 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001839 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001840 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001841 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001842 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001843 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001844 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001845 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001846 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001847 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001848 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001849 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001850 " If TABLE specified, only show tables matching\n"
1851 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001852 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1853 " separator for both the output mode and .import\n"
drhe6229612014-08-18 15:08:26 +00001854#if defined(SQLITE_ENABLE_SESSION)
1855 ".session CMD ... Create or control sessions\n"
1856#endif
drh62cdde52014-05-28 20:22:28 +00001857 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001858 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001859 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001860 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001861 ".tables ?TABLE? List names of tables\n"
1862 " If TABLE specified, only list tables matching\n"
1863 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001864 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001865 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001866 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001867 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001868 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001869 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001870;
1871
drhe6229612014-08-18 15:08:26 +00001872#if defined(SQLITE_ENABLE_SESSION)
1873/*
1874** Print help information for the ".sessions" command
1875*/
1876void session_help(ShellState *p){
1877 fprintf(p->out,
1878 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
1879 "If ?NAME? is omitted, the first defined session is used.\n"
1880 "Subcommands:\n"
1881 " attach TABLE Attach TABLE\n"
1882 " changeset FILE Write a changeset into FILE\n"
1883 " close Close one session\n"
1884 " enable ?BOOLEAN? Set or query the enable bit\n"
1885 " filter GLOB... Reject tables matching GLOBs\n"
1886 " indirect ?BOOLEAN? Mark or query the indirect status\n"
1887 " isempty Query whether the session is empty\n"
1888 " list List currently open session names\n"
1889 " open DB NAME Open a new session on DB\n"
1890 " patchset FILE Write a patchset into FILE\n"
1891 );
1892}
1893#endif
1894
1895
drhdaffd0e2001-04-11 14:28:42 +00001896/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001897static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001898/*
1899** Implementation of the "readfile(X)" SQL function. The entire content
1900** of the file named X is read and returned as a BLOB. NULL is returned
1901** if the file does not exist or is unreadable.
1902*/
1903static void readfileFunc(
1904 sqlite3_context *context,
1905 int argc,
1906 sqlite3_value **argv
1907){
1908 const char *zName;
1909 FILE *in;
1910 long nIn;
1911 void *pBuf;
1912
1913 zName = (const char*)sqlite3_value_text(argv[0]);
1914 if( zName==0 ) return;
1915 in = fopen(zName, "rb");
1916 if( in==0 ) return;
1917 fseek(in, 0, SEEK_END);
1918 nIn = ftell(in);
1919 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00001920 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00001921 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1922 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1923 }else{
1924 sqlite3_free(pBuf);
1925 }
1926 fclose(in);
1927}
1928
1929/*
1930** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1931** is written into file X. The number of bytes written is returned. Or
1932** NULL is returned if something goes wrong, such as being unable to open
1933** file X for writing.
1934*/
1935static void writefileFunc(
1936 sqlite3_context *context,
1937 int argc,
1938 sqlite3_value **argv
1939){
1940 FILE *out;
1941 const char *z;
drhba5b0932014-07-24 12:39:59 +00001942 sqlite3_int64 rc;
1943 const char *zFile;
1944
1945 zFile = (const char*)sqlite3_value_text(argv[0]);
1946 if( zFile==0 ) return;
1947 out = fopen(zFile, "wb");
1948 if( out==0 ) return;
1949 z = (const char*)sqlite3_value_blob(argv[1]);
1950 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001951 rc = 0;
1952 }else{
drh490fe862014-08-11 14:21:32 +00001953 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001954 }
1955 fclose(out);
1956 sqlite3_result_int64(context, rc);
1957}
drhdaffd0e2001-04-11 14:28:42 +00001958
drhe6229612014-08-18 15:08:26 +00001959#if defined(SQLITE_ENABLE_SESSION)
1960/*
1961** Close a single OpenSession object and release all of its associated
1962** resources.
1963*/
1964static void session_close(OpenSession *pSession){
1965 int i;
1966 sqlite3session_delete(pSession->p);
1967 sqlite3_free(pSession->zName);
1968 for(i=0; i<pSession->nFilter; i++){
1969 sqlite3_free(pSession->azFilter[i]);
1970 }
1971 sqlite3_free(pSession->azFilter);
1972 memset(pSession, 0, sizeof(OpenSession));
1973}
1974#endif
1975
1976/*
1977** Close all OpenSession objects and release all assocaited resources.
1978*/
1979static void session_close_all(ShellState *p){
1980#if defined(SQLITE_ENABLE_SESSION)
1981 int i;
1982 for(i=0; i<p->nSession; i++){
1983 session_close(&p->aSession[i]);
1984 }
1985 p->nSession = 0;
1986#endif
1987}
1988
drh75897232000-05-29 14:26:00 +00001989/*
drh03168ca2014-08-18 20:01:31 +00001990** Implementation of the xFilter function for an open session. Omit
1991** any tables named by ".session filter" but let all other table through.
1992*/
1993#if defined(SQLITE_ENABLE_SESSION)
1994static int session_filter(void *pCtx, const char *zTab){
1995 OpenSession *pSession = (OpenSession*)pCtx;
1996 int i;
1997 for(i=0; i<pSession->nFilter; i++){
1998 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
1999 }
2000 return 1;
2001}
2002#endif
2003
2004/*
drh44c2eb12003-04-30 11:38:26 +00002005** Make sure the database is open. If it is not, then open it. If
2006** the database fails to open, print an error message and exit.
2007*/
drhdcd87a92014-08-18 13:45:42 +00002008static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002009 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002010 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002011 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002012 globalDb = p->db;
2013 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2014 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002015 shellstaticFunc, 0, 0);
2016 }
mistachkin8e189222015-04-19 21:43:16 +00002017 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
shane86f5bdb2009-10-24 02:00:07 +00002018 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002019 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002020 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002021 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002022 }
drhc2e87a32006-06-27 15:16:14 +00002023#ifndef SQLITE_OMIT_LOAD_EXTENSION
2024 sqlite3_enable_load_extension(p->db, 1);
2025#endif
mistachkin8e189222015-04-19 21:43:16 +00002026 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002027 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002028 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002029 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002030 }
2031}
2032
2033/*
drhfeac5f82004-08-01 00:10:45 +00002034** Do C-language style dequoting.
2035**
mistachkinf21979d2015-01-18 05:35:01 +00002036** \a -> alarm
2037** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002038** \t -> tab
2039** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002040** \v -> vertical tab
2041** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002042** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002043** \s -> space
drh4c56b992013-06-27 13:26:55 +00002044** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002045** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002046** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002047** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002048*/
2049static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002050 int i, j;
2051 char c;
drhc2ce0be2014-05-29 12:36:14 +00002052 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002053 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002054 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002055 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002056 if( c=='a' ){
2057 c = '\a';
2058 }else if( c=='b' ){
2059 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002060 }else if( c=='t' ){
2061 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002062 }else if( c=='n' ){
2063 c = '\n';
2064 }else if( c=='v' ){
2065 c = '\v';
2066 }else if( c=='f' ){
2067 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002068 }else if( c=='r' ){
2069 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002070 }else if( c=='"' ){
2071 c = '"';
2072 }else if( c=='\'' ){
2073 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002074 }else if( c=='\\' ){
2075 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002076 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002077 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002078 if( z[i+1]>='0' && z[i+1]<='7' ){
2079 i++;
2080 c = (c<<3) + z[i] - '0';
2081 if( z[i+1]>='0' && z[i+1]<='7' ){
2082 i++;
2083 c = (c<<3) + z[i] - '0';
2084 }
2085 }
2086 }
2087 }
2088 z[j] = c;
2089 }
drhc2ce0be2014-05-29 12:36:14 +00002090 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002091}
2092
2093/*
drh348d19c2013-06-03 12:47:43 +00002094** Return the value of a hexadecimal digit. Return -1 if the input
2095** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002096*/
drh348d19c2013-06-03 12:47:43 +00002097static int hexDigitValue(char c){
2098 if( c>='0' && c<='9' ) return c - '0';
2099 if( c>='a' && c<='f' ) return c - 'a' + 10;
2100 if( c>='A' && c<='F' ) return c - 'A' + 10;
2101 return -1;
drhc28490c2006-10-26 14:25:58 +00002102}
2103
2104/*
drh7d9f3942013-04-03 01:26:54 +00002105** Interpret zArg as an integer value, possibly with suffixes.
2106*/
2107static sqlite3_int64 integerValue(const char *zArg){
2108 sqlite3_int64 v = 0;
2109 static const struct { char *zSuffix; int iMult; } aMult[] = {
2110 { "KiB", 1024 },
2111 { "MiB", 1024*1024 },
2112 { "GiB", 1024*1024*1024 },
2113 { "KB", 1000 },
2114 { "MB", 1000000 },
2115 { "GB", 1000000000 },
2116 { "K", 1000 },
2117 { "M", 1000000 },
2118 { "G", 1000000000 },
2119 };
2120 int i;
2121 int isNeg = 0;
2122 if( zArg[0]=='-' ){
2123 isNeg = 1;
2124 zArg++;
2125 }else if( zArg[0]=='+' ){
2126 zArg++;
2127 }
drh348d19c2013-06-03 12:47:43 +00002128 if( zArg[0]=='0' && zArg[1]=='x' ){
2129 int x;
2130 zArg += 2;
2131 while( (x = hexDigitValue(zArg[0]))>=0 ){
2132 v = (v<<4) + x;
2133 zArg++;
2134 }
2135 }else{
2136 while( IsDigit(zArg[0]) ){
2137 v = v*10 + zArg[0] - '0';
2138 zArg++;
2139 }
drh7d9f3942013-04-03 01:26:54 +00002140 }
drhc2bed0a2013-05-24 11:57:50 +00002141 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002142 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2143 v *= aMult[i].iMult;
2144 break;
2145 }
2146 }
2147 return isNeg? -v : v;
2148}
2149
2150/*
drh348d19c2013-06-03 12:47:43 +00002151** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2152** for TRUE and FALSE. Return the integer value if appropriate.
2153*/
2154static int booleanValue(char *zArg){
2155 int i;
2156 if( zArg[0]=='0' && zArg[1]=='x' ){
2157 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2158 }else{
2159 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2160 }
2161 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2162 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2163 return 1;
2164 }
2165 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2166 return 0;
2167 }
2168 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2169 zArg);
2170 return 0;
2171}
2172
2173/*
drh42f64e52012-04-04 16:56:23 +00002174** Close an output file, assuming it is not stderr or stdout
2175*/
2176static void output_file_close(FILE *f){
2177 if( f && f!=stdout && f!=stderr ) fclose(f);
2178}
2179
2180/*
2181** Try to open an output file. The names "stdout" and "stderr" are
2182** recognized and do the right thing. NULL is returned if the output
2183** filename is "off".
2184*/
2185static FILE *output_file_open(const char *zFile){
2186 FILE *f;
2187 if( strcmp(zFile,"stdout")==0 ){
2188 f = stdout;
2189 }else if( strcmp(zFile, "stderr")==0 ){
2190 f = stderr;
2191 }else if( strcmp(zFile, "off")==0 ){
2192 f = 0;
2193 }else{
2194 f = fopen(zFile, "wb");
2195 if( f==0 ){
2196 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2197 }
2198 }
2199 return f;
2200}
2201
2202/*
2203** A routine for handling output from sqlite3_trace().
2204*/
2205static void sql_trace_callback(void *pArg, const char *z){
2206 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002207 if( f ){
2208 int i = (int)strlen(z);
2209 while( i>0 && z[i-1]==';' ){ i--; }
2210 fprintf(f, "%.*s;\n", i, z);
2211 }
drh42f64e52012-04-04 16:56:23 +00002212}
2213
2214/*
drhd8621b92012-04-17 09:09:33 +00002215** A no-op routine that runs with the ".breakpoint" doc-command. This is
2216** a useful spot to set a debugger breakpoint.
2217*/
2218static void test_breakpoint(void){
2219 static int nCall = 0;
2220 nCall++;
2221}
2222
2223/*
mistachkin636bf9f2014-07-19 20:15:16 +00002224** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002225*/
mistachkin636bf9f2014-07-19 20:15:16 +00002226typedef struct ImportCtx ImportCtx;
2227struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002228 const char *zFile; /* Name of the input file */
2229 FILE *in; /* Read the CSV text from this input stream */
2230 char *z; /* Accumulated text for a field */
2231 int n; /* Number of bytes in z */
2232 int nAlloc; /* Space allocated for z[] */
2233 int nLine; /* Current line number */
2234 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002235 int cColSep; /* The column separator character. (Usually ",") */
2236 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002237};
2238
2239/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002240static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002241 if( p->n+1>=p->nAlloc ){
2242 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002243 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002244 if( p->z==0 ){
2245 fprintf(stderr, "out of memory\n");
2246 exit(1);
2247 }
2248 }
2249 p->z[p->n++] = (char)c;
2250}
2251
2252/* Read a single field of CSV text. Compatible with rfc4180 and extended
2253** with the option of having a separator other than ",".
2254**
2255** + Input comes from p->in.
2256** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002257** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002258** + Use p->cSep as the column separator. The default is ",".
2259** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002260** + Keep track of the line number in p->nLine.
2261** + Store the character that terminates the field in p->cTerm. Store
2262** EOF on end-of-file.
2263** + Report syntax errors on stderr
2264*/
mistachkin44723ce2015-03-21 02:22:37 +00002265static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002266 int c;
2267 int cSep = p->cColSep;
2268 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002269 p->n = 0;
2270 c = fgetc(p->in);
2271 if( c==EOF || seenInterrupt ){
2272 p->cTerm = EOF;
2273 return 0;
2274 }
2275 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002276 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002277 int startLine = p->nLine;
2278 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002279 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002280 while( 1 ){
2281 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002282 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002283 if( c==cQuote ){
2284 if( pc==cQuote ){
2285 pc = 0;
2286 continue;
2287 }
2288 }
2289 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002290 || (c==rSep && pc==cQuote)
2291 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002292 || (c==EOF && pc==cQuote)
2293 ){
2294 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002295 p->cTerm = c;
2296 break;
2297 }
2298 if( pc==cQuote && c!='\r' ){
2299 fprintf(stderr, "%s:%d: unescaped %c character\n",
2300 p->zFile, p->nLine, cQuote);
2301 }
2302 if( c==EOF ){
2303 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2304 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002305 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002306 break;
2307 }
mistachkin636bf9f2014-07-19 20:15:16 +00002308 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002309 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002310 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002311 }
drhdb95f682013-06-26 22:46:00 +00002312 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002313 while( c!=EOF && c!=cSep && c!=rSep ){
2314 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002315 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002316 }
mistachkin636bf9f2014-07-19 20:15:16 +00002317 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002318 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002319 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002320 }
drhdb95f682013-06-26 22:46:00 +00002321 p->cTerm = c;
2322 }
drh8dd675e2013-07-12 21:09:24 +00002323 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002324 return p->z;
2325}
2326
mistachkin636bf9f2014-07-19 20:15:16 +00002327/* Read a single field of ASCII delimited text.
2328**
2329** + Input comes from p->in.
2330** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002331** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002332** + Use p->cSep as the column separator. The default is "\x1F".
2333** + Use p->rSep as the row separator. The default is "\x1E".
2334** + Keep track of the row number in p->nLine.
2335** + Store the character that terminates the field in p->cTerm. Store
2336** EOF on end-of-file.
2337** + Report syntax errors on stderr
2338*/
mistachkin44723ce2015-03-21 02:22:37 +00002339static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002340 int c;
2341 int cSep = p->cColSep;
2342 int rSep = p->cRowSep;
2343 p->n = 0;
2344 c = fgetc(p->in);
2345 if( c==EOF || seenInterrupt ){
2346 p->cTerm = EOF;
2347 return 0;
2348 }
2349 while( c!=EOF && c!=cSep && c!=rSep ){
2350 import_append_char(p, c);
2351 c = fgetc(p->in);
2352 }
2353 if( c==rSep ){
2354 p->nLine++;
2355 }
2356 p->cTerm = c;
2357 if( p->z ) p->z[p->n] = 0;
2358 return p->z;
2359}
2360
drhdb95f682013-06-26 22:46:00 +00002361/*
drh4bbcf102014-02-06 02:46:08 +00002362** Try to transfer data for table zTable. If an error is seen while
2363** moving forward, try to go backwards. The backwards movement won't
2364** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002365*/
mistachkine31ae902014-02-06 01:15:29 +00002366static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002367 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002368 sqlite3 *newDb,
2369 const char *zTable
2370){
2371 sqlite3_stmt *pQuery = 0;
2372 sqlite3_stmt *pInsert = 0;
2373 char *zQuery = 0;
2374 char *zInsert = 0;
2375 int rc;
2376 int i, j, n;
2377 int nTable = (int)strlen(zTable);
2378 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002379 int cnt = 0;
2380 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002381
2382 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2383 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2384 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002385 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002386 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2387 zQuery);
2388 goto end_data_xfer;
2389 }
2390 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002391 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002392 if( zInsert==0 ){
2393 fprintf(stderr, "out of memory\n");
2394 goto end_data_xfer;
2395 }
2396 sqlite3_snprintf(200+nTable,zInsert,
2397 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2398 i = (int)strlen(zInsert);
2399 for(j=1; j<n; j++){
2400 memcpy(zInsert+i, ",?", 2);
2401 i += 2;
2402 }
2403 memcpy(zInsert+i, ");", 3);
2404 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2405 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002406 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002407 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2408 zQuery);
2409 goto end_data_xfer;
2410 }
2411 for(k=0; k<2; k++){
2412 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2413 for(i=0; i<n; i++){
2414 switch( sqlite3_column_type(pQuery, i) ){
2415 case SQLITE_NULL: {
2416 sqlite3_bind_null(pInsert, i+1);
2417 break;
2418 }
2419 case SQLITE_INTEGER: {
2420 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2421 break;
2422 }
2423 case SQLITE_FLOAT: {
2424 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2425 break;
2426 }
2427 case SQLITE_TEXT: {
2428 sqlite3_bind_text(pInsert, i+1,
2429 (const char*)sqlite3_column_text(pQuery,i),
2430 -1, SQLITE_STATIC);
2431 break;
2432 }
2433 case SQLITE_BLOB: {
2434 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2435 sqlite3_column_bytes(pQuery,i),
2436 SQLITE_STATIC);
2437 break;
2438 }
2439 }
2440 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002441 rc = sqlite3_step(pInsert);
2442 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2443 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2444 sqlite3_errmsg(newDb));
2445 }
drh3350ce92014-02-06 00:49:12 +00002446 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002447 cnt++;
2448 if( (cnt%spinRate)==0 ){
2449 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2450 fflush(stdout);
2451 }
drh3350ce92014-02-06 00:49:12 +00002452 } /* End while */
2453 if( rc==SQLITE_DONE ) break;
2454 sqlite3_finalize(pQuery);
2455 sqlite3_free(zQuery);
2456 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2457 zTable);
2458 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2459 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002460 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2461 break;
drh3350ce92014-02-06 00:49:12 +00002462 }
2463 } /* End for(k=0...) */
2464
2465end_data_xfer:
2466 sqlite3_finalize(pQuery);
2467 sqlite3_finalize(pInsert);
2468 sqlite3_free(zQuery);
2469 sqlite3_free(zInsert);
2470}
2471
2472
2473/*
2474** Try to transfer all rows of the schema that match zWhere. For
2475** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002476** If an error is encountered while moving forward through the
2477** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002478*/
mistachkine31ae902014-02-06 01:15:29 +00002479static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002480 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002481 sqlite3 *newDb,
2482 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002483 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002484){
2485 sqlite3_stmt *pQuery = 0;
2486 char *zQuery = 0;
2487 int rc;
2488 const unsigned char *zName;
2489 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002490 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002491
2492 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2493 " WHERE %s", zWhere);
2494 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2495 if( rc ){
2496 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2497 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2498 zQuery);
2499 goto end_schema_xfer;
2500 }
2501 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2502 zName = sqlite3_column_text(pQuery, 0);
2503 zSql = sqlite3_column_text(pQuery, 1);
2504 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002505 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2506 if( zErrMsg ){
2507 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2508 sqlite3_free(zErrMsg);
2509 zErrMsg = 0;
2510 }
drh3350ce92014-02-06 00:49:12 +00002511 if( xForEach ){
2512 xForEach(p, newDb, (const char*)zName);
2513 }
2514 printf("done\n");
2515 }
2516 if( rc!=SQLITE_DONE ){
2517 sqlite3_finalize(pQuery);
2518 sqlite3_free(zQuery);
2519 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2520 " WHERE %s ORDER BY rowid DESC", zWhere);
2521 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2522 if( rc ){
2523 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2524 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2525 zQuery);
2526 goto end_schema_xfer;
2527 }
2528 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2529 zName = sqlite3_column_text(pQuery, 0);
2530 zSql = sqlite3_column_text(pQuery, 1);
2531 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002532 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2533 if( zErrMsg ){
2534 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2535 sqlite3_free(zErrMsg);
2536 zErrMsg = 0;
2537 }
drh3350ce92014-02-06 00:49:12 +00002538 if( xForEach ){
2539 xForEach(p, newDb, (const char*)zName);
2540 }
2541 printf("done\n");
2542 }
2543 }
2544end_schema_xfer:
2545 sqlite3_finalize(pQuery);
2546 sqlite3_free(zQuery);
2547}
2548
2549/*
2550** Open a new database file named "zNewDb". Try to recover as much information
2551** as possible out of the main database (which might be corrupt) and write it
2552** into zNewDb.
2553*/
drhdcd87a92014-08-18 13:45:42 +00002554static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002555 int rc;
2556 sqlite3 *newDb = 0;
2557 if( access(zNewDb,0)==0 ){
2558 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2559 return;
2560 }
2561 rc = sqlite3_open(zNewDb, &newDb);
2562 if( rc ){
2563 fprintf(stderr, "Cannot create output database: %s\n",
2564 sqlite3_errmsg(newDb));
2565 }else{
drh54d0d2d2014-04-03 00:32:13 +00002566 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002567 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002568 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2569 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002570 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002571 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002572 }
2573 sqlite3_close(newDb);
2574}
2575
2576/*
drhc2ce0be2014-05-29 12:36:14 +00002577** Change the output file back to stdout
2578*/
drhdcd87a92014-08-18 13:45:42 +00002579static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002580 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002581#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002582 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002583#endif
drhc2ce0be2014-05-29 12:36:14 +00002584 }else{
2585 output_file_close(p->out);
2586 }
2587 p->outfile[0] = 0;
2588 p->out = stdout;
2589}
2590
2591/*
drhf7502f02015-02-06 14:19:44 +00002592** Run an SQL command and return the single integer result.
2593*/
2594static int db_int(ShellState *p, const char *zSql){
2595 sqlite3_stmt *pStmt;
2596 int res = 0;
2597 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2598 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2599 res = sqlite3_column_int(pStmt,0);
2600 }
2601 sqlite3_finalize(pStmt);
2602 return res;
2603}
2604
2605/*
2606** Convert a 2-byte or 4-byte big-endian integer into a native integer
2607*/
2608unsigned int get2byteInt(unsigned char *a){
2609 return (a[0]<<8) + a[1];
2610}
2611unsigned int get4byteInt(unsigned char *a){
2612 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2613}
2614
2615/*
2616** Implementation of the ".info" command.
2617**
2618** Return 1 on error, 2 to exit, and 0 otherwise.
2619*/
drh0e55db12015-02-06 14:51:13 +00002620static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002621 static const struct { const char *zName; int ofst; } aField[] = {
2622 { "file change counter:", 24 },
2623 { "database page count:", 28 },
2624 { "freelist page count:", 36 },
2625 { "schema cookie:", 40 },
2626 { "schema format:", 44 },
2627 { "default cache size:", 48 },
2628 { "autovacuum top root:", 52 },
2629 { "incremental vacuum:", 64 },
2630 { "text encoding:", 56 },
2631 { "user version:", 60 },
2632 { "application id:", 68 },
2633 { "software version:", 96 },
2634 };
drh0e55db12015-02-06 14:51:13 +00002635 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2636 { "number of tables:",
2637 "SELECT count(*) FROM %s WHERE type='table'" },
2638 { "number of indexes:",
2639 "SELECT count(*) FROM %s WHERE type='index'" },
2640 { "number of triggers:",
2641 "SELECT count(*) FROM %s WHERE type='trigger'" },
2642 { "number of views:",
2643 "SELECT count(*) FROM %s WHERE type='view'" },
2644 { "schema size:",
2645 "SELECT total(length(sql)) FROM %s" },
2646 };
2647 sqlite3_file *pFile;
2648 int i;
2649 char *zSchemaTab;
2650 char *zDb = nArg>=2 ? azArg[1] : "main";
2651 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002652 open_db(p, 0);
2653 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002654 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002655 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2656 return 1;
2657 }
2658 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2659 if( i!=SQLITE_OK ){
2660 fprintf(stderr, "unable to read database header\n");
2661 return 1;
2662 }
2663 i = get2byteInt(aHdr+16);
2664 if( i==1 ) i = 65536;
2665 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2666 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2667 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2668 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
2669 for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
2670 int ofst = aField[i].ofst;
2671 unsigned int val = get4byteInt(aHdr + ofst);
2672 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2673 switch( ofst ){
2674 case 56: {
2675 if( val==1 ) fprintf(p->out, " (utf8)");
2676 if( val==2 ) fprintf(p->out, " (utf16le)");
2677 if( val==3 ) fprintf(p->out, " (utf16be)");
2678 }
2679 }
2680 fprintf(p->out, "\n");
2681 }
drh0e55db12015-02-06 14:51:13 +00002682 if( zDb==0 ){
2683 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2684 }else if( strcmp(zDb,"temp")==0 ){
2685 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2686 }else{
2687 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2688 }
2689 for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
2690 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2691 int val = db_int(p, zSql);
2692 sqlite3_free(zSql);
2693 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2694 }
2695 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002696 return 0;
2697}
2698
2699
2700/*
drh75897232000-05-29 14:26:00 +00002701** If an input line begins with "." then invoke this routine to
2702** process that line.
drh67505e72002-04-19 12:34:06 +00002703**
drh47ad6842006-11-08 12:25:42 +00002704** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002705*/
drhdcd87a92014-08-18 13:45:42 +00002706static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00002707 int h = 1;
drh75897232000-05-29 14:26:00 +00002708 int nArg = 0;
2709 int n, c;
drh67505e72002-04-19 12:34:06 +00002710 int rc = 0;
drh75897232000-05-29 14:26:00 +00002711 char *azArg[50];
2712
2713 /* Parse the input line into tokens.
2714 */
mistachkin8e189222015-04-19 21:43:16 +00002715 while( zLine[h] && nArg<ArraySize(azArg) ){
2716 while( IsSpace(zLine[h]) ){ h++; }
2717 if( zLine[h]==0 ) break;
2718 if( zLine[h]=='\'' || zLine[h]=='"' ){
2719 int delim = zLine[h++];
2720 azArg[nArg++] = &zLine[h];
2721 while( zLine[h] && zLine[h]!=delim ){
2722 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
2723 h++;
drh4c56b992013-06-27 13:26:55 +00002724 }
mistachkin8e189222015-04-19 21:43:16 +00002725 if( zLine[h]==delim ){
2726 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00002727 }
drhfeac5f82004-08-01 00:10:45 +00002728 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002729 }else{
mistachkin8e189222015-04-19 21:43:16 +00002730 azArg[nArg++] = &zLine[h];
2731 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
2732 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002733 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002734 }
2735 }
2736
2737 /* Process the input line.
2738 */
shane9bd1b442009-10-23 01:27:39 +00002739 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002740 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002741 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002742 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2743 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2744 ){
drhbc46f022013-01-23 18:53:23 +00002745 const char *zDestFile = 0;
2746 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002747 sqlite3 *pDest;
2748 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002749 int j;
2750 for(j=1; j<nArg; j++){
2751 const char *z = azArg[j];
2752 if( z[0]=='-' ){
2753 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002754 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002755 {
2756 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2757 return 1;
2758 }
2759 }else if( zDestFile==0 ){
2760 zDestFile = azArg[j];
2761 }else if( zDb==0 ){
2762 zDb = zDestFile;
2763 zDestFile = azArg[j];
2764 }else{
2765 fprintf(stderr, "too many arguments to .backup\n");
2766 return 1;
2767 }
drh9ff849f2009-02-04 20:55:57 +00002768 }
drhbc46f022013-01-23 18:53:23 +00002769 if( zDestFile==0 ){
2770 fprintf(stderr, "missing FILENAME argument on .backup\n");
2771 return 1;
2772 }
2773 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002774 rc = sqlite3_open(zDestFile, &pDest);
2775 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002776 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002777 sqlite3_close(pDest);
2778 return 1;
2779 }
drh05782482013-10-24 15:20:20 +00002780 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002781 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2782 if( pBackup==0 ){
2783 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2784 sqlite3_close(pDest);
2785 return 1;
2786 }
2787 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2788 sqlite3_backup_finish(pBackup);
2789 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002790 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002791 }else{
2792 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002793 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002794 }
2795 sqlite3_close(pDest);
2796 }else
2797
drhc2ce0be2014-05-29 12:36:14 +00002798 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2799 if( nArg==2 ){
2800 bail_on_error = booleanValue(azArg[1]);
2801 }else{
2802 fprintf(stderr, "Usage: .bail on|off\n");
2803 rc = 1;
2804 }
drhc49f44e2006-10-26 18:15:42 +00002805 }else
2806
mistachkinf21979d2015-01-18 05:35:01 +00002807 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
2808 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00002809 if( booleanValue(azArg[1]) ){
2810 setBinaryMode(p->out);
2811 }else{
2812 setTextMode(p->out);
2813 }
mistachkinf21979d2015-01-18 05:35:01 +00002814 }else{
2815 fprintf(stderr, "Usage: .binary on|off\n");
2816 rc = 1;
2817 }
2818 }else
2819
drhd8621b92012-04-17 09:09:33 +00002820 /* The undocumented ".breakpoint" command causes a call to the no-op
2821 ** routine named test_breakpoint().
2822 */
2823 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2824 test_breakpoint();
2825 }else
2826
drhc2ce0be2014-05-29 12:36:14 +00002827 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2828 if( nArg==2 ){
2829 tryToClone(p, azArg[1]);
2830 }else{
2831 fprintf(stderr, "Usage: .clone FILENAME\n");
2832 rc = 1;
2833 }
mistachkine31ae902014-02-06 01:15:29 +00002834 }else
2835
drhc2ce0be2014-05-29 12:36:14 +00002836 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002837 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002838 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002839 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002840 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002841 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002842 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002843 data.colWidth[0] = 3;
2844 data.colWidth[1] = 15;
2845 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002846 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002847 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002848 if( zErrMsg ){
2849 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002850 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002851 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002852 }
2853 }else
2854
drh0e55db12015-02-06 14:51:13 +00002855 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2856 rc = shell_dbinfo_command(p, nArg, azArg);
2857 }else
2858
drhc2ce0be2014-05-29 12:36:14 +00002859 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002860 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002861 /* When playing back a "dump", the content might appear in an order
2862 ** which causes immediate foreign key constraints to be violated.
2863 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002864 if( nArg!=1 && nArg!=2 ){
2865 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2866 rc = 1;
2867 goto meta_command_exit;
2868 }
drhf1dfc4f2009-09-23 15:51:35 +00002869 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002870 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002871 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002872 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002873 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002874 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002875 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002876 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002877 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002878 );
2879 run_schema_dump_query(p,
2880 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002881 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002882 );
drh2f464a02011-10-13 00:41:49 +00002883 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002884 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002885 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002886 );
drh4c653a02000-06-07 01:27:47 +00002887 }else{
2888 int i;
drhdd3d4592004-08-30 01:54:05 +00002889 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002890 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002891 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002892 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002893 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002894 " AND sql NOT NULL");
2895 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002896 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002897 "WHERE sql NOT NULL"
2898 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002899 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002900 );
danielk1977bc6ada42004-06-30 08:20:16 +00002901 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002902 }
2903 }
drh45e29d82006-11-20 16:21:10 +00002904 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002905 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002906 p->writableSchema = 0;
2907 }
drh56197952011-10-13 16:30:13 +00002908 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2909 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002910 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002911 }else
drh75897232000-05-29 14:26:00 +00002912
drhc2ce0be2014-05-29 12:36:14 +00002913 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2914 if( nArg==2 ){
2915 p->echoOn = booleanValue(azArg[1]);
2916 }else{
2917 fprintf(stderr, "Usage: .echo on|off\n");
2918 rc = 1;
2919 }
drhdaffd0e2001-04-11 14:28:42 +00002920 }else
2921
drhc2ce0be2014-05-29 12:36:14 +00002922 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2923 if( nArg==2 ){
2924 p->autoEQP = booleanValue(azArg[1]);
2925 }else{
2926 fprintf(stderr, "Usage: .eqp on|off\n");
2927 rc = 1;
2928 }
drhefbf3b12014-02-28 20:47:24 +00002929 }else
2930
drhd3ac7d92013-01-25 18:33:43 +00002931 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002932 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002933 rc = 2;
drh75897232000-05-29 14:26:00 +00002934 }else
2935
drhc2ce0be2014-05-29 12:36:14 +00002936 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002937 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002938 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002939 if(!p->normalMode.valid) {
2940 p->normalMode.valid = 1;
2941 p->normalMode.mode = p->mode;
2942 p->normalMode.showHeader = p->showHeader;
2943 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002944 }
2945 /* We could put this code under the !p->explainValid
2946 ** condition so that it does not execute if we are already in
2947 ** explain mode. However, always executing it allows us an easy
2948 ** was to reset to explain mode in case the user previously
2949 ** did an .explain followed by a .width, .mode or .header
2950 ** command.
2951 */
danielk19770d78bae2008-01-03 07:09:48 +00002952 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002953 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002954 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002955 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002956 p->colWidth[1] = 13; /* opcode */
2957 p->colWidth[2] = 4; /* P1 */
2958 p->colWidth[3] = 4; /* P2 */
2959 p->colWidth[4] = 4; /* P3 */
2960 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002961 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002962 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002963 }else if (p->normalMode.valid) {
2964 p->normalMode.valid = 0;
2965 p->mode = p->normalMode.mode;
2966 p->showHeader = p->normalMode.showHeader;
2967 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002968 }
drh75897232000-05-29 14:26:00 +00002969 }else
2970
drhc1971542014-06-23 23:28:13 +00002971 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002972 ShellState data;
drhc1971542014-06-23 23:28:13 +00002973 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002974 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002975 if( nArg!=1 ){
2976 fprintf(stderr, "Usage: .fullschema\n");
2977 rc = 1;
2978 goto meta_command_exit;
2979 }
2980 open_db(p, 0);
2981 memcpy(&data, p, sizeof(data));
2982 data.showHeader = 0;
2983 data.mode = MODE_Semi;
2984 rc = sqlite3_exec(p->db,
2985 "SELECT sql FROM"
2986 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2987 " FROM sqlite_master UNION ALL"
2988 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002989 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002990 "ORDER BY rowid",
2991 callback, &data, &zErrMsg
2992 );
drh56f674c2014-07-18 14:43:29 +00002993 if( rc==SQLITE_OK ){
2994 sqlite3_stmt *pStmt;
2995 rc = sqlite3_prepare_v2(p->db,
2996 "SELECT rowid FROM sqlite_master"
2997 " WHERE name GLOB 'sqlite_stat[134]'",
2998 -1, &pStmt, 0);
2999 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3000 sqlite3_finalize(pStmt);
3001 }
3002 if( doStats==0 ){
3003 fprintf(p->out, "/* No STAT tables available */\n");
3004 }else{
3005 fprintf(p->out, "ANALYZE sqlite_master;\n");
3006 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3007 callback, &data, &zErrMsg);
3008 data.mode = MODE_Insert;
3009 data.zDestTable = "sqlite_stat1";
3010 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3011 shell_callback, &data,&zErrMsg);
3012 data.zDestTable = "sqlite_stat3";
3013 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3014 shell_callback, &data,&zErrMsg);
3015 data.zDestTable = "sqlite_stat4";
3016 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3017 shell_callback, &data, &zErrMsg);
3018 fprintf(p->out, "ANALYZE sqlite_master;\n");
3019 }
drhc1971542014-06-23 23:28:13 +00003020 }else
3021
drhc2ce0be2014-05-29 12:36:14 +00003022 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3023 if( nArg==2 ){
3024 p->showHeader = booleanValue(azArg[1]);
3025 }else{
3026 fprintf(stderr, "Usage: .headers on|off\n");
3027 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003028 }
drh75897232000-05-29 14:26:00 +00003029 }else
3030
drhc2ce0be2014-05-29 12:36:14 +00003031 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
3032 fprintf(p->out, "%s", zHelp);
3033 }else
3034
3035 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003036 char *zTable; /* Insert data into this table */
3037 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003038 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003039 int nCol; /* Number of columns in the table */
3040 int nByte; /* Number of bytes in an SQL string */
3041 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003042 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003043 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003044 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003045 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003046 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3047 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003048
drhc2ce0be2014-05-29 12:36:14 +00003049 if( nArg!=3 ){
3050 fprintf(stderr, "Usage: .import FILE TABLE\n");
3051 goto meta_command_exit;
3052 }
drh01f37542014-05-31 15:43:33 +00003053 zFile = azArg[1];
3054 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003055 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003056 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003057 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003058 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003059 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003060 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003061 return 1;
drhfeac5f82004-08-01 00:10:45 +00003062 }
drhdb95f682013-06-26 22:46:00 +00003063 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003064 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003065 " for import\n");
3066 return 1;
3067 }
mistachkin636bf9f2014-07-19 20:15:16 +00003068 nSep = strlen30(p->rowSeparator);
3069 if( nSep==0 ){
3070 fprintf(stderr, "Error: non-null row separator required for import\n");
3071 return 1;
3072 }
mistachkine0d68852014-12-11 03:12:33 +00003073 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3074 /* When importing CSV (only), if the row separator is set to the
3075 ** default output row separator, change it to the default input
3076 ** row separator. This avoids having to maintain different input
3077 ** and output row separators. */
3078 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3079 nSep = strlen30(p->rowSeparator);
3080 }
mistachkin636bf9f2014-07-19 20:15:16 +00003081 if( nSep>1 ){
3082 fprintf(stderr, "Error: multi-character row separators not allowed"
3083 " for import\n");
3084 return 1;
3085 }
3086 sCtx.zFile = zFile;
3087 sCtx.nLine = 1;
3088 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003089#ifdef SQLITE_OMIT_POPEN
mistachkinba132c72015-03-19 14:48:38 +00003090 fprintf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003091 return 1;
3092#else
mistachkin636bf9f2014-07-19 20:15:16 +00003093 sCtx.in = popen(sCtx.zFile+1, "r");
3094 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003095 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003096#endif
drh5bde8162013-06-27 14:07:53 +00003097 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003098 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003099 xCloser = fclose;
3100 }
mistachkin636bf9f2014-07-19 20:15:16 +00003101 if( p->mode==MODE_Ascii ){
3102 xRead = ascii_read_one_field;
3103 }else{
3104 xRead = csv_read_one_field;
3105 }
3106 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00003107 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003108 return 1;
3109 }
mistachkin636bf9f2014-07-19 20:15:16 +00003110 sCtx.cColSep = p->colSeparator[0];
3111 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003112 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003113 if( zSql==0 ){
3114 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003115 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003116 return 1;
3117 }
drh4f21c4a2008-12-10 22:15:00 +00003118 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003119 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003120 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003121 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003122 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3123 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003124 while( xRead(&sCtx) ){
3125 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003126 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003127 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003128 }
drh5bde8162013-06-27 14:07:53 +00003129 if( cSep=='(' ){
3130 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003131 sqlite3_free(sCtx.z);
3132 xCloser(sCtx.in);
3133 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003134 return 1;
3135 }
drhdb95f682013-06-26 22:46:00 +00003136 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3137 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3138 sqlite3_free(zCreate);
3139 if( rc ){
3140 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003141 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003142 sqlite3_free(sCtx.z);
3143 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003144 return 1;
3145 }
drhc7181902014-02-27 15:04:13 +00003146 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003147 }
drhfeac5f82004-08-01 00:10:45 +00003148 sqlite3_free(zSql);
3149 if( rc ){
shane916f9612009-10-23 00:37:15 +00003150 if (pStmt) sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003151 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003152 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003153 return 1;
drhfeac5f82004-08-01 00:10:45 +00003154 }
shane916f9612009-10-23 00:37:15 +00003155 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003156 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003157 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003158 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003159 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003160 if( zSql==0 ){
3161 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003162 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003163 return 1;
3164 }
drhdb95f682013-06-26 22:46:00 +00003165 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003166 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003167 for(i=1; i<nCol; i++){
3168 zSql[j++] = ',';
3169 zSql[j++] = '?';
3170 }
3171 zSql[j++] = ')';
3172 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003173 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003174 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003175 if( rc ){
mistachkin8e189222015-04-19 21:43:16 +00003176 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003177 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003178 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003179 return 1;
drhfeac5f82004-08-01 00:10:45 +00003180 }
mistachkin8e189222015-04-19 21:43:16 +00003181 needCommit = sqlite3_get_autocommit(p->db);
3182 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003183 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003184 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003185 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003186 char *z = xRead(&sCtx);
3187 /*
3188 ** Did we reach end-of-file before finding any columns?
3189 ** If so, stop instead of NULL filling the remaining columns.
3190 */
drhdb95f682013-06-26 22:46:00 +00003191 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003192 /*
3193 ** Did we reach end-of-file OR end-of-line before finding any
3194 ** columns in ASCII mode? If so, stop instead of NULL filling
3195 ** the remaining columns.
3196 */
3197 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003198 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003199 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003200 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3201 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003202 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003203 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003204 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003205 }
drhfeac5f82004-08-01 00:10:45 +00003206 }
mistachkin636bf9f2014-07-19 20:15:16 +00003207 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003208 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003209 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003210 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003211 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003212 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3213 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003214 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003215 }
drhdb95f682013-06-26 22:46:00 +00003216 if( i>=nCol ){
3217 sqlite3_step(pStmt);
3218 rc = sqlite3_reset(pStmt);
3219 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003220 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
mistachkin8e189222015-04-19 21:43:16 +00003221 sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003222 }
3223 }
mistachkin636bf9f2014-07-19 20:15:16 +00003224 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003225
mistachkin636bf9f2014-07-19 20:15:16 +00003226 xCloser(sCtx.in);
3227 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003228 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003229 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003230 }else
3231
drh0e55db12015-02-06 14:51:13 +00003232 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3233 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003234 ShellState data;
drh75897232000-05-29 14:26:00 +00003235 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003236 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003237 memcpy(&data, p, sizeof(data));
3238 data.showHeader = 0;
3239 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003240 if( nArg==1 ){
3241 rc = sqlite3_exec(p->db,
3242 "SELECT name FROM sqlite_master "
3243 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3244 "UNION ALL "
3245 "SELECT name FROM sqlite_temp_master "
3246 "WHERE type='index' "
3247 "ORDER BY 1",
3248 callback, &data, &zErrMsg
3249 );
drhc2ce0be2014-05-29 12:36:14 +00003250 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003251 zShellStatic = azArg[1];
3252 rc = sqlite3_exec(p->db,
3253 "SELECT name FROM sqlite_master "
3254 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3255 "UNION ALL "
3256 "SELECT name FROM sqlite_temp_master "
3257 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3258 "ORDER BY 1",
3259 callback, &data, &zErrMsg
3260 );
3261 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003262 }else{
drh0e55db12015-02-06 14:51:13 +00003263 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003264 rc = 1;
3265 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003266 }
drh75897232000-05-29 14:26:00 +00003267 if( zErrMsg ){
3268 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003269 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003270 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003271 }else if( rc != SQLITE_OK ){
3272 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3273 rc = 1;
drh75897232000-05-29 14:26:00 +00003274 }
3275 }else
3276
drhae5e4452007-05-03 17:18:36 +00003277#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003278 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003279 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003280 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3281 iotrace = 0;
3282 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003283 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003284 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003285 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003286 iotrace = stdout;
3287 }else{
3288 iotrace = fopen(azArg[1], "w");
3289 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003290 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003291 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003292 rc = 1;
drhb0603412007-02-28 04:47:26 +00003293 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003294 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003295 }
3296 }
3297 }else
drhae5e4452007-05-03 17:18:36 +00003298#endif
drh1a513372015-05-02 17:40:23 +00003299 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3300 static const struct {
3301 const char *zLimitName; /* Name of a limit */
3302 int limitCode; /* Integer code for that limit */
3303 } aLimit[] = {
3304 { "length", SQLITE_LIMIT_LENGTH },
3305 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3306 { "column", SQLITE_LIMIT_COLUMN },
3307 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3308 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3309 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3310 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3311 { "attached", SQLITE_LIMIT_ATTACHED },
3312 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3313 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3314 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3315 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3316 };
3317 int i, n2;
3318 open_db(p, 0);
3319 if( nArg==1 ){
3320 for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
3321 printf("%20s %d\n", aLimit[i].zLimitName,
3322 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3323 }
3324 }else if( nArg>3 ){
3325 fprintf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
3326 rc = 1;
3327 goto meta_command_exit;
3328 }else{
3329 int iLimit = -1;
3330 n2 = strlen30(azArg[1]);
3331 for(i=0; i<sizeof(aLimit)/sizeof(aLimit[0]); i++){
3332 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3333 if( iLimit<0 ){
3334 iLimit = i;
3335 }else{
3336 fprintf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
3337 rc = 1;
3338 goto meta_command_exit;
3339 }
3340 }
3341 }
3342 if( iLimit<0 ){
3343 fprintf(stderr, "unknown limit: \"%s\"\n"
3344 "enter \".limits\" with no arguments for a list.\n",
3345 azArg[1]);
3346 rc = 1;
3347 goto meta_command_exit;
3348 }
3349 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003350 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3351 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003352 }
3353 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3354 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3355 }
3356 }else
drhb0603412007-02-28 04:47:26 +00003357
drh70df4fe2006-06-13 15:12:21 +00003358#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003359 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003360 const char *zFile, *zProc;
3361 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003362 if( nArg<2 ){
3363 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3364 rc = 1;
3365 goto meta_command_exit;
3366 }
drh1e397f82006-06-08 15:28:43 +00003367 zFile = azArg[1];
3368 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003369 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003370 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3371 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003372 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003373 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003374 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003375 }
3376 }else
drh70df4fe2006-06-13 15:12:21 +00003377#endif
drh1e397f82006-06-08 15:28:43 +00003378
drhc2ce0be2014-05-29 12:36:14 +00003379 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3380 if( nArg!=2 ){
3381 fprintf(stderr, "Usage: .log FILENAME\n");
3382 rc = 1;
3383 }else{
3384 const char *zFile = azArg[1];
3385 output_file_close(p->pLog);
3386 p->pLog = output_file_open(zFile);
3387 }
drh127f9d72010-02-23 01:47:00 +00003388 }else
3389
drhc2ce0be2014-05-29 12:36:14 +00003390 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3391 const char *zMode = nArg>=2 ? azArg[1] : "";
3392 int n2 = (int)strlen(zMode);
3393 int c2 = zMode[0];
3394 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003395 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003396 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003397 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003398 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003399 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003400 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003401 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003402 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003403 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003404 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003405 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003406 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003407 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003408 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003409 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003410 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003411 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003412 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003413 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003414 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003415 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3416 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003417 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3418 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003419 }else {
shane9bd1b442009-10-23 01:27:39 +00003420 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003421 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003422 rc = 1;
drh75897232000-05-29 14:26:00 +00003423 }
3424 }else
3425
drhc2ce0be2014-05-29 12:36:14 +00003426 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3427 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003428 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3429 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003430 }else{
3431 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003432 rc = 1;
3433 }
3434 }else
3435
drh05782482013-10-24 15:20:20 +00003436 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3437 sqlite3 *savedDb = p->db;
3438 const char *zSavedFilename = p->zDbFilename;
3439 char *zNewFilename = 0;
3440 p->db = 0;
3441 if( nArg>=2 ){
3442 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3443 }
3444 open_db(p, 1);
3445 if( p->db!=0 ){
drhe6229612014-08-18 15:08:26 +00003446 session_close_all(p);
drh05782482013-10-24 15:20:20 +00003447 sqlite3_close(savedDb);
3448 sqlite3_free(p->zFreeOnClose);
3449 p->zFreeOnClose = zNewFilename;
3450 }else{
3451 sqlite3_free(zNewFilename);
3452 p->db = savedDb;
3453 p->zDbFilename = zSavedFilename;
3454 }
3455 }else
3456
drhc2ce0be2014-05-29 12:36:14 +00003457 if( c=='o'
3458 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3459 ){
3460 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3461 if( nArg>2 ){
3462 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3463 rc = 1;
3464 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003465 }
drhc2ce0be2014-05-29 12:36:14 +00003466 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3467 if( nArg<2 ){
3468 fprintf(stderr, "Usage: .once FILE\n");
3469 rc = 1;
3470 goto meta_command_exit;
3471 }
3472 p->outCount = 2;
3473 }else{
3474 p->outCount = 0;
3475 }
3476 output_reset(p);
3477 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003478#ifdef SQLITE_OMIT_POPEN
3479 fprintf(stderr,"Error: pipes are not supported in this OS\n");
3480 rc = 1;
3481 p->out = stdout;
3482#else
drhc2ce0be2014-05-29 12:36:14 +00003483 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003484 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003485 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003486 p->out = stdout;
3487 rc = 1;
3488 }else{
drhc2ce0be2014-05-29 12:36:14 +00003489 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003490 }
drh8cd5b252015-03-02 22:06:43 +00003491#endif
drh75897232000-05-29 14:26:00 +00003492 }else{
drhc2ce0be2014-05-29 12:36:14 +00003493 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003494 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003495 if( strcmp(zFile,"off")!=0 ){
3496 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003497 }
drh75897232000-05-29 14:26:00 +00003498 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003499 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003500 } else {
drhc2ce0be2014-05-29 12:36:14 +00003501 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003502 }
3503 }
3504 }else
3505
drh078b1fd2012-09-21 13:40:02 +00003506 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3507 int i;
3508 for(i=1; i<nArg; i++){
3509 if( i>1 ) fprintf(p->out, " ");
3510 fprintf(p->out, "%s", azArg[i]);
3511 }
3512 fprintf(p->out, "\n");
3513 }else
3514
drhc2ce0be2014-05-29 12:36:14 +00003515 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003516 if( nArg >= 2) {
3517 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3518 }
3519 if( nArg >= 3) {
3520 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3521 }
3522 }else
3523
drhc2ce0be2014-05-29 12:36:14 +00003524 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003525 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003526 }else
3527
drhc2ce0be2014-05-29 12:36:14 +00003528 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3529 FILE *alt;
3530 if( nArg!=2 ){
3531 fprintf(stderr, "Usage: .read FILE\n");
3532 rc = 1;
3533 goto meta_command_exit;
3534 }
3535 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003536 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003537 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3538 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003539 }else{
shane9bd1b442009-10-23 01:27:39 +00003540 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003541 fclose(alt);
3542 }
3543 }else
3544
drhc2ce0be2014-05-29 12:36:14 +00003545 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003546 const char *zSrcFile;
3547 const char *zDb;
3548 sqlite3 *pSrc;
3549 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003550 int nTimeout = 0;
3551
drh9ff849f2009-02-04 20:55:57 +00003552 if( nArg==2 ){
3553 zSrcFile = azArg[1];
3554 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003555 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003556 zSrcFile = azArg[2];
3557 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003558 }else{
3559 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3560 rc = 1;
3561 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003562 }
3563 rc = sqlite3_open(zSrcFile, &pSrc);
3564 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003565 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003566 sqlite3_close(pSrc);
3567 return 1;
3568 }
drh05782482013-10-24 15:20:20 +00003569 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003570 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3571 if( pBackup==0 ){
3572 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3573 sqlite3_close(pSrc);
3574 return 1;
3575 }
drhdc2c4912009-02-04 22:46:47 +00003576 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3577 || rc==SQLITE_BUSY ){
3578 if( rc==SQLITE_BUSY ){
3579 if( nTimeout++ >= 3 ) break;
3580 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003581 }
3582 }
3583 sqlite3_backup_finish(pBackup);
3584 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003585 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003586 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003587 fprintf(stderr, "Error: source database is busy\n");
3588 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003589 }else{
3590 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003591 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003592 }
3593 sqlite3_close(pSrc);
3594 }else
3595
dan8d1edb92014-11-05 09:07:28 +00003596
3597 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3598 if( nArg==2 ){
3599 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003600#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3601 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3602#endif
dan8d1edb92014-11-05 09:07:28 +00003603 }else{
3604 fprintf(stderr, "Usage: .scanstats on|off\n");
3605 rc = 1;
3606 }
3607 }else
3608
drhc2ce0be2014-05-29 12:36:14 +00003609 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003610 ShellState data;
drh75897232000-05-29 14:26:00 +00003611 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003612 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003613 memcpy(&data, p, sizeof(data));
3614 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003615 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003616 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003617 int i;
drhf0693c82011-10-11 20:41:54 +00003618 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003619 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003620 char *new_argv[2], *new_colv[2];
3621 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3622 " type text,\n"
3623 " name text,\n"
3624 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003625 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003626 " sql text\n"
3627 ")";
3628 new_argv[1] = 0;
3629 new_colv[0] = "sql";
3630 new_colv[1] = 0;
3631 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003632 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003633 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003634 char *new_argv[2], *new_colv[2];
3635 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3636 " type text,\n"
3637 " name text,\n"
3638 " tbl_name text,\n"
3639 " rootpage integer,\n"
3640 " sql text\n"
3641 ")";
3642 new_argv[1] = 0;
3643 new_colv[0] = "sql";
3644 new_colv[1] = 0;
3645 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003646 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003647 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003648 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003649 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003650 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003651 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003652 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003653 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003654 "WHERE lower(tbl_name) LIKE shellstatic()"
3655 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003656 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003657 callback, &data, &zErrMsg);
3658 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003659 }
drhc2ce0be2014-05-29 12:36:14 +00003660 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003661 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003662 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003663 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003664 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003665 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003666 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003667 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003668 callback, &data, &zErrMsg
3669 );
drhc2ce0be2014-05-29 12:36:14 +00003670 }else{
3671 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3672 rc = 1;
3673 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003674 }
drh75897232000-05-29 14:26:00 +00003675 if( zErrMsg ){
3676 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003677 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003678 rc = 1;
3679 }else if( rc != SQLITE_OK ){
3680 fprintf(stderr,"Error: querying schema information\n");
3681 rc = 1;
3682 }else{
3683 rc = 0;
drh75897232000-05-29 14:26:00 +00003684 }
3685 }else
3686
drhabd4c722014-09-20 18:18:33 +00003687#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3688 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3689 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003690 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003691 }else
3692#endif
3693
drhe6229612014-08-18 15:08:26 +00003694#if defined(SQLITE_ENABLE_SESSION)
3695 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
3696 OpenSession *pSession = &p->aSession[0];
3697 char **azCmd = &azArg[1];
3698 int iSes = 0;
3699 int nCmd = nArg - 1;
3700 int i;
3701 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00003702 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00003703 if( nArg>=3 ){
3704 for(iSes=0; iSes<p->nSession; iSes++){
3705 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
3706 }
3707 if( iSes<p->nSession ){
3708 pSession = &p->aSession[iSes];
3709 azCmd++;
3710 nCmd--;
3711 }else{
3712 pSession = &p->aSession[0];
3713 iSes = 0;
3714 }
3715 }
3716
drh3a67b042014-08-18 17:56:31 +00003717 /* .session attach TABLE
3718 ** Invoke the sqlite3session_attach() interface to attach a particular
3719 ** table so that it is never filtered.
3720 */
3721 if( strcmp(azCmd[0],"attach")==0 ){
3722 if( nCmd!=2 ) goto session_syntax_error;
3723 if( pSession->p==0 ){
3724 session_not_open:
3725 fprintf(stderr, "ERROR: No sessions are open\n");
3726 }else{
3727 rc = sqlite3session_attach(pSession->p, azCmd[1]);
3728 if( rc ){
3729 fprintf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
3730 rc = 0;
3731 }
3732 }
3733 }else
3734
3735 /* .session changeset FILE
3736 ** .session patchset FILE
3737 ** Write a changeset or patchset into a file. The file is overwritten.
3738 */
3739 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
3740 FILE *out = 0;
3741 if( nCmd!=2 ) goto session_syntax_error;
3742 if( pSession->p==0 ) goto session_not_open;
3743 out = fopen(azCmd[1], "wb");
3744 if( out==0 ){
3745 fprintf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
3746 }else{
3747 int szChng;
3748 void *pChng;
3749 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00003750 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00003751 }else{
drh2967e0c2014-08-19 00:26:17 +00003752 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
3753 }
3754 if( rc ){
3755 printf("Error: error code %d\n", rc);
3756 rc = 0;
drh3a67b042014-08-18 17:56:31 +00003757 }
3758 if( pChng
3759 && fwrite(pChng, szChng, 1, out)!=1 ){
3760 fprintf(stderr, "ERROR: Failed to write entire %d-byte output\n",
3761 szChng);
3762 }
3763 sqlite3_free(pChng);
3764 fclose(out);
3765 }
3766 }else
3767
drhe6229612014-08-18 15:08:26 +00003768 /* .session close
3769 ** Close the identified session
3770 */
3771 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00003772 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00003773 if( p->nSession ){
3774 session_close(pSession);
3775 p->aSession[iSes] = p->aSession[--p->nSession];
3776 }
3777 }else
3778
drh03168ca2014-08-18 20:01:31 +00003779 /* .session enable ?BOOLEAN?
3780 ** Query or set the enable flag
3781 */
3782 if( strcmp(azCmd[0], "enable")==0 ){
3783 int ii;
3784 if( nCmd>2 ) goto session_syntax_error;
3785 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
3786 if( p->nSession ){
3787 ii = sqlite3session_enable(pSession->p, ii);
3788 fprintf(p->out, "session %s enable flag = %d\n", pSession->zName, ii);
3789 }
3790 }else
3791
3792 /* .session filter GLOB ....
3793 ** Set a list of GLOB patterns of table names to be excluded.
3794 */
3795 if( strcmp(azCmd[0], "filter")==0 ){
3796 int ii, nByte;
3797 if( nCmd<2 ) goto session_syntax_error;
3798 if( p->nSession ){
3799 for(ii=0; ii<pSession->nFilter; ii++){
3800 sqlite3_free(pSession->azFilter[ii]);
3801 }
3802 sqlite3_free(pSession->azFilter);
3803 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
3804 pSession->azFilter = sqlite3_malloc( nByte );
3805 if( pSession->azFilter==0 ){
3806 fprintf(stderr, "Error: out or memory\n");
3807 exit(1);
3808 }
3809 for(ii=1; ii<nCmd; ii++){
3810 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
3811 }
3812 pSession->nFilter = ii-1;
3813 }
3814 }else
3815
3816 /* .session indirect ?BOOLEAN?
3817 ** Query or set the indirect flag
3818 */
3819 if( strcmp(azCmd[0], "indirect")==0 ){
3820 int ii;
3821 if( nCmd>2 ) goto session_syntax_error;
3822 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
3823 if( p->nSession ){
3824 ii = sqlite3session_indirect(pSession->p, ii);
3825 fprintf(p->out, "session %s indirect flag = %d\n", pSession->zName,ii);
3826 }
3827 }else
3828
3829 /* .session isempty
3830 ** Determine if the session is empty
3831 */
3832 if( strcmp(azCmd[0], "isempty")==0 ){
3833 int ii;
3834 if( nCmd!=1 ) goto session_syntax_error;
3835 if( p->nSession ){
3836 ii = sqlite3session_isempty(pSession->p);
3837 fprintf(p->out, "session %s isempty flag = %d\n", pSession->zName, ii);
3838 }
3839 }else
3840
drhe6229612014-08-18 15:08:26 +00003841 /* .session list
3842 ** List all currently open sessions
3843 */
3844 if( strcmp(azCmd[0],"list")==0 ){
3845 for(i=0; i<p->nSession; i++){
3846 fprintf(p->out, "%d %s\n", i, p->aSession[i].zName);
3847 }
3848 }else
3849
3850 /* .session open DB NAME
3851 ** Open a new session called NAME on the attached database DB.
3852 ** DB is normally "main".
3853 */
3854 if( strcmp(azCmd[0],"open")==0 ){
3855 char *zName;
3856 if( nCmd!=3 ) goto session_syntax_error;
3857 zName = azCmd[2];
3858 if( zName[0]==0 ) goto session_syntax_error;
3859 for(i=0; i<p->nSession; i++){
3860 if( strcmp(p->aSession[i].zName,zName)==0 ){
3861 fprintf(stderr, "Session \"%s\" already exists\n", zName);
3862 goto meta_command_exit;
3863 }
3864 }
3865 if( p->nSession>=ArraySize(p->aSession) ){
3866 fprintf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
3867 goto meta_command_exit;
3868 }
3869 pSession = &p->aSession[p->nSession];
3870 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
3871 if( rc ){
3872 fprintf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00003873 rc = 0;
drhe6229612014-08-18 15:08:26 +00003874 goto meta_command_exit;
3875 }
drh03168ca2014-08-18 20:01:31 +00003876 pSession->nFilter = 0;
3877 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00003878 p->nSession++;
3879 pSession->zName = sqlite3_mprintf("%s", zName);
3880 }else
3881 /* If no command name matches, show a syntax error */
3882 session_syntax_error:
3883 session_help(p);
3884 }else
3885#endif
3886
drh340f5822013-06-27 13:01:21 +00003887#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003888 /* Undocumented commands for internal testing. Subject to change
3889 ** without notice. */
3890 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3891 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3892 int i, v;
3893 for(i=1; i<nArg; i++){
3894 v = booleanValue(azArg[i]);
3895 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3896 }
3897 }
3898 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3899 int i; sqlite3_int64 v;
3900 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003901 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003902 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003903 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003904 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003905 }
3906 }
3907 }else
drh340f5822013-06-27 13:01:21 +00003908#endif
drh348d19c2013-06-03 12:47:43 +00003909
drhc2ce0be2014-05-29 12:36:14 +00003910 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003911 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003912 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003913 rc = 1;
3914 }
drh6976c212014-07-24 12:09:47 +00003915 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003916 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003917 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003918 }
3919 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003920 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3921 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00003922 }
drh75897232000-05-29 14:26:00 +00003923 }else
3924
drh62cdde52014-05-28 20:22:28 +00003925 if( c=='s'
3926 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003927 ){
3928 char *zCmd;
drh54027102014-08-06 14:36:53 +00003929 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003930 if( nArg<2 ){
3931 fprintf(stderr, "Usage: .system COMMAND\n");
3932 rc = 1;
3933 goto meta_command_exit;
3934 }
drhdcb3e3d2014-05-29 03:17:29 +00003935 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003936 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003937 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3938 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003939 }
drh54027102014-08-06 14:36:53 +00003940 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003941 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003942 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003943 }else
3944
drhc2ce0be2014-05-29 12:36:14 +00003945 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003946 int i;
drhc2ce0be2014-05-29 12:36:14 +00003947 if( nArg!=1 ){
3948 fprintf(stderr, "Usage: .show\n");
3949 rc = 1;
3950 goto meta_command_exit;
3951 }
mistachkin636bf9f2014-07-19 20:15:16 +00003952 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3953 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003954 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003955 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3956 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3957 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003958 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003959 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003960 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003961 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003962 fprintf(p->out,"%12.12s: ", "colseparator");
3963 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003964 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003965 fprintf(p->out,"%12.12s: ", "rowseparator");
3966 output_c_string(p->out, p->rowSeparator);
3967 fprintf(p->out, "\n");
3968 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3969 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003970 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003971 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003972 }
drhfeac5f82004-08-01 00:10:45 +00003973 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003974 }else
3975
drhc2ce0be2014-05-29 12:36:14 +00003976 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3977 if( nArg==2 ){
3978 p->statsOn = booleanValue(azArg[1]);
3979 }else{
3980 fprintf(stderr, "Usage: .stats on|off\n");
3981 rc = 1;
3982 }
shaneh642d8b82010-07-28 16:05:34 +00003983 }else
3984
drhc2ce0be2014-05-29 12:36:14 +00003985 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003986 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003987 char **azResult;
drh98781232012-04-23 12:38:05 +00003988 int nRow, nAlloc;
3989 char *zSql = 0;
3990 int ii;
drh05782482013-10-24 15:20:20 +00003991 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003992 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3993 if( rc ) return rc;
3994 zSql = sqlite3_mprintf(
3995 "SELECT name FROM sqlite_master"
3996 " WHERE type IN ('table','view')"
3997 " AND name NOT LIKE 'sqlite_%%'"
3998 " AND name LIKE ?1");
3999 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4000 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
4001 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
4002 if( strcmp(zDbName,"temp")==0 ){
4003 zSql = sqlite3_mprintf(
4004 "%z UNION ALL "
4005 "SELECT 'temp.' || name FROM sqlite_temp_master"
4006 " WHERE type IN ('table','view')"
4007 " AND name NOT LIKE 'sqlite_%%'"
4008 " AND name LIKE ?1", zSql);
4009 }else{
4010 zSql = sqlite3_mprintf(
4011 "%z UNION ALL "
4012 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4013 " WHERE type IN ('table','view')"
4014 " AND name NOT LIKE 'sqlite_%%'"
4015 " AND name LIKE ?1", zSql, zDbName, zDbName);
4016 }
drha50da102000-08-08 20:19:09 +00004017 }
drh98781232012-04-23 12:38:05 +00004018 sqlite3_finalize(pStmt);
4019 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
4020 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4021 sqlite3_free(zSql);
4022 if( rc ) return rc;
4023 nRow = nAlloc = 0;
4024 azResult = 0;
4025 if( nArg>1 ){
4026 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00004027 }else{
drh98781232012-04-23 12:38:05 +00004028 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
4029 }
4030 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4031 if( nRow>=nAlloc ){
4032 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00004033 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00004034 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00004035 if( azNew==0 ){
4036 fprintf(stderr, "Error: out of memory\n");
4037 break;
4038 }
mistachkin8e189222015-04-19 21:43:16 +00004039 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00004040 azResult = azNew;
4041 }
4042 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
4043 if( azResult[nRow] ) nRow++;
4044 }
4045 sqlite3_finalize(pStmt);
4046 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00004047 int len, maxlen = 0;
4048 int i, j;
4049 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00004050 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00004051 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00004052 if( len>maxlen ) maxlen = len;
4053 }
4054 nPrintCol = 80/(maxlen+2);
4055 if( nPrintCol<1 ) nPrintCol = 1;
4056 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
4057 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00004058 for(j=i; j<nRow; j+=nPrintRow){
4059 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00004060 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00004061 }
drh151b7d52013-05-06 20:28:54 +00004062 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00004063 }
4064 }
drh98781232012-04-23 12:38:05 +00004065 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
4066 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00004067 }else
4068
shaneh96887e12011-02-10 21:08:58 +00004069 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00004070 static const struct {
4071 const char *zCtrlName; /* Name of a test-control option */
4072 int ctrlCode; /* Integer code for that option */
4073 } aCtrl[] = {
4074 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
4075 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
4076 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
4077 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
4078 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
4079 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
4080 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
4081 { "assert", SQLITE_TESTCTRL_ASSERT },
4082 { "always", SQLITE_TESTCTRL_ALWAYS },
4083 { "reserve", SQLITE_TESTCTRL_RESERVE },
4084 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
4085 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00004086 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00004087 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00004088 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00004089 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00004090 };
shaneh96887e12011-02-10 21:08:58 +00004091 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00004092 int rc2 = 0;
4093 int i, n2;
drh05782482013-10-24 15:20:20 +00004094 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00004095
drhd416fe72011-03-17 16:45:50 +00004096 /* convert testctrl text option to value. allow any unique prefix
4097 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00004098 n2 = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00004099 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
mistachkin8e189222015-04-19 21:43:16 +00004100 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00004101 if( testctrl<0 ){
4102 testctrl = aCtrl[i].ctrlCode;
4103 }else{
drhb07028f2011-10-14 21:49:18 +00004104 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00004105 testctrl = -1;
4106 break;
4107 }
4108 }
4109 }
drh348d19c2013-06-03 12:47:43 +00004110 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004111 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
4112 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
4113 }else{
4114 switch(testctrl){
4115
4116 /* sqlite3_test_control(int, db, int) */
4117 case SQLITE_TESTCTRL_OPTIMIZATIONS:
4118 case SQLITE_TESTCTRL_RESERVE:
4119 if( nArg==3 ){
4120 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00004121 rc2 = sqlite3_test_control(testctrl, p->db, opt);
4122 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004123 } else {
drhd416fe72011-03-17 16:45:50 +00004124 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
4125 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004126 }
4127 break;
4128
4129 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004130 case SQLITE_TESTCTRL_PRNG_SAVE:
4131 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004132 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004133 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004134 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00004135 rc2 = sqlite3_test_control(testctrl);
4136 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004137 } else {
4138 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
4139 }
4140 break;
4141
4142 /* sqlite3_test_control(int, uint) */
4143 case SQLITE_TESTCTRL_PENDING_BYTE:
4144 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004145 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004146 rc2 = sqlite3_test_control(testctrl, opt);
4147 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004148 } else {
drhd416fe72011-03-17 16:45:50 +00004149 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
4150 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004151 }
4152 break;
4153
4154 /* sqlite3_test_control(int, int) */
4155 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00004156 case SQLITE_TESTCTRL_ALWAYS:
4157 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004158 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00004159 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004160 rc2 = sqlite3_test_control(testctrl, opt);
4161 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004162 } else {
drhd416fe72011-03-17 16:45:50 +00004163 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
4164 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004165 }
4166 break;
4167
4168 /* sqlite3_test_control(int, char *) */
4169#ifdef SQLITE_N_KEYWORD
4170 case SQLITE_TESTCTRL_ISKEYWORD:
4171 if( nArg==3 ){
4172 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004173 rc2 = sqlite3_test_control(testctrl, opt);
4174 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004175 } else {
drhd416fe72011-03-17 16:45:50 +00004176 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
4177 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004178 }
4179 break;
4180#endif
4181
drh1ffede82015-01-30 20:59:27 +00004182 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004183 if( nArg==5 ){
mistachkin8e189222015-04-19 21:43:16 +00004184 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004185 azArg[2],
drh8964b342015-01-29 17:54:52 +00004186 integerValue(azArg[3]),
4187 integerValue(azArg[4]));
mistachkin8e189222015-04-19 21:43:16 +00004188 fprintf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004189 }else{
drh6f5a37a2015-03-27 02:27:20 +00004190 fprintf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004191 }
4192 break;
4193
shaneh96887e12011-02-10 21:08:58 +00004194 case SQLITE_TESTCTRL_BITVEC_TEST:
4195 case SQLITE_TESTCTRL_FAULT_INSTALL:
4196 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4197 case SQLITE_TESTCTRL_SCRATCHMALLOC:
4198 default:
drhd416fe72011-03-17 16:45:50 +00004199 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
4200 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004201 break;
4202 }
4203 }
4204 }else
4205
drhc2ce0be2014-05-29 12:36:14 +00004206 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004207 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004208 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004209 }else
4210
drhc2ce0be2014-05-29 12:36:14 +00004211 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4212 if( nArg==2 ){
4213 enableTimer = booleanValue(azArg[1]);
4214 if( enableTimer && !HAS_TIMER ){
4215 fprintf(stderr, "Error: timer not available on this system.\n");
4216 enableTimer = 0;
4217 }
4218 }else{
4219 fprintf(stderr, "Usage: .timer on|off\n");
4220 rc = 1;
4221 }
shanehe2aa9d72009-11-06 17:20:17 +00004222 }else
4223
drhc2ce0be2014-05-29 12:36:14 +00004224 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004225 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004226 if( nArg!=2 ){
4227 fprintf(stderr, "Usage: .trace FILE|off\n");
4228 rc = 1;
4229 goto meta_command_exit;
4230 }
drh657b4a82015-03-19 13:30:41 +00004231 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004232 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004233#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004234 if( p->traceOut==0 ){
4235 sqlite3_trace(p->db, 0, 0);
4236 }else{
4237 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
4238 }
4239#endif
4240 }else
4241
drhf442e332014-09-10 19:01:14 +00004242#if SQLITE_USER_AUTHENTICATION
4243 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4244 if( nArg<2 ){
4245 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
4246 rc = 1;
4247 goto meta_command_exit;
4248 }
drh7883ecf2014-09-11 16:19:31 +00004249 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004250 if( strcmp(azArg[1],"login")==0 ){
4251 if( nArg!=4 ){
4252 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
4253 rc = 1;
4254 goto meta_command_exit;
4255 }
drhd39c40f2014-09-11 00:27:53 +00004256 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4257 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004258 if( rc ){
4259 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
4260 rc = 1;
4261 }
4262 }else if( strcmp(azArg[1],"add")==0 ){
4263 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00004264 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004265 rc = 1;
4266 goto meta_command_exit;
4267 }
drhd39c40f2014-09-11 00:27:53 +00004268 rc = sqlite3_user_add(p->db, azArg[2],
4269 azArg[3], (int)strlen(azArg[3]),
4270 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004271 if( rc ){
4272 fprintf(stderr, "User-Add failed: %d\n", rc);
4273 rc = 1;
4274 }
4275 }else if( strcmp(azArg[1],"edit")==0 ){
4276 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00004277 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004278 rc = 1;
4279 goto meta_command_exit;
4280 }
drhd39c40f2014-09-11 00:27:53 +00004281 rc = sqlite3_user_change(p->db, azArg[2],
4282 azArg[3], (int)strlen(azArg[3]),
4283 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004284 if( rc ){
4285 fprintf(stderr, "User-Edit failed: %d\n", rc);
4286 rc = 1;
4287 }
4288 }else if( strcmp(azArg[1],"delete")==0 ){
4289 if( nArg!=3 ){
4290 fprintf(stderr, "Usage: .user delete USER\n");
4291 rc = 1;
4292 goto meta_command_exit;
4293 }
4294 rc = sqlite3_user_delete(p->db, azArg[2]);
4295 if( rc ){
4296 fprintf(stderr, "User-Delete failed: %d\n", rc);
4297 rc = 1;
4298 }
4299 }else{
4300 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
4301 rc = 1;
4302 goto meta_command_exit;
4303 }
4304 }else
4305#endif /* SQLITE_USER_AUTHENTICATION */
4306
drh9fd301b2011-06-03 13:28:22 +00004307 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00004308 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004309 sqlite3_libversion(), sqlite3_sourceid());
4310 }else
4311
drhde60fc22011-12-14 17:53:36 +00004312 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4313 const char *zDbName = nArg==2 ? azArg[1] : "main";
4314 char *zVfsName = 0;
4315 if( p->db ){
4316 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4317 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00004318 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004319 sqlite3_free(zVfsName);
4320 }
4321 }
4322 }else
4323
drhcef4fc82012-09-21 22:50:45 +00004324#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4325 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
4326 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00004327 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004328 }else
4329#endif
4330
drhc2ce0be2014-05-29 12:36:14 +00004331 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004332 int j;
drh43617e92006-03-06 20:55:46 +00004333 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004334 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004335 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004336 }
4337 }else
4338
4339 {
shane9bd1b442009-10-23 01:27:39 +00004340 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004341 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004342 rc = 1;
drh75897232000-05-29 14:26:00 +00004343 }
drh67505e72002-04-19 12:34:06 +00004344
drhc2ce0be2014-05-29 12:36:14 +00004345meta_command_exit:
4346 if( p->outCount ){
4347 p->outCount--;
4348 if( p->outCount==0 ) output_reset(p);
4349 }
drh67505e72002-04-19 12:34:06 +00004350 return rc;
drh75897232000-05-29 14:26:00 +00004351}
4352
drh67505e72002-04-19 12:34:06 +00004353/*
drh91a66392007-09-07 01:12:32 +00004354** Return TRUE if a semicolon occurs anywhere in the first N characters
4355** of string z[].
drh324ccef2003-02-05 14:06:20 +00004356*/
drh9f099fd2013-08-06 14:01:46 +00004357static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004358 int i;
4359 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4360 return 0;
drh324ccef2003-02-05 14:06:20 +00004361}
4362
4363/*
drh70c7a4b2003-04-26 03:03:06 +00004364** Test to see if a line consists entirely of whitespace.
4365*/
4366static int _all_whitespace(const char *z){
4367 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004368 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004369 if( *z=='/' && z[1]=='*' ){
4370 z += 2;
4371 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4372 if( *z==0 ) return 0;
4373 z++;
4374 continue;
4375 }
4376 if( *z=='-' && z[1]=='-' ){
4377 z += 2;
4378 while( *z && *z!='\n' ){ z++; }
4379 if( *z==0 ) return 1;
4380 continue;
4381 }
4382 return 0;
4383 }
4384 return 1;
4385}
4386
4387/*
drha9b17162003-04-29 18:01:28 +00004388** Return TRUE if the line typed in is an SQL command terminator other
4389** than a semi-colon. The SQL Server style "go" command is understood
4390** as is the Oracle "/".
4391*/
drh9f099fd2013-08-06 14:01:46 +00004392static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004393 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004394 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4395 return 1; /* Oracle */
4396 }
drhf0693c82011-10-11 20:41:54 +00004397 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004398 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004399 return 1; /* SQL Server */
4400 }
4401 return 0;
4402}
4403
4404/*
drh233a5312008-12-18 22:25:13 +00004405** Return true if zSql is a complete SQL statement. Return false if it
4406** ends in the middle of a string literal or C-style comment.
4407*/
drh9f099fd2013-08-06 14:01:46 +00004408static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004409 int rc;
4410 if( zSql==0 ) return 1;
4411 zSql[nSql] = ';';
4412 zSql[nSql+1] = 0;
4413 rc = sqlite3_complete(zSql);
4414 zSql[nSql] = 0;
4415 return rc;
4416}
4417
4418/*
drh67505e72002-04-19 12:34:06 +00004419** Read input from *in and process it. If *in==0 then input
4420** is interactive - the user is typing it it. Otherwise, input
4421** is coming from a file or device. A prompt is issued and history
4422** is saved only if input is interactive. An interrupt signal will
4423** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004424**
4425** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004426*/
drhdcd87a92014-08-18 13:45:42 +00004427static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004428 char *zLine = 0; /* A single input line */
4429 char *zSql = 0; /* Accumulated SQL text */
4430 int nLine; /* Length of current line */
4431 int nSql = 0; /* Bytes of zSql[] used */
4432 int nAlloc = 0; /* Allocated zSql[] space */
4433 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4434 char *zErrMsg; /* Error message returned */
4435 int rc; /* Error code */
4436 int errCnt = 0; /* Number of errors seen */
4437 int lineno = 0; /* Current line number */
4438 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004439
4440 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4441 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004442 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004443 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004444 /* End of input */
4445 if( stdin_is_interactive ) printf("\n");
4446 break;
drhc49f44e2006-10-26 18:15:42 +00004447 }
drh67505e72002-04-19 12:34:06 +00004448 if( seenInterrupt ){
4449 if( in!=0 ) break;
4450 seenInterrupt = 0;
4451 }
drhc28490c2006-10-26 14:25:58 +00004452 lineno++;
drh849a9d92013-12-21 15:46:06 +00004453 if( nSql==0 && _all_whitespace(zLine) ){
4454 if( p->echoOn ) printf("%s\n", zLine);
4455 continue;
4456 }
drh2af0b2d2002-02-21 02:25:02 +00004457 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004458 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004459 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004460 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004461 break;
4462 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004463 errCnt++;
4464 }
drhdaffd0e2001-04-11 14:28:42 +00004465 continue;
4466 }
drh9f099fd2013-08-06 14:01:46 +00004467 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004468 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004469 }
drh9f099fd2013-08-06 14:01:46 +00004470 nLine = strlen30(zLine);
4471 if( nSql+nLine+2>=nAlloc ){
4472 nAlloc = nSql+nLine+100;
4473 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004474 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004475 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004476 exit(1);
4477 }
drhdaffd0e2001-04-11 14:28:42 +00004478 }
drh9f099fd2013-08-06 14:01:46 +00004479 nSqlPrior = nSql;
4480 if( nSql==0 ){
4481 int i;
4482 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004483 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004484 memcpy(zSql, zLine+i, nLine+1-i);
4485 startline = lineno;
4486 nSql = nLine-i;
4487 }else{
4488 zSql[nSql++] = '\n';
4489 memcpy(zSql+nSql, zLine, nLine+1);
4490 nSql += nLine;
4491 }
4492 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004493 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004494 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004495 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004496 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004497 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004498 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004499 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004500 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004501 char zPrefix[100];
4502 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004503 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004504 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004505 }else{
shane9bd1b442009-10-23 01:27:39 +00004506 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004507 }
drh7f953e22002-07-13 17:33:45 +00004508 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004509 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004510 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004511 zErrMsg = 0;
4512 }else{
shaned2bed1c2009-10-21 03:56:54 +00004513 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004514 }
drhc49f44e2006-10-26 18:15:42 +00004515 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00004516 }
drhdaffd0e2001-04-11 14:28:42 +00004517 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004518 if( p->outCount ){
4519 output_reset(p);
4520 p->outCount = 0;
4521 }
drh9f099fd2013-08-06 14:01:46 +00004522 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004523 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004524 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004525 }
4526 }
drh9f099fd2013-08-06 14:01:46 +00004527 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004528 if( !_all_whitespace(zSql) ){
4529 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004530 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004531 }
drhdaffd0e2001-04-11 14:28:42 +00004532 free(zSql);
4533 }
danielk19772ac27622007-07-03 05:31:16 +00004534 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004535 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004536}
4537
drh67505e72002-04-19 12:34:06 +00004538/*
4539** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004540** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004541*/
4542static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004543 static char *home_dir = NULL;
4544 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004545
drh4ace5362014-11-10 14:42:28 +00004546#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4547 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004548 {
4549 struct passwd *pwent;
4550 uid_t uid = getuid();
4551 if( (pwent=getpwuid(uid)) != NULL) {
4552 home_dir = pwent->pw_dir;
4553 }
drh67505e72002-04-19 12:34:06 +00004554 }
4555#endif
4556
chw65d3c132007-11-12 21:09:10 +00004557#if defined(_WIN32_WCE)
4558 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4559 */
drh85e72432012-04-11 11:38:53 +00004560 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004561#else
4562
drh83905c92012-06-21 13:00:37 +00004563#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004564 if (!home_dir) {
4565 home_dir = getenv("USERPROFILE");
4566 }
4567#endif
4568
drh67505e72002-04-19 12:34:06 +00004569 if (!home_dir) {
4570 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004571 }
4572
drh83905c92012-06-21 13:00:37 +00004573#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004574 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004575 char *zDrive, *zPath;
4576 int n;
4577 zDrive = getenv("HOMEDRIVE");
4578 zPath = getenv("HOMEPATH");
4579 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004580 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004581 home_dir = malloc( n );
4582 if( home_dir==0 ) return 0;
4583 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4584 return home_dir;
4585 }
4586 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004587 }
4588#endif
4589
chw65d3c132007-11-12 21:09:10 +00004590#endif /* !_WIN32_WCE */
4591
drh67505e72002-04-19 12:34:06 +00004592 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004593 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004594 char *z = malloc( n );
4595 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004596 home_dir = z;
4597 }
drhe98d4fa2002-04-21 19:06:22 +00004598
drh67505e72002-04-19 12:34:06 +00004599 return home_dir;
4600}
4601
4602/*
4603** Read input from the file given by sqliterc_override. Or if that
4604** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004605**
4606** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004607*/
drh534f4df2015-02-28 14:03:35 +00004608static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004609 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004610 const char *sqliterc_override /* Name of config file. NULL to use default */
4611){
persicom7e2dfdd2002-04-18 02:46:52 +00004612 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004613 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004614 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004615 FILE *in = NULL;
4616
4617 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004618 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004619 if( home_dir==0 ){
drh534f4df2015-02-28 14:03:35 +00004620 fprintf(stderr, "-- warning: cannot find home directory;"
4621 " cannot read ~/.sqliterc\n");
4622 return;
drhe98d4fa2002-04-21 19:06:22 +00004623 }
drh2f3de322012-06-27 16:41:31 +00004624 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004625 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4626 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004627 }
drha1f9b5e2004-02-14 16:31:02 +00004628 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004629 if( in ){
drhc28490c2006-10-26 14:25:58 +00004630 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004631 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004632 }
drh534f4df2015-02-28 14:03:35 +00004633 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004634 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004635 }
drh85e72432012-04-11 11:38:53 +00004636 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004637}
4638
drh67505e72002-04-19 12:34:06 +00004639/*
drhe1e38c42003-05-04 18:30:59 +00004640** Show available command line options
4641*/
4642static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004643 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004644 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004645 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004646 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004647 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004648 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004649 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004650 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004651 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004652#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4653 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4654#endif
drhcc3b4f82012-02-07 14:13:50 +00004655 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004656 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004657 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004658 " -line set output mode to 'line'\n"
4659 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004660 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004661 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004662#ifdef SQLITE_ENABLE_MULTIPLEX
4663 " -multiplex enable the multiplexor VFS\n"
4664#endif
mistachkine0d68852014-12-11 03:12:33 +00004665 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004666 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004667 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4668 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004669 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004670 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004671 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004672 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004673#ifdef SQLITE_ENABLE_VFSTRACE
4674 " -vfstrace enable tracing of all VFS calls\n"
4675#endif
drhe1e38c42003-05-04 18:30:59 +00004676;
4677static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004678 fprintf(stderr,
4679 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4680 "FILENAME is the name of an SQLite database. A new database is created\n"
4681 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004682 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004683 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004684 }else{
4685 fprintf(stderr, "Use the -help option for additional information\n");
4686 }
4687 exit(1);
4688}
4689
4690/*
drh67505e72002-04-19 12:34:06 +00004691** Initialize the state information in data
4692*/
drhdcd87a92014-08-18 13:45:42 +00004693static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004694 memset(data, 0, sizeof(*data));
4695 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004696 memcpy(data->colSeparator,SEP_Column, 2);
4697 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004698 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004699 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004700 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004701 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004702 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004703 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4704 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004705}
4706
drh98d312f2012-10-25 15:23:14 +00004707/*
drh5c7976f2014-02-10 19:59:27 +00004708** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004709*/
4710#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004711static void printBold(const char *zText){
4712 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4713 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4714 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4715 SetConsoleTextAttribute(out,
4716 FOREGROUND_RED|FOREGROUND_INTENSITY
4717 );
4718 printf("%s", zText);
4719 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004720}
4721#else
drh5c7976f2014-02-10 19:59:27 +00004722static void printBold(const char *zText){
4723 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004724}
4725#endif
4726
4727/*
drh98d312f2012-10-25 15:23:14 +00004728** Get the argument to an --option. Throw an error and die if no argument
4729** is available.
4730*/
4731static char *cmdline_option_value(int argc, char **argv, int i){
4732 if( i==argc ){
4733 fprintf(stderr, "%s: Error: missing argument to %s\n",
4734 argv[0], argv[argc-1]);
4735 exit(1);
4736 }
4737 return argv[i];
4738}
4739
mistachkin44723ce2015-03-21 02:22:37 +00004740int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004741 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004742 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004743 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004744 int i;
drhc28490c2006-10-26 14:25:58 +00004745 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004746 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004747 int readStdin = 1;
4748 int nCmd = 0;
4749 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004750
drh69b30ab2014-02-27 15:11:52 +00004751#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004752 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4753 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4754 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4755 exit(1);
4756 }
drhc7181902014-02-27 15:04:13 +00004757#endif
drh047d4532015-01-18 20:30:23 +00004758 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004759 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004760 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004761 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004762 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004763
drh44c2eb12003-04-30 11:38:26 +00004764 /* Make sure we have a valid signal handler early, before anything
4765 ** else is done.
4766 */
drh4c504392000-10-16 22:06:40 +00004767#ifdef SIGINT
4768 signal(SIGINT, interrupt_handler);
4769#endif
drh44c2eb12003-04-30 11:38:26 +00004770
drhac5649a2014-11-28 13:35:03 +00004771#ifdef SQLITE_SHELL_DBNAME_PROC
4772 {
4773 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4774 ** of a C-function that will provide the name of the database file. Use
4775 ** this compile-time option to embed this shell program in larger
4776 ** applications. */
4777 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4778 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4779 warnInmemoryDb = 0;
4780 }
4781#endif
4782
drh22fbcb82004-02-01 01:22:50 +00004783 /* Do an initial pass through the command-line argument to locate
4784 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004785 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004786 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004787 */
drh98d312f2012-10-25 15:23:14 +00004788 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004789 char *z;
drhc28490c2006-10-26 14:25:58 +00004790 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004791 if( z[0]!='-' ){
4792 if( data.zDbFilename==0 ){
4793 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004794 }else{
4795 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4796 ** mean that nothing is read from stdin */
4797 readStdin = 0;
4798 nCmd++;
4799 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4800 if( azCmd==0 ){
4801 fprintf(stderr, "out of memory\n");
4802 exit(1);
4803 }
4804 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004805 }
drh98d312f2012-10-25 15:23:14 +00004806 }
drhcc3b4f82012-02-07 14:13:50 +00004807 if( z[1]=='-' ) z++;
4808 if( strcmp(z,"-separator")==0
4809 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004810 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004811 || strcmp(z,"-cmd")==0
4812 ){
drh98d312f2012-10-25 15:23:14 +00004813 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004814 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004815 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004816 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004817 /* Need to check for batch mode here to so we can avoid printing
4818 ** informational messages (like from process_sqliterc) before
4819 ** we do the actual processing of arguments later in a second pass.
4820 */
shanef69573d2009-10-24 02:06:14 +00004821 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004822 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004823#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004824 const char *zSize;
4825 sqlite3_int64 szHeap;
4826
drh98d312f2012-10-25 15:23:14 +00004827 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004828 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004829 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004830 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4831#endif
drh44dec872014-08-30 15:49:25 +00004832 }else if( strcmp(z,"-scratch")==0 ){
4833 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004834 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004835 if( sz>400000 ) sz = 400000;
4836 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004837 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004838 if( n>10 ) n = 10;
4839 if( n<1 ) n = 1;
4840 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4841 data.shellFlgs |= SHFLG_Scratch;
4842 }else if( strcmp(z,"-pagecache")==0 ){
4843 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004844 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004845 if( sz>70000 ) sz = 70000;
4846 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004847 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004848 if( n<10 ) n = 10;
4849 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4850 data.shellFlgs |= SHFLG_Pagecache;
4851 }else if( strcmp(z,"-lookaside")==0 ){
4852 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004853 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004854 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004855 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004856 if( n<0 ) n = 0;
4857 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4858 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004859#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004860 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004861 extern int vfstrace_register(
4862 const char *zTraceName,
4863 const char *zOldVfsName,
4864 int (*xOut)(const char*,void*),
4865 void *pOutArg,
4866 int makeDefault
4867 );
drh2b625e22011-03-16 17:05:28 +00004868 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004869#endif
drh6f25e892011-07-08 17:02:57 +00004870#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004871 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004872 extern int sqlite3_multiple_initialize(const char*,int);
4873 sqlite3_multiplex_initialize(0, 1);
4874#endif
drh7d9f3942013-04-03 01:26:54 +00004875 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004876 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4877 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004878 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004879 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004880 if( pVfs ){
4881 sqlite3_vfs_register(pVfs, 1);
4882 }else{
4883 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4884 exit(1);
4885 }
drh44c2eb12003-04-30 11:38:26 +00004886 }
4887 }
drh98d312f2012-10-25 15:23:14 +00004888 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004889#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004890 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004891 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004892#else
shane86f5bdb2009-10-24 02:00:07 +00004893 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4894 return 1;
drh01b41712005-08-29 23:06:23 +00004895#endif
drh98d312f2012-10-25 15:23:14 +00004896 }
4897 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004898
drh44c2eb12003-04-30 11:38:26 +00004899 /* Go ahead and open the database file if it already exists. If the
4900 ** file does not exist, delay opening it. This prevents empty database
4901 ** files from being created if a user mistypes the database name argument
4902 ** to the sqlite command-line tool.
4903 */
drhc8d74412004-08-31 23:41:26 +00004904 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004905 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004906 }
4907
drh22fbcb82004-02-01 01:22:50 +00004908 /* Process the initialization file if there is one. If no -init option
4909 ** is given on the command line, look for a file named ~/.sqliterc and
4910 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004911 */
drh534f4df2015-02-28 14:03:35 +00004912 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004913
drh22fbcb82004-02-01 01:22:50 +00004914 /* Make a second pass through the command-line argument and set
4915 ** options. This second pass is delayed until after the initialization
4916 ** file is processed so that the command-line arguments will override
4917 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004918 */
drh98d312f2012-10-25 15:23:14 +00004919 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004920 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004921 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004922 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004923 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004924 i++;
4925 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004926 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004927 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004928 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004929 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004930 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004931 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004932 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004933 }else if( strcmp(z,"-csv")==0 ){
4934 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004935 memcpy(data.colSeparator,",",2);
4936 }else if( strcmp(z,"-ascii")==0 ){
4937 data.mode = MODE_Ascii;
4938 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004939 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004940 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004941 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00004942 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004943 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00004944 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004945 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004946 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004947 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004948 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004949 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004950 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004951 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004952 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004953 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004954 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004955 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004956 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004957 }else if( strcmp(z,"-eqp")==0 ){
4958 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004959 }else if( strcmp(z,"-stats")==0 ){
4960 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004961 }else if( strcmp(z,"-scanstats")==0 ){
4962 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00004963 }else if( strcmp(z,"-backslash")==0 ){
4964 /* Undocumented command-line option: -backslash
4965 ** Causes C-style backslash escapes to be evaluated in SQL statements
4966 ** prior to sending the SQL into SQLite. Useful for injecting
4967 ** crazy bytes in the middle of SQL statements for testing and debugging.
4968 */
4969 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004970 }else if( strcmp(z,"-bail")==0 ){
4971 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004972 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004973 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004974 return 0;
drhc28490c2006-10-26 14:25:58 +00004975 }else if( strcmp(z,"-interactive")==0 ){
4976 stdin_is_interactive = 1;
4977 }else if( strcmp(z,"-batch")==0 ){
4978 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004979 }else if( strcmp(z,"-heap")==0 ){
4980 i++;
drh44dec872014-08-30 15:49:25 +00004981 }else if( strcmp(z,"-scratch")==0 ){
4982 i+=2;
4983 }else if( strcmp(z,"-pagecache")==0 ){
4984 i+=2;
4985 }else if( strcmp(z,"-lookaside")==0 ){
4986 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004987 }else if( strcmp(z,"-mmap")==0 ){
4988 i++;
drha7e61d82011-03-12 17:02:57 +00004989 }else if( strcmp(z,"-vfs")==0 ){
4990 i++;
drh6f25e892011-07-08 17:02:57 +00004991#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004992 }else if( strcmp(z,"-vfstrace")==0 ){
4993 i++;
drh6f25e892011-07-08 17:02:57 +00004994#endif
4995#ifdef SQLITE_ENABLE_MULTIPLEX
4996 }else if( strcmp(z,"-multiplex")==0 ){
4997 i++;
4998#endif
drhcc3b4f82012-02-07 14:13:50 +00004999 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00005000 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00005001 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00005002 /* Run commands that follow -cmd first and separately from commands
5003 ** that simply appear on the command-line. This seems goofy. It would
5004 ** be better if all commands ran in the order that they appear. But
5005 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00005006 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00005007 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00005008 if( z[0]=='.' ){
5009 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00005010 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00005011 }else{
drh05782482013-10-24 15:20:20 +00005012 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00005013 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
5014 if( zErrMsg!=0 ){
5015 fprintf(stderr,"Error: %s\n", zErrMsg);
5016 if( bail_on_error ) return rc!=0 ? rc : 1;
5017 }else if( rc!=0 ){
5018 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
5019 if( bail_on_error ) return rc;
5020 }
5021 }
drh1e5d0e92000-05-31 23:33:17 +00005022 }else{
shane86f5bdb2009-10-24 02:00:07 +00005023 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00005024 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00005025 return 1;
5026 }
5027 }
drh44c2eb12003-04-30 11:38:26 +00005028
drhac5649a2014-11-28 13:35:03 +00005029 if( !readStdin ){
5030 /* Run all arguments that do not begin with '-' as if they were separate
5031 ** command-line inputs, except for the argToSkip argument which contains
5032 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00005033 */
drhac5649a2014-11-28 13:35:03 +00005034 for(i=0; i<nCmd; i++){
5035 if( azCmd[i][0]=='.' ){
5036 rc = do_meta_command(azCmd[i], &data);
5037 if( rc ) return rc==2 ? 0 : rc;
5038 }else{
5039 open_db(&data, 0);
5040 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
5041 if( zErrMsg!=0 ){
5042 fprintf(stderr,"Error: %s\n", zErrMsg);
5043 return rc!=0 ? rc : 1;
5044 }else if( rc!=0 ){
5045 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
5046 return rc;
5047 }
drh6ff13852001-11-25 13:18:23 +00005048 }
drh75897232000-05-29 14:26:00 +00005049 }
drhac5649a2014-11-28 13:35:03 +00005050 free(azCmd);
drh75897232000-05-29 14:26:00 +00005051 }else{
drh44c2eb12003-04-30 11:38:26 +00005052 /* Run commands received from standard input
5053 */
drhc28490c2006-10-26 14:25:58 +00005054 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00005055 char *zHome;
5056 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00005057 int nHistory;
drh75897232000-05-29 14:26:00 +00005058 printf(
drh743e0032011-12-12 16:51:50 +00005059 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00005060 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00005061 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00005062 );
drhb3735912014-02-10 16:13:42 +00005063 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00005064 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00005065 printBold("transient in-memory database");
5066 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00005067 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00005068 }
drh67505e72002-04-19 12:34:06 +00005069 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00005070 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00005071 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00005072 if( (zHistory = malloc(nHistory))!=0 ){
5073 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
5074 }
drh67505e72002-04-19 12:34:06 +00005075 }
danfd34d6d2015-02-25 10:54:53 +00005076 if( zHistory ) shell_read_history(zHistory);
drhc28490c2006-10-26 14:25:58 +00005077 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00005078 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00005079 shell_stifle_history(100);
5080 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00005081 free(zHistory);
drh67505e72002-04-19 12:34:06 +00005082 }
drhdaffd0e2001-04-11 14:28:42 +00005083 }else{
drhc28490c2006-10-26 14:25:58 +00005084 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00005085 }
5086 }
drh33048c02001-10-01 14:29:22 +00005087 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00005088 if( data.db ){
drhe6229612014-08-18 15:08:26 +00005089 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00005090 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00005091 }
drh05782482013-10-24 15:20:20 +00005092 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00005093 return rc;
drh75897232000-05-29 14:26:00 +00005094}