blob: b1672f633a038a00b0b467515794188a3436952a [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
mistachkin2318d332015-01-12 18:02:52 +000021** If requested, include the SQLite compiler options file for MSVC.
22*/
23#if defined(INCLUDE_MSVC_H)
24#include "msvc.h"
25#endif
26
27/*
drh8cd5b252015-03-02 22:06:43 +000028** No support for loadable extensions in VxWorks.
29*/
drhada3f2b2015-03-23 21:32:50 +000030#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
drh8cd5b252015-03-02 22:06:43 +000031# define SQLITE_OMIT_LOAD_EXTENSION 1
32#endif
33
34/*
drh36f7dd32011-10-13 16:02:17 +000035** Enable large-file support for fopen() and friends on unix.
36*/
37#ifndef SQLITE_DISABLE_LFS
38# define _LARGE_FILE 1
39# ifndef _FILE_OFFSET_BITS
40# define _FILE_OFFSET_BITS 64
41# endif
42# define _LARGEFILE_SOURCE 1
43#endif
44
drh75897232000-05-29 14:26:00 +000045#include <stdlib.h>
46#include <string.h>
47#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000048#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000049#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000050#if SQLITE_USER_AUTHENTICATION
51# include "sqlite3userauth.h"
52#endif
drh75897232000-05-29 14:26:00 +000053#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000054#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000055
drh83905c92012-06-21 13:00:37 +000056#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000057# include <signal.h>
chw97185482008-11-17 08:05:31 +000058# if !defined(__RTP__) && !defined(_WRS_KERNEL)
59# include <pwd.h>
60# endif
drhdd45df82002-04-18 12:39:03 +000061# include <unistd.h>
62# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000063#endif
drh75897232000-05-29 14:26:00 +000064
drh0ede9eb2015-01-10 16:49:23 +000065#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000066# include <readline/readline.h>
67# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000068#endif
danfd34d6d2015-02-25 10:54:53 +000069
drh0ede9eb2015-01-10 16:49:23 +000070#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000071# include <editline/readline.h>
72#endif
danfd34d6d2015-02-25 10:54:53 +000073
74#if HAVE_EDITLINE || HAVE_READLINE
75
76# define shell_add_history(X) add_history(X)
77# define shell_read_history(X) read_history(X)
78# define shell_write_history(X) write_history(X)
79# define shell_stifle_history(X) stifle_history(X)
80# define shell_readline(X) readline(X)
81
82#elif HAVE_LINENOISE
83
84# include "linenoise.h"
85# define shell_add_history(X) linenoiseHistoryAdd(X)
86# define shell_read_history(X) linenoiseHistoryLoad(X)
87# define shell_write_history(X) linenoiseHistorySave(X)
88# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
89# define shell_readline(X) linenoise(X)
90
91#else
92
93# define shell_read_history(X)
94# define shell_write_history(X)
95# define shell_stifle_history(X)
96
97# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000098#endif
99
danfd34d6d2015-02-25 10:54:53 +0000100
adamd2e8464a2006-09-06 21:39:40 +0000101#if defined(_WIN32) || defined(WIN32)
102# include <io.h>
drh6976c212014-07-24 12:09:47 +0000103# include <fcntl.h>
mistachkin073664d2015-06-17 18:57:37 +0000104# define isatty(h) _isatty(h)
105# ifndef access
106# define access(f,m) _access((f),(m))
107# endif
108# undef popen
109# define popen _popen
110# undef pclose
111# define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
mistachkin073664d2015-06-17 18:57:37 +0000113 /* Make sure isatty() has a prototype. */
114 extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000115
mistachkin073664d2015-06-17 18:57:37 +0000116# if !defined(__RTP__) && !defined(_WRS_KERNEL)
117 /* popen and pclose are not C89 functions and so are
118 ** sometimes omitted from the <stdio.h> header */
119 extern FILE *popen(const char*,const char*);
120 extern int pclose(FILE*);
121# else
122# define SQLITE_OMIT_POPEN 1
123# endif
mistachkinf6418892013-08-28 01:54:12 +0000124#endif
drh53371f92013-07-25 17:07:03 +0000125
chw65d3c132007-11-12 21:09:10 +0000126#if defined(_WIN32_WCE)
127/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
128 * thus we always assume that we have a console. That can be
129 * overridden with the -batch command line option.
130 */
131#define isatty(x) 1
132#endif
133
drhf0693c82011-10-11 20:41:54 +0000134/* ctype macros that work with signed characters */
135#define IsSpace(X) isspace((unsigned char)X)
136#define IsDigit(X) isdigit((unsigned char)X)
137#define ToLower(X) (char)tolower((unsigned char)X)
138
drh047d4532015-01-18 20:30:23 +0000139/* On Windows, we normally run with output mode of TEXT so that \n characters
140** are automatically translated into \r\n. However, this behavior needs
141** to be disabled in some cases (ex: when generating CSV output and when
142** rendering quoted strings that contain \n characters). The following
143** routines take care of that.
144*/
145#if defined(_WIN32) || defined(WIN32)
mistachkine4a0d792015-01-27 21:24:33 +0000146static void setBinaryMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000147 fflush(out);
148 _setmode(_fileno(out), _O_BINARY);
149}
mistachkine4a0d792015-01-27 21:24:33 +0000150static void setTextMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000151 fflush(out);
152 _setmode(_fileno(out), _O_TEXT);
153}
154#else
155# define setBinaryMode(X)
156# define setTextMode(X)
157#endif
158
drh43408312013-10-30 12:43:36 +0000159
160/* True if the timer is enabled */
161static int enableTimer = 0;
162
163/* Return the current wall-clock time */
164static sqlite3_int64 timeOfDay(void){
165 static sqlite3_vfs *clockVfs = 0;
166 sqlite3_int64 t;
167 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
dan3fd415b2015-11-16 08:54:10 +0000168 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drh43408312013-10-30 12:43:36 +0000169 clockVfs->xCurrentTimeInt64(clockVfs, &t);
170 }else{
171 double r;
172 clockVfs->xCurrentTime(clockVfs, &r);
173 t = (sqlite3_int64)(r*86400000.0);
174 }
175 return t;
176}
177
drh91eb93c2015-03-03 19:56:20 +0000178#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000179#include <sys/time.h>
180#include <sys/resource.h>
181
drh91eb93c2015-03-03 19:56:20 +0000182/* VxWorks does not support getrusage() as far as we can determine */
183#if defined(_WRS_KERNEL) || defined(__RTP__)
184struct rusage {
185 struct timeval ru_utime; /* user CPU time used */
186 struct timeval ru_stime; /* system CPU time used */
187};
188#define getrusage(A,B) memset(B,0,sizeof(*B))
189#endif
190
drhda108222009-02-25 19:07:24 +0000191/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000192static struct rusage sBegin; /* CPU time at start */
193static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000194
drhda108222009-02-25 19:07:24 +0000195/*
196** Begin timing an operation
197*/
198static void beginTimer(void){
199 if( enableTimer ){
200 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000201 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000202 }
203}
204
205/* Return the difference of two time_structs in seconds */
206static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
207 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
208 (double)(pEnd->tv_sec - pStart->tv_sec);
209}
210
211/*
212** Print the timing results.
213*/
214static void endTimer(void){
215 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000216 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000217 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000218 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000219 printf("Run Time: real %.3f user %f sys %f\n",
220 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000221 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
222 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
223 }
224}
shaneb320ccd2009-10-21 03:42:58 +0000225
drhda108222009-02-25 19:07:24 +0000226#define BEGIN_TIMER beginTimer()
227#define END_TIMER endTimer()
228#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000229
230#elif (defined(_WIN32) || defined(WIN32))
231
232#include <windows.h>
233
234/* Saved resource information for the beginning of an operation */
235static HANDLE hProcess;
236static FILETIME ftKernelBegin;
237static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000238static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000239typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
240 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000241static GETPROCTIMES getProcessTimesAddr = NULL;
242
shaneb320ccd2009-10-21 03:42:58 +0000243/*
244** Check to see if we have timer support. Return 1 if necessary
245** support found (or found previously).
246*/
247static int hasTimer(void){
248 if( getProcessTimesAddr ){
249 return 1;
250 } else {
drh4ace5362014-11-10 14:42:28 +0000251 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
252 ** versions. See if the version we are running on has it, and if it
253 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000254 */
255 hProcess = GetCurrentProcess();
256 if( hProcess ){
257 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
258 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000259 getProcessTimesAddr =
260 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000261 if( NULL != getProcessTimesAddr ){
262 return 1;
263 }
264 FreeLibrary(hinstLib);
265 }
266 }
267 }
268 return 0;
269}
270
271/*
272** Begin timing an operation
273*/
274static void beginTimer(void){
275 if( enableTimer && getProcessTimesAddr ){
276 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000277 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
278 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000279 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000280 }
281}
282
283/* Return the difference of two FILETIME structs in seconds */
284static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
285 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
286 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
287 return (double) ((i64End - i64Start) / 10000000.0);
288}
289
290/*
291** Print the timing results.
292*/
293static void endTimer(void){
294 if( enableTimer && getProcessTimesAddr){
295 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000296 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000297 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000298 printf("Run Time: real %.3f user %f sys %f\n",
299 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000300 timeDiff(&ftUserBegin, &ftUserEnd),
301 timeDiff(&ftKernelBegin, &ftKernelEnd));
302 }
303}
304
305#define BEGIN_TIMER beginTimer()
306#define END_TIMER endTimer()
307#define HAS_TIMER hasTimer()
308
drhda108222009-02-25 19:07:24 +0000309#else
310#define BEGIN_TIMER
311#define END_TIMER
312#define HAS_TIMER 0
313#endif
314
shanec0688ea2009-03-05 03:48:06 +0000315/*
316** Used to prevent warnings about unused parameters
317*/
318#define UNUSED_PARAMETER(x) (void)(x)
319
drhe91d16b2008-12-08 18:27:31 +0000320/*
drhc49f44e2006-10-26 18:15:42 +0000321** If the following flag is set, then command execution stops
322** at an error if we are not interactive.
323*/
324static int bail_on_error = 0;
325
326/*
drhc28490c2006-10-26 14:25:58 +0000327** Threat stdin as an interactive input if the following variable
328** is true. Otherwise, assume stdin is connected to a file or pipe.
329*/
330static int stdin_is_interactive = 1;
331
332/*
drhe05461c2015-12-30 13:36:57 +0000333** On Windows systems we have to know if standard output is a console
334** in order to translate UTF-8 into MBCS. The following variable is
335** true if translation is required.
336*/
337static int stdout_is_console = 1;
338
339/*
drh4c504392000-10-16 22:06:40 +0000340** The following is the open SQLite database. We make a pointer
341** to this database a static variable so that it can be accessed
342** by the SIGINT handler to interrupt database processing.
343*/
mistachkin8e189222015-04-19 21:43:16 +0000344static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000345
346/*
drh67505e72002-04-19 12:34:06 +0000347** True if an interrupt (Control-C) has been received.
348*/
drh43617e92006-03-06 20:55:46 +0000349static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000350
351/*
persicom7e2dfdd2002-04-18 02:46:52 +0000352** This is the name of our program. It is set in main(), used
353** in a number of other places, mostly for error messages.
354*/
355static char *Argv0;
356
357/*
358** Prompt strings. Initialized in main. Settable with
359** .prompt main continue
360*/
361static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
362static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
363
drhb0603412007-02-28 04:47:26 +0000364/*
365** Write I/O traces to the following stream.
366*/
rsebe0a9092007-07-30 18:24:38 +0000367#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000368static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000369#endif
drhb0603412007-02-28 04:47:26 +0000370
371/*
372** This routine works like printf in that its first argument is a
373** format string and subsequent arguments are values to be substituted
374** in place of % fields. The result of formatting this string
375** is written to iotrace.
376*/
rsebe0a9092007-07-30 18:24:38 +0000377#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000378static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000379 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000380 char *z;
drhb0603412007-02-28 04:47:26 +0000381 if( iotrace==0 ) return;
382 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000383 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000384 va_end(ap);
drh41d0ba72016-01-03 11:27:47 +0000385 fprintf(iotrace, "%s", z);
drhf075cd02007-02-28 06:14:25 +0000386 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000387}
rsebe0a9092007-07-30 18:24:38 +0000388#endif
drhb0603412007-02-28 04:47:26 +0000389
drh44c2eb12003-04-30 11:38:26 +0000390
persicom7e2dfdd2002-04-18 02:46:52 +0000391/*
drh83965662003-04-17 02:54:13 +0000392** Determines if a string is a number of not.
393*/
danielk19772e588c72005-12-09 14:25:08 +0000394static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000395 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000396 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000397 return 0;
398 }
399 z++;
400 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000401 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000402 if( *z=='.' ){
403 z++;
drhf0693c82011-10-11 20:41:54 +0000404 if( !IsDigit(*z) ) return 0;
405 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000406 if( realnum ) *realnum = 1;
407 }
408 if( *z=='e' || *z=='E' ){
409 z++;
410 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000411 if( !IsDigit(*z) ) return 0;
412 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000413 if( realnum ) *realnum = 1;
414 }
415 return *z==0;
416}
drh83965662003-04-17 02:54:13 +0000417
418/*
danielk1977bc6ada42004-06-30 08:20:16 +0000419** A global char* and an SQL function to access its current value
420** from within an SQL statement. This program used to use the
421** sqlite_exec_printf() API to substitue a string into an SQL statement.
422** The correct way to do this with sqlite3 is to use the bind API, but
423** since the shell is built around the callback paradigm it would be a lot
424** of work. Instead just use this hack, which is quite harmless.
425*/
426static const char *zShellStatic = 0;
427static void shellstaticFunc(
428 sqlite3_context *context,
429 int argc,
430 sqlite3_value **argv
431){
432 assert( 0==argc );
433 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000434 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000435 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000436 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
437}
438
439
440/*
drhe05461c2015-12-30 13:36:57 +0000441** Compute a string length that is limited to what can be stored in
442** lower 30 bits of a 32-bit signed integer.
443*/
444static int strlen30(const char *z){
445 const char *z2 = z;
446 while( *z2 ){ z2++; }
447 return 0x3fffffff & (int)(z2 - z);
448}
449
450/*
drhfeac5f82004-08-01 00:10:45 +0000451** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000452** the text in memory obtained from malloc() and returns a pointer
453** to the text. NULL is returned at end of file, or if malloc()
454** fails.
455**
drh9f099fd2013-08-06 14:01:46 +0000456** If zLine is not NULL then it is a malloced buffer returned from
457** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000458*/
drh9f099fd2013-08-06 14:01:46 +0000459static char *local_getline(char *zLine, FILE *in){
460 int nLine = zLine==0 ? 0 : 100;
461 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000462
drhb07028f2011-10-14 21:49:18 +0000463 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000464 if( n+100>nLine ){
465 nLine = nLine*2 + 100;
466 zLine = realloc(zLine, nLine);
467 if( zLine==0 ) return 0;
468 }
drhdaffd0e2001-04-11 14:28:42 +0000469 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000470 if( n==0 ){
471 free(zLine);
472 return 0;
473 }
474 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000475 break;
476 }
drh9f099fd2013-08-06 14:01:46 +0000477 while( zLine[n] ) n++;
478 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000479 n--;
shaneh13b36022009-12-17 21:07:15 +0000480 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000481 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000482 break;
drh8e7e7a22000-05-30 18:45:23 +0000483 }
484 }
drhe05461c2015-12-30 13:36:57 +0000485#if defined(_WIN32) || defined(WIN32)
486 /* For interactive input on Windows systems, translate the
487 ** multi-byte characterset characters into UTF-8. */
488 if( stdin_is_interactive ){
489 extern char *sqlite3_win32_mbcs_to_utf8(const char*);
490 char *zTrans = sqlite3_win32_mbcs_to_utf8(zLine);
491 if( zTrans ){
492 int nTrans = strlen30(zTrans)+1;
493 if( nTrans>nLine ){
494 zLine = realloc(zLine, nTrans);
495 if( zLine==0 ){
496 sqlite3_free(zTrans);
497 return 0;
498 }
499 }
500 memcpy(zLine, zTrans, nTrans);
501 sqlite3_free(zTrans);
502 }
503 }
504#endif /* defined(_WIN32) || defined(WIN32) */
drh8e7e7a22000-05-30 18:45:23 +0000505 return zLine;
506}
507
508/*
drhc28490c2006-10-26 14:25:58 +0000509** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000510**
drh9f099fd2013-08-06 14:01:46 +0000511** If in==0 then read from standard input and prompt before each line.
512** If isContinuation is true, then a continuation prompt is appropriate.
513** If isContinuation is zero, then the main prompt should be used.
514**
515** If zPrior is not NULL then it is a buffer from a prior call to this
516** routine that can be reused.
517**
518** The result is stored in space obtained from malloc() and must either
519** be freed by the caller or else passed back into this routine via the
520** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000521*/
drh9f099fd2013-08-06 14:01:46 +0000522static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000523 char *zPrompt;
524 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000525 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000526 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000527 }else{
drh9f099fd2013-08-06 14:01:46 +0000528 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000529#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000530 printf("%s", zPrompt);
531 fflush(stdout);
532 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000533#else
534 free(zPrior);
535 zResult = shell_readline(zPrompt);
536 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000537#endif
drh9f099fd2013-08-06 14:01:46 +0000538 }
drh8e7e7a22000-05-30 18:45:23 +0000539 return zResult;
540}
541
drhdcd87a92014-08-18 13:45:42 +0000542/*
drhe05461c2015-12-30 13:36:57 +0000543** Render output like fprintf(). Except, if the output is going to the
544** console and if this is running on a Windows machine, translate the
545** output from UTF-8 into MBCS.
546*/
547#if defined(_WIN32) || defined(WIN32)
548void utf8_printf(FILE *out, const char *zFormat, ...){
549 va_list ap;
550 va_start(ap, zFormat);
mistachkinaae280e2015-12-31 19:06:24 +0000551 if( stdout_is_console && (out==stdout || out==stderr) ){
drhe05461c2015-12-30 13:36:57 +0000552 extern char *sqlite3_win32_utf8_to_mbcs(const char*);
553 char *z1 = sqlite3_vmprintf(zFormat, ap);
554 char *z2 = sqlite3_win32_utf8_to_mbcs(z1);
555 sqlite3_free(z1);
556 fputs(z2, out);
557 sqlite3_free(z2);
558 }else{
559 vfprintf(out, zFormat, ap);
560 }
561 va_end(ap);
562}
mistachkinaae280e2015-12-31 19:06:24 +0000563#elif !defined(utf8_printf)
drhe05461c2015-12-30 13:36:57 +0000564# define utf8_printf fprintf
565#endif
566
567/*
mistachkinaae280e2015-12-31 19:06:24 +0000568** Render output like fprintf(). This should not be used on anything that
569** includes string formatting (e.g. "%s").
570*/
571#if !defined(raw_printf)
572# define raw_printf fprintf
573#endif
574
575/*
drhdcd87a92014-08-18 13:45:42 +0000576** Shell output mode information from before ".explain on",
577** saved so that it can be restored by ".explain off"
578*/
579typedef struct SavedModeInfo SavedModeInfo;
580struct SavedModeInfo {
581 int valid; /* Is there legit data in here? */
582 int mode; /* Mode prior to ".explain on" */
583 int showHeader; /* The ".header" setting prior to ".explain on" */
584 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000585};
drh45e29d82006-11-20 16:21:10 +0000586
drh8e7e7a22000-05-30 18:45:23 +0000587/*
drhdcd87a92014-08-18 13:45:42 +0000588** State information about the database connection is contained in an
589** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000590*/
drhdcd87a92014-08-18 13:45:42 +0000591typedef struct ShellState ShellState;
592struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000593 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000594 int echoOn; /* True to echo input commands */
drh700c2522016-02-09 18:39:25 +0000595 int autoExplain; /* Automatically turn on .explain mode */
drhc2ce0be2014-05-29 12:36:14 +0000596 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000597 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000598 int scanstatsOn; /* True to display scan stats before each finalize */
drhdf12f1c2015-12-07 21:46:19 +0000599 int countChanges; /* True to display change counts */
drh9569f602015-04-16 15:05:04 +0000600 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000601 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000602 int cnt; /* Number of records displayed so far */
603 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000604 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000605 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000606 int mode; /* An output mode setting */
drh700c2522016-02-09 18:39:25 +0000607 int cMode; /* temporary output mode for the current query */
608 int normalMode; /* Output mode before ".explain on" */
drh45e29d82006-11-20 16:21:10 +0000609 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000610 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000611 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000612 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000613 char colSeparator[20]; /* Column separator character for several modes */
614 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000615 int colWidth[100]; /* Requested width of each column when in column mode*/
616 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000617 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000618 ** the database */
drh44c2eb12003-04-30 11:38:26 +0000619 char outfile[FILENAME_MAX]; /* Filename for *out */
620 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000621 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000622 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000623 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000624 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000625 int *aiIndent; /* Array of indents used in MODE_Explain */
626 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000627 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000628};
629
630/*
drh44dec872014-08-30 15:49:25 +0000631** These are the allowed shellFlgs values
632*/
633#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
634#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
635#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
636
637/*
drh75897232000-05-29 14:26:00 +0000638** These are the allowed modes.
639*/
drh967e8b72000-06-21 13:59:10 +0000640#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000641#define MODE_Column 1 /* One record per line in neat columns */
642#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000643#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
644#define MODE_Html 4 /* Generate an XHTML table */
645#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000646#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000647#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000648#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000649#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000650
drh66ce4d02008-02-15 17:38:06 +0000651static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000652 "line",
653 "column",
654 "list",
655 "semi",
656 "html",
drhfeac5f82004-08-01 00:10:45 +0000657 "insert",
658 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000659 "csv",
drh66ce4d02008-02-15 17:38:06 +0000660 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000661 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000662};
drh75897232000-05-29 14:26:00 +0000663
664/*
mistachkinfad42082014-07-24 22:13:12 +0000665** These are the column/row/line separators used by the various
666** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000667*/
mistachkinfad42082014-07-24 22:13:12 +0000668#define SEP_Column "|"
669#define SEP_Row "\n"
670#define SEP_Tab "\t"
671#define SEP_Space " "
672#define SEP_Comma ","
673#define SEP_CrLf "\r\n"
674#define SEP_Unit "\x1F"
675#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000676
677/*
drh75897232000-05-29 14:26:00 +0000678** Number of elements in an array
679*/
drh902b9ee2008-12-05 17:17:07 +0000680#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000681
682/*
drh127f9d72010-02-23 01:47:00 +0000683** A callback for the sqlite3_log() interface.
684*/
685static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000686 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000687 if( p->pLog==0 ) return;
mistachkinaae280e2015-12-31 19:06:24 +0000688 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
drh127f9d72010-02-23 01:47:00 +0000689 fflush(p->pLog);
690}
691
692/*
shane626a6e42009-10-22 17:30:15 +0000693** Output the given string as a hex-encoded blob (eg. X'1234' )
694*/
695static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
696 int i;
697 char *zBlob = (char *)pBlob;
mistachkinaae280e2015-12-31 19:06:24 +0000698 raw_printf(out,"X'");
699 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
700 raw_printf(out,"'");
shane626a6e42009-10-22 17:30:15 +0000701}
702
703/*
drh28bd4bc2000-06-15 15:57:22 +0000704** Output the given string as a quoted string using SQL quoting conventions.
705*/
706static void output_quoted_string(FILE *out, const char *z){
707 int i;
708 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000709 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000710 for(i=0; z[i]; i++){
711 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000712 }
713 if( nSingle==0 ){
drhe05461c2015-12-30 13:36:57 +0000714 utf8_printf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000715 }else{
mistachkinaae280e2015-12-31 19:06:24 +0000716 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000717 while( *z ){
718 for(i=0; z[i] && z[i]!='\''; i++){}
719 if( i==0 ){
mistachkinaae280e2015-12-31 19:06:24 +0000720 raw_printf(out,"''");
drh28bd4bc2000-06-15 15:57:22 +0000721 z++;
722 }else if( z[i]=='\'' ){
drhe05461c2015-12-30 13:36:57 +0000723 utf8_printf(out,"%.*s''",i,z);
drh28bd4bc2000-06-15 15:57:22 +0000724 z += i+1;
725 }else{
drhe05461c2015-12-30 13:36:57 +0000726 utf8_printf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000727 break;
728 }
729 }
mistachkinaae280e2015-12-31 19:06:24 +0000730 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000731 }
drh047d4532015-01-18 20:30:23 +0000732 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000733}
734
735/*
drhfeac5f82004-08-01 00:10:45 +0000736** Output the given string as a quoted according to C or TCL quoting rules.
737*/
738static void output_c_string(FILE *out, const char *z){
739 unsigned int c;
740 fputc('"', out);
741 while( (c = *(z++))!=0 ){
742 if( c=='\\' ){
743 fputc(c, out);
744 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000745 }else if( c=='"' ){
746 fputc('\\', out);
747 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000748 }else if( c=='\t' ){
749 fputc('\\', out);
750 fputc('t', out);
751 }else if( c=='\n' ){
752 fputc('\\', out);
753 fputc('n', out);
754 }else if( c=='\r' ){
755 fputc('\\', out);
756 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000757 }else if( !isprint(c&0xff) ){
mistachkinaae280e2015-12-31 19:06:24 +0000758 raw_printf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000759 }else{
760 fputc(c, out);
761 }
762 }
763 fputc('"', out);
764}
765
766/*
drhc08a4f12000-06-15 16:49:48 +0000767** Output the given string with characters that are special to
768** HTML escaped.
769*/
770static void output_html_string(FILE *out, const char *z){
771 int i;
drhc3d6ba42014-01-13 20:38:35 +0000772 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000773 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000774 for(i=0; z[i]
775 && z[i]!='<'
776 && z[i]!='&'
777 && z[i]!='>'
778 && z[i]!='\"'
779 && z[i]!='\'';
780 i++){}
drhc08a4f12000-06-15 16:49:48 +0000781 if( i>0 ){
drhe05461c2015-12-30 13:36:57 +0000782 utf8_printf(out,"%.*s",i,z);
drhc08a4f12000-06-15 16:49:48 +0000783 }
784 if( z[i]=='<' ){
mistachkinaae280e2015-12-31 19:06:24 +0000785 raw_printf(out,"&lt;");
drhc08a4f12000-06-15 16:49:48 +0000786 }else if( z[i]=='&' ){
mistachkinaae280e2015-12-31 19:06:24 +0000787 raw_printf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000788 }else if( z[i]=='>' ){
mistachkinaae280e2015-12-31 19:06:24 +0000789 raw_printf(out,"&gt;");
shane43d9cb22009-10-21 14:11:48 +0000790 }else if( z[i]=='\"' ){
mistachkinaae280e2015-12-31 19:06:24 +0000791 raw_printf(out,"&quot;");
shane43d9cb22009-10-21 14:11:48 +0000792 }else if( z[i]=='\'' ){
mistachkinaae280e2015-12-31 19:06:24 +0000793 raw_printf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000794 }else{
795 break;
796 }
797 z += i + 1;
798 }
799}
800
801/*
drhc49f44e2006-10-26 18:15:42 +0000802** If a field contains any character identified by a 1 in the following
803** array, then the string must be quoted for CSV.
804*/
805static const char needCsvQuote[] = {
806 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
807 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
808 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
809 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
811 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
812 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
814 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
815 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
816 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
817 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
818 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
819 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
820 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
821 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
822};
823
824/*
mistachkindd11f2d2014-12-11 04:49:46 +0000825** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000826** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000827** the null value. Strings are quoted if necessary. The separator
828** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000829*/
drhdcd87a92014-08-18 13:45:42 +0000830static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000831 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000832 if( z==0 ){
drhe05461c2015-12-30 13:36:57 +0000833 utf8_printf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000834 }else{
drhc49f44e2006-10-26 18:15:42 +0000835 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000836 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000837 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000838 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000839 || (z[i]==p->colSeparator[0] &&
840 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000841 i = 0;
842 break;
843 }
844 }
845 if( i==0 ){
846 putc('"', out);
847 for(i=0; z[i]; i++){
848 if( z[i]=='"' ) putc('"', out);
849 putc(z[i], out);
850 }
851 putc('"', out);
852 }else{
drhe05461c2015-12-30 13:36:57 +0000853 utf8_printf(out, "%s", z);
drhc49f44e2006-10-26 18:15:42 +0000854 }
drh8e64d1c2004-10-07 00:32:39 +0000855 }
856 if( bSep ){
drhe05461c2015-12-30 13:36:57 +0000857 utf8_printf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000858 }
859}
860
danielk19774af00c62005-01-23 23:43:21 +0000861#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000862/*
drh4c504392000-10-16 22:06:40 +0000863** This routine runs when the user presses Ctrl-C
864*/
865static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000866 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000867 seenInterrupt++;
868 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000869 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000870}
danielk19774af00c62005-01-23 23:43:21 +0000871#endif
drh4c504392000-10-16 22:06:40 +0000872
873/*
shane626a6e42009-10-22 17:30:15 +0000874** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000875** invokes for each row of a query result.
876*/
drh4ace5362014-11-10 14:42:28 +0000877static int shell_callback(
878 void *pArg,
879 int nArg, /* Number of result columns */
880 char **azArg, /* Text of each result column */
881 char **azCol, /* Column names */
882 int *aiType /* Column types */
883){
drh75897232000-05-29 14:26:00 +0000884 int i;
drhdcd87a92014-08-18 13:45:42 +0000885 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000886
drh700c2522016-02-09 18:39:25 +0000887 switch( p->cMode ){
drh75897232000-05-29 14:26:00 +0000888 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000889 int w = 5;
drh6a535342001-10-19 16:44:56 +0000890 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000891 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000892 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000893 if( len>w ) w = len;
894 }
drhe05461c2015-12-30 13:36:57 +0000895 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000896 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000897 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000898 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000899 }
900 break;
901 }
danielk19770d78bae2008-01-03 07:09:48 +0000902 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000903 case MODE_Column: {
drh700c2522016-02-09 18:39:25 +0000904 static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
905 const int *colWidth;
906 int showHdr;
907 char *rowSep;
908 if( p->cMode==MODE_Column ){
909 colWidth = p->colWidth;
910 showHdr = p->showHeader;
911 rowSep = p->rowSeparator;
912 }else{
913 colWidth = aExplainWidths;
914 showHdr = 1;
915 rowSep = "\n";
916 }
drha0c66f52000-07-29 13:20:21 +0000917 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000918 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000919 int w, n;
920 if( i<ArraySize(p->colWidth) ){
drh700c2522016-02-09 18:39:25 +0000921 w = colWidth[i];
drh75897232000-05-29 14:26:00 +0000922 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000923 w = 0;
drh75897232000-05-29 14:26:00 +0000924 }
drh078b1fd2012-09-21 13:40:02 +0000925 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000926 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000927 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000928 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000929 if( w<n ) w = n;
930 }
931 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000932 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000933 }
drh700c2522016-02-09 18:39:25 +0000934 if( showHdr ){
drh078b1fd2012-09-21 13:40:02 +0000935 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +0000936 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
drh700c2522016-02-09 18:39:25 +0000937 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +0000938 }else{
drhe05461c2015-12-30 13:36:57 +0000939 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
drh700c2522016-02-09 18:39:25 +0000940 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +0000941 }
drha0c66f52000-07-29 13:20:21 +0000942 }
943 }
drh700c2522016-02-09 18:39:25 +0000944 if( showHdr ){
drha0c66f52000-07-29 13:20:21 +0000945 for(i=0; i<nArg; i++){
946 int w;
947 if( i<ArraySize(p->actualWidth) ){
948 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000949 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000950 }else{
951 w = 10;
952 }
mistachkinaae280e2015-12-31 19:06:24 +0000953 utf8_printf(p->out,"%-*.*s%s",w,w,
drhe05461c2015-12-30 13:36:57 +0000954 "----------------------------------------------------------"
drha0c66f52000-07-29 13:20:21 +0000955 "----------------------------------------------------------",
drh700c2522016-02-09 18:39:25 +0000956 i==nArg-1 ? rowSep : " ");
drha0c66f52000-07-29 13:20:21 +0000957 }
drh75897232000-05-29 14:26:00 +0000958 }
959 }
drh6a535342001-10-19 16:44:56 +0000960 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000961 for(i=0; i<nArg; i++){
962 int w;
drha0c66f52000-07-29 13:20:21 +0000963 if( i<ArraySize(p->actualWidth) ){
964 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000965 }else{
966 w = 10;
967 }
drh700c2522016-02-09 18:39:25 +0000968 if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000969 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000970 }
dana98bf362013-11-13 18:35:01 +0000971 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000972 if( p->iIndent<p->nIndent ){
mistachkinaae280e2015-12-31 19:06:24 +0000973 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000974 }
danc4650bb2013-11-18 08:41:06 +0000975 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000976 }
drh078b1fd2012-09-21 13:40:02 +0000977 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +0000978 utf8_printf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000979 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +0000980 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +0000981 }else{
drhe05461c2015-12-30 13:36:57 +0000982 utf8_printf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000983 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +0000984 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +0000985 }
drh75897232000-05-29 14:26:00 +0000986 }
987 break;
988 }
drhe3710332000-09-29 13:30:53 +0000989 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000990 case MODE_List: {
991 if( p->cnt++==0 && p->showHeader ){
992 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000993 utf8_printf(p->out,"%s%s",azCol[i],
mistachkin636bf9f2014-07-19 20:15:16 +0000994 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000995 }
996 }
drh6a535342001-10-19 16:44:56 +0000997 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000998 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000999 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +00001000 if( z==0 ) z = p->nullValue;
drhe05461c2015-12-30 13:36:57 +00001001 utf8_printf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001002 if( i<nArg-1 ){
drhe05461c2015-12-30 13:36:57 +00001003 utf8_printf(p->out, "%s", p->colSeparator);
drh700c2522016-02-09 18:39:25 +00001004 }else if( p->cMode==MODE_Semi ){
drhe05461c2015-12-30 13:36:57 +00001005 utf8_printf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001006 }else{
drhe05461c2015-12-30 13:36:57 +00001007 utf8_printf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001008 }
drh75897232000-05-29 14:26:00 +00001009 }
1010 break;
1011 }
drh1e5d0e92000-05-31 23:33:17 +00001012 case MODE_Html: {
1013 if( p->cnt++==0 && p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001014 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001015 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001016 raw_printf(p->out,"<TH>");
shane43d9cb22009-10-21 14:11:48 +00001017 output_html_string(p->out, azCol[i]);
mistachkinaae280e2015-12-31 19:06:24 +00001018 raw_printf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001019 }
mistachkinaae280e2015-12-31 19:06:24 +00001020 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001021 }
drh6a535342001-10-19 16:44:56 +00001022 if( azArg==0 ) break;
mistachkinaae280e2015-12-31 19:06:24 +00001023 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001024 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001025 raw_printf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +00001026 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00001027 raw_printf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001028 }
mistachkinaae280e2015-12-31 19:06:24 +00001029 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001030 break;
1031 }
drhfeac5f82004-08-01 00:10:45 +00001032 case MODE_Tcl: {
1033 if( p->cnt++==0 && p->showHeader ){
1034 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001035 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhe05461c2015-12-30 13:36:57 +00001036 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001037 }
drhe05461c2015-12-30 13:36:57 +00001038 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001039 }
1040 if( azArg==0 ) break;
1041 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +00001042 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
drhe05461c2015-12-30 13:36:57 +00001043 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001044 }
drhe05461c2015-12-30 13:36:57 +00001045 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001046 break;
1047 }
drh8e64d1c2004-10-07 00:32:39 +00001048 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +00001049 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +00001050 if( p->cnt++==0 && p->showHeader ){
1051 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001052 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001053 }
drhe05461c2015-12-30 13:36:57 +00001054 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001055 }
drh40253262014-10-17 21:35:05 +00001056 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +00001057 for(i=0; i<nArg; i++){
1058 output_csv(p, azArg[i], i<nArg-1);
1059 }
drhe05461c2015-12-30 13:36:57 +00001060 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001061 }
drh047d4532015-01-18 20:30:23 +00001062 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +00001063 break;
1064 }
drh28bd4bc2000-06-15 15:57:22 +00001065 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001066 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001067 if( azArg==0 ) break;
drhe05461c2015-12-30 13:36:57 +00001068 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
mistachkin151c75a2015-04-07 21:16:40 +00001069 if( p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001070 raw_printf(p->out,"(");
mistachkin151c75a2015-04-07 21:16:40 +00001071 for(i=0; i<nArg; i++){
1072 char *zSep = i>0 ? ",": "";
drhe05461c2015-12-30 13:36:57 +00001073 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
mistachkin151c75a2015-04-07 21:16:40 +00001074 }
mistachkinaae280e2015-12-31 19:06:24 +00001075 raw_printf(p->out,")");
mistachkin151c75a2015-04-07 21:16:40 +00001076 }
mistachkinaae280e2015-12-31 19:06:24 +00001077 raw_printf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001078 for(i=0; i<nArg; i++){
1079 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001080 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
mistachkinaae280e2015-12-31 19:06:24 +00001081 utf8_printf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001082 }else if( aiType && aiType[i]==SQLITE_TEXT ){
mistachkinaae280e2015-12-31 19:06:24 +00001083 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shanead6b8d02009-10-22 18:12:58 +00001084 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001085 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1086 || aiType[i]==SQLITE_FLOAT) ){
drhe05461c2015-12-30 13:36:57 +00001087 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001088 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1089 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1090 int nBlob = sqlite3_column_bytes(p->pStmt, i);
mistachkinaae280e2015-12-31 19:06:24 +00001091 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shane626a6e42009-10-22 17:30:15 +00001092 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001093 }else if( isNumber(azArg[i], 0) ){
drhe05461c2015-12-30 13:36:57 +00001094 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
drh28bd4bc2000-06-15 15:57:22 +00001095 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001096 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
drh28bd4bc2000-06-15 15:57:22 +00001097 output_quoted_string(p->out, azArg[i]);
1098 }
1099 }
mistachkinaae280e2015-12-31 19:06:24 +00001100 raw_printf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001101 break;
drh28bd4bc2000-06-15 15:57:22 +00001102 }
mistachkin636bf9f2014-07-19 20:15:16 +00001103 case MODE_Ascii: {
1104 if( p->cnt++==0 && p->showHeader ){
1105 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001106 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1107 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +00001108 }
drhe05461c2015-12-30 13:36:57 +00001109 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001110 }
1111 if( azArg==0 ) break;
1112 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001113 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1114 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001115 }
drhe05461c2015-12-30 13:36:57 +00001116 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001117 break;
1118 }
persicom1d0b8722002-04-18 02:53:04 +00001119 }
drh75897232000-05-29 14:26:00 +00001120 return 0;
1121}
1122
1123/*
shane626a6e42009-10-22 17:30:15 +00001124** This is the callback routine that the SQLite library
1125** invokes for each row of a query result.
1126*/
1127static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1128 /* since we don't have type info, call the shell_callback with a NULL value */
1129 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1130}
1131
1132/*
drhdcd87a92014-08-18 13:45:42 +00001133** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001134** the name of the table given. Escape any quote characters in the
1135** table name.
1136*/
drhdcd87a92014-08-18 13:45:42 +00001137static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001138 int i, n;
1139 int needQuote;
1140 char *z;
1141
1142 if( p->zDestTable ){
1143 free(p->zDestTable);
1144 p->zDestTable = 0;
1145 }
1146 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001147 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001148 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001149 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001150 needQuote = 1;
1151 if( zName[i]=='\'' ) n++;
1152 }
1153 }
1154 if( needQuote ) n += 2;
1155 z = p->zDestTable = malloc( n+1 );
1156 if( z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001157 raw_printf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001158 exit(1);
1159 }
1160 n = 0;
1161 if( needQuote ) z[n++] = '\'';
1162 for(i=0; zName[i]; i++){
1163 z[n++] = zName[i];
1164 if( zName[i]=='\'' ) z[n++] = '\'';
1165 }
1166 if( needQuote ) z[n++] = '\'';
1167 z[n] = 0;
1168}
1169
danielk19772a02e332004-06-05 08:04:36 +00001170/* zIn is either a pointer to a NULL-terminated string in memory obtained
1171** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1172** added to zIn, and the result returned in memory obtained from malloc().
1173** zIn, if it was not NULL, is freed.
1174**
1175** If the third argument, quote, is not '\0', then it is used as a
1176** quote character for zAppend.
1177*/
drhc28490c2006-10-26 14:25:58 +00001178static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001179 int len;
1180 int i;
drh4f21c4a2008-12-10 22:15:00 +00001181 int nAppend = strlen30(zAppend);
1182 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001183
1184 len = nAppend+nIn+1;
1185 if( quote ){
1186 len += 2;
1187 for(i=0; i<nAppend; i++){
1188 if( zAppend[i]==quote ) len++;
1189 }
1190 }
1191
1192 zIn = (char *)realloc(zIn, len);
1193 if( !zIn ){
1194 return 0;
1195 }
1196
1197 if( quote ){
1198 char *zCsr = &zIn[nIn];
1199 *zCsr++ = quote;
1200 for(i=0; i<nAppend; i++){
1201 *zCsr++ = zAppend[i];
1202 if( zAppend[i]==quote ) *zCsr++ = quote;
1203 }
1204 *zCsr++ = quote;
1205 *zCsr++ = '\0';
1206 assert( (zCsr-zIn)==len );
1207 }else{
1208 memcpy(&zIn[nIn], zAppend, nAppend);
1209 zIn[len-1] = '\0';
1210 }
1211
1212 return zIn;
1213}
1214
drhdd3d4592004-08-30 01:54:05 +00001215
1216/*
drhb21a8e42012-01-28 21:08:51 +00001217** Execute a query statement that will generate SQL output. Print
1218** the result columns, comma-separated, on a line and then add a
1219** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001220**
drhb21a8e42012-01-28 21:08:51 +00001221** If the number of columns is 1 and that column contains text "--"
1222** then write the semicolon on a separate line. That way, if a
1223** "--" comment occurs at the end of the statement, the comment
1224** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001225*/
drh157e29a2009-05-21 15:15:00 +00001226static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001227 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001228 const char *zSelect, /* SELECT statement to extract content */
1229 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001230){
drhdd3d4592004-08-30 01:54:05 +00001231 sqlite3_stmt *pSelect;
1232 int rc;
drhb21a8e42012-01-28 21:08:51 +00001233 int nResult;
1234 int i;
1235 const char *z;
drhc7181902014-02-27 15:04:13 +00001236 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001237 if( rc!=SQLITE_OK || !pSelect ){
mistachkinaae280e2015-12-31 19:06:24 +00001238 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1239 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001240 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001241 return rc;
1242 }
1243 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001244 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001245 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001246 if( zFirstRow ){
drhe05461c2015-12-30 13:36:57 +00001247 utf8_printf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001248 zFirstRow = 0;
1249 }
drhb21a8e42012-01-28 21:08:51 +00001250 z = (const char*)sqlite3_column_text(pSelect, 0);
drhe05461c2015-12-30 13:36:57 +00001251 utf8_printf(p->out, "%s", z);
drhb21a8e42012-01-28 21:08:51 +00001252 for(i=1; i<nResult; i++){
drhe05461c2015-12-30 13:36:57 +00001253 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
drhb21a8e42012-01-28 21:08:51 +00001254 }
1255 if( z==0 ) z = "";
1256 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1257 if( z[0] ){
mistachkinaae280e2015-12-31 19:06:24 +00001258 raw_printf(p->out, "\n;\n");
drhb21a8e42012-01-28 21:08:51 +00001259 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001260 raw_printf(p->out, ";\n");
drhb21a8e42012-01-28 21:08:51 +00001261 }
drhdd3d4592004-08-30 01:54:05 +00001262 rc = sqlite3_step(pSelect);
1263 }
drh2f464a02011-10-13 00:41:49 +00001264 rc = sqlite3_finalize(pSelect);
1265 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00001266 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1267 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001268 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001269 }
1270 return rc;
drhdd3d4592004-08-30 01:54:05 +00001271}
1272
shane626a6e42009-10-22 17:30:15 +00001273/*
1274** Allocate space and save off current error string.
1275*/
1276static char *save_err_msg(
1277 sqlite3 *db /* Database to query */
1278){
1279 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001280 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001281 if( zErrMsg ){
1282 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1283 }
1284 return zErrMsg;
1285}
1286
1287/*
shaneh642d8b82010-07-28 16:05:34 +00001288** Display memory stats.
1289*/
1290static int display_stats(
1291 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001292 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001293 int bReset /* True to reset the stats */
1294){
1295 int iCur;
1296 int iHiwtr;
1297
1298 if( pArg && pArg->out ){
1299
1300 iHiwtr = iCur = -1;
1301 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001302 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001303 "Memory Used: %d (max %d) bytes\n",
1304 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001305 iHiwtr = iCur = -1;
1306 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001307 raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001308 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001309 if( pArg->shellFlgs & SHFLG_Pagecache ){
1310 iHiwtr = iCur = -1;
1311 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001312 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001313 "Number of Pcache Pages Used: %d (max %d) pages\n",
1314 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001315 }
shaneh642d8b82010-07-28 16:05:34 +00001316 iHiwtr = iCur = -1;
1317 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001318 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001319 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1320 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001321 if( pArg->shellFlgs & SHFLG_Scratch ){
1322 iHiwtr = iCur = -1;
1323 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001324 raw_printf(pArg->out,
1325 "Number of Scratch Allocations Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001326 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001327 }
shaneh642d8b82010-07-28 16:05:34 +00001328 iHiwtr = iCur = -1;
1329 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001330 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001331 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1332 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001333 iHiwtr = iCur = -1;
1334 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001335 raw_printf(pArg->out, "Largest Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001336 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001337 iHiwtr = iCur = -1;
1338 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001339 raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001340 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001341 iHiwtr = iCur = -1;
1342 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001343 raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001344 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001345#ifdef YYTRACKMAXSTACKDEPTH
1346 iHiwtr = iCur = -1;
1347 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001348 raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001349 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001350#endif
1351 }
1352
1353 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001354 if( pArg->shellFlgs & SHFLG_Lookaside ){
1355 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001356 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1357 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001358 raw_printf(pArg->out,
1359 "Lookaside Slots Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001360 iCur, iHiwtr);
1361 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1362 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001363 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
1364 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001365 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1366 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001367 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
1368 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001369 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1370 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001371 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
1372 iHiwtr);
drh44dec872014-08-30 15:49:25 +00001373 }
shaneh642d8b82010-07-28 16:05:34 +00001374 iHiwtr = iCur = -1;
1375 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001376 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
1377 iCur);
drh4ace5362014-11-10 14:42:28 +00001378 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001379 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001380 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
drhc78e6e42011-09-23 18:58:23 +00001381 iHiwtr = iCur = -1;
1382 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001383 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001384 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001385 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001386 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
drhfbbcd5d2012-03-24 20:09:33 +00001387 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001388 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001389 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
1390 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001391 iHiwtr = iCur = -1;
1392 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001393 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
1394 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001395 }
1396
1397 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001398 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1399 bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001400 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001401 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001402 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001403 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001404 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001405 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001406 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001407 }
1408
dan5a790282015-08-07 20:06:14 +00001409 /* Do not remove this machine readable comment: extra-stats-output-here */
1410
shaneh642d8b82010-07-28 16:05:34 +00001411 return 0;
1412}
1413
1414/*
dan8d1edb92014-11-05 09:07:28 +00001415** Display scan stats.
1416*/
1417static void display_scanstats(
1418 sqlite3 *db, /* Database to query */
1419 ShellState *pArg /* Pointer to ShellState */
1420){
drhf5ed7ad2015-06-15 14:43:25 +00001421#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1422 UNUSED_PARAMETER(db);
1423 UNUSED_PARAMETER(pArg);
1424#else
drh15f23c22014-11-06 12:46:16 +00001425 int i, k, n, mx;
mistachkinaae280e2015-12-31 19:06:24 +00001426 raw_printf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001427 mx = 0;
1428 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001429 double rEstLoop = 1.0;
1430 for(i=n=0; 1; i++){
1431 sqlite3_stmt *p = pArg->pStmt;
1432 sqlite3_int64 nLoop, nVisit;
1433 double rEst;
1434 int iSid;
1435 const char *zExplain;
1436 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1437 break;
1438 }
1439 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001440 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001441 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001442 if( n==0 ){
1443 rEstLoop = (double)nLoop;
mistachkinaae280e2015-12-31 19:06:24 +00001444 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001445 }
drh42f30bc2014-11-06 12:08:21 +00001446 n++;
1447 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1448 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1449 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
drhe05461c2015-12-30 13:36:57 +00001450 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
drh42f30bc2014-11-06 12:08:21 +00001451 rEstLoop *= rEst;
mistachkinaae280e2015-12-31 19:06:24 +00001452 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001453 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001454 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001455 );
dan8d1edb92014-11-05 09:07:28 +00001456 }
dan8d1edb92014-11-05 09:07:28 +00001457 }
mistachkinaae280e2015-12-31 19:06:24 +00001458 raw_printf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001459#endif
dan8d1edb92014-11-05 09:07:28 +00001460}
1461
1462/*
dana98bf362013-11-13 18:35:01 +00001463** Parameter azArray points to a zero-terminated array of strings. zStr
1464** points to a single nul-terminated string. Return non-zero if zStr
1465** is equal, according to strcmp(), to any of the strings in the array.
1466** Otherwise, return zero.
1467*/
1468static int str_in_array(const char *zStr, const char **azArray){
1469 int i;
1470 for(i=0; azArray[i]; i++){
1471 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1472 }
1473 return 0;
1474}
1475
1476/*
1477** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001478** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001479** spaces each opcode should be indented before it is output.
1480**
1481** The indenting rules are:
1482**
1483** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1484** all opcodes that occur between the p2 jump destination and the opcode
1485** itself by 2 spaces.
1486**
drh01752bc2013-11-14 23:59:33 +00001487** * For each "Goto", if the jump destination is earlier in the program
1488** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001489** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001490** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001491** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001492** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001493*/
drhdcd87a92014-08-18 13:45:42 +00001494static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001495 const char *zSql; /* The text of the SQL statement */
1496 const char *z; /* Used to check if this is an EXPLAIN */
1497 int *abYield = 0; /* True if op is an OP_Yield */
1498 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001499 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001500
drh8ad0de32014-03-20 18:45:27 +00001501 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1502 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001503 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1504 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001505 const char *azGoto[] = { "Goto", 0 };
1506
1507 /* Try to figure out if this is really an EXPLAIN statement. If this
1508 ** cannot be verified, return early. */
drh87a24aa2016-02-09 20:04:07 +00001509 if( sqlite3_column_count(pSql)!=8 ){
1510 p->cMode = p->mode;
1511 return;
1512 }
dana98bf362013-11-13 18:35:01 +00001513 zSql = sqlite3_sql(pSql);
1514 if( zSql==0 ) return;
1515 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
drh87a24aa2016-02-09 20:04:07 +00001516 if( sqlite3_strnicmp(z, "explain", 7) ){
1517 p->cMode = p->mode;
1518 return;
1519 }
dana98bf362013-11-13 18:35:01 +00001520
1521 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1522 int i;
danc4650bb2013-11-18 08:41:06 +00001523 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001524 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001525
1526 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1527 ** p2 is an instruction address, set variable p2op to the index of that
1528 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1529 ** the current instruction is part of a sub-program generated by an
1530 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001531 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001532 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001533
1534 /* Grow the p->aiIndent array as required */
1535 if( iOp>=nAlloc ){
drh87a24aa2016-02-09 20:04:07 +00001536 if( iOp==0 ){
1537 /* Do further verfication that this is explain output. Abort if
1538 ** it is not */
1539 static const char *explainCols[] = {
1540 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
1541 int jj;
1542 for(jj=0; jj<ArraySize(explainCols); jj++){
1543 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
1544 p->cMode = p->mode;
1545 sqlite3_reset(pSql);
1546 return;
1547 }
1548 }
1549 }
dana98bf362013-11-13 18:35:01 +00001550 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001551 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1552 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001553 }
1554 abYield[iOp] = str_in_array(zOp, azYield);
1555 p->aiIndent[iOp] = 0;
1556 p->nIndent = iOp+1;
1557
1558 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001559 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001560 }
drhfe705102014-03-06 13:38:37 +00001561 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1562 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1563 ){
drhe73f0592014-01-21 22:25:45 +00001564 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001565 }
1566 }
1567
danc4650bb2013-11-18 08:41:06 +00001568 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001569 sqlite3_free(abYield);
1570 sqlite3_reset(pSql);
1571}
1572
1573/*
1574** Free the array allocated by explain_data_prepare().
1575*/
drhdcd87a92014-08-18 13:45:42 +00001576static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001577 sqlite3_free(p->aiIndent);
1578 p->aiIndent = 0;
1579 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001580 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001581}
1582
1583/*
shane626a6e42009-10-22 17:30:15 +00001584** Execute a statement or set of statements. Print
1585** any result rows/columns depending on the current mode
1586** set via the supplied callback.
1587**
1588** This is very similar to SQLite's built-in sqlite3_exec()
1589** function except it takes a slightly different callback
1590** and callback data argument.
1591*/
1592static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001593 sqlite3 *db, /* An open database */
1594 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001595 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001596 /* (not the same as sqlite3_exec) */
1597 ShellState *pArg, /* Pointer to ShellState */
1598 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001599){
dan4564ced2010-01-05 04:59:56 +00001600 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1601 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001602 int rc2;
dan4564ced2010-01-05 04:59:56 +00001603 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001604
1605 if( pzErrMsg ){
1606 *pzErrMsg = NULL;
1607 }
1608
shaneb9fc17d2009-10-22 21:23:35 +00001609 while( zSql[0] && (SQLITE_OK == rc) ){
1610 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1611 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001612 if( pzErrMsg ){
1613 *pzErrMsg = save_err_msg(db);
1614 }
1615 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001616 if( !pStmt ){
1617 /* this happens for a comment or white-space */
1618 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001619 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001620 continue;
1621 }
shane626a6e42009-10-22 17:30:15 +00001622
shaneh642d8b82010-07-28 16:05:34 +00001623 /* save off the prepared statment handle and reset row count */
1624 if( pArg ){
1625 pArg->pStmt = pStmt;
1626 pArg->cnt = 0;
1627 }
1628
shanehb7977c52010-01-18 18:17:10 +00001629 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001630 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001631 const char *zStmtSql = sqlite3_sql(pStmt);
drhe05461c2015-12-30 13:36:57 +00001632 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001633 }
shanehb7977c52010-01-18 18:17:10 +00001634
drhefbf3b12014-02-28 20:47:24 +00001635 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1636 if( pArg && pArg->autoEQP ){
1637 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001638 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1639 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001640 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1641 if( rc==SQLITE_OK ){
1642 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001643 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1644 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1645 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001646 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001647 }
1648 }
1649 sqlite3_finalize(pExplain);
1650 sqlite3_free(zEQP);
1651 }
1652
drh700c2522016-02-09 18:39:25 +00001653 if( pArg ){
1654 pArg->cMode = pArg->mode;
drh87a24aa2016-02-09 20:04:07 +00001655 if( pArg->autoExplain
1656 && sqlite3_column_count(pStmt)==8
drh700c2522016-02-09 18:39:25 +00001657 && sqlite3_strlike("%EXPLAIN%", sqlite3_sql(pStmt),0)==0
drh700c2522016-02-09 18:39:25 +00001658 ){
1659 pArg->cMode = MODE_Explain;
1660 }
1661
1662 /* If the shell is currently in ".explain" mode, gather the extra
1663 ** data required to add indents to the output.*/
1664 if( pArg->cMode==MODE_Explain ){
1665 explain_data_prepare(pArg, pStmt);
1666 }
dana98bf362013-11-13 18:35:01 +00001667 }
1668
shaneb9fc17d2009-10-22 21:23:35 +00001669 /* perform the first step. this will tell us if we
1670 ** have a result set or not and how wide it is.
1671 */
1672 rc = sqlite3_step(pStmt);
1673 /* if we have a result set... */
1674 if( SQLITE_ROW == rc ){
1675 /* if we have a callback... */
1676 if( xCallback ){
1677 /* allocate space for col name ptr, value ptr, and type */
1678 int nCol = sqlite3_column_count(pStmt);
drhf3cdcdc2015-04-29 16:50:28 +00001679 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
shaneb9fc17d2009-10-22 21:23:35 +00001680 if( !pData ){
1681 rc = SQLITE_NOMEM;
1682 }else{
1683 char **azCols = (char **)pData; /* Names of result columns */
1684 char **azVals = &azCols[nCol]; /* Results */
1685 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001686 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001687 assert(sizeof(int) <= sizeof(char *));
1688 /* save off ptrs to column names */
1689 for(i=0; i<nCol; i++){
1690 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1691 }
shaneb9fc17d2009-10-22 21:23:35 +00001692 do{
1693 /* extract the data and data types */
1694 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001695 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh700c2522016-02-09 18:39:25 +00001696 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001697 azVals[i] = "";
1698 }else{
1699 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1700 }
shaneb9fc17d2009-10-22 21:23:35 +00001701 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1702 rc = SQLITE_NOMEM;
1703 break; /* from for */
1704 }
1705 } /* end for */
1706
1707 /* if data and types extracted successfully... */
1708 if( SQLITE_ROW == rc ){
1709 /* call the supplied callback with the result row data */
1710 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1711 rc = SQLITE_ABORT;
1712 }else{
1713 rc = sqlite3_step(pStmt);
1714 }
1715 }
1716 } while( SQLITE_ROW == rc );
1717 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001718 }
1719 }else{
1720 do{
1721 rc = sqlite3_step(pStmt);
1722 } while( rc == SQLITE_ROW );
1723 }
1724 }
1725
dana98bf362013-11-13 18:35:01 +00001726 explain_data_delete(pArg);
1727
shaneh642d8b82010-07-28 16:05:34 +00001728 /* print usage stats if stats on */
1729 if( pArg && pArg->statsOn ){
1730 display_stats(db, pArg, 0);
1731 }
1732
dan8d1edb92014-11-05 09:07:28 +00001733 /* print loop-counters if required */
1734 if( pArg && pArg->scanstatsOn ){
1735 display_scanstats(db, pArg);
1736 }
1737
dan4564ced2010-01-05 04:59:56 +00001738 /* Finalize the statement just executed. If this fails, save a
1739 ** copy of the error message. Otherwise, set zSql to point to the
1740 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001741 rc2 = sqlite3_finalize(pStmt);
1742 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001743 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001744 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001745 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001746 }else if( pzErrMsg ){
1747 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001748 }
shaneh642d8b82010-07-28 16:05:34 +00001749
1750 /* clear saved stmt handle */
1751 if( pArg ){
1752 pArg->pStmt = NULL;
1753 }
shane626a6e42009-10-22 17:30:15 +00001754 }
shaneb9fc17d2009-10-22 21:23:35 +00001755 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001756
1757 return rc;
1758}
1759
drhdd3d4592004-08-30 01:54:05 +00001760
drh33048c02001-10-01 14:29:22 +00001761/*
drh4c653a02000-06-07 01:27:47 +00001762** This is a different callback routine used for dumping the database.
1763** Each row received by this callback consists of a table name,
1764** the table type ("index" or "table") and SQL to create the table.
1765** This routine should print text sufficient to recreate the table.
1766*/
1767static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001768 int rc;
1769 const char *zTable;
1770 const char *zType;
1771 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001772 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001773 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001774
drh902b9ee2008-12-05 17:17:07 +00001775 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001776 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001777 zTable = azArg[0];
1778 zType = azArg[1];
1779 zSql = azArg[2];
1780
drh00b950d2005-09-11 02:03:03 +00001781 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001782 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001783 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001784 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00001785 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1786 return 0;
drh45e29d82006-11-20 16:21:10 +00001787 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1788 char *zIns;
1789 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00001790 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00001791 p->writableSchema = 1;
1792 }
1793 zIns = sqlite3_mprintf(
1794 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1795 "VALUES('table','%q','%q',0,'%q');",
1796 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00001797 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00001798 sqlite3_free(zIns);
1799 return 0;
drh00b950d2005-09-11 02:03:03 +00001800 }else{
drhe05461c2015-12-30 13:36:57 +00001801 utf8_printf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001802 }
danielk19772a02e332004-06-05 08:04:36 +00001803
1804 if( strcmp(zType, "table")==0 ){
1805 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001806 char *zSelect = 0;
1807 char *zTableInfo = 0;
1808 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001809 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001810
1811 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1812 zTableInfo = appendText(zTableInfo, zTable, '"');
1813 zTableInfo = appendText(zTableInfo, ");", 0);
1814
drhc7181902014-02-27 15:04:13 +00001815 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001816 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001817 if( rc!=SQLITE_OK || !pTableInfo ){
1818 return 1;
1819 }
1820
1821 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001822 /* Always quote the table name, even if it appears to be pure ascii,
1823 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1824 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001825 if( zTmp ){
1826 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001827 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001828 }
1829 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1830 rc = sqlite3_step(pTableInfo);
1831 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001832 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001833 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001834 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001835 rc = sqlite3_step(pTableInfo);
1836 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001837 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001838 }else{
1839 zSelect = appendText(zSelect, ") ", 0);
1840 }
drh157e29a2009-05-21 15:15:00 +00001841 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001842 }
1843 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001844 if( rc!=SQLITE_OK || nRow==0 ){
1845 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001846 return 1;
1847 }
1848 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1849 zSelect = appendText(zSelect, zTable, '"');
1850
drh2f464a02011-10-13 00:41:49 +00001851 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001852 if( rc==SQLITE_CORRUPT ){
1853 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001854 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001855 }
drh85e72432012-04-11 11:38:53 +00001856 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001857 }
drh4c653a02000-06-07 01:27:47 +00001858 return 0;
1859}
1860
1861/*
drh45e29d82006-11-20 16:21:10 +00001862** Run zQuery. Use dump_callback() as the callback routine so that
1863** the contents of the query are output as SQL statements.
1864**
drhdd3d4592004-08-30 01:54:05 +00001865** If we get a SQLITE_CORRUPT error, rerun the query after appending
1866** "ORDER BY rowid DESC" to the end.
1867*/
1868static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001869 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001870 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001871){
1872 int rc;
drh2f464a02011-10-13 00:41:49 +00001873 char *zErr = 0;
1874 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001875 if( rc==SQLITE_CORRUPT ){
1876 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001877 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00001878 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00001879 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00001880 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00001881 sqlite3_free(zErr);
1882 zErr = 0;
1883 }
drhdd3d4592004-08-30 01:54:05 +00001884 zQ2 = malloc( len+100 );
1885 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001886 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001887 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1888 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00001889 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00001890 }else{
1891 rc = SQLITE_CORRUPT;
1892 }
1893 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001894 free(zQ2);
1895 }
1896 return rc;
1897}
1898
1899/*
drh75897232000-05-29 14:26:00 +00001900** Text of a help message
1901*/
persicom1d0b8722002-04-18 02:53:04 +00001902static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001903 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001904 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00001905 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00001906 ".changes on|off Show number of rows changed by SQL\n"
drh4bbcf102014-02-06 02:46:08 +00001907 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001908 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001909 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001910 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001911 " If TABLE specified, only dump tables matching\n"
1912 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001913 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001914 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001915 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00001916 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drhc1971542014-06-23 23:28:13 +00001917 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001918 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001919 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001920 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001921 ".indexes ?TABLE? Show names of all indexes\n"
1922 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001923 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001924#ifdef SQLITE_ENABLE_IOTRACE
1925 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1926#endif
drh1a513372015-05-02 17:40:23 +00001927 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00001928#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001929 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001930#endif
drh127f9d72010-02-23 01:47:00 +00001931 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001932 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001933 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001934 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001935 " column Left-aligned columns. (See .width)\n"
1936 " html HTML <table> code\n"
1937 " insert SQL insert statements for TABLE\n"
1938 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001939 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001940 " tabs Tab-separated values\n"
1941 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001942 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001943 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001944 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001945 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001946 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001947 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001948 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001949 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001950 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001951 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001952 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001953 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001954 " If TABLE specified, only show tables matching\n"
1955 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001956 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1957 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001958 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001959 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001960 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001961 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001962 ".tables ?TABLE? List names of tables\n"
1963 " If TABLE specified, only list tables matching\n"
1964 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001965 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001966 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001967 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00001968 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00001969 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00001970 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001971 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001972 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001973;
1974
drhdaffd0e2001-04-11 14:28:42 +00001975/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001976static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001977/*
1978** Implementation of the "readfile(X)" SQL function. The entire content
1979** of the file named X is read and returned as a BLOB. NULL is returned
1980** if the file does not exist or is unreadable.
1981*/
1982static void readfileFunc(
1983 sqlite3_context *context,
1984 int argc,
1985 sqlite3_value **argv
1986){
1987 const char *zName;
1988 FILE *in;
1989 long nIn;
1990 void *pBuf;
1991
drhf5ed7ad2015-06-15 14:43:25 +00001992 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00001993 zName = (const char*)sqlite3_value_text(argv[0]);
1994 if( zName==0 ) return;
1995 in = fopen(zName, "rb");
1996 if( in==0 ) return;
1997 fseek(in, 0, SEEK_END);
1998 nIn = ftell(in);
1999 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00002000 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00002001 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
2002 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
2003 }else{
2004 sqlite3_free(pBuf);
2005 }
2006 fclose(in);
2007}
2008
2009/*
2010** Implementation of the "writefile(X,Y)" SQL function. The argument Y
2011** is written into file X. The number of bytes written is returned. Or
2012** NULL is returned if something goes wrong, such as being unable to open
2013** file X for writing.
2014*/
2015static void writefileFunc(
2016 sqlite3_context *context,
2017 int argc,
2018 sqlite3_value **argv
2019){
2020 FILE *out;
2021 const char *z;
drhba5b0932014-07-24 12:39:59 +00002022 sqlite3_int64 rc;
2023 const char *zFile;
2024
drhf5ed7ad2015-06-15 14:43:25 +00002025 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002026 zFile = (const char*)sqlite3_value_text(argv[0]);
2027 if( zFile==0 ) return;
2028 out = fopen(zFile, "wb");
2029 if( out==0 ) return;
2030 z = (const char*)sqlite3_value_blob(argv[1]);
2031 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002032 rc = 0;
2033 }else{
drh490fe862014-08-11 14:21:32 +00002034 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002035 }
2036 fclose(out);
2037 sqlite3_result_int64(context, rc);
2038}
drhdaffd0e2001-04-11 14:28:42 +00002039
drh75897232000-05-29 14:26:00 +00002040/*
drh44c2eb12003-04-30 11:38:26 +00002041** Make sure the database is open. If it is not, then open it. If
2042** the database fails to open, print an error message and exit.
2043*/
drhdcd87a92014-08-18 13:45:42 +00002044static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002045 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002046 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002047 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002048 globalDb = p->db;
2049 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2050 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002051 shellstaticFunc, 0, 0);
2052 }
mistachkin8e189222015-04-19 21:43:16 +00002053 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkinaae280e2015-12-31 19:06:24 +00002054 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002055 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002056 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002057 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002058 }
drhc2e87a32006-06-27 15:16:14 +00002059#ifndef SQLITE_OMIT_LOAD_EXTENSION
2060 sqlite3_enable_load_extension(p->db, 1);
2061#endif
mistachkin8e189222015-04-19 21:43:16 +00002062 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002063 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002064 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002065 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002066 }
2067}
2068
2069/*
drhfeac5f82004-08-01 00:10:45 +00002070** Do C-language style dequoting.
2071**
mistachkinf21979d2015-01-18 05:35:01 +00002072** \a -> alarm
2073** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002074** \t -> tab
2075** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002076** \v -> vertical tab
2077** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002078** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002079** \s -> space
drh4c56b992013-06-27 13:26:55 +00002080** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002081** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002082** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002083** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002084*/
2085static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002086 int i, j;
2087 char c;
drhc2ce0be2014-05-29 12:36:14 +00002088 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002089 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002090 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002091 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002092 if( c=='a' ){
2093 c = '\a';
2094 }else if( c=='b' ){
2095 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002096 }else if( c=='t' ){
2097 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002098 }else if( c=='n' ){
2099 c = '\n';
2100 }else if( c=='v' ){
2101 c = '\v';
2102 }else if( c=='f' ){
2103 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002104 }else if( c=='r' ){
2105 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002106 }else if( c=='"' ){
2107 c = '"';
2108 }else if( c=='\'' ){
2109 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002110 }else if( c=='\\' ){
2111 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002112 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002113 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002114 if( z[i+1]>='0' && z[i+1]<='7' ){
2115 i++;
2116 c = (c<<3) + z[i] - '0';
2117 if( z[i+1]>='0' && z[i+1]<='7' ){
2118 i++;
2119 c = (c<<3) + z[i] - '0';
2120 }
2121 }
2122 }
2123 }
2124 z[j] = c;
2125 }
drhc2ce0be2014-05-29 12:36:14 +00002126 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002127}
2128
2129/*
drh348d19c2013-06-03 12:47:43 +00002130** Return the value of a hexadecimal digit. Return -1 if the input
2131** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002132*/
drh348d19c2013-06-03 12:47:43 +00002133static int hexDigitValue(char c){
2134 if( c>='0' && c<='9' ) return c - '0';
2135 if( c>='a' && c<='f' ) return c - 'a' + 10;
2136 if( c>='A' && c<='F' ) return c - 'A' + 10;
2137 return -1;
drhc28490c2006-10-26 14:25:58 +00002138}
2139
2140/*
drh7d9f3942013-04-03 01:26:54 +00002141** Interpret zArg as an integer value, possibly with suffixes.
2142*/
2143static sqlite3_int64 integerValue(const char *zArg){
2144 sqlite3_int64 v = 0;
2145 static const struct { char *zSuffix; int iMult; } aMult[] = {
2146 { "KiB", 1024 },
2147 { "MiB", 1024*1024 },
2148 { "GiB", 1024*1024*1024 },
2149 { "KB", 1000 },
2150 { "MB", 1000000 },
2151 { "GB", 1000000000 },
2152 { "K", 1000 },
2153 { "M", 1000000 },
2154 { "G", 1000000000 },
2155 };
2156 int i;
2157 int isNeg = 0;
2158 if( zArg[0]=='-' ){
2159 isNeg = 1;
2160 zArg++;
2161 }else if( zArg[0]=='+' ){
2162 zArg++;
2163 }
drh348d19c2013-06-03 12:47:43 +00002164 if( zArg[0]=='0' && zArg[1]=='x' ){
2165 int x;
2166 zArg += 2;
2167 while( (x = hexDigitValue(zArg[0]))>=0 ){
2168 v = (v<<4) + x;
2169 zArg++;
2170 }
2171 }else{
2172 while( IsDigit(zArg[0]) ){
2173 v = v*10 + zArg[0] - '0';
2174 zArg++;
2175 }
drh7d9f3942013-04-03 01:26:54 +00002176 }
drhc2bed0a2013-05-24 11:57:50 +00002177 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002178 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2179 v *= aMult[i].iMult;
2180 break;
2181 }
2182 }
2183 return isNeg? -v : v;
2184}
2185
2186/*
drh348d19c2013-06-03 12:47:43 +00002187** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2188** for TRUE and FALSE. Return the integer value if appropriate.
2189*/
2190static int booleanValue(char *zArg){
2191 int i;
2192 if( zArg[0]=='0' && zArg[1]=='x' ){
2193 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2194 }else{
2195 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2196 }
2197 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2198 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2199 return 1;
2200 }
2201 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2202 return 0;
2203 }
mistachkinaae280e2015-12-31 19:06:24 +00002204 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002205 zArg);
2206 return 0;
2207}
2208
2209/*
drh42f64e52012-04-04 16:56:23 +00002210** Close an output file, assuming it is not stderr or stdout
2211*/
2212static void output_file_close(FILE *f){
2213 if( f && f!=stdout && f!=stderr ) fclose(f);
2214}
2215
2216/*
2217** Try to open an output file. The names "stdout" and "stderr" are
2218** recognized and do the right thing. NULL is returned if the output
2219** filename is "off".
2220*/
2221static FILE *output_file_open(const char *zFile){
2222 FILE *f;
2223 if( strcmp(zFile,"stdout")==0 ){
2224 f = stdout;
2225 }else if( strcmp(zFile, "stderr")==0 ){
2226 f = stderr;
2227 }else if( strcmp(zFile, "off")==0 ){
2228 f = 0;
2229 }else{
2230 f = fopen(zFile, "wb");
2231 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002232 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002233 }
2234 }
2235 return f;
2236}
2237
2238/*
2239** A routine for handling output from sqlite3_trace().
2240*/
2241static void sql_trace_callback(void *pArg, const char *z){
2242 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002243 if( f ){
2244 int i = (int)strlen(z);
2245 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002246 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002247 }
drh42f64e52012-04-04 16:56:23 +00002248}
2249
2250/*
drhd8621b92012-04-17 09:09:33 +00002251** A no-op routine that runs with the ".breakpoint" doc-command. This is
2252** a useful spot to set a debugger breakpoint.
2253*/
2254static void test_breakpoint(void){
2255 static int nCall = 0;
2256 nCall++;
2257}
2258
2259/*
mistachkin636bf9f2014-07-19 20:15:16 +00002260** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002261*/
mistachkin636bf9f2014-07-19 20:15:16 +00002262typedef struct ImportCtx ImportCtx;
2263struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002264 const char *zFile; /* Name of the input file */
2265 FILE *in; /* Read the CSV text from this input stream */
2266 char *z; /* Accumulated text for a field */
2267 int n; /* Number of bytes in z */
2268 int nAlloc; /* Space allocated for z[] */
2269 int nLine; /* Current line number */
2270 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002271 int cColSep; /* The column separator character. (Usually ",") */
2272 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002273};
2274
2275/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002276static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002277 if( p->n+1>=p->nAlloc ){
2278 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002279 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002280 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002281 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002282 exit(1);
2283 }
2284 }
2285 p->z[p->n++] = (char)c;
2286}
2287
2288/* Read a single field of CSV text. Compatible with rfc4180 and extended
2289** with the option of having a separator other than ",".
2290**
2291** + Input comes from p->in.
2292** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002293** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002294** + Use p->cSep as the column separator. The default is ",".
2295** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002296** + Keep track of the line number in p->nLine.
2297** + Store the character that terminates the field in p->cTerm. Store
2298** EOF on end-of-file.
2299** + Report syntax errors on stderr
2300*/
mistachkin44723ce2015-03-21 02:22:37 +00002301static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002302 int c;
2303 int cSep = p->cColSep;
2304 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002305 p->n = 0;
2306 c = fgetc(p->in);
2307 if( c==EOF || seenInterrupt ){
2308 p->cTerm = EOF;
2309 return 0;
2310 }
2311 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002312 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002313 int startLine = p->nLine;
2314 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002315 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002316 while( 1 ){
2317 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002318 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002319 if( c==cQuote ){
2320 if( pc==cQuote ){
2321 pc = 0;
2322 continue;
2323 }
2324 }
2325 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002326 || (c==rSep && pc==cQuote)
2327 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002328 || (c==EOF && pc==cQuote)
2329 ){
2330 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002331 p->cTerm = c;
2332 break;
2333 }
2334 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002335 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002336 p->zFile, p->nLine, cQuote);
2337 }
2338 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002339 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002340 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002341 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002342 break;
2343 }
mistachkin636bf9f2014-07-19 20:15:16 +00002344 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002345 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002346 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002347 }
drhdb95f682013-06-26 22:46:00 +00002348 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002349 while( c!=EOF && c!=cSep && c!=rSep ){
2350 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002351 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002352 }
mistachkin636bf9f2014-07-19 20:15:16 +00002353 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002354 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002355 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002356 }
drhdb95f682013-06-26 22:46:00 +00002357 p->cTerm = c;
2358 }
drh8dd675e2013-07-12 21:09:24 +00002359 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002360 return p->z;
2361}
2362
mistachkin636bf9f2014-07-19 20:15:16 +00002363/* Read a single field of ASCII delimited text.
2364**
2365** + Input comes from p->in.
2366** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002367** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002368** + Use p->cSep as the column separator. The default is "\x1F".
2369** + Use p->rSep as the row separator. The default is "\x1E".
2370** + Keep track of the row number in p->nLine.
2371** + Store the character that terminates the field in p->cTerm. Store
2372** EOF on end-of-file.
2373** + Report syntax errors on stderr
2374*/
mistachkin44723ce2015-03-21 02:22:37 +00002375static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002376 int c;
2377 int cSep = p->cColSep;
2378 int rSep = p->cRowSep;
2379 p->n = 0;
2380 c = fgetc(p->in);
2381 if( c==EOF || seenInterrupt ){
2382 p->cTerm = EOF;
2383 return 0;
2384 }
2385 while( c!=EOF && c!=cSep && c!=rSep ){
2386 import_append_char(p, c);
2387 c = fgetc(p->in);
2388 }
2389 if( c==rSep ){
2390 p->nLine++;
2391 }
2392 p->cTerm = c;
2393 if( p->z ) p->z[p->n] = 0;
2394 return p->z;
2395}
2396
drhdb95f682013-06-26 22:46:00 +00002397/*
drh4bbcf102014-02-06 02:46:08 +00002398** Try to transfer data for table zTable. If an error is seen while
2399** moving forward, try to go backwards. The backwards movement won't
2400** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002401*/
mistachkine31ae902014-02-06 01:15:29 +00002402static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002403 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002404 sqlite3 *newDb,
2405 const char *zTable
2406){
2407 sqlite3_stmt *pQuery = 0;
2408 sqlite3_stmt *pInsert = 0;
2409 char *zQuery = 0;
2410 char *zInsert = 0;
2411 int rc;
2412 int i, j, n;
2413 int nTable = (int)strlen(zTable);
2414 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002415 int cnt = 0;
2416 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002417
2418 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2419 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2420 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002421 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002422 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2423 zQuery);
2424 goto end_data_xfer;
2425 }
2426 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002427 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002428 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002429 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002430 goto end_data_xfer;
2431 }
2432 sqlite3_snprintf(200+nTable,zInsert,
2433 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2434 i = (int)strlen(zInsert);
2435 for(j=1; j<n; j++){
2436 memcpy(zInsert+i, ",?", 2);
2437 i += 2;
2438 }
2439 memcpy(zInsert+i, ");", 3);
2440 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2441 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002442 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002443 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2444 zQuery);
2445 goto end_data_xfer;
2446 }
2447 for(k=0; k<2; k++){
2448 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2449 for(i=0; i<n; i++){
2450 switch( sqlite3_column_type(pQuery, i) ){
2451 case SQLITE_NULL: {
2452 sqlite3_bind_null(pInsert, i+1);
2453 break;
2454 }
2455 case SQLITE_INTEGER: {
2456 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2457 break;
2458 }
2459 case SQLITE_FLOAT: {
2460 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2461 break;
2462 }
2463 case SQLITE_TEXT: {
2464 sqlite3_bind_text(pInsert, i+1,
2465 (const char*)sqlite3_column_text(pQuery,i),
2466 -1, SQLITE_STATIC);
2467 break;
2468 }
2469 case SQLITE_BLOB: {
2470 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2471 sqlite3_column_bytes(pQuery,i),
2472 SQLITE_STATIC);
2473 break;
2474 }
2475 }
2476 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002477 rc = sqlite3_step(pInsert);
2478 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002479 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002480 sqlite3_errmsg(newDb));
2481 }
drh3350ce92014-02-06 00:49:12 +00002482 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002483 cnt++;
2484 if( (cnt%spinRate)==0 ){
2485 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2486 fflush(stdout);
2487 }
drh3350ce92014-02-06 00:49:12 +00002488 } /* End while */
2489 if( rc==SQLITE_DONE ) break;
2490 sqlite3_finalize(pQuery);
2491 sqlite3_free(zQuery);
2492 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2493 zTable);
2494 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2495 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002496 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002497 break;
drh3350ce92014-02-06 00:49:12 +00002498 }
2499 } /* End for(k=0...) */
2500
2501end_data_xfer:
2502 sqlite3_finalize(pQuery);
2503 sqlite3_finalize(pInsert);
2504 sqlite3_free(zQuery);
2505 sqlite3_free(zInsert);
2506}
2507
2508
2509/*
2510** Try to transfer all rows of the schema that match zWhere. For
2511** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002512** If an error is encountered while moving forward through the
2513** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002514*/
mistachkine31ae902014-02-06 01:15:29 +00002515static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002516 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002517 sqlite3 *newDb,
2518 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002519 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002520){
2521 sqlite3_stmt *pQuery = 0;
2522 char *zQuery = 0;
2523 int rc;
2524 const unsigned char *zName;
2525 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002526 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002527
2528 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2529 " WHERE %s", zWhere);
2530 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2531 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002532 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002533 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2534 zQuery);
2535 goto end_schema_xfer;
2536 }
2537 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2538 zName = sqlite3_column_text(pQuery, 0);
2539 zSql = sqlite3_column_text(pQuery, 1);
2540 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002541 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2542 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002543 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002544 sqlite3_free(zErrMsg);
2545 zErrMsg = 0;
2546 }
drh3350ce92014-02-06 00:49:12 +00002547 if( xForEach ){
2548 xForEach(p, newDb, (const char*)zName);
2549 }
2550 printf("done\n");
2551 }
2552 if( rc!=SQLITE_DONE ){
2553 sqlite3_finalize(pQuery);
2554 sqlite3_free(zQuery);
2555 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2556 " WHERE %s ORDER BY rowid DESC", zWhere);
2557 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2558 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002559 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002560 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2561 zQuery);
2562 goto end_schema_xfer;
2563 }
2564 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2565 zName = sqlite3_column_text(pQuery, 0);
2566 zSql = sqlite3_column_text(pQuery, 1);
2567 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002568 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2569 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002570 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002571 sqlite3_free(zErrMsg);
2572 zErrMsg = 0;
2573 }
drh3350ce92014-02-06 00:49:12 +00002574 if( xForEach ){
2575 xForEach(p, newDb, (const char*)zName);
2576 }
2577 printf("done\n");
2578 }
2579 }
2580end_schema_xfer:
2581 sqlite3_finalize(pQuery);
2582 sqlite3_free(zQuery);
2583}
2584
2585/*
2586** Open a new database file named "zNewDb". Try to recover as much information
2587** as possible out of the main database (which might be corrupt) and write it
2588** into zNewDb.
2589*/
drhdcd87a92014-08-18 13:45:42 +00002590static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002591 int rc;
2592 sqlite3 *newDb = 0;
2593 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002594 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002595 return;
2596 }
2597 rc = sqlite3_open(zNewDb, &newDb);
2598 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002599 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002600 sqlite3_errmsg(newDb));
2601 }else{
drh54d0d2d2014-04-03 00:32:13 +00002602 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002603 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002604 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2605 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002606 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002607 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002608 }
2609 sqlite3_close(newDb);
2610}
2611
2612/*
drhc2ce0be2014-05-29 12:36:14 +00002613** Change the output file back to stdout
2614*/
drhdcd87a92014-08-18 13:45:42 +00002615static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002616 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002617#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002618 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002619#endif
drhc2ce0be2014-05-29 12:36:14 +00002620 }else{
2621 output_file_close(p->out);
2622 }
2623 p->outfile[0] = 0;
2624 p->out = stdout;
2625}
2626
2627/*
drhf7502f02015-02-06 14:19:44 +00002628** Run an SQL command and return the single integer result.
2629*/
2630static int db_int(ShellState *p, const char *zSql){
2631 sqlite3_stmt *pStmt;
2632 int res = 0;
2633 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2634 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2635 res = sqlite3_column_int(pStmt,0);
2636 }
2637 sqlite3_finalize(pStmt);
2638 return res;
2639}
2640
2641/*
2642** Convert a 2-byte or 4-byte big-endian integer into a native integer
2643*/
2644unsigned int get2byteInt(unsigned char *a){
2645 return (a[0]<<8) + a[1];
2646}
2647unsigned int get4byteInt(unsigned char *a){
2648 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2649}
2650
2651/*
2652** Implementation of the ".info" command.
2653**
2654** Return 1 on error, 2 to exit, and 0 otherwise.
2655*/
drh0e55db12015-02-06 14:51:13 +00002656static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002657 static const struct { const char *zName; int ofst; } aField[] = {
2658 { "file change counter:", 24 },
2659 { "database page count:", 28 },
2660 { "freelist page count:", 36 },
2661 { "schema cookie:", 40 },
2662 { "schema format:", 44 },
2663 { "default cache size:", 48 },
2664 { "autovacuum top root:", 52 },
2665 { "incremental vacuum:", 64 },
2666 { "text encoding:", 56 },
2667 { "user version:", 60 },
2668 { "application id:", 68 },
2669 { "software version:", 96 },
2670 };
drh0e55db12015-02-06 14:51:13 +00002671 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2672 { "number of tables:",
2673 "SELECT count(*) FROM %s WHERE type='table'" },
2674 { "number of indexes:",
2675 "SELECT count(*) FROM %s WHERE type='index'" },
2676 { "number of triggers:",
2677 "SELECT count(*) FROM %s WHERE type='trigger'" },
2678 { "number of views:",
2679 "SELECT count(*) FROM %s WHERE type='view'" },
2680 { "schema size:",
2681 "SELECT total(length(sql)) FROM %s" },
2682 };
mistachkinbfe8bd52015-11-17 19:17:14 +00002683 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00002684 int i;
2685 char *zSchemaTab;
2686 char *zDb = nArg>=2 ? azArg[1] : "main";
2687 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002688 open_db(p, 0);
2689 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002690 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002691 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2692 return 1;
2693 }
2694 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2695 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00002696 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00002697 return 1;
2698 }
2699 i = get2byteInt(aHdr+16);
2700 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00002701 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
2702 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2703 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2704 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00002705 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00002706 int ofst = aField[i].ofst;
2707 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00002708 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00002709 switch( ofst ){
2710 case 56: {
mistachkinaae280e2015-12-31 19:06:24 +00002711 if( val==1 ) raw_printf(p->out, " (utf8)");
2712 if( val==2 ) raw_printf(p->out, " (utf16le)");
2713 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00002714 }
2715 }
mistachkinaae280e2015-12-31 19:06:24 +00002716 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00002717 }
drh0e55db12015-02-06 14:51:13 +00002718 if( zDb==0 ){
2719 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2720 }else if( strcmp(zDb,"temp")==0 ){
2721 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2722 }else{
2723 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2724 }
drhf5ed7ad2015-06-15 14:43:25 +00002725 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00002726 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2727 int val = db_int(p, zSql);
2728 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00002729 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00002730 }
2731 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002732 return 0;
2733}
2734
dand95bb392015-09-30 11:19:05 +00002735/*
2736** Print the current sqlite3_errmsg() value to stderr and return 1.
2737*/
2738static int shellDatabaseError(sqlite3 *db){
2739 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00002740 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00002741 return 1;
2742}
2743
2744/*
2745** Print an out-of-memory message to stderr and return 1.
2746*/
2747static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00002748 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00002749 return 1;
2750}
drhf7502f02015-02-06 14:19:44 +00002751
2752/*
drh75897232000-05-29 14:26:00 +00002753** If an input line begins with "." then invoke this routine to
2754** process that line.
drh67505e72002-04-19 12:34:06 +00002755**
drh47ad6842006-11-08 12:25:42 +00002756** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002757*/
drhdcd87a92014-08-18 13:45:42 +00002758static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00002759 int h = 1;
drh75897232000-05-29 14:26:00 +00002760 int nArg = 0;
2761 int n, c;
drh67505e72002-04-19 12:34:06 +00002762 int rc = 0;
drh75897232000-05-29 14:26:00 +00002763 char *azArg[50];
2764
2765 /* Parse the input line into tokens.
2766 */
mistachkin8e189222015-04-19 21:43:16 +00002767 while( zLine[h] && nArg<ArraySize(azArg) ){
2768 while( IsSpace(zLine[h]) ){ h++; }
2769 if( zLine[h]==0 ) break;
2770 if( zLine[h]=='\'' || zLine[h]=='"' ){
2771 int delim = zLine[h++];
2772 azArg[nArg++] = &zLine[h];
2773 while( zLine[h] && zLine[h]!=delim ){
2774 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
2775 h++;
drh4c56b992013-06-27 13:26:55 +00002776 }
mistachkin8e189222015-04-19 21:43:16 +00002777 if( zLine[h]==delim ){
2778 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00002779 }
drhfeac5f82004-08-01 00:10:45 +00002780 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002781 }else{
mistachkin8e189222015-04-19 21:43:16 +00002782 azArg[nArg++] = &zLine[h];
2783 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
2784 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002785 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002786 }
2787 }
2788
2789 /* Process the input line.
2790 */
shane9bd1b442009-10-23 01:27:39 +00002791 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002792 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002793 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002794 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2795 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2796 ){
drhbc46f022013-01-23 18:53:23 +00002797 const char *zDestFile = 0;
2798 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002799 sqlite3 *pDest;
2800 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002801 int j;
2802 for(j=1; j<nArg; j++){
2803 const char *z = azArg[j];
2804 if( z[0]=='-' ){
2805 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002806 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002807 {
mistachkinaae280e2015-12-31 19:06:24 +00002808 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00002809 return 1;
2810 }
2811 }else if( zDestFile==0 ){
2812 zDestFile = azArg[j];
2813 }else if( zDb==0 ){
2814 zDb = zDestFile;
2815 zDestFile = azArg[j];
2816 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002817 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00002818 return 1;
2819 }
drh9ff849f2009-02-04 20:55:57 +00002820 }
drhbc46f022013-01-23 18:53:23 +00002821 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002822 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00002823 return 1;
2824 }
2825 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002826 rc = sqlite3_open(zDestFile, &pDest);
2827 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00002828 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002829 sqlite3_close(pDest);
2830 return 1;
2831 }
drh05782482013-10-24 15:20:20 +00002832 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002833 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2834 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002835 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00002836 sqlite3_close(pDest);
2837 return 1;
2838 }
2839 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2840 sqlite3_backup_finish(pBackup);
2841 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002842 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002843 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002844 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002845 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002846 }
2847 sqlite3_close(pDest);
2848 }else
2849
drhc2ce0be2014-05-29 12:36:14 +00002850 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2851 if( nArg==2 ){
2852 bail_on_error = booleanValue(azArg[1]);
2853 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002854 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00002855 rc = 1;
2856 }
drhc49f44e2006-10-26 18:15:42 +00002857 }else
2858
mistachkinf21979d2015-01-18 05:35:01 +00002859 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
2860 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00002861 if( booleanValue(azArg[1]) ){
2862 setBinaryMode(p->out);
2863 }else{
2864 setTextMode(p->out);
2865 }
mistachkinf21979d2015-01-18 05:35:01 +00002866 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002867 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00002868 rc = 1;
2869 }
2870 }else
2871
drhd8621b92012-04-17 09:09:33 +00002872 /* The undocumented ".breakpoint" command causes a call to the no-op
2873 ** routine named test_breakpoint().
2874 */
2875 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2876 test_breakpoint();
2877 }else
2878
drhdf12f1c2015-12-07 21:46:19 +00002879 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
2880 if( nArg==2 ){
2881 p->countChanges = booleanValue(azArg[1]);
2882 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002883 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00002884 rc = 1;
2885 }
2886 }else
2887
drhc2ce0be2014-05-29 12:36:14 +00002888 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2889 if( nArg==2 ){
2890 tryToClone(p, azArg[1]);
2891 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002892 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00002893 rc = 1;
2894 }
mistachkine31ae902014-02-06 01:15:29 +00002895 }else
2896
drhc2ce0be2014-05-29 12:36:14 +00002897 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002898 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002899 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002900 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002901 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002902 data.showHeader = 1;
drh700c2522016-02-09 18:39:25 +00002903 data.cMode = data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002904 data.colWidth[0] = 3;
2905 data.colWidth[1] = 15;
2906 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002907 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002908 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002909 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002910 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002911 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002912 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002913 }
2914 }else
2915
drh0e55db12015-02-06 14:51:13 +00002916 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2917 rc = shell_dbinfo_command(p, nArg, azArg);
2918 }else
2919
drhc2ce0be2014-05-29 12:36:14 +00002920 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002921 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002922 /* When playing back a "dump", the content might appear in an order
2923 ** which causes immediate foreign key constraints to be violated.
2924 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002925 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00002926 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00002927 rc = 1;
2928 goto meta_command_exit;
2929 }
mistachkinaae280e2015-12-31 19:06:24 +00002930 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
2931 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002932 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002933 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002934 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002935 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002936 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002937 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002938 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002939 );
2940 run_schema_dump_query(p,
2941 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002942 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002943 );
drh2f464a02011-10-13 00:41:49 +00002944 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002945 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002946 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002947 );
drh4c653a02000-06-07 01:27:47 +00002948 }else{
2949 int i;
drhdd3d4592004-08-30 01:54:05 +00002950 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002951 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002952 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002953 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002954 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002955 " AND sql NOT NULL");
2956 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002957 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002958 "WHERE sql NOT NULL"
2959 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002960 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002961 );
danielk1977bc6ada42004-06-30 08:20:16 +00002962 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002963 }
2964 }
drh45e29d82006-11-20 16:21:10 +00002965 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00002966 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002967 p->writableSchema = 0;
2968 }
drh56197952011-10-13 16:30:13 +00002969 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2970 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00002971 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002972 }else
drh75897232000-05-29 14:26:00 +00002973
drhc2ce0be2014-05-29 12:36:14 +00002974 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2975 if( nArg==2 ){
2976 p->echoOn = booleanValue(azArg[1]);
2977 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002978 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00002979 rc = 1;
2980 }
drhdaffd0e2001-04-11 14:28:42 +00002981 }else
2982
drhc2ce0be2014-05-29 12:36:14 +00002983 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2984 if( nArg==2 ){
2985 p->autoEQP = booleanValue(azArg[1]);
2986 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002987 raw_printf(stderr, "Usage: .eqp on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00002988 rc = 1;
2989 }
drhefbf3b12014-02-28 20:47:24 +00002990 }else
2991
drhd3ac7d92013-01-25 18:33:43 +00002992 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002993 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002994 rc = 2;
drh75897232000-05-29 14:26:00 +00002995 }else
2996
drhc2ce0be2014-05-29 12:36:14 +00002997 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00002998 int val = 1;
2999 if( nArg>=2 ){
3000 if( strcmp(azArg[1],"auto")==0 ){
3001 val = 99;
3002 }else{
3003 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003004 }
drh700c2522016-02-09 18:39:25 +00003005 }
3006 if( val==1 && p->mode!=MODE_Explain ){
3007 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003008 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003009 p->autoExplain = 0;
3010 }else if( val==0 ){
3011 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3012 p->autoExplain = 0;
3013 }else if( val==99 ){
3014 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3015 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003016 }
drh75897232000-05-29 14:26:00 +00003017 }else
3018
drhc1971542014-06-23 23:28:13 +00003019 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003020 ShellState data;
drhc1971542014-06-23 23:28:13 +00003021 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003022 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00003023 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003024 raw_printf(stderr, "Usage: .fullschema\n");
drhc1971542014-06-23 23:28:13 +00003025 rc = 1;
3026 goto meta_command_exit;
3027 }
3028 open_db(p, 0);
3029 memcpy(&data, p, sizeof(data));
3030 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003031 data.cMode = data.mode = MODE_Semi;
drhc1971542014-06-23 23:28:13 +00003032 rc = sqlite3_exec(p->db,
3033 "SELECT sql FROM"
3034 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3035 " FROM sqlite_master UNION ALL"
3036 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003037 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003038 "ORDER BY rowid",
3039 callback, &data, &zErrMsg
3040 );
drh56f674c2014-07-18 14:43:29 +00003041 if( rc==SQLITE_OK ){
3042 sqlite3_stmt *pStmt;
3043 rc = sqlite3_prepare_v2(p->db,
3044 "SELECT rowid FROM sqlite_master"
3045 " WHERE name GLOB 'sqlite_stat[134]'",
3046 -1, &pStmt, 0);
3047 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3048 sqlite3_finalize(pStmt);
3049 }
3050 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003051 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003052 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003053 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003054 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3055 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003056 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003057 data.zDestTable = "sqlite_stat1";
3058 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3059 shell_callback, &data,&zErrMsg);
3060 data.zDestTable = "sqlite_stat3";
3061 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3062 shell_callback, &data,&zErrMsg);
3063 data.zDestTable = "sqlite_stat4";
3064 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3065 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003066 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003067 }
drhc1971542014-06-23 23:28:13 +00003068 }else
3069
drhc2ce0be2014-05-29 12:36:14 +00003070 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3071 if( nArg==2 ){
3072 p->showHeader = booleanValue(azArg[1]);
3073 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003074 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003075 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003076 }
drh75897232000-05-29 14:26:00 +00003077 }else
3078
drhc2ce0be2014-05-29 12:36:14 +00003079 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003080 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003081 }else
3082
3083 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003084 char *zTable; /* Insert data into this table */
3085 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003086 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003087 int nCol; /* Number of columns in the table */
3088 int nByte; /* Number of bytes in an SQL string */
3089 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003090 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003091 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003092 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003093 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003094 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3095 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003096
drhc2ce0be2014-05-29 12:36:14 +00003097 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003098 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003099 goto meta_command_exit;
3100 }
drh01f37542014-05-31 15:43:33 +00003101 zFile = azArg[1];
3102 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003103 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003104 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003105 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003106 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003107 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003108 raw_printf(stderr,
3109 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003110 return 1;
drhfeac5f82004-08-01 00:10:45 +00003111 }
drhdb95f682013-06-26 22:46:00 +00003112 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003113 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003114 " for import\n");
3115 return 1;
3116 }
mistachkin636bf9f2014-07-19 20:15:16 +00003117 nSep = strlen30(p->rowSeparator);
3118 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003119 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003120 return 1;
3121 }
mistachkine0d68852014-12-11 03:12:33 +00003122 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3123 /* When importing CSV (only), if the row separator is set to the
3124 ** default output row separator, change it to the default input
3125 ** row separator. This avoids having to maintain different input
3126 ** and output row separators. */
3127 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3128 nSep = strlen30(p->rowSeparator);
3129 }
mistachkin636bf9f2014-07-19 20:15:16 +00003130 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003131 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003132 " for import\n");
3133 return 1;
3134 }
3135 sCtx.zFile = zFile;
3136 sCtx.nLine = 1;
3137 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003138#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003139 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003140 return 1;
3141#else
mistachkin636bf9f2014-07-19 20:15:16 +00003142 sCtx.in = popen(sCtx.zFile+1, "r");
3143 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003144 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003145#endif
drh5bde8162013-06-27 14:07:53 +00003146 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003147 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003148 xCloser = fclose;
3149 }
mistachkin636bf9f2014-07-19 20:15:16 +00003150 if( p->mode==MODE_Ascii ){
3151 xRead = ascii_read_one_field;
3152 }else{
3153 xRead = csv_read_one_field;
3154 }
3155 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003156 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003157 return 1;
3158 }
mistachkin636bf9f2014-07-19 20:15:16 +00003159 sCtx.cColSep = p->colSeparator[0];
3160 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003161 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003162 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003163 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003164 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003165 return 1;
3166 }
drh4f21c4a2008-12-10 22:15:00 +00003167 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003168 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003169 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003170 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003171 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3172 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003173 while( xRead(&sCtx) ){
3174 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003175 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003176 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003177 }
drh5bde8162013-06-27 14:07:53 +00003178 if( cSep=='(' ){
3179 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003180 sqlite3_free(sCtx.z);
3181 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003182 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003183 return 1;
3184 }
drhdb95f682013-06-26 22:46:00 +00003185 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3186 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3187 sqlite3_free(zCreate);
3188 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003189 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003190 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003191 sqlite3_free(sCtx.z);
3192 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003193 return 1;
3194 }
drhc7181902014-02-27 15:04:13 +00003195 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003196 }
drhfeac5f82004-08-01 00:10:45 +00003197 sqlite3_free(zSql);
3198 if( rc ){
shane916f9612009-10-23 00:37:15 +00003199 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00003200 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003201 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003202 return 1;
drhfeac5f82004-08-01 00:10:45 +00003203 }
shane916f9612009-10-23 00:37:15 +00003204 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003205 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003206 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003207 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003208 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003209 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003210 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003211 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003212 return 1;
3213 }
drhdb95f682013-06-26 22:46:00 +00003214 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003215 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003216 for(i=1; i<nCol; i++){
3217 zSql[j++] = ',';
3218 zSql[j++] = '?';
3219 }
3220 zSql[j++] = ')';
3221 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003222 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003223 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003224 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003225 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003226 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003227 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003228 return 1;
drhfeac5f82004-08-01 00:10:45 +00003229 }
mistachkin8e189222015-04-19 21:43:16 +00003230 needCommit = sqlite3_get_autocommit(p->db);
3231 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003232 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003233 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003234 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003235 char *z = xRead(&sCtx);
3236 /*
3237 ** Did we reach end-of-file before finding any columns?
3238 ** If so, stop instead of NULL filling the remaining columns.
3239 */
drhdb95f682013-06-26 22:46:00 +00003240 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003241 /*
3242 ** Did we reach end-of-file OR end-of-line before finding any
3243 ** columns in ASCII mode? If so, stop instead of NULL filling
3244 ** the remaining columns.
3245 */
3246 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003247 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003248 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00003249 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003250 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003251 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003252 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003253 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003254 }
drhfeac5f82004-08-01 00:10:45 +00003255 }
mistachkin636bf9f2014-07-19 20:15:16 +00003256 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003257 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003258 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003259 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003260 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00003261 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003262 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003263 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003264 }
drhdb95f682013-06-26 22:46:00 +00003265 if( i>=nCol ){
3266 sqlite3_step(pStmt);
3267 rc = sqlite3_reset(pStmt);
3268 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003269 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
3270 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003271 }
3272 }
mistachkin636bf9f2014-07-19 20:15:16 +00003273 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003274
mistachkin636bf9f2014-07-19 20:15:16 +00003275 xCloser(sCtx.in);
3276 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003277 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003278 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003279 }else
3280
drh0e55db12015-02-06 14:51:13 +00003281 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3282 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003283 ShellState data;
drh75897232000-05-29 14:26:00 +00003284 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003285 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003286 memcpy(&data, p, sizeof(data));
3287 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003288 data.cMode = data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003289 if( nArg==1 ){
3290 rc = sqlite3_exec(p->db,
3291 "SELECT name FROM sqlite_master "
3292 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3293 "UNION ALL "
3294 "SELECT name FROM sqlite_temp_master "
3295 "WHERE type='index' "
3296 "ORDER BY 1",
3297 callback, &data, &zErrMsg
3298 );
drhc2ce0be2014-05-29 12:36:14 +00003299 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003300 zShellStatic = azArg[1];
3301 rc = sqlite3_exec(p->db,
3302 "SELECT name FROM sqlite_master "
3303 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3304 "UNION ALL "
3305 "SELECT name FROM sqlite_temp_master "
3306 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3307 "ORDER BY 1",
3308 callback, &data, &zErrMsg
3309 );
3310 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003311 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003312 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003313 rc = 1;
3314 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003315 }
drh75897232000-05-29 14:26:00 +00003316 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003317 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003318 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003319 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003320 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003321 raw_printf(stderr,
3322 "Error: querying sqlite_master and sqlite_temp_master\n");
shane86f5bdb2009-10-24 02:00:07 +00003323 rc = 1;
drh75897232000-05-29 14:26:00 +00003324 }
3325 }else
3326
drhae5e4452007-05-03 17:18:36 +00003327#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003328 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003329 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003330 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3331 iotrace = 0;
3332 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003333 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003334 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003335 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003336 iotrace = stdout;
3337 }else{
3338 iotrace = fopen(azArg[1], "w");
3339 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003340 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003341 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003342 rc = 1;
drhb0603412007-02-28 04:47:26 +00003343 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003344 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003345 }
3346 }
3347 }else
drhae5e4452007-05-03 17:18:36 +00003348#endif
drh1a513372015-05-02 17:40:23 +00003349 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3350 static const struct {
3351 const char *zLimitName; /* Name of a limit */
3352 int limitCode; /* Integer code for that limit */
3353 } aLimit[] = {
3354 { "length", SQLITE_LIMIT_LENGTH },
3355 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3356 { "column", SQLITE_LIMIT_COLUMN },
3357 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3358 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3359 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3360 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3361 { "attached", SQLITE_LIMIT_ATTACHED },
3362 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3363 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3364 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3365 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3366 };
3367 int i, n2;
3368 open_db(p, 0);
3369 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003370 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003371 printf("%20s %d\n", aLimit[i].zLimitName,
3372 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3373 }
3374 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003375 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00003376 rc = 1;
3377 goto meta_command_exit;
3378 }else{
3379 int iLimit = -1;
3380 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003381 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003382 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3383 if( iLimit<0 ){
3384 iLimit = i;
3385 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003386 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00003387 rc = 1;
3388 goto meta_command_exit;
3389 }
3390 }
3391 }
3392 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003393 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00003394 "enter \".limits\" with no arguments for a list.\n",
3395 azArg[1]);
3396 rc = 1;
3397 goto meta_command_exit;
3398 }
3399 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003400 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3401 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003402 }
3403 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3404 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3405 }
3406 }else
drhb0603412007-02-28 04:47:26 +00003407
drh70df4fe2006-06-13 15:12:21 +00003408#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003409 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003410 const char *zFile, *zProc;
3411 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003412 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003413 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00003414 rc = 1;
3415 goto meta_command_exit;
3416 }
drh1e397f82006-06-08 15:28:43 +00003417 zFile = azArg[1];
3418 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003419 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003420 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3421 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003422 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003423 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003424 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003425 }
3426 }else
drh70df4fe2006-06-13 15:12:21 +00003427#endif
drh1e397f82006-06-08 15:28:43 +00003428
drhc2ce0be2014-05-29 12:36:14 +00003429 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3430 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003431 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003432 rc = 1;
3433 }else{
3434 const char *zFile = azArg[1];
3435 output_file_close(p->pLog);
3436 p->pLog = output_file_open(zFile);
3437 }
drh127f9d72010-02-23 01:47:00 +00003438 }else
3439
drhc2ce0be2014-05-29 12:36:14 +00003440 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3441 const char *zMode = nArg>=2 ? azArg[1] : "";
3442 int n2 = (int)strlen(zMode);
3443 int c2 = zMode[0];
3444 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003445 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003446 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003447 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003448 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003449 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003450 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003451 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003452 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003453 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003454 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003455 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003456 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003457 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003458 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003459 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003460 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003461 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003462 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003463 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003464 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003465 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3466 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003467 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3468 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003469 }else {
mistachkinaae280e2015-12-31 19:06:24 +00003470 raw_printf(stderr, "Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003471 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003472 rc = 1;
drh75897232000-05-29 14:26:00 +00003473 }
drh700c2522016-02-09 18:39:25 +00003474 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00003475 }else
3476
drhc2ce0be2014-05-29 12:36:14 +00003477 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3478 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003479 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3480 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003481 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003482 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003483 rc = 1;
3484 }
3485 }else
3486
drh05782482013-10-24 15:20:20 +00003487 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3488 sqlite3 *savedDb = p->db;
3489 const char *zSavedFilename = p->zDbFilename;
3490 char *zNewFilename = 0;
3491 p->db = 0;
drhbbe031f2015-06-17 17:08:22 +00003492 if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3493 p->zDbFilename = zNewFilename;
drh05782482013-10-24 15:20:20 +00003494 open_db(p, 1);
3495 if( p->db!=0 ){
3496 sqlite3_close(savedDb);
3497 sqlite3_free(p->zFreeOnClose);
3498 p->zFreeOnClose = zNewFilename;
3499 }else{
3500 sqlite3_free(zNewFilename);
3501 p->db = savedDb;
3502 p->zDbFilename = zSavedFilename;
3503 }
3504 }else
3505
drhc2ce0be2014-05-29 12:36:14 +00003506 if( c=='o'
3507 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3508 ){
3509 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3510 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003511 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00003512 rc = 1;
3513 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003514 }
drhc2ce0be2014-05-29 12:36:14 +00003515 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3516 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003517 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003518 rc = 1;
3519 goto meta_command_exit;
3520 }
3521 p->outCount = 2;
3522 }else{
3523 p->outCount = 0;
3524 }
3525 output_reset(p);
3526 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003527#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003528 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003529 rc = 1;
3530 p->out = stdout;
3531#else
drhc2ce0be2014-05-29 12:36:14 +00003532 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003533 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003534 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003535 p->out = stdout;
3536 rc = 1;
3537 }else{
drhc2ce0be2014-05-29 12:36:14 +00003538 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003539 }
drh8cd5b252015-03-02 22:06:43 +00003540#endif
drh75897232000-05-29 14:26:00 +00003541 }else{
drhc2ce0be2014-05-29 12:36:14 +00003542 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003543 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003544 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003545 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003546 }
drh75897232000-05-29 14:26:00 +00003547 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003548 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003549 } else {
drhc2ce0be2014-05-29 12:36:14 +00003550 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003551 }
3552 }
3553 }else
3554
drh078b1fd2012-09-21 13:40:02 +00003555 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3556 int i;
3557 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00003558 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00003559 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00003560 }
mistachkinaae280e2015-12-31 19:06:24 +00003561 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00003562 }else
3563
drhc2ce0be2014-05-29 12:36:14 +00003564 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003565 if( nArg >= 2) {
3566 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3567 }
3568 if( nArg >= 3) {
3569 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3570 }
3571 }else
3572
drhc2ce0be2014-05-29 12:36:14 +00003573 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003574 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003575 }else
3576
drhc2ce0be2014-05-29 12:36:14 +00003577 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3578 FILE *alt;
3579 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003580 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003581 rc = 1;
3582 goto meta_command_exit;
3583 }
3584 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003585 if( alt==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003586 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
shane9bd1b442009-10-23 01:27:39 +00003587 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003588 }else{
shane9bd1b442009-10-23 01:27:39 +00003589 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003590 fclose(alt);
3591 }
3592 }else
3593
drhc2ce0be2014-05-29 12:36:14 +00003594 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003595 const char *zSrcFile;
3596 const char *zDb;
3597 sqlite3 *pSrc;
3598 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003599 int nTimeout = 0;
3600
drh9ff849f2009-02-04 20:55:57 +00003601 if( nArg==2 ){
3602 zSrcFile = azArg[1];
3603 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003604 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003605 zSrcFile = azArg[2];
3606 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003607 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003608 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003609 rc = 1;
3610 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003611 }
3612 rc = sqlite3_open(zSrcFile, &pSrc);
3613 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003614 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003615 sqlite3_close(pSrc);
3616 return 1;
3617 }
drh05782482013-10-24 15:20:20 +00003618 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003619 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3620 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003621 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00003622 sqlite3_close(pSrc);
3623 return 1;
3624 }
drhdc2c4912009-02-04 22:46:47 +00003625 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3626 || rc==SQLITE_BUSY ){
3627 if( rc==SQLITE_BUSY ){
3628 if( nTimeout++ >= 3 ) break;
3629 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003630 }
3631 }
3632 sqlite3_backup_finish(pBackup);
3633 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003634 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003635 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00003636 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00003637 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003638 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003639 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003640 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003641 }
3642 sqlite3_close(pSrc);
3643 }else
3644
dan8d1edb92014-11-05 09:07:28 +00003645
3646 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3647 if( nArg==2 ){
3648 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003649#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00003650 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00003651#endif
dan8d1edb92014-11-05 09:07:28 +00003652 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003653 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00003654 rc = 1;
3655 }
3656 }else
3657
drhc2ce0be2014-05-29 12:36:14 +00003658 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003659 ShellState data;
drh75897232000-05-29 14:26:00 +00003660 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003661 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003662 memcpy(&data, p, sizeof(data));
3663 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003664 data.cMode = data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003665 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003666 int i;
drhf0693c82011-10-11 20:41:54 +00003667 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003668 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003669 char *new_argv[2], *new_colv[2];
3670 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3671 " type text,\n"
3672 " name text,\n"
3673 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003674 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003675 " sql text\n"
3676 ")";
3677 new_argv[1] = 0;
3678 new_colv[0] = "sql";
3679 new_colv[1] = 0;
3680 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003681 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003682 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003683 char *new_argv[2], *new_colv[2];
3684 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3685 " type text,\n"
3686 " name text,\n"
3687 " tbl_name text,\n"
3688 " rootpage integer,\n"
3689 " sql text\n"
3690 ")";
3691 new_argv[1] = 0;
3692 new_colv[0] = "sql";
3693 new_colv[1] = 0;
3694 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003695 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003696 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003697 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003698 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003699 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003700 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003701 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003702 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003703 "WHERE lower(tbl_name) LIKE shellstatic()"
3704 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003705 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003706 callback, &data, &zErrMsg);
3707 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003708 }
drhc2ce0be2014-05-29 12:36:14 +00003709 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003710 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003711 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003712 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003713 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003714 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003715 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003716 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003717 callback, &data, &zErrMsg
3718 );
drhc2ce0be2014-05-29 12:36:14 +00003719 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003720 raw_printf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003721 rc = 1;
3722 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003723 }
drh75897232000-05-29 14:26:00 +00003724 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003725 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003726 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003727 rc = 1;
3728 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003729 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00003730 rc = 1;
3731 }else{
3732 rc = 0;
drh75897232000-05-29 14:26:00 +00003733 }
3734 }else
3735
drhabd4c722014-09-20 18:18:33 +00003736
3737#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3738 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3739 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003740 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003741 }else
3742#endif
3743
3744
drh340f5822013-06-27 13:01:21 +00003745#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003746 /* Undocumented commands for internal testing. Subject to change
3747 ** without notice. */
3748 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3749 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3750 int i, v;
3751 for(i=1; i<nArg; i++){
3752 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00003753 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00003754 }
3755 }
3756 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3757 int i; sqlite3_int64 v;
3758 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003759 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003760 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003761 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00003762 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003763 }
3764 }
3765 }else
drh340f5822013-06-27 13:01:21 +00003766#endif
drh348d19c2013-06-03 12:47:43 +00003767
drhc2ce0be2014-05-29 12:36:14 +00003768 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003769 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003770 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003771 rc = 1;
3772 }
drh6976c212014-07-24 12:09:47 +00003773 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003774 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003775 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003776 }
3777 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003778 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3779 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003780 }
drh75897232000-05-29 14:26:00 +00003781 }else
3782
drh62cdde52014-05-28 20:22:28 +00003783 if( c=='s'
3784 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003785 ){
3786 char *zCmd;
drh54027102014-08-06 14:36:53 +00003787 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003788 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003789 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00003790 rc = 1;
3791 goto meta_command_exit;
3792 }
drhdcb3e3d2014-05-29 03:17:29 +00003793 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003794 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003795 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3796 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003797 }
drh54027102014-08-06 14:36:53 +00003798 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003799 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00003800 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003801 }else
3802
drhc2ce0be2014-05-29 12:36:14 +00003803 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003804 int i;
drhc2ce0be2014-05-29 12:36:14 +00003805 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003806 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00003807 rc = 1;
3808 goto meta_command_exit;
3809 }
mistachkinaae280e2015-12-31 19:06:24 +00003810 utf8_printf(p->out, "%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3811 utf8_printf(p->out, "%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drh700c2522016-02-09 18:39:25 +00003812 utf8_printf(p->out, "%12.12s: %s\n","explain",
3813 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
mistachkinaae280e2015-12-31 19:06:24 +00003814 utf8_printf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3815 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
3816 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003817 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00003818 raw_printf(p->out, "\n");
3819 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003820 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00003821 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00003822 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00003823 raw_printf(p->out, "\n");
3824 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00003825 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00003826 raw_printf(p->out, "\n");
3827 utf8_printf(p->out, "%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3828 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00003829 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00003830 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003831 }
mistachkinaae280e2015-12-31 19:06:24 +00003832 raw_printf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003833 }else
3834
drhc2ce0be2014-05-29 12:36:14 +00003835 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3836 if( nArg==2 ){
3837 p->statsOn = booleanValue(azArg[1]);
3838 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003839 raw_printf(stderr, "Usage: .stats on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003840 rc = 1;
3841 }
shaneh642d8b82010-07-28 16:05:34 +00003842 }else
3843
drhc2ce0be2014-05-29 12:36:14 +00003844 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003845 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003846 char **azResult;
drh98781232012-04-23 12:38:05 +00003847 int nRow, nAlloc;
3848 char *zSql = 0;
3849 int ii;
drh05782482013-10-24 15:20:20 +00003850 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003851 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00003852 if( rc ) return shellDatabaseError(p->db);
3853
3854 /* Create an SQL statement to query for the list of tables in the
3855 ** main and all attached databases where the table name matches the
3856 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00003857 zSql = sqlite3_mprintf(
3858 "SELECT name FROM sqlite_master"
3859 " WHERE type IN ('table','view')"
3860 " AND name NOT LIKE 'sqlite_%%'"
3861 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00003862 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00003863 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3864 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3865 if( strcmp(zDbName,"temp")==0 ){
3866 zSql = sqlite3_mprintf(
3867 "%z UNION ALL "
3868 "SELECT 'temp.' || name FROM sqlite_temp_master"
3869 " WHERE type IN ('table','view')"
3870 " AND name NOT LIKE 'sqlite_%%'"
3871 " AND name LIKE ?1", zSql);
3872 }else{
3873 zSql = sqlite3_mprintf(
3874 "%z UNION ALL "
3875 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3876 " WHERE type IN ('table','view')"
3877 " AND name NOT LIKE 'sqlite_%%'"
3878 " AND name LIKE ?1", zSql, zDbName, zDbName);
3879 }
drha50da102000-08-08 20:19:09 +00003880 }
dand95bb392015-09-30 11:19:05 +00003881 rc = sqlite3_finalize(pStmt);
3882 if( zSql && rc==SQLITE_OK ){
3883 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3884 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3885 }
drh98781232012-04-23 12:38:05 +00003886 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00003887 if( !zSql ) return shellNomemError();
3888 if( rc ) return shellDatabaseError(p->db);
3889
3890 /* Run the SQL statement prepared by the above block. Store the results
3891 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00003892 nRow = nAlloc = 0;
3893 azResult = 0;
3894 if( nArg>1 ){
3895 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003896 }else{
drh98781232012-04-23 12:38:05 +00003897 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3898 }
3899 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3900 if( nRow>=nAlloc ){
3901 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00003902 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00003903 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00003904 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00003905 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00003906 break;
3907 }
mistachkin8e189222015-04-19 21:43:16 +00003908 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00003909 azResult = azNew;
3910 }
3911 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00003912 if( 0==azResult[nRow] ){
3913 rc = shellNomemError();
3914 break;
3915 }
3916 nRow++;
drh98781232012-04-23 12:38:05 +00003917 }
dand95bb392015-09-30 11:19:05 +00003918 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
3919 rc = shellDatabaseError(p->db);
3920 }
3921
3922 /* Pretty-print the contents of array azResult[] to the output */
3923 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003924 int len, maxlen = 0;
3925 int i, j;
3926 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003927 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003928 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003929 if( len>maxlen ) maxlen = len;
3930 }
3931 nPrintCol = 80/(maxlen+2);
3932 if( nPrintCol<1 ) nPrintCol = 1;
3933 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3934 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003935 for(j=i; j<nRow; j+=nPrintRow){
3936 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00003937 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
3938 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003939 }
mistachkinaae280e2015-12-31 19:06:24 +00003940 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003941 }
3942 }
dand95bb392015-09-30 11:19:05 +00003943
drh98781232012-04-23 12:38:05 +00003944 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3945 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003946 }else
3947
shaneh96887e12011-02-10 21:08:58 +00003948 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003949 static const struct {
3950 const char *zCtrlName; /* Name of a test-control option */
3951 int ctrlCode; /* Integer code for that option */
3952 } aCtrl[] = {
3953 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3954 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3955 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3956 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3957 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3958 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3959 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3960 { "assert", SQLITE_TESTCTRL_ASSERT },
3961 { "always", SQLITE_TESTCTRL_ALWAYS },
3962 { "reserve", SQLITE_TESTCTRL_RESERVE },
3963 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3964 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003965 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003966 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003967 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003968 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003969 };
shaneh96887e12011-02-10 21:08:58 +00003970 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00003971 int rc2 = 0;
3972 int i, n2;
drh05782482013-10-24 15:20:20 +00003973 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003974
drhd416fe72011-03-17 16:45:50 +00003975 /* convert testctrl text option to value. allow any unique prefix
3976 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00003977 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003978 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00003979 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00003980 if( testctrl<0 ){
3981 testctrl = aCtrl[i].ctrlCode;
3982 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003983 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003984 testctrl = -1;
3985 break;
3986 }
3987 }
3988 }
drh348d19c2013-06-03 12:47:43 +00003989 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003990 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00003991 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003992 }else{
3993 switch(testctrl){
3994
3995 /* sqlite3_test_control(int, db, int) */
3996 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3997 case SQLITE_TESTCTRL_RESERVE:
3998 if( nArg==3 ){
3999 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00004000 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004001 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004002 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004003 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004004 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004005 }
4006 break;
4007
4008 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004009 case SQLITE_TESTCTRL_PRNG_SAVE:
4010 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004011 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004012 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004013 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00004014 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00004015 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004016 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004017 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
4018 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004019 }
4020 break;
4021
4022 /* sqlite3_test_control(int, uint) */
4023 case SQLITE_TESTCTRL_PENDING_BYTE:
4024 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004025 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004026 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004027 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004028 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004029 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00004030 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004031 }
4032 break;
4033
4034 /* sqlite3_test_control(int, int) */
4035 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00004036 case SQLITE_TESTCTRL_ALWAYS:
4037 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004038 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00004039 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004040 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004041 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004042 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004043 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004044 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004045 }
4046 break;
4047
4048 /* sqlite3_test_control(int, char *) */
4049#ifdef SQLITE_N_KEYWORD
4050 case SQLITE_TESTCTRL_ISKEYWORD:
4051 if( nArg==3 ){
4052 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004053 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004054 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004055 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004056 utf8_printf(stderr,
4057 "Error: testctrl %s takes a single char * option\n",
4058 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004059 }
4060 break;
4061#endif
4062
drh1ffede82015-01-30 20:59:27 +00004063 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004064 if( nArg==5 ){
mistachkin8e189222015-04-19 21:43:16 +00004065 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004066 azArg[2],
drh8964b342015-01-29 17:54:52 +00004067 integerValue(azArg[3]),
4068 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00004069 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004070 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004071 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004072 }
4073 break;
4074
shaneh96887e12011-02-10 21:08:58 +00004075 case SQLITE_TESTCTRL_BITVEC_TEST:
4076 case SQLITE_TESTCTRL_FAULT_INSTALL:
4077 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4078 case SQLITE_TESTCTRL_SCRATCHMALLOC:
4079 default:
mistachkinaae280e2015-12-31 19:06:24 +00004080 utf8_printf(stderr,
4081 "Error: CLI support for testctrl %s not implemented\n",
4082 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004083 break;
4084 }
4085 }
4086 }else
4087
drhc2ce0be2014-05-29 12:36:14 +00004088 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004089 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004090 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004091 }else
4092
drhc2ce0be2014-05-29 12:36:14 +00004093 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4094 if( nArg==2 ){
4095 enableTimer = booleanValue(azArg[1]);
4096 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00004097 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00004098 enableTimer = 0;
4099 }
4100 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004101 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004102 rc = 1;
4103 }
shanehe2aa9d72009-11-06 17:20:17 +00004104 }else
4105
drhc2ce0be2014-05-29 12:36:14 +00004106 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004107 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004108 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004109 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004110 rc = 1;
4111 goto meta_command_exit;
4112 }
drh657b4a82015-03-19 13:30:41 +00004113 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004114 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004115#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004116 if( p->traceOut==0 ){
4117 sqlite3_trace(p->db, 0, 0);
4118 }else{
4119 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
4120 }
4121#endif
4122 }else
4123
drhf442e332014-09-10 19:01:14 +00004124#if SQLITE_USER_AUTHENTICATION
4125 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4126 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004127 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00004128 rc = 1;
4129 goto meta_command_exit;
4130 }
drh7883ecf2014-09-11 16:19:31 +00004131 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004132 if( strcmp(azArg[1],"login")==0 ){
4133 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00004134 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00004135 rc = 1;
4136 goto meta_command_exit;
4137 }
drhd39c40f2014-09-11 00:27:53 +00004138 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4139 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004140 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004141 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00004142 rc = 1;
4143 }
4144 }else if( strcmp(azArg[1],"add")==0 ){
4145 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004146 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004147 rc = 1;
4148 goto meta_command_exit;
4149 }
drhd39c40f2014-09-11 00:27:53 +00004150 rc = sqlite3_user_add(p->db, azArg[2],
4151 azArg[3], (int)strlen(azArg[3]),
4152 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004153 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004154 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004155 rc = 1;
4156 }
4157 }else if( strcmp(azArg[1],"edit")==0 ){
4158 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004159 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004160 rc = 1;
4161 goto meta_command_exit;
4162 }
drhd39c40f2014-09-11 00:27:53 +00004163 rc = sqlite3_user_change(p->db, azArg[2],
4164 azArg[3], (int)strlen(azArg[3]),
4165 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004166 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004167 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004168 rc = 1;
4169 }
4170 }else if( strcmp(azArg[1],"delete")==0 ){
4171 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004172 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00004173 rc = 1;
4174 goto meta_command_exit;
4175 }
4176 rc = sqlite3_user_delete(p->db, azArg[2]);
4177 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004178 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004179 rc = 1;
4180 }
4181 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004182 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00004183 rc = 1;
4184 goto meta_command_exit;
4185 }
4186 }else
4187#endif /* SQLITE_USER_AUTHENTICATION */
4188
drh9fd301b2011-06-03 13:28:22 +00004189 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004190 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004191 sqlite3_libversion(), sqlite3_sourceid());
4192 }else
4193
drh790f2872015-11-28 18:06:36 +00004194 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
4195 const char *zDbName = nArg==2 ? azArg[1] : "main";
4196 sqlite3_vfs *pVfs;
4197 if( p->db ){
4198 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
4199 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00004200 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
4201 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4202 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4203 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00004204 }
4205 }
4206 }else
4207
drhb19e7352016-01-12 19:37:20 +00004208 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
4209 sqlite3_vfs *pVfs;
4210 sqlite3_vfs *pCurrent = 0;
4211 if( p->db ){
4212 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
4213 }
4214 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
4215 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
4216 pVfs==pCurrent ? " <--- CURRENT" : "");
4217 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4218 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4219 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
4220 if( pVfs->pNext ){
4221 raw_printf(p->out, "-----------------------------------\n");
4222 }
4223 }
4224 }else
4225
drhde60fc22011-12-14 17:53:36 +00004226 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4227 const char *zDbName = nArg==2 ? azArg[1] : "main";
4228 char *zVfsName = 0;
4229 if( p->db ){
4230 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4231 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00004232 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004233 sqlite3_free(zVfsName);
4234 }
4235 }
4236 }else
4237
drhcef4fc82012-09-21 22:50:45 +00004238#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4239 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
4240 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00004241 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004242 }else
4243#endif
4244
drhc2ce0be2014-05-29 12:36:14 +00004245 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004246 int j;
drh43617e92006-03-06 20:55:46 +00004247 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004248 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004249 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004250 }
4251 }else
4252
4253 {
mistachkinaae280e2015-12-31 19:06:24 +00004254 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004255 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004256 rc = 1;
drh75897232000-05-29 14:26:00 +00004257 }
drh67505e72002-04-19 12:34:06 +00004258
drhc2ce0be2014-05-29 12:36:14 +00004259meta_command_exit:
4260 if( p->outCount ){
4261 p->outCount--;
4262 if( p->outCount==0 ) output_reset(p);
4263 }
drh67505e72002-04-19 12:34:06 +00004264 return rc;
drh75897232000-05-29 14:26:00 +00004265}
4266
drh67505e72002-04-19 12:34:06 +00004267/*
drh91a66392007-09-07 01:12:32 +00004268** Return TRUE if a semicolon occurs anywhere in the first N characters
4269** of string z[].
drh324ccef2003-02-05 14:06:20 +00004270*/
drh9f099fd2013-08-06 14:01:46 +00004271static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004272 int i;
4273 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4274 return 0;
drh324ccef2003-02-05 14:06:20 +00004275}
4276
4277/*
drh70c7a4b2003-04-26 03:03:06 +00004278** Test to see if a line consists entirely of whitespace.
4279*/
4280static int _all_whitespace(const char *z){
4281 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004282 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004283 if( *z=='/' && z[1]=='*' ){
4284 z += 2;
4285 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4286 if( *z==0 ) return 0;
4287 z++;
4288 continue;
4289 }
4290 if( *z=='-' && z[1]=='-' ){
4291 z += 2;
4292 while( *z && *z!='\n' ){ z++; }
4293 if( *z==0 ) return 1;
4294 continue;
4295 }
4296 return 0;
4297 }
4298 return 1;
4299}
4300
4301/*
drha9b17162003-04-29 18:01:28 +00004302** Return TRUE if the line typed in is an SQL command terminator other
4303** than a semi-colon. The SQL Server style "go" command is understood
4304** as is the Oracle "/".
4305*/
drh9f099fd2013-08-06 14:01:46 +00004306static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004307 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004308 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4309 return 1; /* Oracle */
4310 }
drhf0693c82011-10-11 20:41:54 +00004311 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004312 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004313 return 1; /* SQL Server */
4314 }
4315 return 0;
4316}
4317
4318/*
drh233a5312008-12-18 22:25:13 +00004319** Return true if zSql is a complete SQL statement. Return false if it
4320** ends in the middle of a string literal or C-style comment.
4321*/
drh9f099fd2013-08-06 14:01:46 +00004322static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004323 int rc;
4324 if( zSql==0 ) return 1;
4325 zSql[nSql] = ';';
4326 zSql[nSql+1] = 0;
4327 rc = sqlite3_complete(zSql);
4328 zSql[nSql] = 0;
4329 return rc;
4330}
4331
4332/*
drh67505e72002-04-19 12:34:06 +00004333** Read input from *in and process it. If *in==0 then input
4334** is interactive - the user is typing it it. Otherwise, input
4335** is coming from a file or device. A prompt is issued and history
4336** is saved only if input is interactive. An interrupt signal will
4337** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004338**
4339** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004340*/
drhdcd87a92014-08-18 13:45:42 +00004341static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004342 char *zLine = 0; /* A single input line */
4343 char *zSql = 0; /* Accumulated SQL text */
4344 int nLine; /* Length of current line */
4345 int nSql = 0; /* Bytes of zSql[] used */
4346 int nAlloc = 0; /* Allocated zSql[] space */
4347 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4348 char *zErrMsg; /* Error message returned */
4349 int rc; /* Error code */
4350 int errCnt = 0; /* Number of errors seen */
4351 int lineno = 0; /* Current line number */
4352 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004353
4354 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4355 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004356 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004357 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004358 /* End of input */
4359 if( stdin_is_interactive ) printf("\n");
4360 break;
drhc49f44e2006-10-26 18:15:42 +00004361 }
drh67505e72002-04-19 12:34:06 +00004362 if( seenInterrupt ){
4363 if( in!=0 ) break;
4364 seenInterrupt = 0;
4365 }
drhc28490c2006-10-26 14:25:58 +00004366 lineno++;
drh849a9d92013-12-21 15:46:06 +00004367 if( nSql==0 && _all_whitespace(zLine) ){
4368 if( p->echoOn ) printf("%s\n", zLine);
4369 continue;
4370 }
drh2af0b2d2002-02-21 02:25:02 +00004371 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004372 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004373 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004374 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004375 break;
4376 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004377 errCnt++;
4378 }
drhdaffd0e2001-04-11 14:28:42 +00004379 continue;
4380 }
drh9f099fd2013-08-06 14:01:46 +00004381 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004382 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004383 }
drh9f099fd2013-08-06 14:01:46 +00004384 nLine = strlen30(zLine);
4385 if( nSql+nLine+2>=nAlloc ){
4386 nAlloc = nSql+nLine+100;
4387 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004388 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004389 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004390 exit(1);
4391 }
drhdaffd0e2001-04-11 14:28:42 +00004392 }
drh9f099fd2013-08-06 14:01:46 +00004393 nSqlPrior = nSql;
4394 if( nSql==0 ){
4395 int i;
4396 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004397 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004398 memcpy(zSql, zLine+i, nLine+1-i);
4399 startline = lineno;
4400 nSql = nLine-i;
4401 }else{
4402 zSql[nSql++] = '\n';
4403 memcpy(zSql+nSql, zLine, nLine+1);
4404 nSql += nLine;
4405 }
4406 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004407 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004408 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004409 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004410 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004411 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004412 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004413 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004414 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004415 char zPrefix[100];
4416 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004417 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004418 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004419 }else{
shane9bd1b442009-10-23 01:27:39 +00004420 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004421 }
drh7f953e22002-07-13 17:33:45 +00004422 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004423 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004424 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004425 zErrMsg = 0;
4426 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004427 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004428 }
drhc49f44e2006-10-26 18:15:42 +00004429 errCnt++;
drhdf12f1c2015-12-07 21:46:19 +00004430 }else if( p->countChanges ){
mistachkinaae280e2015-12-31 19:06:24 +00004431 raw_printf(p->out, "changes: %3d total_changes: %d\n",
drhdf12f1c2015-12-07 21:46:19 +00004432 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
drhdaffd0e2001-04-11 14:28:42 +00004433 }
drhdaffd0e2001-04-11 14:28:42 +00004434 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004435 if( p->outCount ){
4436 output_reset(p);
4437 p->outCount = 0;
4438 }
drh9f099fd2013-08-06 14:01:46 +00004439 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004440 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004441 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004442 }
4443 }
drh9f099fd2013-08-06 14:01:46 +00004444 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004445 if( !_all_whitespace(zSql) ){
mistachkinaae280e2015-12-31 19:06:24 +00004446 utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004447 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004448 }
drhdaffd0e2001-04-11 14:28:42 +00004449 }
drh1f9ca2c2015-08-25 16:57:52 +00004450 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00004451 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004452 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004453}
4454
drh67505e72002-04-19 12:34:06 +00004455/*
4456** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004457** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004458*/
4459static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004460 static char *home_dir = NULL;
4461 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004462
drh4ace5362014-11-10 14:42:28 +00004463#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4464 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004465 {
4466 struct passwd *pwent;
4467 uid_t uid = getuid();
4468 if( (pwent=getpwuid(uid)) != NULL) {
4469 home_dir = pwent->pw_dir;
4470 }
drh67505e72002-04-19 12:34:06 +00004471 }
4472#endif
4473
chw65d3c132007-11-12 21:09:10 +00004474#if defined(_WIN32_WCE)
4475 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4476 */
drh85e72432012-04-11 11:38:53 +00004477 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004478#else
4479
drh83905c92012-06-21 13:00:37 +00004480#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004481 if (!home_dir) {
4482 home_dir = getenv("USERPROFILE");
4483 }
4484#endif
4485
drh67505e72002-04-19 12:34:06 +00004486 if (!home_dir) {
4487 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004488 }
4489
drh83905c92012-06-21 13:00:37 +00004490#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004491 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004492 char *zDrive, *zPath;
4493 int n;
4494 zDrive = getenv("HOMEDRIVE");
4495 zPath = getenv("HOMEPATH");
4496 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004497 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004498 home_dir = malloc( n );
4499 if( home_dir==0 ) return 0;
4500 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4501 return home_dir;
4502 }
4503 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004504 }
4505#endif
4506
chw65d3c132007-11-12 21:09:10 +00004507#endif /* !_WIN32_WCE */
4508
drh67505e72002-04-19 12:34:06 +00004509 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004510 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004511 char *z = malloc( n );
4512 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004513 home_dir = z;
4514 }
drhe98d4fa2002-04-21 19:06:22 +00004515
drh67505e72002-04-19 12:34:06 +00004516 return home_dir;
4517}
4518
4519/*
4520** Read input from the file given by sqliterc_override. Or if that
4521** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004522**
4523** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004524*/
drh534f4df2015-02-28 14:03:35 +00004525static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004526 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004527 const char *sqliterc_override /* Name of config file. NULL to use default */
4528){
persicom7e2dfdd2002-04-18 02:46:52 +00004529 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004530 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004531 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004532 FILE *in = NULL;
4533
4534 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004535 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004536 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004537 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00004538 " cannot read ~/.sqliterc\n");
4539 return;
drhe98d4fa2002-04-21 19:06:22 +00004540 }
drh2f3de322012-06-27 16:41:31 +00004541 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004542 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4543 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004544 }
drha1f9b5e2004-02-14 16:31:02 +00004545 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004546 if( in ){
drhc28490c2006-10-26 14:25:58 +00004547 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00004548 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004549 }
drh534f4df2015-02-28 14:03:35 +00004550 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004551 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004552 }
drh85e72432012-04-11 11:38:53 +00004553 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004554}
4555
drh67505e72002-04-19 12:34:06 +00004556/*
drhe1e38c42003-05-04 18:30:59 +00004557** Show available command line options
4558*/
4559static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004560 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004561 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004562 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004563 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004564 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004565 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004566 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004567 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004568 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004569#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4570 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4571#endif
drhcc3b4f82012-02-07 14:13:50 +00004572 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004573 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004574 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004575 " -line set output mode to 'line'\n"
4576 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004577 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004578 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004579#ifdef SQLITE_ENABLE_MULTIPLEX
4580 " -multiplex enable the multiplexor VFS\n"
4581#endif
mistachkine0d68852014-12-11 03:12:33 +00004582 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004583 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004584 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4585 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004586 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004587 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004588 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004589 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004590#ifdef SQLITE_ENABLE_VFSTRACE
4591 " -vfstrace enable tracing of all VFS calls\n"
4592#endif
drhe1e38c42003-05-04 18:30:59 +00004593;
4594static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00004595 utf8_printf(stderr,
drh80e8be92006-08-29 12:04:19 +00004596 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4597 "FILENAME is the name of an SQLite database. A new database is created\n"
4598 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004599 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00004600 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004601 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004602 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00004603 }
4604 exit(1);
4605}
4606
4607/*
drh67505e72002-04-19 12:34:06 +00004608** Initialize the state information in data
4609*/
drhdcd87a92014-08-18 13:45:42 +00004610static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004611 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00004612 data->normalMode = data->cMode = data->mode = MODE_List;
4613 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00004614 memcpy(data->colSeparator,SEP_Column, 2);
4615 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004616 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004617 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004618 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004619 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004620 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004621 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4622 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004623}
4624
drh98d312f2012-10-25 15:23:14 +00004625/*
drh5c7976f2014-02-10 19:59:27 +00004626** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004627*/
4628#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004629static void printBold(const char *zText){
4630 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4631 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4632 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4633 SetConsoleTextAttribute(out,
4634 FOREGROUND_RED|FOREGROUND_INTENSITY
4635 );
4636 printf("%s", zText);
4637 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004638}
4639#else
drh5c7976f2014-02-10 19:59:27 +00004640static void printBold(const char *zText){
4641 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004642}
4643#endif
4644
4645/*
drh98d312f2012-10-25 15:23:14 +00004646** Get the argument to an --option. Throw an error and die if no argument
4647** is available.
4648*/
4649static char *cmdline_option_value(int argc, char **argv, int i){
4650 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00004651 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00004652 argv[0], argv[argc-1]);
4653 exit(1);
4654 }
4655 return argv[i];
4656}
4657
mistachkin44723ce2015-03-21 02:22:37 +00004658int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004659 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004660 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004661 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004662 int i;
drhc28490c2006-10-26 14:25:58 +00004663 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004664 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004665 int readStdin = 1;
4666 int nCmd = 0;
4667 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004668
drh69b30ab2014-02-27 15:11:52 +00004669#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004670 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004671 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00004672 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4673 exit(1);
4674 }
drhc7181902014-02-27 15:04:13 +00004675#endif
drh047d4532015-01-18 20:30:23 +00004676 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004677 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004678 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004679 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004680 stdin_is_interactive = isatty(0);
drhe05461c2015-12-30 13:36:57 +00004681 stdout_is_console = isatty(1);
persicom7e2dfdd2002-04-18 02:46:52 +00004682
drh44c2eb12003-04-30 11:38:26 +00004683 /* Make sure we have a valid signal handler early, before anything
4684 ** else is done.
4685 */
drh4c504392000-10-16 22:06:40 +00004686#ifdef SIGINT
4687 signal(SIGINT, interrupt_handler);
4688#endif
drh44c2eb12003-04-30 11:38:26 +00004689
drhac5649a2014-11-28 13:35:03 +00004690#ifdef SQLITE_SHELL_DBNAME_PROC
4691 {
4692 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4693 ** of a C-function that will provide the name of the database file. Use
4694 ** this compile-time option to embed this shell program in larger
4695 ** applications. */
4696 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4697 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4698 warnInmemoryDb = 0;
4699 }
4700#endif
4701
drh22fbcb82004-02-01 01:22:50 +00004702 /* Do an initial pass through the command-line argument to locate
4703 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004704 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004705 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004706 */
drh98d312f2012-10-25 15:23:14 +00004707 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004708 char *z;
drhc28490c2006-10-26 14:25:58 +00004709 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004710 if( z[0]!='-' ){
4711 if( data.zDbFilename==0 ){
4712 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004713 }else{
4714 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4715 ** mean that nothing is read from stdin */
4716 readStdin = 0;
4717 nCmd++;
4718 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4719 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004720 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00004721 exit(1);
4722 }
4723 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004724 }
drh98d312f2012-10-25 15:23:14 +00004725 }
drhcc3b4f82012-02-07 14:13:50 +00004726 if( z[1]=='-' ) z++;
4727 if( strcmp(z,"-separator")==0
4728 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004729 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004730 || strcmp(z,"-cmd")==0
4731 ){
drh98d312f2012-10-25 15:23:14 +00004732 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004733 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004734 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004735 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004736 /* Need to check for batch mode here to so we can avoid printing
4737 ** informational messages (like from process_sqliterc) before
4738 ** we do the actual processing of arguments later in a second pass.
4739 */
shanef69573d2009-10-24 02:06:14 +00004740 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004741 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004742#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004743 const char *zSize;
4744 sqlite3_int64 szHeap;
4745
drh98d312f2012-10-25 15:23:14 +00004746 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004747 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004748 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004749 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4750#endif
drh44dec872014-08-30 15:49:25 +00004751 }else if( strcmp(z,"-scratch")==0 ){
4752 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004753 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004754 if( sz>400000 ) sz = 400000;
4755 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004756 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004757 if( n>10 ) n = 10;
4758 if( n<1 ) n = 1;
4759 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4760 data.shellFlgs |= SHFLG_Scratch;
4761 }else if( strcmp(z,"-pagecache")==0 ){
4762 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004763 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004764 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00004765 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004766 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00004767 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
4768 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00004769 data.shellFlgs |= SHFLG_Pagecache;
4770 }else if( strcmp(z,"-lookaside")==0 ){
4771 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004772 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004773 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004774 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004775 if( n<0 ) n = 0;
4776 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4777 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004778#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004779 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004780 extern int vfstrace_register(
4781 const char *zTraceName,
4782 const char *zOldVfsName,
4783 int (*xOut)(const char*,void*),
4784 void *pOutArg,
4785 int makeDefault
4786 );
drh2b625e22011-03-16 17:05:28 +00004787 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004788#endif
drh6f25e892011-07-08 17:02:57 +00004789#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004790 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004791 extern int sqlite3_multiple_initialize(const char*,int);
4792 sqlite3_multiplex_initialize(0, 1);
4793#endif
drh7d9f3942013-04-03 01:26:54 +00004794 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004795 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4796 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004797 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004798 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004799 if( pVfs ){
4800 sqlite3_vfs_register(pVfs, 1);
4801 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004802 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00004803 exit(1);
4804 }
drh44c2eb12003-04-30 11:38:26 +00004805 }
4806 }
drh98d312f2012-10-25 15:23:14 +00004807 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004808#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004809 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004810 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004811#else
mistachkinaae280e2015-12-31 19:06:24 +00004812 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00004813 return 1;
drh01b41712005-08-29 23:06:23 +00004814#endif
drh98d312f2012-10-25 15:23:14 +00004815 }
4816 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004817
drh44c2eb12003-04-30 11:38:26 +00004818 /* Go ahead and open the database file if it already exists. If the
4819 ** file does not exist, delay opening it. This prevents empty database
4820 ** files from being created if a user mistypes the database name argument
4821 ** to the sqlite command-line tool.
4822 */
drhc8d74412004-08-31 23:41:26 +00004823 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004824 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004825 }
4826
drh22fbcb82004-02-01 01:22:50 +00004827 /* Process the initialization file if there is one. If no -init option
4828 ** is given on the command line, look for a file named ~/.sqliterc and
4829 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004830 */
drh534f4df2015-02-28 14:03:35 +00004831 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004832
drh22fbcb82004-02-01 01:22:50 +00004833 /* Make a second pass through the command-line argument and set
4834 ** options. This second pass is delayed until after the initialization
4835 ** file is processed so that the command-line arguments will override
4836 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004837 */
drh98d312f2012-10-25 15:23:14 +00004838 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004839 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004840 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004841 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004842 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004843 i++;
4844 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004845 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004846 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004847 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004848 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004849 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004850 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004851 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004852 }else if( strcmp(z,"-csv")==0 ){
4853 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004854 memcpy(data.colSeparator,",",2);
4855 }else if( strcmp(z,"-ascii")==0 ){
4856 data.mode = MODE_Ascii;
4857 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004858 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004859 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004860 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004861 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004862 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4863 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004864 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004865 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004866 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004867 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004868 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004869 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004870 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004871 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004872 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004873 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004874 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004875 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004876 }else if( strcmp(z,"-eqp")==0 ){
4877 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004878 }else if( strcmp(z,"-stats")==0 ){
4879 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004880 }else if( strcmp(z,"-scanstats")==0 ){
4881 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00004882 }else if( strcmp(z,"-backslash")==0 ){
4883 /* Undocumented command-line option: -backslash
4884 ** Causes C-style backslash escapes to be evaluated in SQL statements
4885 ** prior to sending the SQL into SQLite. Useful for injecting
4886 ** crazy bytes in the middle of SQL statements for testing and debugging.
4887 */
4888 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004889 }else if( strcmp(z,"-bail")==0 ){
4890 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004891 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004892 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004893 return 0;
drhc28490c2006-10-26 14:25:58 +00004894 }else if( strcmp(z,"-interactive")==0 ){
4895 stdin_is_interactive = 1;
4896 }else if( strcmp(z,"-batch")==0 ){
4897 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004898 }else if( strcmp(z,"-heap")==0 ){
4899 i++;
drh44dec872014-08-30 15:49:25 +00004900 }else if( strcmp(z,"-scratch")==0 ){
4901 i+=2;
4902 }else if( strcmp(z,"-pagecache")==0 ){
4903 i+=2;
4904 }else if( strcmp(z,"-lookaside")==0 ){
4905 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004906 }else if( strcmp(z,"-mmap")==0 ){
4907 i++;
drha7e61d82011-03-12 17:02:57 +00004908 }else if( strcmp(z,"-vfs")==0 ){
4909 i++;
drh6f25e892011-07-08 17:02:57 +00004910#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004911 }else if( strcmp(z,"-vfstrace")==0 ){
4912 i++;
drh6f25e892011-07-08 17:02:57 +00004913#endif
4914#ifdef SQLITE_ENABLE_MULTIPLEX
4915 }else if( strcmp(z,"-multiplex")==0 ){
4916 i++;
4917#endif
drhcc3b4f82012-02-07 14:13:50 +00004918 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004919 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004920 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004921 /* Run commands that follow -cmd first and separately from commands
4922 ** that simply appear on the command-line. This seems goofy. It would
4923 ** be better if all commands ran in the order that they appear. But
4924 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004925 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004926 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004927 if( z[0]=='.' ){
4928 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004929 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004930 }else{
drh05782482013-10-24 15:20:20 +00004931 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004932 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4933 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004934 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00004935 if( bail_on_error ) return rc!=0 ? rc : 1;
4936 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004937 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00004938 if( bail_on_error ) return rc;
4939 }
4940 }
drh1e5d0e92000-05-31 23:33:17 +00004941 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004942 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
4943 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004944 return 1;
4945 }
drh700c2522016-02-09 18:39:25 +00004946 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00004947 }
drh44c2eb12003-04-30 11:38:26 +00004948
drhac5649a2014-11-28 13:35:03 +00004949 if( !readStdin ){
4950 /* Run all arguments that do not begin with '-' as if they were separate
4951 ** command-line inputs, except for the argToSkip argument which contains
4952 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004953 */
drhac5649a2014-11-28 13:35:03 +00004954 for(i=0; i<nCmd; i++){
4955 if( azCmd[i][0]=='.' ){
4956 rc = do_meta_command(azCmd[i], &data);
4957 if( rc ) return rc==2 ? 0 : rc;
4958 }else{
4959 open_db(&data, 0);
4960 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4961 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004962 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00004963 return rc!=0 ? rc : 1;
4964 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004965 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00004966 return rc;
4967 }
drh6ff13852001-11-25 13:18:23 +00004968 }
drh75897232000-05-29 14:26:00 +00004969 }
drhac5649a2014-11-28 13:35:03 +00004970 free(azCmd);
drh75897232000-05-29 14:26:00 +00004971 }else{
drh44c2eb12003-04-30 11:38:26 +00004972 /* Run commands received from standard input
4973 */
drhc28490c2006-10-26 14:25:58 +00004974 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004975 char *zHome;
4976 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004977 int nHistory;
drh75897232000-05-29 14:26:00 +00004978 printf(
drh743e0032011-12-12 16:51:50 +00004979 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004980 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004981 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004982 );
drhb3735912014-02-10 16:13:42 +00004983 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004984 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004985 printBold("transient in-memory database");
4986 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004987 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004988 }
drh67505e72002-04-19 12:34:06 +00004989 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004990 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004991 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004992 if( (zHistory = malloc(nHistory))!=0 ){
4993 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4994 }
drh67505e72002-04-19 12:34:06 +00004995 }
drhf5ed7ad2015-06-15 14:43:25 +00004996 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00004997 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004998 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004999 shell_stifle_history(100);
5000 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00005001 free(zHistory);
drh67505e72002-04-19 12:34:06 +00005002 }
drhdaffd0e2001-04-11 14:28:42 +00005003 }else{
drhc28490c2006-10-26 14:25:58 +00005004 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00005005 }
5006 }
drh33048c02001-10-01 14:29:22 +00005007 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00005008 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00005009 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00005010 }
drh05782482013-10-24 15:20:20 +00005011 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00005012 return rc;
drh75897232000-05-29 14:26:00 +00005013}