blob: 47b16f4e6f2de0f731036ce386448ec461989225 [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/*
drh36f7dd32011-10-13 16:02:17 +000028** Enable large-file support for fopen() and friends on unix.
29*/
30#ifndef SQLITE_DISABLE_LFS
31# define _LARGE_FILE 1
32# ifndef _FILE_OFFSET_BITS
33# define _FILE_OFFSET_BITS 64
34# endif
35# define _LARGEFILE_SOURCE 1
36#endif
37
drh75897232000-05-29 14:26:00 +000038#include <stdlib.h>
39#include <string.h>
40#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000041#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000042#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000043#if SQLITE_USER_AUTHENTICATION
44# include "sqlite3userauth.h"
45#endif
drh75897232000-05-29 14:26:00 +000046#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000047#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000048
drh83905c92012-06-21 13:00:37 +000049#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000050# include <signal.h>
chw97185482008-11-17 08:05:31 +000051# if !defined(__RTP__) && !defined(_WRS_KERNEL)
52# include <pwd.h>
53# endif
drhdd45df82002-04-18 12:39:03 +000054# include <unistd.h>
55# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000056#endif
drh75897232000-05-29 14:26:00 +000057
drh0ede9eb2015-01-10 16:49:23 +000058#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000059# include <readline/readline.h>
60# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000061#endif
danfd34d6d2015-02-25 10:54:53 +000062
drh0ede9eb2015-01-10 16:49:23 +000063#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000064# include <editline/readline.h>
65#endif
danfd34d6d2015-02-25 10:54:53 +000066
67#if HAVE_EDITLINE || HAVE_READLINE
68
69# define shell_add_history(X) add_history(X)
70# define shell_read_history(X) read_history(X)
71# define shell_write_history(X) write_history(X)
72# define shell_stifle_history(X) stifle_history(X)
73# define shell_readline(X) readline(X)
74
75#elif HAVE_LINENOISE
76
77# include "linenoise.h"
78# define shell_add_history(X) linenoiseHistoryAdd(X)
79# define shell_read_history(X) linenoiseHistoryLoad(X)
80# define shell_write_history(X) linenoiseHistorySave(X)
81# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
82# define shell_readline(X) linenoise(X)
83
84#else
85
86# define shell_read_history(X)
87# define shell_write_history(X)
88# define shell_stifle_history(X)
89
90# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000091#endif
92
danfd34d6d2015-02-25 10:54:53 +000093
adamd2e8464a2006-09-06 21:39:40 +000094#if defined(_WIN32) || defined(WIN32)
95# include <io.h>
drh6976c212014-07-24 12:09:47 +000096# include <fcntl.h>
shane18e526c2008-12-10 22:30:24 +000097#define isatty(h) _isatty(h)
drh07901eb2014-02-28 19:37:45 +000098#ifndef access
99# define access(f,m) _access((f),(m))
100#endif
drh67ceaa62012-08-27 21:19:03 +0000101#undef popen
drh53371f92013-07-25 17:07:03 +0000102#define popen _popen
drh67ceaa62012-08-27 21:19:03 +0000103#undef pclose
drh12cd6cf2013-06-29 15:40:22 +0000104#define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000105#else
drh4328c8b2003-04-26 02:50:11 +0000106/* Make sure isatty() has a prototype.
107*/
drhb2acc3b2011-10-13 16:36:29 +0000108extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000109
drh53371f92013-07-25 17:07:03 +0000110/* popen and pclose are not C89 functions and so are sometimes omitted from
111** the <stdio.h> header */
mistachkinf6418892013-08-28 01:54:12 +0000112extern FILE *popen(const char*,const char*);
113extern int pclose(FILE*);
114#endif
drh53371f92013-07-25 17:07:03 +0000115
chw65d3c132007-11-12 21:09:10 +0000116#if defined(_WIN32_WCE)
117/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
118 * thus we always assume that we have a console. That can be
119 * overridden with the -batch command line option.
120 */
121#define isatty(x) 1
122#endif
123
drhf0693c82011-10-11 20:41:54 +0000124/* ctype macros that work with signed characters */
125#define IsSpace(X) isspace((unsigned char)X)
126#define IsDigit(X) isdigit((unsigned char)X)
127#define ToLower(X) (char)tolower((unsigned char)X)
128
drh047d4532015-01-18 20:30:23 +0000129/* On Windows, we normally run with output mode of TEXT so that \n characters
130** are automatically translated into \r\n. However, this behavior needs
131** to be disabled in some cases (ex: when generating CSV output and when
132** rendering quoted strings that contain \n characters). The following
133** routines take care of that.
134*/
135#if defined(_WIN32) || defined(WIN32)
mistachkine4a0d792015-01-27 21:24:33 +0000136static void setBinaryMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000137 fflush(out);
138 _setmode(_fileno(out), _O_BINARY);
139}
mistachkine4a0d792015-01-27 21:24:33 +0000140static void setTextMode(FILE *out){
drh047d4532015-01-18 20:30:23 +0000141 fflush(out);
142 _setmode(_fileno(out), _O_TEXT);
143}
144#else
145# define setBinaryMode(X)
146# define setTextMode(X)
147#endif
148
drh43408312013-10-30 12:43:36 +0000149
150/* True if the timer is enabled */
151static int enableTimer = 0;
152
153/* Return the current wall-clock time */
154static sqlite3_int64 timeOfDay(void){
155 static sqlite3_vfs *clockVfs = 0;
156 sqlite3_int64 t;
157 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
158 if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){
159 clockVfs->xCurrentTimeInt64(clockVfs, &t);
160 }else{
161 double r;
162 clockVfs->xCurrentTime(clockVfs, &r);
163 t = (sqlite3_int64)(r*86400000.0);
164 }
165 return t;
166}
167
drhd5d0f642013-02-20 00:54:21 +0000168#if !defined(_WIN32) && !defined(WIN32) && !defined(_WRS_KERNEL) \
169 && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000170#include <sys/time.h>
171#include <sys/resource.h>
172
drhda108222009-02-25 19:07:24 +0000173/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000174static struct rusage sBegin; /* CPU time at start */
175static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000176
drhda108222009-02-25 19:07:24 +0000177/*
178** Begin timing an operation
179*/
180static void beginTimer(void){
181 if( enableTimer ){
182 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000183 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000184 }
185}
186
187/* Return the difference of two time_structs in seconds */
188static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
189 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
190 (double)(pEnd->tv_sec - pStart->tv_sec);
191}
192
193/*
194** Print the timing results.
195*/
196static void endTimer(void){
197 if( enableTimer ){
198 struct rusage sEnd;
drh43408312013-10-30 12:43:36 +0000199 sqlite3_int64 iEnd = timeOfDay();
drhda108222009-02-25 19:07:24 +0000200 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000201 printf("Run Time: real %.3f user %f sys %f\n",
202 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000203 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
204 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
205 }
206}
shaneb320ccd2009-10-21 03:42:58 +0000207
drhda108222009-02-25 19:07:24 +0000208#define BEGIN_TIMER beginTimer()
209#define END_TIMER endTimer()
210#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000211
212#elif (defined(_WIN32) || defined(WIN32))
213
214#include <windows.h>
215
216/* Saved resource information for the beginning of an operation */
217static HANDLE hProcess;
218static FILETIME ftKernelBegin;
219static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000220static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000221typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
222 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000223static GETPROCTIMES getProcessTimesAddr = NULL;
224
shaneb320ccd2009-10-21 03:42:58 +0000225/*
226** Check to see if we have timer support. Return 1 if necessary
227** support found (or found previously).
228*/
229static int hasTimer(void){
230 if( getProcessTimesAddr ){
231 return 1;
232 } else {
drh4ace5362014-11-10 14:42:28 +0000233 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
234 ** versions. See if the version we are running on has it, and if it
235 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000236 */
237 hProcess = GetCurrentProcess();
238 if( hProcess ){
239 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
240 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000241 getProcessTimesAddr =
242 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000243 if( NULL != getProcessTimesAddr ){
244 return 1;
245 }
246 FreeLibrary(hinstLib);
247 }
248 }
249 }
250 return 0;
251}
252
253/*
254** Begin timing an operation
255*/
256static void beginTimer(void){
257 if( enableTimer && getProcessTimesAddr ){
258 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000259 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
260 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000261 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000262 }
263}
264
265/* Return the difference of two FILETIME structs in seconds */
266static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
267 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
268 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
269 return (double) ((i64End - i64Start) / 10000000.0);
270}
271
272/*
273** Print the timing results.
274*/
275static void endTimer(void){
276 if( enableTimer && getProcessTimesAddr){
277 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000278 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000279 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000280 printf("Run Time: real %.3f user %f sys %f\n",
281 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000282 timeDiff(&ftUserBegin, &ftUserEnd),
283 timeDiff(&ftKernelBegin, &ftKernelEnd));
284 }
285}
286
287#define BEGIN_TIMER beginTimer()
288#define END_TIMER endTimer()
289#define HAS_TIMER hasTimer()
290
drhda108222009-02-25 19:07:24 +0000291#else
292#define BEGIN_TIMER
293#define END_TIMER
294#define HAS_TIMER 0
295#endif
296
shanec0688ea2009-03-05 03:48:06 +0000297/*
298** Used to prevent warnings about unused parameters
299*/
300#define UNUSED_PARAMETER(x) (void)(x)
301
drhe91d16b2008-12-08 18:27:31 +0000302/*
drhc49f44e2006-10-26 18:15:42 +0000303** If the following flag is set, then command execution stops
304** at an error if we are not interactive.
305*/
306static int bail_on_error = 0;
307
308/*
drhc28490c2006-10-26 14:25:58 +0000309** Threat stdin as an interactive input if the following variable
310** is true. Otherwise, assume stdin is connected to a file or pipe.
311*/
312static int stdin_is_interactive = 1;
313
314/*
drh4c504392000-10-16 22:06:40 +0000315** The following is the open SQLite database. We make a pointer
316** to this database a static variable so that it can be accessed
317** by the SIGINT handler to interrupt database processing.
318*/
danielk197792f9a1b2004-06-19 09:08:16 +0000319static sqlite3 *db = 0;
drh4c504392000-10-16 22:06:40 +0000320
321/*
drh67505e72002-04-19 12:34:06 +0000322** True if an interrupt (Control-C) has been received.
323*/
drh43617e92006-03-06 20:55:46 +0000324static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000325
326/*
persicom7e2dfdd2002-04-18 02:46:52 +0000327** This is the name of our program. It is set in main(), used
328** in a number of other places, mostly for error messages.
329*/
330static char *Argv0;
331
332/*
333** Prompt strings. Initialized in main. Settable with
334** .prompt main continue
335*/
336static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
337static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
338
drhb0603412007-02-28 04:47:26 +0000339/*
340** Write I/O traces to the following stream.
341*/
rsebe0a9092007-07-30 18:24:38 +0000342#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000343static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000344#endif
drhb0603412007-02-28 04:47:26 +0000345
346/*
347** This routine works like printf in that its first argument is a
348** format string and subsequent arguments are values to be substituted
349** in place of % fields. The result of formatting this string
350** is written to iotrace.
351*/
rsebe0a9092007-07-30 18:24:38 +0000352#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000353static void iotracePrintf(const char *zFormat, ...){
354 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000355 char *z;
drhb0603412007-02-28 04:47:26 +0000356 if( iotrace==0 ) return;
357 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000358 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000359 va_end(ap);
drhf075cd02007-02-28 06:14:25 +0000360 fprintf(iotrace, "%s", z);
361 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000362}
rsebe0a9092007-07-30 18:24:38 +0000363#endif
drhb0603412007-02-28 04:47:26 +0000364
drh44c2eb12003-04-30 11:38:26 +0000365
persicom7e2dfdd2002-04-18 02:46:52 +0000366/*
drh83965662003-04-17 02:54:13 +0000367** Determines if a string is a number of not.
368*/
danielk19772e588c72005-12-09 14:25:08 +0000369static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000370 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000371 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000372 return 0;
373 }
374 z++;
375 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000376 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000377 if( *z=='.' ){
378 z++;
drhf0693c82011-10-11 20:41:54 +0000379 if( !IsDigit(*z) ) return 0;
380 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000381 if( realnum ) *realnum = 1;
382 }
383 if( *z=='e' || *z=='E' ){
384 z++;
385 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000386 if( !IsDigit(*z) ) return 0;
387 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000388 if( realnum ) *realnum = 1;
389 }
390 return *z==0;
391}
drh83965662003-04-17 02:54:13 +0000392
393/*
danielk1977bc6ada42004-06-30 08:20:16 +0000394** A global char* and an SQL function to access its current value
395** from within an SQL statement. This program used to use the
396** sqlite_exec_printf() API to substitue a string into an SQL statement.
397** The correct way to do this with sqlite3 is to use the bind API, but
398** since the shell is built around the callback paradigm it would be a lot
399** of work. Instead just use this hack, which is quite harmless.
400*/
401static const char *zShellStatic = 0;
402static void shellstaticFunc(
403 sqlite3_context *context,
404 int argc,
405 sqlite3_value **argv
406){
407 assert( 0==argc );
408 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000409 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000410 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000411 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
412}
413
414
415/*
drhfeac5f82004-08-01 00:10:45 +0000416** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000417** the text in memory obtained from malloc() and returns a pointer
418** to the text. NULL is returned at end of file, or if malloc()
419** fails.
420**
drh9f099fd2013-08-06 14:01:46 +0000421** If zLine is not NULL then it is a malloced buffer returned from
422** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000423*/
drh9f099fd2013-08-06 14:01:46 +0000424static char *local_getline(char *zLine, FILE *in){
425 int nLine = zLine==0 ? 0 : 100;
426 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000427
drhb07028f2011-10-14 21:49:18 +0000428 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000429 if( n+100>nLine ){
430 nLine = nLine*2 + 100;
431 zLine = realloc(zLine, nLine);
432 if( zLine==0 ) return 0;
433 }
drhdaffd0e2001-04-11 14:28:42 +0000434 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000435 if( n==0 ){
436 free(zLine);
437 return 0;
438 }
439 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000440 break;
441 }
drh9f099fd2013-08-06 14:01:46 +0000442 while( zLine[n] ) n++;
443 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000444 n--;
shaneh13b36022009-12-17 21:07:15 +0000445 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000446 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000447 break;
drh8e7e7a22000-05-30 18:45:23 +0000448 }
449 }
drh8e7e7a22000-05-30 18:45:23 +0000450 return zLine;
451}
452
453/*
drhc28490c2006-10-26 14:25:58 +0000454** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000455**
drh9f099fd2013-08-06 14:01:46 +0000456** If in==0 then read from standard input and prompt before each line.
457** If isContinuation is true, then a continuation prompt is appropriate.
458** If isContinuation is zero, then the main prompt should be used.
459**
460** If zPrior is not NULL then it is a buffer from a prior call to this
461** routine that can be reused.
462**
463** The result is stored in space obtained from malloc() and must either
464** be freed by the caller or else passed back into this routine via the
465** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000466*/
drh9f099fd2013-08-06 14:01:46 +0000467static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000468 char *zPrompt;
469 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000470 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000471 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000472 }else{
drh9f099fd2013-08-06 14:01:46 +0000473 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000474#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000475 printf("%s", zPrompt);
476 fflush(stdout);
477 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000478#else
479 free(zPrior);
480 zResult = shell_readline(zPrompt);
481 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000482#endif
drh9f099fd2013-08-06 14:01:46 +0000483 }
drh8e7e7a22000-05-30 18:45:23 +0000484 return zResult;
485}
486
drhdcd87a92014-08-18 13:45:42 +0000487/*
488** Shell output mode information from before ".explain on",
489** saved so that it can be restored by ".explain off"
490*/
491typedef struct SavedModeInfo SavedModeInfo;
492struct SavedModeInfo {
493 int valid; /* Is there legit data in here? */
494 int mode; /* Mode prior to ".explain on" */
495 int showHeader; /* The ".header" setting prior to ".explain on" */
496 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000497};
drh45e29d82006-11-20 16:21:10 +0000498
drh8e7e7a22000-05-30 18:45:23 +0000499/*
drhdcd87a92014-08-18 13:45:42 +0000500** State information about the database connection is contained in an
501** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000502*/
drhdcd87a92014-08-18 13:45:42 +0000503typedef struct ShellState ShellState;
504struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000505 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000506 int echoOn; /* True to echo input commands */
drhc2ce0be2014-05-29 12:36:14 +0000507 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000508 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000509 int scanstatsOn; /* True to display scan stats before each finalize */
drhc2ce0be2014-05-29 12:36:14 +0000510 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000511 int cnt; /* Number of records displayed so far */
512 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000513 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000514 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000515 int mode; /* An output mode setting */
drh45e29d82006-11-20 16:21:10 +0000516 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000517 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000518 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000519 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000520 char colSeparator[20]; /* Column separator character for several modes */
521 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000522 int colWidth[100]; /* Requested width of each column when in column mode*/
523 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000524 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000525 ** the database */
drhdcd87a92014-08-18 13:45:42 +0000526 SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
drh44c2eb12003-04-30 11:38:26 +0000527 char outfile[FILENAME_MAX]; /* Filename for *out */
528 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000529 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000530 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000531 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000532 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000533 int *aiIndent; /* Array of indents used in MODE_Explain */
534 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000535 int iIndent; /* Index of current op in aiIndent[] */
drh75897232000-05-29 14:26:00 +0000536};
537
538/*
drh44dec872014-08-30 15:49:25 +0000539** These are the allowed shellFlgs values
540*/
541#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
542#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
543#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
544
545/*
drh75897232000-05-29 14:26:00 +0000546** These are the allowed modes.
547*/
drh967e8b72000-06-21 13:59:10 +0000548#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000549#define MODE_Column 1 /* One record per line in neat columns */
550#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000551#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
552#define MODE_Html 4 /* Generate an XHTML table */
553#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000554#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000555#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000556#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000557#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
persicom7e2dfdd2002-04-18 02:46:52 +0000558
drh66ce4d02008-02-15 17:38:06 +0000559static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000560 "line",
561 "column",
562 "list",
563 "semi",
564 "html",
drhfeac5f82004-08-01 00:10:45 +0000565 "insert",
566 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000567 "csv",
drh66ce4d02008-02-15 17:38:06 +0000568 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000569 "ascii",
persicom7e2dfdd2002-04-18 02:46:52 +0000570};
drh75897232000-05-29 14:26:00 +0000571
572/*
mistachkinfad42082014-07-24 22:13:12 +0000573** These are the column/row/line separators used by the various
574** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000575*/
mistachkinfad42082014-07-24 22:13:12 +0000576#define SEP_Column "|"
577#define SEP_Row "\n"
578#define SEP_Tab "\t"
579#define SEP_Space " "
580#define SEP_Comma ","
581#define SEP_CrLf "\r\n"
582#define SEP_Unit "\x1F"
583#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000584
585/*
drh75897232000-05-29 14:26:00 +0000586** Number of elements in an array
587*/
drh902b9ee2008-12-05 17:17:07 +0000588#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000589
590/*
drhea678832008-12-10 19:26:22 +0000591** Compute a string length that is limited to what can be stored in
592** lower 30 bits of a 32-bit signed integer.
593*/
drh4f21c4a2008-12-10 22:15:00 +0000594static int strlen30(const char *z){
drhea678832008-12-10 19:26:22 +0000595 const char *z2 = z;
596 while( *z2 ){ z2++; }
597 return 0x3fffffff & (int)(z2 - z);
598}
599
600/*
drh127f9d72010-02-23 01:47:00 +0000601** A callback for the sqlite3_log() interface.
602*/
603static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000604 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000605 if( p->pLog==0 ) return;
606 fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
607 fflush(p->pLog);
608}
609
610/*
shane626a6e42009-10-22 17:30:15 +0000611** Output the given string as a hex-encoded blob (eg. X'1234' )
612*/
613static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
614 int i;
615 char *zBlob = (char *)pBlob;
616 fprintf(out,"X'");
drhb202d702012-04-24 12:12:57 +0000617 for(i=0; i<nBlob; i++){ fprintf(out,"%02x",zBlob[i]&0xff); }
shane626a6e42009-10-22 17:30:15 +0000618 fprintf(out,"'");
619}
620
621/*
drh28bd4bc2000-06-15 15:57:22 +0000622** Output the given string as a quoted string using SQL quoting conventions.
623*/
624static void output_quoted_string(FILE *out, const char *z){
625 int i;
626 int nSingle = 0;
drh047d4532015-01-18 20:30:23 +0000627 setBinaryMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000628 for(i=0; z[i]; i++){
629 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000630 }
631 if( nSingle==0 ){
632 fprintf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000633 }else{
634 fprintf(out,"'");
635 while( *z ){
636 for(i=0; z[i] && z[i]!='\''; i++){}
637 if( i==0 ){
638 fprintf(out,"''");
639 z++;
640 }else if( z[i]=='\'' ){
641 fprintf(out,"%.*s''",i,z);
642 z += i+1;
643 }else{
drhcd7d2732002-02-26 23:24:26 +0000644 fprintf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000645 break;
646 }
647 }
drhcd7d2732002-02-26 23:24:26 +0000648 fprintf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000649 }
drh047d4532015-01-18 20:30:23 +0000650 setTextMode(out);
drh28bd4bc2000-06-15 15:57:22 +0000651}
652
653/*
drhfeac5f82004-08-01 00:10:45 +0000654** Output the given string as a quoted according to C or TCL quoting rules.
655*/
656static void output_c_string(FILE *out, const char *z){
657 unsigned int c;
658 fputc('"', out);
659 while( (c = *(z++))!=0 ){
660 if( c=='\\' ){
661 fputc(c, out);
662 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000663 }else if( c=='"' ){
664 fputc('\\', out);
665 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000666 }else if( c=='\t' ){
667 fputc('\\', out);
668 fputc('t', out);
669 }else if( c=='\n' ){
670 fputc('\\', out);
671 fputc('n', out);
672 }else if( c=='\r' ){
673 fputc('\\', out);
674 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000675 }else if( !isprint(c&0xff) ){
drh0a8640d2005-08-30 20:12:02 +0000676 fprintf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000677 }else{
678 fputc(c, out);
679 }
680 }
681 fputc('"', out);
682}
683
684/*
drhc08a4f12000-06-15 16:49:48 +0000685** Output the given string with characters that are special to
686** HTML escaped.
687*/
688static void output_html_string(FILE *out, const char *z){
689 int i;
drhc3d6ba42014-01-13 20:38:35 +0000690 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000691 while( *z ){
shane43d9cb22009-10-21 14:11:48 +0000692 for(i=0; z[i]
693 && z[i]!='<'
694 && z[i]!='&'
695 && z[i]!='>'
696 && z[i]!='\"'
697 && z[i]!='\'';
698 i++){}
drhc08a4f12000-06-15 16:49:48 +0000699 if( i>0 ){
700 fprintf(out,"%.*s",i,z);
701 }
702 if( z[i]=='<' ){
703 fprintf(out,"&lt;");
704 }else if( z[i]=='&' ){
705 fprintf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000706 }else if( z[i]=='>' ){
707 fprintf(out,"&gt;");
708 }else if( z[i]=='\"' ){
709 fprintf(out,"&quot;");
710 }else if( z[i]=='\'' ){
711 fprintf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000712 }else{
713 break;
714 }
715 z += i + 1;
716 }
717}
718
719/*
drhc49f44e2006-10-26 18:15:42 +0000720** If a field contains any character identified by a 1 in the following
721** array, then the string must be quoted for CSV.
722*/
723static const char needCsvQuote[] = {
724 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
725 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
726 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
727 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
728 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
729 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
730 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
731 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
732 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
733 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
734 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
735 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
736 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
737 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
738 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
739 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
740};
741
742/*
mistachkindd11f2d2014-12-11 04:49:46 +0000743** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000744** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000745** the null value. Strings are quoted if necessary. The separator
746** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000747*/
drhdcd87a92014-08-18 13:45:42 +0000748static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000749 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000750 if( z==0 ){
mistachkin44b99f72014-12-11 03:29:14 +0000751 fprintf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000752 }else{
drhc49f44e2006-10-26 18:15:42 +0000753 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000754 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000755 for(i=0; z[i]; i++){
drhc85375d2007-12-18 15:41:44 +0000756 if( needCsvQuote[((unsigned char*)z)[i]]
mistachkin636bf9f2014-07-19 20:15:16 +0000757 || (z[i]==p->colSeparator[0] &&
758 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000759 i = 0;
760 break;
761 }
762 }
763 if( i==0 ){
764 putc('"', out);
765 for(i=0; z[i]; i++){
766 if( z[i]=='"' ) putc('"', out);
767 putc(z[i], out);
768 }
769 putc('"', out);
770 }else{
771 fprintf(out, "%s", z);
772 }
drh8e64d1c2004-10-07 00:32:39 +0000773 }
774 if( bSep ){
mistachkin636bf9f2014-07-19 20:15:16 +0000775 fprintf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000776 }
777}
778
danielk19774af00c62005-01-23 23:43:21 +0000779#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000780/*
drh4c504392000-10-16 22:06:40 +0000781** This routine runs when the user presses Ctrl-C
782*/
783static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000784 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000785 seenInterrupt++;
786 if( seenInterrupt>2 ) exit(1);
danielk19776f8a5032004-05-10 10:34:51 +0000787 if( db ) sqlite3_interrupt(db);
drh4c504392000-10-16 22:06:40 +0000788}
danielk19774af00c62005-01-23 23:43:21 +0000789#endif
drh4c504392000-10-16 22:06:40 +0000790
791/*
shane626a6e42009-10-22 17:30:15 +0000792** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000793** invokes for each row of a query result.
794*/
drh4ace5362014-11-10 14:42:28 +0000795static int shell_callback(
796 void *pArg,
797 int nArg, /* Number of result columns */
798 char **azArg, /* Text of each result column */
799 char **azCol, /* Column names */
800 int *aiType /* Column types */
801){
drh75897232000-05-29 14:26:00 +0000802 int i;
drhdcd87a92014-08-18 13:45:42 +0000803 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000804
drh75897232000-05-29 14:26:00 +0000805 switch( p->mode ){
806 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000807 int w = 5;
drh6a535342001-10-19 16:44:56 +0000808 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000809 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000810 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000811 if( len>w ) w = len;
812 }
mistachkin636bf9f2014-07-19 20:15:16 +0000813 if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000814 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000815 fprintf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000816 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000817 }
818 break;
819 }
danielk19770d78bae2008-01-03 07:09:48 +0000820 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000821 case MODE_Column: {
drha0c66f52000-07-29 13:20:21 +0000822 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000823 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000824 int w, n;
825 if( i<ArraySize(p->colWidth) ){
danielk19770d78bae2008-01-03 07:09:48 +0000826 w = p->colWidth[i];
drh75897232000-05-29 14:26:00 +0000827 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000828 w = 0;
drh75897232000-05-29 14:26:00 +0000829 }
drh078b1fd2012-09-21 13:40:02 +0000830 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000831 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000832 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000833 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000834 if( w<n ) w = n;
835 }
836 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +0000837 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +0000838 }
839 if( p->showHeader ){
drh078b1fd2012-09-21 13:40:02 +0000840 if( w<0 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000841 fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
842 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000843 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000844 fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
845 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000846 }
drha0c66f52000-07-29 13:20:21 +0000847 }
848 }
849 if( p->showHeader ){
850 for(i=0; i<nArg; i++){
851 int w;
852 if( i<ArraySize(p->actualWidth) ){
853 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +0000854 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +0000855 }else{
856 w = 10;
857 }
858 fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
859 "----------------------------------------------------------",
mistachkin636bf9f2014-07-19 20:15:16 +0000860 i==nArg-1 ? p->rowSeparator : " ");
drha0c66f52000-07-29 13:20:21 +0000861 }
drh75897232000-05-29 14:26:00 +0000862 }
863 }
drh6a535342001-10-19 16:44:56 +0000864 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000865 for(i=0; i<nArg; i++){
866 int w;
drha0c66f52000-07-29 13:20:21 +0000867 if( i<ArraySize(p->actualWidth) ){
868 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +0000869 }else{
870 w = 10;
871 }
dana98bf362013-11-13 18:35:01 +0000872 if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +0000873 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +0000874 }
dana98bf362013-11-13 18:35:01 +0000875 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +0000876 if( p->iIndent<p->nIndent ){
877 fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +0000878 }
danc4650bb2013-11-18 08:41:06 +0000879 p->iIndent++;
dana98bf362013-11-13 18:35:01 +0000880 }
drh078b1fd2012-09-21 13:40:02 +0000881 if( w<0 ){
882 fprintf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +0000883 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000884 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000885 }else{
886 fprintf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +0000887 azArg[i] ? azArg[i] : p->nullValue,
mistachkin636bf9f2014-07-19 20:15:16 +0000888 i==nArg-1 ? p->rowSeparator : " ");
drh078b1fd2012-09-21 13:40:02 +0000889 }
drh75897232000-05-29 14:26:00 +0000890 }
891 break;
892 }
drhe3710332000-09-29 13:30:53 +0000893 case MODE_Semi:
drh75897232000-05-29 14:26:00 +0000894 case MODE_List: {
895 if( p->cnt++==0 && p->showHeader ){
896 for(i=0; i<nArg; i++){
mistachkin636bf9f2014-07-19 20:15:16 +0000897 fprintf(p->out,"%s%s",azCol[i],
898 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +0000899 }
900 }
drh6a535342001-10-19 16:44:56 +0000901 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +0000902 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +0000903 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +0000904 if( z==0 ) z = p->nullValue;
drh71172c52002-01-24 00:00:21 +0000905 fprintf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +0000906 if( i<nArg-1 ){
mistachkin636bf9f2014-07-19 20:15:16 +0000907 fprintf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +0000908 }else if( p->mode==MODE_Semi ){
mistachkin636bf9f2014-07-19 20:15:16 +0000909 fprintf(p->out, ";%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000910 }else{
mistachkin636bf9f2014-07-19 20:15:16 +0000911 fprintf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +0000912 }
drh75897232000-05-29 14:26:00 +0000913 }
914 break;
915 }
drh1e5d0e92000-05-31 23:33:17 +0000916 case MODE_Html: {
917 if( p->cnt++==0 && p->showHeader ){
mihailim57c591a2008-06-23 21:26:05 +0000918 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000919 for(i=0; i<nArg; i++){
shane43d9cb22009-10-21 14:11:48 +0000920 fprintf(p->out,"<TH>");
921 output_html_string(p->out, azCol[i]);
922 fprintf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +0000923 }
mihailim57c591a2008-06-23 21:26:05 +0000924 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000925 }
drh6a535342001-10-19 16:44:56 +0000926 if( azArg==0 ) break;
mihailim57c591a2008-06-23 21:26:05 +0000927 fprintf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +0000928 for(i=0; i<nArg; i++){
mihailim57c591a2008-06-23 21:26:05 +0000929 fprintf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +0000930 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mihailim57c591a2008-06-23 21:26:05 +0000931 fprintf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +0000932 }
mihailim57c591a2008-06-23 21:26:05 +0000933 fprintf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +0000934 break;
935 }
drhfeac5f82004-08-01 00:10:45 +0000936 case MODE_Tcl: {
937 if( p->cnt++==0 && p->showHeader ){
938 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000939 output_c_string(p->out,azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +0000940 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000941 }
mistachkin636bf9f2014-07-19 20:15:16 +0000942 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000943 }
944 if( azArg==0 ) break;
945 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +0000946 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +0000947 if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +0000948 }
mistachkin636bf9f2014-07-19 20:15:16 +0000949 fprintf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +0000950 break;
951 }
drh8e64d1c2004-10-07 00:32:39 +0000952 case MODE_Csv: {
drh047d4532015-01-18 20:30:23 +0000953 setBinaryMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000954 if( p->cnt++==0 && p->showHeader ){
955 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +0000956 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +0000957 }
mistachkine0d68852014-12-11 03:12:33 +0000958 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000959 }
drh40253262014-10-17 21:35:05 +0000960 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +0000961 for(i=0; i<nArg; i++){
962 output_csv(p, azArg[i], i<nArg-1);
963 }
mistachkine0d68852014-12-11 03:12:33 +0000964 fprintf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000965 }
drh047d4532015-01-18 20:30:23 +0000966 setTextMode(p->out);
drh8e64d1c2004-10-07 00:32:39 +0000967 break;
968 }
drh28bd4bc2000-06-15 15:57:22 +0000969 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +0000970 p->cnt++;
drh6a535342001-10-19 16:44:56 +0000971 if( azArg==0 ) break;
drh33048c02001-10-01 14:29:22 +0000972 fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
drh28bd4bc2000-06-15 15:57:22 +0000973 for(i=0; i<nArg; i++){
974 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +0000975 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
drh28bd4bc2000-06-15 15:57:22 +0000976 fprintf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +0000977 }else if( aiType && aiType[i]==SQLITE_TEXT ){
978 if( zSep[0] ) fprintf(p->out,"%s",zSep);
979 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +0000980 }else if( aiType && (aiType[i]==SQLITE_INTEGER
981 || aiType[i]==SQLITE_FLOAT) ){
shanead6b8d02009-10-22 18:12:58 +0000982 fprintf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +0000983 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
984 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
985 int nBlob = sqlite3_column_bytes(p->pStmt, i);
986 if( zSep[0] ) fprintf(p->out,"%s",zSep);
987 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +0000988 }else if( isNumber(azArg[i], 0) ){
drh28bd4bc2000-06-15 15:57:22 +0000989 fprintf(p->out,"%s%s",zSep, azArg[i]);
990 }else{
991 if( zSep[0] ) fprintf(p->out,"%s",zSep);
992 output_quoted_string(p->out, azArg[i]);
993 }
994 }
995 fprintf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +0000996 break;
drh28bd4bc2000-06-15 15:57:22 +0000997 }
mistachkin636bf9f2014-07-19 20:15:16 +0000998 case MODE_Ascii: {
999 if( p->cnt++==0 && p->showHeader ){
1000 for(i=0; i<nArg; i++){
1001 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
1002 fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
1003 }
1004 fprintf(p->out, "%s", p->rowSeparator);
1005 }
1006 if( azArg==0 ) break;
1007 for(i=0; i<nArg; i++){
1008 if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
mistachkin44b99f72014-12-11 03:29:14 +00001009 fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001010 }
1011 fprintf(p->out, "%s", p->rowSeparator);
1012 break;
1013 }
persicom1d0b8722002-04-18 02:53:04 +00001014 }
drh75897232000-05-29 14:26:00 +00001015 return 0;
1016}
1017
1018/*
shane626a6e42009-10-22 17:30:15 +00001019** This is the callback routine that the SQLite library
1020** invokes for each row of a query result.
1021*/
1022static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1023 /* since we don't have type info, call the shell_callback with a NULL value */
1024 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1025}
1026
1027/*
drhdcd87a92014-08-18 13:45:42 +00001028** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001029** the name of the table given. Escape any quote characters in the
1030** table name.
1031*/
drhdcd87a92014-08-18 13:45:42 +00001032static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001033 int i, n;
1034 int needQuote;
1035 char *z;
1036
1037 if( p->zDestTable ){
1038 free(p->zDestTable);
1039 p->zDestTable = 0;
1040 }
1041 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001042 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001043 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001044 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001045 needQuote = 1;
1046 if( zName[i]=='\'' ) n++;
1047 }
1048 }
1049 if( needQuote ) n += 2;
1050 z = p->zDestTable = malloc( n+1 );
1051 if( z==0 ){
shane86f5bdb2009-10-24 02:00:07 +00001052 fprintf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001053 exit(1);
1054 }
1055 n = 0;
1056 if( needQuote ) z[n++] = '\'';
1057 for(i=0; zName[i]; i++){
1058 z[n++] = zName[i];
1059 if( zName[i]=='\'' ) z[n++] = '\'';
1060 }
1061 if( needQuote ) z[n++] = '\'';
1062 z[n] = 0;
1063}
1064
danielk19772a02e332004-06-05 08:04:36 +00001065/* zIn is either a pointer to a NULL-terminated string in memory obtained
1066** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1067** added to zIn, and the result returned in memory obtained from malloc().
1068** zIn, if it was not NULL, is freed.
1069**
1070** If the third argument, quote, is not '\0', then it is used as a
1071** quote character for zAppend.
1072*/
drhc28490c2006-10-26 14:25:58 +00001073static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001074 int len;
1075 int i;
drh4f21c4a2008-12-10 22:15:00 +00001076 int nAppend = strlen30(zAppend);
1077 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001078
1079 len = nAppend+nIn+1;
1080 if( quote ){
1081 len += 2;
1082 for(i=0; i<nAppend; i++){
1083 if( zAppend[i]==quote ) len++;
1084 }
1085 }
1086
1087 zIn = (char *)realloc(zIn, len);
1088 if( !zIn ){
1089 return 0;
1090 }
1091
1092 if( quote ){
1093 char *zCsr = &zIn[nIn];
1094 *zCsr++ = quote;
1095 for(i=0; i<nAppend; i++){
1096 *zCsr++ = zAppend[i];
1097 if( zAppend[i]==quote ) *zCsr++ = quote;
1098 }
1099 *zCsr++ = quote;
1100 *zCsr++ = '\0';
1101 assert( (zCsr-zIn)==len );
1102 }else{
1103 memcpy(&zIn[nIn], zAppend, nAppend);
1104 zIn[len-1] = '\0';
1105 }
1106
1107 return zIn;
1108}
1109
drhdd3d4592004-08-30 01:54:05 +00001110
1111/*
drhb21a8e42012-01-28 21:08:51 +00001112** Execute a query statement that will generate SQL output. Print
1113** the result columns, comma-separated, on a line and then add a
1114** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001115**
drhb21a8e42012-01-28 21:08:51 +00001116** If the number of columns is 1 and that column contains text "--"
1117** then write the semicolon on a separate line. That way, if a
1118** "--" comment occurs at the end of the statement, the comment
1119** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001120*/
drh157e29a2009-05-21 15:15:00 +00001121static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001122 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001123 const char *zSelect, /* SELECT statement to extract content */
1124 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001125){
drhdd3d4592004-08-30 01:54:05 +00001126 sqlite3_stmt *pSelect;
1127 int rc;
drhb21a8e42012-01-28 21:08:51 +00001128 int nResult;
1129 int i;
1130 const char *z;
drhc7181902014-02-27 15:04:13 +00001131 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001132 if( rc!=SQLITE_OK || !pSelect ){
drh2f464a02011-10-13 00:41:49 +00001133 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001134 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001135 return rc;
1136 }
1137 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001138 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001139 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001140 if( zFirstRow ){
drh2f464a02011-10-13 00:41:49 +00001141 fprintf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001142 zFirstRow = 0;
1143 }
drhb21a8e42012-01-28 21:08:51 +00001144 z = (const char*)sqlite3_column_text(pSelect, 0);
1145 fprintf(p->out, "%s", z);
1146 for(i=1; i<nResult; i++){
1147 fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
1148 }
1149 if( z==0 ) z = "";
1150 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1151 if( z[0] ){
1152 fprintf(p->out, "\n;\n");
1153 }else{
1154 fprintf(p->out, ";\n");
1155 }
drhdd3d4592004-08-30 01:54:05 +00001156 rc = sqlite3_step(pSelect);
1157 }
drh2f464a02011-10-13 00:41:49 +00001158 rc = sqlite3_finalize(pSelect);
1159 if( rc!=SQLITE_OK ){
1160 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001161 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001162 }
1163 return rc;
drhdd3d4592004-08-30 01:54:05 +00001164}
1165
shane626a6e42009-10-22 17:30:15 +00001166/*
1167** Allocate space and save off current error string.
1168*/
1169static char *save_err_msg(
1170 sqlite3 *db /* Database to query */
1171){
1172 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
1173 char *zErrMsg = sqlite3_malloc(nErrMsg);
1174 if( zErrMsg ){
1175 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1176 }
1177 return zErrMsg;
1178}
1179
1180/*
shaneh642d8b82010-07-28 16:05:34 +00001181** Display memory stats.
1182*/
1183static int display_stats(
1184 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001185 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001186 int bReset /* True to reset the stats */
1187){
1188 int iCur;
1189 int iHiwtr;
1190
1191 if( pArg && pArg->out ){
1192
1193 iHiwtr = iCur = -1;
1194 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001195 fprintf(pArg->out,
1196 "Memory Used: %d (max %d) bytes\n",
1197 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001198 iHiwtr = iCur = -1;
1199 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001200 fprintf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
1201 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001202 if( pArg->shellFlgs & SHFLG_Pagecache ){
1203 iHiwtr = iCur = -1;
1204 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001205 fprintf(pArg->out,
1206 "Number of Pcache Pages Used: %d (max %d) pages\n",
1207 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001208 }
shaneh642d8b82010-07-28 16:05:34 +00001209 iHiwtr = iCur = -1;
1210 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001211 fprintf(pArg->out,
1212 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1213 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001214 if( pArg->shellFlgs & SHFLG_Scratch ){
1215 iHiwtr = iCur = -1;
1216 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001217 fprintf(pArg->out, "Number of Scratch Allocations Used: %d (max %d)\n",
1218 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001219 }
shaneh642d8b82010-07-28 16:05:34 +00001220 iHiwtr = iCur = -1;
1221 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001222 fprintf(pArg->out,
1223 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1224 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001225 iHiwtr = iCur = -1;
1226 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001227 fprintf(pArg->out, "Largest Allocation: %d bytes\n",
1228 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001229 iHiwtr = iCur = -1;
1230 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001231 fprintf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
1232 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001233 iHiwtr = iCur = -1;
1234 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001235 fprintf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
1236 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001237#ifdef YYTRACKMAXSTACKDEPTH
1238 iHiwtr = iCur = -1;
1239 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001240 fprintf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
1241 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001242#endif
1243 }
1244
1245 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001246 if( pArg->shellFlgs & SHFLG_Lookaside ){
1247 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001248 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1249 &iCur, &iHiwtr, bReset);
1250 fprintf(pArg->out, "Lookaside Slots Used: %d (max %d)\n",
1251 iCur, iHiwtr);
1252 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1253 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001254 fprintf(pArg->out, "Successful lookaside attempts: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001255 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1256 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001257 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001258 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1259 &iCur, &iHiwtr, bReset);
drh44dec872014-08-30 15:49:25 +00001260 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1261 }
shaneh642d8b82010-07-28 16:05:34 +00001262 iHiwtr = iCur = -1;
1263 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001264 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n",iCur);
1265 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001266 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1267 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1268 iHiwtr = iCur = -1;
1269 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1270 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001271 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001272 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
1273 fprintf(pArg->out, "Page cache writes: %d\n", iCur);
1274 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001275 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001276 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001277 iHiwtr = iCur = -1;
1278 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
drh4ace5362014-11-10 14:42:28 +00001279 fprintf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",iCur);
shaneh642d8b82010-07-28 16:05:34 +00001280 }
1281
1282 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001283 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1284 bReset);
shaneh642d8b82010-07-28 16:05:34 +00001285 fprintf(pArg->out, "Fullscan Steps: %d\n", iCur);
1286 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1287 fprintf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001288 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
shaneh642d8b82010-07-28 16:05:34 +00001289 fprintf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001290 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1291 fprintf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001292 }
1293
1294 return 0;
1295}
1296
1297/*
dan8d1edb92014-11-05 09:07:28 +00001298** Display scan stats.
1299*/
1300static void display_scanstats(
1301 sqlite3 *db, /* Database to query */
1302 ShellState *pArg /* Pointer to ShellState */
1303){
1304#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
drh15f23c22014-11-06 12:46:16 +00001305 int i, k, n, mx;
dan8d1edb92014-11-05 09:07:28 +00001306 fprintf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001307 mx = 0;
1308 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001309 double rEstLoop = 1.0;
1310 for(i=n=0; 1; i++){
1311 sqlite3_stmt *p = pArg->pStmt;
1312 sqlite3_int64 nLoop, nVisit;
1313 double rEst;
1314 int iSid;
1315 const char *zExplain;
1316 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1317 break;
1318 }
1319 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001320 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001321 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001322 if( n==0 ){
1323 rEstLoop = (double)nLoop;
drh15f23c22014-11-06 12:46:16 +00001324 if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001325 }
drh42f30bc2014-11-06 12:08:21 +00001326 n++;
1327 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1328 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1329 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
1330 fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
1331 rEstLoop *= rEst;
drh4ace5362014-11-10 14:42:28 +00001332 fprintf(pArg->out,
1333 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001334 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001335 );
dan8d1edb92014-11-05 09:07:28 +00001336 }
dan8d1edb92014-11-05 09:07:28 +00001337 }
dan8d1edb92014-11-05 09:07:28 +00001338 fprintf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001339#endif
dan8d1edb92014-11-05 09:07:28 +00001340}
1341
1342/*
dana98bf362013-11-13 18:35:01 +00001343** Parameter azArray points to a zero-terminated array of strings. zStr
1344** points to a single nul-terminated string. Return non-zero if zStr
1345** is equal, according to strcmp(), to any of the strings in the array.
1346** Otherwise, return zero.
1347*/
1348static int str_in_array(const char *zStr, const char **azArray){
1349 int i;
1350 for(i=0; azArray[i]; i++){
1351 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1352 }
1353 return 0;
1354}
1355
1356/*
1357** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001358** and populate the ShellState.aiIndent[] array with the number of
dana98bf362013-11-13 18:35:01 +00001359** spaces each opcode should be indented before it is output.
1360**
1361** The indenting rules are:
1362**
1363** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1364** all opcodes that occur between the p2 jump destination and the opcode
1365** itself by 2 spaces.
1366**
drh01752bc2013-11-14 23:59:33 +00001367** * For each "Goto", if the jump destination is earlier in the program
1368** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001369** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001370** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001371** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001372** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001373*/
drhdcd87a92014-08-18 13:45:42 +00001374static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001375 const char *zSql; /* The text of the SQL statement */
1376 const char *z; /* Used to check if this is an EXPLAIN */
1377 int *abYield = 0; /* True if op is an OP_Yield */
1378 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001379 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001380
drh8ad0de32014-03-20 18:45:27 +00001381 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1382 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001383 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1384 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001385 const char *azGoto[] = { "Goto", 0 };
1386
1387 /* Try to figure out if this is really an EXPLAIN statement. If this
1388 ** cannot be verified, return early. */
1389 zSql = sqlite3_sql(pSql);
1390 if( zSql==0 ) return;
1391 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
1392 if( sqlite3_strnicmp(z, "explain", 7) ) return;
1393
1394 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1395 int i;
danc4650bb2013-11-18 08:41:06 +00001396 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001397 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001398
1399 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1400 ** p2 is an instruction address, set variable p2op to the index of that
1401 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1402 ** the current instruction is part of a sub-program generated by an
1403 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001404 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001405 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001406
1407 /* Grow the p->aiIndent array as required */
1408 if( iOp>=nAlloc ){
1409 nAlloc += 100;
1410 p->aiIndent = (int*)sqlite3_realloc(p->aiIndent, nAlloc*sizeof(int));
1411 abYield = (int*)sqlite3_realloc(abYield, nAlloc*sizeof(int));
1412 }
1413 abYield[iOp] = str_in_array(zOp, azYield);
1414 p->aiIndent[iOp] = 0;
1415 p->nIndent = iOp+1;
1416
1417 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001418 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001419 }
drhfe705102014-03-06 13:38:37 +00001420 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1421 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1422 ){
drhe73f0592014-01-21 22:25:45 +00001423 for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001424 }
1425 }
1426
danc4650bb2013-11-18 08:41:06 +00001427 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001428 sqlite3_free(abYield);
1429 sqlite3_reset(pSql);
1430}
1431
1432/*
1433** Free the array allocated by explain_data_prepare().
1434*/
drhdcd87a92014-08-18 13:45:42 +00001435static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001436 sqlite3_free(p->aiIndent);
1437 p->aiIndent = 0;
1438 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001439 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001440}
1441
1442/*
shane626a6e42009-10-22 17:30:15 +00001443** Execute a statement or set of statements. Print
1444** any result rows/columns depending on the current mode
1445** set via the supplied callback.
1446**
1447** This is very similar to SQLite's built-in sqlite3_exec()
1448** function except it takes a slightly different callback
1449** and callback data argument.
1450*/
1451static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001452 sqlite3 *db, /* An open database */
1453 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001454 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001455 /* (not the same as sqlite3_exec) */
1456 ShellState *pArg, /* Pointer to ShellState */
1457 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001458){
dan4564ced2010-01-05 04:59:56 +00001459 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1460 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001461 int rc2;
dan4564ced2010-01-05 04:59:56 +00001462 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001463
1464 if( pzErrMsg ){
1465 *pzErrMsg = NULL;
1466 }
1467
shaneb9fc17d2009-10-22 21:23:35 +00001468 while( zSql[0] && (SQLITE_OK == rc) ){
1469 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1470 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001471 if( pzErrMsg ){
1472 *pzErrMsg = save_err_msg(db);
1473 }
1474 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001475 if( !pStmt ){
1476 /* this happens for a comment or white-space */
1477 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001478 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001479 continue;
1480 }
shane626a6e42009-10-22 17:30:15 +00001481
shaneh642d8b82010-07-28 16:05:34 +00001482 /* save off the prepared statment handle and reset row count */
1483 if( pArg ){
1484 pArg->pStmt = pStmt;
1485 pArg->cnt = 0;
1486 }
1487
shanehb7977c52010-01-18 18:17:10 +00001488 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001489 if( pArg && pArg->echoOn ){
drha8c62df2010-02-15 15:47:18 +00001490 const char *zStmtSql = sqlite3_sql(pStmt);
shaneh642d8b82010-07-28 16:05:34 +00001491 fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001492 }
shanehb7977c52010-01-18 18:17:10 +00001493
drhefbf3b12014-02-28 20:47:24 +00001494 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
1495 if( pArg && pArg->autoEQP ){
1496 sqlite3_stmt *pExplain;
drh4ace5362014-11-10 14:42:28 +00001497 char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
1498 sqlite3_sql(pStmt));
drhefbf3b12014-02-28 20:47:24 +00001499 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1500 if( rc==SQLITE_OK ){
1501 while( sqlite3_step(pExplain)==SQLITE_ROW ){
1502 fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
1503 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1504 fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
1505 fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
1506 }
1507 }
1508 sqlite3_finalize(pExplain);
1509 sqlite3_free(zEQP);
1510 }
1511
dana98bf362013-11-13 18:35:01 +00001512 /* If the shell is currently in ".explain" mode, gather the extra
1513 ** data required to add indents to the output.*/
drh0a305922013-11-21 23:37:02 +00001514 if( pArg && pArg->mode==MODE_Explain ){
dana98bf362013-11-13 18:35:01 +00001515 explain_data_prepare(pArg, pStmt);
1516 }
1517
shaneb9fc17d2009-10-22 21:23:35 +00001518 /* perform the first step. this will tell us if we
1519 ** have a result set or not and how wide it is.
1520 */
1521 rc = sqlite3_step(pStmt);
1522 /* if we have a result set... */
1523 if( SQLITE_ROW == rc ){
1524 /* if we have a callback... */
1525 if( xCallback ){
1526 /* allocate space for col name ptr, value ptr, and type */
1527 int nCol = sqlite3_column_count(pStmt);
1528 void *pData = sqlite3_malloc(3*nCol*sizeof(const char*) + 1);
1529 if( !pData ){
1530 rc = SQLITE_NOMEM;
1531 }else{
1532 char **azCols = (char **)pData; /* Names of result columns */
1533 char **azVals = &azCols[nCol]; /* Results */
1534 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
drh55a1b302013-09-04 16:08:50 +00001535 int i, x;
shaneb9fc17d2009-10-22 21:23:35 +00001536 assert(sizeof(int) <= sizeof(char *));
1537 /* save off ptrs to column names */
1538 for(i=0; i<nCol; i++){
1539 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1540 }
shaneb9fc17d2009-10-22 21:23:35 +00001541 do{
1542 /* extract the data and data types */
1543 for(i=0; i<nCol; i++){
drh55a1b302013-09-04 16:08:50 +00001544 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
drh3432daa2013-10-11 16:35:49 +00001545 if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
drh55a1b302013-09-04 16:08:50 +00001546 azVals[i] = "";
1547 }else{
1548 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1549 }
shaneb9fc17d2009-10-22 21:23:35 +00001550 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1551 rc = SQLITE_NOMEM;
1552 break; /* from for */
1553 }
1554 } /* end for */
1555
1556 /* if data and types extracted successfully... */
1557 if( SQLITE_ROW == rc ){
1558 /* call the supplied callback with the result row data */
1559 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1560 rc = SQLITE_ABORT;
1561 }else{
1562 rc = sqlite3_step(pStmt);
1563 }
1564 }
1565 } while( SQLITE_ROW == rc );
1566 sqlite3_free(pData);
shaneb9fc17d2009-10-22 21:23:35 +00001567 }
1568 }else{
1569 do{
1570 rc = sqlite3_step(pStmt);
1571 } while( rc == SQLITE_ROW );
1572 }
1573 }
1574
dana98bf362013-11-13 18:35:01 +00001575 explain_data_delete(pArg);
1576
shaneh642d8b82010-07-28 16:05:34 +00001577 /* print usage stats if stats on */
1578 if( pArg && pArg->statsOn ){
1579 display_stats(db, pArg, 0);
1580 }
1581
dan8d1edb92014-11-05 09:07:28 +00001582 /* print loop-counters if required */
1583 if( pArg && pArg->scanstatsOn ){
1584 display_scanstats(db, pArg);
1585 }
1586
dan4564ced2010-01-05 04:59:56 +00001587 /* Finalize the statement just executed. If this fails, save a
1588 ** copy of the error message. Otherwise, set zSql to point to the
1589 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001590 rc2 = sqlite3_finalize(pStmt);
1591 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001592 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001593 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001594 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001595 }else if( pzErrMsg ){
1596 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001597 }
shaneh642d8b82010-07-28 16:05:34 +00001598
1599 /* clear saved stmt handle */
1600 if( pArg ){
1601 pArg->pStmt = NULL;
1602 }
shane626a6e42009-10-22 17:30:15 +00001603 }
shaneb9fc17d2009-10-22 21:23:35 +00001604 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001605
1606 return rc;
1607}
1608
drhdd3d4592004-08-30 01:54:05 +00001609
drh33048c02001-10-01 14:29:22 +00001610/*
drh4c653a02000-06-07 01:27:47 +00001611** This is a different callback routine used for dumping the database.
1612** Each row received by this callback consists of a table name,
1613** the table type ("index" or "table") and SQL to create the table.
1614** This routine should print text sufficient to recreate the table.
1615*/
1616static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001617 int rc;
1618 const char *zTable;
1619 const char *zType;
1620 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00001621 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00001622 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00001623
drh902b9ee2008-12-05 17:17:07 +00001624 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00001625 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00001626 zTable = azArg[0];
1627 zType = azArg[1];
1628 zSql = azArg[2];
1629
drh00b950d2005-09-11 02:03:03 +00001630 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00001631 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00001632 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh00b950d2005-09-11 02:03:03 +00001633 fprintf(p->out, "ANALYZE sqlite_master;\n");
1634 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
1635 return 0;
drh45e29d82006-11-20 16:21:10 +00001636 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
1637 char *zIns;
1638 if( !p->writableSchema ){
1639 fprintf(p->out, "PRAGMA writable_schema=ON;\n");
1640 p->writableSchema = 1;
1641 }
1642 zIns = sqlite3_mprintf(
1643 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
1644 "VALUES('table','%q','%q',0,'%q');",
1645 zTable, zTable, zSql);
1646 fprintf(p->out, "%s\n", zIns);
1647 sqlite3_free(zIns);
1648 return 0;
drh00b950d2005-09-11 02:03:03 +00001649 }else{
1650 fprintf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00001651 }
danielk19772a02e332004-06-05 08:04:36 +00001652
1653 if( strcmp(zType, "table")==0 ){
1654 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00001655 char *zSelect = 0;
1656 char *zTableInfo = 0;
1657 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00001658 int nRow = 0;
danielk19772a02e332004-06-05 08:04:36 +00001659
1660 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
1661 zTableInfo = appendText(zTableInfo, zTable, '"');
1662 zTableInfo = appendText(zTableInfo, ");", 0);
1663
drhc7181902014-02-27 15:04:13 +00001664 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00001665 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00001666 if( rc!=SQLITE_OK || !pTableInfo ){
1667 return 1;
1668 }
1669
1670 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00001671 /* Always quote the table name, even if it appears to be pure ascii,
1672 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
1673 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00001674 if( zTmp ){
1675 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00001676 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00001677 }
1678 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
1679 rc = sqlite3_step(pTableInfo);
1680 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00001681 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00001682 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00001683 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00001684 rc = sqlite3_step(pTableInfo);
1685 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00001686 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00001687 }else{
1688 zSelect = appendText(zSelect, ") ", 0);
1689 }
drh157e29a2009-05-21 15:15:00 +00001690 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00001691 }
1692 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00001693 if( rc!=SQLITE_OK || nRow==0 ){
1694 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00001695 return 1;
1696 }
1697 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1698 zSelect = appendText(zSelect, zTable, '"');
1699
drh2f464a02011-10-13 00:41:49 +00001700 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00001701 if( rc==SQLITE_CORRUPT ){
1702 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00001703 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001704 }
drh85e72432012-04-11 11:38:53 +00001705 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00001706 }
drh4c653a02000-06-07 01:27:47 +00001707 return 0;
1708}
1709
1710/*
drh45e29d82006-11-20 16:21:10 +00001711** Run zQuery. Use dump_callback() as the callback routine so that
1712** the contents of the query are output as SQL statements.
1713**
drhdd3d4592004-08-30 01:54:05 +00001714** If we get a SQLITE_CORRUPT error, rerun the query after appending
1715** "ORDER BY rowid DESC" to the end.
1716*/
1717static int run_schema_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001718 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00001719 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00001720){
1721 int rc;
drh2f464a02011-10-13 00:41:49 +00001722 char *zErr = 0;
1723 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00001724 if( rc==SQLITE_CORRUPT ){
1725 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00001726 int len = strlen30(zQuery);
drh2f464a02011-10-13 00:41:49 +00001727 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1728 if( zErr ){
1729 fprintf(p->out, "/****** %s ******/\n", zErr);
1730 sqlite3_free(zErr);
1731 zErr = 0;
1732 }
drhdd3d4592004-08-30 01:54:05 +00001733 zQ2 = malloc( len+100 );
1734 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00001735 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00001736 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1737 if( rc ){
1738 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1739 }else{
1740 rc = SQLITE_CORRUPT;
1741 }
1742 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00001743 free(zQ2);
1744 }
1745 return rc;
1746}
1747
1748/*
drh75897232000-05-29 14:26:00 +00001749** Text of a help message
1750*/
persicom1d0b8722002-04-18 02:53:04 +00001751static char zHelp[] =
drh9ff849f2009-02-04 20:55:57 +00001752 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00001753 ".bail on|off Stop after hitting an error. Default OFF\n"
drh4bbcf102014-02-06 02:46:08 +00001754 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00001755 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00001756 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00001757 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00001758 " If TABLE specified, only dump tables matching\n"
1759 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00001760 ".echo on|off Turn command echo on or off\n"
drh6d36ffe2014-06-16 15:01:37 +00001761 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00001762 ".exit Exit this program\n"
drhc2ce0be2014-05-29 12:36:14 +00001763 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
shanehe2aa9d72009-11-06 17:20:17 +00001764 " With no args, it turns EXPLAIN on.\n"
drhc1971542014-06-23 23:28:13 +00001765 ".fullschema Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00001766 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00001767 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00001768 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00001769 ".indexes ?TABLE? Show names of all indexes\n"
1770 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00001771 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00001772#ifdef SQLITE_ENABLE_IOTRACE
1773 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
1774#endif
drh70df4fe2006-06-13 15:12:21 +00001775#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00001776 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00001777#endif
drh127f9d72010-02-23 01:47:00 +00001778 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00001779 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00001780 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00001781 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00001782 " column Left-aligned columns. (See .width)\n"
1783 " html HTML <table> code\n"
1784 " insert SQL insert statements for TABLE\n"
1785 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00001786 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00001787 " tabs Tab-separated values\n"
1788 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00001789 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00001790 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00001791 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00001792 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00001793 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001794 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00001795 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00001796 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00001797 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00001798 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00001799 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh75897232000-05-29 14:26:00 +00001800 ".schema ?TABLE? Show the CREATE statements\n"
shane86f5bdb2009-10-24 02:00:07 +00001801 " If TABLE specified, only show tables matching\n"
1802 " LIKE pattern TABLE.\n"
mistachkine0d68852014-12-11 03:12:33 +00001803 ".separator COL ?ROW? Change the column separator and optionally the row\n"
1804 " separator for both the output mode and .import\n"
drh62cdde52014-05-28 20:22:28 +00001805 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00001806 ".show Show the current values for various settings\n"
drhc2ce0be2014-05-29 12:36:14 +00001807 ".stats on|off Turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00001808 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00001809 ".tables ?TABLE? List names of tables\n"
1810 " If TABLE specified, only list tables matching\n"
1811 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00001812 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00001813 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00001814 ".trace FILE|off Output each SQL statement as it is run\n"
drhde60fc22011-12-14 17:53:36 +00001815 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00001816 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00001817 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00001818;
1819
drhdaffd0e2001-04-11 14:28:42 +00001820/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00001821static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00001822/*
1823** Implementation of the "readfile(X)" SQL function. The entire content
1824** of the file named X is read and returned as a BLOB. NULL is returned
1825** if the file does not exist or is unreadable.
1826*/
1827static void readfileFunc(
1828 sqlite3_context *context,
1829 int argc,
1830 sqlite3_value **argv
1831){
1832 const char *zName;
1833 FILE *in;
1834 long nIn;
1835 void *pBuf;
1836
1837 zName = (const char*)sqlite3_value_text(argv[0]);
1838 if( zName==0 ) return;
1839 in = fopen(zName, "rb");
1840 if( in==0 ) return;
1841 fseek(in, 0, SEEK_END);
1842 nIn = ftell(in);
1843 rewind(in);
1844 pBuf = sqlite3_malloc( nIn );
1845 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
1846 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
1847 }else{
1848 sqlite3_free(pBuf);
1849 }
1850 fclose(in);
1851}
1852
1853/*
1854** Implementation of the "writefile(X,Y)" SQL function. The argument Y
1855** is written into file X. The number of bytes written is returned. Or
1856** NULL is returned if something goes wrong, such as being unable to open
1857** file X for writing.
1858*/
1859static void writefileFunc(
1860 sqlite3_context *context,
1861 int argc,
1862 sqlite3_value **argv
1863){
1864 FILE *out;
1865 const char *z;
drhba5b0932014-07-24 12:39:59 +00001866 sqlite3_int64 rc;
1867 const char *zFile;
1868
1869 zFile = (const char*)sqlite3_value_text(argv[0]);
1870 if( zFile==0 ) return;
1871 out = fopen(zFile, "wb");
1872 if( out==0 ) return;
1873 z = (const char*)sqlite3_value_blob(argv[1]);
1874 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00001875 rc = 0;
1876 }else{
drh490fe862014-08-11 14:21:32 +00001877 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00001878 }
1879 fclose(out);
1880 sqlite3_result_int64(context, rc);
1881}
drhdaffd0e2001-04-11 14:28:42 +00001882
drh75897232000-05-29 14:26:00 +00001883/*
drh44c2eb12003-04-30 11:38:26 +00001884** Make sure the database is open. If it is not, then open it. If
1885** the database fails to open, print an error message and exit.
1886*/
drhdcd87a92014-08-18 13:45:42 +00001887static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00001888 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00001889 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00001890 sqlite3_open(p->zDbFilename, &p->db);
danielk197780290862004-05-22 09:21:21 +00001891 db = p->db;
drh4cea5ba2008-05-05 16:27:24 +00001892 if( db && sqlite3_errcode(db)==SQLITE_OK ){
1893 sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
1894 shellstaticFunc, 0, 0);
1895 }
1896 if( db==0 || SQLITE_OK!=sqlite3_errcode(db) ){
shane86f5bdb2009-10-24 02:00:07 +00001897 fprintf(stderr,"Error: unable to open database \"%s\": %s\n",
danielk197780290862004-05-22 09:21:21 +00001898 p->zDbFilename, sqlite3_errmsg(db));
drh05782482013-10-24 15:20:20 +00001899 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00001900 exit(1);
drh44c2eb12003-04-30 11:38:26 +00001901 }
drhc2e87a32006-06-27 15:16:14 +00001902#ifndef SQLITE_OMIT_LOAD_EXTENSION
1903 sqlite3_enable_load_extension(p->db, 1);
1904#endif
drhba5b0932014-07-24 12:39:59 +00001905 sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
1906 readfileFunc, 0, 0);
1907 sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
1908 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00001909 }
1910}
1911
1912/*
drhfeac5f82004-08-01 00:10:45 +00001913** Do C-language style dequoting.
1914**
1915** \t -> tab
1916** \n -> newline
1917** \r -> carriage return
drh4c56b992013-06-27 13:26:55 +00001918** \" -> "
drhfeac5f82004-08-01 00:10:45 +00001919** \NNN -> ascii character NNN in octal
1920** \\ -> backslash
1921*/
1922static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00001923 int i, j;
1924 char c;
drhc2ce0be2014-05-29 12:36:14 +00001925 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00001926 for(i=j=0; (c = z[i])!=0; i++, j++){
1927 if( c=='\\' ){
1928 c = z[++i];
1929 if( c=='n' ){
1930 c = '\n';
1931 }else if( c=='t' ){
1932 c = '\t';
1933 }else if( c=='r' ){
1934 c = '\r';
drh4c56b992013-06-27 13:26:55 +00001935 }else if( c=='\\' ){
1936 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00001937 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00001938 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00001939 if( z[i+1]>='0' && z[i+1]<='7' ){
1940 i++;
1941 c = (c<<3) + z[i] - '0';
1942 if( z[i+1]>='0' && z[i+1]<='7' ){
1943 i++;
1944 c = (c<<3) + z[i] - '0';
1945 }
1946 }
1947 }
1948 }
1949 z[j] = c;
1950 }
drhc2ce0be2014-05-29 12:36:14 +00001951 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00001952}
1953
1954/*
drh348d19c2013-06-03 12:47:43 +00001955** Return the value of a hexadecimal digit. Return -1 if the input
1956** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00001957*/
drh348d19c2013-06-03 12:47:43 +00001958static int hexDigitValue(char c){
1959 if( c>='0' && c<='9' ) return c - '0';
1960 if( c>='a' && c<='f' ) return c - 'a' + 10;
1961 if( c>='A' && c<='F' ) return c - 'A' + 10;
1962 return -1;
drhc28490c2006-10-26 14:25:58 +00001963}
1964
1965/*
drh7d9f3942013-04-03 01:26:54 +00001966** Interpret zArg as an integer value, possibly with suffixes.
1967*/
1968static sqlite3_int64 integerValue(const char *zArg){
1969 sqlite3_int64 v = 0;
1970 static const struct { char *zSuffix; int iMult; } aMult[] = {
1971 { "KiB", 1024 },
1972 { "MiB", 1024*1024 },
1973 { "GiB", 1024*1024*1024 },
1974 { "KB", 1000 },
1975 { "MB", 1000000 },
1976 { "GB", 1000000000 },
1977 { "K", 1000 },
1978 { "M", 1000000 },
1979 { "G", 1000000000 },
1980 };
1981 int i;
1982 int isNeg = 0;
1983 if( zArg[0]=='-' ){
1984 isNeg = 1;
1985 zArg++;
1986 }else if( zArg[0]=='+' ){
1987 zArg++;
1988 }
drh348d19c2013-06-03 12:47:43 +00001989 if( zArg[0]=='0' && zArg[1]=='x' ){
1990 int x;
1991 zArg += 2;
1992 while( (x = hexDigitValue(zArg[0]))>=0 ){
1993 v = (v<<4) + x;
1994 zArg++;
1995 }
1996 }else{
1997 while( IsDigit(zArg[0]) ){
1998 v = v*10 + zArg[0] - '0';
1999 zArg++;
2000 }
drh7d9f3942013-04-03 01:26:54 +00002001 }
drhc2bed0a2013-05-24 11:57:50 +00002002 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002003 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2004 v *= aMult[i].iMult;
2005 break;
2006 }
2007 }
2008 return isNeg? -v : v;
2009}
2010
2011/*
drh348d19c2013-06-03 12:47:43 +00002012** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2013** for TRUE and FALSE. Return the integer value if appropriate.
2014*/
2015static int booleanValue(char *zArg){
2016 int i;
2017 if( zArg[0]=='0' && zArg[1]=='x' ){
2018 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2019 }else{
2020 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2021 }
2022 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2023 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2024 return 1;
2025 }
2026 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2027 return 0;
2028 }
2029 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
2030 zArg);
2031 return 0;
2032}
2033
2034/*
drh42f64e52012-04-04 16:56:23 +00002035** Close an output file, assuming it is not stderr or stdout
2036*/
2037static void output_file_close(FILE *f){
2038 if( f && f!=stdout && f!=stderr ) fclose(f);
2039}
2040
2041/*
2042** Try to open an output file. The names "stdout" and "stderr" are
2043** recognized and do the right thing. NULL is returned if the output
2044** filename is "off".
2045*/
2046static FILE *output_file_open(const char *zFile){
2047 FILE *f;
2048 if( strcmp(zFile,"stdout")==0 ){
2049 f = stdout;
2050 }else if( strcmp(zFile, "stderr")==0 ){
2051 f = stderr;
2052 }else if( strcmp(zFile, "off")==0 ){
2053 f = 0;
2054 }else{
2055 f = fopen(zFile, "wb");
2056 if( f==0 ){
2057 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
2058 }
2059 }
2060 return f;
2061}
2062
2063/*
2064** A routine for handling output from sqlite3_trace().
2065*/
2066static void sql_trace_callback(void *pArg, const char *z){
2067 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002068 if( f ){
2069 int i = (int)strlen(z);
2070 while( i>0 && z[i-1]==';' ){ i--; }
2071 fprintf(f, "%.*s;\n", i, z);
2072 }
drh42f64e52012-04-04 16:56:23 +00002073}
2074
2075/*
drhd8621b92012-04-17 09:09:33 +00002076** A no-op routine that runs with the ".breakpoint" doc-command. This is
2077** a useful spot to set a debugger breakpoint.
2078*/
2079static void test_breakpoint(void){
2080 static int nCall = 0;
2081 nCall++;
2082}
2083
2084/*
mistachkin636bf9f2014-07-19 20:15:16 +00002085** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002086*/
mistachkin636bf9f2014-07-19 20:15:16 +00002087typedef struct ImportCtx ImportCtx;
2088struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002089 const char *zFile; /* Name of the input file */
2090 FILE *in; /* Read the CSV text from this input stream */
2091 char *z; /* Accumulated text for a field */
2092 int n; /* Number of bytes in z */
2093 int nAlloc; /* Space allocated for z[] */
2094 int nLine; /* Current line number */
2095 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002096 int cColSep; /* The column separator character. (Usually ",") */
2097 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002098};
2099
2100/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002101static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002102 if( p->n+1>=p->nAlloc ){
2103 p->nAlloc += p->nAlloc + 100;
2104 p->z = sqlite3_realloc(p->z, p->nAlloc);
2105 if( p->z==0 ){
2106 fprintf(stderr, "out of memory\n");
2107 exit(1);
2108 }
2109 }
2110 p->z[p->n++] = (char)c;
2111}
2112
2113/* Read a single field of CSV text. Compatible with rfc4180 and extended
2114** with the option of having a separator other than ",".
2115**
2116** + Input comes from p->in.
2117** + Store results in p->z of length p->n. Space to hold p->z comes
2118** from sqlite3_malloc().
mistachkin636bf9f2014-07-19 20:15:16 +00002119** + Use p->cSep as the column separator. The default is ",".
2120** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002121** + Keep track of the line number in p->nLine.
2122** + Store the character that terminates the field in p->cTerm. Store
2123** EOF on end-of-file.
2124** + Report syntax errors on stderr
2125*/
mistachkin636bf9f2014-07-19 20:15:16 +00002126static char *csv_read_one_field(ImportCtx *p){
2127 int c;
2128 int cSep = p->cColSep;
2129 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002130 p->n = 0;
2131 c = fgetc(p->in);
2132 if( c==EOF || seenInterrupt ){
2133 p->cTerm = EOF;
2134 return 0;
2135 }
2136 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002137 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002138 int startLine = p->nLine;
2139 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002140 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002141 while( 1 ){
2142 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002143 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002144 if( c==cQuote ){
2145 if( pc==cQuote ){
2146 pc = 0;
2147 continue;
2148 }
2149 }
2150 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002151 || (c==rSep && pc==cQuote)
2152 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002153 || (c==EOF && pc==cQuote)
2154 ){
2155 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002156 p->cTerm = c;
2157 break;
2158 }
2159 if( pc==cQuote && c!='\r' ){
2160 fprintf(stderr, "%s:%d: unescaped %c character\n",
2161 p->zFile, p->nLine, cQuote);
2162 }
2163 if( c==EOF ){
2164 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
2165 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002166 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002167 break;
2168 }
mistachkin636bf9f2014-07-19 20:15:16 +00002169 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002170 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002171 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002172 }
drhdb95f682013-06-26 22:46:00 +00002173 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002174 while( c!=EOF && c!=cSep && c!=rSep ){
2175 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002176 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002177 }
mistachkin636bf9f2014-07-19 20:15:16 +00002178 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002179 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002180 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002181 }
drhdb95f682013-06-26 22:46:00 +00002182 p->cTerm = c;
2183 }
drh8dd675e2013-07-12 21:09:24 +00002184 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002185 return p->z;
2186}
2187
mistachkin636bf9f2014-07-19 20:15:16 +00002188/* Read a single field of ASCII delimited text.
2189**
2190** + Input comes from p->in.
2191** + Store results in p->z of length p->n. Space to hold p->z comes
2192** from sqlite3_malloc().
2193** + Use p->cSep as the column separator. The default is "\x1F".
2194** + Use p->rSep as the row separator. The default is "\x1E".
2195** + Keep track of the row number in p->nLine.
2196** + Store the character that terminates the field in p->cTerm. Store
2197** EOF on end-of-file.
2198** + Report syntax errors on stderr
2199*/
2200static char *ascii_read_one_field(ImportCtx *p){
2201 int c;
2202 int cSep = p->cColSep;
2203 int rSep = p->cRowSep;
2204 p->n = 0;
2205 c = fgetc(p->in);
2206 if( c==EOF || seenInterrupt ){
2207 p->cTerm = EOF;
2208 return 0;
2209 }
2210 while( c!=EOF && c!=cSep && c!=rSep ){
2211 import_append_char(p, c);
2212 c = fgetc(p->in);
2213 }
2214 if( c==rSep ){
2215 p->nLine++;
2216 }
2217 p->cTerm = c;
2218 if( p->z ) p->z[p->n] = 0;
2219 return p->z;
2220}
2221
drhdb95f682013-06-26 22:46:00 +00002222/*
drh4bbcf102014-02-06 02:46:08 +00002223** Try to transfer data for table zTable. If an error is seen while
2224** moving forward, try to go backwards. The backwards movement won't
2225** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002226*/
mistachkine31ae902014-02-06 01:15:29 +00002227static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002228 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002229 sqlite3 *newDb,
2230 const char *zTable
2231){
2232 sqlite3_stmt *pQuery = 0;
2233 sqlite3_stmt *pInsert = 0;
2234 char *zQuery = 0;
2235 char *zInsert = 0;
2236 int rc;
2237 int i, j, n;
2238 int nTable = (int)strlen(zTable);
2239 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002240 int cnt = 0;
2241 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002242
2243 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2244 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2245 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002246 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002247 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2248 zQuery);
2249 goto end_data_xfer;
2250 }
2251 n = sqlite3_column_count(pQuery);
2252 zInsert = sqlite3_malloc(200 + nTable + n*3);
2253 if( zInsert==0 ){
2254 fprintf(stderr, "out of memory\n");
2255 goto end_data_xfer;
2256 }
2257 sqlite3_snprintf(200+nTable,zInsert,
2258 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2259 i = (int)strlen(zInsert);
2260 for(j=1; j<n; j++){
2261 memcpy(zInsert+i, ",?", 2);
2262 i += 2;
2263 }
2264 memcpy(zInsert+i, ");", 3);
2265 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2266 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002267 fprintf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002268 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2269 zQuery);
2270 goto end_data_xfer;
2271 }
2272 for(k=0; k<2; k++){
2273 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2274 for(i=0; i<n; i++){
2275 switch( sqlite3_column_type(pQuery, i) ){
2276 case SQLITE_NULL: {
2277 sqlite3_bind_null(pInsert, i+1);
2278 break;
2279 }
2280 case SQLITE_INTEGER: {
2281 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2282 break;
2283 }
2284 case SQLITE_FLOAT: {
2285 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2286 break;
2287 }
2288 case SQLITE_TEXT: {
2289 sqlite3_bind_text(pInsert, i+1,
2290 (const char*)sqlite3_column_text(pQuery,i),
2291 -1, SQLITE_STATIC);
2292 break;
2293 }
2294 case SQLITE_BLOB: {
2295 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2296 sqlite3_column_bytes(pQuery,i),
2297 SQLITE_STATIC);
2298 break;
2299 }
2300 }
2301 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002302 rc = sqlite3_step(pInsert);
2303 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
2304 fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
2305 sqlite3_errmsg(newDb));
2306 }
drh3350ce92014-02-06 00:49:12 +00002307 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002308 cnt++;
2309 if( (cnt%spinRate)==0 ){
2310 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2311 fflush(stdout);
2312 }
drh3350ce92014-02-06 00:49:12 +00002313 } /* End while */
2314 if( rc==SQLITE_DONE ) break;
2315 sqlite3_finalize(pQuery);
2316 sqlite3_free(zQuery);
2317 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2318 zTable);
2319 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2320 if( rc ){
drh4bbcf102014-02-06 02:46:08 +00002321 fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
2322 break;
drh3350ce92014-02-06 00:49:12 +00002323 }
2324 } /* End for(k=0...) */
2325
2326end_data_xfer:
2327 sqlite3_finalize(pQuery);
2328 sqlite3_finalize(pInsert);
2329 sqlite3_free(zQuery);
2330 sqlite3_free(zInsert);
2331}
2332
2333
2334/*
2335** Try to transfer all rows of the schema that match zWhere. For
2336** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002337** If an error is encountered while moving forward through the
2338** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002339*/
mistachkine31ae902014-02-06 01:15:29 +00002340static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002341 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002342 sqlite3 *newDb,
2343 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002344 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002345){
2346 sqlite3_stmt *pQuery = 0;
2347 char *zQuery = 0;
2348 int rc;
2349 const unsigned char *zName;
2350 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002351 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002352
2353 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2354 " WHERE %s", zWhere);
2355 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2356 if( rc ){
2357 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2358 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2359 zQuery);
2360 goto end_schema_xfer;
2361 }
2362 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2363 zName = sqlite3_column_text(pQuery, 0);
2364 zSql = sqlite3_column_text(pQuery, 1);
2365 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002366 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2367 if( zErrMsg ){
2368 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2369 sqlite3_free(zErrMsg);
2370 zErrMsg = 0;
2371 }
drh3350ce92014-02-06 00:49:12 +00002372 if( xForEach ){
2373 xForEach(p, newDb, (const char*)zName);
2374 }
2375 printf("done\n");
2376 }
2377 if( rc!=SQLITE_DONE ){
2378 sqlite3_finalize(pQuery);
2379 sqlite3_free(zQuery);
2380 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2381 " WHERE %s ORDER BY rowid DESC", zWhere);
2382 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2383 if( rc ){
2384 fprintf(stderr, "Error: (%d) %s on [%s]\n",
2385 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2386 zQuery);
2387 goto end_schema_xfer;
2388 }
2389 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2390 zName = sqlite3_column_text(pQuery, 0);
2391 zSql = sqlite3_column_text(pQuery, 1);
2392 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002393 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2394 if( zErrMsg ){
2395 fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
2396 sqlite3_free(zErrMsg);
2397 zErrMsg = 0;
2398 }
drh3350ce92014-02-06 00:49:12 +00002399 if( xForEach ){
2400 xForEach(p, newDb, (const char*)zName);
2401 }
2402 printf("done\n");
2403 }
2404 }
2405end_schema_xfer:
2406 sqlite3_finalize(pQuery);
2407 sqlite3_free(zQuery);
2408}
2409
2410/*
2411** Open a new database file named "zNewDb". Try to recover as much information
2412** as possible out of the main database (which might be corrupt) and write it
2413** into zNewDb.
2414*/
drhdcd87a92014-08-18 13:45:42 +00002415static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002416 int rc;
2417 sqlite3 *newDb = 0;
2418 if( access(zNewDb,0)==0 ){
2419 fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
2420 return;
2421 }
2422 rc = sqlite3_open(zNewDb, &newDb);
2423 if( rc ){
2424 fprintf(stderr, "Cannot create output database: %s\n",
2425 sqlite3_errmsg(newDb));
2426 }else{
drh54d0d2d2014-04-03 00:32:13 +00002427 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002428 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002429 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2430 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002431 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002432 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002433 }
2434 sqlite3_close(newDb);
2435}
2436
2437/*
drhc2ce0be2014-05-29 12:36:14 +00002438** Change the output file back to stdout
2439*/
drhdcd87a92014-08-18 13:45:42 +00002440static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002441 if( p->outfile[0]=='|' ){
2442 pclose(p->out);
2443 }else{
2444 output_file_close(p->out);
2445 }
2446 p->outfile[0] = 0;
2447 p->out = stdout;
2448}
2449
2450/*
drhf7502f02015-02-06 14:19:44 +00002451** Run an SQL command and return the single integer result.
2452*/
2453static int db_int(ShellState *p, const char *zSql){
2454 sqlite3_stmt *pStmt;
2455 int res = 0;
2456 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2457 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2458 res = sqlite3_column_int(pStmt,0);
2459 }
2460 sqlite3_finalize(pStmt);
2461 return res;
2462}
2463
2464/*
2465** Convert a 2-byte or 4-byte big-endian integer into a native integer
2466*/
2467unsigned int get2byteInt(unsigned char *a){
2468 return (a[0]<<8) + a[1];
2469}
2470unsigned int get4byteInt(unsigned char *a){
2471 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2472}
2473
2474/*
2475** Implementation of the ".info" command.
2476**
2477** Return 1 on error, 2 to exit, and 0 otherwise.
2478*/
drh0e55db12015-02-06 14:51:13 +00002479static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002480 static const struct { const char *zName; int ofst; } aField[] = {
2481 { "file change counter:", 24 },
2482 { "database page count:", 28 },
2483 { "freelist page count:", 36 },
2484 { "schema cookie:", 40 },
2485 { "schema format:", 44 },
2486 { "default cache size:", 48 },
2487 { "autovacuum top root:", 52 },
2488 { "incremental vacuum:", 64 },
2489 { "text encoding:", 56 },
2490 { "user version:", 60 },
2491 { "application id:", 68 },
2492 { "software version:", 96 },
2493 };
drh0e55db12015-02-06 14:51:13 +00002494 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2495 { "number of tables:",
2496 "SELECT count(*) FROM %s WHERE type='table'" },
2497 { "number of indexes:",
2498 "SELECT count(*) FROM %s WHERE type='index'" },
2499 { "number of triggers:",
2500 "SELECT count(*) FROM %s WHERE type='trigger'" },
2501 { "number of views:",
2502 "SELECT count(*) FROM %s WHERE type='view'" },
2503 { "schema size:",
2504 "SELECT total(length(sql)) FROM %s" },
2505 };
2506 sqlite3_file *pFile;
2507 int i;
2508 char *zSchemaTab;
2509 char *zDb = nArg>=2 ? azArg[1] : "main";
2510 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002511 open_db(p, 0);
2512 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002513 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002514 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2515 return 1;
2516 }
2517 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
2518 if( i!=SQLITE_OK ){
2519 fprintf(stderr, "unable to read database header\n");
2520 return 1;
2521 }
2522 i = get2byteInt(aHdr+16);
2523 if( i==1 ) i = 65536;
2524 fprintf(p->out, "%-20s %d\n", "database page size:", i);
2525 fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
2526 fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
2527 fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
2528 for(i=0; i<sizeof(aField)/sizeof(aField[0]); i++){
2529 int ofst = aField[i].ofst;
2530 unsigned int val = get4byteInt(aHdr + ofst);
2531 fprintf(p->out, "%-20s %u", aField[i].zName, val);
2532 switch( ofst ){
2533 case 56: {
2534 if( val==1 ) fprintf(p->out, " (utf8)");
2535 if( val==2 ) fprintf(p->out, " (utf16le)");
2536 if( val==3 ) fprintf(p->out, " (utf16be)");
2537 }
2538 }
2539 fprintf(p->out, "\n");
2540 }
drh0e55db12015-02-06 14:51:13 +00002541 if( zDb==0 ){
2542 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
2543 }else if( strcmp(zDb,"temp")==0 ){
2544 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
2545 }else{
2546 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
2547 }
2548 for(i=0; i<sizeof(aQuery)/sizeof(aQuery[0]); i++){
2549 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
2550 int val = db_int(p, zSql);
2551 sqlite3_free(zSql);
2552 fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
2553 }
2554 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00002555 return 0;
2556}
2557
2558
2559/*
drh75897232000-05-29 14:26:00 +00002560** If an input line begins with "." then invoke this routine to
2561** process that line.
drh67505e72002-04-19 12:34:06 +00002562**
drh47ad6842006-11-08 12:25:42 +00002563** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00002564*/
drhdcd87a92014-08-18 13:45:42 +00002565static int do_meta_command(char *zLine, ShellState *p){
drh75897232000-05-29 14:26:00 +00002566 int i = 1;
2567 int nArg = 0;
2568 int n, c;
drh67505e72002-04-19 12:34:06 +00002569 int rc = 0;
drh75897232000-05-29 14:26:00 +00002570 char *azArg[50];
2571
2572 /* Parse the input line into tokens.
2573 */
2574 while( zLine[i] && nArg<ArraySize(azArg) ){
drhf0693c82011-10-11 20:41:54 +00002575 while( IsSpace(zLine[i]) ){ i++; }
drh06333682004-03-09 13:37:45 +00002576 if( zLine[i]==0 ) break;
drh75897232000-05-29 14:26:00 +00002577 if( zLine[i]=='\'' || zLine[i]=='"' ){
2578 int delim = zLine[i++];
2579 azArg[nArg++] = &zLine[i];
drh4c56b992013-06-27 13:26:55 +00002580 while( zLine[i] && zLine[i]!=delim ){
2581 if( zLine[i]=='\\' && delim=='"' && zLine[i+1]!=0 ) i++;
2582 i++;
2583 }
drh75897232000-05-29 14:26:00 +00002584 if( zLine[i]==delim ){
2585 zLine[i++] = 0;
2586 }
drhfeac5f82004-08-01 00:10:45 +00002587 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002588 }else{
2589 azArg[nArg++] = &zLine[i];
drhf0693c82011-10-11 20:41:54 +00002590 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
drh75897232000-05-29 14:26:00 +00002591 if( zLine[i] ) zLine[i++] = 0;
drhfeac5f82004-08-01 00:10:45 +00002592 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00002593 }
2594 }
2595
2596 /* Process the input line.
2597 */
shane9bd1b442009-10-23 01:27:39 +00002598 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00002599 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00002600 c = azArg[0][0];
drh5c7976f2014-02-10 19:59:27 +00002601 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
2602 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
2603 ){
drhbc46f022013-01-23 18:53:23 +00002604 const char *zDestFile = 0;
2605 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00002606 sqlite3 *pDest;
2607 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00002608 int j;
2609 for(j=1; j<nArg; j++){
2610 const char *z = azArg[j];
2611 if( z[0]=='-' ){
2612 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00002613 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00002614 {
2615 fprintf(stderr, "unknown option: %s\n", azArg[j]);
2616 return 1;
2617 }
2618 }else if( zDestFile==0 ){
2619 zDestFile = azArg[j];
2620 }else if( zDb==0 ){
2621 zDb = zDestFile;
2622 zDestFile = azArg[j];
2623 }else{
2624 fprintf(stderr, "too many arguments to .backup\n");
2625 return 1;
2626 }
drh9ff849f2009-02-04 20:55:57 +00002627 }
drhbc46f022013-01-23 18:53:23 +00002628 if( zDestFile==0 ){
2629 fprintf(stderr, "missing FILENAME argument on .backup\n");
2630 return 1;
2631 }
2632 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00002633 rc = sqlite3_open(zDestFile, &pDest);
2634 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00002635 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00002636 sqlite3_close(pDest);
2637 return 1;
2638 }
drh05782482013-10-24 15:20:20 +00002639 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00002640 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
2641 if( pBackup==0 ){
2642 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
2643 sqlite3_close(pDest);
2644 return 1;
2645 }
2646 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
2647 sqlite3_backup_finish(pBackup);
2648 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00002649 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00002650 }else{
2651 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00002652 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00002653 }
2654 sqlite3_close(pDest);
2655 }else
2656
drhc2ce0be2014-05-29 12:36:14 +00002657 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
2658 if( nArg==2 ){
2659 bail_on_error = booleanValue(azArg[1]);
2660 }else{
2661 fprintf(stderr, "Usage: .bail on|off\n");
2662 rc = 1;
2663 }
drhc49f44e2006-10-26 18:15:42 +00002664 }else
2665
drhd8621b92012-04-17 09:09:33 +00002666 /* The undocumented ".breakpoint" command causes a call to the no-op
2667 ** routine named test_breakpoint().
2668 */
2669 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
2670 test_breakpoint();
2671 }else
2672
drhc2ce0be2014-05-29 12:36:14 +00002673 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
2674 if( nArg==2 ){
2675 tryToClone(p, azArg[1]);
2676 }else{
2677 fprintf(stderr, "Usage: .clone FILENAME\n");
2678 rc = 1;
2679 }
mistachkine31ae902014-02-06 01:15:29 +00002680 }else
2681
drhc2ce0be2014-05-29 12:36:14 +00002682 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002683 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00002684 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00002685 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00002686 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00002687 data.showHeader = 1;
jplyon672a1ed2003-05-11 20:07:05 +00002688 data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00002689 data.colWidth[0] = 3;
2690 data.colWidth[1] = 15;
2691 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00002692 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00002693 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00002694 if( zErrMsg ){
2695 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00002696 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00002697 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00002698 }
2699 }else
2700
drh0e55db12015-02-06 14:51:13 +00002701 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
2702 rc = shell_dbinfo_command(p, nArg, azArg);
2703 }else
2704
drhc2ce0be2014-05-29 12:36:14 +00002705 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00002706 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00002707 /* When playing back a "dump", the content might appear in an order
2708 ** which causes immediate foreign key constraints to be violated.
2709 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00002710 if( nArg!=1 && nArg!=2 ){
2711 fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
2712 rc = 1;
2713 goto meta_command_exit;
2714 }
drhf1dfc4f2009-09-23 15:51:35 +00002715 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
drh33048c02001-10-01 14:29:22 +00002716 fprintf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00002717 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00002718 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002719 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00002720 if( nArg==1 ){
drhdd3d4592004-08-30 01:54:05 +00002721 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002722 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002723 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00002724 );
2725 run_schema_dump_query(p,
2726 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00002727 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00002728 );
drh2f464a02011-10-13 00:41:49 +00002729 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002730 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00002731 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00002732 );
drh4c653a02000-06-07 01:27:47 +00002733 }else{
2734 int i;
drhdd3d4592004-08-30 01:54:05 +00002735 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00002736 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00002737 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00002738 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00002739 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00002740 " AND sql NOT NULL");
2741 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00002742 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00002743 "WHERE sql NOT NULL"
2744 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00002745 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00002746 );
danielk1977bc6ada42004-06-30 08:20:16 +00002747 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00002748 }
2749 }
drh45e29d82006-11-20 16:21:10 +00002750 if( p->writableSchema ){
drh56197952011-10-13 16:30:13 +00002751 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00002752 p->writableSchema = 0;
2753 }
drh56197952011-10-13 16:30:13 +00002754 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
2755 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00002756 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00002757 }else
drh75897232000-05-29 14:26:00 +00002758
drhc2ce0be2014-05-29 12:36:14 +00002759 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
2760 if( nArg==2 ){
2761 p->echoOn = booleanValue(azArg[1]);
2762 }else{
2763 fprintf(stderr, "Usage: .echo on|off\n");
2764 rc = 1;
2765 }
drhdaffd0e2001-04-11 14:28:42 +00002766 }else
2767
drhc2ce0be2014-05-29 12:36:14 +00002768 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
2769 if( nArg==2 ){
2770 p->autoEQP = booleanValue(azArg[1]);
2771 }else{
2772 fprintf(stderr, "Usage: .eqp on|off\n");
2773 rc = 1;
2774 }
drhefbf3b12014-02-28 20:47:24 +00002775 }else
2776
drhd3ac7d92013-01-25 18:33:43 +00002777 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00002778 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00002779 rc = 2;
drh75897232000-05-29 14:26:00 +00002780 }else
2781
drhc2ce0be2014-05-29 12:36:14 +00002782 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drhc28490c2006-10-26 14:25:58 +00002783 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
persicom7e2dfdd2002-04-18 02:46:52 +00002784 if(val == 1) {
drhdcd87a92014-08-18 13:45:42 +00002785 if(!p->normalMode.valid) {
2786 p->normalMode.valid = 1;
2787 p->normalMode.mode = p->mode;
2788 p->normalMode.showHeader = p->showHeader;
2789 memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002790 }
2791 /* We could put this code under the !p->explainValid
2792 ** condition so that it does not execute if we are already in
2793 ** explain mode. However, always executing it allows us an easy
2794 ** was to reset to explain mode in case the user previously
2795 ** did an .explain followed by a .width, .mode or .header
2796 ** command.
2797 */
danielk19770d78bae2008-01-03 07:09:48 +00002798 p->mode = MODE_Explain;
persicom7e2dfdd2002-04-18 02:46:52 +00002799 p->showHeader = 1;
drhac68ced2013-11-27 13:24:18 +00002800 memset(p->colWidth,0,sizeof(p->colWidth));
danielk19770d78bae2008-01-03 07:09:48 +00002801 p->colWidth[0] = 4; /* addr */
drh60a713c2008-01-21 16:22:45 +00002802 p->colWidth[1] = 13; /* opcode */
2803 p->colWidth[2] = 4; /* P1 */
2804 p->colWidth[3] = 4; /* P2 */
2805 p->colWidth[4] = 4; /* P3 */
2806 p->colWidth[5] = 13; /* P4 */
danielk19770d78bae2008-01-03 07:09:48 +00002807 p->colWidth[6] = 2; /* P5 */
drh60a713c2008-01-21 16:22:45 +00002808 p->colWidth[7] = 13; /* Comment */
drhdcd87a92014-08-18 13:45:42 +00002809 }else if (p->normalMode.valid) {
2810 p->normalMode.valid = 0;
2811 p->mode = p->normalMode.mode;
2812 p->showHeader = p->normalMode.showHeader;
2813 memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
persicom7e2dfdd2002-04-18 02:46:52 +00002814 }
drh75897232000-05-29 14:26:00 +00002815 }else
2816
drhc1971542014-06-23 23:28:13 +00002817 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00002818 ShellState data;
drhc1971542014-06-23 23:28:13 +00002819 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00002820 int doStats = 0;
drhc1971542014-06-23 23:28:13 +00002821 if( nArg!=1 ){
2822 fprintf(stderr, "Usage: .fullschema\n");
2823 rc = 1;
2824 goto meta_command_exit;
2825 }
2826 open_db(p, 0);
2827 memcpy(&data, p, sizeof(data));
2828 data.showHeader = 0;
2829 data.mode = MODE_Semi;
2830 rc = sqlite3_exec(p->db,
2831 "SELECT sql FROM"
2832 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2833 " FROM sqlite_master UNION ALL"
2834 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00002835 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00002836 "ORDER BY rowid",
2837 callback, &data, &zErrMsg
2838 );
drh56f674c2014-07-18 14:43:29 +00002839 if( rc==SQLITE_OK ){
2840 sqlite3_stmt *pStmt;
2841 rc = sqlite3_prepare_v2(p->db,
2842 "SELECT rowid FROM sqlite_master"
2843 " WHERE name GLOB 'sqlite_stat[134]'",
2844 -1, &pStmt, 0);
2845 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
2846 sqlite3_finalize(pStmt);
2847 }
2848 if( doStats==0 ){
2849 fprintf(p->out, "/* No STAT tables available */\n");
2850 }else{
2851 fprintf(p->out, "ANALYZE sqlite_master;\n");
2852 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
2853 callback, &data, &zErrMsg);
2854 data.mode = MODE_Insert;
2855 data.zDestTable = "sqlite_stat1";
2856 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2857 shell_callback, &data,&zErrMsg);
2858 data.zDestTable = "sqlite_stat3";
2859 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2860 shell_callback, &data,&zErrMsg);
2861 data.zDestTable = "sqlite_stat4";
2862 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2863 shell_callback, &data, &zErrMsg);
2864 fprintf(p->out, "ANALYZE sqlite_master;\n");
2865 }
drhc1971542014-06-23 23:28:13 +00002866 }else
2867
drhc2ce0be2014-05-29 12:36:14 +00002868 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2869 if( nArg==2 ){
2870 p->showHeader = booleanValue(azArg[1]);
2871 }else{
2872 fprintf(stderr, "Usage: .headers on|off\n");
2873 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00002874 }
drh75897232000-05-29 14:26:00 +00002875 }else
2876
drhc2ce0be2014-05-29 12:36:14 +00002877 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
2878 fprintf(p->out, "%s", zHelp);
2879 }else
2880
2881 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00002882 char *zTable; /* Insert data into this table */
2883 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00002884 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00002885 int nCol; /* Number of columns in the table */
2886 int nByte; /* Number of bytes in an SQL string */
2887 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00002888 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00002889 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00002890 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00002891 ImportCtx sCtx; /* Reader context */
mistachkin486fd432014-07-24 22:20:23 +00002892 char *(*xRead)(ImportCtx*); /* Procedure to read one value */
drh5bde8162013-06-27 14:07:53 +00002893 int (*xCloser)(FILE*); /* Procedure to close th3 connection */
drhfeac5f82004-08-01 00:10:45 +00002894
drhc2ce0be2014-05-29 12:36:14 +00002895 if( nArg!=3 ){
2896 fprintf(stderr, "Usage: .import FILE TABLE\n");
2897 goto meta_command_exit;
2898 }
drh01f37542014-05-31 15:43:33 +00002899 zFile = azArg[1];
2900 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00002901 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00002902 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00002903 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002904 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00002905 if( nSep==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002906 fprintf(stderr, "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00002907 return 1;
drhfeac5f82004-08-01 00:10:45 +00002908 }
drhdb95f682013-06-26 22:46:00 +00002909 if( nSep>1 ){
mistachkin636bf9f2014-07-19 20:15:16 +00002910 fprintf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00002911 " for import\n");
2912 return 1;
2913 }
mistachkin636bf9f2014-07-19 20:15:16 +00002914 nSep = strlen30(p->rowSeparator);
2915 if( nSep==0 ){
2916 fprintf(stderr, "Error: non-null row separator required for import\n");
2917 return 1;
2918 }
mistachkine0d68852014-12-11 03:12:33 +00002919 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
2920 /* When importing CSV (only), if the row separator is set to the
2921 ** default output row separator, change it to the default input
2922 ** row separator. This avoids having to maintain different input
2923 ** and output row separators. */
2924 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
2925 nSep = strlen30(p->rowSeparator);
2926 }
mistachkin636bf9f2014-07-19 20:15:16 +00002927 if( nSep>1 ){
2928 fprintf(stderr, "Error: multi-character row separators not allowed"
2929 " for import\n");
2930 return 1;
2931 }
2932 sCtx.zFile = zFile;
2933 sCtx.nLine = 1;
2934 if( sCtx.zFile[0]=='|' ){
2935 sCtx.in = popen(sCtx.zFile+1, "r");
2936 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00002937 xCloser = pclose;
2938 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002939 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00002940 xCloser = fclose;
2941 }
mistachkin636bf9f2014-07-19 20:15:16 +00002942 if( p->mode==MODE_Ascii ){
2943 xRead = ascii_read_one_field;
2944 }else{
2945 xRead = csv_read_one_field;
2946 }
2947 if( sCtx.in==0 ){
drh5bde8162013-06-27 14:07:53 +00002948 fprintf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00002949 return 1;
2950 }
mistachkin636bf9f2014-07-19 20:15:16 +00002951 sCtx.cColSep = p->colSeparator[0];
2952 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00002953 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00002954 if( zSql==0 ){
2955 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00002956 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002957 return 1;
2958 }
drh4f21c4a2008-12-10 22:15:00 +00002959 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00002960 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00002961 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
drhdb95f682013-06-26 22:46:00 +00002962 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
2963 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
2964 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00002965 while( xRead(&sCtx) ){
2966 zCreate = sqlite3_mprintf("%z%c\n \"%s\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00002967 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00002968 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00002969 }
drh5bde8162013-06-27 14:07:53 +00002970 if( cSep=='(' ){
2971 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00002972 sqlite3_free(sCtx.z);
2973 xCloser(sCtx.in);
2974 fprintf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00002975 return 1;
2976 }
drhdb95f682013-06-26 22:46:00 +00002977 zCreate = sqlite3_mprintf("%z\n)", zCreate);
2978 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
2979 sqlite3_free(zCreate);
2980 if( rc ){
2981 fprintf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
2982 sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00002983 sqlite3_free(sCtx.z);
2984 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00002985 return 1;
2986 }
drhc7181902014-02-27 15:04:13 +00002987 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00002988 }
drhfeac5f82004-08-01 00:10:45 +00002989 sqlite3_free(zSql);
2990 if( rc ){
shane916f9612009-10-23 00:37:15 +00002991 if (pStmt) sqlite3_finalize(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002992 fprintf(stderr,"Error: %s\n", sqlite3_errmsg(db));
mistachkin636bf9f2014-07-19 20:15:16 +00002993 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00002994 return 1;
drhfeac5f82004-08-01 00:10:45 +00002995 }
shane916f9612009-10-23 00:37:15 +00002996 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00002997 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00002998 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00002999 if( nCol==0 ) return 0; /* no columns, no error */
drhdb95f682013-06-26 22:46:00 +00003000 zSql = sqlite3_malloc( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003001 if( zSql==0 ){
3002 fprintf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003003 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003004 return 1;
3005 }
drhdb95f682013-06-26 22:46:00 +00003006 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003007 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003008 for(i=1; i<nCol; i++){
3009 zSql[j++] = ',';
3010 zSql[j++] = '?';
3011 }
3012 zSql[j++] = ')';
3013 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003014 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003015 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003016 if( rc ){
3017 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
shane916f9612009-10-23 00:37:15 +00003018 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003019 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003020 return 1;
drhfeac5f82004-08-01 00:10:45 +00003021 }
drh2d463112013-08-06 14:36:36 +00003022 needCommit = sqlite3_get_autocommit(db);
3023 if( needCommit ) sqlite3_exec(db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003024 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003025 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003026 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003027 char *z = xRead(&sCtx);
3028 /*
3029 ** Did we reach end-of-file before finding any columns?
3030 ** If so, stop instead of NULL filling the remaining columns.
3031 */
drhdb95f682013-06-26 22:46:00 +00003032 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003033 /*
3034 ** Did we reach end-of-file OR end-of-line before finding any
3035 ** columns in ASCII mode? If so, stop instead of NULL filling
3036 ** the remaining columns.
3037 */
3038 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003039 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003040 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003041 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3042 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003043 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003044 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003045 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003046 }
drhfeac5f82004-08-01 00:10:45 +00003047 }
mistachkin636bf9f2014-07-19 20:15:16 +00003048 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003049 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003050 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003051 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003052 }while( sCtx.cTerm==sCtx.cColSep );
drhdb95f682013-06-26 22:46:00 +00003053 fprintf(stderr, "%s:%d: expected %d columns but found %d - "
3054 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003055 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003056 }
drhdb95f682013-06-26 22:46:00 +00003057 if( i>=nCol ){
3058 sqlite3_step(pStmt);
3059 rc = sqlite3_reset(pStmt);
3060 if( rc!=SQLITE_OK ){
mistachkin636bf9f2014-07-19 20:15:16 +00003061 fprintf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile, startLine,
drhdb95f682013-06-26 22:46:00 +00003062 sqlite3_errmsg(db));
3063 }
3064 }
mistachkin636bf9f2014-07-19 20:15:16 +00003065 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003066
mistachkin636bf9f2014-07-19 20:15:16 +00003067 xCloser(sCtx.in);
3068 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003069 sqlite3_finalize(pStmt);
drh2d463112013-08-06 14:36:36 +00003070 if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003071 }else
3072
drh0e55db12015-02-06 14:51:13 +00003073 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3074 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003075 ShellState data;
drh75897232000-05-29 14:26:00 +00003076 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003077 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003078 memcpy(&data, p, sizeof(data));
3079 data.showHeader = 0;
3080 data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003081 if( nArg==1 ){
3082 rc = sqlite3_exec(p->db,
3083 "SELECT name FROM sqlite_master "
3084 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3085 "UNION ALL "
3086 "SELECT name FROM sqlite_temp_master "
3087 "WHERE type='index' "
3088 "ORDER BY 1",
3089 callback, &data, &zErrMsg
3090 );
drhc2ce0be2014-05-29 12:36:14 +00003091 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003092 zShellStatic = azArg[1];
3093 rc = sqlite3_exec(p->db,
3094 "SELECT name FROM sqlite_master "
3095 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3096 "UNION ALL "
3097 "SELECT name FROM sqlite_temp_master "
3098 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3099 "ORDER BY 1",
3100 callback, &data, &zErrMsg
3101 );
3102 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003103 }else{
drh0e55db12015-02-06 14:51:13 +00003104 fprintf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003105 rc = 1;
3106 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003107 }
drh75897232000-05-29 14:26:00 +00003108 if( zErrMsg ){
3109 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003110 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003111 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003112 }else if( rc != SQLITE_OK ){
3113 fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
3114 rc = 1;
drh75897232000-05-29 14:26:00 +00003115 }
3116 }else
3117
drhae5e4452007-05-03 17:18:36 +00003118#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003119 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003120 extern void (*sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003121 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3122 iotrace = 0;
3123 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003124 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003125 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003126 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003127 iotrace = stdout;
3128 }else{
3129 iotrace = fopen(azArg[1], "w");
3130 if( iotrace==0 ){
shane9bd1b442009-10-23 01:27:39 +00003131 fprintf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003132 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003133 rc = 1;
drhb0603412007-02-28 04:47:26 +00003134 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003135 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003136 }
3137 }
3138 }else
drhae5e4452007-05-03 17:18:36 +00003139#endif
drhb0603412007-02-28 04:47:26 +00003140
drh70df4fe2006-06-13 15:12:21 +00003141#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003142 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003143 const char *zFile, *zProc;
3144 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003145 if( nArg<2 ){
3146 fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
3147 rc = 1;
3148 goto meta_command_exit;
3149 }
drh1e397f82006-06-08 15:28:43 +00003150 zFile = azArg[1];
3151 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003152 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003153 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3154 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003155 fprintf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003156 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003157 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003158 }
3159 }else
drh70df4fe2006-06-13 15:12:21 +00003160#endif
drh1e397f82006-06-08 15:28:43 +00003161
drhc2ce0be2014-05-29 12:36:14 +00003162 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3163 if( nArg!=2 ){
3164 fprintf(stderr, "Usage: .log FILENAME\n");
3165 rc = 1;
3166 }else{
3167 const char *zFile = azArg[1];
3168 output_file_close(p->pLog);
3169 p->pLog = output_file_open(zFile);
3170 }
drh127f9d72010-02-23 01:47:00 +00003171 }else
3172
drhc2ce0be2014-05-29 12:36:14 +00003173 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3174 const char *zMode = nArg>=2 ? azArg[1] : "";
3175 int n2 = (int)strlen(zMode);
3176 int c2 = zMode[0];
3177 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003178 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003179 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003180 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003181 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003182 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003183 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003184 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003185 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003186 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003187 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003188 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003189 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003190 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003191 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003192 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003193 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003194 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003195 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003196 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003197 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003198 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3199 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003200 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3201 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003202 }else {
shane9bd1b442009-10-23 01:27:39 +00003203 fprintf(stderr,"Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003204 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003205 rc = 1;
drh75897232000-05-29 14:26:00 +00003206 }
3207 }else
3208
drhc2ce0be2014-05-29 12:36:14 +00003209 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3210 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003211 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3212 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003213 }else{
3214 fprintf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003215 rc = 1;
3216 }
3217 }else
3218
drh05782482013-10-24 15:20:20 +00003219 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3220 sqlite3 *savedDb = p->db;
3221 const char *zSavedFilename = p->zDbFilename;
3222 char *zNewFilename = 0;
3223 p->db = 0;
3224 if( nArg>=2 ){
3225 p->zDbFilename = zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3226 }
3227 open_db(p, 1);
3228 if( p->db!=0 ){
3229 sqlite3_close(savedDb);
3230 sqlite3_free(p->zFreeOnClose);
3231 p->zFreeOnClose = zNewFilename;
3232 }else{
3233 sqlite3_free(zNewFilename);
3234 p->db = savedDb;
3235 p->zDbFilename = zSavedFilename;
3236 }
3237 }else
3238
drhc2ce0be2014-05-29 12:36:14 +00003239 if( c=='o'
3240 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3241 ){
3242 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3243 if( nArg>2 ){
3244 fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
3245 rc = 1;
3246 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003247 }
drhc2ce0be2014-05-29 12:36:14 +00003248 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3249 if( nArg<2 ){
3250 fprintf(stderr, "Usage: .once FILE\n");
3251 rc = 1;
3252 goto meta_command_exit;
3253 }
3254 p->outCount = 2;
3255 }else{
3256 p->outCount = 0;
3257 }
3258 output_reset(p);
3259 if( zFile[0]=='|' ){
3260 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003261 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003262 fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003263 p->out = stdout;
3264 rc = 1;
3265 }else{
drhc2ce0be2014-05-29 12:36:14 +00003266 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003267 }
drh75897232000-05-29 14:26:00 +00003268 }else{
drhc2ce0be2014-05-29 12:36:14 +00003269 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003270 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003271 if( strcmp(zFile,"off")!=0 ){
3272 fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003273 }
drh75897232000-05-29 14:26:00 +00003274 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003275 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003276 } else {
drhc2ce0be2014-05-29 12:36:14 +00003277 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003278 }
3279 }
3280 }else
3281
drh078b1fd2012-09-21 13:40:02 +00003282 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3283 int i;
3284 for(i=1; i<nArg; i++){
3285 if( i>1 ) fprintf(p->out, " ");
3286 fprintf(p->out, "%s", azArg[i]);
3287 }
3288 fprintf(p->out, "\n");
3289 }else
3290
drhc2ce0be2014-05-29 12:36:14 +00003291 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003292 if( nArg >= 2) {
3293 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3294 }
3295 if( nArg >= 3) {
3296 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3297 }
3298 }else
3299
drhc2ce0be2014-05-29 12:36:14 +00003300 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003301 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003302 }else
3303
drhc2ce0be2014-05-29 12:36:14 +00003304 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3305 FILE *alt;
3306 if( nArg!=2 ){
3307 fprintf(stderr, "Usage: .read FILE\n");
3308 rc = 1;
3309 goto meta_command_exit;
3310 }
3311 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003312 if( alt==0 ){
shane9bd1b442009-10-23 01:27:39 +00003313 fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
3314 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003315 }else{
shane9bd1b442009-10-23 01:27:39 +00003316 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003317 fclose(alt);
3318 }
3319 }else
3320
drhc2ce0be2014-05-29 12:36:14 +00003321 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003322 const char *zSrcFile;
3323 const char *zDb;
3324 sqlite3 *pSrc;
3325 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003326 int nTimeout = 0;
3327
drh9ff849f2009-02-04 20:55:57 +00003328 if( nArg==2 ){
3329 zSrcFile = azArg[1];
3330 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003331 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003332 zSrcFile = azArg[2];
3333 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003334 }else{
3335 fprintf(stderr, "Usage: .restore ?DB? FILE\n");
3336 rc = 1;
3337 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003338 }
3339 rc = sqlite3_open(zSrcFile, &pSrc);
3340 if( rc!=SQLITE_OK ){
shane9bd1b442009-10-23 01:27:39 +00003341 fprintf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003342 sqlite3_close(pSrc);
3343 return 1;
3344 }
drh05782482013-10-24 15:20:20 +00003345 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003346 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3347 if( pBackup==0 ){
3348 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
3349 sqlite3_close(pSrc);
3350 return 1;
3351 }
drhdc2c4912009-02-04 22:46:47 +00003352 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3353 || rc==SQLITE_BUSY ){
3354 if( rc==SQLITE_BUSY ){
3355 if( nTimeout++ >= 3 ) break;
3356 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003357 }
3358 }
3359 sqlite3_backup_finish(pBackup);
3360 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003361 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003362 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
shane9bd1b442009-10-23 01:27:39 +00003363 fprintf(stderr, "Error: source database is busy\n");
3364 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003365 }else{
3366 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003367 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003368 }
3369 sqlite3_close(pSrc);
3370 }else
3371
dan8d1edb92014-11-05 09:07:28 +00003372
3373 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3374 if( nArg==2 ){
3375 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003376#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
3377 fprintf(stderr, "Warning: .scanstats not available in this build.\n");
3378#endif
dan8d1edb92014-11-05 09:07:28 +00003379 }else{
3380 fprintf(stderr, "Usage: .scanstats on|off\n");
3381 rc = 1;
3382 }
3383 }else
3384
drhc2ce0be2014-05-29 12:36:14 +00003385 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003386 ShellState data;
drh75897232000-05-29 14:26:00 +00003387 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003388 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003389 memcpy(&data, p, sizeof(data));
3390 data.showHeader = 0;
drhe3710332000-09-29 13:30:53 +00003391 data.mode = MODE_Semi;
drhc2ce0be2014-05-29 12:36:14 +00003392 if( nArg==2 ){
drhc8d74412004-08-31 23:41:26 +00003393 int i;
drhf0693c82011-10-11 20:41:54 +00003394 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00003395 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00003396 char *new_argv[2], *new_colv[2];
3397 new_argv[0] = "CREATE TABLE sqlite_master (\n"
3398 " type text,\n"
3399 " name text,\n"
3400 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00003401 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00003402 " sql text\n"
3403 ")";
3404 new_argv[1] = 0;
3405 new_colv[0] = "sql";
3406 new_colv[1] = 0;
3407 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003408 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00003409 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00003410 char *new_argv[2], *new_colv[2];
3411 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
3412 " type text,\n"
3413 " name text,\n"
3414 " tbl_name text,\n"
3415 " rootpage integer,\n"
3416 " sql text\n"
3417 ")";
3418 new_argv[1] = 0;
3419 new_colv[0] = "sql";
3420 new_colv[1] = 0;
3421 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00003422 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00003423 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00003424 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00003425 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003426 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003427 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003428 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003429 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00003430 "WHERE lower(tbl_name) LIKE shellstatic()"
3431 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00003432 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00003433 callback, &data, &zErrMsg);
3434 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00003435 }
drhc2ce0be2014-05-29 12:36:14 +00003436 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00003437 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00003438 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00003439 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00003440 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00003441 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003442 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00003443 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00003444 callback, &data, &zErrMsg
3445 );
drhc2ce0be2014-05-29 12:36:14 +00003446 }else{
3447 fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
3448 rc = 1;
3449 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003450 }
drh75897232000-05-29 14:26:00 +00003451 if( zErrMsg ){
3452 fprintf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003453 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003454 rc = 1;
3455 }else if( rc != SQLITE_OK ){
3456 fprintf(stderr,"Error: querying schema information\n");
3457 rc = 1;
3458 }else{
3459 rc = 0;
drh75897232000-05-29 14:26:00 +00003460 }
3461 }else
3462
drhabd4c722014-09-20 18:18:33 +00003463
3464#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
3465 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
3466 extern int sqlite3SelectTrace;
drh1d9be4f2015-01-22 11:29:25 +00003467 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00003468 }else
3469#endif
3470
3471
drh340f5822013-06-27 13:01:21 +00003472#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00003473 /* Undocumented commands for internal testing. Subject to change
3474 ** without notice. */
3475 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
3476 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
3477 int i, v;
3478 for(i=1; i<nArg; i++){
3479 v = booleanValue(azArg[i]);
3480 fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
3481 }
3482 }
3483 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
3484 int i; sqlite3_int64 v;
3485 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00003486 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00003487 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00003488 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drh340f5822013-06-27 13:01:21 +00003489 fprintf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00003490 }
3491 }
3492 }else
drh340f5822013-06-27 13:01:21 +00003493#endif
drh348d19c2013-06-03 12:47:43 +00003494
drhc2ce0be2014-05-29 12:36:14 +00003495 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00003496 if( nArg<2 || nArg>3 ){
mistachkine0d68852014-12-11 03:12:33 +00003497 fprintf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00003498 rc = 1;
3499 }
drh6976c212014-07-24 12:09:47 +00003500 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00003501 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00003502 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00003503 }
3504 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00003505 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
3506 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh5bb3eb92007-05-04 13:15:55 +00003507 }
drh75897232000-05-29 14:26:00 +00003508 }else
3509
drh62cdde52014-05-28 20:22:28 +00003510 if( c=='s'
3511 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00003512 ){
3513 char *zCmd;
drh54027102014-08-06 14:36:53 +00003514 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00003515 if( nArg<2 ){
3516 fprintf(stderr, "Usage: .system COMMAND\n");
3517 rc = 1;
3518 goto meta_command_exit;
3519 }
drhdcb3e3d2014-05-29 03:17:29 +00003520 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00003521 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00003522 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
3523 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00003524 }
drh54027102014-08-06 14:36:53 +00003525 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00003526 sqlite3_free(zCmd);
drh54027102014-08-06 14:36:53 +00003527 if( x ) fprintf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00003528 }else
3529
drhc2ce0be2014-05-29 12:36:14 +00003530 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003531 int i;
drhc2ce0be2014-05-29 12:36:14 +00003532 if( nArg!=1 ){
3533 fprintf(stderr, "Usage: .show\n");
3534 rc = 1;
3535 goto meta_command_exit;
3536 }
mistachkin636bf9f2014-07-19 20:15:16 +00003537 fprintf(p->out,"%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
3538 fprintf(p->out,"%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
drhdcd87a92014-08-18 13:45:42 +00003539 fprintf(p->out,"%9.9s: %s\n","explain", p->normalMode.valid ? "on" :"off");
mistachkin636bf9f2014-07-19 20:15:16 +00003540 fprintf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
3541 fprintf(p->out,"%12.12s: %s\n","mode", modeDescr[p->mode]);
3542 fprintf(p->out,"%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00003543 output_c_string(p->out, p->nullValue);
drhfeac5f82004-08-01 00:10:45 +00003544 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003545 fprintf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00003546 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkin636bf9f2014-07-19 20:15:16 +00003547 fprintf(p->out,"%12.12s: ", "colseparator");
3548 output_c_string(p->out, p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003549 fprintf(p->out, "\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003550 fprintf(p->out,"%12.12s: ", "rowseparator");
3551 output_c_string(p->out, p->rowSeparator);
3552 fprintf(p->out, "\n");
3553 fprintf(p->out,"%12.12s: %s\n","stats", p->statsOn ? "on" : "off");
3554 fprintf(p->out,"%12.12s: ","width");
persicom7e2dfdd2002-04-18 02:46:52 +00003555 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
drhfeac5f82004-08-01 00:10:45 +00003556 fprintf(p->out,"%d ",p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00003557 }
drhfeac5f82004-08-01 00:10:45 +00003558 fprintf(p->out,"\n");
persicom7e2dfdd2002-04-18 02:46:52 +00003559 }else
3560
drhc2ce0be2014-05-29 12:36:14 +00003561 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
3562 if( nArg==2 ){
3563 p->statsOn = booleanValue(azArg[1]);
3564 }else{
3565 fprintf(stderr, "Usage: .stats on|off\n");
3566 rc = 1;
3567 }
shaneh642d8b82010-07-28 16:05:34 +00003568 }else
3569
drhc2ce0be2014-05-29 12:36:14 +00003570 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00003571 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00003572 char **azResult;
drh98781232012-04-23 12:38:05 +00003573 int nRow, nAlloc;
3574 char *zSql = 0;
3575 int ii;
drh05782482013-10-24 15:20:20 +00003576 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00003577 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
3578 if( rc ) return rc;
3579 zSql = sqlite3_mprintf(
3580 "SELECT name FROM sqlite_master"
3581 " WHERE type IN ('table','view')"
3582 " AND name NOT LIKE 'sqlite_%%'"
3583 " AND name LIKE ?1");
3584 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3585 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
3586 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
3587 if( strcmp(zDbName,"temp")==0 ){
3588 zSql = sqlite3_mprintf(
3589 "%z UNION ALL "
3590 "SELECT 'temp.' || name FROM sqlite_temp_master"
3591 " WHERE type IN ('table','view')"
3592 " AND name NOT LIKE 'sqlite_%%'"
3593 " AND name LIKE ?1", zSql);
3594 }else{
3595 zSql = sqlite3_mprintf(
3596 "%z UNION ALL "
3597 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
3598 " WHERE type IN ('table','view')"
3599 " AND name NOT LIKE 'sqlite_%%'"
3600 " AND name LIKE ?1", zSql, zDbName, zDbName);
3601 }
drha50da102000-08-08 20:19:09 +00003602 }
drh98781232012-04-23 12:38:05 +00003603 sqlite3_finalize(pStmt);
3604 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
3605 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3606 sqlite3_free(zSql);
3607 if( rc ) return rc;
3608 nRow = nAlloc = 0;
3609 azResult = 0;
3610 if( nArg>1 ){
3611 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00003612 }else{
drh98781232012-04-23 12:38:05 +00003613 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
3614 }
3615 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3616 if( nRow>=nAlloc ){
3617 char **azNew;
3618 int n = nAlloc*2 + 10;
3619 azNew = sqlite3_realloc(azResult, sizeof(azResult[0])*n);
3620 if( azNew==0 ){
3621 fprintf(stderr, "Error: out of memory\n");
3622 break;
3623 }
3624 nAlloc = n;
3625 azResult = azNew;
3626 }
3627 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
3628 if( azResult[nRow] ) nRow++;
3629 }
3630 sqlite3_finalize(pStmt);
3631 if( nRow>0 ){
drhe3710332000-09-29 13:30:53 +00003632 int len, maxlen = 0;
3633 int i, j;
3634 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00003635 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00003636 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00003637 if( len>maxlen ) maxlen = len;
3638 }
3639 nPrintCol = 80/(maxlen+2);
3640 if( nPrintCol<1 ) nPrintCol = 1;
3641 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
3642 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00003643 for(j=i; j<nRow; j+=nPrintRow){
3644 char *zSp = j<nPrintRow ? "" : " ";
drh4ace5362014-11-10 14:42:28 +00003645 fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00003646 }
drh151b7d52013-05-06 20:28:54 +00003647 fprintf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00003648 }
3649 }
drh98781232012-04-23 12:38:05 +00003650 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
3651 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00003652 }else
3653
shaneh96887e12011-02-10 21:08:58 +00003654 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00003655 static const struct {
3656 const char *zCtrlName; /* Name of a test-control option */
3657 int ctrlCode; /* Integer code for that option */
3658 } aCtrl[] = {
3659 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
3660 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
3661 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
3662 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
3663 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
3664 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
3665 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
3666 { "assert", SQLITE_TESTCTRL_ASSERT },
3667 { "always", SQLITE_TESTCTRL_ALWAYS },
3668 { "reserve", SQLITE_TESTCTRL_RESERVE },
3669 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
3670 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00003671 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00003672 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00003673 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00003674 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00003675 };
shaneh96887e12011-02-10 21:08:58 +00003676 int testctrl = -1;
3677 int rc = 0;
drhd416fe72011-03-17 16:45:50 +00003678 int i, n;
drh05782482013-10-24 15:20:20 +00003679 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00003680
drhd416fe72011-03-17 16:45:50 +00003681 /* convert testctrl text option to value. allow any unique prefix
3682 ** of the option name, or a numerical value. */
shanehcef83682011-04-07 03:41:01 +00003683 n = strlen30(azArg[1]);
drhfcd71b62011-04-05 22:08:24 +00003684 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
drhd416fe72011-03-17 16:45:50 +00003685 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
3686 if( testctrl<0 ){
3687 testctrl = aCtrl[i].ctrlCode;
3688 }else{
drhb07028f2011-10-14 21:49:18 +00003689 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00003690 testctrl = -1;
3691 break;
3692 }
3693 }
3694 }
drh348d19c2013-06-03 12:47:43 +00003695 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003696 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
3697 fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
3698 }else{
3699 switch(testctrl){
3700
3701 /* sqlite3_test_control(int, db, int) */
3702 case SQLITE_TESTCTRL_OPTIMIZATIONS:
3703 case SQLITE_TESTCTRL_RESERVE:
3704 if( nArg==3 ){
3705 int opt = (int)strtol(azArg[2], 0, 0);
3706 rc = sqlite3_test_control(testctrl, p->db, opt);
drh151b7d52013-05-06 20:28:54 +00003707 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003708 } else {
drhd416fe72011-03-17 16:45:50 +00003709 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3710 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003711 }
3712 break;
3713
3714 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00003715 case SQLITE_TESTCTRL_PRNG_SAVE:
3716 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00003717 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00003718 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00003719 if( nArg==2 ){
3720 rc = sqlite3_test_control(testctrl);
drh151b7d52013-05-06 20:28:54 +00003721 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003722 } else {
3723 fprintf(stderr,"Error: testctrl %s takes no options\n", azArg[1]);
3724 }
3725 break;
3726
3727 /* sqlite3_test_control(int, uint) */
3728 case SQLITE_TESTCTRL_PENDING_BYTE:
3729 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00003730 unsigned int opt = (unsigned int)integerValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003731 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003732 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003733 } else {
drhd416fe72011-03-17 16:45:50 +00003734 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
3735 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003736 }
3737 break;
3738
3739 /* sqlite3_test_control(int, int) */
3740 case SQLITE_TESTCTRL_ASSERT:
drhe4bb23a2015-01-19 15:05:54 +00003741 case SQLITE_TESTCTRL_ALWAYS:
3742 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00003743 if( nArg==3 ){
drh348d19c2013-06-03 12:47:43 +00003744 int opt = booleanValue(azArg[2]);
shaneh96887e12011-02-10 21:08:58 +00003745 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003746 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003747 } else {
drhd416fe72011-03-17 16:45:50 +00003748 fprintf(stderr,"Error: testctrl %s takes a single int option\n",
3749 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003750 }
3751 break;
3752
3753 /* sqlite3_test_control(int, char *) */
3754#ifdef SQLITE_N_KEYWORD
3755 case SQLITE_TESTCTRL_ISKEYWORD:
3756 if( nArg==3 ){
3757 const char *opt = azArg[2];
3758 rc = sqlite3_test_control(testctrl, opt);
drh151b7d52013-05-06 20:28:54 +00003759 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
shaneh96887e12011-02-10 21:08:58 +00003760 } else {
drhd416fe72011-03-17 16:45:50 +00003761 fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
3762 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003763 }
3764 break;
3765#endif
3766
drh1ffede82015-01-30 20:59:27 +00003767 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00003768 if( nArg==5 ){
3769 rc = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00003770 azArg[2],
drh8964b342015-01-29 17:54:52 +00003771 integerValue(azArg[3]),
3772 integerValue(azArg[4]));
3773 }else{
drh1ffede82015-01-30 20:59:27 +00003774 fprintf(stderr,"Usage: .testctrl initmode dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00003775 rc = 1;
3776 }
3777 break;
3778
shaneh96887e12011-02-10 21:08:58 +00003779 case SQLITE_TESTCTRL_BITVEC_TEST:
3780 case SQLITE_TESTCTRL_FAULT_INSTALL:
3781 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
3782 case SQLITE_TESTCTRL_SCRATCHMALLOC:
3783 default:
drhd416fe72011-03-17 16:45:50 +00003784 fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
3785 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00003786 break;
3787 }
3788 }
3789 }else
3790
drhc2ce0be2014-05-29 12:36:14 +00003791 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00003792 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00003793 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00003794 }else
3795
drhc2ce0be2014-05-29 12:36:14 +00003796 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
3797 if( nArg==2 ){
3798 enableTimer = booleanValue(azArg[1]);
3799 if( enableTimer && !HAS_TIMER ){
3800 fprintf(stderr, "Error: timer not available on this system.\n");
3801 enableTimer = 0;
3802 }
3803 }else{
3804 fprintf(stderr, "Usage: .timer on|off\n");
3805 rc = 1;
3806 }
shanehe2aa9d72009-11-06 17:20:17 +00003807 }else
3808
drhc2ce0be2014-05-29 12:36:14 +00003809 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00003810 open_db(p, 0);
drh42f64e52012-04-04 16:56:23 +00003811 output_file_close(p->traceOut);
drhc2ce0be2014-05-29 12:36:14 +00003812 if( nArg!=2 ){
3813 fprintf(stderr, "Usage: .trace FILE|off\n");
3814 rc = 1;
3815 goto meta_command_exit;
3816 }
drh42f64e52012-04-04 16:56:23 +00003817 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00003818#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00003819 if( p->traceOut==0 ){
3820 sqlite3_trace(p->db, 0, 0);
3821 }else{
3822 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
3823 }
3824#endif
3825 }else
3826
drhf442e332014-09-10 19:01:14 +00003827#if SQLITE_USER_AUTHENTICATION
3828 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
3829 if( nArg<2 ){
3830 fprintf(stderr, "Usage: .user SUBCOMMAND ...\n");
3831 rc = 1;
3832 goto meta_command_exit;
3833 }
drh7883ecf2014-09-11 16:19:31 +00003834 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00003835 if( strcmp(azArg[1],"login")==0 ){
3836 if( nArg!=4 ){
3837 fprintf(stderr, "Usage: .user login USER PASSWORD\n");
3838 rc = 1;
3839 goto meta_command_exit;
3840 }
drhd39c40f2014-09-11 00:27:53 +00003841 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
3842 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00003843 if( rc ){
3844 fprintf(stderr, "Authentication failed for user %s\n", azArg[2]);
3845 rc = 1;
3846 }
3847 }else if( strcmp(azArg[1],"add")==0 ){
3848 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003849 fprintf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003850 rc = 1;
3851 goto meta_command_exit;
3852 }
drhd39c40f2014-09-11 00:27:53 +00003853 rc = sqlite3_user_add(p->db, azArg[2],
3854 azArg[3], (int)strlen(azArg[3]),
3855 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003856 if( rc ){
3857 fprintf(stderr, "User-Add failed: %d\n", rc);
3858 rc = 1;
3859 }
3860 }else if( strcmp(azArg[1],"edit")==0 ){
3861 if( nArg!=5 ){
drhd39c40f2014-09-11 00:27:53 +00003862 fprintf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00003863 rc = 1;
3864 goto meta_command_exit;
3865 }
drhd39c40f2014-09-11 00:27:53 +00003866 rc = sqlite3_user_change(p->db, azArg[2],
3867 azArg[3], (int)strlen(azArg[3]),
3868 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00003869 if( rc ){
3870 fprintf(stderr, "User-Edit failed: %d\n", rc);
3871 rc = 1;
3872 }
3873 }else if( strcmp(azArg[1],"delete")==0 ){
3874 if( nArg!=3 ){
3875 fprintf(stderr, "Usage: .user delete USER\n");
3876 rc = 1;
3877 goto meta_command_exit;
3878 }
3879 rc = sqlite3_user_delete(p->db, azArg[2]);
3880 if( rc ){
3881 fprintf(stderr, "User-Delete failed: %d\n", rc);
3882 rc = 1;
3883 }
3884 }else{
3885 fprintf(stderr, "Usage: .user login|add|edit|delete ...\n");
3886 rc = 1;
3887 goto meta_command_exit;
3888 }
3889 }else
3890#endif /* SQLITE_USER_AUTHENTICATION */
3891
drh9fd301b2011-06-03 13:28:22 +00003892 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
drh151b7d52013-05-06 20:28:54 +00003893 fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00003894 sqlite3_libversion(), sqlite3_sourceid());
3895 }else
3896
drhde60fc22011-12-14 17:53:36 +00003897 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
3898 const char *zDbName = nArg==2 ? azArg[1] : "main";
3899 char *zVfsName = 0;
3900 if( p->db ){
3901 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
3902 if( zVfsName ){
drh151b7d52013-05-06 20:28:54 +00003903 fprintf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00003904 sqlite3_free(zVfsName);
3905 }
3906 }
3907 }else
3908
drhcef4fc82012-09-21 22:50:45 +00003909#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
3910 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
3911 extern int sqlite3WhereTrace;
drhc2ce0be2014-05-29 12:36:14 +00003912 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00003913 }else
3914#endif
3915
drhc2ce0be2014-05-29 12:36:14 +00003916 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00003917 int j;
drh43617e92006-03-06 20:55:46 +00003918 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00003919 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00003920 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00003921 }
3922 }else
3923
3924 {
shane9bd1b442009-10-23 01:27:39 +00003925 fprintf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00003926 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00003927 rc = 1;
drh75897232000-05-29 14:26:00 +00003928 }
drh67505e72002-04-19 12:34:06 +00003929
drhc2ce0be2014-05-29 12:36:14 +00003930meta_command_exit:
3931 if( p->outCount ){
3932 p->outCount--;
3933 if( p->outCount==0 ) output_reset(p);
3934 }
drh67505e72002-04-19 12:34:06 +00003935 return rc;
drh75897232000-05-29 14:26:00 +00003936}
3937
drh67505e72002-04-19 12:34:06 +00003938/*
drh91a66392007-09-07 01:12:32 +00003939** Return TRUE if a semicolon occurs anywhere in the first N characters
3940** of string z[].
drh324ccef2003-02-05 14:06:20 +00003941*/
drh9f099fd2013-08-06 14:01:46 +00003942static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00003943 int i;
3944 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
3945 return 0;
drh324ccef2003-02-05 14:06:20 +00003946}
3947
3948/*
drh70c7a4b2003-04-26 03:03:06 +00003949** Test to see if a line consists entirely of whitespace.
3950*/
3951static int _all_whitespace(const char *z){
3952 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00003953 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00003954 if( *z=='/' && z[1]=='*' ){
3955 z += 2;
3956 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
3957 if( *z==0 ) return 0;
3958 z++;
3959 continue;
3960 }
3961 if( *z=='-' && z[1]=='-' ){
3962 z += 2;
3963 while( *z && *z!='\n' ){ z++; }
3964 if( *z==0 ) return 1;
3965 continue;
3966 }
3967 return 0;
3968 }
3969 return 1;
3970}
3971
3972/*
drha9b17162003-04-29 18:01:28 +00003973** Return TRUE if the line typed in is an SQL command terminator other
3974** than a semi-colon. The SQL Server style "go" command is understood
3975** as is the Oracle "/".
3976*/
drh9f099fd2013-08-06 14:01:46 +00003977static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00003978 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00003979 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
3980 return 1; /* Oracle */
3981 }
drhf0693c82011-10-11 20:41:54 +00003982 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00003983 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00003984 return 1; /* SQL Server */
3985 }
3986 return 0;
3987}
3988
3989/*
drh233a5312008-12-18 22:25:13 +00003990** Return true if zSql is a complete SQL statement. Return false if it
3991** ends in the middle of a string literal or C-style comment.
3992*/
drh9f099fd2013-08-06 14:01:46 +00003993static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00003994 int rc;
3995 if( zSql==0 ) return 1;
3996 zSql[nSql] = ';';
3997 zSql[nSql+1] = 0;
3998 rc = sqlite3_complete(zSql);
3999 zSql[nSql] = 0;
4000 return rc;
4001}
4002
4003/*
drh67505e72002-04-19 12:34:06 +00004004** Read input from *in and process it. If *in==0 then input
4005** is interactive - the user is typing it it. Otherwise, input
4006** is coming from a file or device. A prompt is issued and history
4007** is saved only if input is interactive. An interrupt signal will
4008** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004009**
4010** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004011*/
drhdcd87a92014-08-18 13:45:42 +00004012static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004013 char *zLine = 0; /* A single input line */
4014 char *zSql = 0; /* Accumulated SQL text */
4015 int nLine; /* Length of current line */
4016 int nSql = 0; /* Bytes of zSql[] used */
4017 int nAlloc = 0; /* Allocated zSql[] space */
4018 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4019 char *zErrMsg; /* Error message returned */
4020 int rc; /* Error code */
4021 int errCnt = 0; /* Number of errors seen */
4022 int lineno = 0; /* Current line number */
4023 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004024
4025 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4026 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004027 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004028 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004029 /* End of input */
4030 if( stdin_is_interactive ) printf("\n");
4031 break;
drhc49f44e2006-10-26 18:15:42 +00004032 }
drh67505e72002-04-19 12:34:06 +00004033 if( seenInterrupt ){
4034 if( in!=0 ) break;
4035 seenInterrupt = 0;
4036 }
drhc28490c2006-10-26 14:25:58 +00004037 lineno++;
drh849a9d92013-12-21 15:46:06 +00004038 if( nSql==0 && _all_whitespace(zLine) ){
4039 if( p->echoOn ) printf("%s\n", zLine);
4040 continue;
4041 }
drh2af0b2d2002-02-21 02:25:02 +00004042 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004043 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004044 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004045 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004046 break;
4047 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004048 errCnt++;
4049 }
drhdaffd0e2001-04-11 14:28:42 +00004050 continue;
4051 }
drh9f099fd2013-08-06 14:01:46 +00004052 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004053 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004054 }
drh9f099fd2013-08-06 14:01:46 +00004055 nLine = strlen30(zLine);
4056 if( nSql+nLine+2>=nAlloc ){
4057 nAlloc = nSql+nLine+100;
4058 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004059 if( zSql==0 ){
drh9f099fd2013-08-06 14:01:46 +00004060 fprintf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004061 exit(1);
4062 }
drhdaffd0e2001-04-11 14:28:42 +00004063 }
drh9f099fd2013-08-06 14:01:46 +00004064 nSqlPrior = nSql;
4065 if( nSql==0 ){
4066 int i;
4067 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004068 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004069 memcpy(zSql, zLine+i, nLine+1-i);
4070 startline = lineno;
4071 nSql = nLine-i;
4072 }else{
4073 zSql[nSql++] = '\n';
4074 memcpy(zSql+nSql, zLine, nLine+1);
4075 nSql += nLine;
4076 }
4077 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004078 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004079 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004080 open_db(p, 0);
drh3b1a9882007-11-02 12:53:03 +00004081 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004082 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004083 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004084 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004085 char zPrefix[100];
4086 if( in!=0 || !stdin_is_interactive ){
drh5bb3eb92007-05-04 13:15:55 +00004087 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004088 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004089 }else{
shane9bd1b442009-10-23 01:27:39 +00004090 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004091 }
drh7f953e22002-07-13 17:33:45 +00004092 if( zErrMsg!=0 ){
shaned2bed1c2009-10-21 03:56:54 +00004093 fprintf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004094 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004095 zErrMsg = 0;
4096 }else{
shaned2bed1c2009-10-21 03:56:54 +00004097 fprintf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004098 }
drhc49f44e2006-10-26 18:15:42 +00004099 errCnt++;
drhdaffd0e2001-04-11 14:28:42 +00004100 }
drhdaffd0e2001-04-11 14:28:42 +00004101 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004102 if( p->outCount ){
4103 output_reset(p);
4104 p->outCount = 0;
4105 }
drh9f099fd2013-08-06 14:01:46 +00004106 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004107 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004108 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004109 }
4110 }
drh9f099fd2013-08-06 14:01:46 +00004111 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004112 if( !_all_whitespace(zSql) ){
4113 fprintf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004114 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004115 }
drhdaffd0e2001-04-11 14:28:42 +00004116 free(zSql);
4117 }
danielk19772ac27622007-07-03 05:31:16 +00004118 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004119 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004120}
4121
drh67505e72002-04-19 12:34:06 +00004122/*
4123** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004124** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004125*/
4126static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00004127 static char *home_dir = NULL;
4128 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00004129
drh4ace5362014-11-10 14:42:28 +00004130#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
4131 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00004132 {
4133 struct passwd *pwent;
4134 uid_t uid = getuid();
4135 if( (pwent=getpwuid(uid)) != NULL) {
4136 home_dir = pwent->pw_dir;
4137 }
drh67505e72002-04-19 12:34:06 +00004138 }
4139#endif
4140
chw65d3c132007-11-12 21:09:10 +00004141#if defined(_WIN32_WCE)
4142 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
4143 */
drh85e72432012-04-11 11:38:53 +00004144 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00004145#else
4146
drh83905c92012-06-21 13:00:37 +00004147#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00004148 if (!home_dir) {
4149 home_dir = getenv("USERPROFILE");
4150 }
4151#endif
4152
drh67505e72002-04-19 12:34:06 +00004153 if (!home_dir) {
4154 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00004155 }
4156
drh83905c92012-06-21 13:00:37 +00004157#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00004158 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00004159 char *zDrive, *zPath;
4160 int n;
4161 zDrive = getenv("HOMEDRIVE");
4162 zPath = getenv("HOMEPATH");
4163 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00004164 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00004165 home_dir = malloc( n );
4166 if( home_dir==0 ) return 0;
4167 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
4168 return home_dir;
4169 }
4170 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00004171 }
4172#endif
4173
chw65d3c132007-11-12 21:09:10 +00004174#endif /* !_WIN32_WCE */
4175
drh67505e72002-04-19 12:34:06 +00004176 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00004177 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00004178 char *z = malloc( n );
4179 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00004180 home_dir = z;
4181 }
drhe98d4fa2002-04-21 19:06:22 +00004182
drh67505e72002-04-19 12:34:06 +00004183 return home_dir;
4184}
4185
4186/*
4187** Read input from the file given by sqliterc_override. Or if that
4188** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00004189**
4190** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00004191*/
drh534f4df2015-02-28 14:03:35 +00004192static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00004193 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00004194 const char *sqliterc_override /* Name of config file. NULL to use default */
4195){
persicom7e2dfdd2002-04-18 02:46:52 +00004196 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00004197 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00004198 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00004199 FILE *in = NULL;
4200
4201 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00004202 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00004203 if( home_dir==0 ){
drh534f4df2015-02-28 14:03:35 +00004204 fprintf(stderr, "-- warning: cannot find home directory;"
4205 " cannot read ~/.sqliterc\n");
4206 return;
drhe98d4fa2002-04-21 19:06:22 +00004207 }
drh2f3de322012-06-27 16:41:31 +00004208 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00004209 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
4210 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00004211 }
drha1f9b5e2004-02-14 16:31:02 +00004212 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00004213 if( in ){
drhc28490c2006-10-26 14:25:58 +00004214 if( stdin_is_interactive ){
shane86f5bdb2009-10-24 02:00:07 +00004215 fprintf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00004216 }
drh534f4df2015-02-28 14:03:35 +00004217 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00004218 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00004219 }
drh85e72432012-04-11 11:38:53 +00004220 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00004221}
4222
drh67505e72002-04-19 12:34:06 +00004223/*
drhe1e38c42003-05-04 18:30:59 +00004224** Show available command line options
4225*/
4226static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00004227 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00004228 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00004229 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004230 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00004231 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00004232 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00004233 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00004234 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00004235 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00004236#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
4237 " -heap SIZE Size of heap for memsys3 or memsys5\n"
4238#endif
drhcc3b4f82012-02-07 14:13:50 +00004239 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00004240 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00004241 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00004242 " -line set output mode to 'line'\n"
4243 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00004244 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00004245 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00004246#ifdef SQLITE_ENABLE_MULTIPLEX
4247 " -multiplex enable the multiplexor VFS\n"
4248#endif
mistachkine0d68852014-12-11 03:12:33 +00004249 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00004250 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00004251 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
4252 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00004253 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00004254 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00004255 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00004256 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00004257#ifdef SQLITE_ENABLE_VFSTRACE
4258 " -vfstrace enable tracing of all VFS calls\n"
4259#endif
drhe1e38c42003-05-04 18:30:59 +00004260;
4261static void usage(int showDetail){
drh80e8be92006-08-29 12:04:19 +00004262 fprintf(stderr,
4263 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
4264 "FILENAME is the name of an SQLite database. A new database is created\n"
4265 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00004266 if( showDetail ){
drh80e8be92006-08-29 12:04:19 +00004267 fprintf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00004268 }else{
4269 fprintf(stderr, "Use the -help option for additional information\n");
4270 }
4271 exit(1);
4272}
4273
4274/*
drh67505e72002-04-19 12:34:06 +00004275** Initialize the state information in data
4276*/
drhdcd87a92014-08-18 13:45:42 +00004277static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00004278 memset(data, 0, sizeof(*data));
4279 data->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004280 memcpy(data->colSeparator,SEP_Column, 2);
4281 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00004282 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00004283 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00004284 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00004285 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00004286 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00004287 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
4288 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00004289}
4290
drh98d312f2012-10-25 15:23:14 +00004291/*
drh5c7976f2014-02-10 19:59:27 +00004292** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00004293*/
4294#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00004295static void printBold(const char *zText){
4296 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
4297 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
4298 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
4299 SetConsoleTextAttribute(out,
4300 FOREGROUND_RED|FOREGROUND_INTENSITY
4301 );
4302 printf("%s", zText);
4303 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00004304}
4305#else
drh5c7976f2014-02-10 19:59:27 +00004306static void printBold(const char *zText){
4307 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00004308}
4309#endif
4310
4311/*
drh98d312f2012-10-25 15:23:14 +00004312** Get the argument to an --option. Throw an error and die if no argument
4313** is available.
4314*/
4315static char *cmdline_option_value(int argc, char **argv, int i){
4316 if( i==argc ){
4317 fprintf(stderr, "%s: Error: missing argument to %s\n",
4318 argv[0], argv[argc-1]);
4319 exit(1);
4320 }
4321 return argv[i];
4322}
4323
drh75897232000-05-29 14:26:00 +00004324int main(int argc, char **argv){
drh75897232000-05-29 14:26:00 +00004325 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00004326 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00004327 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00004328 int i;
drhc28490c2006-10-26 14:25:58 +00004329 int rc = 0;
drhb3735912014-02-10 16:13:42 +00004330 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00004331 int readStdin = 1;
4332 int nCmd = 0;
4333 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00004334
drh69b30ab2014-02-27 15:11:52 +00004335#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00004336 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
4337 fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
4338 sqlite3_sourceid(), SQLITE_SOURCE_ID);
4339 exit(1);
4340 }
drhc7181902014-02-27 15:04:13 +00004341#endif
drh047d4532015-01-18 20:30:23 +00004342 setBinaryMode(stdin);
drh81cda642015-01-24 12:12:57 +00004343 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
drhdaffd0e2001-04-11 14:28:42 +00004344 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00004345 main_init(&data);
drhc28490c2006-10-26 14:25:58 +00004346 stdin_is_interactive = isatty(0);
persicom7e2dfdd2002-04-18 02:46:52 +00004347
drh44c2eb12003-04-30 11:38:26 +00004348 /* Make sure we have a valid signal handler early, before anything
4349 ** else is done.
4350 */
drh4c504392000-10-16 22:06:40 +00004351#ifdef SIGINT
4352 signal(SIGINT, interrupt_handler);
4353#endif
drh44c2eb12003-04-30 11:38:26 +00004354
drhac5649a2014-11-28 13:35:03 +00004355#ifdef SQLITE_SHELL_DBNAME_PROC
4356 {
4357 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
4358 ** of a C-function that will provide the name of the database file. Use
4359 ** this compile-time option to embed this shell program in larger
4360 ** applications. */
4361 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
4362 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
4363 warnInmemoryDb = 0;
4364 }
4365#endif
4366
drh22fbcb82004-02-01 01:22:50 +00004367 /* Do an initial pass through the command-line argument to locate
4368 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00004369 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00004370 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00004371 */
drh98d312f2012-10-25 15:23:14 +00004372 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00004373 char *z;
drhc28490c2006-10-26 14:25:58 +00004374 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004375 if( z[0]!='-' ){
4376 if( data.zDbFilename==0 ){
4377 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00004378 }else{
4379 /* Excesss arguments are interpreted as SQL (or dot-commands) and
4380 ** mean that nothing is read from stdin */
4381 readStdin = 0;
4382 nCmd++;
4383 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
4384 if( azCmd==0 ){
4385 fprintf(stderr, "out of memory\n");
4386 exit(1);
4387 }
4388 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00004389 }
drh98d312f2012-10-25 15:23:14 +00004390 }
drhcc3b4f82012-02-07 14:13:50 +00004391 if( z[1]=='-' ) z++;
4392 if( strcmp(z,"-separator")==0
4393 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00004394 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00004395 || strcmp(z,"-cmd")==0
4396 ){
drh98d312f2012-10-25 15:23:14 +00004397 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004398 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00004399 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00004400 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00004401 /* Need to check for batch mode here to so we can avoid printing
4402 ** informational messages (like from process_sqliterc) before
4403 ** we do the actual processing of arguments later in a second pass.
4404 */
shanef69573d2009-10-24 02:06:14 +00004405 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00004406 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00004407#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00004408 const char *zSize;
4409 sqlite3_int64 szHeap;
4410
drh98d312f2012-10-25 15:23:14 +00004411 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00004412 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00004413 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00004414 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
4415#endif
drh44dec872014-08-30 15:49:25 +00004416 }else if( strcmp(z,"-scratch")==0 ){
4417 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004418 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004419 if( sz>400000 ) sz = 400000;
4420 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00004421 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004422 if( n>10 ) n = 10;
4423 if( n<1 ) n = 1;
4424 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
4425 data.shellFlgs |= SHFLG_Scratch;
4426 }else if( strcmp(z,"-pagecache")==0 ){
4427 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004428 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004429 if( sz>70000 ) sz = 70000;
4430 if( sz<800 ) sz = 800;
mistachkin31970cc2014-09-01 01:16:49 +00004431 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004432 if( n<10 ) n = 10;
4433 sqlite3_config(SQLITE_CONFIG_PAGECACHE, malloc(n*sz+1), sz, n);
4434 data.shellFlgs |= SHFLG_Pagecache;
4435 }else if( strcmp(z,"-lookaside")==0 ){
4436 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00004437 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004438 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00004439 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00004440 if( n<0 ) n = 0;
4441 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
4442 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00004443#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00004444 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00004445 extern int vfstrace_register(
4446 const char *zTraceName,
4447 const char *zOldVfsName,
4448 int (*xOut)(const char*,void*),
4449 void *pOutArg,
4450 int makeDefault
4451 );
drh2b625e22011-03-16 17:05:28 +00004452 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00004453#endif
drh6f25e892011-07-08 17:02:57 +00004454#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00004455 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00004456 extern int sqlite3_multiple_initialize(const char*,int);
4457 sqlite3_multiplex_initialize(0, 1);
4458#endif
drh7d9f3942013-04-03 01:26:54 +00004459 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00004460 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
4461 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00004462 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00004463 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00004464 if( pVfs ){
4465 sqlite3_vfs_register(pVfs, 1);
4466 }else{
4467 fprintf(stderr, "no such VFS: \"%s\"\n", argv[i]);
4468 exit(1);
4469 }
drh44c2eb12003-04-30 11:38:26 +00004470 }
4471 }
drh98d312f2012-10-25 15:23:14 +00004472 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00004473#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00004474 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00004475 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00004476#else
shane86f5bdb2009-10-24 02:00:07 +00004477 fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
4478 return 1;
drh01b41712005-08-29 23:06:23 +00004479#endif
drh98d312f2012-10-25 15:23:14 +00004480 }
4481 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00004482
drh44c2eb12003-04-30 11:38:26 +00004483 /* Go ahead and open the database file if it already exists. If the
4484 ** file does not exist, delay opening it. This prevents empty database
4485 ** files from being created if a user mistypes the database name argument
4486 ** to the sqlite command-line tool.
4487 */
drhc8d74412004-08-31 23:41:26 +00004488 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00004489 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00004490 }
4491
drh22fbcb82004-02-01 01:22:50 +00004492 /* Process the initialization file if there is one. If no -init option
4493 ** is given on the command line, look for a file named ~/.sqliterc and
4494 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00004495 */
drh534f4df2015-02-28 14:03:35 +00004496 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00004497
drh22fbcb82004-02-01 01:22:50 +00004498 /* Make a second pass through the command-line argument and set
4499 ** options. This second pass is delayed until after the initialization
4500 ** file is processed so that the command-line arguments will override
4501 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00004502 */
drh98d312f2012-10-25 15:23:14 +00004503 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00004504 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00004505 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00004506 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00004507 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00004508 i++;
4509 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004510 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00004511 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004512 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00004513 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004514 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00004515 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00004516 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00004517 }else if( strcmp(z,"-csv")==0 ){
4518 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00004519 memcpy(data.colSeparator,",",2);
4520 }else if( strcmp(z,"-ascii")==0 ){
4521 data.mode = MODE_Ascii;
4522 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004523 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00004524 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00004525 SEP_Record);
mistachkine0d68852014-12-11 03:12:33 +00004526 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004527 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
4528 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00004529 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00004530 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00004531 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004532 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00004533 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00004534 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00004535 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004536 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00004537 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004538 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00004539 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00004540 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00004541 }else if( strcmp(z,"-eqp")==0 ){
4542 data.autoEQP = 1;
shaneh642d8b82010-07-28 16:05:34 +00004543 }else if( strcmp(z,"-stats")==0 ){
4544 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00004545 }else if( strcmp(z,"-scanstats")==0 ){
4546 data.scanstatsOn = 1;
drhc49f44e2006-10-26 18:15:42 +00004547 }else if( strcmp(z,"-bail")==0 ){
4548 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00004549 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00004550 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00004551 return 0;
drhc28490c2006-10-26 14:25:58 +00004552 }else if( strcmp(z,"-interactive")==0 ){
4553 stdin_is_interactive = 1;
4554 }else if( strcmp(z,"-batch")==0 ){
4555 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00004556 }else if( strcmp(z,"-heap")==0 ){
4557 i++;
drh44dec872014-08-30 15:49:25 +00004558 }else if( strcmp(z,"-scratch")==0 ){
4559 i+=2;
4560 }else if( strcmp(z,"-pagecache")==0 ){
4561 i+=2;
4562 }else if( strcmp(z,"-lookaside")==0 ){
4563 i+=2;
drh7d9f3942013-04-03 01:26:54 +00004564 }else if( strcmp(z,"-mmap")==0 ){
4565 i++;
drha7e61d82011-03-12 17:02:57 +00004566 }else if( strcmp(z,"-vfs")==0 ){
4567 i++;
drh6f25e892011-07-08 17:02:57 +00004568#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00004569 }else if( strcmp(z,"-vfstrace")==0 ){
4570 i++;
drh6f25e892011-07-08 17:02:57 +00004571#endif
4572#ifdef SQLITE_ENABLE_MULTIPLEX
4573 }else if( strcmp(z,"-multiplex")==0 ){
4574 i++;
4575#endif
drhcc3b4f82012-02-07 14:13:50 +00004576 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00004577 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00004578 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00004579 /* Run commands that follow -cmd first and separately from commands
4580 ** that simply appear on the command-line. This seems goofy. It would
4581 ** be better if all commands ran in the order that they appear. But
4582 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00004583 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00004584 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00004585 if( z[0]=='.' ){
4586 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00004587 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00004588 }else{
drh05782482013-10-24 15:20:20 +00004589 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00004590 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
4591 if( zErrMsg!=0 ){
4592 fprintf(stderr,"Error: %s\n", zErrMsg);
4593 if( bail_on_error ) return rc!=0 ? rc : 1;
4594 }else if( rc!=0 ){
4595 fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z);
4596 if( bail_on_error ) return rc;
4597 }
4598 }
drh1e5d0e92000-05-31 23:33:17 +00004599 }else{
shane86f5bdb2009-10-24 02:00:07 +00004600 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
drhe1e38c42003-05-04 18:30:59 +00004601 fprintf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00004602 return 1;
4603 }
4604 }
drh44c2eb12003-04-30 11:38:26 +00004605
drhac5649a2014-11-28 13:35:03 +00004606 if( !readStdin ){
4607 /* Run all arguments that do not begin with '-' as if they were separate
4608 ** command-line inputs, except for the argToSkip argument which contains
4609 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00004610 */
drhac5649a2014-11-28 13:35:03 +00004611 for(i=0; i<nCmd; i++){
4612 if( azCmd[i][0]=='.' ){
4613 rc = do_meta_command(azCmd[i], &data);
4614 if( rc ) return rc==2 ? 0 : rc;
4615 }else{
4616 open_db(&data, 0);
4617 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
4618 if( zErrMsg!=0 ){
4619 fprintf(stderr,"Error: %s\n", zErrMsg);
4620 return rc!=0 ? rc : 1;
4621 }else if( rc!=0 ){
4622 fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
4623 return rc;
4624 }
drh6ff13852001-11-25 13:18:23 +00004625 }
drh75897232000-05-29 14:26:00 +00004626 }
drhac5649a2014-11-28 13:35:03 +00004627 free(azCmd);
drh75897232000-05-29 14:26:00 +00004628 }else{
drh44c2eb12003-04-30 11:38:26 +00004629 /* Run commands received from standard input
4630 */
drhc28490c2006-10-26 14:25:58 +00004631 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00004632 char *zHome;
4633 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00004634 int nHistory;
drh75897232000-05-29 14:26:00 +00004635 printf(
drh743e0032011-12-12 16:51:50 +00004636 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00004637 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00004638 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00004639 );
drhb3735912014-02-10 16:13:42 +00004640 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00004641 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00004642 printBold("transient in-memory database");
4643 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00004644 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00004645 }
drh67505e72002-04-19 12:34:06 +00004646 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00004647 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00004648 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00004649 if( (zHistory = malloc(nHistory))!=0 ){
4650 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
4651 }
drh67505e72002-04-19 12:34:06 +00004652 }
danfd34d6d2015-02-25 10:54:53 +00004653 if( zHistory ) shell_read_history(zHistory);
drhc28490c2006-10-26 14:25:58 +00004654 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00004655 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00004656 shell_stifle_history(100);
4657 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00004658 free(zHistory);
drh67505e72002-04-19 12:34:06 +00004659 }
drhdaffd0e2001-04-11 14:28:42 +00004660 }else{
drhc28490c2006-10-26 14:25:58 +00004661 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00004662 }
4663 }
drh33048c02001-10-01 14:29:22 +00004664 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00004665 if( data.db ){
drhe14cd932010-12-08 03:28:17 +00004666 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00004667 }
drh05782482013-10-24 15:20:20 +00004668 sqlite3_free(data.zFreeOnClose);
drhc28490c2006-10-26 14:25:58 +00004669 return rc;
drh75897232000-05-29 14:26:00 +00004670}