blob: e8d215b95a59650a86cd3dbebac42bae237d5901 [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
mistachkin2318d332015-01-12 18:02:52 +000021** If requested, include the SQLite compiler options file for MSVC.
22*/
23#if defined(INCLUDE_MSVC_H)
24#include "msvc.h"
25#endif
26
27/*
drh8cd5b252015-03-02 22:06:43 +000028** No support for loadable extensions in VxWorks.
29*/
drhada3f2b2015-03-23 21:32:50 +000030#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
drh8cd5b252015-03-02 22:06:43 +000031# define SQLITE_OMIT_LOAD_EXTENSION 1
32#endif
33
34/*
drh36f7dd32011-10-13 16:02:17 +000035** Enable large-file support for fopen() and friends on unix.
36*/
37#ifndef SQLITE_DISABLE_LFS
38# define _LARGE_FILE 1
39# ifndef _FILE_OFFSET_BITS
40# define _FILE_OFFSET_BITS 64
41# endif
42# define _LARGEFILE_SOURCE 1
43#endif
44
drh75897232000-05-29 14:26:00 +000045#include <stdlib.h>
46#include <string.h>
47#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000048#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000049#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000050#if SQLITE_USER_AUTHENTICATION
51# include "sqlite3userauth.h"
52#endif
drh75897232000-05-29 14:26:00 +000053#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000054#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000055
drh83905c92012-06-21 13:00:37 +000056#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000057# include <signal.h>
chw97185482008-11-17 08:05:31 +000058# if !defined(__RTP__) && !defined(_WRS_KERNEL)
59# include <pwd.h>
60# endif
drhdd45df82002-04-18 12:39:03 +000061# include <unistd.h>
62# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000063#endif
drh75897232000-05-29 14:26:00 +000064
drh0ede9eb2015-01-10 16:49:23 +000065#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000066# include <readline/readline.h>
67# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000068#endif
danfd34d6d2015-02-25 10:54:53 +000069
drh0ede9eb2015-01-10 16:49:23 +000070#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000071# include <editline/readline.h>
72#endif
danfd34d6d2015-02-25 10:54:53 +000073
74#if HAVE_EDITLINE || HAVE_READLINE
75
76# define shell_add_history(X) add_history(X)
77# define shell_read_history(X) read_history(X)
78# define shell_write_history(X) write_history(X)
79# define shell_stifle_history(X) stifle_history(X)
80# define shell_readline(X) readline(X)
81
82#elif HAVE_LINENOISE
83
84# include "linenoise.h"
85# define shell_add_history(X) linenoiseHistoryAdd(X)
86# define shell_read_history(X) linenoiseHistoryLoad(X)
87# define shell_write_history(X) linenoiseHistorySave(X)
88# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
89# define shell_readline(X) linenoise(X)
90
91#else
92
mistachkin1fe36bb2016-04-04 02:16:44 +000093# define shell_read_history(X)
danfd34d6d2015-02-25 10:54:53 +000094# define shell_write_history(X)
95# define shell_stifle_history(X)
96
97# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000098#endif
99
danfd34d6d2015-02-25 10:54:53 +0000100
adamd2e8464a2006-09-06 21:39:40 +0000101#if defined(_WIN32) || defined(WIN32)
102# include <io.h>
drh6976c212014-07-24 12:09:47 +0000103# include <fcntl.h>
mistachkin073664d2015-06-17 18:57:37 +0000104# define isatty(h) _isatty(h)
105# ifndef access
106# define access(f,m) _access((f),(m))
107# endif
108# undef popen
109# define popen _popen
110# undef pclose
111# define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
mistachkin073664d2015-06-17 18:57:37 +0000113 /* Make sure isatty() has a prototype. */
114 extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000115
mistachkin073664d2015-06-17 18:57:37 +0000116# if !defined(__RTP__) && !defined(_WRS_KERNEL)
117 /* popen and pclose are not C89 functions and so are
118 ** sometimes omitted from the <stdio.h> header */
119 extern FILE *popen(const char*,const char*);
120 extern int pclose(FILE*);
121# else
122# define SQLITE_OMIT_POPEN 1
123# endif
mistachkinf6418892013-08-28 01:54:12 +0000124#endif
drh53371f92013-07-25 17:07:03 +0000125
chw65d3c132007-11-12 21:09:10 +0000126#if defined(_WIN32_WCE)
127/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
128 * thus we always assume that we have a console. That can be
129 * overridden with the -batch command line option.
130 */
131#define isatty(x) 1
132#endif
133
drhf0693c82011-10-11 20:41:54 +0000134/* ctype macros that work with signed characters */
135#define IsSpace(X) isspace((unsigned char)X)
136#define IsDigit(X) isdigit((unsigned char)X)
137#define ToLower(X) (char)tolower((unsigned char)X)
138
mistachkin1fe36bb2016-04-04 02:16:44 +0000139#if defined(_WIN32) || defined(WIN32)
140#include <windows.h>
141
142/* string conversion routines only needed on Win32 */
143extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
144extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
145extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
146#endif
147
drh047d4532015-01-18 20:30:23 +0000148/* On Windows, we normally run with output mode of TEXT so that \n characters
149** are automatically translated into \r\n. However, this behavior needs
150** to be disabled in some cases (ex: when generating CSV output and when
151** rendering quoted strings that contain \n characters). The following
152** routines take care of that.
153*/
154#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000155static void setBinaryMode(FILE *file, int isOutput){
156 if( isOutput ) fflush(file);
157 _setmode(_fileno(file), _O_BINARY);
drh047d4532015-01-18 20:30:23 +0000158}
mistachkin1fe36bb2016-04-04 02:16:44 +0000159static void setTextMode(FILE *file, int isOutput){
160 if( isOutput ) fflush(file);
161 _setmode(_fileno(file), _O_TEXT);
drh047d4532015-01-18 20:30:23 +0000162}
163#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000164# define setBinaryMode(X,Y)
165# define setTextMode(X,Y)
drh047d4532015-01-18 20:30:23 +0000166#endif
167
drh43408312013-10-30 12:43:36 +0000168
169/* True if the timer is enabled */
170static int enableTimer = 0;
171
172/* Return the current wall-clock time */
173static sqlite3_int64 timeOfDay(void){
174 static sqlite3_vfs *clockVfs = 0;
175 sqlite3_int64 t;
176 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
dan3fd415b2015-11-16 08:54:10 +0000177 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drh43408312013-10-30 12:43:36 +0000178 clockVfs->xCurrentTimeInt64(clockVfs, &t);
179 }else{
180 double r;
181 clockVfs->xCurrentTime(clockVfs, &r);
182 t = (sqlite3_int64)(r*86400000.0);
183 }
184 return t;
185}
186
drh91eb93c2015-03-03 19:56:20 +0000187#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000188#include <sys/time.h>
189#include <sys/resource.h>
190
drh91eb93c2015-03-03 19:56:20 +0000191/* VxWorks does not support getrusage() as far as we can determine */
192#if defined(_WRS_KERNEL) || defined(__RTP__)
193struct rusage {
194 struct timeval ru_utime; /* user CPU time used */
195 struct timeval ru_stime; /* system CPU time used */
196};
197#define getrusage(A,B) memset(B,0,sizeof(*B))
198#endif
199
drhda108222009-02-25 19:07:24 +0000200/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000201static struct rusage sBegin; /* CPU time at start */
202static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000203
drhda108222009-02-25 19:07:24 +0000204/*
205** Begin timing an operation
206*/
207static void beginTimer(void){
208 if( enableTimer ){
209 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000210 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000211 }
212}
213
214/* Return the difference of two time_structs in seconds */
215static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
mistachkin1fe36bb2016-04-04 02:16:44 +0000216 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
drhda108222009-02-25 19:07:24 +0000217 (double)(pEnd->tv_sec - pStart->tv_sec);
218}
219
220/*
221** Print the timing results.
222*/
223static void endTimer(void){
224 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000225 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000226 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000227 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000228 printf("Run Time: real %.3f user %f sys %f\n",
229 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000230 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
231 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
232 }
233}
shaneb320ccd2009-10-21 03:42:58 +0000234
drhda108222009-02-25 19:07:24 +0000235#define BEGIN_TIMER beginTimer()
236#define END_TIMER endTimer()
237#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000238
239#elif (defined(_WIN32) || defined(WIN32))
240
shaneb320ccd2009-10-21 03:42:58 +0000241/* Saved resource information for the beginning of an operation */
242static HANDLE hProcess;
243static FILETIME ftKernelBegin;
244static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000245static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000246typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
247 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000248static GETPROCTIMES getProcessTimesAddr = NULL;
249
shaneb320ccd2009-10-21 03:42:58 +0000250/*
251** Check to see if we have timer support. Return 1 if necessary
252** support found (or found previously).
253*/
254static int hasTimer(void){
255 if( getProcessTimesAddr ){
256 return 1;
257 } else {
drh4ace5362014-11-10 14:42:28 +0000258 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
259 ** versions. See if the version we are running on has it, and if it
260 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000261 */
262 hProcess = GetCurrentProcess();
263 if( hProcess ){
264 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
265 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000266 getProcessTimesAddr =
267 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000268 if( NULL != getProcessTimesAddr ){
269 return 1;
270 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000271 FreeLibrary(hinstLib);
shaneb320ccd2009-10-21 03:42:58 +0000272 }
273 }
274 }
275 return 0;
276}
277
278/*
279** Begin timing an operation
280*/
281static void beginTimer(void){
282 if( enableTimer && getProcessTimesAddr ){
283 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000284 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
285 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000286 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000287 }
288}
289
290/* Return the difference of two FILETIME structs in seconds */
291static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
292 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
293 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
294 return (double) ((i64End - i64Start) / 10000000.0);
295}
296
297/*
298** Print the timing results.
299*/
300static void endTimer(void){
301 if( enableTimer && getProcessTimesAddr){
302 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000303 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000304 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000305 printf("Run Time: real %.3f user %f sys %f\n",
306 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000307 timeDiff(&ftUserBegin, &ftUserEnd),
308 timeDiff(&ftKernelBegin, &ftKernelEnd));
309 }
310}
311
312#define BEGIN_TIMER beginTimer()
313#define END_TIMER endTimer()
314#define HAS_TIMER hasTimer()
315
drhda108222009-02-25 19:07:24 +0000316#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000317#define BEGIN_TIMER
drhda108222009-02-25 19:07:24 +0000318#define END_TIMER
319#define HAS_TIMER 0
320#endif
321
shanec0688ea2009-03-05 03:48:06 +0000322/*
323** Used to prevent warnings about unused parameters
324*/
325#define UNUSED_PARAMETER(x) (void)(x)
326
drhe91d16b2008-12-08 18:27:31 +0000327/*
drhc49f44e2006-10-26 18:15:42 +0000328** If the following flag is set, then command execution stops
329** at an error if we are not interactive.
330*/
331static int bail_on_error = 0;
332
333/*
drhc28490c2006-10-26 14:25:58 +0000334** Threat stdin as an interactive input if the following variable
335** is true. Otherwise, assume stdin is connected to a file or pipe.
336*/
337static int stdin_is_interactive = 1;
338
339/*
drhe05461c2015-12-30 13:36:57 +0000340** On Windows systems we have to know if standard output is a console
341** in order to translate UTF-8 into MBCS. The following variable is
342** true if translation is required.
343*/
344static int stdout_is_console = 1;
345
346/*
drh4c504392000-10-16 22:06:40 +0000347** The following is the open SQLite database. We make a pointer
348** to this database a static variable so that it can be accessed
349** by the SIGINT handler to interrupt database processing.
350*/
mistachkin8e189222015-04-19 21:43:16 +0000351static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000352
353/*
drh67505e72002-04-19 12:34:06 +0000354** True if an interrupt (Control-C) has been received.
355*/
drh43617e92006-03-06 20:55:46 +0000356static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000357
358/*
persicom7e2dfdd2002-04-18 02:46:52 +0000359** This is the name of our program. It is set in main(), used
360** in a number of other places, mostly for error messages.
361*/
362static char *Argv0;
363
364/*
365** Prompt strings. Initialized in main. Settable with
366** .prompt main continue
367*/
368static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
369static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
370
drhb0603412007-02-28 04:47:26 +0000371/*
mistachkin710b33b2016-01-03 18:59:28 +0000372** Render output like fprintf(). Except, if the output is going to the
373** console and if this is running on a Windows machine, translate the
374** output from UTF-8 into MBCS.
375*/
376#if defined(_WIN32) || defined(WIN32)
377void utf8_printf(FILE *out, const char *zFormat, ...){
378 va_list ap;
379 va_start(ap, zFormat);
380 if( stdout_is_console && (out==stdout || out==stderr) ){
mistachkin710b33b2016-01-03 18:59:28 +0000381 char *z1 = sqlite3_vmprintf(zFormat, ap);
mistachkin1fe36bb2016-04-04 02:16:44 +0000382 char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
mistachkin710b33b2016-01-03 18:59:28 +0000383 sqlite3_free(z1);
384 fputs(z2, out);
385 sqlite3_free(z2);
386 }else{
387 vfprintf(out, zFormat, ap);
388 }
389 va_end(ap);
390}
391#elif !defined(utf8_printf)
392# define utf8_printf fprintf
393#endif
394
395/*
396** Render output like fprintf(). This should not be used on anything that
397** includes string formatting (e.g. "%s").
398*/
399#if !defined(raw_printf)
400# define raw_printf fprintf
401#endif
402
403/*
drhb0603412007-02-28 04:47:26 +0000404** Write I/O traces to the following stream.
405*/
rsebe0a9092007-07-30 18:24:38 +0000406#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000407static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000408#endif
drhb0603412007-02-28 04:47:26 +0000409
410/*
411** This routine works like printf in that its first argument is a
412** format string and subsequent arguments are values to be substituted
413** in place of % fields. The result of formatting this string
414** is written to iotrace.
415*/
rsebe0a9092007-07-30 18:24:38 +0000416#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000417static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000418 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000419 char *z;
drhb0603412007-02-28 04:47:26 +0000420 if( iotrace==0 ) return;
421 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000422 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000423 va_end(ap);
mistachkin710b33b2016-01-03 18:59:28 +0000424 utf8_printf(iotrace, "%s", z);
drhf075cd02007-02-28 06:14:25 +0000425 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000426}
rsebe0a9092007-07-30 18:24:38 +0000427#endif
drhb0603412007-02-28 04:47:26 +0000428
drh44c2eb12003-04-30 11:38:26 +0000429
persicom7e2dfdd2002-04-18 02:46:52 +0000430/*
drh83965662003-04-17 02:54:13 +0000431** Determines if a string is a number of not.
432*/
danielk19772e588c72005-12-09 14:25:08 +0000433static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000434 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000435 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000436 return 0;
437 }
438 z++;
439 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000440 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000441 if( *z=='.' ){
442 z++;
drhf0693c82011-10-11 20:41:54 +0000443 if( !IsDigit(*z) ) return 0;
444 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000445 if( realnum ) *realnum = 1;
446 }
447 if( *z=='e' || *z=='E' ){
448 z++;
449 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000450 if( !IsDigit(*z) ) return 0;
451 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000452 if( realnum ) *realnum = 1;
453 }
454 return *z==0;
455}
drh83965662003-04-17 02:54:13 +0000456
457/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000458** A global char* and an SQL function to access its current value
459** from within an SQL statement. This program used to use the
danielk1977bc6ada42004-06-30 08:20:16 +0000460** sqlite_exec_printf() API to substitue a string into an SQL statement.
461** The correct way to do this with sqlite3 is to use the bind API, but
462** since the shell is built around the callback paradigm it would be a lot
463** of work. Instead just use this hack, which is quite harmless.
464*/
465static const char *zShellStatic = 0;
466static void shellstaticFunc(
467 sqlite3_context *context,
468 int argc,
469 sqlite3_value **argv
470){
471 assert( 0==argc );
472 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000473 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000474 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000475 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
476}
477
478
479/*
drhe05461c2015-12-30 13:36:57 +0000480** Compute a string length that is limited to what can be stored in
481** lower 30 bits of a 32-bit signed integer.
482*/
483static int strlen30(const char *z){
484 const char *z2 = z;
485 while( *z2 ){ z2++; }
486 return 0x3fffffff & (int)(z2 - z);
487}
488
489/*
drhfeac5f82004-08-01 00:10:45 +0000490** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000491** the text in memory obtained from malloc() and returns a pointer
492** to the text. NULL is returned at end of file, or if malloc()
493** fails.
494**
drh9f099fd2013-08-06 14:01:46 +0000495** If zLine is not NULL then it is a malloced buffer returned from
496** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000497*/
drh9f099fd2013-08-06 14:01:46 +0000498static char *local_getline(char *zLine, FILE *in){
499 int nLine = zLine==0 ? 0 : 100;
500 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000501
drhb07028f2011-10-14 21:49:18 +0000502 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000503 if( n+100>nLine ){
504 nLine = nLine*2 + 100;
505 zLine = realloc(zLine, nLine);
506 if( zLine==0 ) return 0;
507 }
drhdaffd0e2001-04-11 14:28:42 +0000508 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000509 if( n==0 ){
510 free(zLine);
511 return 0;
512 }
513 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000514 break;
515 }
drh9f099fd2013-08-06 14:01:46 +0000516 while( zLine[n] ) n++;
517 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000518 n--;
shaneh13b36022009-12-17 21:07:15 +0000519 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000520 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000521 break;
drh8e7e7a22000-05-30 18:45:23 +0000522 }
523 }
drhe05461c2015-12-30 13:36:57 +0000524#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000525 /* For interactive input on Windows systems, translate the
drhe05461c2015-12-30 13:36:57 +0000526 ** multi-byte characterset characters into UTF-8. */
527 if( stdin_is_interactive ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000528 char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
drhe05461c2015-12-30 13:36:57 +0000529 if( zTrans ){
530 int nTrans = strlen30(zTrans)+1;
531 if( nTrans>nLine ){
532 zLine = realloc(zLine, nTrans);
533 if( zLine==0 ){
534 sqlite3_free(zTrans);
535 return 0;
536 }
537 }
538 memcpy(zLine, zTrans, nTrans);
539 sqlite3_free(zTrans);
540 }
541 }
542#endif /* defined(_WIN32) || defined(WIN32) */
drh8e7e7a22000-05-30 18:45:23 +0000543 return zLine;
544}
545
546/*
drhc28490c2006-10-26 14:25:58 +0000547** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000548**
drh9f099fd2013-08-06 14:01:46 +0000549** If in==0 then read from standard input and prompt before each line.
550** If isContinuation is true, then a continuation prompt is appropriate.
551** If isContinuation is zero, then the main prompt should be used.
552**
553** If zPrior is not NULL then it is a buffer from a prior call to this
554** routine that can be reused.
555**
556** The result is stored in space obtained from malloc() and must either
557** be freed by the caller or else passed back into this routine via the
558** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000559*/
drh9f099fd2013-08-06 14:01:46 +0000560static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000561 char *zPrompt;
562 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000563 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000564 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000565 }else{
drh9f099fd2013-08-06 14:01:46 +0000566 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000567#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000568 printf("%s", zPrompt);
569 fflush(stdout);
570 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000571#else
572 free(zPrior);
573 zResult = shell_readline(zPrompt);
574 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000575#endif
drh9f099fd2013-08-06 14:01:46 +0000576 }
drh8e7e7a22000-05-30 18:45:23 +0000577 return zResult;
578}
579
drhe6229612014-08-18 15:08:26 +0000580#if defined(SQLITE_ENABLE_SESSION)
581/*
582** State information for a single open session
583*/
584typedef struct OpenSession OpenSession;
585struct OpenSession {
586 char *zName; /* Symbolic name for this session */
587 int nFilter; /* Number of xFilter rejection GLOB patterns */
588 char **azFilter; /* Array of xFilter rejection GLOB patterns */
589 sqlite3_session *p; /* The open session */
590};
591#endif
592
drhdcd87a92014-08-18 13:45:42 +0000593/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000594** Shell output mode information from before ".explain on",
drhdcd87a92014-08-18 13:45:42 +0000595** saved so that it can be restored by ".explain off"
596*/
597typedef struct SavedModeInfo SavedModeInfo;
598struct SavedModeInfo {
599 int valid; /* Is there legit data in here? */
600 int mode; /* Mode prior to ".explain on" */
601 int showHeader; /* The ".header" setting prior to ".explain on" */
602 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000603};
drh45e29d82006-11-20 16:21:10 +0000604
drh8e7e7a22000-05-30 18:45:23 +0000605/*
drhdcd87a92014-08-18 13:45:42 +0000606** State information about the database connection is contained in an
607** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000608*/
drhdcd87a92014-08-18 13:45:42 +0000609typedef struct ShellState ShellState;
610struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000611 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000612 int echoOn; /* True to echo input commands */
drh700c2522016-02-09 18:39:25 +0000613 int autoExplain; /* Automatically turn on .explain mode */
drhc2ce0be2014-05-29 12:36:14 +0000614 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000615 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000616 int scanstatsOn; /* True to display scan stats before each finalize */
drhdf12f1c2015-12-07 21:46:19 +0000617 int countChanges; /* True to display change counts */
drh9569f602015-04-16 15:05:04 +0000618 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000619 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000620 int cnt; /* Number of records displayed so far */
621 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000622 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000623 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000624 int mode; /* An output mode setting */
drh700c2522016-02-09 18:39:25 +0000625 int cMode; /* temporary output mode for the current query */
626 int normalMode; /* Output mode before ".explain on" */
drh45e29d82006-11-20 16:21:10 +0000627 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000628 int showHeader; /* True to show column names in List or Column mode */
drh44dec872014-08-30 15:49:25 +0000629 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000630 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000631 char colSeparator[20]; /* Column separator character for several modes */
632 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000633 int colWidth[100]; /* Requested width of each column when in column mode*/
634 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000635 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000636 ** the database */
drh44c2eb12003-04-30 11:38:26 +0000637 char outfile[FILENAME_MAX]; /* Filename for *out */
638 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000639 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000640 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000641 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000642 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000643 int *aiIndent; /* Array of indents used in MODE_Explain */
644 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000645 int iIndent; /* Index of current op in aiIndent[] */
drhe6229612014-08-18 15:08:26 +0000646#if defined(SQLITE_ENABLE_SESSION)
647 int nSession; /* Number of active sessions */
648 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
649#endif
drh75897232000-05-29 14:26:00 +0000650};
651
652/*
drh44dec872014-08-30 15:49:25 +0000653** These are the allowed shellFlgs values
654*/
655#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
656#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
657#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
658
659/*
drh75897232000-05-29 14:26:00 +0000660** These are the allowed modes.
661*/
drh967e8b72000-06-21 13:59:10 +0000662#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000663#define MODE_Column 1 /* One record per line in neat columns */
664#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000665#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
666#define MODE_Html 4 /* Generate an XHTML table */
667#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000668#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000669#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000670#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000671#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
drh4926fec2016-04-13 15:33:42 +0000672#define MODE_Pretty 10 /* Pretty-print schemas */
persicom7e2dfdd2002-04-18 02:46:52 +0000673
drh66ce4d02008-02-15 17:38:06 +0000674static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000675 "line",
676 "column",
677 "list",
678 "semi",
679 "html",
drhfeac5f82004-08-01 00:10:45 +0000680 "insert",
681 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000682 "csv",
drh66ce4d02008-02-15 17:38:06 +0000683 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000684 "ascii",
drh4926fec2016-04-13 15:33:42 +0000685 "prettyprint",
persicom7e2dfdd2002-04-18 02:46:52 +0000686};
drh75897232000-05-29 14:26:00 +0000687
688/*
mistachkinfad42082014-07-24 22:13:12 +0000689** These are the column/row/line separators used by the various
690** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000691*/
mistachkinfad42082014-07-24 22:13:12 +0000692#define SEP_Column "|"
693#define SEP_Row "\n"
694#define SEP_Tab "\t"
695#define SEP_Space " "
696#define SEP_Comma ","
697#define SEP_CrLf "\r\n"
698#define SEP_Unit "\x1F"
699#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000700
701/*
drh75897232000-05-29 14:26:00 +0000702** Number of elements in an array
703*/
drh902b9ee2008-12-05 17:17:07 +0000704#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000705
706/*
drh127f9d72010-02-23 01:47:00 +0000707** A callback for the sqlite3_log() interface.
708*/
709static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000710 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000711 if( p->pLog==0 ) return;
mistachkinaae280e2015-12-31 19:06:24 +0000712 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
drh127f9d72010-02-23 01:47:00 +0000713 fflush(p->pLog);
714}
715
716/*
shane626a6e42009-10-22 17:30:15 +0000717** Output the given string as a hex-encoded blob (eg. X'1234' )
718*/
719static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
720 int i;
721 char *zBlob = (char *)pBlob;
mistachkinaae280e2015-12-31 19:06:24 +0000722 raw_printf(out,"X'");
723 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
724 raw_printf(out,"'");
shane626a6e42009-10-22 17:30:15 +0000725}
726
727/*
drh28bd4bc2000-06-15 15:57:22 +0000728** Output the given string as a quoted string using SQL quoting conventions.
729*/
730static void output_quoted_string(FILE *out, const char *z){
731 int i;
732 int nSingle = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +0000733 setBinaryMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000734 for(i=0; z[i]; i++){
735 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000736 }
737 if( nSingle==0 ){
drhe05461c2015-12-30 13:36:57 +0000738 utf8_printf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000739 }else{
mistachkinaae280e2015-12-31 19:06:24 +0000740 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000741 while( *z ){
742 for(i=0; z[i] && z[i]!='\''; i++){}
743 if( i==0 ){
mistachkinaae280e2015-12-31 19:06:24 +0000744 raw_printf(out,"''");
drh28bd4bc2000-06-15 15:57:22 +0000745 z++;
746 }else if( z[i]=='\'' ){
drhe05461c2015-12-30 13:36:57 +0000747 utf8_printf(out,"%.*s''",i,z);
drh28bd4bc2000-06-15 15:57:22 +0000748 z += i+1;
749 }else{
drhe05461c2015-12-30 13:36:57 +0000750 utf8_printf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000751 break;
752 }
753 }
mistachkinaae280e2015-12-31 19:06:24 +0000754 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000755 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000756 setTextMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000757}
758
759/*
drhfeac5f82004-08-01 00:10:45 +0000760** Output the given string as a quoted according to C or TCL quoting rules.
761*/
762static void output_c_string(FILE *out, const char *z){
763 unsigned int c;
764 fputc('"', out);
765 while( (c = *(z++))!=0 ){
766 if( c=='\\' ){
767 fputc(c, out);
768 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000769 }else if( c=='"' ){
770 fputc('\\', out);
771 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000772 }else if( c=='\t' ){
773 fputc('\\', out);
774 fputc('t', out);
775 }else if( c=='\n' ){
776 fputc('\\', out);
777 fputc('n', out);
778 }else if( c=='\r' ){
779 fputc('\\', out);
780 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000781 }else if( !isprint(c&0xff) ){
mistachkinaae280e2015-12-31 19:06:24 +0000782 raw_printf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000783 }else{
784 fputc(c, out);
785 }
786 }
787 fputc('"', out);
788}
789
790/*
drhc08a4f12000-06-15 16:49:48 +0000791** Output the given string with characters that are special to
792** HTML escaped.
793*/
794static void output_html_string(FILE *out, const char *z){
795 int i;
drhc3d6ba42014-01-13 20:38:35 +0000796 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000797 while( *z ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000798 for(i=0; z[i]
799 && z[i]!='<'
800 && z[i]!='&'
801 && z[i]!='>'
802 && z[i]!='\"'
shane43d9cb22009-10-21 14:11:48 +0000803 && z[i]!='\'';
804 i++){}
drhc08a4f12000-06-15 16:49:48 +0000805 if( i>0 ){
drhe05461c2015-12-30 13:36:57 +0000806 utf8_printf(out,"%.*s",i,z);
drhc08a4f12000-06-15 16:49:48 +0000807 }
808 if( z[i]=='<' ){
mistachkinaae280e2015-12-31 19:06:24 +0000809 raw_printf(out,"&lt;");
drhc08a4f12000-06-15 16:49:48 +0000810 }else if( z[i]=='&' ){
mistachkinaae280e2015-12-31 19:06:24 +0000811 raw_printf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000812 }else if( z[i]=='>' ){
mistachkinaae280e2015-12-31 19:06:24 +0000813 raw_printf(out,"&gt;");
shane43d9cb22009-10-21 14:11:48 +0000814 }else if( z[i]=='\"' ){
mistachkinaae280e2015-12-31 19:06:24 +0000815 raw_printf(out,"&quot;");
shane43d9cb22009-10-21 14:11:48 +0000816 }else if( z[i]=='\'' ){
mistachkinaae280e2015-12-31 19:06:24 +0000817 raw_printf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000818 }else{
819 break;
820 }
821 z += i + 1;
822 }
823}
824
825/*
drhc49f44e2006-10-26 18:15:42 +0000826** If a field contains any character identified by a 1 in the following
827** array, then the string must be quoted for CSV.
828*/
829static const char needCsvQuote[] = {
mistachkin1fe36bb2016-04-04 02:16:44 +0000830 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
831 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
832 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
833 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
834 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
836 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
838 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
839 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
840 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
841 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
842 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
843 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
844 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
845 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
drhc49f44e2006-10-26 18:15:42 +0000846};
847
848/*
mistachkindd11f2d2014-12-11 04:49:46 +0000849** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000850** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000851** the null value. Strings are quoted if necessary. The separator
852** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000853*/
drhdcd87a92014-08-18 13:45:42 +0000854static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000855 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000856 if( z==0 ){
drhe05461c2015-12-30 13:36:57 +0000857 utf8_printf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000858 }else{
drhc49f44e2006-10-26 18:15:42 +0000859 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000860 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000861 for(i=0; z[i]; i++){
mistachkin1fe36bb2016-04-04 02:16:44 +0000862 if( needCsvQuote[((unsigned char*)z)[i]]
863 || (z[i]==p->colSeparator[0] &&
mistachkin636bf9f2014-07-19 20:15:16 +0000864 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000865 i = 0;
866 break;
867 }
868 }
869 if( i==0 ){
870 putc('"', out);
871 for(i=0; z[i]; i++){
872 if( z[i]=='"' ) putc('"', out);
873 putc(z[i], out);
874 }
875 putc('"', out);
876 }else{
drhe05461c2015-12-30 13:36:57 +0000877 utf8_printf(out, "%s", z);
drhc49f44e2006-10-26 18:15:42 +0000878 }
drh8e64d1c2004-10-07 00:32:39 +0000879 }
880 if( bSep ){
drhe05461c2015-12-30 13:36:57 +0000881 utf8_printf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000882 }
883}
884
danielk19774af00c62005-01-23 23:43:21 +0000885#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000886/*
drh4c504392000-10-16 22:06:40 +0000887** This routine runs when the user presses Ctrl-C
888*/
889static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000890 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000891 seenInterrupt++;
892 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000893 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000894}
danielk19774af00c62005-01-23 23:43:21 +0000895#endif
drh4c504392000-10-16 22:06:40 +0000896
897/*
drhde613c62016-04-04 17:23:10 +0000898** When the ".auth ON" is set, the following authorizer callback is
899** invoked. It always returns SQLITE_OK.
900*/
901static int shellAuth(
902 void *pClientData,
903 int op,
904 const char *zA1,
905 const char *zA2,
906 const char *zA3,
907 const char *zA4
908){
909 ShellState *p = (ShellState*)pClientData;
910 static const char *azAction[] = { 0,
911 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
912 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
913 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
914 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
915 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
916 "DROP_TRIGGER", "DROP_VIEW", "INSERT",
917 "PRAGMA", "READ", "SELECT",
918 "TRANSACTION", "UPDATE", "ATTACH",
919 "DETACH", "ALTER_TABLE", "REINDEX",
920 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
921 "FUNCTION", "SAVEPOINT", "RECURSIVE"
922 };
923 int i;
924 const char *az[4];
925 az[0] = zA1;
926 az[1] = zA2;
927 az[2] = zA3;
928 az[3] = zA4;
929 raw_printf(p->out, "authorizer: %s", azAction[op]);
930 for(i=0; i<4; i++){
931 raw_printf(p->out, " ");
932 if( az[i] ){
933 output_c_string(p->out, az[i]);
934 }else{
935 raw_printf(p->out, "NULL");
936 }
937 }
938 raw_printf(p->out, "\n");
939 return SQLITE_OK;
940}
941
942
943/*
shane626a6e42009-10-22 17:30:15 +0000944** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000945** invokes for each row of a query result.
946*/
drh4ace5362014-11-10 14:42:28 +0000947static int shell_callback(
948 void *pArg,
949 int nArg, /* Number of result columns */
950 char **azArg, /* Text of each result column */
951 char **azCol, /* Column names */
952 int *aiType /* Column types */
953){
drh75897232000-05-29 14:26:00 +0000954 int i;
drhdcd87a92014-08-18 13:45:42 +0000955 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000956
drh700c2522016-02-09 18:39:25 +0000957 switch( p->cMode ){
drh75897232000-05-29 14:26:00 +0000958 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000959 int w = 5;
drh6a535342001-10-19 16:44:56 +0000960 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000961 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000962 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000963 if( len>w ) w = len;
964 }
drhe05461c2015-12-30 13:36:57 +0000965 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000966 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000967 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000968 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000969 }
970 break;
971 }
danielk19770d78bae2008-01-03 07:09:48 +0000972 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000973 case MODE_Column: {
drh700c2522016-02-09 18:39:25 +0000974 static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
975 const int *colWidth;
976 int showHdr;
977 char *rowSep;
978 if( p->cMode==MODE_Column ){
979 colWidth = p->colWidth;
980 showHdr = p->showHeader;
981 rowSep = p->rowSeparator;
982 }else{
983 colWidth = aExplainWidths;
984 showHdr = 1;
mistachkin6d945552016-02-09 20:31:50 +0000985 rowSep = SEP_Row;
drh700c2522016-02-09 18:39:25 +0000986 }
drha0c66f52000-07-29 13:20:21 +0000987 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000988 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000989 int w, n;
990 if( i<ArraySize(p->colWidth) ){
drh700c2522016-02-09 18:39:25 +0000991 w = colWidth[i];
drh75897232000-05-29 14:26:00 +0000992 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000993 w = 0;
drh75897232000-05-29 14:26:00 +0000994 }
drh078b1fd2012-09-21 13:40:02 +0000995 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000996 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000997 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000998 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000999 if( w<n ) w = n;
1000 }
1001 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001002 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001003 }
drh700c2522016-02-09 18:39:25 +00001004 if( showHdr ){
drh078b1fd2012-09-21 13:40:02 +00001005 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001006 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001007 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001008 }else{
drhe05461c2015-12-30 13:36:57 +00001009 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001010 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001011 }
drha0c66f52000-07-29 13:20:21 +00001012 }
1013 }
drh700c2522016-02-09 18:39:25 +00001014 if( showHdr ){
drha0c66f52000-07-29 13:20:21 +00001015 for(i=0; i<nArg; i++){
1016 int w;
1017 if( i<ArraySize(p->actualWidth) ){
1018 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +00001019 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +00001020 }else{
1021 w = 10;
1022 }
mistachkinaae280e2015-12-31 19:06:24 +00001023 utf8_printf(p->out,"%-*.*s%s",w,w,
drhe05461c2015-12-30 13:36:57 +00001024 "----------------------------------------------------------"
drha0c66f52000-07-29 13:20:21 +00001025 "----------------------------------------------------------",
drh700c2522016-02-09 18:39:25 +00001026 i==nArg-1 ? rowSep : " ");
drha0c66f52000-07-29 13:20:21 +00001027 }
drh75897232000-05-29 14:26:00 +00001028 }
1029 }
drh6a535342001-10-19 16:44:56 +00001030 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001031 for(i=0; i<nArg; i++){
1032 int w;
drha0c66f52000-07-29 13:20:21 +00001033 if( i<ArraySize(p->actualWidth) ){
1034 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001035 }else{
1036 w = 10;
1037 }
drh700c2522016-02-09 18:39:25 +00001038 if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +00001039 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001040 }
dana98bf362013-11-13 18:35:01 +00001041 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +00001042 if( p->iIndent<p->nIndent ){
mistachkinaae280e2015-12-31 19:06:24 +00001043 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +00001044 }
danc4650bb2013-11-18 08:41:06 +00001045 p->iIndent++;
dana98bf362013-11-13 18:35:01 +00001046 }
drh078b1fd2012-09-21 13:40:02 +00001047 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001048 utf8_printf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +00001049 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001050 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001051 }else{
drhe05461c2015-12-30 13:36:57 +00001052 utf8_printf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +00001053 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001054 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001055 }
drh75897232000-05-29 14:26:00 +00001056 }
1057 break;
1058 }
drh4926fec2016-04-13 15:33:42 +00001059 case MODE_Semi: { /* .schema and .fullschema output */
1060 utf8_printf(p->out, "%s;\n", azArg[0]);
1061 break;
1062 }
1063 case MODE_Pretty: { /* .schema and .fullschema with --indent */
1064 char *z;
drh07d683f2016-04-13 21:00:36 +00001065 int j;
drh4926fec2016-04-13 15:33:42 +00001066 int nParen = 0;
1067 char cEnd = 0;
1068 char c;
1069 int nLine = 0;
1070 assert( nArg==1 );
1071 if( azArg[0]==0 ) break;
1072 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
1073 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
1074 ){
1075 utf8_printf(p->out, "%s;\n", azArg[0]);
1076 break;
1077 }
1078 z = sqlite3_mprintf("%s", azArg[0]);
1079 j = 0;
1080 for(i=0; IsSpace(z[i]); i++){}
1081 for(; (c = z[i])!=0; i++){
1082 if( IsSpace(c) ){
1083 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
1084 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
1085 j--;
1086 }
1087 z[j++] = c;
1088 }
1089 while( j>0 && IsSpace(z[j-1]) ){ j--; }
1090 z[j] = 0;
1091 if( strlen30(z)>=79 ){
drh07d683f2016-04-13 21:00:36 +00001092 for(i=j=0; (c = z[i])!=0; i++){
drh4926fec2016-04-13 15:33:42 +00001093 if( c==cEnd ){
1094 cEnd = 0;
1095 }else if( c=='"' || c=='\'' || c=='`' ){
1096 cEnd = c;
1097 }else if( c=='[' ){
1098 cEnd = ']';
1099 }else if( c=='(' ){
1100 nParen++;
1101 }else if( c==')' ){
1102 nParen--;
1103 if( nLine>0 && nParen==0 && j>0 ){
1104 utf8_printf(p->out, "%.*s\n", j, z);
1105 j = 0;
1106 }
1107 }
1108 z[j++] = c;
1109 if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
1110 if( c=='\n' ) j--;
1111 utf8_printf(p->out, "%.*s\n ", j, z);
1112 j = 0;
1113 nLine++;
1114 while( IsSpace(z[i+1]) ){ i++; }
1115 }
1116 }
1117 z[j] = 0;
1118 }
1119 utf8_printf(p->out, "%s;\n", z);
1120 sqlite3_free(z);
1121 break;
1122 }
drh75897232000-05-29 14:26:00 +00001123 case MODE_List: {
1124 if( p->cnt++==0 && p->showHeader ){
1125 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001126 utf8_printf(p->out,"%s%s",azCol[i],
mistachkin636bf9f2014-07-19 20:15:16 +00001127 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +00001128 }
1129 }
drh6a535342001-10-19 16:44:56 +00001130 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001131 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001132 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +00001133 if( z==0 ) z = p->nullValue;
drhe05461c2015-12-30 13:36:57 +00001134 utf8_printf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001135 if( i<nArg-1 ){
drhe05461c2015-12-30 13:36:57 +00001136 utf8_printf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +00001137 }else{
drhe05461c2015-12-30 13:36:57 +00001138 utf8_printf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001139 }
drh75897232000-05-29 14:26:00 +00001140 }
1141 break;
1142 }
drh1e5d0e92000-05-31 23:33:17 +00001143 case MODE_Html: {
1144 if( p->cnt++==0 && p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001145 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001146 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001147 raw_printf(p->out,"<TH>");
shane43d9cb22009-10-21 14:11:48 +00001148 output_html_string(p->out, azCol[i]);
mistachkinaae280e2015-12-31 19:06:24 +00001149 raw_printf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001150 }
mistachkinaae280e2015-12-31 19:06:24 +00001151 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001152 }
drh6a535342001-10-19 16:44:56 +00001153 if( azArg==0 ) break;
mistachkinaae280e2015-12-31 19:06:24 +00001154 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001155 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001156 raw_printf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +00001157 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00001158 raw_printf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001159 }
mistachkinaae280e2015-12-31 19:06:24 +00001160 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001161 break;
1162 }
drhfeac5f82004-08-01 00:10:45 +00001163 case MODE_Tcl: {
1164 if( p->cnt++==0 && p->showHeader ){
1165 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001166 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhe05461c2015-12-30 13:36:57 +00001167 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001168 }
drhe05461c2015-12-30 13:36:57 +00001169 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001170 }
1171 if( azArg==0 ) break;
1172 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +00001173 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
drhe05461c2015-12-30 13:36:57 +00001174 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001175 }
drhe05461c2015-12-30 13:36:57 +00001176 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001177 break;
1178 }
drh8e64d1c2004-10-07 00:32:39 +00001179 case MODE_Csv: {
mistachkin1fe36bb2016-04-04 02:16:44 +00001180 setBinaryMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001181 if( p->cnt++==0 && p->showHeader ){
1182 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001183 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001184 }
drhe05461c2015-12-30 13:36:57 +00001185 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001186 }
drh40253262014-10-17 21:35:05 +00001187 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +00001188 for(i=0; i<nArg; i++){
1189 output_csv(p, azArg[i], i<nArg-1);
1190 }
drhe05461c2015-12-30 13:36:57 +00001191 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001192 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001193 setTextMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001194 break;
1195 }
drh28bd4bc2000-06-15 15:57:22 +00001196 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001197 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001198 if( azArg==0 ) break;
drhe05461c2015-12-30 13:36:57 +00001199 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
mistachkin151c75a2015-04-07 21:16:40 +00001200 if( p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001201 raw_printf(p->out,"(");
mistachkin151c75a2015-04-07 21:16:40 +00001202 for(i=0; i<nArg; i++){
1203 char *zSep = i>0 ? ",": "";
drhe05461c2015-12-30 13:36:57 +00001204 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
mistachkin151c75a2015-04-07 21:16:40 +00001205 }
mistachkinaae280e2015-12-31 19:06:24 +00001206 raw_printf(p->out,")");
mistachkin151c75a2015-04-07 21:16:40 +00001207 }
mistachkinaae280e2015-12-31 19:06:24 +00001208 raw_printf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001209 for(i=0; i<nArg; i++){
1210 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001211 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
mistachkinaae280e2015-12-31 19:06:24 +00001212 utf8_printf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001213 }else if( aiType && aiType[i]==SQLITE_TEXT ){
mistachkinaae280e2015-12-31 19:06:24 +00001214 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shanead6b8d02009-10-22 18:12:58 +00001215 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001216 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1217 || aiType[i]==SQLITE_FLOAT) ){
drhe05461c2015-12-30 13:36:57 +00001218 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001219 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1220 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1221 int nBlob = sqlite3_column_bytes(p->pStmt, i);
mistachkinaae280e2015-12-31 19:06:24 +00001222 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shane626a6e42009-10-22 17:30:15 +00001223 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001224 }else if( isNumber(azArg[i], 0) ){
drhe05461c2015-12-30 13:36:57 +00001225 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
drh28bd4bc2000-06-15 15:57:22 +00001226 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001227 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
drh28bd4bc2000-06-15 15:57:22 +00001228 output_quoted_string(p->out, azArg[i]);
1229 }
1230 }
mistachkinaae280e2015-12-31 19:06:24 +00001231 raw_printf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001232 break;
drh28bd4bc2000-06-15 15:57:22 +00001233 }
mistachkin636bf9f2014-07-19 20:15:16 +00001234 case MODE_Ascii: {
1235 if( p->cnt++==0 && p->showHeader ){
1236 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001237 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1238 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +00001239 }
drhe05461c2015-12-30 13:36:57 +00001240 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001241 }
1242 if( azArg==0 ) break;
1243 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001244 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1245 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001246 }
drhe05461c2015-12-30 13:36:57 +00001247 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001248 break;
1249 }
persicom1d0b8722002-04-18 02:53:04 +00001250 }
drh75897232000-05-29 14:26:00 +00001251 return 0;
1252}
1253
1254/*
shane626a6e42009-10-22 17:30:15 +00001255** This is the callback routine that the SQLite library
1256** invokes for each row of a query result.
1257*/
1258static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1259 /* since we don't have type info, call the shell_callback with a NULL value */
1260 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1261}
1262
1263/*
drhdcd87a92014-08-18 13:45:42 +00001264** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001265** the name of the table given. Escape any quote characters in the
1266** table name.
1267*/
drhdcd87a92014-08-18 13:45:42 +00001268static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001269 int i, n;
1270 int needQuote;
1271 char *z;
1272
1273 if( p->zDestTable ){
1274 free(p->zDestTable);
1275 p->zDestTable = 0;
1276 }
1277 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001278 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001279 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001280 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001281 needQuote = 1;
1282 if( zName[i]=='\'' ) n++;
1283 }
1284 }
1285 if( needQuote ) n += 2;
1286 z = p->zDestTable = malloc( n+1 );
1287 if( z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001288 raw_printf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001289 exit(1);
1290 }
1291 n = 0;
1292 if( needQuote ) z[n++] = '\'';
1293 for(i=0; zName[i]; i++){
1294 z[n++] = zName[i];
1295 if( zName[i]=='\'' ) z[n++] = '\'';
1296 }
1297 if( needQuote ) z[n++] = '\'';
1298 z[n] = 0;
1299}
1300
danielk19772a02e332004-06-05 08:04:36 +00001301/* zIn is either a pointer to a NULL-terminated string in memory obtained
1302** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1303** added to zIn, and the result returned in memory obtained from malloc().
1304** zIn, if it was not NULL, is freed.
1305**
mistachkin1fe36bb2016-04-04 02:16:44 +00001306** If the third argument, quote, is not '\0', then it is used as a
danielk19772a02e332004-06-05 08:04:36 +00001307** quote character for zAppend.
1308*/
drhc28490c2006-10-26 14:25:58 +00001309static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001310 int len;
1311 int i;
drh4f21c4a2008-12-10 22:15:00 +00001312 int nAppend = strlen30(zAppend);
1313 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001314
1315 len = nAppend+nIn+1;
1316 if( quote ){
1317 len += 2;
1318 for(i=0; i<nAppend; i++){
1319 if( zAppend[i]==quote ) len++;
1320 }
1321 }
1322
1323 zIn = (char *)realloc(zIn, len);
1324 if( !zIn ){
1325 return 0;
1326 }
1327
1328 if( quote ){
1329 char *zCsr = &zIn[nIn];
1330 *zCsr++ = quote;
1331 for(i=0; i<nAppend; i++){
1332 *zCsr++ = zAppend[i];
1333 if( zAppend[i]==quote ) *zCsr++ = quote;
1334 }
1335 *zCsr++ = quote;
1336 *zCsr++ = '\0';
1337 assert( (zCsr-zIn)==len );
1338 }else{
1339 memcpy(&zIn[nIn], zAppend, nAppend);
1340 zIn[len-1] = '\0';
1341 }
1342
1343 return zIn;
1344}
1345
drhdd3d4592004-08-30 01:54:05 +00001346
1347/*
drhb21a8e42012-01-28 21:08:51 +00001348** Execute a query statement that will generate SQL output. Print
1349** the result columns, comma-separated, on a line and then add a
1350** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001351**
drhb21a8e42012-01-28 21:08:51 +00001352** If the number of columns is 1 and that column contains text "--"
mistachkin1fe36bb2016-04-04 02:16:44 +00001353** then write the semicolon on a separate line. That way, if a
drhb21a8e42012-01-28 21:08:51 +00001354** "--" comment occurs at the end of the statement, the comment
1355** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001356*/
drh157e29a2009-05-21 15:15:00 +00001357static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001358 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001359 const char *zSelect, /* SELECT statement to extract content */
1360 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001361){
drhdd3d4592004-08-30 01:54:05 +00001362 sqlite3_stmt *pSelect;
1363 int rc;
drhb21a8e42012-01-28 21:08:51 +00001364 int nResult;
1365 int i;
1366 const char *z;
drhc7181902014-02-27 15:04:13 +00001367 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001368 if( rc!=SQLITE_OK || !pSelect ){
mistachkinaae280e2015-12-31 19:06:24 +00001369 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1370 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001371 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001372 return rc;
1373 }
1374 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001375 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001376 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001377 if( zFirstRow ){
drhe05461c2015-12-30 13:36:57 +00001378 utf8_printf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001379 zFirstRow = 0;
1380 }
drhb21a8e42012-01-28 21:08:51 +00001381 z = (const char*)sqlite3_column_text(pSelect, 0);
drhe05461c2015-12-30 13:36:57 +00001382 utf8_printf(p->out, "%s", z);
mistachkin1fe36bb2016-04-04 02:16:44 +00001383 for(i=1; i<nResult; i++){
drhe05461c2015-12-30 13:36:57 +00001384 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
drhb21a8e42012-01-28 21:08:51 +00001385 }
1386 if( z==0 ) z = "";
1387 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1388 if( z[0] ){
mistachkinaae280e2015-12-31 19:06:24 +00001389 raw_printf(p->out, "\n;\n");
drhb21a8e42012-01-28 21:08:51 +00001390 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001391 raw_printf(p->out, ";\n");
mistachkin1fe36bb2016-04-04 02:16:44 +00001392 }
drhdd3d4592004-08-30 01:54:05 +00001393 rc = sqlite3_step(pSelect);
1394 }
drh2f464a02011-10-13 00:41:49 +00001395 rc = sqlite3_finalize(pSelect);
1396 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00001397 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1398 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001399 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001400 }
1401 return rc;
drhdd3d4592004-08-30 01:54:05 +00001402}
1403
shane626a6e42009-10-22 17:30:15 +00001404/*
1405** Allocate space and save off current error string.
1406*/
1407static char *save_err_msg(
1408 sqlite3 *db /* Database to query */
1409){
1410 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001411 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001412 if( zErrMsg ){
1413 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1414 }
1415 return zErrMsg;
1416}
1417
drh34784902016-02-27 17:12:36 +00001418#ifdef __linux__
1419/*
1420** Attempt to display I/O stats on Linux using /proc/PID/io
1421*/
1422static void displayLinuxIoStats(FILE *out){
1423 FILE *in;
1424 char z[200];
1425 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
1426 in = fopen(z, "rb");
1427 if( in==0 ) return;
1428 while( fgets(z, sizeof(z), in)!=0 ){
1429 static const struct {
1430 const char *zPattern;
1431 const char *zDesc;
1432 } aTrans[] = {
drhfc1a84c2016-02-27 19:19:22 +00001433 { "rchar: ", "Bytes received by read():" },
1434 { "wchar: ", "Bytes sent to write():" },
1435 { "syscr: ", "Read() system calls:" },
1436 { "syscw: ", "Write() system calls:" },
1437 { "read_bytes: ", "Bytes read from storage:" },
1438 { "write_bytes: ", "Bytes written to storage:" },
1439 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
drh34784902016-02-27 17:12:36 +00001440 };
1441 int i;
1442 for(i=0; i<ArraySize(aTrans); i++){
1443 int n = (int)strlen(aTrans[i].zPattern);
1444 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
1445 raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
1446 break;
1447 }
1448 }
1449 }
1450 fclose(in);
mistachkin1fe36bb2016-04-04 02:16:44 +00001451}
drh34784902016-02-27 17:12:36 +00001452#endif
1453
1454
shane626a6e42009-10-22 17:30:15 +00001455/*
shaneh642d8b82010-07-28 16:05:34 +00001456** Display memory stats.
1457*/
1458static int display_stats(
1459 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001460 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001461 int bReset /* True to reset the stats */
1462){
1463 int iCur;
1464 int iHiwtr;
1465
1466 if( pArg && pArg->out ){
mistachkin1fe36bb2016-04-04 02:16:44 +00001467
shaneh642d8b82010-07-28 16:05:34 +00001468 iHiwtr = iCur = -1;
1469 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001470 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001471 "Memory Used: %d (max %d) bytes\n",
1472 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001473 iHiwtr = iCur = -1;
1474 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001475 raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001476 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001477 if( pArg->shellFlgs & SHFLG_Pagecache ){
1478 iHiwtr = iCur = -1;
1479 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001480 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001481 "Number of Pcache Pages Used: %d (max %d) pages\n",
1482 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001483 }
shaneh642d8b82010-07-28 16:05:34 +00001484 iHiwtr = iCur = -1;
1485 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001486 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001487 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1488 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001489 if( pArg->shellFlgs & SHFLG_Scratch ){
1490 iHiwtr = iCur = -1;
1491 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001492 raw_printf(pArg->out,
1493 "Number of Scratch Allocations Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001494 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001495 }
shaneh642d8b82010-07-28 16:05:34 +00001496 iHiwtr = iCur = -1;
1497 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001498 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001499 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1500 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001501 iHiwtr = iCur = -1;
1502 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001503 raw_printf(pArg->out, "Largest Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001504 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001505 iHiwtr = iCur = -1;
1506 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001507 raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001508 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001509 iHiwtr = iCur = -1;
1510 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001511 raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001512 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001513#ifdef YYTRACKMAXSTACKDEPTH
1514 iHiwtr = iCur = -1;
1515 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001516 raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001517 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001518#endif
1519 }
1520
1521 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001522 if( pArg->shellFlgs & SHFLG_Lookaside ){
1523 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001524 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1525 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001526 raw_printf(pArg->out,
1527 "Lookaside Slots Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001528 iCur, iHiwtr);
1529 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1530 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001531 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
1532 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001533 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1534 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001535 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
1536 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001537 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1538 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001539 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
1540 iHiwtr);
drh44dec872014-08-30 15:49:25 +00001541 }
shaneh642d8b82010-07-28 16:05:34 +00001542 iHiwtr = iCur = -1;
1543 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001544 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
1545 iCur);
drh4ace5362014-11-10 14:42:28 +00001546 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001547 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001548 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
drhc78e6e42011-09-23 18:58:23 +00001549 iHiwtr = iCur = -1;
1550 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001551 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001552 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001553 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001554 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
drhfbbcd5d2012-03-24 20:09:33 +00001555 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001556 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001557 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001558 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001559 iHiwtr = iCur = -1;
1560 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001561 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001562 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001563 }
1564
1565 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001566 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1567 bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001568 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001569 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001570 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001571 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001572 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001573 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001574 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001575 }
1576
drh34784902016-02-27 17:12:36 +00001577#ifdef __linux__
1578 displayLinuxIoStats(pArg->out);
1579#endif
1580
dan5a790282015-08-07 20:06:14 +00001581 /* Do not remove this machine readable comment: extra-stats-output-here */
1582
shaneh642d8b82010-07-28 16:05:34 +00001583 return 0;
1584}
1585
1586/*
dan8d1edb92014-11-05 09:07:28 +00001587** Display scan stats.
1588*/
1589static void display_scanstats(
1590 sqlite3 *db, /* Database to query */
1591 ShellState *pArg /* Pointer to ShellState */
1592){
drhf5ed7ad2015-06-15 14:43:25 +00001593#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1594 UNUSED_PARAMETER(db);
1595 UNUSED_PARAMETER(pArg);
1596#else
drh15f23c22014-11-06 12:46:16 +00001597 int i, k, n, mx;
mistachkinaae280e2015-12-31 19:06:24 +00001598 raw_printf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001599 mx = 0;
1600 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001601 double rEstLoop = 1.0;
1602 for(i=n=0; 1; i++){
1603 sqlite3_stmt *p = pArg->pStmt;
1604 sqlite3_int64 nLoop, nVisit;
1605 double rEst;
1606 int iSid;
1607 const char *zExplain;
1608 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1609 break;
1610 }
1611 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001612 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001613 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001614 if( n==0 ){
1615 rEstLoop = (double)nLoop;
mistachkinaae280e2015-12-31 19:06:24 +00001616 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001617 }
drh42f30bc2014-11-06 12:08:21 +00001618 n++;
1619 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1620 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1621 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
drhe05461c2015-12-30 13:36:57 +00001622 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
drh42f30bc2014-11-06 12:08:21 +00001623 rEstLoop *= rEst;
mistachkin1fe36bb2016-04-04 02:16:44 +00001624 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001625 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001626 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001627 );
dan8d1edb92014-11-05 09:07:28 +00001628 }
dan8d1edb92014-11-05 09:07:28 +00001629 }
mistachkinaae280e2015-12-31 19:06:24 +00001630 raw_printf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001631#endif
dan8d1edb92014-11-05 09:07:28 +00001632}
1633
1634/*
dana98bf362013-11-13 18:35:01 +00001635** Parameter azArray points to a zero-terminated array of strings. zStr
1636** points to a single nul-terminated string. Return non-zero if zStr
1637** is equal, according to strcmp(), to any of the strings in the array.
1638** Otherwise, return zero.
1639*/
1640static int str_in_array(const char *zStr, const char **azArray){
1641 int i;
1642 for(i=0; azArray[i]; i++){
1643 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1644 }
1645 return 0;
1646}
1647
1648/*
1649** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001650** and populate the ShellState.aiIndent[] array with the number of
mistachkin1fe36bb2016-04-04 02:16:44 +00001651** spaces each opcode should be indented before it is output.
dana98bf362013-11-13 18:35:01 +00001652**
1653** The indenting rules are:
1654**
1655** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1656** all opcodes that occur between the p2 jump destination and the opcode
1657** itself by 2 spaces.
1658**
drh01752bc2013-11-14 23:59:33 +00001659** * For each "Goto", if the jump destination is earlier in the program
1660** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001661** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001662** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001663** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001664** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001665*/
drhdcd87a92014-08-18 13:45:42 +00001666static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001667 const char *zSql; /* The text of the SQL statement */
1668 const char *z; /* Used to check if this is an EXPLAIN */
1669 int *abYield = 0; /* True if op is an OP_Yield */
1670 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001671 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001672
drh8ad0de32014-03-20 18:45:27 +00001673 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1674 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001675 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1676 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001677 const char *azGoto[] = { "Goto", 0 };
1678
1679 /* Try to figure out if this is really an EXPLAIN statement. If this
1680 ** cannot be verified, return early. */
drh87a24aa2016-02-09 20:04:07 +00001681 if( sqlite3_column_count(pSql)!=8 ){
1682 p->cMode = p->mode;
1683 return;
1684 }
dana98bf362013-11-13 18:35:01 +00001685 zSql = sqlite3_sql(pSql);
1686 if( zSql==0 ) return;
1687 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
drh87a24aa2016-02-09 20:04:07 +00001688 if( sqlite3_strnicmp(z, "explain", 7) ){
1689 p->cMode = p->mode;
1690 return;
1691 }
dana98bf362013-11-13 18:35:01 +00001692
1693 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1694 int i;
danc4650bb2013-11-18 08:41:06 +00001695 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001696 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001697
1698 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1699 ** p2 is an instruction address, set variable p2op to the index of that
1700 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1701 ** the current instruction is part of a sub-program generated by an
1702 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001703 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001704 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001705
1706 /* Grow the p->aiIndent array as required */
1707 if( iOp>=nAlloc ){
drh87a24aa2016-02-09 20:04:07 +00001708 if( iOp==0 ){
1709 /* Do further verfication that this is explain output. Abort if
1710 ** it is not */
1711 static const char *explainCols[] = {
1712 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
1713 int jj;
1714 for(jj=0; jj<ArraySize(explainCols); jj++){
1715 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
1716 p->cMode = p->mode;
1717 sqlite3_reset(pSql);
1718 return;
1719 }
1720 }
1721 }
dana98bf362013-11-13 18:35:01 +00001722 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001723 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1724 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001725 }
1726 abYield[iOp] = str_in_array(zOp, azYield);
1727 p->aiIndent[iOp] = 0;
1728 p->nIndent = iOp+1;
1729
1730 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001731 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001732 }
drhfe705102014-03-06 13:38:37 +00001733 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1734 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1735 ){
drheacd29d2016-04-15 15:03:27 +00001736 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001737 }
1738 }
1739
danc4650bb2013-11-18 08:41:06 +00001740 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001741 sqlite3_free(abYield);
1742 sqlite3_reset(pSql);
1743}
1744
1745/*
1746** Free the array allocated by explain_data_prepare().
1747*/
drhdcd87a92014-08-18 13:45:42 +00001748static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001749 sqlite3_free(p->aiIndent);
1750 p->aiIndent = 0;
1751 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001752 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001753}
1754
1755/*
drheacd29d2016-04-15 15:03:27 +00001756** Disable and restore .wheretrace and .selecttrace settings.
1757*/
1758#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1759extern int sqlite3SelectTrace;
1760static int savedSelectTrace;
1761#endif
1762#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1763extern int sqlite3WhereTrace;
1764static int savedWhereTrace;
1765#endif
1766static void disable_debug_trace_modes(void){
1767#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1768 savedSelectTrace = sqlite3SelectTrace;
1769 sqlite3SelectTrace = 0;
1770#endif
1771#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1772 savedWhereTrace = sqlite3WhereTrace;
1773 sqlite3WhereTrace = 0;
1774#endif
1775}
1776static void restore_debug_trace_modes(void){
1777#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1778 sqlite3SelectTrace = savedSelectTrace;
1779#endif
1780#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1781 sqlite3WhereTrace = savedWhereTrace;
1782#endif
1783}
1784
1785/*
1786** Run a prepared statement
1787*/
1788static void exec_prepared_stmt(
1789 ShellState *pArg, /* Pointer to ShellState */
1790 sqlite3_stmt *pStmt, /* Statment to run */
1791 int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
1792){
1793 int rc;
1794
1795 /* perform the first step. this will tell us if we
1796 ** have a result set or not and how wide it is.
1797 */
1798 rc = sqlite3_step(pStmt);
1799 /* if we have a result set... */
1800 if( SQLITE_ROW == rc ){
1801 /* if we have a callback... */
1802 if( xCallback ){
1803 /* allocate space for col name ptr, value ptr, and type */
1804 int nCol = sqlite3_column_count(pStmt);
1805 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
1806 if( !pData ){
1807 rc = SQLITE_NOMEM;
1808 }else{
1809 char **azCols = (char **)pData; /* Names of result columns */
1810 char **azVals = &azCols[nCol]; /* Results */
1811 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1812 int i, x;
1813 assert(sizeof(int) <= sizeof(char *));
1814 /* save off ptrs to column names */
1815 for(i=0; i<nCol; i++){
1816 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1817 }
1818 do{
1819 /* extract the data and data types */
1820 for(i=0; i<nCol; i++){
1821 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1822 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
1823 azVals[i] = "";
1824 }else{
1825 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1826 }
1827 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1828 rc = SQLITE_NOMEM;
1829 break; /* from for */
1830 }
1831 } /* end for */
1832
1833 /* if data and types extracted successfully... */
1834 if( SQLITE_ROW == rc ){
1835 /* call the supplied callback with the result row data */
1836 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1837 rc = SQLITE_ABORT;
1838 }else{
1839 rc = sqlite3_step(pStmt);
1840 }
1841 }
1842 } while( SQLITE_ROW == rc );
1843 sqlite3_free(pData);
1844 }
1845 }else{
1846 do{
1847 rc = sqlite3_step(pStmt);
1848 } while( rc == SQLITE_ROW );
1849 }
1850 }
1851}
1852
1853/*
mistachkin1fe36bb2016-04-04 02:16:44 +00001854** Execute a statement or set of statements. Print
1855** any result rows/columns depending on the current mode
shane626a6e42009-10-22 17:30:15 +00001856** set via the supplied callback.
1857**
mistachkin1fe36bb2016-04-04 02:16:44 +00001858** This is very similar to SQLite's built-in sqlite3_exec()
1859** function except it takes a slightly different callback
shane626a6e42009-10-22 17:30:15 +00001860** and callback data argument.
1861*/
1862static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001863 sqlite3 *db, /* An open database */
1864 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001865 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001866 /* (not the same as sqlite3_exec) */
1867 ShellState *pArg, /* Pointer to ShellState */
1868 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001869){
dan4564ced2010-01-05 04:59:56 +00001870 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1871 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001872 int rc2;
dan4564ced2010-01-05 04:59:56 +00001873 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001874
1875 if( pzErrMsg ){
1876 *pzErrMsg = NULL;
1877 }
1878
shaneb9fc17d2009-10-22 21:23:35 +00001879 while( zSql[0] && (SQLITE_OK == rc) ){
drheacd29d2016-04-15 15:03:27 +00001880 static const char *zStmtSql;
shaneb9fc17d2009-10-22 21:23:35 +00001881 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1882 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001883 if( pzErrMsg ){
1884 *pzErrMsg = save_err_msg(db);
1885 }
1886 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001887 if( !pStmt ){
1888 /* this happens for a comment or white-space */
1889 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001890 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001891 continue;
1892 }
drheacd29d2016-04-15 15:03:27 +00001893 zStmtSql = sqlite3_sql(pStmt);
1894 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
shane626a6e42009-10-22 17:30:15 +00001895
shaneh642d8b82010-07-28 16:05:34 +00001896 /* save off the prepared statment handle and reset row count */
1897 if( pArg ){
1898 pArg->pStmt = pStmt;
1899 pArg->cnt = 0;
1900 }
1901
shanehb7977c52010-01-18 18:17:10 +00001902 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001903 if( pArg && pArg->echoOn ){
drhe05461c2015-12-30 13:36:57 +00001904 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001905 }
shanehb7977c52010-01-18 18:17:10 +00001906
drhefbf3b12014-02-28 20:47:24 +00001907 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
drheacd29d2016-04-15 15:03:27 +00001908 if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
drhefbf3b12014-02-28 20:47:24 +00001909 sqlite3_stmt *pExplain;
drheacd29d2016-04-15 15:03:27 +00001910 char *zEQP;
1911 disable_debug_trace_modes();
1912 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
drhefbf3b12014-02-28 20:47:24 +00001913 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1914 if( rc==SQLITE_OK ){
1915 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001916 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1917 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1918 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001919 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001920 }
1921 }
1922 sqlite3_finalize(pExplain);
1923 sqlite3_free(zEQP);
drheacd29d2016-04-15 15:03:27 +00001924 if( pArg->autoEQP>=2 ){
1925 /* Also do an EXPLAIN for ".eqp full" mode */
1926 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
1927 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1928 if( rc==SQLITE_OK ){
1929 pArg->cMode = MODE_Explain;
1930 explain_data_prepare(pArg, pExplain);
1931 exec_prepared_stmt(pArg, pExplain, xCallback);
1932 explain_data_delete(pArg);
1933 }
1934 sqlite3_finalize(pExplain);
1935 sqlite3_free(zEQP);
1936 }
1937 restore_debug_trace_modes();
drhefbf3b12014-02-28 20:47:24 +00001938 }
1939
drh700c2522016-02-09 18:39:25 +00001940 if( pArg ){
1941 pArg->cMode = pArg->mode;
drh87a24aa2016-02-09 20:04:07 +00001942 if( pArg->autoExplain
1943 && sqlite3_column_count(pStmt)==8
drheacd29d2016-04-15 15:03:27 +00001944 && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
drh700c2522016-02-09 18:39:25 +00001945 ){
1946 pArg->cMode = MODE_Explain;
1947 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001948
drh700c2522016-02-09 18:39:25 +00001949 /* If the shell is currently in ".explain" mode, gather the extra
1950 ** data required to add indents to the output.*/
1951 if( pArg->cMode==MODE_Explain ){
1952 explain_data_prepare(pArg, pStmt);
1953 }
dana98bf362013-11-13 18:35:01 +00001954 }
1955
drheacd29d2016-04-15 15:03:27 +00001956 exec_prepared_stmt(pArg, pStmt, xCallback);
dana98bf362013-11-13 18:35:01 +00001957 explain_data_delete(pArg);
1958
shaneh642d8b82010-07-28 16:05:34 +00001959 /* print usage stats if stats on */
1960 if( pArg && pArg->statsOn ){
1961 display_stats(db, pArg, 0);
1962 }
1963
dan8d1edb92014-11-05 09:07:28 +00001964 /* print loop-counters if required */
1965 if( pArg && pArg->scanstatsOn ){
1966 display_scanstats(db, pArg);
1967 }
1968
mistachkin1fe36bb2016-04-04 02:16:44 +00001969 /* Finalize the statement just executed. If this fails, save a
dan4564ced2010-01-05 04:59:56 +00001970 ** copy of the error message. Otherwise, set zSql to point to the
1971 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001972 rc2 = sqlite3_finalize(pStmt);
1973 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001974 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001975 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001976 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001977 }else if( pzErrMsg ){
1978 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001979 }
shaneh642d8b82010-07-28 16:05:34 +00001980
1981 /* clear saved stmt handle */
1982 if( pArg ){
1983 pArg->pStmt = NULL;
1984 }
shane626a6e42009-10-22 17:30:15 +00001985 }
shaneb9fc17d2009-10-22 21:23:35 +00001986 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001987
1988 return rc;
1989}
1990
drhdd3d4592004-08-30 01:54:05 +00001991
drh33048c02001-10-01 14:29:22 +00001992/*
drh4c653a02000-06-07 01:27:47 +00001993** This is a different callback routine used for dumping the database.
1994** Each row received by this callback consists of a table name,
1995** the table type ("index" or "table") and SQL to create the table.
1996** This routine should print text sufficient to recreate the table.
1997*/
1998static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001999 int rc;
2000 const char *zTable;
2001 const char *zType;
2002 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00002003 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00002004 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00002005
drh902b9ee2008-12-05 17:17:07 +00002006 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00002007 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00002008 zTable = azArg[0];
2009 zType = azArg[1];
2010 zSql = azArg[2];
mistachkin1fe36bb2016-04-04 02:16:44 +00002011
drh00b950d2005-09-11 02:03:03 +00002012 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00002013 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00002014 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002015 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00002016 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
2017 return 0;
drh45e29d82006-11-20 16:21:10 +00002018 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
2019 char *zIns;
2020 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00002021 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00002022 p->writableSchema = 1;
2023 }
2024 zIns = sqlite3_mprintf(
2025 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
2026 "VALUES('table','%q','%q',0,'%q');",
2027 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00002028 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00002029 sqlite3_free(zIns);
2030 return 0;
drh00b950d2005-09-11 02:03:03 +00002031 }else{
drhe05461c2015-12-30 13:36:57 +00002032 utf8_printf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00002033 }
danielk19772a02e332004-06-05 08:04:36 +00002034
2035 if( strcmp(zType, "table")==0 ){
2036 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00002037 char *zSelect = 0;
2038 char *zTableInfo = 0;
2039 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00002040 int nRow = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +00002041
danielk19772a02e332004-06-05 08:04:36 +00002042 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
2043 zTableInfo = appendText(zTableInfo, zTable, '"');
2044 zTableInfo = appendText(zTableInfo, ");", 0);
2045
drhc7181902014-02-27 15:04:13 +00002046 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00002047 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00002048 if( rc!=SQLITE_OK || !pTableInfo ){
2049 return 1;
2050 }
2051
2052 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00002053 /* Always quote the table name, even if it appears to be pure ascii,
2054 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
2055 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00002056 if( zTmp ){
2057 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00002058 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00002059 }
2060 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
2061 rc = sqlite3_step(pTableInfo);
2062 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00002063 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00002064 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00002065 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00002066 rc = sqlite3_step(pTableInfo);
2067 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00002068 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00002069 }else{
2070 zSelect = appendText(zSelect, ") ", 0);
2071 }
drh157e29a2009-05-21 15:15:00 +00002072 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00002073 }
2074 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00002075 if( rc!=SQLITE_OK || nRow==0 ){
2076 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00002077 return 1;
2078 }
2079 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
2080 zSelect = appendText(zSelect, zTable, '"');
2081
drh2f464a02011-10-13 00:41:49 +00002082 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00002083 if( rc==SQLITE_CORRUPT ){
2084 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00002085 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00002086 }
drh85e72432012-04-11 11:38:53 +00002087 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00002088 }
drh4c653a02000-06-07 01:27:47 +00002089 return 0;
2090}
2091
2092/*
drh45e29d82006-11-20 16:21:10 +00002093** Run zQuery. Use dump_callback() as the callback routine so that
2094** the contents of the query are output as SQL statements.
2095**
drhdd3d4592004-08-30 01:54:05 +00002096** If we get a SQLITE_CORRUPT error, rerun the query after appending
2097** "ORDER BY rowid DESC" to the end.
2098*/
2099static int run_schema_dump_query(
mistachkin1fe36bb2016-04-04 02:16:44 +00002100 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00002101 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00002102){
2103 int rc;
drh2f464a02011-10-13 00:41:49 +00002104 char *zErr = 0;
2105 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00002106 if( rc==SQLITE_CORRUPT ){
2107 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00002108 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00002109 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00002110 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00002111 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002112 sqlite3_free(zErr);
2113 zErr = 0;
2114 }
drhdd3d4592004-08-30 01:54:05 +00002115 zQ2 = malloc( len+100 );
2116 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00002117 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00002118 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
2119 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002120 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002121 }else{
2122 rc = SQLITE_CORRUPT;
2123 }
2124 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00002125 free(zQ2);
2126 }
2127 return rc;
2128}
2129
2130/*
drh75897232000-05-29 14:26:00 +00002131** Text of a help message
2132*/
persicom1d0b8722002-04-18 02:53:04 +00002133static char zHelp[] =
drhde613c62016-04-04 17:23:10 +00002134 ".auth ON|OFF Show authorizer callbacks\n"
drh9ff849f2009-02-04 20:55:57 +00002135 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00002136 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00002137 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00002138 ".changes on|off Show number of rows changed by SQL\n"
drh4bbcf102014-02-06 02:46:08 +00002139 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00002140 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00002141 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00002142 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00002143 " If TABLE specified, only dump tables matching\n"
2144 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00002145 ".echo on|off Turn command echo on or off\n"
drheacd29d2016-04-15 15:03:27 +00002146 ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00002147 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00002148 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drh4926fec2016-04-13 15:33:42 +00002149 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00002150 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00002151 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00002152 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00002153 ".indexes ?TABLE? Show names of all indexes\n"
2154 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00002155 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00002156#ifdef SQLITE_ENABLE_IOTRACE
2157 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
2158#endif
drh1a513372015-05-02 17:40:23 +00002159 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00002160#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002161 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00002162#endif
drh127f9d72010-02-23 01:47:00 +00002163 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00002164 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00002165 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00002166 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00002167 " column Left-aligned columns. (See .width)\n"
2168 " html HTML <table> code\n"
2169 " insert SQL insert statements for TABLE\n"
2170 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00002171 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00002172 " tabs Tab-separated values\n"
2173 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00002174 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00002175 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00002176 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00002177 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00002178 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002179 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002180 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00002181 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00002182 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00002183 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00002184 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh4926fec2016-04-13 15:33:42 +00002185 ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
2186 " Add --indent for pretty-printing\n"
mistachkine0d68852014-12-11 03:12:33 +00002187 ".separator COL ?ROW? Change the column separator and optionally the row\n"
2188 " separator for both the output mode and .import\n"
drhe6229612014-08-18 15:08:26 +00002189#if defined(SQLITE_ENABLE_SESSION)
2190 ".session CMD ... Create or control sessions\n"
2191#endif
drh62cdde52014-05-28 20:22:28 +00002192 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00002193 ".show Show the current values for various settings\n"
drh34784902016-02-27 17:12:36 +00002194 ".stats ?on|off? Show stats or turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00002195 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00002196 ".tables ?TABLE? List names of tables\n"
2197 " If TABLE specified, only list tables matching\n"
2198 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00002199 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00002200 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00002201 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00002202 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00002203 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00002204 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00002205 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00002206 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00002207;
2208
drhe6229612014-08-18 15:08:26 +00002209#if defined(SQLITE_ENABLE_SESSION)
2210/*
2211** Print help information for the ".sessions" command
2212*/
2213void session_help(ShellState *p){
mistachkin899c5c92016-04-03 20:50:02 +00002214 raw_printf(p->out,
drhe6229612014-08-18 15:08:26 +00002215 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
2216 "If ?NAME? is omitted, the first defined session is used.\n"
2217 "Subcommands:\n"
2218 " attach TABLE Attach TABLE\n"
2219 " changeset FILE Write a changeset into FILE\n"
2220 " close Close one session\n"
2221 " enable ?BOOLEAN? Set or query the enable bit\n"
mistachkin1fe36bb2016-04-04 02:16:44 +00002222 " filter GLOB... Reject tables matching GLOBs\n"
drhe6229612014-08-18 15:08:26 +00002223 " indirect ?BOOLEAN? Mark or query the indirect status\n"
2224 " isempty Query whether the session is empty\n"
2225 " list List currently open session names\n"
2226 " open DB NAME Open a new session on DB\n"
2227 " patchset FILE Write a patchset into FILE\n"
2228 );
2229}
2230#endif
2231
2232
drhdaffd0e2001-04-11 14:28:42 +00002233/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00002234static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00002235/*
2236** Implementation of the "readfile(X)" SQL function. The entire content
2237** of the file named X is read and returned as a BLOB. NULL is returned
2238** if the file does not exist or is unreadable.
2239*/
2240static void readfileFunc(
2241 sqlite3_context *context,
2242 int argc,
2243 sqlite3_value **argv
2244){
2245 const char *zName;
2246 FILE *in;
2247 long nIn;
2248 void *pBuf;
2249
drhf5ed7ad2015-06-15 14:43:25 +00002250 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002251 zName = (const char*)sqlite3_value_text(argv[0]);
2252 if( zName==0 ) return;
2253 in = fopen(zName, "rb");
2254 if( in==0 ) return;
2255 fseek(in, 0, SEEK_END);
2256 nIn = ftell(in);
2257 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00002258 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00002259 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
2260 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
2261 }else{
2262 sqlite3_free(pBuf);
2263 }
2264 fclose(in);
2265}
2266
2267/*
2268** Implementation of the "writefile(X,Y)" SQL function. The argument Y
2269** is written into file X. The number of bytes written is returned. Or
2270** NULL is returned if something goes wrong, such as being unable to open
2271** file X for writing.
2272*/
2273static void writefileFunc(
2274 sqlite3_context *context,
2275 int argc,
2276 sqlite3_value **argv
2277){
2278 FILE *out;
2279 const char *z;
drhba5b0932014-07-24 12:39:59 +00002280 sqlite3_int64 rc;
2281 const char *zFile;
2282
drhf5ed7ad2015-06-15 14:43:25 +00002283 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002284 zFile = (const char*)sqlite3_value_text(argv[0]);
2285 if( zFile==0 ) return;
2286 out = fopen(zFile, "wb");
2287 if( out==0 ) return;
2288 z = (const char*)sqlite3_value_blob(argv[1]);
2289 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002290 rc = 0;
2291 }else{
drh490fe862014-08-11 14:21:32 +00002292 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002293 }
2294 fclose(out);
2295 sqlite3_result_int64(context, rc);
2296}
drhdaffd0e2001-04-11 14:28:42 +00002297
drhe6229612014-08-18 15:08:26 +00002298#if defined(SQLITE_ENABLE_SESSION)
2299/*
2300** Close a single OpenSession object and release all of its associated
2301** resources.
2302*/
2303static void session_close(OpenSession *pSession){
2304 int i;
2305 sqlite3session_delete(pSession->p);
2306 sqlite3_free(pSession->zName);
2307 for(i=0; i<pSession->nFilter; i++){
2308 sqlite3_free(pSession->azFilter[i]);
2309 }
2310 sqlite3_free(pSession->azFilter);
2311 memset(pSession, 0, sizeof(OpenSession));
2312}
2313#endif
2314
2315/*
drh51b55a32016-04-04 12:38:05 +00002316** Close all OpenSession objects and release all associated resources.
drhe6229612014-08-18 15:08:26 +00002317*/
drhe6229612014-08-18 15:08:26 +00002318#if defined(SQLITE_ENABLE_SESSION)
drh51b55a32016-04-04 12:38:05 +00002319static void session_close_all(ShellState *p){
drhe6229612014-08-18 15:08:26 +00002320 int i;
2321 for(i=0; i<p->nSession; i++){
2322 session_close(&p->aSession[i]);
2323 }
2324 p->nSession = 0;
drhe6229612014-08-18 15:08:26 +00002325}
drh51b55a32016-04-04 12:38:05 +00002326#else
2327# define session_close_all(X)
2328#endif
drhe6229612014-08-18 15:08:26 +00002329
drh75897232000-05-29 14:26:00 +00002330/*
drh03168ca2014-08-18 20:01:31 +00002331** Implementation of the xFilter function for an open session. Omit
2332** any tables named by ".session filter" but let all other table through.
2333*/
2334#if defined(SQLITE_ENABLE_SESSION)
2335static int session_filter(void *pCtx, const char *zTab){
2336 OpenSession *pSession = (OpenSession*)pCtx;
2337 int i;
2338 for(i=0; i<pSession->nFilter; i++){
2339 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
2340 }
2341 return 1;
2342}
2343#endif
2344
2345/*
drh44c2eb12003-04-30 11:38:26 +00002346** Make sure the database is open. If it is not, then open it. If
2347** the database fails to open, print an error message and exit.
2348*/
drhdcd87a92014-08-18 13:45:42 +00002349static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002350 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002351 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002352 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002353 globalDb = p->db;
2354 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2355 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002356 shellstaticFunc, 0, 0);
2357 }
mistachkin8e189222015-04-19 21:43:16 +00002358 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00002359 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002360 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002361 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002362 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002363 }
drhc2e87a32006-06-27 15:16:14 +00002364#ifndef SQLITE_OMIT_LOAD_EXTENSION
2365 sqlite3_enable_load_extension(p->db, 1);
2366#endif
mistachkin8e189222015-04-19 21:43:16 +00002367 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002368 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002369 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002370 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002371 }
2372}
2373
2374/*
drhfeac5f82004-08-01 00:10:45 +00002375** Do C-language style dequoting.
2376**
mistachkinf21979d2015-01-18 05:35:01 +00002377** \a -> alarm
2378** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002379** \t -> tab
2380** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002381** \v -> vertical tab
2382** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002383** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002384** \s -> space
drh4c56b992013-06-27 13:26:55 +00002385** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002386** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002387** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002388** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002389*/
2390static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002391 int i, j;
2392 char c;
drhc2ce0be2014-05-29 12:36:14 +00002393 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002394 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002395 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002396 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002397 if( c=='a' ){
2398 c = '\a';
2399 }else if( c=='b' ){
2400 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002401 }else if( c=='t' ){
2402 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002403 }else if( c=='n' ){
2404 c = '\n';
2405 }else if( c=='v' ){
2406 c = '\v';
2407 }else if( c=='f' ){
2408 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002409 }else if( c=='r' ){
2410 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002411 }else if( c=='"' ){
2412 c = '"';
2413 }else if( c=='\'' ){
2414 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002415 }else if( c=='\\' ){
2416 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002417 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002418 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002419 if( z[i+1]>='0' && z[i+1]<='7' ){
2420 i++;
2421 c = (c<<3) + z[i] - '0';
2422 if( z[i+1]>='0' && z[i+1]<='7' ){
2423 i++;
2424 c = (c<<3) + z[i] - '0';
2425 }
2426 }
2427 }
2428 }
2429 z[j] = c;
2430 }
drhc2ce0be2014-05-29 12:36:14 +00002431 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002432}
2433
2434/*
drh348d19c2013-06-03 12:47:43 +00002435** Return the value of a hexadecimal digit. Return -1 if the input
2436** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002437*/
drh348d19c2013-06-03 12:47:43 +00002438static int hexDigitValue(char c){
2439 if( c>='0' && c<='9' ) return c - '0';
2440 if( c>='a' && c<='f' ) return c - 'a' + 10;
2441 if( c>='A' && c<='F' ) return c - 'A' + 10;
2442 return -1;
drhc28490c2006-10-26 14:25:58 +00002443}
2444
2445/*
drh7d9f3942013-04-03 01:26:54 +00002446** Interpret zArg as an integer value, possibly with suffixes.
2447*/
2448static sqlite3_int64 integerValue(const char *zArg){
2449 sqlite3_int64 v = 0;
2450 static const struct { char *zSuffix; int iMult; } aMult[] = {
2451 { "KiB", 1024 },
2452 { "MiB", 1024*1024 },
2453 { "GiB", 1024*1024*1024 },
2454 { "KB", 1000 },
2455 { "MB", 1000000 },
2456 { "GB", 1000000000 },
2457 { "K", 1000 },
2458 { "M", 1000000 },
2459 { "G", 1000000000 },
2460 };
2461 int i;
2462 int isNeg = 0;
2463 if( zArg[0]=='-' ){
2464 isNeg = 1;
2465 zArg++;
2466 }else if( zArg[0]=='+' ){
2467 zArg++;
2468 }
drh348d19c2013-06-03 12:47:43 +00002469 if( zArg[0]=='0' && zArg[1]=='x' ){
2470 int x;
2471 zArg += 2;
2472 while( (x = hexDigitValue(zArg[0]))>=0 ){
2473 v = (v<<4) + x;
2474 zArg++;
2475 }
2476 }else{
2477 while( IsDigit(zArg[0]) ){
2478 v = v*10 + zArg[0] - '0';
2479 zArg++;
2480 }
drh7d9f3942013-04-03 01:26:54 +00002481 }
drhc2bed0a2013-05-24 11:57:50 +00002482 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002483 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2484 v *= aMult[i].iMult;
2485 break;
2486 }
2487 }
2488 return isNeg? -v : v;
2489}
2490
2491/*
drh348d19c2013-06-03 12:47:43 +00002492** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2493** for TRUE and FALSE. Return the integer value if appropriate.
2494*/
2495static int booleanValue(char *zArg){
2496 int i;
2497 if( zArg[0]=='0' && zArg[1]=='x' ){
2498 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2499 }else{
2500 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2501 }
2502 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2503 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2504 return 1;
2505 }
2506 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2507 return 0;
2508 }
mistachkinaae280e2015-12-31 19:06:24 +00002509 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002510 zArg);
2511 return 0;
2512}
2513
2514/*
drh42f64e52012-04-04 16:56:23 +00002515** Close an output file, assuming it is not stderr or stdout
2516*/
2517static void output_file_close(FILE *f){
2518 if( f && f!=stdout && f!=stderr ) fclose(f);
2519}
2520
2521/*
2522** Try to open an output file. The names "stdout" and "stderr" are
mistachkin1fe36bb2016-04-04 02:16:44 +00002523** recognized and do the right thing. NULL is returned if the output
drh42f64e52012-04-04 16:56:23 +00002524** filename is "off".
2525*/
2526static FILE *output_file_open(const char *zFile){
2527 FILE *f;
2528 if( strcmp(zFile,"stdout")==0 ){
2529 f = stdout;
2530 }else if( strcmp(zFile, "stderr")==0 ){
2531 f = stderr;
2532 }else if( strcmp(zFile, "off")==0 ){
2533 f = 0;
2534 }else{
2535 f = fopen(zFile, "wb");
2536 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002537 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002538 }
2539 }
2540 return f;
2541}
2542
2543/*
2544** A routine for handling output from sqlite3_trace().
2545*/
drh4b363a52016-07-23 20:27:41 +00002546static int sql_trace_callback(
2547 unsigned mType,
2548 void *pArg,
2549 void *pP,
2550 void *pX
2551){
drh42f64e52012-04-04 16:56:23 +00002552 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002553 if( f ){
drh4b363a52016-07-23 20:27:41 +00002554 const char *z = (const char*)pX;
drh4b2590e2014-08-19 19:28:00 +00002555 int i = (int)strlen(z);
2556 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002557 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002558 }
drh4b363a52016-07-23 20:27:41 +00002559 return 0;
drh42f64e52012-04-04 16:56:23 +00002560}
2561
2562/*
drhd8621b92012-04-17 09:09:33 +00002563** A no-op routine that runs with the ".breakpoint" doc-command. This is
2564** a useful spot to set a debugger breakpoint.
2565*/
2566static void test_breakpoint(void){
2567 static int nCall = 0;
2568 nCall++;
2569}
2570
2571/*
mistachkin636bf9f2014-07-19 20:15:16 +00002572** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002573*/
mistachkin636bf9f2014-07-19 20:15:16 +00002574typedef struct ImportCtx ImportCtx;
2575struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002576 const char *zFile; /* Name of the input file */
2577 FILE *in; /* Read the CSV text from this input stream */
2578 char *z; /* Accumulated text for a field */
2579 int n; /* Number of bytes in z */
2580 int nAlloc; /* Space allocated for z[] */
2581 int nLine; /* Current line number */
2582 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002583 int cColSep; /* The column separator character. (Usually ",") */
2584 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002585};
2586
2587/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002588static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002589 if( p->n+1>=p->nAlloc ){
2590 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002591 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002592 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002593 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002594 exit(1);
2595 }
2596 }
2597 p->z[p->n++] = (char)c;
2598}
2599
2600/* Read a single field of CSV text. Compatible with rfc4180 and extended
2601** with the option of having a separator other than ",".
2602**
2603** + Input comes from p->in.
2604** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002605** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002606** + Use p->cSep as the column separator. The default is ",".
2607** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002608** + Keep track of the line number in p->nLine.
2609** + Store the character that terminates the field in p->cTerm. Store
2610** EOF on end-of-file.
2611** + Report syntax errors on stderr
2612*/
mistachkin44723ce2015-03-21 02:22:37 +00002613static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002614 int c;
2615 int cSep = p->cColSep;
2616 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002617 p->n = 0;
2618 c = fgetc(p->in);
2619 if( c==EOF || seenInterrupt ){
2620 p->cTerm = EOF;
2621 return 0;
2622 }
2623 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002624 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002625 int startLine = p->nLine;
2626 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002627 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002628 while( 1 ){
2629 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002630 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002631 if( c==cQuote ){
2632 if( pc==cQuote ){
2633 pc = 0;
2634 continue;
2635 }
2636 }
2637 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002638 || (c==rSep && pc==cQuote)
2639 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002640 || (c==EOF && pc==cQuote)
2641 ){
2642 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002643 p->cTerm = c;
2644 break;
2645 }
2646 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002647 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002648 p->zFile, p->nLine, cQuote);
2649 }
2650 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002651 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002652 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002653 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002654 break;
2655 }
mistachkin636bf9f2014-07-19 20:15:16 +00002656 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002657 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002658 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002659 }
drhdb95f682013-06-26 22:46:00 +00002660 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002661 while( c!=EOF && c!=cSep && c!=rSep ){
2662 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002663 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002664 }
mistachkin636bf9f2014-07-19 20:15:16 +00002665 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002666 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002667 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002668 }
drhdb95f682013-06-26 22:46:00 +00002669 p->cTerm = c;
2670 }
drh8dd675e2013-07-12 21:09:24 +00002671 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002672 return p->z;
2673}
2674
mistachkin636bf9f2014-07-19 20:15:16 +00002675/* Read a single field of ASCII delimited text.
2676**
2677** + Input comes from p->in.
2678** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002679** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002680** + Use p->cSep as the column separator. The default is "\x1F".
2681** + Use p->rSep as the row separator. The default is "\x1E".
2682** + Keep track of the row number in p->nLine.
2683** + Store the character that terminates the field in p->cTerm. Store
2684** EOF on end-of-file.
2685** + Report syntax errors on stderr
2686*/
mistachkin44723ce2015-03-21 02:22:37 +00002687static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002688 int c;
2689 int cSep = p->cColSep;
2690 int rSep = p->cRowSep;
2691 p->n = 0;
2692 c = fgetc(p->in);
2693 if( c==EOF || seenInterrupt ){
2694 p->cTerm = EOF;
2695 return 0;
2696 }
2697 while( c!=EOF && c!=cSep && c!=rSep ){
2698 import_append_char(p, c);
2699 c = fgetc(p->in);
2700 }
2701 if( c==rSep ){
2702 p->nLine++;
2703 }
2704 p->cTerm = c;
2705 if( p->z ) p->z[p->n] = 0;
2706 return p->z;
2707}
2708
drhdb95f682013-06-26 22:46:00 +00002709/*
drh4bbcf102014-02-06 02:46:08 +00002710** Try to transfer data for table zTable. If an error is seen while
2711** moving forward, try to go backwards. The backwards movement won't
2712** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002713*/
mistachkine31ae902014-02-06 01:15:29 +00002714static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002715 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002716 sqlite3 *newDb,
2717 const char *zTable
2718){
mistachkin1fe36bb2016-04-04 02:16:44 +00002719 sqlite3_stmt *pQuery = 0;
drh3350ce92014-02-06 00:49:12 +00002720 sqlite3_stmt *pInsert = 0;
2721 char *zQuery = 0;
2722 char *zInsert = 0;
2723 int rc;
2724 int i, j, n;
2725 int nTable = (int)strlen(zTable);
2726 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002727 int cnt = 0;
2728 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002729
2730 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2731 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2732 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002733 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002734 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2735 zQuery);
2736 goto end_data_xfer;
2737 }
2738 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002739 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002740 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002741 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002742 goto end_data_xfer;
2743 }
2744 sqlite3_snprintf(200+nTable,zInsert,
2745 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2746 i = (int)strlen(zInsert);
2747 for(j=1; j<n; j++){
2748 memcpy(zInsert+i, ",?", 2);
2749 i += 2;
2750 }
2751 memcpy(zInsert+i, ");", 3);
2752 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2753 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002754 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002755 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2756 zQuery);
2757 goto end_data_xfer;
2758 }
2759 for(k=0; k<2; k++){
2760 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2761 for(i=0; i<n; i++){
2762 switch( sqlite3_column_type(pQuery, i) ){
2763 case SQLITE_NULL: {
2764 sqlite3_bind_null(pInsert, i+1);
2765 break;
2766 }
2767 case SQLITE_INTEGER: {
2768 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2769 break;
2770 }
2771 case SQLITE_FLOAT: {
2772 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2773 break;
2774 }
2775 case SQLITE_TEXT: {
2776 sqlite3_bind_text(pInsert, i+1,
2777 (const char*)sqlite3_column_text(pQuery,i),
2778 -1, SQLITE_STATIC);
2779 break;
2780 }
2781 case SQLITE_BLOB: {
2782 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2783 sqlite3_column_bytes(pQuery,i),
2784 SQLITE_STATIC);
2785 break;
2786 }
2787 }
2788 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002789 rc = sqlite3_step(pInsert);
2790 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002791 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002792 sqlite3_errmsg(newDb));
2793 }
drh3350ce92014-02-06 00:49:12 +00002794 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002795 cnt++;
2796 if( (cnt%spinRate)==0 ){
2797 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2798 fflush(stdout);
2799 }
drh3350ce92014-02-06 00:49:12 +00002800 } /* End while */
2801 if( rc==SQLITE_DONE ) break;
2802 sqlite3_finalize(pQuery);
2803 sqlite3_free(zQuery);
2804 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2805 zTable);
2806 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2807 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002808 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002809 break;
drh3350ce92014-02-06 00:49:12 +00002810 }
2811 } /* End for(k=0...) */
2812
2813end_data_xfer:
2814 sqlite3_finalize(pQuery);
2815 sqlite3_finalize(pInsert);
2816 sqlite3_free(zQuery);
2817 sqlite3_free(zInsert);
2818}
2819
2820
2821/*
2822** Try to transfer all rows of the schema that match zWhere. For
2823** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002824** If an error is encountered while moving forward through the
2825** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002826*/
mistachkine31ae902014-02-06 01:15:29 +00002827static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002828 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002829 sqlite3 *newDb,
2830 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002831 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002832){
2833 sqlite3_stmt *pQuery = 0;
2834 char *zQuery = 0;
2835 int rc;
2836 const unsigned char *zName;
2837 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002838 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002839
2840 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2841 " WHERE %s", zWhere);
2842 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2843 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002844 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002845 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2846 zQuery);
2847 goto end_schema_xfer;
2848 }
2849 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2850 zName = sqlite3_column_text(pQuery, 0);
2851 zSql = sqlite3_column_text(pQuery, 1);
2852 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002853 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2854 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002855 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002856 sqlite3_free(zErrMsg);
2857 zErrMsg = 0;
2858 }
drh3350ce92014-02-06 00:49:12 +00002859 if( xForEach ){
2860 xForEach(p, newDb, (const char*)zName);
2861 }
2862 printf("done\n");
2863 }
2864 if( rc!=SQLITE_DONE ){
2865 sqlite3_finalize(pQuery);
2866 sqlite3_free(zQuery);
2867 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2868 " WHERE %s ORDER BY rowid DESC", zWhere);
2869 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2870 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002871 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002872 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2873 zQuery);
2874 goto end_schema_xfer;
2875 }
2876 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2877 zName = sqlite3_column_text(pQuery, 0);
2878 zSql = sqlite3_column_text(pQuery, 1);
2879 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002880 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2881 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002882 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002883 sqlite3_free(zErrMsg);
2884 zErrMsg = 0;
2885 }
drh3350ce92014-02-06 00:49:12 +00002886 if( xForEach ){
2887 xForEach(p, newDb, (const char*)zName);
2888 }
2889 printf("done\n");
2890 }
2891 }
2892end_schema_xfer:
2893 sqlite3_finalize(pQuery);
2894 sqlite3_free(zQuery);
2895}
2896
2897/*
2898** Open a new database file named "zNewDb". Try to recover as much information
2899** as possible out of the main database (which might be corrupt) and write it
2900** into zNewDb.
2901*/
drhdcd87a92014-08-18 13:45:42 +00002902static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002903 int rc;
2904 sqlite3 *newDb = 0;
2905 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002906 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002907 return;
2908 }
2909 rc = sqlite3_open(zNewDb, &newDb);
2910 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002911 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002912 sqlite3_errmsg(newDb));
2913 }else{
drh54d0d2d2014-04-03 00:32:13 +00002914 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002915 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002916 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2917 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002918 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002919 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002920 }
2921 sqlite3_close(newDb);
2922}
2923
2924/*
drhc2ce0be2014-05-29 12:36:14 +00002925** Change the output file back to stdout
2926*/
drhdcd87a92014-08-18 13:45:42 +00002927static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002928 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002929#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002930 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002931#endif
drhc2ce0be2014-05-29 12:36:14 +00002932 }else{
2933 output_file_close(p->out);
2934 }
2935 p->outfile[0] = 0;
2936 p->out = stdout;
2937}
2938
2939/*
drhf7502f02015-02-06 14:19:44 +00002940** Run an SQL command and return the single integer result.
2941*/
2942static int db_int(ShellState *p, const char *zSql){
2943 sqlite3_stmt *pStmt;
2944 int res = 0;
2945 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2946 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2947 res = sqlite3_column_int(pStmt,0);
2948 }
2949 sqlite3_finalize(pStmt);
2950 return res;
2951}
2952
2953/*
2954** Convert a 2-byte or 4-byte big-endian integer into a native integer
2955*/
drha0620ac2016-07-13 13:05:13 +00002956static unsigned int get2byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00002957 return (a[0]<<8) + a[1];
2958}
drha0620ac2016-07-13 13:05:13 +00002959static unsigned int get4byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00002960 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2961}
2962
2963/*
2964** Implementation of the ".info" command.
2965**
2966** Return 1 on error, 2 to exit, and 0 otherwise.
2967*/
drh0e55db12015-02-06 14:51:13 +00002968static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002969 static const struct { const char *zName; int ofst; } aField[] = {
2970 { "file change counter:", 24 },
2971 { "database page count:", 28 },
2972 { "freelist page count:", 36 },
2973 { "schema cookie:", 40 },
2974 { "schema format:", 44 },
2975 { "default cache size:", 48 },
2976 { "autovacuum top root:", 52 },
2977 { "incremental vacuum:", 64 },
2978 { "text encoding:", 56 },
2979 { "user version:", 60 },
2980 { "application id:", 68 },
2981 { "software version:", 96 },
2982 };
drh0e55db12015-02-06 14:51:13 +00002983 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2984 { "number of tables:",
2985 "SELECT count(*) FROM %s WHERE type='table'" },
2986 { "number of indexes:",
2987 "SELECT count(*) FROM %s WHERE type='index'" },
2988 { "number of triggers:",
2989 "SELECT count(*) FROM %s WHERE type='trigger'" },
2990 { "number of views:",
2991 "SELECT count(*) FROM %s WHERE type='view'" },
2992 { "schema size:",
2993 "SELECT total(length(sql)) FROM %s" },
2994 };
mistachkinbfe8bd52015-11-17 19:17:14 +00002995 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00002996 int i;
2997 char *zSchemaTab;
2998 char *zDb = nArg>=2 ? azArg[1] : "main";
2999 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00003000 open_db(p, 0);
3001 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00003002 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00003003 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
3004 return 1;
3005 }
3006 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
3007 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003008 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00003009 return 1;
3010 }
3011 i = get2byteInt(aHdr+16);
3012 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00003013 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
3014 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
3015 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
3016 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00003017 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00003018 int ofst = aField[i].ofst;
3019 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00003020 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00003021 switch( ofst ){
3022 case 56: {
mistachkin1fe36bb2016-04-04 02:16:44 +00003023 if( val==1 ) raw_printf(p->out, " (utf8)");
3024 if( val==2 ) raw_printf(p->out, " (utf16le)");
3025 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00003026 }
3027 }
mistachkinaae280e2015-12-31 19:06:24 +00003028 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00003029 }
drh0e55db12015-02-06 14:51:13 +00003030 if( zDb==0 ){
3031 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
3032 }else if( strcmp(zDb,"temp")==0 ){
3033 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
3034 }else{
3035 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
3036 }
drhf5ed7ad2015-06-15 14:43:25 +00003037 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00003038 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
3039 int val = db_int(p, zSql);
3040 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00003041 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00003042 }
3043 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00003044 return 0;
3045}
3046
dand95bb392015-09-30 11:19:05 +00003047/*
3048** Print the current sqlite3_errmsg() value to stderr and return 1.
3049*/
3050static int shellDatabaseError(sqlite3 *db){
3051 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00003052 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00003053 return 1;
3054}
3055
3056/*
3057** Print an out-of-memory message to stderr and return 1.
3058*/
3059static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00003060 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00003061 return 1;
3062}
drhf7502f02015-02-06 14:19:44 +00003063
3064/*
drh4926fec2016-04-13 15:33:42 +00003065** Compare the string as a command-line option with either one or two
3066** initial "-" characters.
3067*/
3068static int optionMatch(const char *zStr, const char *zOpt){
3069 if( zStr[0]!='-' ) return 0;
3070 zStr++;
3071 if( zStr[0]=='-' ) zStr++;
3072 return strcmp(zStr, zOpt)==0;
3073}
3074
3075/*
drh75897232000-05-29 14:26:00 +00003076** If an input line begins with "." then invoke this routine to
3077** process that line.
drh67505e72002-04-19 12:34:06 +00003078**
drh47ad6842006-11-08 12:25:42 +00003079** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00003080*/
drhdcd87a92014-08-18 13:45:42 +00003081static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00003082 int h = 1;
drh75897232000-05-29 14:26:00 +00003083 int nArg = 0;
3084 int n, c;
drh67505e72002-04-19 12:34:06 +00003085 int rc = 0;
drh75897232000-05-29 14:26:00 +00003086 char *azArg[50];
3087
3088 /* Parse the input line into tokens.
3089 */
mistachkin8e189222015-04-19 21:43:16 +00003090 while( zLine[h] && nArg<ArraySize(azArg) ){
3091 while( IsSpace(zLine[h]) ){ h++; }
3092 if( zLine[h]==0 ) break;
3093 if( zLine[h]=='\'' || zLine[h]=='"' ){
3094 int delim = zLine[h++];
3095 azArg[nArg++] = &zLine[h];
mistachkin1fe36bb2016-04-04 02:16:44 +00003096 while( zLine[h] && zLine[h]!=delim ){
mistachkin8e189222015-04-19 21:43:16 +00003097 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
mistachkin1fe36bb2016-04-04 02:16:44 +00003098 h++;
drh4c56b992013-06-27 13:26:55 +00003099 }
mistachkin8e189222015-04-19 21:43:16 +00003100 if( zLine[h]==delim ){
3101 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00003102 }
drhfeac5f82004-08-01 00:10:45 +00003103 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003104 }else{
mistachkin8e189222015-04-19 21:43:16 +00003105 azArg[nArg++] = &zLine[h];
3106 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
3107 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00003108 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003109 }
3110 }
3111
3112 /* Process the input line.
3113 */
shane9bd1b442009-10-23 01:27:39 +00003114 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00003115 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00003116 c = azArg[0][0];
drhde613c62016-04-04 17:23:10 +00003117
3118 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
3119 if( nArg!=2 ){
3120 raw_printf(stderr, "Usage: .auth ON|OFF\n");
3121 rc = 1;
3122 goto meta_command_exit;
3123 }
3124 open_db(p, 0);
3125 if( booleanValue(azArg[1]) ){
3126 sqlite3_set_authorizer(p->db, shellAuth, p);
3127 }else{
3128 sqlite3_set_authorizer(p->db, 0, 0);
3129 }
3130 }else
3131
drh5c7976f2014-02-10 19:59:27 +00003132 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
3133 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
3134 ){
drhbc46f022013-01-23 18:53:23 +00003135 const char *zDestFile = 0;
3136 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00003137 sqlite3 *pDest;
3138 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00003139 int j;
3140 for(j=1; j<nArg; j++){
3141 const char *z = azArg[j];
3142 if( z[0]=='-' ){
3143 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00003144 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00003145 {
mistachkinaae280e2015-12-31 19:06:24 +00003146 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00003147 return 1;
3148 }
3149 }else if( zDestFile==0 ){
3150 zDestFile = azArg[j];
3151 }else if( zDb==0 ){
3152 zDb = zDestFile;
3153 zDestFile = azArg[j];
3154 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003155 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00003156 return 1;
3157 }
drh9ff849f2009-02-04 20:55:57 +00003158 }
drhbc46f022013-01-23 18:53:23 +00003159 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003160 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00003161 return 1;
3162 }
3163 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00003164 rc = sqlite3_open(zDestFile, &pDest);
3165 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003166 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00003167 sqlite3_close(pDest);
3168 return 1;
3169 }
drh05782482013-10-24 15:20:20 +00003170 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003171 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
3172 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003173 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00003174 sqlite3_close(pDest);
3175 return 1;
3176 }
3177 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
3178 sqlite3_backup_finish(pBackup);
3179 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003180 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00003181 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003182 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00003183 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003184 }
3185 sqlite3_close(pDest);
3186 }else
3187
drhc2ce0be2014-05-29 12:36:14 +00003188 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
3189 if( nArg==2 ){
3190 bail_on_error = booleanValue(azArg[1]);
3191 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003192 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003193 rc = 1;
3194 }
drhc49f44e2006-10-26 18:15:42 +00003195 }else
3196
mistachkinf21979d2015-01-18 05:35:01 +00003197 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
3198 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00003199 if( booleanValue(azArg[1]) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003200 setBinaryMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003201 }else{
mistachkin1fe36bb2016-04-04 02:16:44 +00003202 setTextMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003203 }
mistachkinf21979d2015-01-18 05:35:01 +00003204 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003205 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00003206 rc = 1;
3207 }
3208 }else
3209
drhd8621b92012-04-17 09:09:33 +00003210 /* The undocumented ".breakpoint" command causes a call to the no-op
3211 ** routine named test_breakpoint().
3212 */
3213 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
3214 test_breakpoint();
3215 }else
3216
drhdf12f1c2015-12-07 21:46:19 +00003217 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
3218 if( nArg==2 ){
3219 p->countChanges = booleanValue(azArg[1]);
3220 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003221 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00003222 rc = 1;
3223 }
3224 }else
3225
drhc2ce0be2014-05-29 12:36:14 +00003226 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
3227 if( nArg==2 ){
3228 tryToClone(p, azArg[1]);
3229 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003230 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003231 rc = 1;
3232 }
mistachkine31ae902014-02-06 01:15:29 +00003233 }else
3234
drhc2ce0be2014-05-29 12:36:14 +00003235 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003236 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00003237 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003238 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00003239 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00003240 data.showHeader = 1;
drh700c2522016-02-09 18:39:25 +00003241 data.cMode = data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00003242 data.colWidth[0] = 3;
3243 data.colWidth[1] = 15;
3244 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00003245 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00003246 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00003247 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003248 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003249 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003250 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00003251 }
3252 }else
3253
drh0e55db12015-02-06 14:51:13 +00003254 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
3255 rc = shell_dbinfo_command(p, nArg, azArg);
3256 }else
3257
drhc2ce0be2014-05-29 12:36:14 +00003258 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00003259 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00003260 /* When playing back a "dump", the content might appear in an order
3261 ** which causes immediate foreign key constraints to be violated.
3262 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00003263 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003264 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003265 rc = 1;
3266 goto meta_command_exit;
3267 }
mistachkinaae280e2015-12-31 19:06:24 +00003268 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
3269 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00003270 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00003271 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00003272 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00003273 if( nArg==1 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003274 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003275 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003276 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00003277 );
mistachkin1fe36bb2016-04-04 02:16:44 +00003278 run_schema_dump_query(p,
drh4f324762009-05-21 14:51:03 +00003279 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003280 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00003281 );
drh2f464a02011-10-13 00:41:49 +00003282 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003283 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00003284 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00003285 );
drh4c653a02000-06-07 01:27:47 +00003286 }else{
3287 int i;
drhdd3d4592004-08-30 01:54:05 +00003288 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00003289 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00003290 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003291 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00003292 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00003293 " AND sql NOT NULL");
3294 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003295 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00003296 "WHERE sql NOT NULL"
3297 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00003298 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00003299 );
danielk1977bc6ada42004-06-30 08:20:16 +00003300 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00003301 }
3302 }
drh45e29d82006-11-20 16:21:10 +00003303 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00003304 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00003305 p->writableSchema = 0;
3306 }
drh56197952011-10-13 16:30:13 +00003307 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
3308 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00003309 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00003310 }else
drh75897232000-05-29 14:26:00 +00003311
drhc2ce0be2014-05-29 12:36:14 +00003312 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
3313 if( nArg==2 ){
3314 p->echoOn = booleanValue(azArg[1]);
3315 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003316 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003317 rc = 1;
3318 }
drhdaffd0e2001-04-11 14:28:42 +00003319 }else
3320
drhc2ce0be2014-05-29 12:36:14 +00003321 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
3322 if( nArg==2 ){
drheacd29d2016-04-15 15:03:27 +00003323 if( strcmp(azArg[1],"full")==0 ){
3324 p->autoEQP = 2;
3325 }else{
3326 p->autoEQP = booleanValue(azArg[1]);
3327 }
drhc2ce0be2014-05-29 12:36:14 +00003328 }else{
drheacd29d2016-04-15 15:03:27 +00003329 raw_printf(stderr, "Usage: .eqp on|off|full\n");
drhc2ce0be2014-05-29 12:36:14 +00003330 rc = 1;
mistachkin1fe36bb2016-04-04 02:16:44 +00003331 }
drhefbf3b12014-02-28 20:47:24 +00003332 }else
3333
drhd3ac7d92013-01-25 18:33:43 +00003334 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00003335 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00003336 rc = 2;
drh75897232000-05-29 14:26:00 +00003337 }else
3338
drhc2ce0be2014-05-29 12:36:14 +00003339 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00003340 int val = 1;
3341 if( nArg>=2 ){
3342 if( strcmp(azArg[1],"auto")==0 ){
3343 val = 99;
3344 }else{
3345 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003346 }
drh700c2522016-02-09 18:39:25 +00003347 }
3348 if( val==1 && p->mode!=MODE_Explain ){
3349 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003350 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003351 p->autoExplain = 0;
3352 }else if( val==0 ){
3353 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3354 p->autoExplain = 0;
3355 }else if( val==99 ){
3356 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3357 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003358 }
drh75897232000-05-29 14:26:00 +00003359 }else
3360
drhc1971542014-06-23 23:28:13 +00003361 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003362 ShellState data;
drhc1971542014-06-23 23:28:13 +00003363 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003364 int doStats = 0;
drh4926fec2016-04-13 15:33:42 +00003365 memcpy(&data, p, sizeof(data));
3366 data.showHeader = 0;
3367 data.cMode = data.mode = MODE_Semi;
3368 if( nArg==2 && optionMatch(azArg[1], "indent") ){
3369 data.cMode = data.mode = MODE_Pretty;
3370 nArg = 1;
3371 }
drhc1971542014-06-23 23:28:13 +00003372 if( nArg!=1 ){
drh4926fec2016-04-13 15:33:42 +00003373 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
drhc1971542014-06-23 23:28:13 +00003374 rc = 1;
3375 goto meta_command_exit;
3376 }
3377 open_db(p, 0);
drhc1971542014-06-23 23:28:13 +00003378 rc = sqlite3_exec(p->db,
3379 "SELECT sql FROM"
3380 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3381 " FROM sqlite_master UNION ALL"
3382 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003383 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003384 "ORDER BY rowid",
3385 callback, &data, &zErrMsg
3386 );
drh56f674c2014-07-18 14:43:29 +00003387 if( rc==SQLITE_OK ){
3388 sqlite3_stmt *pStmt;
3389 rc = sqlite3_prepare_v2(p->db,
3390 "SELECT rowid FROM sqlite_master"
3391 " WHERE name GLOB 'sqlite_stat[134]'",
3392 -1, &pStmt, 0);
3393 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3394 sqlite3_finalize(pStmt);
3395 }
3396 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003397 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003398 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003399 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003400 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3401 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003402 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003403 data.zDestTable = "sqlite_stat1";
3404 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3405 shell_callback, &data,&zErrMsg);
3406 data.zDestTable = "sqlite_stat3";
3407 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3408 shell_callback, &data,&zErrMsg);
3409 data.zDestTable = "sqlite_stat4";
3410 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3411 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003412 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003413 }
drhc1971542014-06-23 23:28:13 +00003414 }else
3415
drhc2ce0be2014-05-29 12:36:14 +00003416 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3417 if( nArg==2 ){
3418 p->showHeader = booleanValue(azArg[1]);
3419 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003420 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003421 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003422 }
drh75897232000-05-29 14:26:00 +00003423 }else
3424
drhc2ce0be2014-05-29 12:36:14 +00003425 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003426 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003427 }else
3428
3429 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003430 char *zTable; /* Insert data into this table */
3431 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003432 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003433 int nCol; /* Number of columns in the table */
3434 int nByte; /* Number of bytes in an SQL string */
3435 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003436 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003437 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003438 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003439 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003440 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3441 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003442
drhc2ce0be2014-05-29 12:36:14 +00003443 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003444 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003445 goto meta_command_exit;
3446 }
drh01f37542014-05-31 15:43:33 +00003447 zFile = azArg[1];
3448 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003449 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003450 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003451 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003452 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003453 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003454 raw_printf(stderr,
3455 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003456 return 1;
drhfeac5f82004-08-01 00:10:45 +00003457 }
drhdb95f682013-06-26 22:46:00 +00003458 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003459 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003460 " for import\n");
3461 return 1;
3462 }
mistachkin636bf9f2014-07-19 20:15:16 +00003463 nSep = strlen30(p->rowSeparator);
3464 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003465 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003466 return 1;
3467 }
mistachkine0d68852014-12-11 03:12:33 +00003468 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3469 /* When importing CSV (only), if the row separator is set to the
3470 ** default output row separator, change it to the default input
3471 ** row separator. This avoids having to maintain different input
3472 ** and output row separators. */
3473 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3474 nSep = strlen30(p->rowSeparator);
3475 }
mistachkin636bf9f2014-07-19 20:15:16 +00003476 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003477 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003478 " for import\n");
3479 return 1;
3480 }
3481 sCtx.zFile = zFile;
3482 sCtx.nLine = 1;
3483 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003484#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003485 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003486 return 1;
3487#else
mistachkin636bf9f2014-07-19 20:15:16 +00003488 sCtx.in = popen(sCtx.zFile+1, "r");
3489 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003490 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003491#endif
drh5bde8162013-06-27 14:07:53 +00003492 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003493 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003494 xCloser = fclose;
3495 }
mistachkin636bf9f2014-07-19 20:15:16 +00003496 if( p->mode==MODE_Ascii ){
3497 xRead = ascii_read_one_field;
3498 }else{
3499 xRead = csv_read_one_field;
3500 }
3501 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003502 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003503 return 1;
3504 }
mistachkin636bf9f2014-07-19 20:15:16 +00003505 sCtx.cColSep = p->colSeparator[0];
3506 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003507 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003508 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003509 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003510 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003511 return 1;
3512 }
drh4f21c4a2008-12-10 22:15:00 +00003513 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003514 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003515 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003516 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003517 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3518 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003519 while( xRead(&sCtx) ){
drhd8c22ac2016-02-25 13:33:02 +00003520 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003521 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003522 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003523 }
drh5bde8162013-06-27 14:07:53 +00003524 if( cSep=='(' ){
3525 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003526 sqlite3_free(sCtx.z);
3527 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003528 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003529 return 1;
3530 }
drhdb95f682013-06-26 22:46:00 +00003531 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3532 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3533 sqlite3_free(zCreate);
3534 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003535 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003536 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003537 sqlite3_free(sCtx.z);
3538 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003539 return 1;
3540 }
drhc7181902014-02-27 15:04:13 +00003541 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003542 }
drhfeac5f82004-08-01 00:10:45 +00003543 sqlite3_free(zSql);
3544 if( rc ){
shane916f9612009-10-23 00:37:15 +00003545 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00003546 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003547 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003548 return 1;
drhfeac5f82004-08-01 00:10:45 +00003549 }
shane916f9612009-10-23 00:37:15 +00003550 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003551 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003552 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003553 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003554 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003555 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003556 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003557 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003558 return 1;
3559 }
drhdb95f682013-06-26 22:46:00 +00003560 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003561 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003562 for(i=1; i<nCol; i++){
3563 zSql[j++] = ',';
3564 zSql[j++] = '?';
3565 }
3566 zSql[j++] = ')';
3567 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003568 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003569 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003570 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003571 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003572 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003573 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003574 return 1;
drhfeac5f82004-08-01 00:10:45 +00003575 }
mistachkin8e189222015-04-19 21:43:16 +00003576 needCommit = sqlite3_get_autocommit(p->db);
3577 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003578 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003579 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003580 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003581 char *z = xRead(&sCtx);
3582 /*
3583 ** Did we reach end-of-file before finding any columns?
3584 ** If so, stop instead of NULL filling the remaining columns.
3585 */
drhdb95f682013-06-26 22:46:00 +00003586 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003587 /*
3588 ** Did we reach end-of-file OR end-of-line before finding any
3589 ** columns in ASCII mode? If so, stop instead of NULL filling
3590 ** the remaining columns.
3591 */
3592 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003593 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003594 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00003595 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003596 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003597 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003598 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003599 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003600 }
drhfeac5f82004-08-01 00:10:45 +00003601 }
mistachkin636bf9f2014-07-19 20:15:16 +00003602 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003603 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003604 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003605 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003606 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00003607 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003608 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003609 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003610 }
drhdb95f682013-06-26 22:46:00 +00003611 if( i>=nCol ){
3612 sqlite3_step(pStmt);
3613 rc = sqlite3_reset(pStmt);
3614 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003615 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
3616 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003617 }
3618 }
mistachkin636bf9f2014-07-19 20:15:16 +00003619 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003620
mistachkin636bf9f2014-07-19 20:15:16 +00003621 xCloser(sCtx.in);
3622 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003623 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003624 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003625 }else
3626
drh0e55db12015-02-06 14:51:13 +00003627 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3628 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003629 ShellState data;
drh75897232000-05-29 14:26:00 +00003630 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003631 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003632 memcpy(&data, p, sizeof(data));
3633 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003634 data.cMode = data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003635 if( nArg==1 ){
3636 rc = sqlite3_exec(p->db,
3637 "SELECT name FROM sqlite_master "
3638 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3639 "UNION ALL "
3640 "SELECT name FROM sqlite_temp_master "
3641 "WHERE type='index' "
3642 "ORDER BY 1",
3643 callback, &data, &zErrMsg
3644 );
drhc2ce0be2014-05-29 12:36:14 +00003645 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003646 zShellStatic = azArg[1];
3647 rc = sqlite3_exec(p->db,
3648 "SELECT name FROM sqlite_master "
3649 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3650 "UNION ALL "
3651 "SELECT name FROM sqlite_temp_master "
3652 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3653 "ORDER BY 1",
3654 callback, &data, &zErrMsg
3655 );
3656 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003657 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003658 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003659 rc = 1;
3660 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003661 }
drh75897232000-05-29 14:26:00 +00003662 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003663 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003664 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003665 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003666 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003667 raw_printf(stderr,
3668 "Error: querying sqlite_master and sqlite_temp_master\n");
shane86f5bdb2009-10-24 02:00:07 +00003669 rc = 1;
drh75897232000-05-29 14:26:00 +00003670 }
3671 }else
3672
drhae5e4452007-05-03 17:18:36 +00003673#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003674 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003675 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003676 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3677 iotrace = 0;
3678 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003679 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003680 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003681 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003682 iotrace = stdout;
3683 }else{
3684 iotrace = fopen(azArg[1], "w");
3685 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003686 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003687 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003688 rc = 1;
drhb0603412007-02-28 04:47:26 +00003689 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003690 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003691 }
3692 }
3693 }else
drhae5e4452007-05-03 17:18:36 +00003694#endif
drh1a513372015-05-02 17:40:23 +00003695 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3696 static const struct {
3697 const char *zLimitName; /* Name of a limit */
3698 int limitCode; /* Integer code for that limit */
3699 } aLimit[] = {
3700 { "length", SQLITE_LIMIT_LENGTH },
3701 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3702 { "column", SQLITE_LIMIT_COLUMN },
3703 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3704 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3705 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3706 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3707 { "attached", SQLITE_LIMIT_ATTACHED },
3708 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3709 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3710 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3711 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3712 };
3713 int i, n2;
3714 open_db(p, 0);
3715 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003716 for(i=0; i<ArraySize(aLimit); i++){
mistachkin1fe36bb2016-04-04 02:16:44 +00003717 printf("%20s %d\n", aLimit[i].zLimitName,
drh1a513372015-05-02 17:40:23 +00003718 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3719 }
3720 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003721 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00003722 rc = 1;
3723 goto meta_command_exit;
3724 }else{
3725 int iLimit = -1;
3726 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003727 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003728 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3729 if( iLimit<0 ){
3730 iLimit = i;
3731 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003732 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00003733 rc = 1;
3734 goto meta_command_exit;
3735 }
3736 }
3737 }
3738 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003739 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00003740 "enter \".limits\" with no arguments for a list.\n",
3741 azArg[1]);
3742 rc = 1;
3743 goto meta_command_exit;
3744 }
3745 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003746 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3747 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003748 }
3749 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3750 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3751 }
3752 }else
drhb0603412007-02-28 04:47:26 +00003753
drh70df4fe2006-06-13 15:12:21 +00003754#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003755 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003756 const char *zFile, *zProc;
3757 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003758 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003759 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00003760 rc = 1;
3761 goto meta_command_exit;
3762 }
drh1e397f82006-06-08 15:28:43 +00003763 zFile = azArg[1];
3764 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003765 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003766 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3767 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003768 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003769 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003770 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003771 }
3772 }else
drh70df4fe2006-06-13 15:12:21 +00003773#endif
drh1e397f82006-06-08 15:28:43 +00003774
drhc2ce0be2014-05-29 12:36:14 +00003775 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3776 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003777 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003778 rc = 1;
3779 }else{
3780 const char *zFile = azArg[1];
3781 output_file_close(p->pLog);
3782 p->pLog = output_file_open(zFile);
3783 }
drh127f9d72010-02-23 01:47:00 +00003784 }else
3785
drhc2ce0be2014-05-29 12:36:14 +00003786 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3787 const char *zMode = nArg>=2 ? azArg[1] : "";
3788 int n2 = (int)strlen(zMode);
3789 int c2 = zMode[0];
3790 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003791 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003792 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003793 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003794 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003795 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003796 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003797 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003798 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003799 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003800 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003801 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003802 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003803 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003804 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003805 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003806 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003807 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003808 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003809 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003810 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003811 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3812 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003813 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3814 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003815 }else {
mistachkinaae280e2015-12-31 19:06:24 +00003816 raw_printf(stderr, "Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003817 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003818 rc = 1;
drh75897232000-05-29 14:26:00 +00003819 }
drh700c2522016-02-09 18:39:25 +00003820 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00003821 }else
3822
drhc2ce0be2014-05-29 12:36:14 +00003823 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3824 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003825 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3826 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003827 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003828 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003829 rc = 1;
3830 }
3831 }else
3832
drh05782482013-10-24 15:20:20 +00003833 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3834 sqlite3 *savedDb = p->db;
3835 const char *zSavedFilename = p->zDbFilename;
3836 char *zNewFilename = 0;
3837 p->db = 0;
drhbbe031f2015-06-17 17:08:22 +00003838 if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3839 p->zDbFilename = zNewFilename;
drh05782482013-10-24 15:20:20 +00003840 open_db(p, 1);
3841 if( p->db!=0 ){
drhe6229612014-08-18 15:08:26 +00003842 session_close_all(p);
drh05782482013-10-24 15:20:20 +00003843 sqlite3_close(savedDb);
3844 sqlite3_free(p->zFreeOnClose);
3845 p->zFreeOnClose = zNewFilename;
3846 }else{
3847 sqlite3_free(zNewFilename);
3848 p->db = savedDb;
3849 p->zDbFilename = zSavedFilename;
3850 }
3851 }else
3852
drhc2ce0be2014-05-29 12:36:14 +00003853 if( c=='o'
3854 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3855 ){
3856 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3857 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003858 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00003859 rc = 1;
3860 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003861 }
drhc2ce0be2014-05-29 12:36:14 +00003862 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3863 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003864 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003865 rc = 1;
3866 goto meta_command_exit;
3867 }
3868 p->outCount = 2;
3869 }else{
3870 p->outCount = 0;
3871 }
3872 output_reset(p);
3873 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003874#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003875 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003876 rc = 1;
3877 p->out = stdout;
3878#else
drhc2ce0be2014-05-29 12:36:14 +00003879 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003880 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003881 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003882 p->out = stdout;
3883 rc = 1;
3884 }else{
drhc2ce0be2014-05-29 12:36:14 +00003885 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003886 }
drh8cd5b252015-03-02 22:06:43 +00003887#endif
drh75897232000-05-29 14:26:00 +00003888 }else{
drhc2ce0be2014-05-29 12:36:14 +00003889 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003890 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003891 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003892 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003893 }
drh75897232000-05-29 14:26:00 +00003894 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003895 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003896 } else {
drhc2ce0be2014-05-29 12:36:14 +00003897 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003898 }
3899 }
3900 }else
3901
drh078b1fd2012-09-21 13:40:02 +00003902 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3903 int i;
3904 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00003905 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00003906 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00003907 }
mistachkinaae280e2015-12-31 19:06:24 +00003908 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00003909 }else
3910
drhc2ce0be2014-05-29 12:36:14 +00003911 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003912 if( nArg >= 2) {
3913 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3914 }
3915 if( nArg >= 3) {
3916 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3917 }
3918 }else
3919
drhc2ce0be2014-05-29 12:36:14 +00003920 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003921 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003922 }else
3923
drhc2ce0be2014-05-29 12:36:14 +00003924 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3925 FILE *alt;
3926 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003927 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003928 rc = 1;
3929 goto meta_command_exit;
3930 }
3931 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003932 if( alt==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003933 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
shane9bd1b442009-10-23 01:27:39 +00003934 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003935 }else{
shane9bd1b442009-10-23 01:27:39 +00003936 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003937 fclose(alt);
3938 }
3939 }else
3940
drhc2ce0be2014-05-29 12:36:14 +00003941 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003942 const char *zSrcFile;
3943 const char *zDb;
3944 sqlite3 *pSrc;
3945 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003946 int nTimeout = 0;
3947
drh9ff849f2009-02-04 20:55:57 +00003948 if( nArg==2 ){
3949 zSrcFile = azArg[1];
3950 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003951 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003952 zSrcFile = azArg[2];
3953 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003954 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003955 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003956 rc = 1;
3957 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003958 }
3959 rc = sqlite3_open(zSrcFile, &pSrc);
3960 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003961 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003962 sqlite3_close(pSrc);
3963 return 1;
3964 }
drh05782482013-10-24 15:20:20 +00003965 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003966 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3967 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003968 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00003969 sqlite3_close(pSrc);
3970 return 1;
3971 }
drhdc2c4912009-02-04 22:46:47 +00003972 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3973 || rc==SQLITE_BUSY ){
3974 if( rc==SQLITE_BUSY ){
3975 if( nTimeout++ >= 3 ) break;
3976 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003977 }
3978 }
3979 sqlite3_backup_finish(pBackup);
3980 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003981 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003982 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00003983 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00003984 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003985 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003986 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003987 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003988 }
3989 sqlite3_close(pSrc);
3990 }else
3991
dan8d1edb92014-11-05 09:07:28 +00003992
3993 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3994 if( nArg==2 ){
3995 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003996#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00003997 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00003998#endif
dan8d1edb92014-11-05 09:07:28 +00003999 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004000 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00004001 rc = 1;
4002 }
4003 }else
4004
drhc2ce0be2014-05-29 12:36:14 +00004005 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00004006 ShellState data;
drh75897232000-05-29 14:26:00 +00004007 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00004008 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00004009 memcpy(&data, p, sizeof(data));
4010 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00004011 data.cMode = data.mode = MODE_Semi;
drh4926fec2016-04-13 15:33:42 +00004012 if( nArg>=2 && optionMatch(azArg[1], "indent") ){
4013 data.cMode = data.mode = MODE_Pretty;
4014 nArg--;
4015 if( nArg==2 ) azArg[1] = azArg[2];
4016 }
4017 if( nArg==2 && azArg[1][0]!='-' ){
drhc8d74412004-08-31 23:41:26 +00004018 int i;
drhf0693c82011-10-11 20:41:54 +00004019 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00004020 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00004021 char *new_argv[2], *new_colv[2];
4022 new_argv[0] = "CREATE TABLE sqlite_master (\n"
4023 " type text,\n"
4024 " name text,\n"
4025 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00004026 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00004027 " sql text\n"
4028 ")";
4029 new_argv[1] = 0;
4030 new_colv[0] = "sql";
4031 new_colv[1] = 0;
4032 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004033 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00004034 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00004035 char *new_argv[2], *new_colv[2];
4036 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
4037 " type text,\n"
4038 " name text,\n"
4039 " tbl_name text,\n"
4040 " rootpage integer,\n"
4041 " sql text\n"
4042 ")";
4043 new_argv[1] = 0;
4044 new_colv[0] = "sql";
4045 new_colv[1] = 0;
4046 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004047 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00004048 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00004049 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00004050 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004051 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004052 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004053 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004054 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00004055 "WHERE lower(tbl_name) LIKE shellstatic()"
4056 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00004057 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00004058 callback, &data, &zErrMsg);
4059 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00004060 }
drhc2ce0be2014-05-29 12:36:14 +00004061 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00004062 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004063 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004064 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004065 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004066 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00004067 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00004068 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00004069 callback, &data, &zErrMsg
4070 );
drhc2ce0be2014-05-29 12:36:14 +00004071 }else{
drh4926fec2016-04-13 15:33:42 +00004072 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00004073 rc = 1;
4074 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004075 }
drh75897232000-05-29 14:26:00 +00004076 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00004077 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004078 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00004079 rc = 1;
4080 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004081 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00004082 rc = 1;
4083 }else{
4084 rc = 0;
drh75897232000-05-29 14:26:00 +00004085 }
4086 }else
4087
drhabd4c722014-09-20 18:18:33 +00004088#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
4089 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
drh1d9be4f2015-01-22 11:29:25 +00004090 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00004091 }else
4092#endif
4093
drhe6229612014-08-18 15:08:26 +00004094#if defined(SQLITE_ENABLE_SESSION)
4095 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
4096 OpenSession *pSession = &p->aSession[0];
4097 char **azCmd = &azArg[1];
4098 int iSes = 0;
4099 int nCmd = nArg - 1;
4100 int i;
4101 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00004102 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00004103 if( nArg>=3 ){
4104 for(iSes=0; iSes<p->nSession; iSes++){
4105 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
4106 }
4107 if( iSes<p->nSession ){
4108 pSession = &p->aSession[iSes];
4109 azCmd++;
4110 nCmd--;
4111 }else{
4112 pSession = &p->aSession[0];
4113 iSes = 0;
4114 }
4115 }
4116
drh3a67b042014-08-18 17:56:31 +00004117 /* .session attach TABLE
4118 ** Invoke the sqlite3session_attach() interface to attach a particular
4119 ** table so that it is never filtered.
4120 */
4121 if( strcmp(azCmd[0],"attach")==0 ){
4122 if( nCmd!=2 ) goto session_syntax_error;
4123 if( pSession->p==0 ){
4124 session_not_open:
mistachkin899c5c92016-04-03 20:50:02 +00004125 raw_printf(stderr, "ERROR: No sessions are open\n");
drh3a67b042014-08-18 17:56:31 +00004126 }else{
4127 rc = sqlite3session_attach(pSession->p, azCmd[1]);
4128 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004129 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004130 rc = 0;
4131 }
4132 }
4133 }else
4134
4135 /* .session changeset FILE
4136 ** .session patchset FILE
4137 ** Write a changeset or patchset into a file. The file is overwritten.
4138 */
4139 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
4140 FILE *out = 0;
4141 if( nCmd!=2 ) goto session_syntax_error;
4142 if( pSession->p==0 ) goto session_not_open;
4143 out = fopen(azCmd[1], "wb");
4144 if( out==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004145 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
drh3a67b042014-08-18 17:56:31 +00004146 }else{
4147 int szChng;
4148 void *pChng;
4149 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00004150 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00004151 }else{
drh2967e0c2014-08-19 00:26:17 +00004152 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
4153 }
4154 if( rc ){
4155 printf("Error: error code %d\n", rc);
4156 rc = 0;
drh3a67b042014-08-18 17:56:31 +00004157 }
mistachkin1fe36bb2016-04-04 02:16:44 +00004158 if( pChng
drh3a67b042014-08-18 17:56:31 +00004159 && fwrite(pChng, szChng, 1, out)!=1 ){
mistachkin899c5c92016-04-03 20:50:02 +00004160 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
drh3a67b042014-08-18 17:56:31 +00004161 szChng);
4162 }
4163 sqlite3_free(pChng);
4164 fclose(out);
4165 }
4166 }else
4167
drhe6229612014-08-18 15:08:26 +00004168 /* .session close
4169 ** Close the identified session
4170 */
4171 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00004172 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00004173 if( p->nSession ){
4174 session_close(pSession);
4175 p->aSession[iSes] = p->aSession[--p->nSession];
4176 }
4177 }else
4178
drh03168ca2014-08-18 20:01:31 +00004179 /* .session enable ?BOOLEAN?
4180 ** Query or set the enable flag
4181 */
4182 if( strcmp(azCmd[0], "enable")==0 ){
4183 int ii;
4184 if( nCmd>2 ) goto session_syntax_error;
4185 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4186 if( p->nSession ){
4187 ii = sqlite3session_enable(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004188 utf8_printf(p->out, "session %s enable flag = %d\n",
4189 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004190 }
4191 }else
4192
4193 /* .session filter GLOB ....
4194 ** Set a list of GLOB patterns of table names to be excluded.
4195 */
4196 if( strcmp(azCmd[0], "filter")==0 ){
4197 int ii, nByte;
4198 if( nCmd<2 ) goto session_syntax_error;
4199 if( p->nSession ){
4200 for(ii=0; ii<pSession->nFilter; ii++){
4201 sqlite3_free(pSession->azFilter[ii]);
4202 }
4203 sqlite3_free(pSession->azFilter);
4204 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
4205 pSession->azFilter = sqlite3_malloc( nByte );
4206 if( pSession->azFilter==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004207 raw_printf(stderr, "Error: out or memory\n");
drh03168ca2014-08-18 20:01:31 +00004208 exit(1);
4209 }
4210 for(ii=1; ii<nCmd; ii++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004211 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
drh03168ca2014-08-18 20:01:31 +00004212 }
4213 pSession->nFilter = ii-1;
4214 }
4215 }else
4216
4217 /* .session indirect ?BOOLEAN?
4218 ** Query or set the indirect flag
4219 */
4220 if( strcmp(azCmd[0], "indirect")==0 ){
4221 int ii;
4222 if( nCmd>2 ) goto session_syntax_error;
4223 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4224 if( p->nSession ){
4225 ii = sqlite3session_indirect(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004226 utf8_printf(p->out, "session %s indirect flag = %d\n",
4227 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004228 }
4229 }else
4230
4231 /* .session isempty
4232 ** Determine if the session is empty
4233 */
4234 if( strcmp(azCmd[0], "isempty")==0 ){
4235 int ii;
4236 if( nCmd!=1 ) goto session_syntax_error;
4237 if( p->nSession ){
4238 ii = sqlite3session_isempty(pSession->p);
mistachkin899c5c92016-04-03 20:50:02 +00004239 utf8_printf(p->out, "session %s isempty flag = %d\n",
4240 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004241 }
4242 }else
4243
drhe6229612014-08-18 15:08:26 +00004244 /* .session list
4245 ** List all currently open sessions
4246 */
4247 if( strcmp(azCmd[0],"list")==0 ){
4248 for(i=0; i<p->nSession; i++){
mistachkin899c5c92016-04-03 20:50:02 +00004249 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
drhe6229612014-08-18 15:08:26 +00004250 }
4251 }else
4252
4253 /* .session open DB NAME
4254 ** Open a new session called NAME on the attached database DB.
4255 ** DB is normally "main".
4256 */
4257 if( strcmp(azCmd[0],"open")==0 ){
4258 char *zName;
4259 if( nCmd!=3 ) goto session_syntax_error;
4260 zName = azCmd[2];
4261 if( zName[0]==0 ) goto session_syntax_error;
4262 for(i=0; i<p->nSession; i++){
4263 if( strcmp(p->aSession[i].zName,zName)==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004264 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
drhe6229612014-08-18 15:08:26 +00004265 goto meta_command_exit;
4266 }
4267 }
4268 if( p->nSession>=ArraySize(p->aSession) ){
mistachkin899c5c92016-04-03 20:50:02 +00004269 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
drhe6229612014-08-18 15:08:26 +00004270 goto meta_command_exit;
4271 }
4272 pSession = &p->aSession[p->nSession];
4273 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
4274 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004275 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004276 rc = 0;
drhe6229612014-08-18 15:08:26 +00004277 goto meta_command_exit;
4278 }
drh03168ca2014-08-18 20:01:31 +00004279 pSession->nFilter = 0;
4280 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00004281 p->nSession++;
4282 pSession->zName = sqlite3_mprintf("%s", zName);
4283 }else
4284 /* If no command name matches, show a syntax error */
4285 session_syntax_error:
4286 session_help(p);
4287 }else
4288#endif
4289
drh340f5822013-06-27 13:01:21 +00004290#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00004291 /* Undocumented commands for internal testing. Subject to change
4292 ** without notice. */
4293 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
4294 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
4295 int i, v;
4296 for(i=1; i<nArg; i++){
4297 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00004298 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00004299 }
4300 }
4301 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
4302 int i; sqlite3_int64 v;
4303 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00004304 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00004305 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00004306 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00004307 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00004308 }
4309 }
4310 }else
drh340f5822013-06-27 13:01:21 +00004311#endif
drh348d19c2013-06-03 12:47:43 +00004312
drhc2ce0be2014-05-29 12:36:14 +00004313 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00004314 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004315 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00004316 rc = 1;
4317 }
drh6976c212014-07-24 12:09:47 +00004318 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004319 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00004320 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00004321 }
4322 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00004323 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
4324 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00004325 }
drh75897232000-05-29 14:26:00 +00004326 }else
4327
drh62cdde52014-05-28 20:22:28 +00004328 if( c=='s'
4329 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00004330 ){
4331 char *zCmd;
drh54027102014-08-06 14:36:53 +00004332 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00004333 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004334 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00004335 rc = 1;
4336 goto meta_command_exit;
4337 }
drhdcb3e3d2014-05-29 03:17:29 +00004338 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00004339 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00004340 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
4341 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00004342 }
drh54027102014-08-06 14:36:53 +00004343 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00004344 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00004345 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00004346 }else
4347
drhc2ce0be2014-05-29 12:36:14 +00004348 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drheacd29d2016-04-15 15:03:27 +00004349 static const char *azBool[] = { "off", "on", "full", "unk" };
persicom7e2dfdd2002-04-18 02:46:52 +00004350 int i;
drhc2ce0be2014-05-29 12:36:14 +00004351 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00004352 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00004353 rc = 1;
4354 goto meta_command_exit;
4355 }
drheacd29d2016-04-15 15:03:27 +00004356 utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]);
4357 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
drh700c2522016-02-09 18:39:25 +00004358 utf8_printf(p->out, "%12.12s: %s\n","explain",
4359 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
drheacd29d2016-04-15 15:03:27 +00004360 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004361 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
4362 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00004363 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00004364 raw_printf(p->out, "\n");
4365 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00004366 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00004367 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004368 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004369 raw_printf(p->out, "\n");
4370 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004371 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004372 raw_printf(p->out, "\n");
drheacd29d2016-04-15 15:03:27 +00004373 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004374 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00004375 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00004376 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00004377 }
mistachkinaae280e2015-12-31 19:06:24 +00004378 raw_printf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00004379 }else
4380
drhc2ce0be2014-05-29 12:36:14 +00004381 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
4382 if( nArg==2 ){
4383 p->statsOn = booleanValue(azArg[1]);
drh34784902016-02-27 17:12:36 +00004384 }else if( nArg==1 ){
4385 display_stats(p->db, p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004386 }else{
drh34784902016-02-27 17:12:36 +00004387 raw_printf(stderr, "Usage: .stats ?on|off?\n");
drhc2ce0be2014-05-29 12:36:14 +00004388 rc = 1;
4389 }
shaneh642d8b82010-07-28 16:05:34 +00004390 }else
4391
drhc2ce0be2014-05-29 12:36:14 +00004392 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00004393 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00004394 char **azResult;
drh98781232012-04-23 12:38:05 +00004395 int nRow, nAlloc;
4396 char *zSql = 0;
4397 int ii;
drh05782482013-10-24 15:20:20 +00004398 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00004399 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00004400 if( rc ) return shellDatabaseError(p->db);
4401
4402 /* Create an SQL statement to query for the list of tables in the
4403 ** main and all attached databases where the table name matches the
4404 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00004405 zSql = sqlite3_mprintf(
4406 "SELECT name FROM sqlite_master"
4407 " WHERE type IN ('table','view')"
4408 " AND name NOT LIKE 'sqlite_%%'"
4409 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00004410 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00004411 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
4412 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
4413 if( strcmp(zDbName,"temp")==0 ){
4414 zSql = sqlite3_mprintf(
4415 "%z UNION ALL "
4416 "SELECT 'temp.' || name FROM sqlite_temp_master"
4417 " WHERE type IN ('table','view')"
4418 " AND name NOT LIKE 'sqlite_%%'"
4419 " AND name LIKE ?1", zSql);
4420 }else{
4421 zSql = sqlite3_mprintf(
4422 "%z UNION ALL "
4423 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4424 " WHERE type IN ('table','view')"
4425 " AND name NOT LIKE 'sqlite_%%'"
4426 " AND name LIKE ?1", zSql, zDbName, zDbName);
4427 }
drha50da102000-08-08 20:19:09 +00004428 }
dand95bb392015-09-30 11:19:05 +00004429 rc = sqlite3_finalize(pStmt);
4430 if( zSql && rc==SQLITE_OK ){
4431 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
4432 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4433 }
drh98781232012-04-23 12:38:05 +00004434 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00004435 if( !zSql ) return shellNomemError();
4436 if( rc ) return shellDatabaseError(p->db);
4437
4438 /* Run the SQL statement prepared by the above block. Store the results
4439 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00004440 nRow = nAlloc = 0;
4441 azResult = 0;
4442 if( nArg>1 ){
4443 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00004444 }else{
drh98781232012-04-23 12:38:05 +00004445 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
4446 }
4447 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4448 if( nRow>=nAlloc ){
4449 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00004450 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00004451 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00004452 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00004453 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00004454 break;
4455 }
mistachkin8e189222015-04-19 21:43:16 +00004456 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00004457 azResult = azNew;
4458 }
4459 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00004460 if( 0==azResult[nRow] ){
4461 rc = shellNomemError();
4462 break;
4463 }
4464 nRow++;
drh98781232012-04-23 12:38:05 +00004465 }
dand95bb392015-09-30 11:19:05 +00004466 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
4467 rc = shellDatabaseError(p->db);
4468 }
4469
4470 /* Pretty-print the contents of array azResult[] to the output */
4471 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00004472 int len, maxlen = 0;
4473 int i, j;
4474 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00004475 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00004476 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00004477 if( len>maxlen ) maxlen = len;
4478 }
4479 nPrintCol = 80/(maxlen+2);
4480 if( nPrintCol<1 ) nPrintCol = 1;
4481 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
4482 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00004483 for(j=i; j<nRow; j+=nPrintRow){
4484 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00004485 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
4486 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00004487 }
mistachkinaae280e2015-12-31 19:06:24 +00004488 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00004489 }
4490 }
dand95bb392015-09-30 11:19:05 +00004491
drh98781232012-04-23 12:38:05 +00004492 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
4493 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00004494 }else
4495
shaneh96887e12011-02-10 21:08:58 +00004496 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00004497 static const struct {
4498 const char *zCtrlName; /* Name of a test-control option */
4499 int ctrlCode; /* Integer code for that option */
4500 } aCtrl[] = {
4501 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
4502 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
4503 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
4504 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
4505 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
4506 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
4507 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
4508 { "assert", SQLITE_TESTCTRL_ASSERT },
4509 { "always", SQLITE_TESTCTRL_ALWAYS },
4510 { "reserve", SQLITE_TESTCTRL_RESERVE },
4511 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
4512 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00004513 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00004514 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00004515 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00004516 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00004517 };
shaneh96887e12011-02-10 21:08:58 +00004518 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00004519 int rc2 = 0;
4520 int i, n2;
drh05782482013-10-24 15:20:20 +00004521 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00004522
drhd416fe72011-03-17 16:45:50 +00004523 /* convert testctrl text option to value. allow any unique prefix
4524 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00004525 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00004526 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00004527 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00004528 if( testctrl<0 ){
4529 testctrl = aCtrl[i].ctrlCode;
4530 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004531 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00004532 testctrl = -1;
4533 break;
4534 }
4535 }
4536 }
drh348d19c2013-06-03 12:47:43 +00004537 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004538 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00004539 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004540 }else{
4541 switch(testctrl){
4542
4543 /* sqlite3_test_control(int, db, int) */
4544 case SQLITE_TESTCTRL_OPTIMIZATIONS:
mistachkin1fe36bb2016-04-04 02:16:44 +00004545 case SQLITE_TESTCTRL_RESERVE:
shaneh96887e12011-02-10 21:08:58 +00004546 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004547 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00004548 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004549 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004550 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004551 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004552 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004553 }
4554 break;
4555
4556 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004557 case SQLITE_TESTCTRL_PRNG_SAVE:
4558 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004559 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004560 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004561 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00004562 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00004563 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004564 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004565 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
4566 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004567 }
4568 break;
4569
4570 /* sqlite3_test_control(int, uint) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004571 case SQLITE_TESTCTRL_PENDING_BYTE:
shaneh96887e12011-02-10 21:08:58 +00004572 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004573 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004574 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004575 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004576 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004577 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00004578 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004579 }
4580 break;
mistachkin1fe36bb2016-04-04 02:16:44 +00004581
shaneh96887e12011-02-10 21:08:58 +00004582 /* sqlite3_test_control(int, int) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004583 case SQLITE_TESTCTRL_ASSERT:
4584 case SQLITE_TESTCTRL_ALWAYS:
4585 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004586 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004587 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004588 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004589 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004590 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004591 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004592 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004593 }
4594 break;
4595
4596 /* sqlite3_test_control(int, char *) */
4597#ifdef SQLITE_N_KEYWORD
mistachkin1fe36bb2016-04-04 02:16:44 +00004598 case SQLITE_TESTCTRL_ISKEYWORD:
shaneh96887e12011-02-10 21:08:58 +00004599 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004600 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004601 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004602 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004603 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004604 utf8_printf(stderr,
4605 "Error: testctrl %s takes a single char * option\n",
4606 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004607 }
4608 break;
4609#endif
4610
drh1ffede82015-01-30 20:59:27 +00004611 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004612 if( nArg==5 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004613 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004614 azArg[2],
drh8964b342015-01-29 17:54:52 +00004615 integerValue(azArg[3]),
4616 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00004617 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004618 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004619 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004620 }
4621 break;
4622
mistachkin1fe36bb2016-04-04 02:16:44 +00004623 case SQLITE_TESTCTRL_BITVEC_TEST:
4624 case SQLITE_TESTCTRL_FAULT_INSTALL:
4625 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4626 case SQLITE_TESTCTRL_SCRATCHMALLOC:
shaneh96887e12011-02-10 21:08:58 +00004627 default:
mistachkinaae280e2015-12-31 19:06:24 +00004628 utf8_printf(stderr,
4629 "Error: CLI support for testctrl %s not implemented\n",
4630 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004631 break;
4632 }
4633 }
4634 }else
4635
drhc2ce0be2014-05-29 12:36:14 +00004636 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004637 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004638 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004639 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004640
drhc2ce0be2014-05-29 12:36:14 +00004641 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4642 if( nArg==2 ){
4643 enableTimer = booleanValue(azArg[1]);
4644 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00004645 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00004646 enableTimer = 0;
4647 }
4648 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004649 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004650 rc = 1;
4651 }
shanehe2aa9d72009-11-06 17:20:17 +00004652 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004653
drhc2ce0be2014-05-29 12:36:14 +00004654 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004655 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004656 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004657 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004658 rc = 1;
4659 goto meta_command_exit;
4660 }
drh657b4a82015-03-19 13:30:41 +00004661 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004662 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004663#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004664 if( p->traceOut==0 ){
drh4b363a52016-07-23 20:27:41 +00004665 sqlite3_trace_v2(p->db, 0, 0, 0);
drh42f64e52012-04-04 16:56:23 +00004666 }else{
drh4b363a52016-07-23 20:27:41 +00004667 sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004668 }
4669#endif
4670 }else
4671
drhf442e332014-09-10 19:01:14 +00004672#if SQLITE_USER_AUTHENTICATION
4673 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4674 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004675 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00004676 rc = 1;
4677 goto meta_command_exit;
4678 }
drh7883ecf2014-09-11 16:19:31 +00004679 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004680 if( strcmp(azArg[1],"login")==0 ){
4681 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00004682 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00004683 rc = 1;
4684 goto meta_command_exit;
4685 }
drhd39c40f2014-09-11 00:27:53 +00004686 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4687 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004688 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004689 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00004690 rc = 1;
4691 }
4692 }else if( strcmp(azArg[1],"add")==0 ){
4693 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004694 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004695 rc = 1;
4696 goto meta_command_exit;
4697 }
drhd39c40f2014-09-11 00:27:53 +00004698 rc = sqlite3_user_add(p->db, azArg[2],
4699 azArg[3], (int)strlen(azArg[3]),
4700 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004701 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004702 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004703 rc = 1;
4704 }
4705 }else if( strcmp(azArg[1],"edit")==0 ){
4706 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004707 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004708 rc = 1;
4709 goto meta_command_exit;
4710 }
drhd39c40f2014-09-11 00:27:53 +00004711 rc = sqlite3_user_change(p->db, azArg[2],
4712 azArg[3], (int)strlen(azArg[3]),
4713 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004714 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004715 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004716 rc = 1;
4717 }
4718 }else if( strcmp(azArg[1],"delete")==0 ){
4719 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004720 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00004721 rc = 1;
4722 goto meta_command_exit;
4723 }
4724 rc = sqlite3_user_delete(p->db, azArg[2]);
4725 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004726 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004727 rc = 1;
4728 }
4729 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004730 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00004731 rc = 1;
4732 goto meta_command_exit;
mistachkin1fe36bb2016-04-04 02:16:44 +00004733 }
drhf442e332014-09-10 19:01:14 +00004734 }else
4735#endif /* SQLITE_USER_AUTHENTICATION */
4736
drh9fd301b2011-06-03 13:28:22 +00004737 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004738 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004739 sqlite3_libversion(), sqlite3_sourceid());
4740 }else
4741
drh790f2872015-11-28 18:06:36 +00004742 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
4743 const char *zDbName = nArg==2 ? azArg[1] : "main";
4744 sqlite3_vfs *pVfs;
4745 if( p->db ){
4746 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
4747 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00004748 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
4749 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4750 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4751 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00004752 }
4753 }
4754 }else
4755
drhb19e7352016-01-12 19:37:20 +00004756 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
4757 sqlite3_vfs *pVfs;
4758 sqlite3_vfs *pCurrent = 0;
4759 if( p->db ){
4760 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
4761 }
4762 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
4763 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
4764 pVfs==pCurrent ? " <--- CURRENT" : "");
4765 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4766 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4767 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
4768 if( pVfs->pNext ){
4769 raw_printf(p->out, "-----------------------------------\n");
4770 }
4771 }
4772 }else
4773
drhde60fc22011-12-14 17:53:36 +00004774 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4775 const char *zDbName = nArg==2 ? azArg[1] : "main";
4776 char *zVfsName = 0;
4777 if( p->db ){
4778 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4779 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00004780 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004781 sqlite3_free(zVfsName);
4782 }
4783 }
4784 }else
4785
drhcef4fc82012-09-21 22:50:45 +00004786#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4787 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004788 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004789 }else
4790#endif
4791
drhc2ce0be2014-05-29 12:36:14 +00004792 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004793 int j;
drh43617e92006-03-06 20:55:46 +00004794 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004795 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004796 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004797 }
4798 }else
4799
4800 {
mistachkinaae280e2015-12-31 19:06:24 +00004801 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004802 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004803 rc = 1;
drh75897232000-05-29 14:26:00 +00004804 }
drh67505e72002-04-19 12:34:06 +00004805
drhc2ce0be2014-05-29 12:36:14 +00004806meta_command_exit:
4807 if( p->outCount ){
4808 p->outCount--;
4809 if( p->outCount==0 ) output_reset(p);
4810 }
drh67505e72002-04-19 12:34:06 +00004811 return rc;
drh75897232000-05-29 14:26:00 +00004812}
4813
drh67505e72002-04-19 12:34:06 +00004814/*
drh91a66392007-09-07 01:12:32 +00004815** Return TRUE if a semicolon occurs anywhere in the first N characters
4816** of string z[].
drh324ccef2003-02-05 14:06:20 +00004817*/
drh9f099fd2013-08-06 14:01:46 +00004818static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004819 int i;
4820 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4821 return 0;
drh324ccef2003-02-05 14:06:20 +00004822}
4823
4824/*
drh70c7a4b2003-04-26 03:03:06 +00004825** Test to see if a line consists entirely of whitespace.
4826*/
4827static int _all_whitespace(const char *z){
4828 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004829 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004830 if( *z=='/' && z[1]=='*' ){
4831 z += 2;
4832 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4833 if( *z==0 ) return 0;
4834 z++;
4835 continue;
4836 }
4837 if( *z=='-' && z[1]=='-' ){
4838 z += 2;
4839 while( *z && *z!='\n' ){ z++; }
4840 if( *z==0 ) return 1;
4841 continue;
4842 }
4843 return 0;
4844 }
4845 return 1;
4846}
4847
4848/*
drha9b17162003-04-29 18:01:28 +00004849** Return TRUE if the line typed in is an SQL command terminator other
4850** than a semi-colon. The SQL Server style "go" command is understood
4851** as is the Oracle "/".
4852*/
drh9f099fd2013-08-06 14:01:46 +00004853static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004854 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004855 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4856 return 1; /* Oracle */
4857 }
drhf0693c82011-10-11 20:41:54 +00004858 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004859 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004860 return 1; /* SQL Server */
4861 }
4862 return 0;
4863}
4864
4865/*
drh233a5312008-12-18 22:25:13 +00004866** Return true if zSql is a complete SQL statement. Return false if it
4867** ends in the middle of a string literal or C-style comment.
4868*/
drh9f099fd2013-08-06 14:01:46 +00004869static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004870 int rc;
4871 if( zSql==0 ) return 1;
4872 zSql[nSql] = ';';
4873 zSql[nSql+1] = 0;
4874 rc = sqlite3_complete(zSql);
4875 zSql[nSql] = 0;
4876 return rc;
4877}
4878
4879/*
drh67505e72002-04-19 12:34:06 +00004880** Read input from *in and process it. If *in==0 then input
4881** is interactive - the user is typing it it. Otherwise, input
4882** is coming from a file or device. A prompt is issued and history
4883** is saved only if input is interactive. An interrupt signal will
4884** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004885**
4886** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004887*/
drhdcd87a92014-08-18 13:45:42 +00004888static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004889 char *zLine = 0; /* A single input line */
4890 char *zSql = 0; /* Accumulated SQL text */
4891 int nLine; /* Length of current line */
4892 int nSql = 0; /* Bytes of zSql[] used */
4893 int nAlloc = 0; /* Allocated zSql[] space */
4894 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4895 char *zErrMsg; /* Error message returned */
4896 int rc; /* Error code */
4897 int errCnt = 0; /* Number of errors seen */
4898 int lineno = 0; /* Current line number */
4899 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004900
4901 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4902 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004903 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004904 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004905 /* End of input */
4906 if( stdin_is_interactive ) printf("\n");
4907 break;
drhc49f44e2006-10-26 18:15:42 +00004908 }
drh67505e72002-04-19 12:34:06 +00004909 if( seenInterrupt ){
4910 if( in!=0 ) break;
4911 seenInterrupt = 0;
4912 }
drhc28490c2006-10-26 14:25:58 +00004913 lineno++;
drh849a9d92013-12-21 15:46:06 +00004914 if( nSql==0 && _all_whitespace(zLine) ){
4915 if( p->echoOn ) printf("%s\n", zLine);
4916 continue;
4917 }
drh2af0b2d2002-02-21 02:25:02 +00004918 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004919 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004920 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004921 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004922 break;
4923 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004924 errCnt++;
4925 }
drhdaffd0e2001-04-11 14:28:42 +00004926 continue;
4927 }
drh9f099fd2013-08-06 14:01:46 +00004928 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004929 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004930 }
drh9f099fd2013-08-06 14:01:46 +00004931 nLine = strlen30(zLine);
4932 if( nSql+nLine+2>=nAlloc ){
4933 nAlloc = nSql+nLine+100;
4934 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004935 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004936 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004937 exit(1);
4938 }
drhdaffd0e2001-04-11 14:28:42 +00004939 }
drh9f099fd2013-08-06 14:01:46 +00004940 nSqlPrior = nSql;
4941 if( nSql==0 ){
4942 int i;
4943 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004944 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004945 memcpy(zSql, zLine+i, nLine+1-i);
4946 startline = lineno;
4947 nSql = nLine-i;
4948 }else{
4949 zSql[nSql++] = '\n';
4950 memcpy(zSql+nSql, zLine, nLine+1);
4951 nSql += nLine;
4952 }
4953 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004954 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004955 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004956 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004957 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004958 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004959 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004960 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004961 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004962 char zPrefix[100];
4963 if( in!=0 || !stdin_is_interactive ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004964 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004965 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004966 }else{
shane9bd1b442009-10-23 01:27:39 +00004967 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004968 }
drh7f953e22002-07-13 17:33:45 +00004969 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004970 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004971 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004972 zErrMsg = 0;
4973 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004974 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004975 }
drhc49f44e2006-10-26 18:15:42 +00004976 errCnt++;
drhdf12f1c2015-12-07 21:46:19 +00004977 }else if( p->countChanges ){
mistachkinaae280e2015-12-31 19:06:24 +00004978 raw_printf(p->out, "changes: %3d total_changes: %d\n",
drhdf12f1c2015-12-07 21:46:19 +00004979 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
drhdaffd0e2001-04-11 14:28:42 +00004980 }
drhdaffd0e2001-04-11 14:28:42 +00004981 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004982 if( p->outCount ){
4983 output_reset(p);
4984 p->outCount = 0;
4985 }
drh9f099fd2013-08-06 14:01:46 +00004986 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004987 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004988 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004989 }
4990 }
drh9f099fd2013-08-06 14:01:46 +00004991 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004992 if( !_all_whitespace(zSql) ){
mistachkinaae280e2015-12-31 19:06:24 +00004993 utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004994 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004995 }
drhdaffd0e2001-04-11 14:28:42 +00004996 }
drh1f9ca2c2015-08-25 16:57:52 +00004997 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00004998 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004999 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00005000}
5001
drh67505e72002-04-19 12:34:06 +00005002/*
5003** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00005004** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00005005*/
5006static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00005007 static char *home_dir = NULL;
5008 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00005009
drh4ace5362014-11-10 14:42:28 +00005010#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
5011 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00005012 {
5013 struct passwd *pwent;
5014 uid_t uid = getuid();
5015 if( (pwent=getpwuid(uid)) != NULL) {
5016 home_dir = pwent->pw_dir;
5017 }
drh67505e72002-04-19 12:34:06 +00005018 }
5019#endif
5020
chw65d3c132007-11-12 21:09:10 +00005021#if defined(_WIN32_WCE)
5022 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
5023 */
drh85e72432012-04-11 11:38:53 +00005024 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00005025#else
5026
drh83905c92012-06-21 13:00:37 +00005027#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00005028 if (!home_dir) {
5029 home_dir = getenv("USERPROFILE");
5030 }
5031#endif
5032
drh67505e72002-04-19 12:34:06 +00005033 if (!home_dir) {
5034 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00005035 }
5036
drh83905c92012-06-21 13:00:37 +00005037#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00005038 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00005039 char *zDrive, *zPath;
5040 int n;
5041 zDrive = getenv("HOMEDRIVE");
5042 zPath = getenv("HOMEPATH");
5043 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00005044 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00005045 home_dir = malloc( n );
5046 if( home_dir==0 ) return 0;
5047 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
5048 return home_dir;
5049 }
5050 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00005051 }
5052#endif
5053
chw65d3c132007-11-12 21:09:10 +00005054#endif /* !_WIN32_WCE */
5055
drh67505e72002-04-19 12:34:06 +00005056 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00005057 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00005058 char *z = malloc( n );
5059 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00005060 home_dir = z;
5061 }
drhe98d4fa2002-04-21 19:06:22 +00005062
drh67505e72002-04-19 12:34:06 +00005063 return home_dir;
5064}
5065
5066/*
5067** Read input from the file given by sqliterc_override. Or if that
5068** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00005069**
5070** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00005071*/
drh534f4df2015-02-28 14:03:35 +00005072static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00005073 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00005074 const char *sqliterc_override /* Name of config file. NULL to use default */
5075){
persicom7e2dfdd2002-04-18 02:46:52 +00005076 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00005077 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00005078 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00005079 FILE *in = NULL;
5080
5081 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00005082 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00005083 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005084 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00005085 " cannot read ~/.sqliterc\n");
5086 return;
drhe98d4fa2002-04-21 19:06:22 +00005087 }
drh2f3de322012-06-27 16:41:31 +00005088 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00005089 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
5090 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00005091 }
drha1f9b5e2004-02-14 16:31:02 +00005092 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00005093 if( in ){
drhc28490c2006-10-26 14:25:58 +00005094 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00005095 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00005096 }
drh534f4df2015-02-28 14:03:35 +00005097 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00005098 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00005099 }
drh85e72432012-04-11 11:38:53 +00005100 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00005101}
5102
drh67505e72002-04-19 12:34:06 +00005103/*
drhe1e38c42003-05-04 18:30:59 +00005104** Show available command line options
5105*/
mistachkin1fe36bb2016-04-04 02:16:44 +00005106static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00005107 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00005108 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00005109 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005110 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00005111 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00005112 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00005113 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00005114 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00005115 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00005116#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
5117 " -heap SIZE Size of heap for memsys3 or memsys5\n"
5118#endif
drhcc3b4f82012-02-07 14:13:50 +00005119 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00005120 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00005121 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005122 " -line set output mode to 'line'\n"
5123 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00005124 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00005125 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00005126#ifdef SQLITE_ENABLE_MULTIPLEX
5127 " -multiplex enable the multiplexor VFS\n"
5128#endif
mistachkine0d68852014-12-11 03:12:33 +00005129 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00005130 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00005131 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
5132 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00005133 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00005134 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00005135 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00005136 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00005137#ifdef SQLITE_ENABLE_VFSTRACE
5138 " -vfstrace enable tracing of all VFS calls\n"
5139#endif
drhe1e38c42003-05-04 18:30:59 +00005140;
5141static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00005142 utf8_printf(stderr,
mistachkin1fe36bb2016-04-04 02:16:44 +00005143 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
drh80e8be92006-08-29 12:04:19 +00005144 "FILENAME is the name of an SQLite database. A new database is created\n"
5145 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00005146 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00005147 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00005148 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005149 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00005150 }
5151 exit(1);
5152}
5153
5154/*
drh67505e72002-04-19 12:34:06 +00005155** Initialize the state information in data
5156*/
drhdcd87a92014-08-18 13:45:42 +00005157static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00005158 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00005159 data->normalMode = data->cMode = data->mode = MODE_List;
5160 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00005161 memcpy(data->colSeparator,SEP_Column, 2);
5162 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00005163 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00005164 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00005165 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00005166 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00005167 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00005168 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
5169 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00005170}
5171
drh98d312f2012-10-25 15:23:14 +00005172/*
drh5c7976f2014-02-10 19:59:27 +00005173** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00005174*/
5175#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00005176static void printBold(const char *zText){
5177 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
5178 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
5179 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
5180 SetConsoleTextAttribute(out,
5181 FOREGROUND_RED|FOREGROUND_INTENSITY
5182 );
5183 printf("%s", zText);
5184 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00005185}
5186#else
drh5c7976f2014-02-10 19:59:27 +00005187static void printBold(const char *zText){
5188 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00005189}
5190#endif
5191
5192/*
drh98d312f2012-10-25 15:23:14 +00005193** Get the argument to an --option. Throw an error and die if no argument
5194** is available.
5195*/
5196static char *cmdline_option_value(int argc, char **argv, int i){
5197 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00005198 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00005199 argv[0], argv[argc-1]);
5200 exit(1);
5201 }
5202 return argv[i];
5203}
5204
mistachkin1fe36bb2016-04-04 02:16:44 +00005205#ifndef SQLITE_SHELL_IS_UTF8
5206# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
5207# define SQLITE_SHELL_IS_UTF8 (0)
5208# else
5209# define SQLITE_SHELL_IS_UTF8 (1)
5210# endif
5211#endif
5212
5213#if SQLITE_SHELL_IS_UTF8
mistachkin44723ce2015-03-21 02:22:37 +00005214int SQLITE_CDECL main(int argc, char **argv){
mistachkin1fe36bb2016-04-04 02:16:44 +00005215#else
5216int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
mistachkin1810f222016-04-04 02:33:34 +00005217 char **argv;
mistachkin1fe36bb2016-04-04 02:16:44 +00005218#endif
drh75897232000-05-29 14:26:00 +00005219 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00005220 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00005221 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00005222 int i;
drhc28490c2006-10-26 14:25:58 +00005223 int rc = 0;
drhb3735912014-02-10 16:13:42 +00005224 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00005225 int readStdin = 1;
5226 int nCmd = 0;
5227 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00005228
mistachkin1fe36bb2016-04-04 02:16:44 +00005229 setBinaryMode(stdin, 0);
5230 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
mistachkin1810f222016-04-04 02:33:34 +00005231 stdin_is_interactive = isatty(0);
5232 stdout_is_console = isatty(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005233
drh69b30ab2014-02-27 15:11:52 +00005234#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00005235 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005236 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00005237 sqlite3_sourceid(), SQLITE_SOURCE_ID);
5238 exit(1);
5239 }
drhc7181902014-02-27 15:04:13 +00005240#endif
persicom7e2dfdd2002-04-18 02:46:52 +00005241 main_init(&data);
mistachkin1fe36bb2016-04-04 02:16:44 +00005242#if !SQLITE_SHELL_IS_UTF8
5243 sqlite3_initialize();
5244 argv = sqlite3_malloc64(sizeof(argv[0])*argc);
5245 if( argv==0 ){
5246 raw_printf(stderr, "out of memory\n");
5247 exit(1);
5248 }
5249 for(i=0; i<argc; i++){
5250 argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
5251 if( argv[i]==0 ){
5252 raw_printf(stderr, "out of memory\n");
5253 exit(1);
5254 }
5255 }
5256#endif
mistachkin1810f222016-04-04 02:33:34 +00005257 assert( argc>=1 && argv && argv[0] );
mistachkin1fe36bb2016-04-04 02:16:44 +00005258 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00005259
drh44c2eb12003-04-30 11:38:26 +00005260 /* Make sure we have a valid signal handler early, before anything
5261 ** else is done.
5262 */
drh4c504392000-10-16 22:06:40 +00005263#ifdef SIGINT
5264 signal(SIGINT, interrupt_handler);
5265#endif
drh44c2eb12003-04-30 11:38:26 +00005266
drhac5649a2014-11-28 13:35:03 +00005267#ifdef SQLITE_SHELL_DBNAME_PROC
5268 {
5269 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
5270 ** of a C-function that will provide the name of the database file. Use
5271 ** this compile-time option to embed this shell program in larger
5272 ** applications. */
5273 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
5274 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
5275 warnInmemoryDb = 0;
5276 }
5277#endif
5278
drh22fbcb82004-02-01 01:22:50 +00005279 /* Do an initial pass through the command-line argument to locate
5280 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00005281 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00005282 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00005283 */
drh98d312f2012-10-25 15:23:14 +00005284 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00005285 char *z;
drhc28490c2006-10-26 14:25:58 +00005286 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005287 if( z[0]!='-' ){
5288 if( data.zDbFilename==0 ){
5289 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00005290 }else{
5291 /* Excesss arguments are interpreted as SQL (or dot-commands) and
5292 ** mean that nothing is read from stdin */
5293 readStdin = 0;
5294 nCmd++;
5295 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
5296 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005297 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00005298 exit(1);
5299 }
5300 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00005301 }
drh98d312f2012-10-25 15:23:14 +00005302 }
drhcc3b4f82012-02-07 14:13:50 +00005303 if( z[1]=='-' ) z++;
5304 if( strcmp(z,"-separator")==0
5305 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00005306 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00005307 || strcmp(z,"-cmd")==0
5308 ){
drh98d312f2012-10-25 15:23:14 +00005309 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005310 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00005311 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005312 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00005313 /* Need to check for batch mode here to so we can avoid printing
mistachkin1fe36bb2016-04-04 02:16:44 +00005314 ** informational messages (like from process_sqliterc) before
drh98d312f2012-10-25 15:23:14 +00005315 ** we do the actual processing of arguments later in a second pass.
5316 */
shanef69573d2009-10-24 02:06:14 +00005317 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00005318 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00005319#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00005320 const char *zSize;
5321 sqlite3_int64 szHeap;
5322
drh98d312f2012-10-25 15:23:14 +00005323 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00005324 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00005325 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00005326 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
drhc530b9c2016-07-25 11:27:22 +00005327#else
5328 (void)cmdline_option_value(argc, argv, ++i);
drh9c88d682010-12-17 14:03:01 +00005329#endif
drh44dec872014-08-30 15:49:25 +00005330 }else if( strcmp(z,"-scratch")==0 ){
5331 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005332 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005333 if( sz>400000 ) sz = 400000;
5334 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00005335 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005336 if( n>10 ) n = 10;
5337 if( n<1 ) n = 1;
5338 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
5339 data.shellFlgs |= SHFLG_Scratch;
5340 }else if( strcmp(z,"-pagecache")==0 ){
5341 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005342 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005343 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00005344 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005345 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00005346 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
5347 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00005348 data.shellFlgs |= SHFLG_Pagecache;
5349 }else if( strcmp(z,"-lookaside")==0 ){
5350 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005351 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005352 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005353 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005354 if( n<0 ) n = 0;
5355 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
5356 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00005357#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00005358 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00005359 extern int vfstrace_register(
5360 const char *zTraceName,
5361 const char *zOldVfsName,
5362 int (*xOut)(const char*,void*),
5363 void *pOutArg,
5364 int makeDefault
5365 );
drh2b625e22011-03-16 17:05:28 +00005366 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00005367#endif
drh6f25e892011-07-08 17:02:57 +00005368#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00005369 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00005370 extern int sqlite3_multiple_initialize(const char*,int);
5371 sqlite3_multiplex_initialize(0, 1);
5372#endif
drh7d9f3942013-04-03 01:26:54 +00005373 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00005374 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
5375 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00005376 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00005377 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00005378 if( pVfs ){
5379 sqlite3_vfs_register(pVfs, 1);
5380 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005381 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00005382 exit(1);
5383 }
drh44c2eb12003-04-30 11:38:26 +00005384 }
5385 }
drh98d312f2012-10-25 15:23:14 +00005386 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00005387#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00005388 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00005389 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00005390#else
mistachkinaae280e2015-12-31 19:06:24 +00005391 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00005392 return 1;
drh01b41712005-08-29 23:06:23 +00005393#endif
drh98d312f2012-10-25 15:23:14 +00005394 }
5395 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00005396
drh44c2eb12003-04-30 11:38:26 +00005397 /* Go ahead and open the database file if it already exists. If the
5398 ** file does not exist, delay opening it. This prevents empty database
5399 ** files from being created if a user mistypes the database name argument
5400 ** to the sqlite command-line tool.
5401 */
drhc8d74412004-08-31 23:41:26 +00005402 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00005403 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00005404 }
5405
drh22fbcb82004-02-01 01:22:50 +00005406 /* Process the initialization file if there is one. If no -init option
5407 ** is given on the command line, look for a file named ~/.sqliterc and
5408 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00005409 */
drh534f4df2015-02-28 14:03:35 +00005410 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00005411
drh22fbcb82004-02-01 01:22:50 +00005412 /* Make a second pass through the command-line argument and set
5413 ** options. This second pass is delayed until after the initialization
5414 ** file is processed so that the command-line arguments will override
5415 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00005416 */
drh98d312f2012-10-25 15:23:14 +00005417 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00005418 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005419 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00005420 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00005421 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00005422 i++;
5423 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005424 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00005425 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005426 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00005427 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005428 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00005429 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00005430 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00005431 }else if( strcmp(z,"-csv")==0 ){
5432 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00005433 memcpy(data.colSeparator,",",2);
5434 }else if( strcmp(z,"-ascii")==0 ){
5435 data.mode = MODE_Ascii;
5436 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005437 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00005438 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005439 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00005440 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00005441 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00005442 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00005443 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00005444 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00005445 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005446 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00005447 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00005448 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005449 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005450 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00005451 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005452 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00005453 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00005454 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00005455 }else if( strcmp(z,"-eqp")==0 ){
5456 data.autoEQP = 1;
drheacd29d2016-04-15 15:03:27 +00005457 }else if( strcmp(z,"-eqpfull")==0 ){
5458 data.autoEQP = 2;
shaneh642d8b82010-07-28 16:05:34 +00005459 }else if( strcmp(z,"-stats")==0 ){
5460 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00005461 }else if( strcmp(z,"-scanstats")==0 ){
5462 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00005463 }else if( strcmp(z,"-backslash")==0 ){
5464 /* Undocumented command-line option: -backslash
5465 ** Causes C-style backslash escapes to be evaluated in SQL statements
5466 ** prior to sending the SQL into SQLite. Useful for injecting
5467 ** crazy bytes in the middle of SQL statements for testing and debugging.
5468 */
5469 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00005470 }else if( strcmp(z,"-bail")==0 ){
5471 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00005472 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00005473 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00005474 return 0;
drhc28490c2006-10-26 14:25:58 +00005475 }else if( strcmp(z,"-interactive")==0 ){
5476 stdin_is_interactive = 1;
5477 }else if( strcmp(z,"-batch")==0 ){
5478 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00005479 }else if( strcmp(z,"-heap")==0 ){
5480 i++;
drh44dec872014-08-30 15:49:25 +00005481 }else if( strcmp(z,"-scratch")==0 ){
5482 i+=2;
5483 }else if( strcmp(z,"-pagecache")==0 ){
5484 i+=2;
5485 }else if( strcmp(z,"-lookaside")==0 ){
5486 i+=2;
drh7d9f3942013-04-03 01:26:54 +00005487 }else if( strcmp(z,"-mmap")==0 ){
5488 i++;
drha7e61d82011-03-12 17:02:57 +00005489 }else if( strcmp(z,"-vfs")==0 ){
5490 i++;
drh6f25e892011-07-08 17:02:57 +00005491#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00005492 }else if( strcmp(z,"-vfstrace")==0 ){
5493 i++;
drh6f25e892011-07-08 17:02:57 +00005494#endif
5495#ifdef SQLITE_ENABLE_MULTIPLEX
5496 }else if( strcmp(z,"-multiplex")==0 ){
5497 i++;
5498#endif
drhcc3b4f82012-02-07 14:13:50 +00005499 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00005500 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00005501 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00005502 /* Run commands that follow -cmd first and separately from commands
5503 ** that simply appear on the command-line. This seems goofy. It would
5504 ** be better if all commands ran in the order that they appear. But
5505 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00005506 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00005507 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00005508 if( z[0]=='.' ){
5509 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00005510 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00005511 }else{
drh05782482013-10-24 15:20:20 +00005512 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00005513 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
5514 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005515 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00005516 if( bail_on_error ) return rc!=0 ? rc : 1;
5517 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005518 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00005519 if( bail_on_error ) return rc;
5520 }
5521 }
drh1e5d0e92000-05-31 23:33:17 +00005522 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005523 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
5524 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00005525 return 1;
5526 }
drh700c2522016-02-09 18:39:25 +00005527 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00005528 }
drh44c2eb12003-04-30 11:38:26 +00005529
drhac5649a2014-11-28 13:35:03 +00005530 if( !readStdin ){
5531 /* Run all arguments that do not begin with '-' as if they were separate
5532 ** command-line inputs, except for the argToSkip argument which contains
5533 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00005534 */
drhac5649a2014-11-28 13:35:03 +00005535 for(i=0; i<nCmd; i++){
5536 if( azCmd[i][0]=='.' ){
5537 rc = do_meta_command(azCmd[i], &data);
5538 if( rc ) return rc==2 ? 0 : rc;
5539 }else{
5540 open_db(&data, 0);
5541 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
5542 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005543 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00005544 return rc!=0 ? rc : 1;
5545 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005546 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00005547 return rc;
5548 }
drh6ff13852001-11-25 13:18:23 +00005549 }
drh75897232000-05-29 14:26:00 +00005550 }
drhac5649a2014-11-28 13:35:03 +00005551 free(azCmd);
drh75897232000-05-29 14:26:00 +00005552 }else{
drh44c2eb12003-04-30 11:38:26 +00005553 /* Run commands received from standard input
5554 */
drhc28490c2006-10-26 14:25:58 +00005555 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00005556 char *zHome;
5557 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00005558 int nHistory;
drh75897232000-05-29 14:26:00 +00005559 printf(
drh743e0032011-12-12 16:51:50 +00005560 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00005561 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00005562 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00005563 );
drhb3735912014-02-10 16:13:42 +00005564 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00005565 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00005566 printBold("transient in-memory database");
5567 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00005568 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00005569 }
drh67505e72002-04-19 12:34:06 +00005570 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00005571 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00005572 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00005573 if( (zHistory = malloc(nHistory))!=0 ){
5574 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
5575 }
drh67505e72002-04-19 12:34:06 +00005576 }
drhf5ed7ad2015-06-15 14:43:25 +00005577 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00005578 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00005579 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00005580 shell_stifle_history(100);
5581 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00005582 free(zHistory);
drh67505e72002-04-19 12:34:06 +00005583 }
drhdaffd0e2001-04-11 14:28:42 +00005584 }else{
drhc28490c2006-10-26 14:25:58 +00005585 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00005586 }
5587 }
drh33048c02001-10-01 14:29:22 +00005588 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00005589 if( data.db ){
drhe6229612014-08-18 15:08:26 +00005590 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00005591 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00005592 }
mistachkin1fe36bb2016-04-04 02:16:44 +00005593 sqlite3_free(data.zFreeOnClose);
5594#if !SQLITE_SHELL_IS_UTF8
5595 for(i=0; i<argc; i++) sqlite3_free(argv[i]);
5596 sqlite3_free(argv);
5597#endif
drhc28490c2006-10-26 14:25:58 +00005598 return rc;
drh75897232000-05-29 14:26:00 +00005599}