blob: c45b28b999cf95403b4c5a2098331ff2cdffb492 [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. */
1509 zSql = sqlite3_sql(pSql);
1510 if( zSql==0 ) return;
1511 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1512 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1513
1514 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1515 int i;
danc4650bb2013-11-18 08:41:06 +00001516 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001517 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001518
1519 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1520 ** p2 is an instruction address, set variable p2op to the index of that
1521 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1522 ** the current instruction is part of a sub-program generated by an
1523 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001524 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001525 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001526
1527 /* Grow the p->aiIndent array as required */
1528 if( iOp>=nAlloc ){
1529 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001530 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1531 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001532 }
1533 abYield[iOp] = str_in_array(zOp, azYield);
1534 p->aiIndent[iOp] = 0;
1535 p->nIndent = iOp+1;
1536
1537 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001538 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001539 }
drhfe705102014-03-06 13:38:37 +00001540 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1541 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1542 ){
drhe73f0592014-01-21 22:25:45 +00001543 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001544 }
1545 }
1546
danc4650bb2013-11-18 08:41:06 +00001547 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001548 sqlite3_free(abYield);
1549 sqlite3_reset(pSql);
1550}
1551
1552/*
1553** Free the array allocated by explain_data_prepare().
1554*/
drhdcd87a92014-08-18 13:45:42 +00001555static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001556 sqlite3_free(p->aiIndent);
1557 p->aiIndent = 0;
1558 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001559 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001560}
1561
1562/*
shane626a6e42009-10-22 17:30:15 +00001563** Execute a statement or set of statements. Print
1564** any result rows/columns depending on the current mode
1565** set via the supplied callback.
1566**
1567** This is very similar to SQLite's built-in sqlite3_exec()
1568** function except it takes a slightly different callback
1569** and callback data argument.
1570*/
1571static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001572 sqlite3 *db, /* An open database */
1573 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001574 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001575 /* (not the same as sqlite3_exec) */
1576 ShellState *pArg, /* Pointer to ShellState */
1577 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001578){
dan4564ced2010-01-05 04:59:56 +00001579 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1580 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001581 int rc2;
dan4564ced2010-01-05 04:59:56 +00001582 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001583
1584 if( pzErrMsg ){
1585 *pzErrMsg = NULL;
1586 }
1587
shaneb9fc17d2009-10-22 21:23:35 +00001588 while( zSql[0] && (SQLITE_OK == rc) ){
1589 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1590 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001591 if( pzErrMsg ){
1592 *pzErrMsg = save_err_msg(db);
1593 }
1594 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001595 if( !pStmt ){
1596 /* this happens for a comment or white-space */
1597 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001598 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001599 continue;
1600 }
shane626a6e42009-10-22 17:30:15 +00001601
shaneh642d8b82010-07-28 16:05:34 +00001602 /* save off the prepared statment handle and reset row count */
1603 if( pArg ){
1604 pArg->pStmt = pStmt;
1605 pArg->cnt = 0;
1606 }
1607
shanehb7977c52010-01-18 18:17:10 +00001608 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001609 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001610 const char *zStmtSql = sqlite3_sql(pStmt);
drhe05461c2015-12-30 13:36:57 +00001611 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001612 }
shanehb7977c52010-01-18 18:17:10 +00001613
drhefbf3b12014-02-28 20:47:24 +00001614 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1615 if( pArg && pArg->autoEQP ){
1616 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001617 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1618 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001619 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1620 if( rc==SQLITE_OK ){
1621 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001622 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1623 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1624 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001625 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001626 }
1627 }
1628 sqlite3_finalize(pExplain);
1629 sqlite3_free(zEQP);
1630 }
1631
drh700c2522016-02-09 18:39:25 +00001632 if( pArg ){
1633 pArg->cMode = pArg->mode;
1634 if( sqlite3_column_count(pStmt)==8
1635 && sqlite3_strlike("%EXPLAIN%", sqlite3_sql(pStmt),0)==0
1636 && sqlite3_strlike("%QUERY%", sqlite3_sql(pStmt),0)!=0
1637 ){
1638 pArg->cMode = MODE_Explain;
1639 }
1640
1641 /* If the shell is currently in ".explain" mode, gather the extra
1642 ** data required to add indents to the output.*/
1643 if( pArg->cMode==MODE_Explain ){
1644 explain_data_prepare(pArg, pStmt);
1645 }
dana98bf362013-11-13 18:35:01 +00001646 }
1647
shaneb9fc17d2009-10-22 21:23:35 +00001648 /* perform the first step. this will tell us if we
1649 ** have a result set or not and how wide it is.
1650 */
1651 rc = sqlite3_step(pStmt);
1652 /* if we have a result set... */
1653 if( SQLITE_ROW == rc ){
1654 /* if we have a callback... */
1655 if( xCallback ){
1656 /* allocate space for col name ptr, value ptr, and type */
1657 int nCol = sqlite3_column_count(pStmt);
drhf3cdcdc2015-04-29 16:50:28 +00001658 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
shaneb9fc17d2009-10-22 21:23:35 +00001659 if( !pData ){
1660 rc = SQLITE_NOMEM;
1661 }else{
1662 char **azCols = (char **)pData; /* Names of result columns */
1663 char **azVals = &azCols[nCol]; /* Results */
1664 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001665 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001666 assert(sizeof(int) <= sizeof(char *));
1667 /* save off ptrs to column names */
1668 for(i=0; i<nCol; i++){
1669 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1670 }
shaneb9fc17d2009-10-22 21:23:35 +00001671 do{
1672 /* extract the data and data types */
1673 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001674 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh700c2522016-02-09 18:39:25 +00001675 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001676 azVals[i] = "";
1677 }else{
1678 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1679 }
shaneb9fc17d2009-10-22 21:23:35 +00001680 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1681 rc = SQLITE_NOMEM;
1682 break; /* from for */
1683 }
1684 } /* end for */
1685
1686 /* if data and types extracted successfully... */
1687 if( SQLITE_ROW == rc ){
1688 /* call the supplied callback with the result row data */
1689 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1690 rc = SQLITE_ABORT;
1691 }else{
1692 rc = sqlite3_step(pStmt);
1693 }
1694 }
1695 } while( SQLITE_ROW == rc );
1696 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001697 }
1698 }else{
1699 do{
1700 rc = sqlite3_step(pStmt);
1701 } while( rc == SQLITE_ROW );
1702 }
1703 }
1704
dana98bf362013-11-13 18:35:01 +00001705 explain_data_delete(pArg);
1706
shaneh642d8b82010-07-28 16:05:34 +00001707 /* print usage stats if stats on */
1708 if( pArg && pArg->statsOn ){
1709 display_stats(db, pArg, 0);
1710 }
1711
dan8d1edb92014-11-05 09:07:28 +00001712 /* print loop-counters if required */
1713 if( pArg && pArg->scanstatsOn ){
1714 display_scanstats(db, pArg);
1715 }
1716
dan4564ced2010-01-05 04:59:56 +00001717 /* Finalize the statement just executed. If this fails, save a
1718 ** copy of the error message. Otherwise, set zSql to point to the
1719 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001720 rc2 = sqlite3_finalize(pStmt);
1721 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001722 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001723 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001724 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001725 }else if( pzErrMsg ){
1726 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001727 }
shaneh642d8b82010-07-28 16:05:34 +00001728
1729 /* clear saved stmt handle */
1730 if( pArg ){
1731 pArg->pStmt = NULL;
1732 }
shane626a6e42009-10-22 17:30:15 +00001733 }
shaneb9fc17d2009-10-22 21:23:35 +00001734 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001735
1736 return rc;
1737}
1738
drhdd3d4592004-08-30 01:54:05 +00001739
drh33048c02001-10-01 14:29:22 +00001740/*
drh4c653a02000-06-07 01:27:47 +00001741** This is a different callback routine used for dumping the database.
1742** Each row received by this callback consists of a table name,
1743** the table type ("index" or "table") and SQL to create the table.
1744** This routine should print text sufficient to recreate the table.
1745*/
1746static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001747 int rc;
1748 const char *zTable;
1749 const char *zType;
1750 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001751 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001752 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001753
drh902b9ee2008-12-05 17:17:07 +00001754 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001755 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001756 zTable = azArg[0];
1757 zType = azArg[1];
1758 zSql = azArg[2];
1759
drh00b950d2005-09-11 02:03:03 +00001760 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001761 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001762 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001763 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00001764 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1765 return 0;
drh45e29d82006-11-20 16:21:10 +00001766 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1767 char *zIns;
1768 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00001769 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00001770 p->writableSchema = 1;
1771 }
1772 zIns = sqlite3_mprintf(
1773 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1774 "VALUES('table','%q','%q',0,'%q');",
1775 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00001776 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00001777 sqlite3_free(zIns);
1778 return 0;
drh00b950d2005-09-11 02:03:03 +00001779 }else{
drhe05461c2015-12-30 13:36:57 +00001780 utf8_printf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001781 }
danielk19772a02e332004-06-05 08:04:36 +00001782
1783 if( strcmp(zType, "table")==0 ){
1784 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001785 char *zSelect = 0;
1786 char *zTableInfo = 0;
1787 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001788 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001789
1790 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1791 zTableInfo = appendText(zTableInfo, zTable, '"');
1792 zTableInfo = appendText(zTableInfo, ");", 0);
1793
drhc7181902014-02-27 15:04:13 +00001794 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001795 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001796 if( rc!=SQLITE_OK || !pTableInfo ){
1797 return 1;
1798 }
1799
1800 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001801 /* Always quote the table name, even if it appears to be pure ascii,
1802 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1803 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001804 if( zTmp ){
1805 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001806 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001807 }
1808 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1809 rc = sqlite3_step(pTableInfo);
1810 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001811 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001812 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001813 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001814 rc = sqlite3_step(pTableInfo);
1815 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001816 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001817 }else{
1818 zSelect = appendText(zSelect, ") ", 0);
1819 }
drh157e29a2009-05-21 15:15:00 +00001820 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001821 }
1822 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001823 if( rc!=SQLITE_OK || nRow==0 ){
1824 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001825 return 1;
1826 }
1827 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1828 zSelect = appendText(zSelect, zTable, '"');
1829
drh2f464a02011-10-13 00:41:49 +00001830 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001831 if( rc==SQLITE_CORRUPT ){
1832 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001833 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001834 }
drh85e72432012-04-11 11:38:53 +00001835 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001836 }
drh4c653a02000-06-07 01:27:47 +00001837 return 0;
1838}
1839
1840/*
drh45e29d82006-11-20 16:21:10 +00001841** Run zQuery. Use dump_callback() as the callback routine so that
1842** the contents of the query are output as SQL statements.
1843**
drhdd3d4592004-08-30 01:54:05 +00001844** If we get a SQLITE_CORRUPT error, rerun the query after appending
1845** "ORDER BY rowid DESC" to the end.
1846*/
1847static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001848 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001849 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001850){
1851 int rc;
drh2f464a02011-10-13 00:41:49 +00001852 char *zErr = 0;
1853 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001854 if( rc==SQLITE_CORRUPT ){
1855 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001856 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00001857 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00001858 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00001859 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00001860 sqlite3_free(zErr);
1861 zErr = 0;
1862 }
drhdd3d4592004-08-30 01:54:05 +00001863 zQ2 = malloc( len+100 );
1864 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001865 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001866 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1867 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00001868 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00001869 }else{
1870 rc = SQLITE_CORRUPT;
1871 }
1872 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001873 free(zQ2);
1874 }
1875 return rc;
1876}
1877
1878/*
drh75897232000-05-29 14:26:00 +00001879** Text of a help message
1880*/
persicom1d0b8722002-04-18 02:53:04 +00001881static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001882 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001883 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00001884 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00001885 ".changes on|off Show number of rows changed by SQL\n"
drh4bbcf102014-02-06 02:46:08 +00001886 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001887 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001888 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001889 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001890 " If TABLE specified, only dump tables matching\n"
1891 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001892 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001893 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001894 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00001895 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drhc1971542014-06-23 23:28:13 +00001896 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001897 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001898 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001899 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001900 ".indexes ?TABLE? Show names of all indexes\n"
1901 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001902 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001903#ifdef SQLITE_ENABLE_IOTRACE
1904 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1905#endif
drh1a513372015-05-02 17:40:23 +00001906 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00001907#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001908 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001909#endif
drh127f9d72010-02-23 01:47:00 +00001910 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001911 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001912 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001913 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001914 " column Left-aligned columns. (See .width)\n"
1915 " html HTML <table> code\n"
1916 " insert SQL insert statements for TABLE\n"
1917 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001918 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001919 " tabs Tab-separated values\n"
1920 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001921 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001922 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001923 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001924 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001925 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001926 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001927 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001928 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001929 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001930 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001931 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001932 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001933 " If TABLE specified, only show tables matching\n"
1934 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001935 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1936 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001937 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001938 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001939 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001940 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001941 ".tables ?TABLE? List names of tables\n"
1942 " If TABLE specified, only list tables matching\n"
1943 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001944 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001945 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001946 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00001947 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00001948 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00001949 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001950 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001951 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001952;
1953
drhdaffd0e2001-04-11 14:28:42 +00001954/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001955static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001956/*
1957** Implementation of the "readfile(X)" SQL function. The entire content
1958** of the file named X is read and returned as a BLOB. NULL is returned
1959** if the file does not exist or is unreadable.
1960*/
1961static void readfileFunc(
1962 sqlite3_context *context,
1963 int argc,
1964 sqlite3_value **argv
1965){
1966 const char *zName;
1967 FILE *in;
1968 long nIn;
1969 void *pBuf;
1970
drhf5ed7ad2015-06-15 14:43:25 +00001971 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00001972 zName = (const char*)sqlite3_value_text(argv[0]);
1973 if( zName==0 ) return;
1974 in = fopen(zName, "rb");
1975 if( in==0 ) return;
1976 fseek(in, 0, SEEK_END);
1977 nIn = ftell(in);
1978 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00001979 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00001980 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1981 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1982 }else{
1983 sqlite3_free(pBuf);
1984 }
1985 fclose(in);
1986}
1987
1988/*
1989** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1990** is written into file X. The number of bytes written is returned. Or
1991** NULL is returned if something goes wrong, such as being unable to open
1992** file X for writing.
1993*/
1994static void writefileFunc(
1995 sqlite3_context *context,
1996 int argc,
1997 sqlite3_value **argv
1998){
1999 FILE *out;
2000 const char *z;
drhba5b0932014-07-24 12:39:59 +00002001 sqlite3_int64 rc;
2002 const char *zFile;
2003
drhf5ed7ad2015-06-15 14:43:25 +00002004 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002005 zFile = (const char*)sqlite3_value_text(argv[0]);
2006 if( zFile==0 ) return;
2007 out = fopen(zFile, "wb");
2008 if( out==0 ) return;
2009 z = (const char*)sqlite3_value_blob(argv[1]);
2010 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002011 rc = 0;
2012 }else{
drh490fe862014-08-11 14:21:32 +00002013 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002014 }
2015 fclose(out);
2016 sqlite3_result_int64(context, rc);
2017}
drhdaffd0e2001-04-11 14:28:42 +00002018
drh75897232000-05-29 14:26:00 +00002019/*
drh44c2eb12003-04-30 11:38:26 +00002020** Make sure the database is open. If it is not, then open it. If
2021** the database fails to open, print an error message and exit.
2022*/
drhdcd87a92014-08-18 13:45:42 +00002023static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002024 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002025 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002026 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002027 globalDb = p->db;
2028 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2029 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002030 shellstaticFunc, 0, 0);
2031 }
mistachkin8e189222015-04-19 21:43:16 +00002032 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkinaae280e2015-12-31 19:06:24 +00002033 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002034 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002035 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002036 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002037 }
drhc2e87a32006-06-27 15:16:14 +00002038#ifndef SQLITE_OMIT_LOAD_EXTENSION
2039 sqlite3_enable_load_extension(p->db, 1);
2040#endif
mistachkin8e189222015-04-19 21:43:16 +00002041 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002042 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002043 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002044 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002045 }
2046}
2047
2048/*
drhfeac5f82004-08-01 00:10:45 +00002049** Do C-language style dequoting.
2050**
mistachkinf21979d2015-01-18 05:35:01 +00002051** \a -> alarm
2052** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002053** \t -> tab
2054** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002055** \v -> vertical tab
2056** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002057** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002058** \s -> space
drh4c56b992013-06-27 13:26:55 +00002059** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002060** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002061** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002062** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002063*/
2064static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002065 int i, j;
2066 char c;
drhc2ce0be2014-05-29 12:36:14 +00002067 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002068 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002069 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002070 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002071 if( c=='a' ){
2072 c = '\a';
2073 }else if( c=='b' ){
2074 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002075 }else if( c=='t' ){
2076 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002077 }else if( c=='n' ){
2078 c = '\n';
2079 }else if( c=='v' ){
2080 c = '\v';
2081 }else if( c=='f' ){
2082 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002083 }else if( c=='r' ){
2084 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002085 }else if( c=='"' ){
2086 c = '"';
2087 }else if( c=='\'' ){
2088 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002089 }else if( c=='\\' ){
2090 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002091 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002092 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002093 if( z[i+1]>='0' && z[i+1]<='7' ){
2094 i++;
2095 c = (c<<3) + z[i] - '0';
2096 if( z[i+1]>='0' && z[i+1]<='7' ){
2097 i++;
2098 c = (c<<3) + z[i] - '0';
2099 }
2100 }
2101 }
2102 }
2103 z[j] = c;
2104 }
drhc2ce0be2014-05-29 12:36:14 +00002105 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002106}
2107
2108/*
drh348d19c2013-06-03 12:47:43 +00002109** Return the value of a hexadecimal digit. Return -1 if the input
2110** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002111*/
drh348d19c2013-06-03 12:47:43 +00002112static int hexDigitValue(char c){
2113 if( c>='0' && c<='9' ) return c - '0';
2114 if( c>='a' && c<='f' ) return c - 'a' + 10;
2115 if( c>='A' && c<='F' ) return c - 'A' + 10;
2116 return -1;
drhc28490c2006-10-26 14:25:58 +00002117}
2118
2119/*
drh7d9f3942013-04-03 01:26:54 +00002120** Interpret zArg as an integer value, possibly with suffixes.
2121*/
2122static sqlite3_int64 integerValue(const char *zArg){
2123 sqlite3_int64 v = 0;
2124 static const struct { char *zSuffix; int iMult; } aMult[] = {
2125 { "KiB", 1024 },
2126 { "MiB", 1024*1024 },
2127 { "GiB", 1024*1024*1024 },
2128 { "KB", 1000 },
2129 { "MB", 1000000 },
2130 { "GB", 1000000000 },
2131 { "K", 1000 },
2132 { "M", 1000000 },
2133 { "G", 1000000000 },
2134 };
2135 int i;
2136 int isNeg = 0;
2137 if( zArg[0]=='-' ){
2138 isNeg = 1;
2139 zArg++;
2140 }else if( zArg[0]=='+' ){
2141 zArg++;
2142 }
drh348d19c2013-06-03 12:47:43 +00002143 if( zArg[0]=='0' && zArg[1]=='x' ){
2144 int x;
2145 zArg += 2;
2146 while( (x = hexDigitValue(zArg[0]))>=0 ){
2147 v = (v<<4) + x;
2148 zArg++;
2149 }
2150 }else{
2151 while( IsDigit(zArg[0]) ){
2152 v = v*10 + zArg[0] - '0';
2153 zArg++;
2154 }
drh7d9f3942013-04-03 01:26:54 +00002155 }
drhc2bed0a2013-05-24 11:57:50 +00002156 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002157 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2158 v *= aMult[i].iMult;
2159 break;
2160 }
2161 }
2162 return isNeg? -v : v;
2163}
2164
2165/*
drh348d19c2013-06-03 12:47:43 +00002166** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2167** for TRUE and FALSE. Return the integer value if appropriate.
2168*/
2169static int booleanValue(char *zArg){
2170 int i;
2171 if( zArg[0]=='0' && zArg[1]=='x' ){
2172 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2173 }else{
2174 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2175 }
2176 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2177 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2178 return 1;
2179 }
2180 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2181 return 0;
2182 }
mistachkinaae280e2015-12-31 19:06:24 +00002183 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002184 zArg);
2185 return 0;
2186}
2187
2188/*
drh42f64e52012-04-04 16:56:23 +00002189** Close an output file, assuming it is not stderr or stdout
2190*/
2191static void output_file_close(FILE *f){
2192 if( f && f!=stdout && f!=stderr ) fclose(f);
2193}
2194
2195/*
2196** Try to open an output file. The names "stdout" and "stderr" are
2197** recognized and do the right thing. NULL is returned if the output
2198** filename is "off".
2199*/
2200static FILE *output_file_open(const char *zFile){
2201 FILE *f;
2202 if( strcmp(zFile,"stdout")==0 ){
2203 f = stdout;
2204 }else if( strcmp(zFile, "stderr")==0 ){
2205 f = stderr;
2206 }else if( strcmp(zFile, "off")==0 ){
2207 f = 0;
2208 }else{
2209 f = fopen(zFile, "wb");
2210 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002211 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002212 }
2213 }
2214 return f;
2215}
2216
2217/*
2218** A routine for handling output from sqlite3_trace().
2219*/
2220static void sql_trace_callback(void *pArg, const char *z){
2221 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002222 if( f ){
2223 int i = (int)strlen(z);
2224 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002225 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002226 }
drh42f64e52012-04-04 16:56:23 +00002227}
2228
2229/*
drhd8621b92012-04-17 09:09:33 +00002230** A no-op routine that runs with the ".breakpoint" doc-command. This is
2231** a useful spot to set a debugger breakpoint.
2232*/
2233static void test_breakpoint(void){
2234 static int nCall = 0;
2235 nCall++;
2236}
2237
2238/*
mistachkin636bf9f2014-07-19 20:15:16 +00002239** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002240*/
mistachkin636bf9f2014-07-19 20:15:16 +00002241typedef struct ImportCtx ImportCtx;
2242struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002243 const char *zFile; /* Name of the input file */
2244 FILE *in; /* Read the CSV text from this input stream */
2245 char *z; /* Accumulated text for a field */
2246 int n; /* Number of bytes in z */
2247 int nAlloc; /* Space allocated for z[] */
2248 int nLine; /* Current line number */
2249 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002250 int cColSep; /* The column separator character. (Usually ",") */
2251 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002252};
2253
2254/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002255static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002256 if( p->n+1>=p->nAlloc ){
2257 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002258 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002259 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002260 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002261 exit(1);
2262 }
2263 }
2264 p->z[p->n++] = (char)c;
2265}
2266
2267/* Read a single field of CSV text. Compatible with rfc4180 and extended
2268** with the option of having a separator other than ",".
2269**
2270** + Input comes from p->in.
2271** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002272** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002273** + Use p->cSep as the column separator. The default is ",".
2274** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002275** + Keep track of the line number in p->nLine.
2276** + Store the character that terminates the field in p->cTerm. Store
2277** EOF on end-of-file.
2278** + Report syntax errors on stderr
2279*/
mistachkin44723ce2015-03-21 02:22:37 +00002280static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002281 int c;
2282 int cSep = p->cColSep;
2283 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002284 p->n = 0;
2285 c = fgetc(p->in);
2286 if( c==EOF || seenInterrupt ){
2287 p->cTerm = EOF;
2288 return 0;
2289 }
2290 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002291 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002292 int startLine = p->nLine;
2293 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002294 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002295 while( 1 ){
2296 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002297 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002298 if( c==cQuote ){
2299 if( pc==cQuote ){
2300 pc = 0;
2301 continue;
2302 }
2303 }
2304 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002305 || (c==rSep && pc==cQuote)
2306 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002307 || (c==EOF && pc==cQuote)
2308 ){
2309 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002310 p->cTerm = c;
2311 break;
2312 }
2313 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002314 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002315 p->zFile, p->nLine, cQuote);
2316 }
2317 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002318 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002319 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002320 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002321 break;
2322 }
mistachkin636bf9f2014-07-19 20:15:16 +00002323 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002324 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002325 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002326 }
drhdb95f682013-06-26 22:46:00 +00002327 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002328 while( c!=EOF && c!=cSep && c!=rSep ){
2329 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002330 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002331 }
mistachkin636bf9f2014-07-19 20:15:16 +00002332 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002333 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002334 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002335 }
drhdb95f682013-06-26 22:46:00 +00002336 p->cTerm = c;
2337 }
drh8dd675e2013-07-12 21:09:24 +00002338 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002339 return p->z;
2340}
2341
mistachkin636bf9f2014-07-19 20:15:16 +00002342/* Read a single field of ASCII delimited text.
2343**
2344** + Input comes from p->in.
2345** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002346** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002347** + Use p->cSep as the column separator. The default is "\x1F".
2348** + Use p->rSep as the row separator. The default is "\x1E".
2349** + Keep track of the row number in p->nLine.
2350** + Store the character that terminates the field in p->cTerm. Store
2351** EOF on end-of-file.
2352** + Report syntax errors on stderr
2353*/
mistachkin44723ce2015-03-21 02:22:37 +00002354static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002355 int c;
2356 int cSep = p->cColSep;
2357 int rSep = p->cRowSep;
2358 p->n = 0;
2359 c = fgetc(p->in);
2360 if( c==EOF || seenInterrupt ){
2361 p->cTerm = EOF;
2362 return 0;
2363 }
2364 while( c!=EOF && c!=cSep && c!=rSep ){
2365 import_append_char(p, c);
2366 c = fgetc(p->in);
2367 }
2368 if( c==rSep ){
2369 p->nLine++;
2370 }
2371 p->cTerm = c;
2372 if( p->z ) p->z[p->n] = 0;
2373 return p->z;
2374}
2375
drhdb95f682013-06-26 22:46:00 +00002376/*
drh4bbcf102014-02-06 02:46:08 +00002377** Try to transfer data for table zTable. If an error is seen while
2378** moving forward, try to go backwards. The backwards movement won't
2379** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002380*/
mistachkine31ae902014-02-06 01:15:29 +00002381static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002382 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002383 sqlite3 *newDb,
2384 const char *zTable
2385){
2386 sqlite3_stmt *pQuery = 0;
2387 sqlite3_stmt *pInsert = 0;
2388 char *zQuery = 0;
2389 char *zInsert = 0;
2390 int rc;
2391 int i, j, n;
2392 int nTable = (int)strlen(zTable);
2393 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002394 int cnt = 0;
2395 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002396
2397 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2398 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2399 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002400 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002401 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2402 zQuery);
2403 goto end_data_xfer;
2404 }
2405 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002406 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002407 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002408 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002409 goto end_data_xfer;
2410 }
2411 sqlite3_snprintf(200+nTable,zInsert,
2412 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2413 i = (int)strlen(zInsert);
2414 for(j=1; j<n; j++){
2415 memcpy(zInsert+i, ",?", 2);
2416 i += 2;
2417 }
2418 memcpy(zInsert+i, ");", 3);
2419 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 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(newDb), sqlite3_errmsg(newDb),
2423 zQuery);
2424 goto end_data_xfer;
2425 }
2426 for(k=0; k<2; k++){
2427 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2428 for(i=0; i<n; i++){
2429 switch( sqlite3_column_type(pQuery, i) ){
2430 case SQLITE_NULL: {
2431 sqlite3_bind_null(pInsert, i+1);
2432 break;
2433 }
2434 case SQLITE_INTEGER: {
2435 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2436 break;
2437 }
2438 case SQLITE_FLOAT: {
2439 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2440 break;
2441 }
2442 case SQLITE_TEXT: {
2443 sqlite3_bind_text(pInsert, i+1,
2444 (const char*)sqlite3_column_text(pQuery,i),
2445 -1, SQLITE_STATIC);
2446 break;
2447 }
2448 case SQLITE_BLOB: {
2449 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2450 sqlite3_column_bytes(pQuery,i),
2451 SQLITE_STATIC);
2452 break;
2453 }
2454 }
2455 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002456 rc = sqlite3_step(pInsert);
2457 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002458 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002459 sqlite3_errmsg(newDb));
2460 }
drh3350ce92014-02-06 00:49:12 +00002461 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002462 cnt++;
2463 if( (cnt%spinRate)==0 ){
2464 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2465 fflush(stdout);
2466 }
drh3350ce92014-02-06 00:49:12 +00002467 } /* End while */
2468 if( rc==SQLITE_DONE ) break;
2469 sqlite3_finalize(pQuery);
2470 sqlite3_free(zQuery);
2471 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2472 zTable);
2473 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2474 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002475 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002476 break;
drh3350ce92014-02-06 00:49:12 +00002477 }
2478 } /* End for(k=0...) */
2479
2480end_data_xfer:
2481 sqlite3_finalize(pQuery);
2482 sqlite3_finalize(pInsert);
2483 sqlite3_free(zQuery);
2484 sqlite3_free(zInsert);
2485}
2486
2487
2488/*
2489** Try to transfer all rows of the schema that match zWhere. For
2490** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002491** If an error is encountered while moving forward through the
2492** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002493*/
mistachkine31ae902014-02-06 01:15:29 +00002494static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002495 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002496 sqlite3 *newDb,
2497 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002498 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002499){
2500 sqlite3_stmt *pQuery = 0;
2501 char *zQuery = 0;
2502 int rc;
2503 const unsigned char *zName;
2504 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002505 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002506
2507 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2508 " WHERE %s", zWhere);
2509 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2510 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002511 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002512 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2513 zQuery);
2514 goto end_schema_xfer;
2515 }
2516 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2517 zName = sqlite3_column_text(pQuery, 0);
2518 zSql = sqlite3_column_text(pQuery, 1);
2519 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002520 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2521 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002522 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002523 sqlite3_free(zErrMsg);
2524 zErrMsg = 0;
2525 }
drh3350ce92014-02-06 00:49:12 +00002526 if( xForEach ){
2527 xForEach(p, newDb, (const char*)zName);
2528 }
2529 printf("done\n");
2530 }
2531 if( rc!=SQLITE_DONE ){
2532 sqlite3_finalize(pQuery);
2533 sqlite3_free(zQuery);
2534 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2535 " WHERE %s ORDER BY rowid DESC", zWhere);
2536 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2537 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002538 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002539 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2540 zQuery);
2541 goto end_schema_xfer;
2542 }
2543 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2544 zName = sqlite3_column_text(pQuery, 0);
2545 zSql = sqlite3_column_text(pQuery, 1);
2546 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002547 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2548 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002549 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002550 sqlite3_free(zErrMsg);
2551 zErrMsg = 0;
2552 }
drh3350ce92014-02-06 00:49:12 +00002553 if( xForEach ){
2554 xForEach(p, newDb, (const char*)zName);
2555 }
2556 printf("done\n");
2557 }
2558 }
2559end_schema_xfer:
2560 sqlite3_finalize(pQuery);
2561 sqlite3_free(zQuery);
2562}
2563
2564/*
2565** Open a new database file named "zNewDb". Try to recover as much information
2566** as possible out of the main database (which might be corrupt) and write it
2567** into zNewDb.
2568*/
drhdcd87a92014-08-18 13:45:42 +00002569static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002570 int rc;
2571 sqlite3 *newDb = 0;
2572 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002573 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002574 return;
2575 }
2576 rc = sqlite3_open(zNewDb, &newDb);
2577 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002578 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002579 sqlite3_errmsg(newDb));
2580 }else{
drh54d0d2d2014-04-03 00:32:13 +00002581 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002582 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002583 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2584 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002585 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002586 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002587 }
2588 sqlite3_close(newDb);
2589}
2590
2591/*
drhc2ce0be2014-05-29 12:36:14 +00002592** Change the output file back to stdout
2593*/
drhdcd87a92014-08-18 13:45:42 +00002594static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002595 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002596#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002597 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002598#endif
drhc2ce0be2014-05-29 12:36:14 +00002599 }else{
2600 output_file_close(p->out);
2601 }
2602 p->outfile[0] = 0;
2603 p->out = stdout;
2604}
2605
2606/*
drhf7502f02015-02-06 14:19:44 +00002607** Run an SQL command and return the single integer result.
2608*/
2609static int db_int(ShellState *p, const char *zSql){
2610 sqlite3_stmt *pStmt;
2611 int res = 0;
2612 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2613 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2614 res = sqlite3_column_int(pStmt,0);
2615 }
2616 sqlite3_finalize(pStmt);
2617 return res;
2618}
2619
2620/*
2621** Convert a 2-byte or 4-byte big-endian integer into a native integer
2622*/
2623unsigned int get2byteInt(unsigned char *a){
2624 return (a[0]<<8) + a[1];
2625}
2626unsigned int get4byteInt(unsigned char *a){
2627 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2628}
2629
2630/*
2631** Implementation of the ".info" command.
2632**
2633** Return 1 on error, 2 to exit, and 0 otherwise.
2634*/
drh0e55db12015-02-06 14:51:13 +00002635static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002636 static const struct { const char *zName; int ofst; } aField[] = {
2637 { "file change counter:", 24 },
2638 { "database page count:", 28 },
2639 { "freelist page count:", 36 },
2640 { "schema cookie:", 40 },
2641 { "schema format:", 44 },
2642 { "default cache size:", 48 },
2643 { "autovacuum top root:", 52 },
2644 { "incremental vacuum:", 64 },
2645 { "text encoding:", 56 },
2646 { "user version:", 60 },
2647 { "application id:", 68 },
2648 { "software version:", 96 },
2649 };
drh0e55db12015-02-06 14:51:13 +00002650 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2651 { "number of tables:",
2652 "SELECT count(*) FROM %s WHERE type='table'" },
2653 { "number of indexes:",
2654 "SELECT count(*) FROM %s WHERE type='index'" },
2655 { "number of triggers:",
2656 "SELECT count(*) FROM %s WHERE type='trigger'" },
2657 { "number of views:",
2658 "SELECT count(*) FROM %s WHERE type='view'" },
2659 { "schema size:",
2660 "SELECT total(length(sql)) FROM %s" },
2661 };
mistachkinbfe8bd52015-11-17 19:17:14 +00002662 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00002663 int i;
2664 char *zSchemaTab;
2665 char *zDb = nArg>=2 ? azArg[1] : "main";
2666 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002667 open_db(p, 0);
2668 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002669 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002670 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2671 return 1;
2672 }
2673 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2674 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00002675 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00002676 return 1;
2677 }
2678 i = get2byteInt(aHdr+16);
2679 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00002680 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
2681 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2682 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2683 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00002684 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00002685 int ofst = aField[i].ofst;
2686 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00002687 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00002688 switch( ofst ){
2689 case 56: {
mistachkinaae280e2015-12-31 19:06:24 +00002690 if( val==1 ) raw_printf(p->out, " (utf8)");
2691 if( val==2 ) raw_printf(p->out, " (utf16le)");
2692 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00002693 }
2694 }
mistachkinaae280e2015-12-31 19:06:24 +00002695 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00002696 }
drh0e55db12015-02-06 14:51:13 +00002697 if( zDb==0 ){
2698 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2699 }else if( strcmp(zDb,"temp")==0 ){
2700 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2701 }else{
2702 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2703 }
drhf5ed7ad2015-06-15 14:43:25 +00002704 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00002705 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2706 int val = db_int(p, zSql);
2707 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00002708 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00002709 }
2710 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002711 return 0;
2712}
2713
dand95bb392015-09-30 11:19:05 +00002714/*
2715** Print the current sqlite3_errmsg() value to stderr and return 1.
2716*/
2717static int shellDatabaseError(sqlite3 *db){
2718 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00002719 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00002720 return 1;
2721}
2722
2723/*
2724** Print an out-of-memory message to stderr and return 1.
2725*/
2726static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00002727 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00002728 return 1;
2729}
drhf7502f02015-02-06 14:19:44 +00002730
2731/*
drh75897232000-05-29 14:26:00 +00002732** If an input line begins with "." then invoke this routine to
2733** process that line.
drh67505e72002-04-19 12:34:06 +00002734**
drh47ad6842006-11-08 12:25:42 +00002735** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002736*/
drhdcd87a92014-08-18 13:45:42 +00002737static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00002738 int h = 1;
drh75897232000-05-29 14:26:00 +00002739 int nArg = 0;
2740 int n, c;
drh67505e72002-04-19 12:34:06 +00002741 int rc = 0;
drh75897232000-05-29 14:26:00 +00002742 char *azArg[50];
2743
2744 /* Parse the input line into tokens.
2745 */
mistachkin8e189222015-04-19 21:43:16 +00002746 while( zLine[h] && nArg<ArraySize(azArg) ){
2747 while( IsSpace(zLine[h]) ){ h++; }
2748 if( zLine[h]==0 ) break;
2749 if( zLine[h]=='\'' || zLine[h]=='"' ){
2750 int delim = zLine[h++];
2751 azArg[nArg++] = &zLine[h];
2752 while( zLine[h] && zLine[h]!=delim ){
2753 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
2754 h++;
drh4c56b992013-06-27 13:26:55 +00002755 }
mistachkin8e189222015-04-19 21:43:16 +00002756 if( zLine[h]==delim ){
2757 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00002758 }
drhfeac5f82004-08-01 00:10:45 +00002759 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002760 }else{
mistachkin8e189222015-04-19 21:43:16 +00002761 azArg[nArg++] = &zLine[h];
2762 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
2763 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002764 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002765 }
2766 }
2767
2768 /* Process the input line.
2769 */
shane9bd1b442009-10-23 01:27:39 +00002770 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002771 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002772 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002773 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2774 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2775 ){
drhbc46f022013-01-23 18:53:23 +00002776 const char *zDestFile = 0;
2777 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002778 sqlite3 *pDest;
2779 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002780 int j;
2781 for(j=1; j<nArg; j++){
2782 const char *z = azArg[j];
2783 if( z[0]=='-' ){
2784 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002785 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002786 {
mistachkinaae280e2015-12-31 19:06:24 +00002787 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00002788 return 1;
2789 }
2790 }else if( zDestFile==0 ){
2791 zDestFile = azArg[j];
2792 }else if( zDb==0 ){
2793 zDb = zDestFile;
2794 zDestFile = azArg[j];
2795 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002796 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00002797 return 1;
2798 }
drh9ff849f2009-02-04 20:55:57 +00002799 }
drhbc46f022013-01-23 18:53:23 +00002800 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002801 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00002802 return 1;
2803 }
2804 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002805 rc = sqlite3_open(zDestFile, &pDest);
2806 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00002807 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002808 sqlite3_close(pDest);
2809 return 1;
2810 }
drh05782482013-10-24 15:20:20 +00002811 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002812 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2813 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002814 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00002815 sqlite3_close(pDest);
2816 return 1;
2817 }
2818 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2819 sqlite3_backup_finish(pBackup);
2820 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002821 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002822 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002823 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002824 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002825 }
2826 sqlite3_close(pDest);
2827 }else
2828
drhc2ce0be2014-05-29 12:36:14 +00002829 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2830 if( nArg==2 ){
2831 bail_on_error = booleanValue(azArg[1]);
2832 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002833 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00002834 rc = 1;
2835 }
drhc49f44e2006-10-26 18:15:42 +00002836 }else
2837
mistachkinf21979d2015-01-18 05:35:01 +00002838 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
2839 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00002840 if( booleanValue(azArg[1]) ){
2841 setBinaryMode(p->out);
2842 }else{
2843 setTextMode(p->out);
2844 }
mistachkinf21979d2015-01-18 05:35:01 +00002845 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002846 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00002847 rc = 1;
2848 }
2849 }else
2850
drhd8621b92012-04-17 09:09:33 +00002851 /* The undocumented ".breakpoint" command causes a call to the no-op
2852 ** routine named test_breakpoint().
2853 */
2854 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2855 test_breakpoint();
2856 }else
2857
drhdf12f1c2015-12-07 21:46:19 +00002858 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
2859 if( nArg==2 ){
2860 p->countChanges = booleanValue(azArg[1]);
2861 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002862 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00002863 rc = 1;
2864 }
2865 }else
2866
drhc2ce0be2014-05-29 12:36:14 +00002867 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2868 if( nArg==2 ){
2869 tryToClone(p, azArg[1]);
2870 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002871 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00002872 rc = 1;
2873 }
mistachkine31ae902014-02-06 01:15:29 +00002874 }else
2875
drhc2ce0be2014-05-29 12:36:14 +00002876 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002877 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002878 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002879 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002880 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002881 data.showHeader = 1;
drh700c2522016-02-09 18:39:25 +00002882 data.cMode = data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002883 data.colWidth[0] = 3;
2884 data.colWidth[1] = 15;
2885 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002886 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002887 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002888 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002889 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002890 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002891 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002892 }
2893 }else
2894
drh0e55db12015-02-06 14:51:13 +00002895 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2896 rc = shell_dbinfo_command(p, nArg, azArg);
2897 }else
2898
drhc2ce0be2014-05-29 12:36:14 +00002899 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002900 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002901 /* When playing back a "dump", the content might appear in an order
2902 ** which causes immediate foreign key constraints to be violated.
2903 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002904 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00002905 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00002906 rc = 1;
2907 goto meta_command_exit;
2908 }
mistachkinaae280e2015-12-31 19:06:24 +00002909 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
2910 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002911 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002912 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002913 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002914 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002915 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002916 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002917 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002918 );
2919 run_schema_dump_query(p,
2920 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002921 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002922 );
drh2f464a02011-10-13 00:41:49 +00002923 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002924 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002925 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002926 );
drh4c653a02000-06-07 01:27:47 +00002927 }else{
2928 int i;
drhdd3d4592004-08-30 01:54:05 +00002929 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002930 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002931 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002932 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002933 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002934 " AND sql NOT NULL");
2935 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002936 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002937 "WHERE sql NOT NULL"
2938 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002939 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002940 );
danielk1977bc6ada42004-06-30 08:20:16 +00002941 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002942 }
2943 }
drh45e29d82006-11-20 16:21:10 +00002944 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00002945 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002946 p->writableSchema = 0;
2947 }
drh56197952011-10-13 16:30:13 +00002948 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2949 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00002950 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002951 }else
drh75897232000-05-29 14:26:00 +00002952
drhc2ce0be2014-05-29 12:36:14 +00002953 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2954 if( nArg==2 ){
2955 p->echoOn = booleanValue(azArg[1]);
2956 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002957 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00002958 rc = 1;
2959 }
drhdaffd0e2001-04-11 14:28:42 +00002960 }else
2961
drhc2ce0be2014-05-29 12:36:14 +00002962 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2963 if( nArg==2 ){
2964 p->autoEQP = booleanValue(azArg[1]);
2965 }else{
mistachkinaae280e2015-12-31 19:06:24 +00002966 raw_printf(stderr, "Usage: .eqp on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00002967 rc = 1;
2968 }
drhefbf3b12014-02-28 20:47:24 +00002969 }else
2970
drhd3ac7d92013-01-25 18:33:43 +00002971 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002972 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002973 rc = 2;
drh75897232000-05-29 14:26:00 +00002974 }else
2975
drhc2ce0be2014-05-29 12:36:14 +00002976 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00002977 int val = 1;
2978 if( nArg>=2 ){
2979 if( strcmp(azArg[1],"auto")==0 ){
2980 val = 99;
2981 }else{
2982 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00002983 }
drh700c2522016-02-09 18:39:25 +00002984 }
2985 if( val==1 && p->mode!=MODE_Explain ){
2986 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00002987 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00002988 p->autoExplain = 0;
2989 }else if( val==0 ){
2990 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
2991 p->autoExplain = 0;
2992 }else if( val==99 ){
2993 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
2994 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002995 }
drh75897232000-05-29 14:26:00 +00002996 }else
2997
drhc1971542014-06-23 23:28:13 +00002998 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002999 ShellState data;
drhc1971542014-06-23 23:28:13 +00003000 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003001 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00003002 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003003 raw_printf(stderr, "Usage: .fullschema\n");
drhc1971542014-06-23 23:28:13 +00003004 rc = 1;
3005 goto meta_command_exit;
3006 }
3007 open_db(p, 0);
3008 memcpy(&data, p, sizeof(data));
3009 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003010 data.cMode = data.mode = MODE_Semi;
drhc1971542014-06-23 23:28:13 +00003011 rc = sqlite3_exec(p->db,
3012 "SELECT sql FROM"
3013 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3014 " FROM sqlite_master UNION ALL"
3015 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003016 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003017 "ORDER BY rowid",
3018 callback, &data, &zErrMsg
3019 );
drh56f674c2014-07-18 14:43:29 +00003020 if( rc==SQLITE_OK ){
3021 sqlite3_stmt *pStmt;
3022 rc = sqlite3_prepare_v2(p->db,
3023 "SELECT rowid FROM sqlite_master"
3024 " WHERE name GLOB 'sqlite_stat[134]'",
3025 -1, &pStmt, 0);
3026 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3027 sqlite3_finalize(pStmt);
3028 }
3029 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003030 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003031 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003032 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003033 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3034 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003035 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003036 data.zDestTable = "sqlite_stat1";
3037 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3038 shell_callback, &data,&zErrMsg);
3039 data.zDestTable = "sqlite_stat3";
3040 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3041 shell_callback, &data,&zErrMsg);
3042 data.zDestTable = "sqlite_stat4";
3043 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3044 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003045 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003046 }
drhc1971542014-06-23 23:28:13 +00003047 }else
3048
drhc2ce0be2014-05-29 12:36:14 +00003049 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3050 if( nArg==2 ){
3051 p->showHeader = booleanValue(azArg[1]);
3052 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003053 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003054 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003055 }
drh75897232000-05-29 14:26:00 +00003056 }else
3057
drhc2ce0be2014-05-29 12:36:14 +00003058 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003059 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003060 }else
3061
3062 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003063 char *zTable; /* Insert data into this table */
3064 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003065 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003066 int nCol; /* Number of columns in the table */
3067 int nByte; /* Number of bytes in an SQL string */
3068 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003069 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003070 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003071 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003072 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003073 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3074 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003075
drhc2ce0be2014-05-29 12:36:14 +00003076 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003077 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003078 goto meta_command_exit;
3079 }
drh01f37542014-05-31 15:43:33 +00003080 zFile = azArg[1];
3081 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003082 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003083 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003084 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003085 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003086 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003087 raw_printf(stderr,
3088 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003089 return 1;
drhfeac5f82004-08-01 00:10:45 +00003090 }
drhdb95f682013-06-26 22:46:00 +00003091 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003092 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003093 " for import\n");
3094 return 1;
3095 }
mistachkin636bf9f2014-07-19 20:15:16 +00003096 nSep = strlen30(p->rowSeparator);
3097 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003098 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003099 return 1;
3100 }
mistachkine0d68852014-12-11 03:12:33 +00003101 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3102 /* When importing CSV (only), if the row separator is set to the
3103 ** default output row separator, change it to the default input
3104 ** row separator. This avoids having to maintain different input
3105 ** and output row separators. */
3106 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3107 nSep = strlen30(p->rowSeparator);
3108 }
mistachkin636bf9f2014-07-19 20:15:16 +00003109 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003110 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003111 " for import\n");
3112 return 1;
3113 }
3114 sCtx.zFile = zFile;
3115 sCtx.nLine = 1;
3116 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003117#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003118 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003119 return 1;
3120#else
mistachkin636bf9f2014-07-19 20:15:16 +00003121 sCtx.in = popen(sCtx.zFile+1, "r");
3122 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003123 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003124#endif
drh5bde8162013-06-27 14:07:53 +00003125 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003126 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003127 xCloser = fclose;
3128 }
mistachkin636bf9f2014-07-19 20:15:16 +00003129 if( p->mode==MODE_Ascii ){
3130 xRead = ascii_read_one_field;
3131 }else{
3132 xRead = csv_read_one_field;
3133 }
3134 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003135 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003136 return 1;
3137 }
mistachkin636bf9f2014-07-19 20:15:16 +00003138 sCtx.cColSep = p->colSeparator[0];
3139 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003140 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003141 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003142 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003143 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003144 return 1;
3145 }
drh4f21c4a2008-12-10 22:15:00 +00003146 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003147 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003148 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003149 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003150 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3151 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003152 while( xRead(&sCtx) ){
3153 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003154 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003155 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003156 }
drh5bde8162013-06-27 14:07:53 +00003157 if( cSep=='(' ){
3158 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003159 sqlite3_free(sCtx.z);
3160 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003161 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003162 return 1;
3163 }
drhdb95f682013-06-26 22:46:00 +00003164 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3165 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3166 sqlite3_free(zCreate);
3167 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003168 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003169 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003170 sqlite3_free(sCtx.z);
3171 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003172 return 1;
3173 }
drhc7181902014-02-27 15:04:13 +00003174 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003175 }
drhfeac5f82004-08-01 00:10:45 +00003176 sqlite3_free(zSql);
3177 if( rc ){
shane916f9612009-10-23 00:37:15 +00003178 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00003179 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003180 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003181 return 1;
drhfeac5f82004-08-01 00:10:45 +00003182 }
shane916f9612009-10-23 00:37:15 +00003183 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003184 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003185 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003186 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003187 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003188 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003189 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003190 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003191 return 1;
3192 }
drhdb95f682013-06-26 22:46:00 +00003193 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003194 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003195 for(i=1; i<nCol; i++){
3196 zSql[j++] = ',';
3197 zSql[j++] = '?';
3198 }
3199 zSql[j++] = ')';
3200 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003201 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003202 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003203 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003204 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003205 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003206 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003207 return 1;
drhfeac5f82004-08-01 00:10:45 +00003208 }
mistachkin8e189222015-04-19 21:43:16 +00003209 needCommit = sqlite3_get_autocommit(p->db);
3210 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003211 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003212 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003213 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003214 char *z = xRead(&sCtx);
3215 /*
3216 ** Did we reach end-of-file before finding any columns?
3217 ** If so, stop instead of NULL filling the remaining columns.
3218 */
drhdb95f682013-06-26 22:46:00 +00003219 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003220 /*
3221 ** Did we reach end-of-file OR end-of-line before finding any
3222 ** columns in ASCII mode? If so, stop instead of NULL filling
3223 ** the remaining columns.
3224 */
3225 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003226 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003227 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00003228 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003229 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003230 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003231 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003232 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003233 }
drhfeac5f82004-08-01 00:10:45 +00003234 }
mistachkin636bf9f2014-07-19 20:15:16 +00003235 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003236 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003237 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003238 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003239 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00003240 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003241 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003242 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003243 }
drhdb95f682013-06-26 22:46:00 +00003244 if( i>=nCol ){
3245 sqlite3_step(pStmt);
3246 rc = sqlite3_reset(pStmt);
3247 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003248 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
3249 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003250 }
3251 }
mistachkin636bf9f2014-07-19 20:15:16 +00003252 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003253
mistachkin636bf9f2014-07-19 20:15:16 +00003254 xCloser(sCtx.in);
3255 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003256 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003257 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003258 }else
3259
drh0e55db12015-02-06 14:51:13 +00003260 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3261 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003262 ShellState data;
drh75897232000-05-29 14:26:00 +00003263 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003264 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003265 memcpy(&data, p, sizeof(data));
3266 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003267 data.cMode = data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003268 if( nArg==1 ){
3269 rc = sqlite3_exec(p->db,
3270 "SELECT name FROM sqlite_master "
3271 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3272 "UNION ALL "
3273 "SELECT name FROM sqlite_temp_master "
3274 "WHERE type='index' "
3275 "ORDER BY 1",
3276 callback, &data, &zErrMsg
3277 );
drhc2ce0be2014-05-29 12:36:14 +00003278 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003279 zShellStatic = azArg[1];
3280 rc = sqlite3_exec(p->db,
3281 "SELECT name FROM sqlite_master "
3282 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3283 "UNION ALL "
3284 "SELECT name FROM sqlite_temp_master "
3285 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3286 "ORDER BY 1",
3287 callback, &data, &zErrMsg
3288 );
3289 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003290 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003291 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003292 rc = 1;
3293 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003294 }
drh75897232000-05-29 14:26:00 +00003295 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003296 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003297 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003298 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003299 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003300 raw_printf(stderr,
3301 "Error: querying sqlite_master and sqlite_temp_master\n");
shane86f5bdb2009-10-24 02:00:07 +00003302 rc = 1;
drh75897232000-05-29 14:26:00 +00003303 }
3304 }else
3305
drhae5e4452007-05-03 17:18:36 +00003306#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003307 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003308 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003309 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3310 iotrace = 0;
3311 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003312 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003313 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003314 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003315 iotrace = stdout;
3316 }else{
3317 iotrace = fopen(azArg[1], "w");
3318 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003319 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003320 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003321 rc = 1;
drhb0603412007-02-28 04:47:26 +00003322 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003323 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003324 }
3325 }
3326 }else
drhae5e4452007-05-03 17:18:36 +00003327#endif
drh1a513372015-05-02 17:40:23 +00003328 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3329 static const struct {
3330 const char *zLimitName; /* Name of a limit */
3331 int limitCode; /* Integer code for that limit */
3332 } aLimit[] = {
3333 { "length", SQLITE_LIMIT_LENGTH },
3334 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3335 { "column", SQLITE_LIMIT_COLUMN },
3336 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3337 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3338 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3339 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3340 { "attached", SQLITE_LIMIT_ATTACHED },
3341 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3342 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3343 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3344 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3345 };
3346 int i, n2;
3347 open_db(p, 0);
3348 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003349 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003350 printf("%20s %d\n", aLimit[i].zLimitName,
3351 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3352 }
3353 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003354 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00003355 rc = 1;
3356 goto meta_command_exit;
3357 }else{
3358 int iLimit = -1;
3359 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003360 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003361 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3362 if( iLimit<0 ){
3363 iLimit = i;
3364 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003365 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00003366 rc = 1;
3367 goto meta_command_exit;
3368 }
3369 }
3370 }
3371 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003372 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00003373 "enter \".limits\" with no arguments for a list.\n",
3374 azArg[1]);
3375 rc = 1;
3376 goto meta_command_exit;
3377 }
3378 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003379 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3380 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003381 }
3382 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3383 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3384 }
3385 }else
drhb0603412007-02-28 04:47:26 +00003386
drh70df4fe2006-06-13 15:12:21 +00003387#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003388 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003389 const char *zFile, *zProc;
3390 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003391 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003392 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00003393 rc = 1;
3394 goto meta_command_exit;
3395 }
drh1e397f82006-06-08 15:28:43 +00003396 zFile = azArg[1];
3397 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003398 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003399 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3400 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003401 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003402 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003403 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003404 }
3405 }else
drh70df4fe2006-06-13 15:12:21 +00003406#endif
drh1e397f82006-06-08 15:28:43 +00003407
drhc2ce0be2014-05-29 12:36:14 +00003408 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3409 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003410 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003411 rc = 1;
3412 }else{
3413 const char *zFile = azArg[1];
3414 output_file_close(p->pLog);
3415 p->pLog = output_file_open(zFile);
3416 }
drh127f9d72010-02-23 01:47:00 +00003417 }else
3418
drhc2ce0be2014-05-29 12:36:14 +00003419 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3420 const char *zMode = nArg>=2 ? azArg[1] : "";
3421 int n2 = (int)strlen(zMode);
3422 int c2 = zMode[0];
3423 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003424 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003425 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003426 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003427 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003428 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003429 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003430 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003431 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003432 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003433 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003434 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003435 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003436 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003437 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003438 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003439 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003440 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003441 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003442 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003443 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003444 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3445 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003446 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3447 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003448 }else {
mistachkinaae280e2015-12-31 19:06:24 +00003449 raw_printf(stderr, "Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003450 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003451 rc = 1;
drh75897232000-05-29 14:26:00 +00003452 }
drh700c2522016-02-09 18:39:25 +00003453 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00003454 }else
3455
drhc2ce0be2014-05-29 12:36:14 +00003456 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3457 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003458 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3459 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003460 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003461 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003462 rc = 1;
3463 }
3464 }else
3465
drh05782482013-10-24 15:20:20 +00003466 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3467 sqlite3 *savedDb = p->db;
3468 const char *zSavedFilename = p->zDbFilename;
3469 char *zNewFilename = 0;
3470 p->db = 0;
drhbbe031f2015-06-17 17:08:22 +00003471 if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3472 p->zDbFilename = zNewFilename;
drh05782482013-10-24 15:20:20 +00003473 open_db(p, 1);
3474 if( p->db!=0 ){
3475 sqlite3_close(savedDb);
3476 sqlite3_free(p->zFreeOnClose);
3477 p->zFreeOnClose = zNewFilename;
3478 }else{
3479 sqlite3_free(zNewFilename);
3480 p->db = savedDb;
3481 p->zDbFilename = zSavedFilename;
3482 }
3483 }else
3484
drhc2ce0be2014-05-29 12:36:14 +00003485 if( c=='o'
3486 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3487 ){
3488 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3489 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003490 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00003491 rc = 1;
3492 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003493 }
drhc2ce0be2014-05-29 12:36:14 +00003494 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3495 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003496 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003497 rc = 1;
3498 goto meta_command_exit;
3499 }
3500 p->outCount = 2;
3501 }else{
3502 p->outCount = 0;
3503 }
3504 output_reset(p);
3505 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003506#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003507 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003508 rc = 1;
3509 p->out = stdout;
3510#else
drhc2ce0be2014-05-29 12:36:14 +00003511 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003512 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003513 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003514 p->out = stdout;
3515 rc = 1;
3516 }else{
drhc2ce0be2014-05-29 12:36:14 +00003517 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003518 }
drh8cd5b252015-03-02 22:06:43 +00003519#endif
drh75897232000-05-29 14:26:00 +00003520 }else{
drhc2ce0be2014-05-29 12:36:14 +00003521 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003522 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003523 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003524 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003525 }
drh75897232000-05-29 14:26:00 +00003526 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003527 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003528 } else {
drhc2ce0be2014-05-29 12:36:14 +00003529 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003530 }
3531 }
3532 }else
3533
drh078b1fd2012-09-21 13:40:02 +00003534 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3535 int i;
3536 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00003537 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00003538 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00003539 }
mistachkinaae280e2015-12-31 19:06:24 +00003540 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00003541 }else
3542
drhc2ce0be2014-05-29 12:36:14 +00003543 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003544 if( nArg >= 2) {
3545 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3546 }
3547 if( nArg >= 3) {
3548 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3549 }
3550 }else
3551
drhc2ce0be2014-05-29 12:36:14 +00003552 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003553 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003554 }else
3555
drhc2ce0be2014-05-29 12:36:14 +00003556 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3557 FILE *alt;
3558 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003559 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003560 rc = 1;
3561 goto meta_command_exit;
3562 }
3563 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003564 if( alt==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003565 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
shane9bd1b442009-10-23 01:27:39 +00003566 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003567 }else{
shane9bd1b442009-10-23 01:27:39 +00003568 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003569 fclose(alt);
3570 }
3571 }else
3572
drhc2ce0be2014-05-29 12:36:14 +00003573 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003574 const char *zSrcFile;
3575 const char *zDb;
3576 sqlite3 *pSrc;
3577 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003578 int nTimeout = 0;
3579
drh9ff849f2009-02-04 20:55:57 +00003580 if( nArg==2 ){
3581 zSrcFile = azArg[1];
3582 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003583 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003584 zSrcFile = azArg[2];
3585 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003586 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003587 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003588 rc = 1;
3589 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003590 }
3591 rc = sqlite3_open(zSrcFile, &pSrc);
3592 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003593 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003594 sqlite3_close(pSrc);
3595 return 1;
3596 }
drh05782482013-10-24 15:20:20 +00003597 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003598 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3599 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003600 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00003601 sqlite3_close(pSrc);
3602 return 1;
3603 }
drhdc2c4912009-02-04 22:46:47 +00003604 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3605 || rc==SQLITE_BUSY ){
3606 if( rc==SQLITE_BUSY ){
3607 if( nTimeout++ >= 3 ) break;
3608 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003609 }
3610 }
3611 sqlite3_backup_finish(pBackup);
3612 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003613 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003614 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00003615 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00003616 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003617 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003618 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003619 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003620 }
3621 sqlite3_close(pSrc);
3622 }else
3623
dan8d1edb92014-11-05 09:07:28 +00003624
3625 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3626 if( nArg==2 ){
3627 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003628#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00003629 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00003630#endif
dan8d1edb92014-11-05 09:07:28 +00003631 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003632 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00003633 rc = 1;
3634 }
3635 }else
3636
drhc2ce0be2014-05-29 12:36:14 +00003637 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003638 ShellState data;
drh75897232000-05-29 14:26:00 +00003639 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003640 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003641 memcpy(&data, p, sizeof(data));
3642 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003643 data.cMode = data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003644 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003645 int i;
drhf0693c82011-10-11 20:41:54 +00003646 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003647 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003648 char *new_argv[2], *new_colv[2];
3649 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3650 " type text,\n"
3651 " name text,\n"
3652 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003653 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003654 " sql text\n"
3655 ")";
3656 new_argv[1] = 0;
3657 new_colv[0] = "sql";
3658 new_colv[1] = 0;
3659 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003660 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003661 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003662 char *new_argv[2], *new_colv[2];
3663 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3664 " type text,\n"
3665 " name text,\n"
3666 " tbl_name text,\n"
3667 " rootpage integer,\n"
3668 " sql text\n"
3669 ")";
3670 new_argv[1] = 0;
3671 new_colv[0] = "sql";
3672 new_colv[1] = 0;
3673 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003674 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003675 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003676 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003677 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003678 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003679 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003680 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003681 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003682 "WHERE lower(tbl_name) LIKE shellstatic()"
3683 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003684 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003685 callback, &data, &zErrMsg);
3686 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003687 }
drhc2ce0be2014-05-29 12:36:14 +00003688 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003689 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003690 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003691 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003692 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003693 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003694 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003695 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003696 callback, &data, &zErrMsg
3697 );
drhc2ce0be2014-05-29 12:36:14 +00003698 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003699 raw_printf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003700 rc = 1;
3701 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003702 }
drh75897232000-05-29 14:26:00 +00003703 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003704 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003705 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003706 rc = 1;
3707 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003708 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00003709 rc = 1;
3710 }else{
3711 rc = 0;
drh75897232000-05-29 14:26:00 +00003712 }
3713 }else
3714
drhabd4c722014-09-20 18:18:33 +00003715
3716#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3717 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3718 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003719 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003720 }else
3721#endif
3722
3723
drh340f5822013-06-27 13:01:21 +00003724#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003725 /* Undocumented commands for internal testing. Subject to change
3726 ** without notice. */
3727 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3728 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3729 int i, v;
3730 for(i=1; i<nArg; i++){
3731 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00003732 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00003733 }
3734 }
3735 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3736 int i; sqlite3_int64 v;
3737 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003738 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003739 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003740 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00003741 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003742 }
3743 }
3744 }else
drh340f5822013-06-27 13:01:21 +00003745#endif
drh348d19c2013-06-03 12:47:43 +00003746
drhc2ce0be2014-05-29 12:36:14 +00003747 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003748 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003749 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003750 rc = 1;
3751 }
drh6976c212014-07-24 12:09:47 +00003752 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003753 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003754 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003755 }
3756 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003757 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3758 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003759 }
drh75897232000-05-29 14:26:00 +00003760 }else
3761
drh62cdde52014-05-28 20:22:28 +00003762 if( c=='s'
3763 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003764 ){
3765 char *zCmd;
drh54027102014-08-06 14:36:53 +00003766 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003767 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003768 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00003769 rc = 1;
3770 goto meta_command_exit;
3771 }
drhdcb3e3d2014-05-29 03:17:29 +00003772 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003773 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003774 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3775 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003776 }
drh54027102014-08-06 14:36:53 +00003777 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003778 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00003779 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003780 }else
3781
drhc2ce0be2014-05-29 12:36:14 +00003782 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003783 int i;
drhc2ce0be2014-05-29 12:36:14 +00003784 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003785 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00003786 rc = 1;
3787 goto meta_command_exit;
3788 }
mistachkinaae280e2015-12-31 19:06:24 +00003789 utf8_printf(p->out, "%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3790 utf8_printf(p->out, "%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drh700c2522016-02-09 18:39:25 +00003791 utf8_printf(p->out, "%12.12s: %s\n","explain",
3792 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
mistachkinaae280e2015-12-31 19:06:24 +00003793 utf8_printf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3794 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
3795 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003796 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00003797 raw_printf(p->out, "\n");
3798 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003799 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00003800 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00003801 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00003802 raw_printf(p->out, "\n");
3803 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00003804 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00003805 raw_printf(p->out, "\n");
3806 utf8_printf(p->out, "%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3807 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00003808 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00003809 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003810 }
mistachkinaae280e2015-12-31 19:06:24 +00003811 raw_printf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003812 }else
3813
drhc2ce0be2014-05-29 12:36:14 +00003814 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3815 if( nArg==2 ){
3816 p->statsOn = booleanValue(azArg[1]);
3817 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003818 raw_printf(stderr, "Usage: .stats on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003819 rc = 1;
3820 }
shaneh642d8b82010-07-28 16:05:34 +00003821 }else
3822
drhc2ce0be2014-05-29 12:36:14 +00003823 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003824 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003825 char **azResult;
drh98781232012-04-23 12:38:05 +00003826 int nRow, nAlloc;
3827 char *zSql = 0;
3828 int ii;
drh05782482013-10-24 15:20:20 +00003829 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003830 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00003831 if( rc ) return shellDatabaseError(p->db);
3832
3833 /* Create an SQL statement to query for the list of tables in the
3834 ** main and all attached databases where the table name matches the
3835 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00003836 zSql = sqlite3_mprintf(
3837 "SELECT name FROM sqlite_master"
3838 " WHERE type IN ('table','view')"
3839 " AND name NOT LIKE 'sqlite_%%'"
3840 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00003841 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00003842 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3843 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3844 if( strcmp(zDbName,"temp")==0 ){
3845 zSql = sqlite3_mprintf(
3846 "%z UNION ALL "
3847 "SELECT 'temp.' || name FROM sqlite_temp_master"
3848 " WHERE type IN ('table','view')"
3849 " AND name NOT LIKE 'sqlite_%%'"
3850 " AND name LIKE ?1", zSql);
3851 }else{
3852 zSql = sqlite3_mprintf(
3853 "%z UNION ALL "
3854 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3855 " WHERE type IN ('table','view')"
3856 " AND name NOT LIKE 'sqlite_%%'"
3857 " AND name LIKE ?1", zSql, zDbName, zDbName);
3858 }
drha50da102000-08-08 20:19:09 +00003859 }
dand95bb392015-09-30 11:19:05 +00003860 rc = sqlite3_finalize(pStmt);
3861 if( zSql && rc==SQLITE_OK ){
3862 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3863 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3864 }
drh98781232012-04-23 12:38:05 +00003865 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00003866 if( !zSql ) return shellNomemError();
3867 if( rc ) return shellDatabaseError(p->db);
3868
3869 /* Run the SQL statement prepared by the above block. Store the results
3870 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00003871 nRow = nAlloc = 0;
3872 azResult = 0;
3873 if( nArg>1 ){
3874 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003875 }else{
drh98781232012-04-23 12:38:05 +00003876 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3877 }
3878 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3879 if( nRow>=nAlloc ){
3880 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00003881 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00003882 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00003883 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00003884 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00003885 break;
3886 }
mistachkin8e189222015-04-19 21:43:16 +00003887 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00003888 azResult = azNew;
3889 }
3890 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00003891 if( 0==azResult[nRow] ){
3892 rc = shellNomemError();
3893 break;
3894 }
3895 nRow++;
drh98781232012-04-23 12:38:05 +00003896 }
dand95bb392015-09-30 11:19:05 +00003897 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
3898 rc = shellDatabaseError(p->db);
3899 }
3900
3901 /* Pretty-print the contents of array azResult[] to the output */
3902 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003903 int len, maxlen = 0;
3904 int i, j;
3905 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003906 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003907 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003908 if( len>maxlen ) maxlen = len;
3909 }
3910 nPrintCol = 80/(maxlen+2);
3911 if( nPrintCol<1 ) nPrintCol = 1;
3912 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3913 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003914 for(j=i; j<nRow; j+=nPrintRow){
3915 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00003916 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
3917 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003918 }
mistachkinaae280e2015-12-31 19:06:24 +00003919 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003920 }
3921 }
dand95bb392015-09-30 11:19:05 +00003922
drh98781232012-04-23 12:38:05 +00003923 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3924 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003925 }else
3926
shaneh96887e12011-02-10 21:08:58 +00003927 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003928 static const struct {
3929 const char *zCtrlName; /* Name of a test-control option */
3930 int ctrlCode; /* Integer code for that option */
3931 } aCtrl[] = {
3932 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3933 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3934 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3935 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3936 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3937 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3938 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3939 { "assert", SQLITE_TESTCTRL_ASSERT },
3940 { "always", SQLITE_TESTCTRL_ALWAYS },
3941 { "reserve", SQLITE_TESTCTRL_RESERVE },
3942 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3943 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003944 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003945 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003946 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003947 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003948 };
shaneh96887e12011-02-10 21:08:58 +00003949 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00003950 int rc2 = 0;
3951 int i, n2;
drh05782482013-10-24 15:20:20 +00003952 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003953
drhd416fe72011-03-17 16:45:50 +00003954 /* convert testctrl text option to value. allow any unique prefix
3955 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00003956 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003957 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00003958 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00003959 if( testctrl<0 ){
3960 testctrl = aCtrl[i].ctrlCode;
3961 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003962 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003963 testctrl = -1;
3964 break;
3965 }
3966 }
3967 }
drh348d19c2013-06-03 12:47:43 +00003968 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003969 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00003970 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003971 }else{
3972 switch(testctrl){
3973
3974 /* sqlite3_test_control(int, db, int) */
3975 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3976 case SQLITE_TESTCTRL_RESERVE:
3977 if( nArg==3 ){
3978 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00003979 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00003980 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003981 } else {
mistachkinaae280e2015-12-31 19:06:24 +00003982 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00003983 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003984 }
3985 break;
3986
3987 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003988 case SQLITE_TESTCTRL_PRNG_SAVE:
3989 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003990 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003991 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003992 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00003993 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00003994 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00003995 } else {
mistachkinaae280e2015-12-31 19:06:24 +00003996 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
3997 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003998 }
3999 break;
4000
4001 /* sqlite3_test_control(int, uint) */
4002 case SQLITE_TESTCTRL_PENDING_BYTE:
4003 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004004 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004005 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004006 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004007 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004008 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00004009 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004010 }
4011 break;
4012
4013 /* sqlite3_test_control(int, int) */
4014 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00004015 case SQLITE_TESTCTRL_ALWAYS:
4016 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004017 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00004018 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004019 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004020 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004021 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004022 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004023 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004024 }
4025 break;
4026
4027 /* sqlite3_test_control(int, char *) */
4028#ifdef SQLITE_N_KEYWORD
4029 case SQLITE_TESTCTRL_ISKEYWORD:
4030 if( nArg==3 ){
4031 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004032 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004033 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004034 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004035 utf8_printf(stderr,
4036 "Error: testctrl %s takes a single char * option\n",
4037 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004038 }
4039 break;
4040#endif
4041
drh1ffede82015-01-30 20:59:27 +00004042 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004043 if( nArg==5 ){
mistachkin8e189222015-04-19 21:43:16 +00004044 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004045 azArg[2],
drh8964b342015-01-29 17:54:52 +00004046 integerValue(azArg[3]),
4047 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00004048 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004049 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004050 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004051 }
4052 break;
4053
shaneh96887e12011-02-10 21:08:58 +00004054 case SQLITE_TESTCTRL_BITVEC_TEST:
4055 case SQLITE_TESTCTRL_FAULT_INSTALL:
4056 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4057 case SQLITE_TESTCTRL_SCRATCHMALLOC:
4058 default:
mistachkinaae280e2015-12-31 19:06:24 +00004059 utf8_printf(stderr,
4060 "Error: CLI support for testctrl %s not implemented\n",
4061 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004062 break;
4063 }
4064 }
4065 }else
4066
drhc2ce0be2014-05-29 12:36:14 +00004067 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004068 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004069 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004070 }else
4071
drhc2ce0be2014-05-29 12:36:14 +00004072 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4073 if( nArg==2 ){
4074 enableTimer = booleanValue(azArg[1]);
4075 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00004076 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00004077 enableTimer = 0;
4078 }
4079 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004080 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004081 rc = 1;
4082 }
shanehe2aa9d72009-11-06 17:20:17 +00004083 }else
4084
drhc2ce0be2014-05-29 12:36:14 +00004085 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004086 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004087 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004088 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004089 rc = 1;
4090 goto meta_command_exit;
4091 }
drh657b4a82015-03-19 13:30:41 +00004092 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004093 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004094#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004095 if( p->traceOut==0 ){
4096 sqlite3_trace(p->db, 0, 0);
4097 }else{
4098 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
4099 }
4100#endif
4101 }else
4102
drhf442e332014-09-10 19:01:14 +00004103#if SQLITE_USER_AUTHENTICATION
4104 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4105 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004106 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00004107 rc = 1;
4108 goto meta_command_exit;
4109 }
drh7883ecf2014-09-11 16:19:31 +00004110 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004111 if( strcmp(azArg[1],"login")==0 ){
4112 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00004113 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00004114 rc = 1;
4115 goto meta_command_exit;
4116 }
drhd39c40f2014-09-11 00:27:53 +00004117 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4118 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004119 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004120 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00004121 rc = 1;
4122 }
4123 }else if( strcmp(azArg[1],"add")==0 ){
4124 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004125 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004126 rc = 1;
4127 goto meta_command_exit;
4128 }
drhd39c40f2014-09-11 00:27:53 +00004129 rc = sqlite3_user_add(p->db, azArg[2],
4130 azArg[3], (int)strlen(azArg[3]),
4131 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004132 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004133 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004134 rc = 1;
4135 }
4136 }else if( strcmp(azArg[1],"edit")==0 ){
4137 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004138 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004139 rc = 1;
4140 goto meta_command_exit;
4141 }
drhd39c40f2014-09-11 00:27:53 +00004142 rc = sqlite3_user_change(p->db, azArg[2],
4143 azArg[3], (int)strlen(azArg[3]),
4144 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004145 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004146 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004147 rc = 1;
4148 }
4149 }else if( strcmp(azArg[1],"delete")==0 ){
4150 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004151 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00004152 rc = 1;
4153 goto meta_command_exit;
4154 }
4155 rc = sqlite3_user_delete(p->db, azArg[2]);
4156 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004157 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004158 rc = 1;
4159 }
4160 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004161 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00004162 rc = 1;
4163 goto meta_command_exit;
4164 }
4165 }else
4166#endif /* SQLITE_USER_AUTHENTICATION */
4167
drh9fd301b2011-06-03 13:28:22 +00004168 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004169 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004170 sqlite3_libversion(), sqlite3_sourceid());
4171 }else
4172
drh790f2872015-11-28 18:06:36 +00004173 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
4174 const char *zDbName = nArg==2 ? azArg[1] : "main";
4175 sqlite3_vfs *pVfs;
4176 if( p->db ){
4177 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
4178 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00004179 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
4180 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4181 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4182 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00004183 }
4184 }
4185 }else
4186
drhb19e7352016-01-12 19:37:20 +00004187 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
4188 sqlite3_vfs *pVfs;
4189 sqlite3_vfs *pCurrent = 0;
4190 if( p->db ){
4191 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
4192 }
4193 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
4194 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
4195 pVfs==pCurrent ? " <--- CURRENT" : "");
4196 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4197 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4198 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
4199 if( pVfs->pNext ){
4200 raw_printf(p->out, "-----------------------------------\n");
4201 }
4202 }
4203 }else
4204
drhde60fc22011-12-14 17:53:36 +00004205 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4206 const char *zDbName = nArg==2 ? azArg[1] : "main";
4207 char *zVfsName = 0;
4208 if( p->db ){
4209 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4210 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00004211 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004212 sqlite3_free(zVfsName);
4213 }
4214 }
4215 }else
4216
drhcef4fc82012-09-21 22:50:45 +00004217#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4218 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
4219 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00004220 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004221 }else
4222#endif
4223
drhc2ce0be2014-05-29 12:36:14 +00004224 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004225 int j;
drh43617e92006-03-06 20:55:46 +00004226 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004227 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004228 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004229 }
4230 }else
4231
4232 {
mistachkinaae280e2015-12-31 19:06:24 +00004233 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004234 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004235 rc = 1;
drh75897232000-05-29 14:26:00 +00004236 }
drh67505e72002-04-19 12:34:06 +00004237
drhc2ce0be2014-05-29 12:36:14 +00004238meta_command_exit:
4239 if( p->outCount ){
4240 p->outCount--;
4241 if( p->outCount==0 ) output_reset(p);
4242 }
drh67505e72002-04-19 12:34:06 +00004243 return rc;
drh75897232000-05-29 14:26:00 +00004244}
4245
drh67505e72002-04-19 12:34:06 +00004246/*
drh91a66392007-09-07 01:12:32 +00004247** Return TRUE if a semicolon occurs anywhere in the first N characters
4248** of string z[].
drh324ccef2003-02-05 14:06:20 +00004249*/
drh9f099fd2013-08-06 14:01:46 +00004250static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004251 int i;
4252 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4253 return 0;
drh324ccef2003-02-05 14:06:20 +00004254}
4255
4256/*
drh70c7a4b2003-04-26 03:03:06 +00004257** Test to see if a line consists entirely of whitespace.
4258*/
4259static int _all_whitespace(const char *z){
4260 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004261 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004262 if( *z=='/' && z[1]=='*' ){
4263 z += 2;
4264 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4265 if( *z==0 ) return 0;
4266 z++;
4267 continue;
4268 }
4269 if( *z=='-' && z[1]=='-' ){
4270 z += 2;
4271 while( *z && *z!='\n' ){ z++; }
4272 if( *z==0 ) return 1;
4273 continue;
4274 }
4275 return 0;
4276 }
4277 return 1;
4278}
4279
4280/*
drha9b17162003-04-29 18:01:28 +00004281** Return TRUE if the line typed in is an SQL command terminator other
4282** than a semi-colon. The SQL Server style "go" command is understood
4283** as is the Oracle "/".
4284*/
drh9f099fd2013-08-06 14:01:46 +00004285static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004286 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004287 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4288 return 1; /* Oracle */
4289 }
drhf0693c82011-10-11 20:41:54 +00004290 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004291 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004292 return 1; /* SQL Server */
4293 }
4294 return 0;
4295}
4296
4297/*
drh233a5312008-12-18 22:25:13 +00004298** Return true if zSql is a complete SQL statement. Return false if it
4299** ends in the middle of a string literal or C-style comment.
4300*/
drh9f099fd2013-08-06 14:01:46 +00004301static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004302 int rc;
4303 if( zSql==0 ) return 1;
4304 zSql[nSql] = ';';
4305 zSql[nSql+1] = 0;
4306 rc = sqlite3_complete(zSql);
4307 zSql[nSql] = 0;
4308 return rc;
4309}
4310
4311/*
drh67505e72002-04-19 12:34:06 +00004312** Read input from *in and process it. If *in==0 then input
4313** is interactive - the user is typing it it. Otherwise, input
4314** is coming from a file or device. A prompt is issued and history
4315** is saved only if input is interactive. An interrupt signal will
4316** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004317**
4318** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004319*/
drhdcd87a92014-08-18 13:45:42 +00004320static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004321 char *zLine = 0; /* A single input line */
4322 char *zSql = 0; /* Accumulated SQL text */
4323 int nLine; /* Length of current line */
4324 int nSql = 0; /* Bytes of zSql[] used */
4325 int nAlloc = 0; /* Allocated zSql[] space */
4326 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4327 char *zErrMsg; /* Error message returned */
4328 int rc; /* Error code */
4329 int errCnt = 0; /* Number of errors seen */
4330 int lineno = 0; /* Current line number */
4331 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004332
4333 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4334 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004335 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004336 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004337 /* End of input */
4338 if( stdin_is_interactive ) printf("\n");
4339 break;
drhc49f44e2006-10-26 18:15:42 +00004340 }
drh67505e72002-04-19 12:34:06 +00004341 if( seenInterrupt ){
4342 if( in!=0 ) break;
4343 seenInterrupt = 0;
4344 }
drhc28490c2006-10-26 14:25:58 +00004345 lineno++;
drh849a9d92013-12-21 15:46:06 +00004346 if( nSql==0 && _all_whitespace(zLine) ){
4347 if( p->echoOn ) printf("%s\n", zLine);
4348 continue;
4349 }
drh2af0b2d2002-02-21 02:25:02 +00004350 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004351 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004352 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004353 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004354 break;
4355 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004356 errCnt++;
4357 }
drhdaffd0e2001-04-11 14:28:42 +00004358 continue;
4359 }
drh9f099fd2013-08-06 14:01:46 +00004360 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004361 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004362 }
drh9f099fd2013-08-06 14:01:46 +00004363 nLine = strlen30(zLine);
4364 if( nSql+nLine+2>=nAlloc ){
4365 nAlloc = nSql+nLine+100;
4366 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004367 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004368 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004369 exit(1);
4370 }
drhdaffd0e2001-04-11 14:28:42 +00004371 }
drh9f099fd2013-08-06 14:01:46 +00004372 nSqlPrior = nSql;
4373 if( nSql==0 ){
4374 int i;
4375 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004376 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004377 memcpy(zSql, zLine+i, nLine+1-i);
4378 startline = lineno;
4379 nSql = nLine-i;
4380 }else{
4381 zSql[nSql++] = '\n';
4382 memcpy(zSql+nSql, zLine, nLine+1);
4383 nSql += nLine;
4384 }
4385 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004386 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004387 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004388 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004389 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004390 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004391 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004392 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004393 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004394 char zPrefix[100];
4395 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004396 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004397 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004398 }else{
shane9bd1b442009-10-23 01:27:39 +00004399 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004400 }
drh7f953e22002-07-13 17:33:45 +00004401 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004402 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004403 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004404 zErrMsg = 0;
4405 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004406 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004407 }
drhc49f44e2006-10-26 18:15:42 +00004408 errCnt++;
drhdf12f1c2015-12-07 21:46:19 +00004409 }else if( p->countChanges ){
mistachkinaae280e2015-12-31 19:06:24 +00004410 raw_printf(p->out, "changes: %3d total_changes: %d\n",
drhdf12f1c2015-12-07 21:46:19 +00004411 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
drhdaffd0e2001-04-11 14:28:42 +00004412 }
drhdaffd0e2001-04-11 14:28:42 +00004413 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004414 if( p->outCount ){
4415 output_reset(p);
4416 p->outCount = 0;
4417 }
drh9f099fd2013-08-06 14:01:46 +00004418 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004419 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004420 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004421 }
4422 }
drh9f099fd2013-08-06 14:01:46 +00004423 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004424 if( !_all_whitespace(zSql) ){
mistachkinaae280e2015-12-31 19:06:24 +00004425 utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004426 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004427 }
drhdaffd0e2001-04-11 14:28:42 +00004428 }
drh1f9ca2c2015-08-25 16:57:52 +00004429 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00004430 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004431 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004432}
4433
drh67505e72002-04-19 12:34:06 +00004434/*
4435** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004436** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004437*/
4438static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004439 static char *home_dir = NULL;
4440 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004441
drh4ace5362014-11-10 14:42:28 +00004442#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4443 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004444 {
4445 struct passwd *pwent;
4446 uid_t uid = getuid();
4447 if( (pwent=getpwuid(uid)) != NULL) {
4448 home_dir = pwent->pw_dir;
4449 }
drh67505e72002-04-19 12:34:06 +00004450 }
4451#endif
4452
chw65d3c132007-11-12 21:09:10 +00004453#if defined(_WIN32_WCE)
4454 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4455 */
drh85e72432012-04-11 11:38:53 +00004456 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004457#else
4458
drh83905c92012-06-21 13:00:37 +00004459#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004460 if (!home_dir) {
4461 home_dir = getenv("USERPROFILE");
4462 }
4463#endif
4464
drh67505e72002-04-19 12:34:06 +00004465 if (!home_dir) {
4466 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004467 }
4468
drh83905c92012-06-21 13:00:37 +00004469#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004470 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004471 char *zDrive, *zPath;
4472 int n;
4473 zDrive = getenv("HOMEDRIVE");
4474 zPath = getenv("HOMEPATH");
4475 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004476 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004477 home_dir = malloc( n );
4478 if( home_dir==0 ) return 0;
4479 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4480 return home_dir;
4481 }
4482 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004483 }
4484#endif
4485
chw65d3c132007-11-12 21:09:10 +00004486#endif /* !_WIN32_WCE */
4487
drh67505e72002-04-19 12:34:06 +00004488 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004489 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004490 char *z = malloc( n );
4491 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004492 home_dir = z;
4493 }
drhe98d4fa2002-04-21 19:06:22 +00004494
drh67505e72002-04-19 12:34:06 +00004495 return home_dir;
4496}
4497
4498/*
4499** Read input from the file given by sqliterc_override. Or if that
4500** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004501**
4502** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004503*/
drh534f4df2015-02-28 14:03:35 +00004504static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004505 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004506 const char *sqliterc_override /* Name of config file. NULL to use default */
4507){
persicom7e2dfdd2002-04-18 02:46:52 +00004508 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004509 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004510 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004511 FILE *in = NULL;
4512
4513 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004514 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004515 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004516 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00004517 " cannot read ~/.sqliterc\n");
4518 return;
drhe98d4fa2002-04-21 19:06:22 +00004519 }
drh2f3de322012-06-27 16:41:31 +00004520 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004521 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4522 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004523 }
drha1f9b5e2004-02-14 16:31:02 +00004524 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004525 if( in ){
drhc28490c2006-10-26 14:25:58 +00004526 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00004527 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004528 }
drh534f4df2015-02-28 14:03:35 +00004529 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004530 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004531 }
drh85e72432012-04-11 11:38:53 +00004532 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004533}
4534
drh67505e72002-04-19 12:34:06 +00004535/*
drhe1e38c42003-05-04 18:30:59 +00004536** Show available command line options
4537*/
4538static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004539 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004540 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004541 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004542 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004543 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004544 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004545 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004546 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004547 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004548#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4549 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4550#endif
drhcc3b4f82012-02-07 14:13:50 +00004551 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004552 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004553 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004554 " -line set output mode to 'line'\n"
4555 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004556 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004557 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004558#ifdef SQLITE_ENABLE_MULTIPLEX
4559 " -multiplex enable the multiplexor VFS\n"
4560#endif
mistachkine0d68852014-12-11 03:12:33 +00004561 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004562 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004563 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4564 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004565 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004566 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004567 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004568 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004569#ifdef SQLITE_ENABLE_VFSTRACE
4570 " -vfstrace enable tracing of all VFS calls\n"
4571#endif
drhe1e38c42003-05-04 18:30:59 +00004572;
4573static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00004574 utf8_printf(stderr,
drh80e8be92006-08-29 12:04:19 +00004575 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4576 "FILENAME is the name of an SQLite database. A new database is created\n"
4577 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004578 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00004579 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004580 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004581 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00004582 }
4583 exit(1);
4584}
4585
4586/*
drh67505e72002-04-19 12:34:06 +00004587** Initialize the state information in data
4588*/
drhdcd87a92014-08-18 13:45:42 +00004589static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004590 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00004591 data->normalMode = data->cMode = data->mode = MODE_List;
4592 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00004593 memcpy(data->colSeparator,SEP_Column, 2);
4594 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004595 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004596 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004597 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004598 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004599 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004600 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4601 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004602}
4603
drh98d312f2012-10-25 15:23:14 +00004604/*
drh5c7976f2014-02-10 19:59:27 +00004605** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004606*/
4607#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004608static void printBold(const char *zText){
4609 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4610 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4611 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4612 SetConsoleTextAttribute(out,
4613 FOREGROUND_RED|FOREGROUND_INTENSITY
4614 );
4615 printf("%s", zText);
4616 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004617}
4618#else
drh5c7976f2014-02-10 19:59:27 +00004619static void printBold(const char *zText){
4620 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004621}
4622#endif
4623
4624/*
drh98d312f2012-10-25 15:23:14 +00004625** Get the argument to an --option. Throw an error and die if no argument
4626** is available.
4627*/
4628static char *cmdline_option_value(int argc, char **argv, int i){
4629 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00004630 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00004631 argv[0], argv[argc-1]);
4632 exit(1);
4633 }
4634 return argv[i];
4635}
4636
mistachkin44723ce2015-03-21 02:22:37 +00004637int SQLITE_CDECL main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004638 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004639 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004640 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004641 int i;
drhc28490c2006-10-26 14:25:58 +00004642 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004643 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004644 int readStdin = 1;
4645 int nCmd = 0;
4646 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004647
drh69b30ab2014-02-27 15:11:52 +00004648#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004649 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004650 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00004651 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4652 exit(1);
4653 }
drhc7181902014-02-27 15:04:13 +00004654#endif
drh047d4532015-01-18 20:30:23 +00004655 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004656 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004657 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004658 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004659 stdin_is_interactive = isatty(0);
drhe05461c2015-12-30 13:36:57 +00004660 stdout_is_console = isatty(1);
persicom7e2dfdd2002-04-18 02:46:52 +00004661
drh44c2eb12003-04-30 11:38:26 +00004662 /* Make sure we have a valid signal handler early, before anything
4663 ** else is done.
4664 */
drh4c504392000-10-16 22:06:40 +00004665#ifdef SIGINT
4666 signal(SIGINT, interrupt_handler);
4667#endif
drh44c2eb12003-04-30 11:38:26 +00004668
drhac5649a2014-11-28 13:35:03 +00004669#ifdef SQLITE_SHELL_DBNAME_PROC
4670 {
4671 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4672 ** of a C-function that will provide the name of the database file. Use
4673 ** this compile-time option to embed this shell program in larger
4674 ** applications. */
4675 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4676 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4677 warnInmemoryDb = 0;
4678 }
4679#endif
4680
drh22fbcb82004-02-01 01:22:50 +00004681 /* Do an initial pass through the command-line argument to locate
4682 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004683 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004684 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004685 */
drh98d312f2012-10-25 15:23:14 +00004686 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004687 char *z;
drhc28490c2006-10-26 14:25:58 +00004688 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004689 if( z[0]!='-' ){
4690 if( data.zDbFilename==0 ){
4691 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004692 }else{
4693 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4694 ** mean that nothing is read from stdin */
4695 readStdin = 0;
4696 nCmd++;
4697 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4698 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004699 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00004700 exit(1);
4701 }
4702 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004703 }
drh98d312f2012-10-25 15:23:14 +00004704 }
drhcc3b4f82012-02-07 14:13:50 +00004705 if( z[1]=='-' ) z++;
4706 if( strcmp(z,"-separator")==0
4707 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004708 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004709 || strcmp(z,"-cmd")==0
4710 ){
drh98d312f2012-10-25 15:23:14 +00004711 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004712 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004713 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004714 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004715 /* Need to check for batch mode here to so we can avoid printing
4716 ** informational messages (like from process_sqliterc) before
4717 ** we do the actual processing of arguments later in a second pass.
4718 */
shanef69573d2009-10-24 02:06:14 +00004719 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004720 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004721#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004722 const char *zSize;
4723 sqlite3_int64 szHeap;
4724
drh98d312f2012-10-25 15:23:14 +00004725 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004726 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004727 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004728 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4729#endif
drh44dec872014-08-30 15:49:25 +00004730 }else if( strcmp(z,"-scratch")==0 ){
4731 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004732 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004733 if( sz>400000 ) sz = 400000;
4734 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004735 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004736 if( n>10 ) n = 10;
4737 if( n<1 ) n = 1;
4738 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4739 data.shellFlgs |= SHFLG_Scratch;
4740 }else if( strcmp(z,"-pagecache")==0 ){
4741 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004742 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004743 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00004744 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004745 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00004746 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
4747 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00004748 data.shellFlgs |= SHFLG_Pagecache;
4749 }else if( strcmp(z,"-lookaside")==0 ){
4750 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004751 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004752 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004753 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004754 if( n<0 ) n = 0;
4755 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4756 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004757#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004758 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004759 extern int vfstrace_register(
4760 const char *zTraceName,
4761 const char *zOldVfsName,
4762 int (*xOut)(const char*,void*),
4763 void *pOutArg,
4764 int makeDefault
4765 );
drh2b625e22011-03-16 17:05:28 +00004766 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004767#endif
drh6f25e892011-07-08 17:02:57 +00004768#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004769 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004770 extern int sqlite3_multiple_initialize(const char*,int);
4771 sqlite3_multiplex_initialize(0, 1);
4772#endif
drh7d9f3942013-04-03 01:26:54 +00004773 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004774 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4775 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004776 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004777 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004778 if( pVfs ){
4779 sqlite3_vfs_register(pVfs, 1);
4780 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004781 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00004782 exit(1);
4783 }
drh44c2eb12003-04-30 11:38:26 +00004784 }
4785 }
drh98d312f2012-10-25 15:23:14 +00004786 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004787#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004788 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004789 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004790#else
mistachkinaae280e2015-12-31 19:06:24 +00004791 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00004792 return 1;
drh01b41712005-08-29 23:06:23 +00004793#endif
drh98d312f2012-10-25 15:23:14 +00004794 }
4795 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004796
drh44c2eb12003-04-30 11:38:26 +00004797 /* Go ahead and open the database file if it already exists. If the
4798 ** file does not exist, delay opening it. This prevents empty database
4799 ** files from being created if a user mistypes the database name argument
4800 ** to the sqlite command-line tool.
4801 */
drhc8d74412004-08-31 23:41:26 +00004802 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004803 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004804 }
4805
drh22fbcb82004-02-01 01:22:50 +00004806 /* Process the initialization file if there is one. If no -init option
4807 ** is given on the command line, look for a file named ~/.sqliterc and
4808 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004809 */
drh534f4df2015-02-28 14:03:35 +00004810 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004811
drh22fbcb82004-02-01 01:22:50 +00004812 /* Make a second pass through the command-line argument and set
4813 ** options. This second pass is delayed until after the initialization
4814 ** file is processed so that the command-line arguments will override
4815 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004816 */
drh98d312f2012-10-25 15:23:14 +00004817 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004818 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004819 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004820 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004821 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004822 i++;
4823 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004824 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004825 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004826 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004827 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004828 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004829 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004830 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004831 }else if( strcmp(z,"-csv")==0 ){
4832 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004833 memcpy(data.colSeparator,",",2);
4834 }else if( strcmp(z,"-ascii")==0 ){
4835 data.mode = MODE_Ascii;
4836 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004837 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004838 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004839 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004840 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004841 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4842 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004843 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004844 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004845 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004846 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004847 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004848 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004849 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004850 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004851 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004852 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004853 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004854 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004855 }else if( strcmp(z,"-eqp")==0 ){
4856 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004857 }else if( strcmp(z,"-stats")==0 ){
4858 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004859 }else if( strcmp(z,"-scanstats")==0 ){
4860 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00004861 }else if( strcmp(z,"-backslash")==0 ){
4862 /* Undocumented command-line option: -backslash
4863 ** Causes C-style backslash escapes to be evaluated in SQL statements
4864 ** prior to sending the SQL into SQLite. Useful for injecting
4865 ** crazy bytes in the middle of SQL statements for testing and debugging.
4866 */
4867 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004868 }else if( strcmp(z,"-bail")==0 ){
4869 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004870 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004871 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004872 return 0;
drhc28490c2006-10-26 14:25:58 +00004873 }else if( strcmp(z,"-interactive")==0 ){
4874 stdin_is_interactive = 1;
4875 }else if( strcmp(z,"-batch")==0 ){
4876 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004877 }else if( strcmp(z,"-heap")==0 ){
4878 i++;
drh44dec872014-08-30 15:49:25 +00004879 }else if( strcmp(z,"-scratch")==0 ){
4880 i+=2;
4881 }else if( strcmp(z,"-pagecache")==0 ){
4882 i+=2;
4883 }else if( strcmp(z,"-lookaside")==0 ){
4884 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004885 }else if( strcmp(z,"-mmap")==0 ){
4886 i++;
drha7e61d82011-03-12 17:02:57 +00004887 }else if( strcmp(z,"-vfs")==0 ){
4888 i++;
drh6f25e892011-07-08 17:02:57 +00004889#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004890 }else if( strcmp(z,"-vfstrace")==0 ){
4891 i++;
drh6f25e892011-07-08 17:02:57 +00004892#endif
4893#ifdef SQLITE_ENABLE_MULTIPLEX
4894 }else if( strcmp(z,"-multiplex")==0 ){
4895 i++;
4896#endif
drhcc3b4f82012-02-07 14:13:50 +00004897 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004898 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004899 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004900 /* Run commands that follow -cmd first and separately from commands
4901 ** that simply appear on the command-line. This seems goofy. It would
4902 ** be better if all commands ran in the order that they appear. But
4903 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004904 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004905 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004906 if( z[0]=='.' ){
4907 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004908 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004909 }else{
drh05782482013-10-24 15:20:20 +00004910 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004911 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4912 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004913 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00004914 if( bail_on_error ) return rc!=0 ? rc : 1;
4915 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004916 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00004917 if( bail_on_error ) return rc;
4918 }
4919 }
drh1e5d0e92000-05-31 23:33:17 +00004920 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004921 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
4922 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004923 return 1;
4924 }
drh700c2522016-02-09 18:39:25 +00004925 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00004926 }
drh44c2eb12003-04-30 11:38:26 +00004927
drhac5649a2014-11-28 13:35:03 +00004928 if( !readStdin ){
4929 /* Run all arguments that do not begin with '-' as if they were separate
4930 ** command-line inputs, except for the argToSkip argument which contains
4931 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004932 */
drhac5649a2014-11-28 13:35:03 +00004933 for(i=0; i<nCmd; i++){
4934 if( azCmd[i][0]=='.' ){
4935 rc = do_meta_command(azCmd[i], &data);
4936 if( rc ) return rc==2 ? 0 : rc;
4937 }else{
4938 open_db(&data, 0);
4939 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4940 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004941 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00004942 return rc!=0 ? rc : 1;
4943 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004944 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00004945 return rc;
4946 }
drh6ff13852001-11-25 13:18:23 +00004947 }
drh75897232000-05-29 14:26:00 +00004948 }
drhac5649a2014-11-28 13:35:03 +00004949 free(azCmd);
drh75897232000-05-29 14:26:00 +00004950 }else{
drh44c2eb12003-04-30 11:38:26 +00004951 /* Run commands received from standard input
4952 */
drhc28490c2006-10-26 14:25:58 +00004953 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004954 char *zHome;
4955 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004956 int nHistory;
drh75897232000-05-29 14:26:00 +00004957 printf(
drh743e0032011-12-12 16:51:50 +00004958 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004959 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004960 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004961 );
drhb3735912014-02-10 16:13:42 +00004962 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004963 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004964 printBold("transient in-memory database");
4965 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004966 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004967 }
drh67505e72002-04-19 12:34:06 +00004968 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004969 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004970 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004971 if( (zHistory = malloc(nHistory))!=0 ){
4972 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4973 }
drh67505e72002-04-19 12:34:06 +00004974 }
drhf5ed7ad2015-06-15 14:43:25 +00004975 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00004976 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004977 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004978 shell_stifle_history(100);
4979 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004980 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004981 }
drhdaffd0e2001-04-11 14:28:42 +00004982 }else{
drhc28490c2006-10-26 14:25:58 +00004983 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004984 }
4985 }
drh33048c02001-10-01 14:29:22 +00004986 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004987 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004988 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004989 }
drh05782482013-10-24 15:20:20 +00004990 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004991 return rc;
drh75897232000-05-29 14:26:00 +00004992}