blob: 4559d4734c772795055e32052ac0a2c5ac8747c0 [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*/
2546static void sql_trace_callback(void *pArg, const char *z){
2547 FILE *f = (FILE*)pArg;
drh4b2590e2014-08-19 19:28:00 +00002548 if( f ){
2549 int i = (int)strlen(z);
2550 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002551 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002552 }
drh42f64e52012-04-04 16:56:23 +00002553}
2554
2555/*
drhd8621b92012-04-17 09:09:33 +00002556** A no-op routine that runs with the ".breakpoint" doc-command. This is
2557** a useful spot to set a debugger breakpoint.
2558*/
2559static void test_breakpoint(void){
2560 static int nCall = 0;
2561 nCall++;
2562}
2563
2564/*
mistachkin636bf9f2014-07-19 20:15:16 +00002565** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002566*/
mistachkin636bf9f2014-07-19 20:15:16 +00002567typedef struct ImportCtx ImportCtx;
2568struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002569 const char *zFile; /* Name of the input file */
2570 FILE *in; /* Read the CSV text from this input stream */
2571 char *z; /* Accumulated text for a field */
2572 int n; /* Number of bytes in z */
2573 int nAlloc; /* Space allocated for z[] */
2574 int nLine; /* Current line number */
2575 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002576 int cColSep; /* The column separator character. (Usually ",") */
2577 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002578};
2579
2580/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002581static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002582 if( p->n+1>=p->nAlloc ){
2583 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002584 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002585 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002586 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002587 exit(1);
2588 }
2589 }
2590 p->z[p->n++] = (char)c;
2591}
2592
2593/* Read a single field of CSV text. Compatible with rfc4180 and extended
2594** with the option of having a separator other than ",".
2595**
2596** + Input comes from p->in.
2597** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002598** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002599** + Use p->cSep as the column separator. The default is ",".
2600** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002601** + Keep track of the line number in p->nLine.
2602** + Store the character that terminates the field in p->cTerm. Store
2603** EOF on end-of-file.
2604** + Report syntax errors on stderr
2605*/
mistachkin44723ce2015-03-21 02:22:37 +00002606static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002607 int c;
2608 int cSep = p->cColSep;
2609 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002610 p->n = 0;
2611 c = fgetc(p->in);
2612 if( c==EOF || seenInterrupt ){
2613 p->cTerm = EOF;
2614 return 0;
2615 }
2616 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002617 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002618 int startLine = p->nLine;
2619 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002620 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002621 while( 1 ){
2622 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002623 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002624 if( c==cQuote ){
2625 if( pc==cQuote ){
2626 pc = 0;
2627 continue;
2628 }
2629 }
2630 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002631 || (c==rSep && pc==cQuote)
2632 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002633 || (c==EOF && pc==cQuote)
2634 ){
2635 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002636 p->cTerm = c;
2637 break;
2638 }
2639 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002640 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002641 p->zFile, p->nLine, cQuote);
2642 }
2643 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002644 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002645 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002646 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002647 break;
2648 }
mistachkin636bf9f2014-07-19 20:15:16 +00002649 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002650 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002651 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002652 }
drhdb95f682013-06-26 22:46:00 +00002653 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002654 while( c!=EOF && c!=cSep && c!=rSep ){
2655 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002656 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002657 }
mistachkin636bf9f2014-07-19 20:15:16 +00002658 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002659 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002660 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002661 }
drhdb95f682013-06-26 22:46:00 +00002662 p->cTerm = c;
2663 }
drh8dd675e2013-07-12 21:09:24 +00002664 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002665 return p->z;
2666}
2667
mistachkin636bf9f2014-07-19 20:15:16 +00002668/* Read a single field of ASCII delimited text.
2669**
2670** + Input comes from p->in.
2671** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002672** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002673** + Use p->cSep as the column separator. The default is "\x1F".
2674** + Use p->rSep as the row separator. The default is "\x1E".
2675** + Keep track of the row number in p->nLine.
2676** + Store the character that terminates the field in p->cTerm. Store
2677** EOF on end-of-file.
2678** + Report syntax errors on stderr
2679*/
mistachkin44723ce2015-03-21 02:22:37 +00002680static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002681 int c;
2682 int cSep = p->cColSep;
2683 int rSep = p->cRowSep;
2684 p->n = 0;
2685 c = fgetc(p->in);
2686 if( c==EOF || seenInterrupt ){
2687 p->cTerm = EOF;
2688 return 0;
2689 }
2690 while( c!=EOF && c!=cSep && c!=rSep ){
2691 import_append_char(p, c);
2692 c = fgetc(p->in);
2693 }
2694 if( c==rSep ){
2695 p->nLine++;
2696 }
2697 p->cTerm = c;
2698 if( p->z ) p->z[p->n] = 0;
2699 return p->z;
2700}
2701
drhdb95f682013-06-26 22:46:00 +00002702/*
drh4bbcf102014-02-06 02:46:08 +00002703** Try to transfer data for table zTable. If an error is seen while
2704** moving forward, try to go backwards. The backwards movement won't
2705** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002706*/
mistachkine31ae902014-02-06 01:15:29 +00002707static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002708 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002709 sqlite3 *newDb,
2710 const char *zTable
2711){
mistachkin1fe36bb2016-04-04 02:16:44 +00002712 sqlite3_stmt *pQuery = 0;
drh3350ce92014-02-06 00:49:12 +00002713 sqlite3_stmt *pInsert = 0;
2714 char *zQuery = 0;
2715 char *zInsert = 0;
2716 int rc;
2717 int i, j, n;
2718 int nTable = (int)strlen(zTable);
2719 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002720 int cnt = 0;
2721 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002722
2723 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2724 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2725 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002726 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002727 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2728 zQuery);
2729 goto end_data_xfer;
2730 }
2731 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002732 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002733 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002734 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002735 goto end_data_xfer;
2736 }
2737 sqlite3_snprintf(200+nTable,zInsert,
2738 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2739 i = (int)strlen(zInsert);
2740 for(j=1; j<n; j++){
2741 memcpy(zInsert+i, ",?", 2);
2742 i += 2;
2743 }
2744 memcpy(zInsert+i, ");", 3);
2745 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2746 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002747 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002748 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2749 zQuery);
2750 goto end_data_xfer;
2751 }
2752 for(k=0; k<2; k++){
2753 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2754 for(i=0; i<n; i++){
2755 switch( sqlite3_column_type(pQuery, i) ){
2756 case SQLITE_NULL: {
2757 sqlite3_bind_null(pInsert, i+1);
2758 break;
2759 }
2760 case SQLITE_INTEGER: {
2761 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2762 break;
2763 }
2764 case SQLITE_FLOAT: {
2765 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2766 break;
2767 }
2768 case SQLITE_TEXT: {
2769 sqlite3_bind_text(pInsert, i+1,
2770 (const char*)sqlite3_column_text(pQuery,i),
2771 -1, SQLITE_STATIC);
2772 break;
2773 }
2774 case SQLITE_BLOB: {
2775 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2776 sqlite3_column_bytes(pQuery,i),
2777 SQLITE_STATIC);
2778 break;
2779 }
2780 }
2781 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002782 rc = sqlite3_step(pInsert);
2783 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002784 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002785 sqlite3_errmsg(newDb));
2786 }
drh3350ce92014-02-06 00:49:12 +00002787 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002788 cnt++;
2789 if( (cnt%spinRate)==0 ){
2790 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2791 fflush(stdout);
2792 }
drh3350ce92014-02-06 00:49:12 +00002793 } /* End while */
2794 if( rc==SQLITE_DONE ) break;
2795 sqlite3_finalize(pQuery);
2796 sqlite3_free(zQuery);
2797 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2798 zTable);
2799 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2800 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002801 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002802 break;
drh3350ce92014-02-06 00:49:12 +00002803 }
2804 } /* End for(k=0...) */
2805
2806end_data_xfer:
2807 sqlite3_finalize(pQuery);
2808 sqlite3_finalize(pInsert);
2809 sqlite3_free(zQuery);
2810 sqlite3_free(zInsert);
2811}
2812
2813
2814/*
2815** Try to transfer all rows of the schema that match zWhere. For
2816** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002817** If an error is encountered while moving forward through the
2818** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002819*/
mistachkine31ae902014-02-06 01:15:29 +00002820static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002821 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002822 sqlite3 *newDb,
2823 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002824 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002825){
2826 sqlite3_stmt *pQuery = 0;
2827 char *zQuery = 0;
2828 int rc;
2829 const unsigned char *zName;
2830 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002831 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002832
2833 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2834 " WHERE %s", zWhere);
2835 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2836 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002837 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002838 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2839 zQuery);
2840 goto end_schema_xfer;
2841 }
2842 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2843 zName = sqlite3_column_text(pQuery, 0);
2844 zSql = sqlite3_column_text(pQuery, 1);
2845 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002846 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2847 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002848 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002849 sqlite3_free(zErrMsg);
2850 zErrMsg = 0;
2851 }
drh3350ce92014-02-06 00:49:12 +00002852 if( xForEach ){
2853 xForEach(p, newDb, (const char*)zName);
2854 }
2855 printf("done\n");
2856 }
2857 if( rc!=SQLITE_DONE ){
2858 sqlite3_finalize(pQuery);
2859 sqlite3_free(zQuery);
2860 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2861 " WHERE %s ORDER BY rowid DESC", zWhere);
2862 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2863 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002864 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002865 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2866 zQuery);
2867 goto end_schema_xfer;
2868 }
2869 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2870 zName = sqlite3_column_text(pQuery, 0);
2871 zSql = sqlite3_column_text(pQuery, 1);
2872 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002873 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2874 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002875 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002876 sqlite3_free(zErrMsg);
2877 zErrMsg = 0;
2878 }
drh3350ce92014-02-06 00:49:12 +00002879 if( xForEach ){
2880 xForEach(p, newDb, (const char*)zName);
2881 }
2882 printf("done\n");
2883 }
2884 }
2885end_schema_xfer:
2886 sqlite3_finalize(pQuery);
2887 sqlite3_free(zQuery);
2888}
2889
2890/*
2891** Open a new database file named "zNewDb". Try to recover as much information
2892** as possible out of the main database (which might be corrupt) and write it
2893** into zNewDb.
2894*/
drhdcd87a92014-08-18 13:45:42 +00002895static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002896 int rc;
2897 sqlite3 *newDb = 0;
2898 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002899 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002900 return;
2901 }
2902 rc = sqlite3_open(zNewDb, &newDb);
2903 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002904 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002905 sqlite3_errmsg(newDb));
2906 }else{
drh54d0d2d2014-04-03 00:32:13 +00002907 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002908 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002909 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2910 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002911 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002912 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002913 }
2914 sqlite3_close(newDb);
2915}
2916
2917/*
drhc2ce0be2014-05-29 12:36:14 +00002918** Change the output file back to stdout
2919*/
drhdcd87a92014-08-18 13:45:42 +00002920static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002921 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002922#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002923 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002924#endif
drhc2ce0be2014-05-29 12:36:14 +00002925 }else{
2926 output_file_close(p->out);
2927 }
2928 p->outfile[0] = 0;
2929 p->out = stdout;
2930}
2931
2932/*
drhf7502f02015-02-06 14:19:44 +00002933** Run an SQL command and return the single integer result.
2934*/
2935static int db_int(ShellState *p, const char *zSql){
2936 sqlite3_stmt *pStmt;
2937 int res = 0;
2938 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2939 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2940 res = sqlite3_column_int(pStmt,0);
2941 }
2942 sqlite3_finalize(pStmt);
2943 return res;
2944}
2945
2946/*
2947** Convert a 2-byte or 4-byte big-endian integer into a native integer
2948*/
2949unsigned int get2byteInt(unsigned char *a){
2950 return (a[0]<<8) + a[1];
2951}
2952unsigned int get4byteInt(unsigned char *a){
2953 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2954}
2955
2956/*
2957** Implementation of the ".info" command.
2958**
2959** Return 1 on error, 2 to exit, and 0 otherwise.
2960*/
drh0e55db12015-02-06 14:51:13 +00002961static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002962 static const struct { const char *zName; int ofst; } aField[] = {
2963 { "file change counter:", 24 },
2964 { "database page count:", 28 },
2965 { "freelist page count:", 36 },
2966 { "schema cookie:", 40 },
2967 { "schema format:", 44 },
2968 { "default cache size:", 48 },
2969 { "autovacuum top root:", 52 },
2970 { "incremental vacuum:", 64 },
2971 { "text encoding:", 56 },
2972 { "user version:", 60 },
2973 { "application id:", 68 },
2974 { "software version:", 96 },
2975 };
drh0e55db12015-02-06 14:51:13 +00002976 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2977 { "number of tables:",
2978 "SELECT count(*) FROM %s WHERE type='table'" },
2979 { "number of indexes:",
2980 "SELECT count(*) FROM %s WHERE type='index'" },
2981 { "number of triggers:",
2982 "SELECT count(*) FROM %s WHERE type='trigger'" },
2983 { "number of views:",
2984 "SELECT count(*) FROM %s WHERE type='view'" },
2985 { "schema size:",
2986 "SELECT total(length(sql)) FROM %s" },
2987 };
mistachkinbfe8bd52015-11-17 19:17:14 +00002988 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00002989 int i;
2990 char *zSchemaTab;
2991 char *zDb = nArg>=2 ? azArg[1] : "main";
2992 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00002993 open_db(p, 0);
2994 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00002995 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00002996 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
2997 return 1;
2998 }
2999 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
3000 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003001 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00003002 return 1;
3003 }
3004 i = get2byteInt(aHdr+16);
3005 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00003006 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
3007 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
3008 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
3009 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00003010 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00003011 int ofst = aField[i].ofst;
3012 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00003013 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00003014 switch( ofst ){
3015 case 56: {
mistachkin1fe36bb2016-04-04 02:16:44 +00003016 if( val==1 ) raw_printf(p->out, " (utf8)");
3017 if( val==2 ) raw_printf(p->out, " (utf16le)");
3018 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00003019 }
3020 }
mistachkinaae280e2015-12-31 19:06:24 +00003021 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00003022 }
drh0e55db12015-02-06 14:51:13 +00003023 if( zDb==0 ){
3024 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
3025 }else if( strcmp(zDb,"temp")==0 ){
3026 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
3027 }else{
3028 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
3029 }
drhf5ed7ad2015-06-15 14:43:25 +00003030 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00003031 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
3032 int val = db_int(p, zSql);
3033 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00003034 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00003035 }
3036 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00003037 return 0;
3038}
3039
dand95bb392015-09-30 11:19:05 +00003040/*
3041** Print the current sqlite3_errmsg() value to stderr and return 1.
3042*/
3043static int shellDatabaseError(sqlite3 *db){
3044 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00003045 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00003046 return 1;
3047}
3048
3049/*
3050** Print an out-of-memory message to stderr and return 1.
3051*/
3052static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00003053 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00003054 return 1;
3055}
drhf7502f02015-02-06 14:19:44 +00003056
3057/*
drh4926fec2016-04-13 15:33:42 +00003058** Compare the string as a command-line option with either one or two
3059** initial "-" characters.
3060*/
3061static int optionMatch(const char *zStr, const char *zOpt){
3062 if( zStr[0]!='-' ) return 0;
3063 zStr++;
3064 if( zStr[0]=='-' ) zStr++;
3065 return strcmp(zStr, zOpt)==0;
3066}
3067
3068/*
drh75897232000-05-29 14:26:00 +00003069** If an input line begins with "." then invoke this routine to
3070** process that line.
drh67505e72002-04-19 12:34:06 +00003071**
drh47ad6842006-11-08 12:25:42 +00003072** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00003073*/
drhdcd87a92014-08-18 13:45:42 +00003074static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00003075 int h = 1;
drh75897232000-05-29 14:26:00 +00003076 int nArg = 0;
3077 int n, c;
drh67505e72002-04-19 12:34:06 +00003078 int rc = 0;
drh75897232000-05-29 14:26:00 +00003079 char *azArg[50];
3080
3081 /* Parse the input line into tokens.
3082 */
mistachkin8e189222015-04-19 21:43:16 +00003083 while( zLine[h] && nArg<ArraySize(azArg) ){
3084 while( IsSpace(zLine[h]) ){ h++; }
3085 if( zLine[h]==0 ) break;
3086 if( zLine[h]=='\'' || zLine[h]=='"' ){
3087 int delim = zLine[h++];
3088 azArg[nArg++] = &zLine[h];
mistachkin1fe36bb2016-04-04 02:16:44 +00003089 while( zLine[h] && zLine[h]!=delim ){
mistachkin8e189222015-04-19 21:43:16 +00003090 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
mistachkin1fe36bb2016-04-04 02:16:44 +00003091 h++;
drh4c56b992013-06-27 13:26:55 +00003092 }
mistachkin8e189222015-04-19 21:43:16 +00003093 if( zLine[h]==delim ){
3094 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00003095 }
drhfeac5f82004-08-01 00:10:45 +00003096 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003097 }else{
mistachkin8e189222015-04-19 21:43:16 +00003098 azArg[nArg++] = &zLine[h];
3099 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
3100 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00003101 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003102 }
3103 }
3104
3105 /* Process the input line.
3106 */
shane9bd1b442009-10-23 01:27:39 +00003107 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00003108 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00003109 c = azArg[0][0];
drhde613c62016-04-04 17:23:10 +00003110
3111 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
3112 if( nArg!=2 ){
3113 raw_printf(stderr, "Usage: .auth ON|OFF\n");
3114 rc = 1;
3115 goto meta_command_exit;
3116 }
3117 open_db(p, 0);
3118 if( booleanValue(azArg[1]) ){
3119 sqlite3_set_authorizer(p->db, shellAuth, p);
3120 }else{
3121 sqlite3_set_authorizer(p->db, 0, 0);
3122 }
3123 }else
3124
drh5c7976f2014-02-10 19:59:27 +00003125 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
3126 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
3127 ){
drhbc46f022013-01-23 18:53:23 +00003128 const char *zDestFile = 0;
3129 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00003130 sqlite3 *pDest;
3131 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00003132 int j;
3133 for(j=1; j<nArg; j++){
3134 const char *z = azArg[j];
3135 if( z[0]=='-' ){
3136 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00003137 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00003138 {
mistachkinaae280e2015-12-31 19:06:24 +00003139 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00003140 return 1;
3141 }
3142 }else if( zDestFile==0 ){
3143 zDestFile = azArg[j];
3144 }else if( zDb==0 ){
3145 zDb = zDestFile;
3146 zDestFile = azArg[j];
3147 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003148 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00003149 return 1;
3150 }
drh9ff849f2009-02-04 20:55:57 +00003151 }
drhbc46f022013-01-23 18:53:23 +00003152 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003153 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00003154 return 1;
3155 }
3156 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00003157 rc = sqlite3_open(zDestFile, &pDest);
3158 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003159 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00003160 sqlite3_close(pDest);
3161 return 1;
3162 }
drh05782482013-10-24 15:20:20 +00003163 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003164 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
3165 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003166 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00003167 sqlite3_close(pDest);
3168 return 1;
3169 }
3170 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
3171 sqlite3_backup_finish(pBackup);
3172 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003173 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00003174 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003175 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00003176 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003177 }
3178 sqlite3_close(pDest);
3179 }else
3180
drhc2ce0be2014-05-29 12:36:14 +00003181 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
3182 if( nArg==2 ){
3183 bail_on_error = booleanValue(azArg[1]);
3184 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003185 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003186 rc = 1;
3187 }
drhc49f44e2006-10-26 18:15:42 +00003188 }else
3189
mistachkinf21979d2015-01-18 05:35:01 +00003190 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
3191 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00003192 if( booleanValue(azArg[1]) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003193 setBinaryMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003194 }else{
mistachkin1fe36bb2016-04-04 02:16:44 +00003195 setTextMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003196 }
mistachkinf21979d2015-01-18 05:35:01 +00003197 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003198 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00003199 rc = 1;
3200 }
3201 }else
3202
drhd8621b92012-04-17 09:09:33 +00003203 /* The undocumented ".breakpoint" command causes a call to the no-op
3204 ** routine named test_breakpoint().
3205 */
3206 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
3207 test_breakpoint();
3208 }else
3209
drhdf12f1c2015-12-07 21:46:19 +00003210 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
3211 if( nArg==2 ){
3212 p->countChanges = booleanValue(azArg[1]);
3213 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003214 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00003215 rc = 1;
3216 }
3217 }else
3218
drhc2ce0be2014-05-29 12:36:14 +00003219 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
3220 if( nArg==2 ){
3221 tryToClone(p, azArg[1]);
3222 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003223 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003224 rc = 1;
3225 }
mistachkine31ae902014-02-06 01:15:29 +00003226 }else
3227
drhc2ce0be2014-05-29 12:36:14 +00003228 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003229 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00003230 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003231 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00003232 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00003233 data.showHeader = 1;
drh700c2522016-02-09 18:39:25 +00003234 data.cMode = data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00003235 data.colWidth[0] = 3;
3236 data.colWidth[1] = 15;
3237 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00003238 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00003239 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00003240 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003241 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003242 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003243 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00003244 }
3245 }else
3246
drh0e55db12015-02-06 14:51:13 +00003247 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
3248 rc = shell_dbinfo_command(p, nArg, azArg);
3249 }else
3250
drhc2ce0be2014-05-29 12:36:14 +00003251 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00003252 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00003253 /* When playing back a "dump", the content might appear in an order
3254 ** which causes immediate foreign key constraints to be violated.
3255 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00003256 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003257 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003258 rc = 1;
3259 goto meta_command_exit;
3260 }
mistachkinaae280e2015-12-31 19:06:24 +00003261 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
3262 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00003263 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00003264 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00003265 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00003266 if( nArg==1 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003267 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003268 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003269 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00003270 );
mistachkin1fe36bb2016-04-04 02:16:44 +00003271 run_schema_dump_query(p,
drh4f324762009-05-21 14:51:03 +00003272 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003273 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00003274 );
drh2f464a02011-10-13 00:41:49 +00003275 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003276 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00003277 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00003278 );
drh4c653a02000-06-07 01:27:47 +00003279 }else{
3280 int i;
drhdd3d4592004-08-30 01:54:05 +00003281 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00003282 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00003283 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003284 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00003285 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00003286 " AND sql NOT NULL");
3287 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003288 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00003289 "WHERE sql NOT NULL"
3290 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00003291 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00003292 );
danielk1977bc6ada42004-06-30 08:20:16 +00003293 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00003294 }
3295 }
drh45e29d82006-11-20 16:21:10 +00003296 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00003297 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00003298 p->writableSchema = 0;
3299 }
drh56197952011-10-13 16:30:13 +00003300 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
3301 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00003302 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00003303 }else
drh75897232000-05-29 14:26:00 +00003304
drhc2ce0be2014-05-29 12:36:14 +00003305 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
3306 if( nArg==2 ){
3307 p->echoOn = booleanValue(azArg[1]);
3308 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003309 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003310 rc = 1;
3311 }
drhdaffd0e2001-04-11 14:28:42 +00003312 }else
3313
drhc2ce0be2014-05-29 12:36:14 +00003314 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
3315 if( nArg==2 ){
drheacd29d2016-04-15 15:03:27 +00003316 if( strcmp(azArg[1],"full")==0 ){
3317 p->autoEQP = 2;
3318 }else{
3319 p->autoEQP = booleanValue(azArg[1]);
3320 }
drhc2ce0be2014-05-29 12:36:14 +00003321 }else{
drheacd29d2016-04-15 15:03:27 +00003322 raw_printf(stderr, "Usage: .eqp on|off|full\n");
drhc2ce0be2014-05-29 12:36:14 +00003323 rc = 1;
mistachkin1fe36bb2016-04-04 02:16:44 +00003324 }
drhefbf3b12014-02-28 20:47:24 +00003325 }else
3326
drhd3ac7d92013-01-25 18:33:43 +00003327 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00003328 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00003329 rc = 2;
drh75897232000-05-29 14:26:00 +00003330 }else
3331
drhc2ce0be2014-05-29 12:36:14 +00003332 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00003333 int val = 1;
3334 if( nArg>=2 ){
3335 if( strcmp(azArg[1],"auto")==0 ){
3336 val = 99;
3337 }else{
3338 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003339 }
drh700c2522016-02-09 18:39:25 +00003340 }
3341 if( val==1 && p->mode!=MODE_Explain ){
3342 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003343 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003344 p->autoExplain = 0;
3345 }else if( val==0 ){
3346 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3347 p->autoExplain = 0;
3348 }else if( val==99 ){
3349 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3350 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003351 }
drh75897232000-05-29 14:26:00 +00003352 }else
3353
drhc1971542014-06-23 23:28:13 +00003354 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003355 ShellState data;
drhc1971542014-06-23 23:28:13 +00003356 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003357 int doStats = 0;
drh4926fec2016-04-13 15:33:42 +00003358 memcpy(&data, p, sizeof(data));
3359 data.showHeader = 0;
3360 data.cMode = data.mode = MODE_Semi;
3361 if( nArg==2 && optionMatch(azArg[1], "indent") ){
3362 data.cMode = data.mode = MODE_Pretty;
3363 nArg = 1;
3364 }
drhc1971542014-06-23 23:28:13 +00003365 if( nArg!=1 ){
drh4926fec2016-04-13 15:33:42 +00003366 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
drhc1971542014-06-23 23:28:13 +00003367 rc = 1;
3368 goto meta_command_exit;
3369 }
3370 open_db(p, 0);
drhc1971542014-06-23 23:28:13 +00003371 rc = sqlite3_exec(p->db,
3372 "SELECT sql FROM"
3373 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3374 " FROM sqlite_master UNION ALL"
3375 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003376 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003377 "ORDER BY rowid",
3378 callback, &data, &zErrMsg
3379 );
drh56f674c2014-07-18 14:43:29 +00003380 if( rc==SQLITE_OK ){
3381 sqlite3_stmt *pStmt;
3382 rc = sqlite3_prepare_v2(p->db,
3383 "SELECT rowid FROM sqlite_master"
3384 " WHERE name GLOB 'sqlite_stat[134]'",
3385 -1, &pStmt, 0);
3386 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3387 sqlite3_finalize(pStmt);
3388 }
3389 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003390 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003391 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003392 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003393 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3394 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003395 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003396 data.zDestTable = "sqlite_stat1";
3397 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3398 shell_callback, &data,&zErrMsg);
3399 data.zDestTable = "sqlite_stat3";
3400 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3401 shell_callback, &data,&zErrMsg);
3402 data.zDestTable = "sqlite_stat4";
3403 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3404 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003405 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003406 }
drhc1971542014-06-23 23:28:13 +00003407 }else
3408
drhc2ce0be2014-05-29 12:36:14 +00003409 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3410 if( nArg==2 ){
3411 p->showHeader = booleanValue(azArg[1]);
3412 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003413 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003414 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003415 }
drh75897232000-05-29 14:26:00 +00003416 }else
3417
drhc2ce0be2014-05-29 12:36:14 +00003418 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003419 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003420 }else
3421
3422 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003423 char *zTable; /* Insert data into this table */
3424 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003425 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003426 int nCol; /* Number of columns in the table */
3427 int nByte; /* Number of bytes in an SQL string */
3428 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003429 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003430 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003431 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003432 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003433 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3434 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003435
drhc2ce0be2014-05-29 12:36:14 +00003436 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003437 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003438 goto meta_command_exit;
3439 }
drh01f37542014-05-31 15:43:33 +00003440 zFile = azArg[1];
3441 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003442 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003443 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003444 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003445 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003446 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003447 raw_printf(stderr,
3448 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003449 return 1;
drhfeac5f82004-08-01 00:10:45 +00003450 }
drhdb95f682013-06-26 22:46:00 +00003451 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003452 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003453 " for import\n");
3454 return 1;
3455 }
mistachkin636bf9f2014-07-19 20:15:16 +00003456 nSep = strlen30(p->rowSeparator);
3457 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003458 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003459 return 1;
3460 }
mistachkine0d68852014-12-11 03:12:33 +00003461 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3462 /* When importing CSV (only), if the row separator is set to the
3463 ** default output row separator, change it to the default input
3464 ** row separator. This avoids having to maintain different input
3465 ** and output row separators. */
3466 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3467 nSep = strlen30(p->rowSeparator);
3468 }
mistachkin636bf9f2014-07-19 20:15:16 +00003469 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003470 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003471 " for import\n");
3472 return 1;
3473 }
3474 sCtx.zFile = zFile;
3475 sCtx.nLine = 1;
3476 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003477#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003478 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003479 return 1;
3480#else
mistachkin636bf9f2014-07-19 20:15:16 +00003481 sCtx.in = popen(sCtx.zFile+1, "r");
3482 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003483 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003484#endif
drh5bde8162013-06-27 14:07:53 +00003485 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003486 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003487 xCloser = fclose;
3488 }
mistachkin636bf9f2014-07-19 20:15:16 +00003489 if( p->mode==MODE_Ascii ){
3490 xRead = ascii_read_one_field;
3491 }else{
3492 xRead = csv_read_one_field;
3493 }
3494 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003495 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003496 return 1;
3497 }
mistachkin636bf9f2014-07-19 20:15:16 +00003498 sCtx.cColSep = p->colSeparator[0];
3499 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003500 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003501 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003502 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003503 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003504 return 1;
3505 }
drh4f21c4a2008-12-10 22:15:00 +00003506 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003507 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003508 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003509 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003510 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3511 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003512 while( xRead(&sCtx) ){
drhd8c22ac2016-02-25 13:33:02 +00003513 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003514 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003515 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003516 }
drh5bde8162013-06-27 14:07:53 +00003517 if( cSep=='(' ){
3518 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003519 sqlite3_free(sCtx.z);
3520 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003521 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003522 return 1;
3523 }
drhdb95f682013-06-26 22:46:00 +00003524 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3525 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3526 sqlite3_free(zCreate);
3527 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003528 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003529 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003530 sqlite3_free(sCtx.z);
3531 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003532 return 1;
3533 }
drhc7181902014-02-27 15:04:13 +00003534 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003535 }
drhfeac5f82004-08-01 00:10:45 +00003536 sqlite3_free(zSql);
3537 if( rc ){
shane916f9612009-10-23 00:37:15 +00003538 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00003539 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003540 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003541 return 1;
drhfeac5f82004-08-01 00:10:45 +00003542 }
shane916f9612009-10-23 00:37:15 +00003543 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003544 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003545 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003546 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003547 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003548 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003549 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003550 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003551 return 1;
3552 }
drhdb95f682013-06-26 22:46:00 +00003553 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003554 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003555 for(i=1; i<nCol; i++){
3556 zSql[j++] = ',';
3557 zSql[j++] = '?';
3558 }
3559 zSql[j++] = ')';
3560 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003561 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003562 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003563 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003564 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003565 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003566 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003567 return 1;
drhfeac5f82004-08-01 00:10:45 +00003568 }
mistachkin8e189222015-04-19 21:43:16 +00003569 needCommit = sqlite3_get_autocommit(p->db);
3570 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003571 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003572 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003573 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003574 char *z = xRead(&sCtx);
3575 /*
3576 ** Did we reach end-of-file before finding any columns?
3577 ** If so, stop instead of NULL filling the remaining columns.
3578 */
drhdb95f682013-06-26 22:46:00 +00003579 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003580 /*
3581 ** Did we reach end-of-file OR end-of-line before finding any
3582 ** columns in ASCII mode? If so, stop instead of NULL filling
3583 ** the remaining columns.
3584 */
3585 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003586 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003587 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00003588 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003589 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003590 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003591 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003592 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003593 }
drhfeac5f82004-08-01 00:10:45 +00003594 }
mistachkin636bf9f2014-07-19 20:15:16 +00003595 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003596 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003597 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003598 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003599 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00003600 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003601 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003602 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003603 }
drhdb95f682013-06-26 22:46:00 +00003604 if( i>=nCol ){
3605 sqlite3_step(pStmt);
3606 rc = sqlite3_reset(pStmt);
3607 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003608 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
3609 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003610 }
3611 }
mistachkin636bf9f2014-07-19 20:15:16 +00003612 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003613
mistachkin636bf9f2014-07-19 20:15:16 +00003614 xCloser(sCtx.in);
3615 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003616 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003617 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003618 }else
3619
drh0e55db12015-02-06 14:51:13 +00003620 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3621 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003622 ShellState data;
drh75897232000-05-29 14:26:00 +00003623 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003624 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003625 memcpy(&data, p, sizeof(data));
3626 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003627 data.cMode = data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003628 if( nArg==1 ){
3629 rc = sqlite3_exec(p->db,
3630 "SELECT name FROM sqlite_master "
3631 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3632 "UNION ALL "
3633 "SELECT name FROM sqlite_temp_master "
3634 "WHERE type='index' "
3635 "ORDER BY 1",
3636 callback, &data, &zErrMsg
3637 );
drhc2ce0be2014-05-29 12:36:14 +00003638 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003639 zShellStatic = azArg[1];
3640 rc = sqlite3_exec(p->db,
3641 "SELECT name FROM sqlite_master "
3642 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3643 "UNION ALL "
3644 "SELECT name FROM sqlite_temp_master "
3645 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3646 "ORDER BY 1",
3647 callback, &data, &zErrMsg
3648 );
3649 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003650 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003651 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003652 rc = 1;
3653 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003654 }
drh75897232000-05-29 14:26:00 +00003655 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003656 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003657 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003658 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003659 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003660 raw_printf(stderr,
3661 "Error: querying sqlite_master and sqlite_temp_master\n");
shane86f5bdb2009-10-24 02:00:07 +00003662 rc = 1;
drh75897232000-05-29 14:26:00 +00003663 }
3664 }else
3665
drhae5e4452007-05-03 17:18:36 +00003666#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003667 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003668 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003669 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3670 iotrace = 0;
3671 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003672 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003673 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003674 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003675 iotrace = stdout;
3676 }else{
3677 iotrace = fopen(azArg[1], "w");
3678 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003679 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003680 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003681 rc = 1;
drhb0603412007-02-28 04:47:26 +00003682 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003683 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003684 }
3685 }
3686 }else
drhae5e4452007-05-03 17:18:36 +00003687#endif
drh1a513372015-05-02 17:40:23 +00003688 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3689 static const struct {
3690 const char *zLimitName; /* Name of a limit */
3691 int limitCode; /* Integer code for that limit */
3692 } aLimit[] = {
3693 { "length", SQLITE_LIMIT_LENGTH },
3694 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3695 { "column", SQLITE_LIMIT_COLUMN },
3696 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3697 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3698 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3699 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3700 { "attached", SQLITE_LIMIT_ATTACHED },
3701 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3702 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3703 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3704 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3705 };
3706 int i, n2;
3707 open_db(p, 0);
3708 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003709 for(i=0; i<ArraySize(aLimit); i++){
mistachkin1fe36bb2016-04-04 02:16:44 +00003710 printf("%20s %d\n", aLimit[i].zLimitName,
drh1a513372015-05-02 17:40:23 +00003711 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3712 }
3713 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003714 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00003715 rc = 1;
3716 goto meta_command_exit;
3717 }else{
3718 int iLimit = -1;
3719 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003720 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003721 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3722 if( iLimit<0 ){
3723 iLimit = i;
3724 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003725 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00003726 rc = 1;
3727 goto meta_command_exit;
3728 }
3729 }
3730 }
3731 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003732 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00003733 "enter \".limits\" with no arguments for a list.\n",
3734 azArg[1]);
3735 rc = 1;
3736 goto meta_command_exit;
3737 }
3738 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003739 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3740 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003741 }
3742 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3743 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3744 }
3745 }else
drhb0603412007-02-28 04:47:26 +00003746
drh70df4fe2006-06-13 15:12:21 +00003747#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003748 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003749 const char *zFile, *zProc;
3750 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003751 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003752 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00003753 rc = 1;
3754 goto meta_command_exit;
3755 }
drh1e397f82006-06-08 15:28:43 +00003756 zFile = azArg[1];
3757 zProc = nArg>=3 ? azArg[2] : 0;
drh52195c32016-05-28 15:03:06 +00003758 /* open_db(p, 0); */
drh1e397f82006-06-08 15:28:43 +00003759 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3760 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003761 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003762 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003763 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003764 }
3765 }else
drh70df4fe2006-06-13 15:12:21 +00003766#endif
drh1e397f82006-06-08 15:28:43 +00003767
drhc2ce0be2014-05-29 12:36:14 +00003768 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3769 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003770 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003771 rc = 1;
3772 }else{
3773 const char *zFile = azArg[1];
3774 output_file_close(p->pLog);
3775 p->pLog = output_file_open(zFile);
3776 }
drh127f9d72010-02-23 01:47:00 +00003777 }else
3778
drhc2ce0be2014-05-29 12:36:14 +00003779 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3780 const char *zMode = nArg>=2 ? azArg[1] : "";
3781 int n2 = (int)strlen(zMode);
3782 int c2 = zMode[0];
3783 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003784 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003785 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003786 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003787 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003788 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003789 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003790 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003791 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003792 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003793 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003794 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003795 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003796 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003797 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003798 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003799 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003800 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003801 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003802 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003803 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003804 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3805 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003806 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3807 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003808 }else {
mistachkinaae280e2015-12-31 19:06:24 +00003809 raw_printf(stderr, "Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003810 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003811 rc = 1;
drh75897232000-05-29 14:26:00 +00003812 }
drh700c2522016-02-09 18:39:25 +00003813 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00003814 }else
3815
drhc2ce0be2014-05-29 12:36:14 +00003816 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3817 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003818 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3819 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003820 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003821 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003822 rc = 1;
3823 }
3824 }else
3825
drh05782482013-10-24 15:20:20 +00003826 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3827 sqlite3 *savedDb = p->db;
3828 const char *zSavedFilename = p->zDbFilename;
3829 char *zNewFilename = 0;
3830 p->db = 0;
drhbbe031f2015-06-17 17:08:22 +00003831 if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3832 p->zDbFilename = zNewFilename;
drh05782482013-10-24 15:20:20 +00003833 open_db(p, 1);
3834 if( p->db!=0 ){
drhe6229612014-08-18 15:08:26 +00003835 session_close_all(p);
drh05782482013-10-24 15:20:20 +00003836 sqlite3_close(savedDb);
3837 sqlite3_free(p->zFreeOnClose);
3838 p->zFreeOnClose = zNewFilename;
3839 }else{
3840 sqlite3_free(zNewFilename);
3841 p->db = savedDb;
3842 p->zDbFilename = zSavedFilename;
3843 }
3844 }else
3845
drhc2ce0be2014-05-29 12:36:14 +00003846 if( c=='o'
3847 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3848 ){
3849 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3850 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003851 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00003852 rc = 1;
3853 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003854 }
drhc2ce0be2014-05-29 12:36:14 +00003855 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3856 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003857 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003858 rc = 1;
3859 goto meta_command_exit;
3860 }
3861 p->outCount = 2;
3862 }else{
3863 p->outCount = 0;
3864 }
3865 output_reset(p);
3866 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003867#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003868 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003869 rc = 1;
3870 p->out = stdout;
3871#else
drhc2ce0be2014-05-29 12:36:14 +00003872 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003873 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003874 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003875 p->out = stdout;
3876 rc = 1;
3877 }else{
drhc2ce0be2014-05-29 12:36:14 +00003878 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003879 }
drh8cd5b252015-03-02 22:06:43 +00003880#endif
drh75897232000-05-29 14:26:00 +00003881 }else{
drhc2ce0be2014-05-29 12:36:14 +00003882 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003883 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003884 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003885 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003886 }
drh75897232000-05-29 14:26:00 +00003887 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003888 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003889 } else {
drhc2ce0be2014-05-29 12:36:14 +00003890 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003891 }
3892 }
3893 }else
3894
drh078b1fd2012-09-21 13:40:02 +00003895 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3896 int i;
3897 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00003898 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00003899 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00003900 }
mistachkinaae280e2015-12-31 19:06:24 +00003901 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00003902 }else
3903
drhc2ce0be2014-05-29 12:36:14 +00003904 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003905 if( nArg >= 2) {
3906 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3907 }
3908 if( nArg >= 3) {
3909 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3910 }
3911 }else
3912
drhc2ce0be2014-05-29 12:36:14 +00003913 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003914 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003915 }else
3916
drhc2ce0be2014-05-29 12:36:14 +00003917 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3918 FILE *alt;
3919 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003920 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003921 rc = 1;
3922 goto meta_command_exit;
3923 }
3924 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003925 if( alt==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003926 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
shane9bd1b442009-10-23 01:27:39 +00003927 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003928 }else{
shane9bd1b442009-10-23 01:27:39 +00003929 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003930 fclose(alt);
3931 }
3932 }else
3933
drhc2ce0be2014-05-29 12:36:14 +00003934 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003935 const char *zSrcFile;
3936 const char *zDb;
3937 sqlite3 *pSrc;
3938 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003939 int nTimeout = 0;
3940
drh9ff849f2009-02-04 20:55:57 +00003941 if( nArg==2 ){
3942 zSrcFile = azArg[1];
3943 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003944 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003945 zSrcFile = azArg[2];
3946 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003947 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003948 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003949 rc = 1;
3950 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003951 }
3952 rc = sqlite3_open(zSrcFile, &pSrc);
3953 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003954 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003955 sqlite3_close(pSrc);
3956 return 1;
3957 }
drh05782482013-10-24 15:20:20 +00003958 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003959 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3960 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003961 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00003962 sqlite3_close(pSrc);
3963 return 1;
3964 }
drhdc2c4912009-02-04 22:46:47 +00003965 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3966 || rc==SQLITE_BUSY ){
3967 if( rc==SQLITE_BUSY ){
3968 if( nTimeout++ >= 3 ) break;
3969 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003970 }
3971 }
3972 sqlite3_backup_finish(pBackup);
3973 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003974 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003975 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00003976 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00003977 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003978 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003979 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003980 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003981 }
3982 sqlite3_close(pSrc);
3983 }else
3984
dan8d1edb92014-11-05 09:07:28 +00003985
3986 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3987 if( nArg==2 ){
3988 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003989#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00003990 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00003991#endif
dan8d1edb92014-11-05 09:07:28 +00003992 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003993 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00003994 rc = 1;
3995 }
3996 }else
3997
drhc2ce0be2014-05-29 12:36:14 +00003998 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003999 ShellState data;
drh75897232000-05-29 14:26:00 +00004000 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00004001 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00004002 memcpy(&data, p, sizeof(data));
4003 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00004004 data.cMode = data.mode = MODE_Semi;
drh4926fec2016-04-13 15:33:42 +00004005 if( nArg>=2 && optionMatch(azArg[1], "indent") ){
4006 data.cMode = data.mode = MODE_Pretty;
4007 nArg--;
4008 if( nArg==2 ) azArg[1] = azArg[2];
4009 }
4010 if( nArg==2 && azArg[1][0]!='-' ){
drhc8d74412004-08-31 23:41:26 +00004011 int i;
drhf0693c82011-10-11 20:41:54 +00004012 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00004013 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00004014 char *new_argv[2], *new_colv[2];
4015 new_argv[0] = "CREATE TABLE sqlite_master (\n"
4016 " type text,\n"
4017 " name text,\n"
4018 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00004019 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00004020 " sql text\n"
4021 ")";
4022 new_argv[1] = 0;
4023 new_colv[0] = "sql";
4024 new_colv[1] = 0;
4025 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004026 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00004027 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00004028 char *new_argv[2], *new_colv[2];
4029 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
4030 " type text,\n"
4031 " name text,\n"
4032 " tbl_name text,\n"
4033 " rootpage integer,\n"
4034 " sql text\n"
4035 ")";
4036 new_argv[1] = 0;
4037 new_colv[0] = "sql";
4038 new_colv[1] = 0;
4039 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004040 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00004041 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00004042 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00004043 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004044 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004045 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004046 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004047 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00004048 "WHERE lower(tbl_name) LIKE shellstatic()"
4049 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00004050 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00004051 callback, &data, &zErrMsg);
4052 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00004053 }
drhc2ce0be2014-05-29 12:36:14 +00004054 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00004055 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004056 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004057 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004058 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004059 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00004060 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00004061 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00004062 callback, &data, &zErrMsg
4063 );
drhc2ce0be2014-05-29 12:36:14 +00004064 }else{
drh4926fec2016-04-13 15:33:42 +00004065 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00004066 rc = 1;
4067 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004068 }
drh75897232000-05-29 14:26:00 +00004069 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00004070 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004071 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00004072 rc = 1;
4073 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004074 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00004075 rc = 1;
4076 }else{
4077 rc = 0;
drh75897232000-05-29 14:26:00 +00004078 }
4079 }else
4080
drhabd4c722014-09-20 18:18:33 +00004081#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
4082 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
drh1d9be4f2015-01-22 11:29:25 +00004083 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00004084 }else
4085#endif
4086
drhe6229612014-08-18 15:08:26 +00004087#if defined(SQLITE_ENABLE_SESSION)
4088 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
4089 OpenSession *pSession = &p->aSession[0];
4090 char **azCmd = &azArg[1];
4091 int iSes = 0;
4092 int nCmd = nArg - 1;
4093 int i;
4094 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00004095 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00004096 if( nArg>=3 ){
4097 for(iSes=0; iSes<p->nSession; iSes++){
4098 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
4099 }
4100 if( iSes<p->nSession ){
4101 pSession = &p->aSession[iSes];
4102 azCmd++;
4103 nCmd--;
4104 }else{
4105 pSession = &p->aSession[0];
4106 iSes = 0;
4107 }
4108 }
4109
drh3a67b042014-08-18 17:56:31 +00004110 /* .session attach TABLE
4111 ** Invoke the sqlite3session_attach() interface to attach a particular
4112 ** table so that it is never filtered.
4113 */
4114 if( strcmp(azCmd[0],"attach")==0 ){
4115 if( nCmd!=2 ) goto session_syntax_error;
4116 if( pSession->p==0 ){
4117 session_not_open:
mistachkin899c5c92016-04-03 20:50:02 +00004118 raw_printf(stderr, "ERROR: No sessions are open\n");
drh3a67b042014-08-18 17:56:31 +00004119 }else{
4120 rc = sqlite3session_attach(pSession->p, azCmd[1]);
4121 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004122 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004123 rc = 0;
4124 }
4125 }
4126 }else
4127
4128 /* .session changeset FILE
4129 ** .session patchset FILE
4130 ** Write a changeset or patchset into a file. The file is overwritten.
4131 */
4132 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
4133 FILE *out = 0;
4134 if( nCmd!=2 ) goto session_syntax_error;
4135 if( pSession->p==0 ) goto session_not_open;
4136 out = fopen(azCmd[1], "wb");
4137 if( out==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004138 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
drh3a67b042014-08-18 17:56:31 +00004139 }else{
4140 int szChng;
4141 void *pChng;
4142 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00004143 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00004144 }else{
drh2967e0c2014-08-19 00:26:17 +00004145 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
4146 }
4147 if( rc ){
4148 printf("Error: error code %d\n", rc);
4149 rc = 0;
drh3a67b042014-08-18 17:56:31 +00004150 }
mistachkin1fe36bb2016-04-04 02:16:44 +00004151 if( pChng
drh3a67b042014-08-18 17:56:31 +00004152 && fwrite(pChng, szChng, 1, out)!=1 ){
mistachkin899c5c92016-04-03 20:50:02 +00004153 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
drh3a67b042014-08-18 17:56:31 +00004154 szChng);
4155 }
4156 sqlite3_free(pChng);
4157 fclose(out);
4158 }
4159 }else
4160
drhe6229612014-08-18 15:08:26 +00004161 /* .session close
4162 ** Close the identified session
4163 */
4164 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00004165 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00004166 if( p->nSession ){
4167 session_close(pSession);
4168 p->aSession[iSes] = p->aSession[--p->nSession];
4169 }
4170 }else
4171
drh03168ca2014-08-18 20:01:31 +00004172 /* .session enable ?BOOLEAN?
4173 ** Query or set the enable flag
4174 */
4175 if( strcmp(azCmd[0], "enable")==0 ){
4176 int ii;
4177 if( nCmd>2 ) goto session_syntax_error;
4178 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4179 if( p->nSession ){
4180 ii = sqlite3session_enable(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004181 utf8_printf(p->out, "session %s enable flag = %d\n",
4182 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004183 }
4184 }else
4185
4186 /* .session filter GLOB ....
4187 ** Set a list of GLOB patterns of table names to be excluded.
4188 */
4189 if( strcmp(azCmd[0], "filter")==0 ){
4190 int ii, nByte;
4191 if( nCmd<2 ) goto session_syntax_error;
4192 if( p->nSession ){
4193 for(ii=0; ii<pSession->nFilter; ii++){
4194 sqlite3_free(pSession->azFilter[ii]);
4195 }
4196 sqlite3_free(pSession->azFilter);
4197 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
4198 pSession->azFilter = sqlite3_malloc( nByte );
4199 if( pSession->azFilter==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004200 raw_printf(stderr, "Error: out or memory\n");
drh03168ca2014-08-18 20:01:31 +00004201 exit(1);
4202 }
4203 for(ii=1; ii<nCmd; ii++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004204 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
drh03168ca2014-08-18 20:01:31 +00004205 }
4206 pSession->nFilter = ii-1;
4207 }
4208 }else
4209
4210 /* .session indirect ?BOOLEAN?
4211 ** Query or set the indirect flag
4212 */
4213 if( strcmp(azCmd[0], "indirect")==0 ){
4214 int ii;
4215 if( nCmd>2 ) goto session_syntax_error;
4216 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4217 if( p->nSession ){
4218 ii = sqlite3session_indirect(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004219 utf8_printf(p->out, "session %s indirect flag = %d\n",
4220 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004221 }
4222 }else
4223
4224 /* .session isempty
4225 ** Determine if the session is empty
4226 */
4227 if( strcmp(azCmd[0], "isempty")==0 ){
4228 int ii;
4229 if( nCmd!=1 ) goto session_syntax_error;
4230 if( p->nSession ){
4231 ii = sqlite3session_isempty(pSession->p);
mistachkin899c5c92016-04-03 20:50:02 +00004232 utf8_printf(p->out, "session %s isempty flag = %d\n",
4233 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004234 }
4235 }else
4236
drhe6229612014-08-18 15:08:26 +00004237 /* .session list
4238 ** List all currently open sessions
4239 */
4240 if( strcmp(azCmd[0],"list")==0 ){
4241 for(i=0; i<p->nSession; i++){
mistachkin899c5c92016-04-03 20:50:02 +00004242 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
drhe6229612014-08-18 15:08:26 +00004243 }
4244 }else
4245
4246 /* .session open DB NAME
4247 ** Open a new session called NAME on the attached database DB.
4248 ** DB is normally "main".
4249 */
4250 if( strcmp(azCmd[0],"open")==0 ){
4251 char *zName;
4252 if( nCmd!=3 ) goto session_syntax_error;
4253 zName = azCmd[2];
4254 if( zName[0]==0 ) goto session_syntax_error;
4255 for(i=0; i<p->nSession; i++){
4256 if( strcmp(p->aSession[i].zName,zName)==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004257 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
drhe6229612014-08-18 15:08:26 +00004258 goto meta_command_exit;
4259 }
4260 }
4261 if( p->nSession>=ArraySize(p->aSession) ){
mistachkin899c5c92016-04-03 20:50:02 +00004262 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
drhe6229612014-08-18 15:08:26 +00004263 goto meta_command_exit;
4264 }
4265 pSession = &p->aSession[p->nSession];
4266 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
4267 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004268 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004269 rc = 0;
drhe6229612014-08-18 15:08:26 +00004270 goto meta_command_exit;
4271 }
drh03168ca2014-08-18 20:01:31 +00004272 pSession->nFilter = 0;
4273 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00004274 p->nSession++;
4275 pSession->zName = sqlite3_mprintf("%s", zName);
4276 }else
4277 /* If no command name matches, show a syntax error */
4278 session_syntax_error:
4279 session_help(p);
4280 }else
4281#endif
4282
drh340f5822013-06-27 13:01:21 +00004283#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00004284 /* Undocumented commands for internal testing. Subject to change
4285 ** without notice. */
4286 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
4287 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
4288 int i, v;
4289 for(i=1; i<nArg; i++){
4290 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00004291 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00004292 }
4293 }
4294 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
4295 int i; sqlite3_int64 v;
4296 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00004297 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00004298 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00004299 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00004300 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00004301 }
4302 }
4303 }else
drh340f5822013-06-27 13:01:21 +00004304#endif
drh348d19c2013-06-03 12:47:43 +00004305
drhc2ce0be2014-05-29 12:36:14 +00004306 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00004307 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004308 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00004309 rc = 1;
4310 }
drh6976c212014-07-24 12:09:47 +00004311 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004312 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00004313 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00004314 }
4315 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00004316 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
4317 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00004318 }
drh75897232000-05-29 14:26:00 +00004319 }else
4320
drh62cdde52014-05-28 20:22:28 +00004321 if( c=='s'
4322 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00004323 ){
4324 char *zCmd;
drh54027102014-08-06 14:36:53 +00004325 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00004326 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004327 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00004328 rc = 1;
4329 goto meta_command_exit;
4330 }
drhdcb3e3d2014-05-29 03:17:29 +00004331 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00004332 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00004333 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
4334 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00004335 }
drh54027102014-08-06 14:36:53 +00004336 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00004337 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00004338 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00004339 }else
4340
drhc2ce0be2014-05-29 12:36:14 +00004341 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drheacd29d2016-04-15 15:03:27 +00004342 static const char *azBool[] = { "off", "on", "full", "unk" };
persicom7e2dfdd2002-04-18 02:46:52 +00004343 int i;
drhc2ce0be2014-05-29 12:36:14 +00004344 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00004345 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00004346 rc = 1;
4347 goto meta_command_exit;
4348 }
drheacd29d2016-04-15 15:03:27 +00004349 utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]);
4350 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
drh700c2522016-02-09 18:39:25 +00004351 utf8_printf(p->out, "%12.12s: %s\n","explain",
4352 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
drheacd29d2016-04-15 15:03:27 +00004353 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004354 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
4355 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00004356 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00004357 raw_printf(p->out, "\n");
4358 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00004359 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00004360 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004361 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004362 raw_printf(p->out, "\n");
4363 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004364 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004365 raw_printf(p->out, "\n");
drheacd29d2016-04-15 15:03:27 +00004366 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004367 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00004368 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00004369 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00004370 }
mistachkinaae280e2015-12-31 19:06:24 +00004371 raw_printf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00004372 }else
4373
drhc2ce0be2014-05-29 12:36:14 +00004374 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
4375 if( nArg==2 ){
4376 p->statsOn = booleanValue(azArg[1]);
drh34784902016-02-27 17:12:36 +00004377 }else if( nArg==1 ){
4378 display_stats(p->db, p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004379 }else{
drh34784902016-02-27 17:12:36 +00004380 raw_printf(stderr, "Usage: .stats ?on|off?\n");
drhc2ce0be2014-05-29 12:36:14 +00004381 rc = 1;
4382 }
shaneh642d8b82010-07-28 16:05:34 +00004383 }else
4384
drhc2ce0be2014-05-29 12:36:14 +00004385 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00004386 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00004387 char **azResult;
drh98781232012-04-23 12:38:05 +00004388 int nRow, nAlloc;
4389 char *zSql = 0;
4390 int ii;
drh05782482013-10-24 15:20:20 +00004391 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00004392 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00004393 if( rc ) return shellDatabaseError(p->db);
4394
4395 /* Create an SQL statement to query for the list of tables in the
4396 ** main and all attached databases where the table name matches the
4397 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00004398 zSql = sqlite3_mprintf(
4399 "SELECT name FROM sqlite_master"
4400 " WHERE type IN ('table','view')"
4401 " AND name NOT LIKE 'sqlite_%%'"
4402 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00004403 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00004404 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
4405 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
4406 if( strcmp(zDbName,"temp")==0 ){
4407 zSql = sqlite3_mprintf(
4408 "%z UNION ALL "
4409 "SELECT 'temp.' || name FROM sqlite_temp_master"
4410 " WHERE type IN ('table','view')"
4411 " AND name NOT LIKE 'sqlite_%%'"
4412 " AND name LIKE ?1", zSql);
4413 }else{
4414 zSql = sqlite3_mprintf(
4415 "%z UNION ALL "
4416 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4417 " WHERE type IN ('table','view')"
4418 " AND name NOT LIKE 'sqlite_%%'"
4419 " AND name LIKE ?1", zSql, zDbName, zDbName);
4420 }
drha50da102000-08-08 20:19:09 +00004421 }
dand95bb392015-09-30 11:19:05 +00004422 rc = sqlite3_finalize(pStmt);
4423 if( zSql && rc==SQLITE_OK ){
4424 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
4425 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4426 }
drh98781232012-04-23 12:38:05 +00004427 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00004428 if( !zSql ) return shellNomemError();
4429 if( rc ) return shellDatabaseError(p->db);
4430
4431 /* Run the SQL statement prepared by the above block. Store the results
4432 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00004433 nRow = nAlloc = 0;
4434 azResult = 0;
4435 if( nArg>1 ){
4436 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00004437 }else{
drh98781232012-04-23 12:38:05 +00004438 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
4439 }
4440 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4441 if( nRow>=nAlloc ){
4442 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00004443 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00004444 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00004445 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00004446 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00004447 break;
4448 }
mistachkin8e189222015-04-19 21:43:16 +00004449 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00004450 azResult = azNew;
4451 }
4452 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00004453 if( 0==azResult[nRow] ){
4454 rc = shellNomemError();
4455 break;
4456 }
4457 nRow++;
drh98781232012-04-23 12:38:05 +00004458 }
dand95bb392015-09-30 11:19:05 +00004459 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
4460 rc = shellDatabaseError(p->db);
4461 }
4462
4463 /* Pretty-print the contents of array azResult[] to the output */
4464 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00004465 int len, maxlen = 0;
4466 int i, j;
4467 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00004468 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00004469 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00004470 if( len>maxlen ) maxlen = len;
4471 }
4472 nPrintCol = 80/(maxlen+2);
4473 if( nPrintCol<1 ) nPrintCol = 1;
4474 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
4475 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00004476 for(j=i; j<nRow; j+=nPrintRow){
4477 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00004478 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
4479 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00004480 }
mistachkinaae280e2015-12-31 19:06:24 +00004481 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00004482 }
4483 }
dand95bb392015-09-30 11:19:05 +00004484
drh98781232012-04-23 12:38:05 +00004485 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
4486 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00004487 }else
4488
shaneh96887e12011-02-10 21:08:58 +00004489 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00004490 static const struct {
4491 const char *zCtrlName; /* Name of a test-control option */
4492 int ctrlCode; /* Integer code for that option */
4493 } aCtrl[] = {
4494 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
4495 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
4496 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
4497 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
4498 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
4499 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
4500 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
4501 { "assert", SQLITE_TESTCTRL_ASSERT },
4502 { "always", SQLITE_TESTCTRL_ALWAYS },
4503 { "reserve", SQLITE_TESTCTRL_RESERVE },
4504 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
4505 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00004506 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00004507 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00004508 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00004509 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00004510 };
shaneh96887e12011-02-10 21:08:58 +00004511 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00004512 int rc2 = 0;
4513 int i, n2;
drh05782482013-10-24 15:20:20 +00004514 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00004515
drhd416fe72011-03-17 16:45:50 +00004516 /* convert testctrl text option to value. allow any unique prefix
4517 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00004518 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00004519 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00004520 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00004521 if( testctrl<0 ){
4522 testctrl = aCtrl[i].ctrlCode;
4523 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004524 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00004525 testctrl = -1;
4526 break;
4527 }
4528 }
4529 }
drh348d19c2013-06-03 12:47:43 +00004530 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004531 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00004532 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004533 }else{
4534 switch(testctrl){
4535
4536 /* sqlite3_test_control(int, db, int) */
4537 case SQLITE_TESTCTRL_OPTIMIZATIONS:
mistachkin1fe36bb2016-04-04 02:16:44 +00004538 case SQLITE_TESTCTRL_RESERVE:
shaneh96887e12011-02-10 21:08:58 +00004539 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004540 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00004541 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004542 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004543 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004544 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004545 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004546 }
4547 break;
4548
4549 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004550 case SQLITE_TESTCTRL_PRNG_SAVE:
4551 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004552 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004553 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004554 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00004555 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00004556 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004557 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004558 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
4559 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004560 }
4561 break;
4562
4563 /* sqlite3_test_control(int, uint) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004564 case SQLITE_TESTCTRL_PENDING_BYTE:
shaneh96887e12011-02-10 21:08:58 +00004565 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004566 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004567 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004568 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004569 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004570 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00004571 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004572 }
4573 break;
mistachkin1fe36bb2016-04-04 02:16:44 +00004574
shaneh96887e12011-02-10 21:08:58 +00004575 /* sqlite3_test_control(int, int) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004576 case SQLITE_TESTCTRL_ASSERT:
4577 case SQLITE_TESTCTRL_ALWAYS:
4578 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004579 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004580 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004581 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004582 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004583 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004584 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004585 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004586 }
4587 break;
4588
4589 /* sqlite3_test_control(int, char *) */
4590#ifdef SQLITE_N_KEYWORD
mistachkin1fe36bb2016-04-04 02:16:44 +00004591 case SQLITE_TESTCTRL_ISKEYWORD:
shaneh96887e12011-02-10 21:08:58 +00004592 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004593 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004594 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004595 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004596 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004597 utf8_printf(stderr,
4598 "Error: testctrl %s takes a single char * option\n",
4599 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004600 }
4601 break;
4602#endif
4603
drh1ffede82015-01-30 20:59:27 +00004604 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004605 if( nArg==5 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004606 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004607 azArg[2],
drh8964b342015-01-29 17:54:52 +00004608 integerValue(azArg[3]),
4609 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00004610 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004611 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004612 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004613 }
4614 break;
4615
mistachkin1fe36bb2016-04-04 02:16:44 +00004616 case SQLITE_TESTCTRL_BITVEC_TEST:
4617 case SQLITE_TESTCTRL_FAULT_INSTALL:
4618 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4619 case SQLITE_TESTCTRL_SCRATCHMALLOC:
shaneh96887e12011-02-10 21:08:58 +00004620 default:
mistachkinaae280e2015-12-31 19:06:24 +00004621 utf8_printf(stderr,
4622 "Error: CLI support for testctrl %s not implemented\n",
4623 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004624 break;
4625 }
4626 }
4627 }else
4628
drhc2ce0be2014-05-29 12:36:14 +00004629 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004630 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004631 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004632 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004633
drhc2ce0be2014-05-29 12:36:14 +00004634 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4635 if( nArg==2 ){
4636 enableTimer = booleanValue(azArg[1]);
4637 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00004638 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00004639 enableTimer = 0;
4640 }
4641 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004642 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004643 rc = 1;
4644 }
shanehe2aa9d72009-11-06 17:20:17 +00004645 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004646
drhc2ce0be2014-05-29 12:36:14 +00004647 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004648 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004649 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004650 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004651 rc = 1;
4652 goto meta_command_exit;
4653 }
drh657b4a82015-03-19 13:30:41 +00004654 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004655 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004656#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004657 if( p->traceOut==0 ){
4658 sqlite3_trace(p->db, 0, 0);
4659 }else{
4660 sqlite3_trace(p->db, sql_trace_callback, p->traceOut);
4661 }
4662#endif
4663 }else
4664
drhf442e332014-09-10 19:01:14 +00004665#if SQLITE_USER_AUTHENTICATION
4666 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4667 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004668 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00004669 rc = 1;
4670 goto meta_command_exit;
4671 }
drh7883ecf2014-09-11 16:19:31 +00004672 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004673 if( strcmp(azArg[1],"login")==0 ){
4674 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00004675 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00004676 rc = 1;
4677 goto meta_command_exit;
4678 }
drhd39c40f2014-09-11 00:27:53 +00004679 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4680 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004681 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004682 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00004683 rc = 1;
4684 }
4685 }else if( strcmp(azArg[1],"add")==0 ){
4686 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004687 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004688 rc = 1;
4689 goto meta_command_exit;
4690 }
drhd39c40f2014-09-11 00:27:53 +00004691 rc = sqlite3_user_add(p->db, azArg[2],
4692 azArg[3], (int)strlen(azArg[3]),
4693 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004694 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004695 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004696 rc = 1;
4697 }
4698 }else if( strcmp(azArg[1],"edit")==0 ){
4699 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004700 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004701 rc = 1;
4702 goto meta_command_exit;
4703 }
drhd39c40f2014-09-11 00:27:53 +00004704 rc = sqlite3_user_change(p->db, azArg[2],
4705 azArg[3], (int)strlen(azArg[3]),
4706 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004707 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004708 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004709 rc = 1;
4710 }
4711 }else if( strcmp(azArg[1],"delete")==0 ){
4712 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004713 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00004714 rc = 1;
4715 goto meta_command_exit;
4716 }
4717 rc = sqlite3_user_delete(p->db, azArg[2]);
4718 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004719 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004720 rc = 1;
4721 }
4722 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004723 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00004724 rc = 1;
4725 goto meta_command_exit;
mistachkin1fe36bb2016-04-04 02:16:44 +00004726 }
drhf442e332014-09-10 19:01:14 +00004727 }else
4728#endif /* SQLITE_USER_AUTHENTICATION */
4729
drh9fd301b2011-06-03 13:28:22 +00004730 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004731 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004732 sqlite3_libversion(), sqlite3_sourceid());
4733 }else
4734
drh790f2872015-11-28 18:06:36 +00004735 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
4736 const char *zDbName = nArg==2 ? azArg[1] : "main";
4737 sqlite3_vfs *pVfs;
4738 if( p->db ){
4739 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
4740 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00004741 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
4742 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4743 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4744 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00004745 }
4746 }
4747 }else
4748
drhb19e7352016-01-12 19:37:20 +00004749 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
4750 sqlite3_vfs *pVfs;
4751 sqlite3_vfs *pCurrent = 0;
4752 if( p->db ){
4753 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
4754 }
4755 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
4756 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
4757 pVfs==pCurrent ? " <--- CURRENT" : "");
4758 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4759 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4760 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
4761 if( pVfs->pNext ){
4762 raw_printf(p->out, "-----------------------------------\n");
4763 }
4764 }
4765 }else
4766
drhde60fc22011-12-14 17:53:36 +00004767 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4768 const char *zDbName = nArg==2 ? azArg[1] : "main";
4769 char *zVfsName = 0;
4770 if( p->db ){
4771 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4772 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00004773 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004774 sqlite3_free(zVfsName);
4775 }
4776 }
4777 }else
4778
drhcef4fc82012-09-21 22:50:45 +00004779#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4780 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004781 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004782 }else
4783#endif
4784
drhc2ce0be2014-05-29 12:36:14 +00004785 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004786 int j;
drh43617e92006-03-06 20:55:46 +00004787 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004788 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004789 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004790 }
4791 }else
4792
4793 {
mistachkinaae280e2015-12-31 19:06:24 +00004794 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004795 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004796 rc = 1;
drh75897232000-05-29 14:26:00 +00004797 }
drh67505e72002-04-19 12:34:06 +00004798
drhc2ce0be2014-05-29 12:36:14 +00004799meta_command_exit:
4800 if( p->outCount ){
4801 p->outCount--;
4802 if( p->outCount==0 ) output_reset(p);
4803 }
drh67505e72002-04-19 12:34:06 +00004804 return rc;
drh75897232000-05-29 14:26:00 +00004805}
4806
drh67505e72002-04-19 12:34:06 +00004807/*
drh91a66392007-09-07 01:12:32 +00004808** Return TRUE if a semicolon occurs anywhere in the first N characters
4809** of string z[].
drh324ccef2003-02-05 14:06:20 +00004810*/
drh9f099fd2013-08-06 14:01:46 +00004811static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004812 int i;
4813 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4814 return 0;
drh324ccef2003-02-05 14:06:20 +00004815}
4816
4817/*
drh70c7a4b2003-04-26 03:03:06 +00004818** Test to see if a line consists entirely of whitespace.
4819*/
4820static int _all_whitespace(const char *z){
4821 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004822 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004823 if( *z=='/' && z[1]=='*' ){
4824 z += 2;
4825 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4826 if( *z==0 ) return 0;
4827 z++;
4828 continue;
4829 }
4830 if( *z=='-' && z[1]=='-' ){
4831 z += 2;
4832 while( *z && *z!='\n' ){ z++; }
4833 if( *z==0 ) return 1;
4834 continue;
4835 }
4836 return 0;
4837 }
4838 return 1;
4839}
4840
4841/*
drha9b17162003-04-29 18:01:28 +00004842** Return TRUE if the line typed in is an SQL command terminator other
4843** than a semi-colon. The SQL Server style "go" command is understood
4844** as is the Oracle "/".
4845*/
drh9f099fd2013-08-06 14:01:46 +00004846static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004847 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004848 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4849 return 1; /* Oracle */
4850 }
drhf0693c82011-10-11 20:41:54 +00004851 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004852 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004853 return 1; /* SQL Server */
4854 }
4855 return 0;
4856}
4857
4858/*
drh233a5312008-12-18 22:25:13 +00004859** Return true if zSql is a complete SQL statement. Return false if it
4860** ends in the middle of a string literal or C-style comment.
4861*/
drh9f099fd2013-08-06 14:01:46 +00004862static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004863 int rc;
4864 if( zSql==0 ) return 1;
4865 zSql[nSql] = ';';
4866 zSql[nSql+1] = 0;
4867 rc = sqlite3_complete(zSql);
4868 zSql[nSql] = 0;
4869 return rc;
4870}
4871
4872/*
drh67505e72002-04-19 12:34:06 +00004873** Read input from *in and process it. If *in==0 then input
4874** is interactive - the user is typing it it. Otherwise, input
4875** is coming from a file or device. A prompt is issued and history
4876** is saved only if input is interactive. An interrupt signal will
4877** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004878**
4879** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004880*/
drhdcd87a92014-08-18 13:45:42 +00004881static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004882 char *zLine = 0; /* A single input line */
4883 char *zSql = 0; /* Accumulated SQL text */
4884 int nLine; /* Length of current line */
4885 int nSql = 0; /* Bytes of zSql[] used */
4886 int nAlloc = 0; /* Allocated zSql[] space */
4887 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4888 char *zErrMsg; /* Error message returned */
4889 int rc; /* Error code */
4890 int errCnt = 0; /* Number of errors seen */
4891 int lineno = 0; /* Current line number */
4892 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004893
4894 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4895 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004896 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004897 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004898 /* End of input */
4899 if( stdin_is_interactive ) printf("\n");
4900 break;
drhc49f44e2006-10-26 18:15:42 +00004901 }
drh67505e72002-04-19 12:34:06 +00004902 if( seenInterrupt ){
4903 if( in!=0 ) break;
4904 seenInterrupt = 0;
4905 }
drhc28490c2006-10-26 14:25:58 +00004906 lineno++;
drh849a9d92013-12-21 15:46:06 +00004907 if( nSql==0 && _all_whitespace(zLine) ){
4908 if( p->echoOn ) printf("%s\n", zLine);
4909 continue;
4910 }
drh2af0b2d2002-02-21 02:25:02 +00004911 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004912 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004913 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004914 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004915 break;
4916 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004917 errCnt++;
4918 }
drhdaffd0e2001-04-11 14:28:42 +00004919 continue;
4920 }
drh9f099fd2013-08-06 14:01:46 +00004921 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004922 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004923 }
drh9f099fd2013-08-06 14:01:46 +00004924 nLine = strlen30(zLine);
4925 if( nSql+nLine+2>=nAlloc ){
4926 nAlloc = nSql+nLine+100;
4927 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004928 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004929 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004930 exit(1);
4931 }
drhdaffd0e2001-04-11 14:28:42 +00004932 }
drh9f099fd2013-08-06 14:01:46 +00004933 nSqlPrior = nSql;
4934 if( nSql==0 ){
4935 int i;
4936 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004937 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004938 memcpy(zSql, zLine+i, nLine+1-i);
4939 startline = lineno;
4940 nSql = nLine-i;
4941 }else{
4942 zSql[nSql++] = '\n';
4943 memcpy(zSql+nSql, zLine, nLine+1);
4944 nSql += nLine;
4945 }
4946 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004947 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004948 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004949 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004950 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004951 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004952 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004953 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004954 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004955 char zPrefix[100];
4956 if( in!=0 || !stdin_is_interactive ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004957 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004958 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004959 }else{
shane9bd1b442009-10-23 01:27:39 +00004960 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004961 }
drh7f953e22002-07-13 17:33:45 +00004962 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004963 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004964 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004965 zErrMsg = 0;
4966 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004967 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004968 }
drhc49f44e2006-10-26 18:15:42 +00004969 errCnt++;
drhdf12f1c2015-12-07 21:46:19 +00004970 }else if( p->countChanges ){
mistachkinaae280e2015-12-31 19:06:24 +00004971 raw_printf(p->out, "changes: %3d total_changes: %d\n",
drhdf12f1c2015-12-07 21:46:19 +00004972 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
drhdaffd0e2001-04-11 14:28:42 +00004973 }
drhdaffd0e2001-04-11 14:28:42 +00004974 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004975 if( p->outCount ){
4976 output_reset(p);
4977 p->outCount = 0;
4978 }
drh9f099fd2013-08-06 14:01:46 +00004979 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004980 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004981 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004982 }
4983 }
drh9f099fd2013-08-06 14:01:46 +00004984 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004985 if( !_all_whitespace(zSql) ){
mistachkinaae280e2015-12-31 19:06:24 +00004986 utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004987 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004988 }
drhdaffd0e2001-04-11 14:28:42 +00004989 }
drh1f9ca2c2015-08-25 16:57:52 +00004990 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00004991 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00004992 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00004993}
4994
drh67505e72002-04-19 12:34:06 +00004995/*
4996** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00004997** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00004998*/
4999static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00005000 static char *home_dir = NULL;
5001 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00005002
drh4ace5362014-11-10 14:42:28 +00005003#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
5004 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00005005 {
5006 struct passwd *pwent;
5007 uid_t uid = getuid();
5008 if( (pwent=getpwuid(uid)) != NULL) {
5009 home_dir = pwent->pw_dir;
5010 }
drh67505e72002-04-19 12:34:06 +00005011 }
5012#endif
5013
chw65d3c132007-11-12 21:09:10 +00005014#if defined(_WIN32_WCE)
5015 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
5016 */
drh85e72432012-04-11 11:38:53 +00005017 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00005018#else
5019
drh83905c92012-06-21 13:00:37 +00005020#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00005021 if (!home_dir) {
5022 home_dir = getenv("USERPROFILE");
5023 }
5024#endif
5025
drh67505e72002-04-19 12:34:06 +00005026 if (!home_dir) {
5027 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00005028 }
5029
drh83905c92012-06-21 13:00:37 +00005030#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00005031 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00005032 char *zDrive, *zPath;
5033 int n;
5034 zDrive = getenv("HOMEDRIVE");
5035 zPath = getenv("HOMEPATH");
5036 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00005037 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00005038 home_dir = malloc( n );
5039 if( home_dir==0 ) return 0;
5040 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
5041 return home_dir;
5042 }
5043 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00005044 }
5045#endif
5046
chw65d3c132007-11-12 21:09:10 +00005047#endif /* !_WIN32_WCE */
5048
drh67505e72002-04-19 12:34:06 +00005049 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00005050 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00005051 char *z = malloc( n );
5052 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00005053 home_dir = z;
5054 }
drhe98d4fa2002-04-21 19:06:22 +00005055
drh67505e72002-04-19 12:34:06 +00005056 return home_dir;
5057}
5058
5059/*
5060** Read input from the file given by sqliterc_override. Or if that
5061** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00005062**
5063** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00005064*/
drh534f4df2015-02-28 14:03:35 +00005065static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00005066 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00005067 const char *sqliterc_override /* Name of config file. NULL to use default */
5068){
persicom7e2dfdd2002-04-18 02:46:52 +00005069 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00005070 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00005071 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00005072 FILE *in = NULL;
5073
5074 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00005075 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00005076 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005077 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00005078 " cannot read ~/.sqliterc\n");
5079 return;
drhe98d4fa2002-04-21 19:06:22 +00005080 }
drh2f3de322012-06-27 16:41:31 +00005081 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00005082 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
5083 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00005084 }
drha1f9b5e2004-02-14 16:31:02 +00005085 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00005086 if( in ){
drhc28490c2006-10-26 14:25:58 +00005087 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00005088 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00005089 }
drh534f4df2015-02-28 14:03:35 +00005090 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00005091 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00005092 }
drh85e72432012-04-11 11:38:53 +00005093 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00005094}
5095
drh67505e72002-04-19 12:34:06 +00005096/*
drhe1e38c42003-05-04 18:30:59 +00005097** Show available command line options
5098*/
mistachkin1fe36bb2016-04-04 02:16:44 +00005099static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00005100 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00005101 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00005102 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005103 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00005104 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00005105 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00005106 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00005107 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00005108 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00005109#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
5110 " -heap SIZE Size of heap for memsys3 or memsys5\n"
5111#endif
drhcc3b4f82012-02-07 14:13:50 +00005112 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00005113 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00005114 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005115 " -line set output mode to 'line'\n"
5116 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00005117 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00005118 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00005119#ifdef SQLITE_ENABLE_MULTIPLEX
5120 " -multiplex enable the multiplexor VFS\n"
5121#endif
mistachkine0d68852014-12-11 03:12:33 +00005122 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00005123 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00005124 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
5125 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00005126 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00005127 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00005128 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00005129 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00005130#ifdef SQLITE_ENABLE_VFSTRACE
5131 " -vfstrace enable tracing of all VFS calls\n"
5132#endif
drhe1e38c42003-05-04 18:30:59 +00005133;
5134static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00005135 utf8_printf(stderr,
mistachkin1fe36bb2016-04-04 02:16:44 +00005136 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
drh80e8be92006-08-29 12:04:19 +00005137 "FILENAME is the name of an SQLite database. A new database is created\n"
5138 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00005139 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00005140 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00005141 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005142 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00005143 }
5144 exit(1);
5145}
5146
5147/*
drh67505e72002-04-19 12:34:06 +00005148** Initialize the state information in data
5149*/
drhdcd87a92014-08-18 13:45:42 +00005150static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00005151 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00005152 data->normalMode = data->cMode = data->mode = MODE_List;
5153 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00005154 memcpy(data->colSeparator,SEP_Column, 2);
5155 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00005156 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00005157 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00005158 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00005159 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00005160 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00005161 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
5162 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00005163}
5164
drh98d312f2012-10-25 15:23:14 +00005165/*
drh5c7976f2014-02-10 19:59:27 +00005166** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00005167*/
5168#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00005169static void printBold(const char *zText){
5170 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
5171 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
5172 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
5173 SetConsoleTextAttribute(out,
5174 FOREGROUND_RED|FOREGROUND_INTENSITY
5175 );
5176 printf("%s", zText);
5177 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00005178}
5179#else
drh5c7976f2014-02-10 19:59:27 +00005180static void printBold(const char *zText){
5181 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00005182}
5183#endif
5184
5185/*
drh98d312f2012-10-25 15:23:14 +00005186** Get the argument to an --option. Throw an error and die if no argument
5187** is available.
5188*/
5189static char *cmdline_option_value(int argc, char **argv, int i){
5190 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00005191 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00005192 argv[0], argv[argc-1]);
5193 exit(1);
5194 }
5195 return argv[i];
5196}
5197
mistachkin1fe36bb2016-04-04 02:16:44 +00005198#ifndef SQLITE_SHELL_IS_UTF8
5199# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
5200# define SQLITE_SHELL_IS_UTF8 (0)
5201# else
5202# define SQLITE_SHELL_IS_UTF8 (1)
5203# endif
5204#endif
5205
5206#if SQLITE_SHELL_IS_UTF8
mistachkin44723ce2015-03-21 02:22:37 +00005207int SQLITE_CDECL main(int argc, char **argv){
mistachkin1fe36bb2016-04-04 02:16:44 +00005208#else
5209int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
mistachkin1810f222016-04-04 02:33:34 +00005210 char **argv;
mistachkin1fe36bb2016-04-04 02:16:44 +00005211#endif
drh75897232000-05-29 14:26:00 +00005212 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00005213 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00005214 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00005215 int i;
drhc28490c2006-10-26 14:25:58 +00005216 int rc = 0;
drhb3735912014-02-10 16:13:42 +00005217 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00005218 int readStdin = 1;
5219 int nCmd = 0;
5220 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00005221
mistachkin1fe36bb2016-04-04 02:16:44 +00005222 setBinaryMode(stdin, 0);
5223 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
mistachkin1810f222016-04-04 02:33:34 +00005224 stdin_is_interactive = isatty(0);
5225 stdout_is_console = isatty(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005226
drh69b30ab2014-02-27 15:11:52 +00005227#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00005228 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005229 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00005230 sqlite3_sourceid(), SQLITE_SOURCE_ID);
5231 exit(1);
5232 }
drhc7181902014-02-27 15:04:13 +00005233#endif
persicom7e2dfdd2002-04-18 02:46:52 +00005234 main_init(&data);
mistachkin1fe36bb2016-04-04 02:16:44 +00005235#if !SQLITE_SHELL_IS_UTF8
5236 sqlite3_initialize();
5237 argv = sqlite3_malloc64(sizeof(argv[0])*argc);
5238 if( argv==0 ){
5239 raw_printf(stderr, "out of memory\n");
5240 exit(1);
5241 }
5242 for(i=0; i<argc; i++){
5243 argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
5244 if( argv[i]==0 ){
5245 raw_printf(stderr, "out of memory\n");
5246 exit(1);
5247 }
5248 }
5249#endif
mistachkin1810f222016-04-04 02:33:34 +00005250 assert( argc>=1 && argv && argv[0] );
mistachkin1fe36bb2016-04-04 02:16:44 +00005251 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00005252
drh44c2eb12003-04-30 11:38:26 +00005253 /* Make sure we have a valid signal handler early, before anything
5254 ** else is done.
5255 */
drh4c504392000-10-16 22:06:40 +00005256#ifdef SIGINT
5257 signal(SIGINT, interrupt_handler);
5258#endif
drh44c2eb12003-04-30 11:38:26 +00005259
drhac5649a2014-11-28 13:35:03 +00005260#ifdef SQLITE_SHELL_DBNAME_PROC
5261 {
5262 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
5263 ** of a C-function that will provide the name of the database file. Use
5264 ** this compile-time option to embed this shell program in larger
5265 ** applications. */
5266 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
5267 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
5268 warnInmemoryDb = 0;
5269 }
5270#endif
5271
drh22fbcb82004-02-01 01:22:50 +00005272 /* Do an initial pass through the command-line argument to locate
5273 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00005274 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00005275 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00005276 */
drh98d312f2012-10-25 15:23:14 +00005277 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00005278 char *z;
drhc28490c2006-10-26 14:25:58 +00005279 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005280 if( z[0]!='-' ){
5281 if( data.zDbFilename==0 ){
5282 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00005283 }else{
5284 /* Excesss arguments are interpreted as SQL (or dot-commands) and
5285 ** mean that nothing is read from stdin */
5286 readStdin = 0;
5287 nCmd++;
5288 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
5289 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005290 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00005291 exit(1);
5292 }
5293 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00005294 }
drh98d312f2012-10-25 15:23:14 +00005295 }
drhcc3b4f82012-02-07 14:13:50 +00005296 if( z[1]=='-' ) z++;
5297 if( strcmp(z,"-separator")==0
5298 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00005299 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00005300 || strcmp(z,"-cmd")==0
5301 ){
drh98d312f2012-10-25 15:23:14 +00005302 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005303 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00005304 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005305 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00005306 /* Need to check for batch mode here to so we can avoid printing
mistachkin1fe36bb2016-04-04 02:16:44 +00005307 ** informational messages (like from process_sqliterc) before
drh98d312f2012-10-25 15:23:14 +00005308 ** we do the actual processing of arguments later in a second pass.
5309 */
shanef69573d2009-10-24 02:06:14 +00005310 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00005311 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00005312#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00005313 const char *zSize;
5314 sqlite3_int64 szHeap;
5315
drh98d312f2012-10-25 15:23:14 +00005316 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00005317 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00005318 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00005319 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
5320#endif
drh44dec872014-08-30 15:49:25 +00005321 }else if( strcmp(z,"-scratch")==0 ){
5322 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005323 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005324 if( sz>400000 ) sz = 400000;
5325 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00005326 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005327 if( n>10 ) n = 10;
5328 if( n<1 ) n = 1;
5329 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
5330 data.shellFlgs |= SHFLG_Scratch;
5331 }else if( strcmp(z,"-pagecache")==0 ){
5332 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005333 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005334 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00005335 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005336 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00005337 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
5338 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00005339 data.shellFlgs |= SHFLG_Pagecache;
5340 }else if( strcmp(z,"-lookaside")==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<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005344 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005345 if( n<0 ) n = 0;
5346 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
5347 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00005348#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00005349 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00005350 extern int vfstrace_register(
5351 const char *zTraceName,
5352 const char *zOldVfsName,
5353 int (*xOut)(const char*,void*),
5354 void *pOutArg,
5355 int makeDefault
5356 );
drh2b625e22011-03-16 17:05:28 +00005357 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00005358#endif
drh6f25e892011-07-08 17:02:57 +00005359#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00005360 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00005361 extern int sqlite3_multiple_initialize(const char*,int);
5362 sqlite3_multiplex_initialize(0, 1);
5363#endif
drh7d9f3942013-04-03 01:26:54 +00005364 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00005365 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
5366 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00005367 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00005368 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00005369 if( pVfs ){
5370 sqlite3_vfs_register(pVfs, 1);
5371 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005372 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00005373 exit(1);
5374 }
drh44c2eb12003-04-30 11:38:26 +00005375 }
5376 }
drh98d312f2012-10-25 15:23:14 +00005377 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00005378#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00005379 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00005380 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00005381#else
mistachkinaae280e2015-12-31 19:06:24 +00005382 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00005383 return 1;
drh01b41712005-08-29 23:06:23 +00005384#endif
drh98d312f2012-10-25 15:23:14 +00005385 }
5386 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00005387
drh44c2eb12003-04-30 11:38:26 +00005388 /* Go ahead and open the database file if it already exists. If the
5389 ** file does not exist, delay opening it. This prevents empty database
5390 ** files from being created if a user mistypes the database name argument
5391 ** to the sqlite command-line tool.
5392 */
drhc8d74412004-08-31 23:41:26 +00005393 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00005394 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00005395 }
5396
drh22fbcb82004-02-01 01:22:50 +00005397 /* Process the initialization file if there is one. If no -init option
5398 ** is given on the command line, look for a file named ~/.sqliterc and
5399 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00005400 */
drh534f4df2015-02-28 14:03:35 +00005401 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00005402
drh22fbcb82004-02-01 01:22:50 +00005403 /* Make a second pass through the command-line argument and set
5404 ** options. This second pass is delayed until after the initialization
5405 ** file is processed so that the command-line arguments will override
5406 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00005407 */
drh98d312f2012-10-25 15:23:14 +00005408 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00005409 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005410 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00005411 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00005412 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00005413 i++;
5414 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005415 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00005416 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005417 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00005418 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005419 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00005420 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00005421 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00005422 }else if( strcmp(z,"-csv")==0 ){
5423 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00005424 memcpy(data.colSeparator,",",2);
5425 }else if( strcmp(z,"-ascii")==0 ){
5426 data.mode = MODE_Ascii;
5427 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005428 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00005429 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005430 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00005431 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00005432 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00005433 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00005434 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00005435 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00005436 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005437 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00005438 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00005439 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005440 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005441 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00005442 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005443 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00005444 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00005445 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00005446 }else if( strcmp(z,"-eqp")==0 ){
5447 data.autoEQP = 1;
drheacd29d2016-04-15 15:03:27 +00005448 }else if( strcmp(z,"-eqpfull")==0 ){
5449 data.autoEQP = 2;
shaneh642d8b82010-07-28 16:05:34 +00005450 }else if( strcmp(z,"-stats")==0 ){
5451 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00005452 }else if( strcmp(z,"-scanstats")==0 ){
5453 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00005454 }else if( strcmp(z,"-backslash")==0 ){
5455 /* Undocumented command-line option: -backslash
5456 ** Causes C-style backslash escapes to be evaluated in SQL statements
5457 ** prior to sending the SQL into SQLite. Useful for injecting
5458 ** crazy bytes in the middle of SQL statements for testing and debugging.
5459 */
5460 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00005461 }else if( strcmp(z,"-bail")==0 ){
5462 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00005463 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00005464 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00005465 return 0;
drhc28490c2006-10-26 14:25:58 +00005466 }else if( strcmp(z,"-interactive")==0 ){
5467 stdin_is_interactive = 1;
5468 }else if( strcmp(z,"-batch")==0 ){
5469 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00005470 }else if( strcmp(z,"-heap")==0 ){
5471 i++;
drh44dec872014-08-30 15:49:25 +00005472 }else if( strcmp(z,"-scratch")==0 ){
5473 i+=2;
5474 }else if( strcmp(z,"-pagecache")==0 ){
5475 i+=2;
5476 }else if( strcmp(z,"-lookaside")==0 ){
5477 i+=2;
drh7d9f3942013-04-03 01:26:54 +00005478 }else if( strcmp(z,"-mmap")==0 ){
5479 i++;
drha7e61d82011-03-12 17:02:57 +00005480 }else if( strcmp(z,"-vfs")==0 ){
5481 i++;
drh6f25e892011-07-08 17:02:57 +00005482#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00005483 }else if( strcmp(z,"-vfstrace")==0 ){
5484 i++;
drh6f25e892011-07-08 17:02:57 +00005485#endif
5486#ifdef SQLITE_ENABLE_MULTIPLEX
5487 }else if( strcmp(z,"-multiplex")==0 ){
5488 i++;
5489#endif
drhcc3b4f82012-02-07 14:13:50 +00005490 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00005491 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00005492 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00005493 /* Run commands that follow -cmd first and separately from commands
5494 ** that simply appear on the command-line. This seems goofy. It would
5495 ** be better if all commands ran in the order that they appear. But
5496 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00005497 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00005498 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00005499 if( z[0]=='.' ){
5500 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00005501 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00005502 }else{
drh05782482013-10-24 15:20:20 +00005503 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00005504 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
5505 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005506 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00005507 if( bail_on_error ) return rc!=0 ? rc : 1;
5508 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005509 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00005510 if( bail_on_error ) return rc;
5511 }
5512 }
drh1e5d0e92000-05-31 23:33:17 +00005513 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005514 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
5515 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00005516 return 1;
5517 }
drh700c2522016-02-09 18:39:25 +00005518 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00005519 }
drh44c2eb12003-04-30 11:38:26 +00005520
drhac5649a2014-11-28 13:35:03 +00005521 if( !readStdin ){
5522 /* Run all arguments that do not begin with '-' as if they were separate
5523 ** command-line inputs, except for the argToSkip argument which contains
5524 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00005525 */
drhac5649a2014-11-28 13:35:03 +00005526 for(i=0; i<nCmd; i++){
5527 if( azCmd[i][0]=='.' ){
5528 rc = do_meta_command(azCmd[i], &data);
5529 if( rc ) return rc==2 ? 0 : rc;
5530 }else{
5531 open_db(&data, 0);
5532 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
5533 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005534 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00005535 return rc!=0 ? rc : 1;
5536 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005537 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00005538 return rc;
5539 }
drh6ff13852001-11-25 13:18:23 +00005540 }
drh75897232000-05-29 14:26:00 +00005541 }
drhac5649a2014-11-28 13:35:03 +00005542 free(azCmd);
drh75897232000-05-29 14:26:00 +00005543 }else{
drh44c2eb12003-04-30 11:38:26 +00005544 /* Run commands received from standard input
5545 */
drhc28490c2006-10-26 14:25:58 +00005546 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00005547 char *zHome;
5548 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00005549 int nHistory;
drh75897232000-05-29 14:26:00 +00005550 printf(
drh743e0032011-12-12 16:51:50 +00005551 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00005552 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00005553 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00005554 );
drhb3735912014-02-10 16:13:42 +00005555 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00005556 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00005557 printBold("transient in-memory database");
5558 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00005559 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00005560 }
drh67505e72002-04-19 12:34:06 +00005561 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00005562 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00005563 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00005564 if( (zHistory = malloc(nHistory))!=0 ){
5565 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
5566 }
drh67505e72002-04-19 12:34:06 +00005567 }
drhf5ed7ad2015-06-15 14:43:25 +00005568 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00005569 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00005570 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00005571 shell_stifle_history(100);
5572 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00005573 free(zHistory);
drh67505e72002-04-19 12:34:06 +00005574 }
drhdaffd0e2001-04-11 14:28:42 +00005575 }else{
drhc28490c2006-10-26 14:25:58 +00005576 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00005577 }
5578 }
drh33048c02001-10-01 14:29:22 +00005579 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00005580 if( data.db ){
drhe6229612014-08-18 15:08:26 +00005581 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00005582 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00005583 }
mistachkin1fe36bb2016-04-04 02:16:44 +00005584 sqlite3_free(data.zFreeOnClose);
5585#if !SQLITE_SHELL_IS_UTF8
5586 for(i=0; i<argc; i++) sqlite3_free(argv[i]);
5587 sqlite3_free(argv);
5588#endif
drhc28490c2006-10-26 14:25:58 +00005589 return rc;
drh75897232000-05-29 14:26:00 +00005590}