blob: e1a4089bb0e6ce83be943d014a7d660d990df24d [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. */
drhfc8b40f2016-09-07 10:10:18 +0000527 if( stdin_is_interactive && in==stdin ){
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 */
drh760c8162016-09-16 02:52:22 +0000629 int nCheck; /* Number of ".check" commands run */
drh44dec872014-08-30 15:49:25 +0000630 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000631 char *zDestTable; /* Name of destination table when MODE_Insert */
drh760c8162016-09-16 02:52:22 +0000632 char zTestcase[30]; /* Name of current test case */
mistachkin636bf9f2014-07-19 20:15:16 +0000633 char colSeparator[20]; /* Column separator character for several modes */
634 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000635 int colWidth[100]; /* Requested width of each column when in column mode*/
636 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000637 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000638 ** the database */
drh44c2eb12003-04-30 11:38:26 +0000639 char outfile[FILENAME_MAX]; /* Filename for *out */
640 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000641 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000642 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000643 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000644 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000645 int *aiIndent; /* Array of indents used in MODE_Explain */
646 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000647 int iIndent; /* Index of current op in aiIndent[] */
drhe6229612014-08-18 15:08:26 +0000648#if defined(SQLITE_ENABLE_SESSION)
649 int nSession; /* Number of active sessions */
650 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
651#endif
drh75897232000-05-29 14:26:00 +0000652};
653
654/*
drh44dec872014-08-30 15:49:25 +0000655** These are the allowed shellFlgs values
656*/
657#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
658#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
659#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
660
661/*
drh75897232000-05-29 14:26:00 +0000662** These are the allowed modes.
663*/
drh967e8b72000-06-21 13:59:10 +0000664#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000665#define MODE_Column 1 /* One record per line in neat columns */
666#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000667#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
668#define MODE_Html 4 /* Generate an XHTML table */
669#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000670#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000671#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000672#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000673#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
drh4926fec2016-04-13 15:33:42 +0000674#define MODE_Pretty 10 /* Pretty-print schemas */
persicom7e2dfdd2002-04-18 02:46:52 +0000675
drh66ce4d02008-02-15 17:38:06 +0000676static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000677 "line",
678 "column",
679 "list",
680 "semi",
681 "html",
drhfeac5f82004-08-01 00:10:45 +0000682 "insert",
683 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000684 "csv",
drh66ce4d02008-02-15 17:38:06 +0000685 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000686 "ascii",
drh4926fec2016-04-13 15:33:42 +0000687 "prettyprint",
persicom7e2dfdd2002-04-18 02:46:52 +0000688};
drh75897232000-05-29 14:26:00 +0000689
690/*
mistachkinfad42082014-07-24 22:13:12 +0000691** These are the column/row/line separators used by the various
692** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000693*/
mistachkinfad42082014-07-24 22:13:12 +0000694#define SEP_Column "|"
695#define SEP_Row "\n"
696#define SEP_Tab "\t"
697#define SEP_Space " "
698#define SEP_Comma ","
699#define SEP_CrLf "\r\n"
700#define SEP_Unit "\x1F"
701#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000702
703/*
drh75897232000-05-29 14:26:00 +0000704** Number of elements in an array
705*/
drh902b9ee2008-12-05 17:17:07 +0000706#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000707
708/*
drh127f9d72010-02-23 01:47:00 +0000709** A callback for the sqlite3_log() interface.
710*/
711static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000712 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000713 if( p->pLog==0 ) return;
mistachkinaae280e2015-12-31 19:06:24 +0000714 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
drh127f9d72010-02-23 01:47:00 +0000715 fflush(p->pLog);
716}
717
718/*
shane626a6e42009-10-22 17:30:15 +0000719** Output the given string as a hex-encoded blob (eg. X'1234' )
720*/
721static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
722 int i;
723 char *zBlob = (char *)pBlob;
mistachkinaae280e2015-12-31 19:06:24 +0000724 raw_printf(out,"X'");
725 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
726 raw_printf(out,"'");
shane626a6e42009-10-22 17:30:15 +0000727}
728
729/*
drh28bd4bc2000-06-15 15:57:22 +0000730** Output the given string as a quoted string using SQL quoting conventions.
731*/
732static void output_quoted_string(FILE *out, const char *z){
733 int i;
734 int nSingle = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +0000735 setBinaryMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000736 for(i=0; z[i]; i++){
737 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000738 }
739 if( nSingle==0 ){
drhe05461c2015-12-30 13:36:57 +0000740 utf8_printf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000741 }else{
mistachkinaae280e2015-12-31 19:06:24 +0000742 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000743 while( *z ){
744 for(i=0; z[i] && z[i]!='\''; i++){}
745 if( i==0 ){
mistachkinaae280e2015-12-31 19:06:24 +0000746 raw_printf(out,"''");
drh28bd4bc2000-06-15 15:57:22 +0000747 z++;
748 }else if( z[i]=='\'' ){
drhe05461c2015-12-30 13:36:57 +0000749 utf8_printf(out,"%.*s''",i,z);
drh28bd4bc2000-06-15 15:57:22 +0000750 z += i+1;
751 }else{
drhe05461c2015-12-30 13:36:57 +0000752 utf8_printf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000753 break;
754 }
755 }
mistachkinaae280e2015-12-31 19:06:24 +0000756 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000757 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000758 setTextMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000759}
760
761/*
drhfeac5f82004-08-01 00:10:45 +0000762** Output the given string as a quoted according to C or TCL quoting rules.
763*/
764static void output_c_string(FILE *out, const char *z){
765 unsigned int c;
766 fputc('"', out);
767 while( (c = *(z++))!=0 ){
768 if( c=='\\' ){
769 fputc(c, out);
770 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000771 }else if( c=='"' ){
772 fputc('\\', out);
773 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000774 }else if( c=='\t' ){
775 fputc('\\', out);
776 fputc('t', out);
777 }else if( c=='\n' ){
778 fputc('\\', out);
779 fputc('n', out);
780 }else if( c=='\r' ){
781 fputc('\\', out);
782 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000783 }else if( !isprint(c&0xff) ){
mistachkinaae280e2015-12-31 19:06:24 +0000784 raw_printf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000785 }else{
786 fputc(c, out);
787 }
788 }
789 fputc('"', out);
790}
791
792/*
drhc08a4f12000-06-15 16:49:48 +0000793** Output the given string with characters that are special to
794** HTML escaped.
795*/
796static void output_html_string(FILE *out, const char *z){
797 int i;
drhc3d6ba42014-01-13 20:38:35 +0000798 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000799 while( *z ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000800 for(i=0; z[i]
801 && z[i]!='<'
802 && z[i]!='&'
803 && z[i]!='>'
804 && z[i]!='\"'
shane43d9cb22009-10-21 14:11:48 +0000805 && z[i]!='\'';
806 i++){}
drhc08a4f12000-06-15 16:49:48 +0000807 if( i>0 ){
drhe05461c2015-12-30 13:36:57 +0000808 utf8_printf(out,"%.*s",i,z);
drhc08a4f12000-06-15 16:49:48 +0000809 }
810 if( z[i]=='<' ){
mistachkinaae280e2015-12-31 19:06:24 +0000811 raw_printf(out,"&lt;");
drhc08a4f12000-06-15 16:49:48 +0000812 }else if( z[i]=='&' ){
mistachkinaae280e2015-12-31 19:06:24 +0000813 raw_printf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000814 }else if( z[i]=='>' ){
mistachkinaae280e2015-12-31 19:06:24 +0000815 raw_printf(out,"&gt;");
shane43d9cb22009-10-21 14:11:48 +0000816 }else if( z[i]=='\"' ){
mistachkinaae280e2015-12-31 19:06:24 +0000817 raw_printf(out,"&quot;");
shane43d9cb22009-10-21 14:11:48 +0000818 }else if( z[i]=='\'' ){
mistachkinaae280e2015-12-31 19:06:24 +0000819 raw_printf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000820 }else{
821 break;
822 }
823 z += i + 1;
824 }
825}
826
827/*
drhc49f44e2006-10-26 18:15:42 +0000828** If a field contains any character identified by a 1 in the following
829** array, then the string must be quoted for CSV.
830*/
831static const char needCsvQuote[] = {
mistachkin1fe36bb2016-04-04 02:16:44 +0000832 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
833 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
834 1, 0, 1, 0, 0, 0, 0, 1, 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, 0,
838 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
839 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
846 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
847 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
drhc49f44e2006-10-26 18:15:42 +0000848};
849
850/*
mistachkindd11f2d2014-12-11 04:49:46 +0000851** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000852** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000853** the null value. Strings are quoted if necessary. The separator
854** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000855*/
drhdcd87a92014-08-18 13:45:42 +0000856static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000857 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000858 if( z==0 ){
drhe05461c2015-12-30 13:36:57 +0000859 utf8_printf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000860 }else{
drhc49f44e2006-10-26 18:15:42 +0000861 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000862 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000863 for(i=0; z[i]; i++){
mistachkin1fe36bb2016-04-04 02:16:44 +0000864 if( needCsvQuote[((unsigned char*)z)[i]]
865 || (z[i]==p->colSeparator[0] &&
mistachkin636bf9f2014-07-19 20:15:16 +0000866 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000867 i = 0;
868 break;
869 }
870 }
871 if( i==0 ){
872 putc('"', out);
873 for(i=0; z[i]; i++){
874 if( z[i]=='"' ) putc('"', out);
875 putc(z[i], out);
876 }
877 putc('"', out);
878 }else{
drhe05461c2015-12-30 13:36:57 +0000879 utf8_printf(out, "%s", z);
drhc49f44e2006-10-26 18:15:42 +0000880 }
drh8e64d1c2004-10-07 00:32:39 +0000881 }
882 if( bSep ){
drhe05461c2015-12-30 13:36:57 +0000883 utf8_printf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000884 }
885}
886
danielk19774af00c62005-01-23 23:43:21 +0000887#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000888/*
drh4c504392000-10-16 22:06:40 +0000889** This routine runs when the user presses Ctrl-C
890*/
891static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000892 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000893 seenInterrupt++;
894 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000895 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000896}
danielk19774af00c62005-01-23 23:43:21 +0000897#endif
drh4c504392000-10-16 22:06:40 +0000898
899/*
drhde613c62016-04-04 17:23:10 +0000900** When the ".auth ON" is set, the following authorizer callback is
901** invoked. It always returns SQLITE_OK.
902*/
903static int shellAuth(
904 void *pClientData,
905 int op,
906 const char *zA1,
907 const char *zA2,
908 const char *zA3,
909 const char *zA4
910){
911 ShellState *p = (ShellState*)pClientData;
912 static const char *azAction[] = { 0,
913 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
914 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
915 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
916 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
917 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
918 "DROP_TRIGGER", "DROP_VIEW", "INSERT",
919 "PRAGMA", "READ", "SELECT",
920 "TRANSACTION", "UPDATE", "ATTACH",
921 "DETACH", "ALTER_TABLE", "REINDEX",
922 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
923 "FUNCTION", "SAVEPOINT", "RECURSIVE"
924 };
925 int i;
926 const char *az[4];
927 az[0] = zA1;
928 az[1] = zA2;
929 az[2] = zA3;
930 az[3] = zA4;
931 raw_printf(p->out, "authorizer: %s", azAction[op]);
932 for(i=0; i<4; i++){
933 raw_printf(p->out, " ");
934 if( az[i] ){
935 output_c_string(p->out, az[i]);
936 }else{
937 raw_printf(p->out, "NULL");
938 }
939 }
940 raw_printf(p->out, "\n");
941 return SQLITE_OK;
942}
943
944
945/*
shane626a6e42009-10-22 17:30:15 +0000946** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000947** invokes for each row of a query result.
948*/
drh4ace5362014-11-10 14:42:28 +0000949static int shell_callback(
950 void *pArg,
951 int nArg, /* Number of result columns */
952 char **azArg, /* Text of each result column */
953 char **azCol, /* Column names */
954 int *aiType /* Column types */
955){
drh75897232000-05-29 14:26:00 +0000956 int i;
drhdcd87a92014-08-18 13:45:42 +0000957 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000958
drh700c2522016-02-09 18:39:25 +0000959 switch( p->cMode ){
drh75897232000-05-29 14:26:00 +0000960 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000961 int w = 5;
drh6a535342001-10-19 16:44:56 +0000962 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000963 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000964 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000965 if( len>w ) w = len;
966 }
drhe05461c2015-12-30 13:36:57 +0000967 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000968 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000969 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000970 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000971 }
972 break;
973 }
danielk19770d78bae2008-01-03 07:09:48 +0000974 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000975 case MODE_Column: {
drh700c2522016-02-09 18:39:25 +0000976 static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
977 const int *colWidth;
978 int showHdr;
979 char *rowSep;
980 if( p->cMode==MODE_Column ){
981 colWidth = p->colWidth;
982 showHdr = p->showHeader;
983 rowSep = p->rowSeparator;
984 }else{
985 colWidth = aExplainWidths;
986 showHdr = 1;
mistachkin6d945552016-02-09 20:31:50 +0000987 rowSep = SEP_Row;
drh700c2522016-02-09 18:39:25 +0000988 }
drha0c66f52000-07-29 13:20:21 +0000989 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000990 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000991 int w, n;
992 if( i<ArraySize(p->colWidth) ){
drh700c2522016-02-09 18:39:25 +0000993 w = colWidth[i];
drh75897232000-05-29 14:26:00 +0000994 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000995 w = 0;
drh75897232000-05-29 14:26:00 +0000996 }
drh078b1fd2012-09-21 13:40:02 +0000997 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000998 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000999 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +00001000 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +00001001 if( w<n ) w = n;
1002 }
1003 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001004 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001005 }
drh700c2522016-02-09 18:39:25 +00001006 if( showHdr ){
drh078b1fd2012-09-21 13:40:02 +00001007 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001008 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001009 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001010 }else{
drhe05461c2015-12-30 13:36:57 +00001011 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001012 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001013 }
drha0c66f52000-07-29 13:20:21 +00001014 }
1015 }
drh700c2522016-02-09 18:39:25 +00001016 if( showHdr ){
drha0c66f52000-07-29 13:20:21 +00001017 for(i=0; i<nArg; i++){
1018 int w;
1019 if( i<ArraySize(p->actualWidth) ){
1020 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +00001021 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +00001022 }else{
1023 w = 10;
1024 }
mistachkinaae280e2015-12-31 19:06:24 +00001025 utf8_printf(p->out,"%-*.*s%s",w,w,
drhe05461c2015-12-30 13:36:57 +00001026 "----------------------------------------------------------"
drha0c66f52000-07-29 13:20:21 +00001027 "----------------------------------------------------------",
drh700c2522016-02-09 18:39:25 +00001028 i==nArg-1 ? rowSep : " ");
drha0c66f52000-07-29 13:20:21 +00001029 }
drh75897232000-05-29 14:26:00 +00001030 }
1031 }
drh6a535342001-10-19 16:44:56 +00001032 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001033 for(i=0; i<nArg; i++){
1034 int w;
drha0c66f52000-07-29 13:20:21 +00001035 if( i<ArraySize(p->actualWidth) ){
1036 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001037 }else{
1038 w = 10;
1039 }
drh700c2522016-02-09 18:39:25 +00001040 if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +00001041 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001042 }
dana98bf362013-11-13 18:35:01 +00001043 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +00001044 if( p->iIndent<p->nIndent ){
mistachkinaae280e2015-12-31 19:06:24 +00001045 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +00001046 }
danc4650bb2013-11-18 08:41:06 +00001047 p->iIndent++;
dana98bf362013-11-13 18:35:01 +00001048 }
drh078b1fd2012-09-21 13:40:02 +00001049 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001050 utf8_printf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +00001051 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001052 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001053 }else{
drhe05461c2015-12-30 13:36:57 +00001054 utf8_printf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +00001055 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001056 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001057 }
drh75897232000-05-29 14:26:00 +00001058 }
1059 break;
1060 }
drh4926fec2016-04-13 15:33:42 +00001061 case MODE_Semi: { /* .schema and .fullschema output */
1062 utf8_printf(p->out, "%s;\n", azArg[0]);
1063 break;
1064 }
1065 case MODE_Pretty: { /* .schema and .fullschema with --indent */
1066 char *z;
drh07d683f2016-04-13 21:00:36 +00001067 int j;
drh4926fec2016-04-13 15:33:42 +00001068 int nParen = 0;
1069 char cEnd = 0;
1070 char c;
1071 int nLine = 0;
1072 assert( nArg==1 );
1073 if( azArg[0]==0 ) break;
1074 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
1075 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
1076 ){
1077 utf8_printf(p->out, "%s;\n", azArg[0]);
1078 break;
1079 }
1080 z = sqlite3_mprintf("%s", azArg[0]);
1081 j = 0;
1082 for(i=0; IsSpace(z[i]); i++){}
1083 for(; (c = z[i])!=0; i++){
1084 if( IsSpace(c) ){
1085 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
1086 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
1087 j--;
1088 }
1089 z[j++] = c;
1090 }
1091 while( j>0 && IsSpace(z[j-1]) ){ j--; }
1092 z[j] = 0;
1093 if( strlen30(z)>=79 ){
drh07d683f2016-04-13 21:00:36 +00001094 for(i=j=0; (c = z[i])!=0; i++){
drh4926fec2016-04-13 15:33:42 +00001095 if( c==cEnd ){
1096 cEnd = 0;
1097 }else if( c=='"' || c=='\'' || c=='`' ){
1098 cEnd = c;
1099 }else if( c=='[' ){
1100 cEnd = ']';
1101 }else if( c=='(' ){
1102 nParen++;
1103 }else if( c==')' ){
1104 nParen--;
1105 if( nLine>0 && nParen==0 && j>0 ){
1106 utf8_printf(p->out, "%.*s\n", j, z);
1107 j = 0;
1108 }
1109 }
1110 z[j++] = c;
1111 if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
1112 if( c=='\n' ) j--;
1113 utf8_printf(p->out, "%.*s\n ", j, z);
1114 j = 0;
1115 nLine++;
1116 while( IsSpace(z[i+1]) ){ i++; }
1117 }
1118 }
1119 z[j] = 0;
1120 }
1121 utf8_printf(p->out, "%s;\n", z);
1122 sqlite3_free(z);
1123 break;
1124 }
drh75897232000-05-29 14:26:00 +00001125 case MODE_List: {
1126 if( p->cnt++==0 && p->showHeader ){
1127 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001128 utf8_printf(p->out,"%s%s",azCol[i],
mistachkin636bf9f2014-07-19 20:15:16 +00001129 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +00001130 }
1131 }
drh6a535342001-10-19 16:44:56 +00001132 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001133 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001134 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +00001135 if( z==0 ) z = p->nullValue;
drhe05461c2015-12-30 13:36:57 +00001136 utf8_printf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001137 if( i<nArg-1 ){
drhe05461c2015-12-30 13:36:57 +00001138 utf8_printf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +00001139 }else{
drhe05461c2015-12-30 13:36:57 +00001140 utf8_printf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001141 }
drh75897232000-05-29 14:26:00 +00001142 }
1143 break;
1144 }
drh1e5d0e92000-05-31 23:33:17 +00001145 case MODE_Html: {
1146 if( p->cnt++==0 && p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001147 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001148 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001149 raw_printf(p->out,"<TH>");
shane43d9cb22009-10-21 14:11:48 +00001150 output_html_string(p->out, azCol[i]);
mistachkinaae280e2015-12-31 19:06:24 +00001151 raw_printf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001152 }
mistachkinaae280e2015-12-31 19:06:24 +00001153 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001154 }
drh6a535342001-10-19 16:44:56 +00001155 if( azArg==0 ) break;
mistachkinaae280e2015-12-31 19:06:24 +00001156 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001157 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001158 raw_printf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +00001159 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00001160 raw_printf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001161 }
mistachkinaae280e2015-12-31 19:06:24 +00001162 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001163 break;
1164 }
drhfeac5f82004-08-01 00:10:45 +00001165 case MODE_Tcl: {
1166 if( p->cnt++==0 && p->showHeader ){
1167 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001168 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhe05461c2015-12-30 13:36:57 +00001169 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001170 }
drhe05461c2015-12-30 13:36:57 +00001171 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001172 }
1173 if( azArg==0 ) break;
1174 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +00001175 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
drhe05461c2015-12-30 13:36:57 +00001176 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001177 }
drhe05461c2015-12-30 13:36:57 +00001178 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001179 break;
1180 }
drh8e64d1c2004-10-07 00:32:39 +00001181 case MODE_Csv: {
mistachkin1fe36bb2016-04-04 02:16:44 +00001182 setBinaryMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001183 if( p->cnt++==0 && p->showHeader ){
1184 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001185 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001186 }
drhe05461c2015-12-30 13:36:57 +00001187 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001188 }
drh40253262014-10-17 21:35:05 +00001189 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +00001190 for(i=0; i<nArg; i++){
1191 output_csv(p, azArg[i], i<nArg-1);
1192 }
drhe05461c2015-12-30 13:36:57 +00001193 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001194 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001195 setTextMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001196 break;
1197 }
drh28bd4bc2000-06-15 15:57:22 +00001198 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001199 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001200 if( azArg==0 ) break;
drhe05461c2015-12-30 13:36:57 +00001201 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
mistachkin151c75a2015-04-07 21:16:40 +00001202 if( p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001203 raw_printf(p->out,"(");
mistachkin151c75a2015-04-07 21:16:40 +00001204 for(i=0; i<nArg; i++){
1205 char *zSep = i>0 ? ",": "";
drhe05461c2015-12-30 13:36:57 +00001206 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
mistachkin151c75a2015-04-07 21:16:40 +00001207 }
mistachkinaae280e2015-12-31 19:06:24 +00001208 raw_printf(p->out,")");
mistachkin151c75a2015-04-07 21:16:40 +00001209 }
mistachkinaae280e2015-12-31 19:06:24 +00001210 raw_printf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001211 for(i=0; i<nArg; i++){
1212 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001213 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
mistachkinaae280e2015-12-31 19:06:24 +00001214 utf8_printf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001215 }else if( aiType && aiType[i]==SQLITE_TEXT ){
mistachkinaae280e2015-12-31 19:06:24 +00001216 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shanead6b8d02009-10-22 18:12:58 +00001217 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001218 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1219 || aiType[i]==SQLITE_FLOAT) ){
drhe05461c2015-12-30 13:36:57 +00001220 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001221 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1222 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1223 int nBlob = sqlite3_column_bytes(p->pStmt, i);
mistachkinaae280e2015-12-31 19:06:24 +00001224 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shane626a6e42009-10-22 17:30:15 +00001225 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001226 }else if( isNumber(azArg[i], 0) ){
drhe05461c2015-12-30 13:36:57 +00001227 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
drh28bd4bc2000-06-15 15:57:22 +00001228 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001229 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
drh28bd4bc2000-06-15 15:57:22 +00001230 output_quoted_string(p->out, azArg[i]);
1231 }
1232 }
mistachkinaae280e2015-12-31 19:06:24 +00001233 raw_printf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001234 break;
drh28bd4bc2000-06-15 15:57:22 +00001235 }
mistachkin636bf9f2014-07-19 20:15:16 +00001236 case MODE_Ascii: {
1237 if( p->cnt++==0 && p->showHeader ){
1238 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001239 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1240 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +00001241 }
drhe05461c2015-12-30 13:36:57 +00001242 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001243 }
1244 if( azArg==0 ) break;
1245 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001246 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1247 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001248 }
drhe05461c2015-12-30 13:36:57 +00001249 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001250 break;
1251 }
persicom1d0b8722002-04-18 02:53:04 +00001252 }
drh75897232000-05-29 14:26:00 +00001253 return 0;
1254}
1255
1256/*
shane626a6e42009-10-22 17:30:15 +00001257** This is the callback routine that the SQLite library
1258** invokes for each row of a query result.
1259*/
1260static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1261 /* since we don't have type info, call the shell_callback with a NULL value */
1262 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1263}
1264
1265/*
drhdcd87a92014-08-18 13:45:42 +00001266** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001267** the name of the table given. Escape any quote characters in the
1268** table name.
1269*/
drhdcd87a92014-08-18 13:45:42 +00001270static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001271 int i, n;
1272 int needQuote;
1273 char *z;
1274
1275 if( p->zDestTable ){
1276 free(p->zDestTable);
1277 p->zDestTable = 0;
1278 }
1279 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001280 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001281 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001282 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001283 needQuote = 1;
1284 if( zName[i]=='\'' ) n++;
1285 }
1286 }
1287 if( needQuote ) n += 2;
1288 z = p->zDestTable = malloc( n+1 );
1289 if( z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001290 raw_printf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001291 exit(1);
1292 }
1293 n = 0;
1294 if( needQuote ) z[n++] = '\'';
1295 for(i=0; zName[i]; i++){
1296 z[n++] = zName[i];
1297 if( zName[i]=='\'' ) z[n++] = '\'';
1298 }
1299 if( needQuote ) z[n++] = '\'';
1300 z[n] = 0;
1301}
1302
danielk19772a02e332004-06-05 08:04:36 +00001303/* zIn is either a pointer to a NULL-terminated string in memory obtained
1304** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1305** added to zIn, and the result returned in memory obtained from malloc().
1306** zIn, if it was not NULL, is freed.
1307**
mistachkin1fe36bb2016-04-04 02:16:44 +00001308** If the third argument, quote, is not '\0', then it is used as a
danielk19772a02e332004-06-05 08:04:36 +00001309** quote character for zAppend.
1310*/
drhc28490c2006-10-26 14:25:58 +00001311static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001312 int len;
1313 int i;
drh4f21c4a2008-12-10 22:15:00 +00001314 int nAppend = strlen30(zAppend);
1315 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001316
1317 len = nAppend+nIn+1;
1318 if( quote ){
1319 len += 2;
1320 for(i=0; i<nAppend; i++){
1321 if( zAppend[i]==quote ) len++;
1322 }
1323 }
1324
1325 zIn = (char *)realloc(zIn, len);
1326 if( !zIn ){
1327 return 0;
1328 }
1329
1330 if( quote ){
1331 char *zCsr = &zIn[nIn];
1332 *zCsr++ = quote;
1333 for(i=0; i<nAppend; i++){
1334 *zCsr++ = zAppend[i];
1335 if( zAppend[i]==quote ) *zCsr++ = quote;
1336 }
1337 *zCsr++ = quote;
1338 *zCsr++ = '\0';
1339 assert( (zCsr-zIn)==len );
1340 }else{
1341 memcpy(&zIn[nIn], zAppend, nAppend);
1342 zIn[len-1] = '\0';
1343 }
1344
1345 return zIn;
1346}
1347
drhdd3d4592004-08-30 01:54:05 +00001348
1349/*
drhb21a8e42012-01-28 21:08:51 +00001350** Execute a query statement that will generate SQL output. Print
1351** the result columns, comma-separated, on a line and then add a
1352** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001353**
drhb21a8e42012-01-28 21:08:51 +00001354** If the number of columns is 1 and that column contains text "--"
mistachkin1fe36bb2016-04-04 02:16:44 +00001355** then write the semicolon on a separate line. That way, if a
drhb21a8e42012-01-28 21:08:51 +00001356** "--" comment occurs at the end of the statement, the comment
1357** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001358*/
drh157e29a2009-05-21 15:15:00 +00001359static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001360 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001361 const char *zSelect, /* SELECT statement to extract content */
1362 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001363){
drhdd3d4592004-08-30 01:54:05 +00001364 sqlite3_stmt *pSelect;
1365 int rc;
drhb21a8e42012-01-28 21:08:51 +00001366 int nResult;
1367 int i;
1368 const char *z;
drhc7181902014-02-27 15:04:13 +00001369 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001370 if( rc!=SQLITE_OK || !pSelect ){
mistachkinaae280e2015-12-31 19:06:24 +00001371 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1372 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001373 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001374 return rc;
1375 }
1376 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001377 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001378 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001379 if( zFirstRow ){
drhe05461c2015-12-30 13:36:57 +00001380 utf8_printf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001381 zFirstRow = 0;
1382 }
drhb21a8e42012-01-28 21:08:51 +00001383 z = (const char*)sqlite3_column_text(pSelect, 0);
drhe05461c2015-12-30 13:36:57 +00001384 utf8_printf(p->out, "%s", z);
mistachkin1fe36bb2016-04-04 02:16:44 +00001385 for(i=1; i<nResult; i++){
drhe05461c2015-12-30 13:36:57 +00001386 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
drhb21a8e42012-01-28 21:08:51 +00001387 }
1388 if( z==0 ) z = "";
1389 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1390 if( z[0] ){
mistachkinaae280e2015-12-31 19:06:24 +00001391 raw_printf(p->out, "\n;\n");
drhb21a8e42012-01-28 21:08:51 +00001392 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001393 raw_printf(p->out, ";\n");
mistachkin1fe36bb2016-04-04 02:16:44 +00001394 }
drhdd3d4592004-08-30 01:54:05 +00001395 rc = sqlite3_step(pSelect);
1396 }
drh2f464a02011-10-13 00:41:49 +00001397 rc = sqlite3_finalize(pSelect);
1398 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00001399 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1400 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001401 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001402 }
1403 return rc;
drhdd3d4592004-08-30 01:54:05 +00001404}
1405
shane626a6e42009-10-22 17:30:15 +00001406/*
1407** Allocate space and save off current error string.
1408*/
1409static char *save_err_msg(
1410 sqlite3 *db /* Database to query */
1411){
1412 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001413 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001414 if( zErrMsg ){
1415 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1416 }
1417 return zErrMsg;
1418}
1419
drh34784902016-02-27 17:12:36 +00001420#ifdef __linux__
1421/*
1422** Attempt to display I/O stats on Linux using /proc/PID/io
1423*/
1424static void displayLinuxIoStats(FILE *out){
1425 FILE *in;
1426 char z[200];
1427 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
1428 in = fopen(z, "rb");
1429 if( in==0 ) return;
1430 while( fgets(z, sizeof(z), in)!=0 ){
1431 static const struct {
1432 const char *zPattern;
1433 const char *zDesc;
1434 } aTrans[] = {
drhfc1a84c2016-02-27 19:19:22 +00001435 { "rchar: ", "Bytes received by read():" },
1436 { "wchar: ", "Bytes sent to write():" },
1437 { "syscr: ", "Read() system calls:" },
1438 { "syscw: ", "Write() system calls:" },
1439 { "read_bytes: ", "Bytes read from storage:" },
1440 { "write_bytes: ", "Bytes written to storage:" },
1441 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
drh34784902016-02-27 17:12:36 +00001442 };
1443 int i;
1444 for(i=0; i<ArraySize(aTrans); i++){
1445 int n = (int)strlen(aTrans[i].zPattern);
1446 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
1447 raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
1448 break;
1449 }
1450 }
1451 }
1452 fclose(in);
mistachkin1fe36bb2016-04-04 02:16:44 +00001453}
drh34784902016-02-27 17:12:36 +00001454#endif
1455
1456
shane626a6e42009-10-22 17:30:15 +00001457/*
shaneh642d8b82010-07-28 16:05:34 +00001458** Display memory stats.
1459*/
1460static int display_stats(
1461 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001462 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001463 int bReset /* True to reset the stats */
1464){
1465 int iCur;
1466 int iHiwtr;
1467
1468 if( pArg && pArg->out ){
mistachkin1fe36bb2016-04-04 02:16:44 +00001469
shaneh642d8b82010-07-28 16:05:34 +00001470 iHiwtr = iCur = -1;
1471 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001472 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001473 "Memory Used: %d (max %d) bytes\n",
1474 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001475 iHiwtr = iCur = -1;
1476 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001477 raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001478 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001479 if( pArg->shellFlgs & SHFLG_Pagecache ){
1480 iHiwtr = iCur = -1;
1481 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001482 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001483 "Number of Pcache Pages Used: %d (max %d) pages\n",
1484 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001485 }
shaneh642d8b82010-07-28 16:05:34 +00001486 iHiwtr = iCur = -1;
1487 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001488 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001489 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1490 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001491 if( pArg->shellFlgs & SHFLG_Scratch ){
1492 iHiwtr = iCur = -1;
1493 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001494 raw_printf(pArg->out,
1495 "Number of Scratch Allocations Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001496 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001497 }
shaneh642d8b82010-07-28 16:05:34 +00001498 iHiwtr = iCur = -1;
1499 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001500 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001501 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1502 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001503 iHiwtr = iCur = -1;
1504 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001505 raw_printf(pArg->out, "Largest Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001506 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001507 iHiwtr = iCur = -1;
1508 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001509 raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001510 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001511 iHiwtr = iCur = -1;
1512 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001513 raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001514 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001515#ifdef YYTRACKMAXSTACKDEPTH
1516 iHiwtr = iCur = -1;
1517 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001518 raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001519 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001520#endif
1521 }
1522
1523 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001524 if( pArg->shellFlgs & SHFLG_Lookaside ){
1525 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001526 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1527 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001528 raw_printf(pArg->out,
1529 "Lookaside Slots Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001530 iCur, iHiwtr);
1531 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1532 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001533 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
1534 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001535 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1536 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001537 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
1538 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001539 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1540 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001541 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
1542 iHiwtr);
drh44dec872014-08-30 15:49:25 +00001543 }
shaneh642d8b82010-07-28 16:05:34 +00001544 iHiwtr = iCur = -1;
1545 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001546 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
1547 iCur);
drh4ace5362014-11-10 14:42:28 +00001548 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001549 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001550 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
drhc78e6e42011-09-23 18:58:23 +00001551 iHiwtr = iCur = -1;
1552 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001553 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001554 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001555 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001556 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
drhfbbcd5d2012-03-24 20:09:33 +00001557 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001558 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001559 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001560 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001561 iHiwtr = iCur = -1;
1562 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001563 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001564 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001565 }
1566
1567 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001568 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1569 bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001570 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001571 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001572 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001573 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001574 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001575 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001576 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001577 }
1578
drh34784902016-02-27 17:12:36 +00001579#ifdef __linux__
1580 displayLinuxIoStats(pArg->out);
1581#endif
1582
dan5a790282015-08-07 20:06:14 +00001583 /* Do not remove this machine readable comment: extra-stats-output-here */
1584
shaneh642d8b82010-07-28 16:05:34 +00001585 return 0;
1586}
1587
1588/*
dan8d1edb92014-11-05 09:07:28 +00001589** Display scan stats.
1590*/
1591static void display_scanstats(
1592 sqlite3 *db, /* Database to query */
1593 ShellState *pArg /* Pointer to ShellState */
1594){
drhf5ed7ad2015-06-15 14:43:25 +00001595#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1596 UNUSED_PARAMETER(db);
1597 UNUSED_PARAMETER(pArg);
1598#else
drh15f23c22014-11-06 12:46:16 +00001599 int i, k, n, mx;
mistachkinaae280e2015-12-31 19:06:24 +00001600 raw_printf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001601 mx = 0;
1602 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001603 double rEstLoop = 1.0;
1604 for(i=n=0; 1; i++){
1605 sqlite3_stmt *p = pArg->pStmt;
1606 sqlite3_int64 nLoop, nVisit;
1607 double rEst;
1608 int iSid;
1609 const char *zExplain;
1610 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1611 break;
1612 }
1613 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001614 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001615 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001616 if( n==0 ){
1617 rEstLoop = (double)nLoop;
mistachkinaae280e2015-12-31 19:06:24 +00001618 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001619 }
drh42f30bc2014-11-06 12:08:21 +00001620 n++;
1621 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1622 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1623 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
drhe05461c2015-12-30 13:36:57 +00001624 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
drh42f30bc2014-11-06 12:08:21 +00001625 rEstLoop *= rEst;
mistachkin1fe36bb2016-04-04 02:16:44 +00001626 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001627 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001628 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001629 );
dan8d1edb92014-11-05 09:07:28 +00001630 }
dan8d1edb92014-11-05 09:07:28 +00001631 }
mistachkinaae280e2015-12-31 19:06:24 +00001632 raw_printf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001633#endif
dan8d1edb92014-11-05 09:07:28 +00001634}
1635
1636/*
dana98bf362013-11-13 18:35:01 +00001637** Parameter azArray points to a zero-terminated array of strings. zStr
1638** points to a single nul-terminated string. Return non-zero if zStr
1639** is equal, according to strcmp(), to any of the strings in the array.
1640** Otherwise, return zero.
1641*/
1642static int str_in_array(const char *zStr, const char **azArray){
1643 int i;
1644 for(i=0; azArray[i]; i++){
1645 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1646 }
1647 return 0;
1648}
1649
1650/*
1651** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001652** and populate the ShellState.aiIndent[] array with the number of
mistachkin1fe36bb2016-04-04 02:16:44 +00001653** spaces each opcode should be indented before it is output.
dana98bf362013-11-13 18:35:01 +00001654**
1655** The indenting rules are:
1656**
1657** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1658** all opcodes that occur between the p2 jump destination and the opcode
1659** itself by 2 spaces.
1660**
drh01752bc2013-11-14 23:59:33 +00001661** * For each "Goto", if the jump destination is earlier in the program
1662** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001663** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001664** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001665** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001666** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001667*/
drhdcd87a92014-08-18 13:45:42 +00001668static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001669 const char *zSql; /* The text of the SQL statement */
1670 const char *z; /* Used to check if this is an EXPLAIN */
1671 int *abYield = 0; /* True if op is an OP_Yield */
1672 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001673 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001674
drh8ad0de32014-03-20 18:45:27 +00001675 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1676 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001677 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1678 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001679 const char *azGoto[] = { "Goto", 0 };
1680
1681 /* Try to figure out if this is really an EXPLAIN statement. If this
1682 ** cannot be verified, return early. */
drh87a24aa2016-02-09 20:04:07 +00001683 if( sqlite3_column_count(pSql)!=8 ){
1684 p->cMode = p->mode;
1685 return;
1686 }
dana98bf362013-11-13 18:35:01 +00001687 zSql = sqlite3_sql(pSql);
1688 if( zSql==0 ) return;
1689 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
drh87a24aa2016-02-09 20:04:07 +00001690 if( sqlite3_strnicmp(z, "explain", 7) ){
1691 p->cMode = p->mode;
1692 return;
1693 }
dana98bf362013-11-13 18:35:01 +00001694
1695 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1696 int i;
danc4650bb2013-11-18 08:41:06 +00001697 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001698 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001699
1700 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1701 ** p2 is an instruction address, set variable p2op to the index of that
1702 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1703 ** the current instruction is part of a sub-program generated by an
1704 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001705 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001706 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001707
1708 /* Grow the p->aiIndent array as required */
1709 if( iOp>=nAlloc ){
drh87a24aa2016-02-09 20:04:07 +00001710 if( iOp==0 ){
1711 /* Do further verfication that this is explain output. Abort if
1712 ** it is not */
1713 static const char *explainCols[] = {
1714 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
1715 int jj;
1716 for(jj=0; jj<ArraySize(explainCols); jj++){
1717 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
1718 p->cMode = p->mode;
1719 sqlite3_reset(pSql);
1720 return;
1721 }
1722 }
1723 }
dana98bf362013-11-13 18:35:01 +00001724 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001725 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1726 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001727 }
1728 abYield[iOp] = str_in_array(zOp, azYield);
1729 p->aiIndent[iOp] = 0;
1730 p->nIndent = iOp+1;
1731
1732 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001733 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001734 }
drhfe705102014-03-06 13:38:37 +00001735 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1736 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1737 ){
drheacd29d2016-04-15 15:03:27 +00001738 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001739 }
1740 }
1741
danc4650bb2013-11-18 08:41:06 +00001742 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001743 sqlite3_free(abYield);
1744 sqlite3_reset(pSql);
1745}
1746
1747/*
1748** Free the array allocated by explain_data_prepare().
1749*/
drhdcd87a92014-08-18 13:45:42 +00001750static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001751 sqlite3_free(p->aiIndent);
1752 p->aiIndent = 0;
1753 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001754 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001755}
1756
1757/*
drheacd29d2016-04-15 15:03:27 +00001758** Disable and restore .wheretrace and .selecttrace settings.
1759*/
1760#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1761extern int sqlite3SelectTrace;
1762static int savedSelectTrace;
1763#endif
1764#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1765extern int sqlite3WhereTrace;
1766static int savedWhereTrace;
1767#endif
1768static void disable_debug_trace_modes(void){
1769#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1770 savedSelectTrace = sqlite3SelectTrace;
1771 sqlite3SelectTrace = 0;
1772#endif
1773#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1774 savedWhereTrace = sqlite3WhereTrace;
1775 sqlite3WhereTrace = 0;
1776#endif
1777}
1778static void restore_debug_trace_modes(void){
1779#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1780 sqlite3SelectTrace = savedSelectTrace;
1781#endif
1782#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1783 sqlite3WhereTrace = savedWhereTrace;
1784#endif
1785}
1786
1787/*
1788** Run a prepared statement
1789*/
1790static void exec_prepared_stmt(
1791 ShellState *pArg, /* Pointer to ShellState */
1792 sqlite3_stmt *pStmt, /* Statment to run */
1793 int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
1794){
1795 int rc;
1796
1797 /* perform the first step. this will tell us if we
1798 ** have a result set or not and how wide it is.
1799 */
1800 rc = sqlite3_step(pStmt);
1801 /* if we have a result set... */
1802 if( SQLITE_ROW == rc ){
1803 /* if we have a callback... */
1804 if( xCallback ){
1805 /* allocate space for col name ptr, value ptr, and type */
1806 int nCol = sqlite3_column_count(pStmt);
1807 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
1808 if( !pData ){
1809 rc = SQLITE_NOMEM;
1810 }else{
1811 char **azCols = (char **)pData; /* Names of result columns */
1812 char **azVals = &azCols[nCol]; /* Results */
1813 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1814 int i, x;
1815 assert(sizeof(int) <= sizeof(char *));
1816 /* save off ptrs to column names */
1817 for(i=0; i<nCol; i++){
1818 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1819 }
1820 do{
1821 /* extract the data and data types */
1822 for(i=0; i<nCol; i++){
1823 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1824 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
1825 azVals[i] = "";
1826 }else{
1827 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1828 }
1829 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1830 rc = SQLITE_NOMEM;
1831 break; /* from for */
1832 }
1833 } /* end for */
1834
1835 /* if data and types extracted successfully... */
1836 if( SQLITE_ROW == rc ){
1837 /* call the supplied callback with the result row data */
1838 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1839 rc = SQLITE_ABORT;
1840 }else{
1841 rc = sqlite3_step(pStmt);
1842 }
1843 }
1844 } while( SQLITE_ROW == rc );
1845 sqlite3_free(pData);
1846 }
1847 }else{
1848 do{
1849 rc = sqlite3_step(pStmt);
1850 } while( rc == SQLITE_ROW );
1851 }
1852 }
1853}
1854
1855/*
mistachkin1fe36bb2016-04-04 02:16:44 +00001856** Execute a statement or set of statements. Print
1857** any result rows/columns depending on the current mode
shane626a6e42009-10-22 17:30:15 +00001858** set via the supplied callback.
1859**
mistachkin1fe36bb2016-04-04 02:16:44 +00001860** This is very similar to SQLite's built-in sqlite3_exec()
1861** function except it takes a slightly different callback
shane626a6e42009-10-22 17:30:15 +00001862** and callback data argument.
1863*/
1864static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001865 sqlite3 *db, /* An open database */
1866 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001867 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001868 /* (not the same as sqlite3_exec) */
1869 ShellState *pArg, /* Pointer to ShellState */
1870 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001871){
dan4564ced2010-01-05 04:59:56 +00001872 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1873 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001874 int rc2;
dan4564ced2010-01-05 04:59:56 +00001875 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001876
1877 if( pzErrMsg ){
1878 *pzErrMsg = NULL;
1879 }
1880
shaneb9fc17d2009-10-22 21:23:35 +00001881 while( zSql[0] && (SQLITE_OK == rc) ){
drheacd29d2016-04-15 15:03:27 +00001882 static const char *zStmtSql;
shaneb9fc17d2009-10-22 21:23:35 +00001883 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1884 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001885 if( pzErrMsg ){
1886 *pzErrMsg = save_err_msg(db);
1887 }
1888 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001889 if( !pStmt ){
1890 /* this happens for a comment or white-space */
1891 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001892 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001893 continue;
1894 }
drheacd29d2016-04-15 15:03:27 +00001895 zStmtSql = sqlite3_sql(pStmt);
1896 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
shane626a6e42009-10-22 17:30:15 +00001897
shaneh642d8b82010-07-28 16:05:34 +00001898 /* save off the prepared statment handle and reset row count */
1899 if( pArg ){
1900 pArg->pStmt = pStmt;
1901 pArg->cnt = 0;
1902 }
1903
shanehb7977c52010-01-18 18:17:10 +00001904 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001905 if( pArg && pArg->echoOn ){
drhe05461c2015-12-30 13:36:57 +00001906 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001907 }
shanehb7977c52010-01-18 18:17:10 +00001908
drhefbf3b12014-02-28 20:47:24 +00001909 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
drheacd29d2016-04-15 15:03:27 +00001910 if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
drhefbf3b12014-02-28 20:47:24 +00001911 sqlite3_stmt *pExplain;
drheacd29d2016-04-15 15:03:27 +00001912 char *zEQP;
1913 disable_debug_trace_modes();
1914 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
drhefbf3b12014-02-28 20:47:24 +00001915 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1916 if( rc==SQLITE_OK ){
1917 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001918 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1919 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1920 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001921 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001922 }
1923 }
1924 sqlite3_finalize(pExplain);
1925 sqlite3_free(zEQP);
drheacd29d2016-04-15 15:03:27 +00001926 if( pArg->autoEQP>=2 ){
1927 /* Also do an EXPLAIN for ".eqp full" mode */
1928 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
1929 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1930 if( rc==SQLITE_OK ){
1931 pArg->cMode = MODE_Explain;
1932 explain_data_prepare(pArg, pExplain);
1933 exec_prepared_stmt(pArg, pExplain, xCallback);
1934 explain_data_delete(pArg);
1935 }
1936 sqlite3_finalize(pExplain);
1937 sqlite3_free(zEQP);
1938 }
1939 restore_debug_trace_modes();
drhefbf3b12014-02-28 20:47:24 +00001940 }
1941
drh700c2522016-02-09 18:39:25 +00001942 if( pArg ){
1943 pArg->cMode = pArg->mode;
drh87a24aa2016-02-09 20:04:07 +00001944 if( pArg->autoExplain
1945 && sqlite3_column_count(pStmt)==8
drheacd29d2016-04-15 15:03:27 +00001946 && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
drh700c2522016-02-09 18:39:25 +00001947 ){
1948 pArg->cMode = MODE_Explain;
1949 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001950
drh700c2522016-02-09 18:39:25 +00001951 /* If the shell is currently in ".explain" mode, gather the extra
1952 ** data required to add indents to the output.*/
1953 if( pArg->cMode==MODE_Explain ){
1954 explain_data_prepare(pArg, pStmt);
1955 }
dana98bf362013-11-13 18:35:01 +00001956 }
1957
drheacd29d2016-04-15 15:03:27 +00001958 exec_prepared_stmt(pArg, pStmt, xCallback);
dana98bf362013-11-13 18:35:01 +00001959 explain_data_delete(pArg);
1960
shaneh642d8b82010-07-28 16:05:34 +00001961 /* print usage stats if stats on */
1962 if( pArg && pArg->statsOn ){
1963 display_stats(db, pArg, 0);
1964 }
1965
dan8d1edb92014-11-05 09:07:28 +00001966 /* print loop-counters if required */
1967 if( pArg && pArg->scanstatsOn ){
1968 display_scanstats(db, pArg);
1969 }
1970
mistachkin1fe36bb2016-04-04 02:16:44 +00001971 /* Finalize the statement just executed. If this fails, save a
dan4564ced2010-01-05 04:59:56 +00001972 ** copy of the error message. Otherwise, set zSql to point to the
1973 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001974 rc2 = sqlite3_finalize(pStmt);
1975 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001976 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001977 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001978 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001979 }else if( pzErrMsg ){
1980 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001981 }
shaneh642d8b82010-07-28 16:05:34 +00001982
1983 /* clear saved stmt handle */
1984 if( pArg ){
1985 pArg->pStmt = NULL;
1986 }
shane626a6e42009-10-22 17:30:15 +00001987 }
shaneb9fc17d2009-10-22 21:23:35 +00001988 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001989
1990 return rc;
1991}
1992
drhdd3d4592004-08-30 01:54:05 +00001993
drh33048c02001-10-01 14:29:22 +00001994/*
drh4c653a02000-06-07 01:27:47 +00001995** This is a different callback routine used for dumping the database.
1996** Each row received by this callback consists of a table name,
1997** the table type ("index" or "table") and SQL to create the table.
1998** This routine should print text sufficient to recreate the table.
1999*/
2000static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00002001 int rc;
2002 const char *zTable;
2003 const char *zType;
2004 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00002005 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00002006 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00002007
drh902b9ee2008-12-05 17:17:07 +00002008 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00002009 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00002010 zTable = azArg[0];
2011 zType = azArg[1];
2012 zSql = azArg[2];
mistachkin1fe36bb2016-04-04 02:16:44 +00002013
drh00b950d2005-09-11 02:03:03 +00002014 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00002015 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00002016 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002017 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00002018 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
2019 return 0;
drh45e29d82006-11-20 16:21:10 +00002020 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
2021 char *zIns;
2022 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00002023 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00002024 p->writableSchema = 1;
2025 }
2026 zIns = sqlite3_mprintf(
2027 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
2028 "VALUES('table','%q','%q',0,'%q');",
2029 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00002030 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00002031 sqlite3_free(zIns);
2032 return 0;
drh00b950d2005-09-11 02:03:03 +00002033 }else{
drhe05461c2015-12-30 13:36:57 +00002034 utf8_printf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00002035 }
danielk19772a02e332004-06-05 08:04:36 +00002036
2037 if( strcmp(zType, "table")==0 ){
2038 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00002039 char *zSelect = 0;
2040 char *zTableInfo = 0;
2041 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00002042 int nRow = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +00002043
danielk19772a02e332004-06-05 08:04:36 +00002044 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
2045 zTableInfo = appendText(zTableInfo, zTable, '"');
2046 zTableInfo = appendText(zTableInfo, ");", 0);
2047
drhc7181902014-02-27 15:04:13 +00002048 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00002049 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00002050 if( rc!=SQLITE_OK || !pTableInfo ){
2051 return 1;
2052 }
2053
2054 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00002055 /* Always quote the table name, even if it appears to be pure ascii,
2056 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
2057 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00002058 if( zTmp ){
2059 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00002060 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00002061 }
2062 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
2063 rc = sqlite3_step(pTableInfo);
2064 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00002065 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00002066 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00002067 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00002068 rc = sqlite3_step(pTableInfo);
2069 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00002070 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00002071 }else{
2072 zSelect = appendText(zSelect, ") ", 0);
2073 }
drh157e29a2009-05-21 15:15:00 +00002074 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00002075 }
2076 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00002077 if( rc!=SQLITE_OK || nRow==0 ){
2078 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00002079 return 1;
2080 }
2081 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
2082 zSelect = appendText(zSelect, zTable, '"');
2083
drh2f464a02011-10-13 00:41:49 +00002084 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00002085 if( rc==SQLITE_CORRUPT ){
2086 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00002087 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00002088 }
drh85e72432012-04-11 11:38:53 +00002089 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00002090 }
drh4c653a02000-06-07 01:27:47 +00002091 return 0;
2092}
2093
2094/*
drh45e29d82006-11-20 16:21:10 +00002095** Run zQuery. Use dump_callback() as the callback routine so that
2096** the contents of the query are output as SQL statements.
2097**
drhdd3d4592004-08-30 01:54:05 +00002098** If we get a SQLITE_CORRUPT error, rerun the query after appending
2099** "ORDER BY rowid DESC" to the end.
2100*/
2101static int run_schema_dump_query(
mistachkin1fe36bb2016-04-04 02:16:44 +00002102 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00002103 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00002104){
2105 int rc;
drh2f464a02011-10-13 00:41:49 +00002106 char *zErr = 0;
2107 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00002108 if( rc==SQLITE_CORRUPT ){
2109 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00002110 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00002111 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00002112 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00002113 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002114 sqlite3_free(zErr);
2115 zErr = 0;
2116 }
drhdd3d4592004-08-30 01:54:05 +00002117 zQ2 = malloc( len+100 );
2118 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00002119 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00002120 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
2121 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002122 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002123 }else{
2124 rc = SQLITE_CORRUPT;
2125 }
2126 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00002127 free(zQ2);
2128 }
2129 return rc;
2130}
2131
2132/*
drh75897232000-05-29 14:26:00 +00002133** Text of a help message
2134*/
persicom1d0b8722002-04-18 02:53:04 +00002135static char zHelp[] =
drhde613c62016-04-04 17:23:10 +00002136 ".auth ON|OFF Show authorizer callbacks\n"
drh9ff849f2009-02-04 20:55:57 +00002137 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00002138 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00002139 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00002140 ".changes on|off Show number of rows changed by SQL\n"
drh2db82112016-09-15 21:35:24 +00002141 ".check GLOB Fail if output since .testcase does not match\n"
drh4bbcf102014-02-06 02:46:08 +00002142 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00002143 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00002144 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00002145 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00002146 " If TABLE specified, only dump tables matching\n"
2147 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00002148 ".echo on|off Turn command echo on or off\n"
drheacd29d2016-04-15 15:03:27 +00002149 ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00002150 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00002151 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drh4926fec2016-04-13 15:33:42 +00002152 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00002153 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00002154 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00002155 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00002156 ".indexes ?TABLE? Show names of all indexes\n"
2157 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00002158 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00002159#ifdef SQLITE_ENABLE_IOTRACE
2160 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
2161#endif
drh1a513372015-05-02 17:40:23 +00002162 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00002163#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002164 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00002165#endif
drh127f9d72010-02-23 01:47:00 +00002166 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00002167 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00002168 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00002169 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00002170 " column Left-aligned columns. (See .width)\n"
2171 " html HTML <table> code\n"
2172 " insert SQL insert statements for TABLE\n"
2173 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00002174 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00002175 " tabs Tab-separated values\n"
2176 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00002177 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00002178 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drhcd0509e2016-09-16 00:26:08 +00002179 ".open ?-new? ?FILE? Close existing database and reopen FILE\n"
2180 " The --new starts with an empty file\n"
drhc2ce0be2014-05-29 12:36:14 +00002181 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00002182 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002183 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002184 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00002185 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00002186 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00002187 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00002188 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh4926fec2016-04-13 15:33:42 +00002189 ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
2190 " Add --indent for pretty-printing\n"
mistachkine0d68852014-12-11 03:12:33 +00002191 ".separator COL ?ROW? Change the column separator and optionally the row\n"
2192 " separator for both the output mode and .import\n"
drhe6229612014-08-18 15:08:26 +00002193#if defined(SQLITE_ENABLE_SESSION)
2194 ".session CMD ... Create or control sessions\n"
2195#endif
drh62cdde52014-05-28 20:22:28 +00002196 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00002197 ".show Show the current values for various settings\n"
drh34784902016-02-27 17:12:36 +00002198 ".stats ?on|off? Show stats or turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00002199 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00002200 ".tables ?TABLE? List names of tables\n"
2201 " If TABLE specified, only list tables matching\n"
2202 " LIKE pattern TABLE.\n"
drh760c8162016-09-16 02:52:22 +00002203 ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
drh2dfbbca2000-07-28 14:32:48 +00002204 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00002205 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00002206 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00002207 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00002208 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00002209 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00002210 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00002211 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00002212;
2213
drhe6229612014-08-18 15:08:26 +00002214#if defined(SQLITE_ENABLE_SESSION)
2215/*
2216** Print help information for the ".sessions" command
2217*/
2218void session_help(ShellState *p){
mistachkin899c5c92016-04-03 20:50:02 +00002219 raw_printf(p->out,
drhe6229612014-08-18 15:08:26 +00002220 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
2221 "If ?NAME? is omitted, the first defined session is used.\n"
2222 "Subcommands:\n"
2223 " attach TABLE Attach TABLE\n"
2224 " changeset FILE Write a changeset into FILE\n"
2225 " close Close one session\n"
2226 " enable ?BOOLEAN? Set or query the enable bit\n"
mistachkin1fe36bb2016-04-04 02:16:44 +00002227 " filter GLOB... Reject tables matching GLOBs\n"
drhe6229612014-08-18 15:08:26 +00002228 " indirect ?BOOLEAN? Mark or query the indirect status\n"
2229 " isempty Query whether the session is empty\n"
2230 " list List currently open session names\n"
2231 " open DB NAME Open a new session on DB\n"
2232 " patchset FILE Write a patchset into FILE\n"
2233 );
2234}
2235#endif
2236
2237
drhdaffd0e2001-04-11 14:28:42 +00002238/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00002239static int process_input(ShellState *p, FILE *in);
drh2db82112016-09-15 21:35:24 +00002240
2241
2242/*
2243** Read the content of a file into memory obtained from sqlite3_malloc64().
2244** The caller is responsible for freeing the memory.
2245**
2246** NULL is returned if any error is encountered.
2247*/
2248static char *readFile(const char *zName){
2249 FILE *in = fopen(zName, "rb");
2250 long nIn;
2251 char *pBuf;
2252 if( in==0 ) return 0;
2253 fseek(in, 0, SEEK_END);
2254 nIn = ftell(in);
2255 rewind(in);
2256 pBuf = sqlite3_malloc64( nIn );
2257 if( pBuf==0 ) return 0;
2258 if( 1!=fread(pBuf, nIn, 1, in) ){
2259 sqlite3_free(pBuf);
2260 return 0;
2261 }
2262 return pBuf;
2263}
2264
drhba5b0932014-07-24 12:39:59 +00002265/*
2266** Implementation of the "readfile(X)" SQL function. The entire content
2267** of the file named X is read and returned as a BLOB. NULL is returned
2268** if the file does not exist or is unreadable.
2269*/
2270static void readfileFunc(
2271 sqlite3_context *context,
2272 int argc,
2273 sqlite3_value **argv
2274){
2275 const char *zName;
drhba5b0932014-07-24 12:39:59 +00002276 void *pBuf;
2277
drhf5ed7ad2015-06-15 14:43:25 +00002278 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002279 zName = (const char*)sqlite3_value_text(argv[0]);
2280 if( zName==0 ) return;
drh2db82112016-09-15 21:35:24 +00002281 pBuf = readFile(zName);
2282 if( pBuf ) sqlite3_result_blob(context, pBuf, -1, sqlite3_free);
drhba5b0932014-07-24 12:39:59 +00002283}
2284
2285/*
2286** Implementation of the "writefile(X,Y)" SQL function. The argument Y
2287** is written into file X. The number of bytes written is returned. Or
2288** NULL is returned if something goes wrong, such as being unable to open
2289** file X for writing.
2290*/
2291static void writefileFunc(
2292 sqlite3_context *context,
2293 int argc,
2294 sqlite3_value **argv
2295){
2296 FILE *out;
2297 const char *z;
drhba5b0932014-07-24 12:39:59 +00002298 sqlite3_int64 rc;
2299 const char *zFile;
2300
drhf5ed7ad2015-06-15 14:43:25 +00002301 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002302 zFile = (const char*)sqlite3_value_text(argv[0]);
2303 if( zFile==0 ) return;
2304 out = fopen(zFile, "wb");
2305 if( out==0 ) return;
2306 z = (const char*)sqlite3_value_blob(argv[1]);
2307 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002308 rc = 0;
2309 }else{
drh490fe862014-08-11 14:21:32 +00002310 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002311 }
2312 fclose(out);
2313 sqlite3_result_int64(context, rc);
2314}
drhdaffd0e2001-04-11 14:28:42 +00002315
drhe6229612014-08-18 15:08:26 +00002316#if defined(SQLITE_ENABLE_SESSION)
2317/*
2318** Close a single OpenSession object and release all of its associated
2319** resources.
2320*/
2321static void session_close(OpenSession *pSession){
2322 int i;
2323 sqlite3session_delete(pSession->p);
2324 sqlite3_free(pSession->zName);
2325 for(i=0; i<pSession->nFilter; i++){
2326 sqlite3_free(pSession->azFilter[i]);
2327 }
2328 sqlite3_free(pSession->azFilter);
2329 memset(pSession, 0, sizeof(OpenSession));
2330}
2331#endif
2332
2333/*
drh51b55a32016-04-04 12:38:05 +00002334** Close all OpenSession objects and release all associated resources.
drhe6229612014-08-18 15:08:26 +00002335*/
drhe6229612014-08-18 15:08:26 +00002336#if defined(SQLITE_ENABLE_SESSION)
drh51b55a32016-04-04 12:38:05 +00002337static void session_close_all(ShellState *p){
drhe6229612014-08-18 15:08:26 +00002338 int i;
2339 for(i=0; i<p->nSession; i++){
2340 session_close(&p->aSession[i]);
2341 }
2342 p->nSession = 0;
drhe6229612014-08-18 15:08:26 +00002343}
drh51b55a32016-04-04 12:38:05 +00002344#else
2345# define session_close_all(X)
2346#endif
drhe6229612014-08-18 15:08:26 +00002347
drh75897232000-05-29 14:26:00 +00002348/*
drh03168ca2014-08-18 20:01:31 +00002349** Implementation of the xFilter function for an open session. Omit
2350** any tables named by ".session filter" but let all other table through.
2351*/
2352#if defined(SQLITE_ENABLE_SESSION)
2353static int session_filter(void *pCtx, const char *zTab){
2354 OpenSession *pSession = (OpenSession*)pCtx;
2355 int i;
2356 for(i=0; i<pSession->nFilter; i++){
2357 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
2358 }
2359 return 1;
2360}
2361#endif
2362
2363/*
drh44c2eb12003-04-30 11:38:26 +00002364** Make sure the database is open. If it is not, then open it. If
2365** the database fails to open, print an error message and exit.
2366*/
drhdcd87a92014-08-18 13:45:42 +00002367static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002368 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002369 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002370 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002371 globalDb = p->db;
2372 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2373 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002374 shellstaticFunc, 0, 0);
2375 }
mistachkin8e189222015-04-19 21:43:16 +00002376 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00002377 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002378 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002379 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002380 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002381 }
drhc2e87a32006-06-27 15:16:14 +00002382#ifndef SQLITE_OMIT_LOAD_EXTENSION
2383 sqlite3_enable_load_extension(p->db, 1);
2384#endif
mistachkin8e189222015-04-19 21:43:16 +00002385 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002386 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002387 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002388 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002389 }
2390}
2391
2392/*
drhfeac5f82004-08-01 00:10:45 +00002393** Do C-language style dequoting.
2394**
mistachkinf21979d2015-01-18 05:35:01 +00002395** \a -> alarm
2396** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002397** \t -> tab
2398** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002399** \v -> vertical tab
2400** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002401** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002402** \s -> space
drh4c56b992013-06-27 13:26:55 +00002403** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002404** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002405** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002406** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002407*/
2408static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002409 int i, j;
2410 char c;
drhc2ce0be2014-05-29 12:36:14 +00002411 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002412 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002413 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002414 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002415 if( c=='a' ){
2416 c = '\a';
2417 }else if( c=='b' ){
2418 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002419 }else if( c=='t' ){
2420 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002421 }else if( c=='n' ){
2422 c = '\n';
2423 }else if( c=='v' ){
2424 c = '\v';
2425 }else if( c=='f' ){
2426 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002427 }else if( c=='r' ){
2428 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002429 }else if( c=='"' ){
2430 c = '"';
2431 }else if( c=='\'' ){
2432 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002433 }else if( c=='\\' ){
2434 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002435 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002436 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002437 if( z[i+1]>='0' && z[i+1]<='7' ){
2438 i++;
2439 c = (c<<3) + z[i] - '0';
2440 if( z[i+1]>='0' && z[i+1]<='7' ){
2441 i++;
2442 c = (c<<3) + z[i] - '0';
2443 }
2444 }
2445 }
2446 }
2447 z[j] = c;
2448 }
drhc2ce0be2014-05-29 12:36:14 +00002449 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002450}
2451
2452/*
drh348d19c2013-06-03 12:47:43 +00002453** Return the value of a hexadecimal digit. Return -1 if the input
2454** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002455*/
drh348d19c2013-06-03 12:47:43 +00002456static int hexDigitValue(char c){
2457 if( c>='0' && c<='9' ) return c - '0';
2458 if( c>='a' && c<='f' ) return c - 'a' + 10;
2459 if( c>='A' && c<='F' ) return c - 'A' + 10;
2460 return -1;
drhc28490c2006-10-26 14:25:58 +00002461}
2462
2463/*
drh7d9f3942013-04-03 01:26:54 +00002464** Interpret zArg as an integer value, possibly with suffixes.
2465*/
2466static sqlite3_int64 integerValue(const char *zArg){
2467 sqlite3_int64 v = 0;
2468 static const struct { char *zSuffix; int iMult; } aMult[] = {
2469 { "KiB", 1024 },
2470 { "MiB", 1024*1024 },
2471 { "GiB", 1024*1024*1024 },
2472 { "KB", 1000 },
2473 { "MB", 1000000 },
2474 { "GB", 1000000000 },
2475 { "K", 1000 },
2476 { "M", 1000000 },
2477 { "G", 1000000000 },
2478 };
2479 int i;
2480 int isNeg = 0;
2481 if( zArg[0]=='-' ){
2482 isNeg = 1;
2483 zArg++;
2484 }else if( zArg[0]=='+' ){
2485 zArg++;
2486 }
drh348d19c2013-06-03 12:47:43 +00002487 if( zArg[0]=='0' && zArg[1]=='x' ){
2488 int x;
2489 zArg += 2;
2490 while( (x = hexDigitValue(zArg[0]))>=0 ){
2491 v = (v<<4) + x;
2492 zArg++;
2493 }
2494 }else{
2495 while( IsDigit(zArg[0]) ){
2496 v = v*10 + zArg[0] - '0';
2497 zArg++;
2498 }
drh7d9f3942013-04-03 01:26:54 +00002499 }
drhc2bed0a2013-05-24 11:57:50 +00002500 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002501 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2502 v *= aMult[i].iMult;
2503 break;
2504 }
2505 }
2506 return isNeg? -v : v;
2507}
2508
2509/*
drh348d19c2013-06-03 12:47:43 +00002510** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2511** for TRUE and FALSE. Return the integer value if appropriate.
2512*/
2513static int booleanValue(char *zArg){
2514 int i;
2515 if( zArg[0]=='0' && zArg[1]=='x' ){
2516 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2517 }else{
2518 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2519 }
2520 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2521 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2522 return 1;
2523 }
2524 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2525 return 0;
2526 }
mistachkinaae280e2015-12-31 19:06:24 +00002527 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002528 zArg);
2529 return 0;
2530}
2531
2532/*
drh42f64e52012-04-04 16:56:23 +00002533** Close an output file, assuming it is not stderr or stdout
2534*/
2535static void output_file_close(FILE *f){
2536 if( f && f!=stdout && f!=stderr ) fclose(f);
2537}
2538
2539/*
2540** Try to open an output file. The names "stdout" and "stderr" are
mistachkin1fe36bb2016-04-04 02:16:44 +00002541** recognized and do the right thing. NULL is returned if the output
drh42f64e52012-04-04 16:56:23 +00002542** filename is "off".
2543*/
2544static FILE *output_file_open(const char *zFile){
2545 FILE *f;
2546 if( strcmp(zFile,"stdout")==0 ){
2547 f = stdout;
2548 }else if( strcmp(zFile, "stderr")==0 ){
2549 f = stderr;
2550 }else if( strcmp(zFile, "off")==0 ){
2551 f = 0;
2552 }else{
2553 f = fopen(zFile, "wb");
2554 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002555 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002556 }
2557 }
2558 return f;
2559}
2560
2561/*
2562** A routine for handling output from sqlite3_trace().
2563*/
drh4b363a52016-07-23 20:27:41 +00002564static int sql_trace_callback(
2565 unsigned mType,
2566 void *pArg,
2567 void *pP,
2568 void *pX
2569){
drh42f64e52012-04-04 16:56:23 +00002570 FILE *f = (FILE*)pArg;
drhb0df5402016-08-01 17:06:44 +00002571 UNUSED_PARAMETER(mType);
2572 UNUSED_PARAMETER(pP);
drh4b2590e2014-08-19 19:28:00 +00002573 if( f ){
drh4b363a52016-07-23 20:27:41 +00002574 const char *z = (const char*)pX;
drh4b2590e2014-08-19 19:28:00 +00002575 int i = (int)strlen(z);
2576 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002577 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002578 }
drh4b363a52016-07-23 20:27:41 +00002579 return 0;
drh42f64e52012-04-04 16:56:23 +00002580}
2581
2582/*
drhd8621b92012-04-17 09:09:33 +00002583** A no-op routine that runs with the ".breakpoint" doc-command. This is
2584** a useful spot to set a debugger breakpoint.
2585*/
2586static void test_breakpoint(void){
2587 static int nCall = 0;
2588 nCall++;
2589}
2590
2591/*
mistachkin636bf9f2014-07-19 20:15:16 +00002592** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002593*/
mistachkin636bf9f2014-07-19 20:15:16 +00002594typedef struct ImportCtx ImportCtx;
2595struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002596 const char *zFile; /* Name of the input file */
2597 FILE *in; /* Read the CSV text from this input stream */
2598 char *z; /* Accumulated text for a field */
2599 int n; /* Number of bytes in z */
2600 int nAlloc; /* Space allocated for z[] */
2601 int nLine; /* Current line number */
2602 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002603 int cColSep; /* The column separator character. (Usually ",") */
2604 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002605};
2606
2607/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002608static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002609 if( p->n+1>=p->nAlloc ){
2610 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002611 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002612 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002613 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002614 exit(1);
2615 }
2616 }
2617 p->z[p->n++] = (char)c;
2618}
2619
2620/* Read a single field of CSV text. Compatible with rfc4180 and extended
2621** with the option of having a separator other than ",".
2622**
2623** + Input comes from p->in.
2624** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002625** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002626** + Use p->cSep as the column separator. The default is ",".
2627** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002628** + Keep track of the line number in p->nLine.
2629** + Store the character that terminates the field in p->cTerm. Store
2630** EOF on end-of-file.
2631** + Report syntax errors on stderr
2632*/
mistachkin44723ce2015-03-21 02:22:37 +00002633static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002634 int c;
2635 int cSep = p->cColSep;
2636 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002637 p->n = 0;
2638 c = fgetc(p->in);
2639 if( c==EOF || seenInterrupt ){
2640 p->cTerm = EOF;
2641 return 0;
2642 }
2643 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002644 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002645 int startLine = p->nLine;
2646 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002647 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002648 while( 1 ){
2649 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002650 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002651 if( c==cQuote ){
2652 if( pc==cQuote ){
2653 pc = 0;
2654 continue;
2655 }
2656 }
2657 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002658 || (c==rSep && pc==cQuote)
2659 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002660 || (c==EOF && pc==cQuote)
2661 ){
2662 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002663 p->cTerm = c;
2664 break;
2665 }
2666 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002667 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002668 p->zFile, p->nLine, cQuote);
2669 }
2670 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002671 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002672 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002673 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002674 break;
2675 }
mistachkin636bf9f2014-07-19 20:15:16 +00002676 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002677 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002678 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002679 }
drhdb95f682013-06-26 22:46:00 +00002680 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002681 while( c!=EOF && c!=cSep && c!=rSep ){
2682 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002683 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002684 }
mistachkin636bf9f2014-07-19 20:15:16 +00002685 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002686 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002687 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002688 }
drhdb95f682013-06-26 22:46:00 +00002689 p->cTerm = c;
2690 }
drh8dd675e2013-07-12 21:09:24 +00002691 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002692 return p->z;
2693}
2694
mistachkin636bf9f2014-07-19 20:15:16 +00002695/* Read a single field of ASCII delimited text.
2696**
2697** + Input comes from p->in.
2698** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002699** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002700** + Use p->cSep as the column separator. The default is "\x1F".
2701** + Use p->rSep as the row separator. The default is "\x1E".
2702** + Keep track of the row number in p->nLine.
2703** + Store the character that terminates the field in p->cTerm. Store
2704** EOF on end-of-file.
2705** + Report syntax errors on stderr
2706*/
mistachkin44723ce2015-03-21 02:22:37 +00002707static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002708 int c;
2709 int cSep = p->cColSep;
2710 int rSep = p->cRowSep;
2711 p->n = 0;
2712 c = fgetc(p->in);
2713 if( c==EOF || seenInterrupt ){
2714 p->cTerm = EOF;
2715 return 0;
2716 }
2717 while( c!=EOF && c!=cSep && c!=rSep ){
2718 import_append_char(p, c);
2719 c = fgetc(p->in);
2720 }
2721 if( c==rSep ){
2722 p->nLine++;
2723 }
2724 p->cTerm = c;
2725 if( p->z ) p->z[p->n] = 0;
2726 return p->z;
2727}
2728
drhdb95f682013-06-26 22:46:00 +00002729/*
drh4bbcf102014-02-06 02:46:08 +00002730** Try to transfer data for table zTable. If an error is seen while
2731** moving forward, try to go backwards. The backwards movement won't
2732** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002733*/
mistachkine31ae902014-02-06 01:15:29 +00002734static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002735 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002736 sqlite3 *newDb,
2737 const char *zTable
2738){
mistachkin1fe36bb2016-04-04 02:16:44 +00002739 sqlite3_stmt *pQuery = 0;
drh3350ce92014-02-06 00:49:12 +00002740 sqlite3_stmt *pInsert = 0;
2741 char *zQuery = 0;
2742 char *zInsert = 0;
2743 int rc;
2744 int i, j, n;
2745 int nTable = (int)strlen(zTable);
2746 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002747 int cnt = 0;
2748 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002749
2750 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2751 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2752 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002753 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002754 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2755 zQuery);
2756 goto end_data_xfer;
2757 }
2758 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002759 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002760 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002761 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002762 goto end_data_xfer;
2763 }
2764 sqlite3_snprintf(200+nTable,zInsert,
2765 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2766 i = (int)strlen(zInsert);
2767 for(j=1; j<n; j++){
2768 memcpy(zInsert+i, ",?", 2);
2769 i += 2;
2770 }
2771 memcpy(zInsert+i, ");", 3);
2772 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2773 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002774 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002775 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2776 zQuery);
2777 goto end_data_xfer;
2778 }
2779 for(k=0; k<2; k++){
2780 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2781 for(i=0; i<n; i++){
2782 switch( sqlite3_column_type(pQuery, i) ){
2783 case SQLITE_NULL: {
2784 sqlite3_bind_null(pInsert, i+1);
2785 break;
2786 }
2787 case SQLITE_INTEGER: {
2788 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2789 break;
2790 }
2791 case SQLITE_FLOAT: {
2792 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2793 break;
2794 }
2795 case SQLITE_TEXT: {
2796 sqlite3_bind_text(pInsert, i+1,
2797 (const char*)sqlite3_column_text(pQuery,i),
2798 -1, SQLITE_STATIC);
2799 break;
2800 }
2801 case SQLITE_BLOB: {
2802 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2803 sqlite3_column_bytes(pQuery,i),
2804 SQLITE_STATIC);
2805 break;
2806 }
2807 }
2808 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002809 rc = sqlite3_step(pInsert);
2810 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002811 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002812 sqlite3_errmsg(newDb));
2813 }
drh3350ce92014-02-06 00:49:12 +00002814 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002815 cnt++;
2816 if( (cnt%spinRate)==0 ){
2817 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2818 fflush(stdout);
2819 }
drh3350ce92014-02-06 00:49:12 +00002820 } /* End while */
2821 if( rc==SQLITE_DONE ) break;
2822 sqlite3_finalize(pQuery);
2823 sqlite3_free(zQuery);
2824 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2825 zTable);
2826 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2827 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002828 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002829 break;
drh3350ce92014-02-06 00:49:12 +00002830 }
2831 } /* End for(k=0...) */
2832
2833end_data_xfer:
2834 sqlite3_finalize(pQuery);
2835 sqlite3_finalize(pInsert);
2836 sqlite3_free(zQuery);
2837 sqlite3_free(zInsert);
2838}
2839
2840
2841/*
2842** Try to transfer all rows of the schema that match zWhere. For
2843** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002844** If an error is encountered while moving forward through the
2845** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002846*/
mistachkine31ae902014-02-06 01:15:29 +00002847static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002848 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002849 sqlite3 *newDb,
2850 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002851 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002852){
2853 sqlite3_stmt *pQuery = 0;
2854 char *zQuery = 0;
2855 int rc;
2856 const unsigned char *zName;
2857 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002858 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002859
2860 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2861 " WHERE %s", 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 if( rc!=SQLITE_DONE ){
2885 sqlite3_finalize(pQuery);
2886 sqlite3_free(zQuery);
2887 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2888 " WHERE %s ORDER BY rowid DESC", zWhere);
2889 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2890 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002891 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002892 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2893 zQuery);
2894 goto end_schema_xfer;
2895 }
2896 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2897 zName = sqlite3_column_text(pQuery, 0);
2898 zSql = sqlite3_column_text(pQuery, 1);
2899 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002900 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2901 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002902 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002903 sqlite3_free(zErrMsg);
2904 zErrMsg = 0;
2905 }
drh3350ce92014-02-06 00:49:12 +00002906 if( xForEach ){
2907 xForEach(p, newDb, (const char*)zName);
2908 }
2909 printf("done\n");
2910 }
2911 }
2912end_schema_xfer:
2913 sqlite3_finalize(pQuery);
2914 sqlite3_free(zQuery);
2915}
2916
2917/*
2918** Open a new database file named "zNewDb". Try to recover as much information
2919** as possible out of the main database (which might be corrupt) and write it
2920** into zNewDb.
2921*/
drhdcd87a92014-08-18 13:45:42 +00002922static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002923 int rc;
2924 sqlite3 *newDb = 0;
2925 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002926 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002927 return;
2928 }
2929 rc = sqlite3_open(zNewDb, &newDb);
2930 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002931 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002932 sqlite3_errmsg(newDb));
2933 }else{
drh54d0d2d2014-04-03 00:32:13 +00002934 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002935 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002936 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2937 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002938 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002939 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002940 }
2941 sqlite3_close(newDb);
2942}
2943
2944/*
drhc2ce0be2014-05-29 12:36:14 +00002945** Change the output file back to stdout
2946*/
drhdcd87a92014-08-18 13:45:42 +00002947static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002948 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002949#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002950 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002951#endif
drhc2ce0be2014-05-29 12:36:14 +00002952 }else{
2953 output_file_close(p->out);
2954 }
2955 p->outfile[0] = 0;
2956 p->out = stdout;
2957}
2958
2959/*
drhf7502f02015-02-06 14:19:44 +00002960** Run an SQL command and return the single integer result.
2961*/
2962static int db_int(ShellState *p, const char *zSql){
2963 sqlite3_stmt *pStmt;
2964 int res = 0;
2965 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2966 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2967 res = sqlite3_column_int(pStmt,0);
2968 }
2969 sqlite3_finalize(pStmt);
2970 return res;
2971}
2972
2973/*
2974** Convert a 2-byte or 4-byte big-endian integer into a native integer
2975*/
drha0620ac2016-07-13 13:05:13 +00002976static unsigned int get2byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00002977 return (a[0]<<8) + a[1];
2978}
drha0620ac2016-07-13 13:05:13 +00002979static unsigned int get4byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00002980 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2981}
2982
2983/*
2984** Implementation of the ".info" command.
2985**
2986** Return 1 on error, 2 to exit, and 0 otherwise.
2987*/
drh0e55db12015-02-06 14:51:13 +00002988static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002989 static const struct { const char *zName; int ofst; } aField[] = {
2990 { "file change counter:", 24 },
2991 { "database page count:", 28 },
2992 { "freelist page count:", 36 },
2993 { "schema cookie:", 40 },
2994 { "schema format:", 44 },
2995 { "default cache size:", 48 },
2996 { "autovacuum top root:", 52 },
2997 { "incremental vacuum:", 64 },
2998 { "text encoding:", 56 },
2999 { "user version:", 60 },
3000 { "application id:", 68 },
3001 { "software version:", 96 },
3002 };
drh0e55db12015-02-06 14:51:13 +00003003 static const struct { const char *zName; const char *zSql; } aQuery[] = {
3004 { "number of tables:",
3005 "SELECT count(*) FROM %s WHERE type='table'" },
3006 { "number of indexes:",
3007 "SELECT count(*) FROM %s WHERE type='index'" },
3008 { "number of triggers:",
3009 "SELECT count(*) FROM %s WHERE type='trigger'" },
3010 { "number of views:",
3011 "SELECT count(*) FROM %s WHERE type='view'" },
3012 { "schema size:",
3013 "SELECT total(length(sql)) FROM %s" },
3014 };
mistachkinbfe8bd52015-11-17 19:17:14 +00003015 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00003016 int i;
3017 char *zSchemaTab;
3018 char *zDb = nArg>=2 ? azArg[1] : "main";
3019 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00003020 open_db(p, 0);
3021 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00003022 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00003023 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
3024 return 1;
3025 }
3026 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
3027 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003028 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00003029 return 1;
3030 }
3031 i = get2byteInt(aHdr+16);
3032 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00003033 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
3034 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
3035 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
3036 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00003037 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00003038 int ofst = aField[i].ofst;
3039 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00003040 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00003041 switch( ofst ){
3042 case 56: {
mistachkin1fe36bb2016-04-04 02:16:44 +00003043 if( val==1 ) raw_printf(p->out, " (utf8)");
3044 if( val==2 ) raw_printf(p->out, " (utf16le)");
3045 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00003046 }
3047 }
mistachkinaae280e2015-12-31 19:06:24 +00003048 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00003049 }
drh0e55db12015-02-06 14:51:13 +00003050 if( zDb==0 ){
3051 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
3052 }else if( strcmp(zDb,"temp")==0 ){
3053 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
3054 }else{
3055 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
3056 }
drhf5ed7ad2015-06-15 14:43:25 +00003057 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00003058 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
3059 int val = db_int(p, zSql);
3060 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00003061 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00003062 }
3063 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00003064 return 0;
3065}
3066
dand95bb392015-09-30 11:19:05 +00003067/*
3068** Print the current sqlite3_errmsg() value to stderr and return 1.
3069*/
3070static int shellDatabaseError(sqlite3 *db){
3071 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00003072 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00003073 return 1;
3074}
3075
3076/*
3077** Print an out-of-memory message to stderr and return 1.
3078*/
3079static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00003080 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00003081 return 1;
3082}
drhf7502f02015-02-06 14:19:44 +00003083
drh2db82112016-09-15 21:35:24 +00003084#ifdef SQLITE_DEBUG
3085/*
3086** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
3087** if they match and FALSE (0) if they do not match.
3088**
3089** Globbing rules:
3090**
3091** '*' Matches any sequence of zero or more characters.
3092**
3093** '?' Matches exactly one character.
3094**
3095** [...] Matches one character from the enclosed list of
3096** characters.
3097**
3098** [^...] Matches one character not in the enclosed list.
3099**
3100** '#' Matches any sequence of one or more digits with an
3101** optional + or - sign in front
3102**
3103** ' ' Any span of whitespace matches any other span of
3104** whitespace.
3105**
3106** Extra whitespace at the end of z[] is ignored.
3107*/
3108static int testcase_glob(const char *zGlob, const char *z){
3109 int c, c2;
3110 int invert;
3111 int seen;
3112
3113 while( (c = (*(zGlob++)))!=0 ){
3114 if( IsSpace(c) ){
3115 if( !IsSpace(*z) ) return 0;
3116 while( IsSpace(*zGlob) ) zGlob++;
3117 while( IsSpace(*z) ) z++;
3118 }else if( c=='*' ){
3119 while( (c=(*(zGlob++))) == '*' || c=='?' ){
3120 if( c=='?' && (*(z++))==0 ) return 0;
3121 }
3122 if( c==0 ){
3123 return 1;
3124 }else if( c=='[' ){
3125 while( *z && testcase_glob(zGlob-1,z)==0 ){
3126 z++;
3127 }
3128 return (*z)!=0;
3129 }
3130 while( (c2 = (*(z++)))!=0 ){
3131 while( c2!=c ){
3132 c2 = *(z++);
3133 if( c2==0 ) return 0;
3134 }
3135 if( testcase_glob(zGlob,z) ) return 1;
3136 }
3137 return 0;
3138 }else if( c=='?' ){
3139 if( (*(z++))==0 ) return 0;
3140 }else if( c=='[' ){
3141 int prior_c = 0;
3142 seen = 0;
3143 invert = 0;
3144 c = *(z++);
3145 if( c==0 ) return 0;
3146 c2 = *(zGlob++);
3147 if( c2=='^' ){
3148 invert = 1;
3149 c2 = *(zGlob++);
3150 }
3151 if( c2==']' ){
3152 if( c==']' ) seen = 1;
3153 c2 = *(zGlob++);
3154 }
3155 while( c2 && c2!=']' ){
3156 if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
3157 c2 = *(zGlob++);
3158 if( c>=prior_c && c<=c2 ) seen = 1;
3159 prior_c = 0;
3160 }else{
3161 if( c==c2 ){
3162 seen = 1;
3163 }
3164 prior_c = c2;
3165 }
3166 c2 = *(zGlob++);
3167 }
3168 if( c2==0 || (seen ^ invert)==0 ) return 0;
3169 }else if( c=='#' ){
3170 if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
3171 if( !IsDigit(z[0]) ) return 0;
3172 z++;
3173 while( IsDigit(z[0]) ){ z++; }
3174 }else{
3175 if( c!=(*(z++)) ) return 0;
3176 }
3177 }
3178 while( IsSpace(*z) ){ z++; }
3179 return *z==0;
3180}
3181#endif /* defined(SQLITE_DEBUG) */
3182
3183
drhf7502f02015-02-06 14:19:44 +00003184/*
drh4926fec2016-04-13 15:33:42 +00003185** Compare the string as a command-line option with either one or two
3186** initial "-" characters.
3187*/
3188static int optionMatch(const char *zStr, const char *zOpt){
3189 if( zStr[0]!='-' ) return 0;
3190 zStr++;
3191 if( zStr[0]=='-' ) zStr++;
3192 return strcmp(zStr, zOpt)==0;
3193}
3194
3195/*
drhcd0509e2016-09-16 00:26:08 +00003196** Delete a file.
3197*/
3198int shellDeleteFile(const char *zFilename){
3199 int rc;
3200#ifdef _WIN32
3201 wchar_t *z = sqlite3_utf8_to_path(zFilename, 0);
3202 rc = _wunlink(z);
3203 sqlite3_free(z);
3204#else
3205 rc = unlink(zFilename);
3206#endif
3207 return rc;
3208}
3209
3210/*
drh75897232000-05-29 14:26:00 +00003211** If an input line begins with "." then invoke this routine to
3212** process that line.
drh67505e72002-04-19 12:34:06 +00003213**
drh47ad6842006-11-08 12:25:42 +00003214** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00003215*/
drhdcd87a92014-08-18 13:45:42 +00003216static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00003217 int h = 1;
drh75897232000-05-29 14:26:00 +00003218 int nArg = 0;
3219 int n, c;
drh67505e72002-04-19 12:34:06 +00003220 int rc = 0;
drh75897232000-05-29 14:26:00 +00003221 char *azArg[50];
3222
3223 /* Parse the input line into tokens.
3224 */
mistachkin8e189222015-04-19 21:43:16 +00003225 while( zLine[h] && nArg<ArraySize(azArg) ){
3226 while( IsSpace(zLine[h]) ){ h++; }
3227 if( zLine[h]==0 ) break;
3228 if( zLine[h]=='\'' || zLine[h]=='"' ){
3229 int delim = zLine[h++];
3230 azArg[nArg++] = &zLine[h];
mistachkin1fe36bb2016-04-04 02:16:44 +00003231 while( zLine[h] && zLine[h]!=delim ){
mistachkin8e189222015-04-19 21:43:16 +00003232 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
mistachkin1fe36bb2016-04-04 02:16:44 +00003233 h++;
drh4c56b992013-06-27 13:26:55 +00003234 }
mistachkin8e189222015-04-19 21:43:16 +00003235 if( zLine[h]==delim ){
3236 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00003237 }
drhfeac5f82004-08-01 00:10:45 +00003238 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003239 }else{
mistachkin8e189222015-04-19 21:43:16 +00003240 azArg[nArg++] = &zLine[h];
3241 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
3242 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00003243 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003244 }
3245 }
3246
3247 /* Process the input line.
3248 */
shane9bd1b442009-10-23 01:27:39 +00003249 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00003250 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00003251 c = azArg[0][0];
drhde613c62016-04-04 17:23:10 +00003252
3253 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
3254 if( nArg!=2 ){
3255 raw_printf(stderr, "Usage: .auth ON|OFF\n");
3256 rc = 1;
3257 goto meta_command_exit;
3258 }
3259 open_db(p, 0);
3260 if( booleanValue(azArg[1]) ){
3261 sqlite3_set_authorizer(p->db, shellAuth, p);
3262 }else{
3263 sqlite3_set_authorizer(p->db, 0, 0);
3264 }
3265 }else
3266
drh5c7976f2014-02-10 19:59:27 +00003267 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
3268 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
3269 ){
drhbc46f022013-01-23 18:53:23 +00003270 const char *zDestFile = 0;
3271 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00003272 sqlite3 *pDest;
3273 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00003274 int j;
3275 for(j=1; j<nArg; j++){
3276 const char *z = azArg[j];
3277 if( z[0]=='-' ){
3278 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00003279 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00003280 {
mistachkinaae280e2015-12-31 19:06:24 +00003281 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00003282 return 1;
3283 }
3284 }else if( zDestFile==0 ){
3285 zDestFile = azArg[j];
3286 }else if( zDb==0 ){
3287 zDb = zDestFile;
3288 zDestFile = azArg[j];
3289 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003290 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00003291 return 1;
3292 }
drh9ff849f2009-02-04 20:55:57 +00003293 }
drhbc46f022013-01-23 18:53:23 +00003294 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003295 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00003296 return 1;
3297 }
3298 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00003299 rc = sqlite3_open(zDestFile, &pDest);
3300 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003301 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00003302 sqlite3_close(pDest);
3303 return 1;
3304 }
drh05782482013-10-24 15:20:20 +00003305 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003306 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
3307 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003308 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00003309 sqlite3_close(pDest);
3310 return 1;
3311 }
3312 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
3313 sqlite3_backup_finish(pBackup);
3314 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003315 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00003316 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003317 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00003318 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003319 }
3320 sqlite3_close(pDest);
3321 }else
3322
drhc2ce0be2014-05-29 12:36:14 +00003323 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
3324 if( nArg==2 ){
3325 bail_on_error = booleanValue(azArg[1]);
3326 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003327 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003328 rc = 1;
3329 }
drhc49f44e2006-10-26 18:15:42 +00003330 }else
3331
mistachkinf21979d2015-01-18 05:35:01 +00003332 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
3333 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00003334 if( booleanValue(azArg[1]) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003335 setBinaryMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003336 }else{
mistachkin1fe36bb2016-04-04 02:16:44 +00003337 setTextMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003338 }
mistachkinf21979d2015-01-18 05:35:01 +00003339 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003340 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00003341 rc = 1;
3342 }
3343 }else
3344
drhd8621b92012-04-17 09:09:33 +00003345 /* The undocumented ".breakpoint" command causes a call to the no-op
3346 ** routine named test_breakpoint().
3347 */
3348 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
3349 test_breakpoint();
3350 }else
3351
drhdf12f1c2015-12-07 21:46:19 +00003352 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
3353 if( nArg==2 ){
3354 p->countChanges = booleanValue(azArg[1]);
3355 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003356 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00003357 rc = 1;
3358 }
3359 }else
3360
drh2db82112016-09-15 21:35:24 +00003361 /* Cancel output redirection, if it is currently set (by .testcase)
3362 ** Then read the content of the testcase-out.txt file and compare against
3363 ** azArg[1]. If there are differences, report an error and exit.
3364 */
3365 if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
3366 char *zRes = 0;
3367 output_reset(p);
3368 if( nArg!=2 ){
3369 raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
drh760c8162016-09-16 02:52:22 +00003370 rc = 2;
drh2db82112016-09-15 21:35:24 +00003371 }else if( (zRes = readFile("testcase-out.txt"))==0 ){
3372 raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
3373 rc = 2;
3374 }else if( testcase_glob(azArg[1],zRes)==0 ){
drh760c8162016-09-16 02:52:22 +00003375 raw_printf(stderr,
3376 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
3377 p->zTestcase, azArg[1], zRes);
drh2db82112016-09-15 21:35:24 +00003378 rc = 2;
drh760c8162016-09-16 02:52:22 +00003379 }else{
3380 raw_printf(stdout, "testcase-%s ok\n", p->zTestcase);
3381 p->nCheck++;
drh2db82112016-09-15 21:35:24 +00003382 }
3383 sqlite3_free(zRes);
3384 }else
drh2db82112016-09-15 21:35:24 +00003385
drhc2ce0be2014-05-29 12:36:14 +00003386 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
3387 if( nArg==2 ){
3388 tryToClone(p, azArg[1]);
3389 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003390 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003391 rc = 1;
3392 }
mistachkine31ae902014-02-06 01:15:29 +00003393 }else
3394
drhc2ce0be2014-05-29 12:36:14 +00003395 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003396 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00003397 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003398 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00003399 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00003400 data.showHeader = 1;
drh700c2522016-02-09 18:39:25 +00003401 data.cMode = data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00003402 data.colWidth[0] = 3;
3403 data.colWidth[1] = 15;
3404 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00003405 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00003406 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00003407 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003408 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003409 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003410 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00003411 }
3412 }else
3413
drh0e55db12015-02-06 14:51:13 +00003414 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
3415 rc = shell_dbinfo_command(p, nArg, azArg);
3416 }else
3417
drhc2ce0be2014-05-29 12:36:14 +00003418 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00003419 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00003420 /* When playing back a "dump", the content might appear in an order
3421 ** which causes immediate foreign key constraints to be violated.
3422 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00003423 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003424 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003425 rc = 1;
3426 goto meta_command_exit;
3427 }
mistachkinaae280e2015-12-31 19:06:24 +00003428 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
3429 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00003430 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00003431 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00003432 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00003433 if( nArg==1 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003434 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003435 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003436 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00003437 );
mistachkin1fe36bb2016-04-04 02:16:44 +00003438 run_schema_dump_query(p,
drh4f324762009-05-21 14:51:03 +00003439 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003440 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00003441 );
drh2f464a02011-10-13 00:41:49 +00003442 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003443 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00003444 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00003445 );
drh4c653a02000-06-07 01:27:47 +00003446 }else{
3447 int i;
drhdd3d4592004-08-30 01:54:05 +00003448 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00003449 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00003450 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003451 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00003452 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00003453 " AND sql NOT NULL");
3454 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003455 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00003456 "WHERE sql NOT NULL"
3457 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00003458 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00003459 );
danielk1977bc6ada42004-06-30 08:20:16 +00003460 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00003461 }
3462 }
drh45e29d82006-11-20 16:21:10 +00003463 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00003464 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00003465 p->writableSchema = 0;
3466 }
drh56197952011-10-13 16:30:13 +00003467 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
3468 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00003469 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00003470 }else
drh75897232000-05-29 14:26:00 +00003471
drhc2ce0be2014-05-29 12:36:14 +00003472 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
3473 if( nArg==2 ){
3474 p->echoOn = booleanValue(azArg[1]);
3475 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003476 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003477 rc = 1;
3478 }
drhdaffd0e2001-04-11 14:28:42 +00003479 }else
3480
drhc2ce0be2014-05-29 12:36:14 +00003481 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
3482 if( nArg==2 ){
drheacd29d2016-04-15 15:03:27 +00003483 if( strcmp(azArg[1],"full")==0 ){
3484 p->autoEQP = 2;
3485 }else{
3486 p->autoEQP = booleanValue(azArg[1]);
3487 }
drhc2ce0be2014-05-29 12:36:14 +00003488 }else{
drheacd29d2016-04-15 15:03:27 +00003489 raw_printf(stderr, "Usage: .eqp on|off|full\n");
drhc2ce0be2014-05-29 12:36:14 +00003490 rc = 1;
mistachkin1fe36bb2016-04-04 02:16:44 +00003491 }
drhefbf3b12014-02-28 20:47:24 +00003492 }else
3493
drhd3ac7d92013-01-25 18:33:43 +00003494 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00003495 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00003496 rc = 2;
drh75897232000-05-29 14:26:00 +00003497 }else
3498
drhc2ce0be2014-05-29 12:36:14 +00003499 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00003500 int val = 1;
3501 if( nArg>=2 ){
3502 if( strcmp(azArg[1],"auto")==0 ){
3503 val = 99;
3504 }else{
3505 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003506 }
drh700c2522016-02-09 18:39:25 +00003507 }
3508 if( val==1 && p->mode!=MODE_Explain ){
3509 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003510 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003511 p->autoExplain = 0;
3512 }else if( val==0 ){
3513 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3514 p->autoExplain = 0;
3515 }else if( val==99 ){
3516 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3517 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003518 }
drh75897232000-05-29 14:26:00 +00003519 }else
3520
drhc1971542014-06-23 23:28:13 +00003521 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003522 ShellState data;
drhc1971542014-06-23 23:28:13 +00003523 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003524 int doStats = 0;
drh4926fec2016-04-13 15:33:42 +00003525 memcpy(&data, p, sizeof(data));
3526 data.showHeader = 0;
3527 data.cMode = data.mode = MODE_Semi;
3528 if( nArg==2 && optionMatch(azArg[1], "indent") ){
3529 data.cMode = data.mode = MODE_Pretty;
3530 nArg = 1;
3531 }
drhc1971542014-06-23 23:28:13 +00003532 if( nArg!=1 ){
drh4926fec2016-04-13 15:33:42 +00003533 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
drhc1971542014-06-23 23:28:13 +00003534 rc = 1;
3535 goto meta_command_exit;
3536 }
3537 open_db(p, 0);
drhc1971542014-06-23 23:28:13 +00003538 rc = sqlite3_exec(p->db,
3539 "SELECT sql FROM"
3540 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3541 " FROM sqlite_master UNION ALL"
3542 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003543 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003544 "ORDER BY rowid",
3545 callback, &data, &zErrMsg
3546 );
drh56f674c2014-07-18 14:43:29 +00003547 if( rc==SQLITE_OK ){
3548 sqlite3_stmt *pStmt;
3549 rc = sqlite3_prepare_v2(p->db,
3550 "SELECT rowid FROM sqlite_master"
3551 " WHERE name GLOB 'sqlite_stat[134]'",
3552 -1, &pStmt, 0);
3553 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3554 sqlite3_finalize(pStmt);
3555 }
3556 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003557 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003558 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003559 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003560 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3561 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003562 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003563 data.zDestTable = "sqlite_stat1";
3564 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3565 shell_callback, &data,&zErrMsg);
3566 data.zDestTable = "sqlite_stat3";
3567 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3568 shell_callback, &data,&zErrMsg);
3569 data.zDestTable = "sqlite_stat4";
3570 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3571 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003572 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003573 }
drhc1971542014-06-23 23:28:13 +00003574 }else
3575
drhc2ce0be2014-05-29 12:36:14 +00003576 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3577 if( nArg==2 ){
3578 p->showHeader = booleanValue(azArg[1]);
3579 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003580 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003581 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003582 }
drh75897232000-05-29 14:26:00 +00003583 }else
3584
drhc2ce0be2014-05-29 12:36:14 +00003585 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003586 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003587 }else
3588
3589 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003590 char *zTable; /* Insert data into this table */
3591 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003592 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003593 int nCol; /* Number of columns in the table */
3594 int nByte; /* Number of bytes in an SQL string */
3595 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003596 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003597 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003598 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003599 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003600 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3601 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003602
drhc2ce0be2014-05-29 12:36:14 +00003603 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003604 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003605 goto meta_command_exit;
3606 }
drh01f37542014-05-31 15:43:33 +00003607 zFile = azArg[1];
3608 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003609 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003610 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003611 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003612 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003613 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003614 raw_printf(stderr,
3615 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003616 return 1;
drhfeac5f82004-08-01 00:10:45 +00003617 }
drhdb95f682013-06-26 22:46:00 +00003618 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003619 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003620 " for import\n");
3621 return 1;
3622 }
mistachkin636bf9f2014-07-19 20:15:16 +00003623 nSep = strlen30(p->rowSeparator);
3624 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003625 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003626 return 1;
3627 }
mistachkine0d68852014-12-11 03:12:33 +00003628 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3629 /* When importing CSV (only), if the row separator is set to the
3630 ** default output row separator, change it to the default input
3631 ** row separator. This avoids having to maintain different input
3632 ** and output row separators. */
3633 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3634 nSep = strlen30(p->rowSeparator);
3635 }
mistachkin636bf9f2014-07-19 20:15:16 +00003636 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003637 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003638 " for import\n");
3639 return 1;
3640 }
3641 sCtx.zFile = zFile;
3642 sCtx.nLine = 1;
3643 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003644#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003645 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003646 return 1;
3647#else
mistachkin636bf9f2014-07-19 20:15:16 +00003648 sCtx.in = popen(sCtx.zFile+1, "r");
3649 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003650 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003651#endif
drh5bde8162013-06-27 14:07:53 +00003652 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003653 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003654 xCloser = fclose;
3655 }
mistachkin636bf9f2014-07-19 20:15:16 +00003656 if( p->mode==MODE_Ascii ){
3657 xRead = ascii_read_one_field;
3658 }else{
3659 xRead = csv_read_one_field;
3660 }
3661 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003662 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003663 return 1;
3664 }
mistachkin636bf9f2014-07-19 20:15:16 +00003665 sCtx.cColSep = p->colSeparator[0];
3666 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003667 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003668 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003669 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003670 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003671 return 1;
3672 }
drh4f21c4a2008-12-10 22:15:00 +00003673 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003674 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003675 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003676 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003677 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3678 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003679 while( xRead(&sCtx) ){
drhd8c22ac2016-02-25 13:33:02 +00003680 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003681 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003682 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003683 }
drh5bde8162013-06-27 14:07:53 +00003684 if( cSep=='(' ){
3685 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003686 sqlite3_free(sCtx.z);
3687 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003688 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003689 return 1;
3690 }
drhdb95f682013-06-26 22:46:00 +00003691 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3692 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3693 sqlite3_free(zCreate);
3694 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003695 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003696 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003697 sqlite3_free(sCtx.z);
3698 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003699 return 1;
3700 }
drhc7181902014-02-27 15:04:13 +00003701 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003702 }
drhfeac5f82004-08-01 00:10:45 +00003703 sqlite3_free(zSql);
3704 if( rc ){
shane916f9612009-10-23 00:37:15 +00003705 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00003706 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003707 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003708 return 1;
drhfeac5f82004-08-01 00:10:45 +00003709 }
shane916f9612009-10-23 00:37:15 +00003710 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003711 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003712 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003713 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003714 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003715 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003716 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003717 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003718 return 1;
3719 }
drhdb95f682013-06-26 22:46:00 +00003720 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003721 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003722 for(i=1; i<nCol; i++){
3723 zSql[j++] = ',';
3724 zSql[j++] = '?';
3725 }
3726 zSql[j++] = ')';
3727 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003728 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003729 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003730 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003731 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003732 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003733 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003734 return 1;
drhfeac5f82004-08-01 00:10:45 +00003735 }
mistachkin8e189222015-04-19 21:43:16 +00003736 needCommit = sqlite3_get_autocommit(p->db);
3737 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003738 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003739 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003740 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003741 char *z = xRead(&sCtx);
3742 /*
3743 ** Did we reach end-of-file before finding any columns?
3744 ** If so, stop instead of NULL filling the remaining columns.
3745 */
drhdb95f682013-06-26 22:46:00 +00003746 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003747 /*
3748 ** Did we reach end-of-file OR end-of-line before finding any
3749 ** columns in ASCII mode? If so, stop instead of NULL filling
3750 ** the remaining columns.
3751 */
3752 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003753 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003754 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00003755 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003756 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003757 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003758 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003759 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003760 }
drhfeac5f82004-08-01 00:10:45 +00003761 }
mistachkin636bf9f2014-07-19 20:15:16 +00003762 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003763 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003764 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003765 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003766 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00003767 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003768 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003769 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003770 }
drhdb95f682013-06-26 22:46:00 +00003771 if( i>=nCol ){
3772 sqlite3_step(pStmt);
3773 rc = sqlite3_reset(pStmt);
3774 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003775 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
3776 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003777 }
3778 }
mistachkin636bf9f2014-07-19 20:15:16 +00003779 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003780
mistachkin636bf9f2014-07-19 20:15:16 +00003781 xCloser(sCtx.in);
3782 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003783 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003784 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003785 }else
3786
drh0e55db12015-02-06 14:51:13 +00003787 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3788 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003789 ShellState data;
drh75897232000-05-29 14:26:00 +00003790 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003791 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003792 memcpy(&data, p, sizeof(data));
3793 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003794 data.cMode = data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003795 if( nArg==1 ){
3796 rc = sqlite3_exec(p->db,
3797 "SELECT name FROM sqlite_master "
3798 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3799 "UNION ALL "
3800 "SELECT name FROM sqlite_temp_master "
3801 "WHERE type='index' "
3802 "ORDER BY 1",
3803 callback, &data, &zErrMsg
3804 );
drhc2ce0be2014-05-29 12:36:14 +00003805 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003806 zShellStatic = azArg[1];
3807 rc = sqlite3_exec(p->db,
3808 "SELECT name FROM sqlite_master "
3809 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3810 "UNION ALL "
3811 "SELECT name FROM sqlite_temp_master "
3812 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3813 "ORDER BY 1",
3814 callback, &data, &zErrMsg
3815 );
3816 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003817 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003818 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003819 rc = 1;
3820 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003821 }
drh75897232000-05-29 14:26:00 +00003822 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003823 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003824 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003825 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003826 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003827 raw_printf(stderr,
3828 "Error: querying sqlite_master and sqlite_temp_master\n");
shane86f5bdb2009-10-24 02:00:07 +00003829 rc = 1;
drh75897232000-05-29 14:26:00 +00003830 }
3831 }else
3832
drhae5e4452007-05-03 17:18:36 +00003833#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003834 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003835 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003836 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3837 iotrace = 0;
3838 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003839 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003840 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003841 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003842 iotrace = stdout;
3843 }else{
3844 iotrace = fopen(azArg[1], "w");
3845 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003846 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003847 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003848 rc = 1;
drhb0603412007-02-28 04:47:26 +00003849 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003850 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003851 }
3852 }
3853 }else
drhae5e4452007-05-03 17:18:36 +00003854#endif
drh1a513372015-05-02 17:40:23 +00003855 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3856 static const struct {
3857 const char *zLimitName; /* Name of a limit */
3858 int limitCode; /* Integer code for that limit */
3859 } aLimit[] = {
3860 { "length", SQLITE_LIMIT_LENGTH },
3861 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3862 { "column", SQLITE_LIMIT_COLUMN },
3863 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3864 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3865 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3866 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3867 { "attached", SQLITE_LIMIT_ATTACHED },
3868 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3869 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3870 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3871 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3872 };
3873 int i, n2;
3874 open_db(p, 0);
3875 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003876 for(i=0; i<ArraySize(aLimit); i++){
mistachkin1fe36bb2016-04-04 02:16:44 +00003877 printf("%20s %d\n", aLimit[i].zLimitName,
drh1a513372015-05-02 17:40:23 +00003878 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3879 }
3880 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003881 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00003882 rc = 1;
3883 goto meta_command_exit;
3884 }else{
3885 int iLimit = -1;
3886 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003887 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003888 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3889 if( iLimit<0 ){
3890 iLimit = i;
3891 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003892 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00003893 rc = 1;
3894 goto meta_command_exit;
3895 }
3896 }
3897 }
3898 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003899 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00003900 "enter \".limits\" with no arguments for a list.\n",
3901 azArg[1]);
3902 rc = 1;
3903 goto meta_command_exit;
3904 }
3905 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003906 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3907 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003908 }
3909 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3910 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3911 }
3912 }else
drhb0603412007-02-28 04:47:26 +00003913
drh70df4fe2006-06-13 15:12:21 +00003914#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003915 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003916 const char *zFile, *zProc;
3917 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003918 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003919 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00003920 rc = 1;
3921 goto meta_command_exit;
3922 }
drh1e397f82006-06-08 15:28:43 +00003923 zFile = azArg[1];
3924 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003925 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003926 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3927 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003928 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003929 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003930 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003931 }
3932 }else
drh70df4fe2006-06-13 15:12:21 +00003933#endif
drh1e397f82006-06-08 15:28:43 +00003934
drhc2ce0be2014-05-29 12:36:14 +00003935 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3936 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003937 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003938 rc = 1;
3939 }else{
3940 const char *zFile = azArg[1];
3941 output_file_close(p->pLog);
3942 p->pLog = output_file_open(zFile);
3943 }
drh127f9d72010-02-23 01:47:00 +00003944 }else
3945
drhc2ce0be2014-05-29 12:36:14 +00003946 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3947 const char *zMode = nArg>=2 ? azArg[1] : "";
3948 int n2 = (int)strlen(zMode);
3949 int c2 = zMode[0];
3950 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003951 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003952 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003953 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003954 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003955 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003956 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003957 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003958 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003959 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003960 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003961 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003962 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003963 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003964 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003965 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003966 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003967 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003968 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003969 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003970 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003971 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3972 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003973 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3974 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003975 }else {
mistachkinaae280e2015-12-31 19:06:24 +00003976 raw_printf(stderr, "Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003977 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003978 rc = 1;
drh75897232000-05-29 14:26:00 +00003979 }
drh700c2522016-02-09 18:39:25 +00003980 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00003981 }else
3982
drhc2ce0be2014-05-29 12:36:14 +00003983 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3984 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003985 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3986 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003987 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003988 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003989 rc = 1;
3990 }
3991 }else
3992
drh05782482013-10-24 15:20:20 +00003993 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
drhcd0509e2016-09-16 00:26:08 +00003994 char *zNewFilename; /* Name of the database file to open */
3995 int iName = 1; /* Index in azArg[] of the filename */
drh760c8162016-09-16 02:52:22 +00003996 int newFlag = 0; /* True to delete file before opening */
drhcd0509e2016-09-16 00:26:08 +00003997 /* Close the existing database */
3998 session_close_all(p);
3999 sqlite3_close(p->db);
drh05782482013-10-24 15:20:20 +00004000 p->db = 0;
drhcd0509e2016-09-16 00:26:08 +00004001 sqlite3_free(p->zFreeOnClose);
4002 p->zFreeOnClose = 0;
drh760c8162016-09-16 02:52:22 +00004003 /* Check for command-line arguments */
4004 for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
4005 const char *z = azArg[iName];
4006 if( optionMatch(z,"new") ){
4007 newFlag = 1;
4008 }else if( z[0]=='-' ){
4009 utf8_printf(stderr, "unknown option: %s\n", z);
4010 rc = 1;
4011 }
drhcd0509e2016-09-16 00:26:08 +00004012 }
4013 /* If a filename is specified, try to open it first */
4014 zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
4015 if( zNewFilename ){
drh760c8162016-09-16 02:52:22 +00004016 if( newFlag ) shellDeleteFile(zNewFilename);
drhcd0509e2016-09-16 00:26:08 +00004017 p->zDbFilename = zNewFilename;
4018 open_db(p, 1);
4019 if( p->db==0 ){
4020 utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
4021 sqlite3_free(zNewFilename);
4022 }else{
4023 p->zFreeOnClose = zNewFilename;
4024 }
4025 }
4026 if( p->db==0 ){
4027 /* As a fall-back open a TEMP database */
4028 p->zDbFilename = 0;
4029 open_db(p, 0);
drh05782482013-10-24 15:20:20 +00004030 }
4031 }else
4032
drhc2ce0be2014-05-29 12:36:14 +00004033 if( c=='o'
4034 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
4035 ){
4036 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
4037 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004038 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00004039 rc = 1;
4040 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004041 }
drhc2ce0be2014-05-29 12:36:14 +00004042 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
4043 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004044 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004045 rc = 1;
4046 goto meta_command_exit;
4047 }
4048 p->outCount = 2;
4049 }else{
4050 p->outCount = 0;
4051 }
4052 output_reset(p);
4053 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00004054#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00004055 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00004056 rc = 1;
4057 p->out = stdout;
4058#else
drhc2ce0be2014-05-29 12:36:14 +00004059 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00004060 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004061 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00004062 p->out = stdout;
4063 rc = 1;
4064 }else{
drhc2ce0be2014-05-29 12:36:14 +00004065 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00004066 }
drh8cd5b252015-03-02 22:06:43 +00004067#endif
drh75897232000-05-29 14:26:00 +00004068 }else{
drhc2ce0be2014-05-29 12:36:14 +00004069 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00004070 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004071 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004072 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00004073 }
drh75897232000-05-29 14:26:00 +00004074 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00004075 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00004076 } else {
drhc2ce0be2014-05-29 12:36:14 +00004077 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00004078 }
4079 }
4080 }else
4081
drh078b1fd2012-09-21 13:40:02 +00004082 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
4083 int i;
4084 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00004085 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00004086 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00004087 }
mistachkinaae280e2015-12-31 19:06:24 +00004088 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00004089 }else
4090
drhc2ce0be2014-05-29 12:36:14 +00004091 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00004092 if( nArg >= 2) {
4093 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
4094 }
4095 if( nArg >= 3) {
4096 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
4097 }
4098 }else
4099
drhc2ce0be2014-05-29 12:36:14 +00004100 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00004101 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00004102 }else
4103
drhc2ce0be2014-05-29 12:36:14 +00004104 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
4105 FILE *alt;
4106 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004107 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004108 rc = 1;
4109 goto meta_command_exit;
4110 }
4111 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00004112 if( alt==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004113 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
shane9bd1b442009-10-23 01:27:39 +00004114 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00004115 }else{
shane9bd1b442009-10-23 01:27:39 +00004116 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00004117 fclose(alt);
4118 }
4119 }else
4120
drhc2ce0be2014-05-29 12:36:14 +00004121 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00004122 const char *zSrcFile;
4123 const char *zDb;
4124 sqlite3 *pSrc;
4125 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00004126 int nTimeout = 0;
4127
drh9ff849f2009-02-04 20:55:57 +00004128 if( nArg==2 ){
4129 zSrcFile = azArg[1];
4130 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00004131 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00004132 zSrcFile = azArg[2];
4133 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00004134 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004135 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004136 rc = 1;
4137 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00004138 }
4139 rc = sqlite3_open(zSrcFile, &pSrc);
4140 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004141 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00004142 sqlite3_close(pSrc);
4143 return 1;
4144 }
drh05782482013-10-24 15:20:20 +00004145 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00004146 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
4147 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004148 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00004149 sqlite3_close(pSrc);
4150 return 1;
4151 }
drhdc2c4912009-02-04 22:46:47 +00004152 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
4153 || rc==SQLITE_BUSY ){
4154 if( rc==SQLITE_BUSY ){
4155 if( nTimeout++ >= 3 ) break;
4156 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00004157 }
4158 }
4159 sqlite3_backup_finish(pBackup);
4160 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00004161 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00004162 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00004163 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00004164 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004165 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004166 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00004167 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004168 }
4169 sqlite3_close(pSrc);
4170 }else
4171
dan8d1edb92014-11-05 09:07:28 +00004172
4173 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
4174 if( nArg==2 ){
4175 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00004176#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00004177 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00004178#endif
dan8d1edb92014-11-05 09:07:28 +00004179 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004180 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00004181 rc = 1;
4182 }
4183 }else
4184
drhc2ce0be2014-05-29 12:36:14 +00004185 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00004186 ShellState data;
drh75897232000-05-29 14:26:00 +00004187 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00004188 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00004189 memcpy(&data, p, sizeof(data));
4190 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00004191 data.cMode = data.mode = MODE_Semi;
drh4926fec2016-04-13 15:33:42 +00004192 if( nArg>=2 && optionMatch(azArg[1], "indent") ){
4193 data.cMode = data.mode = MODE_Pretty;
4194 nArg--;
4195 if( nArg==2 ) azArg[1] = azArg[2];
4196 }
4197 if( nArg==2 && azArg[1][0]!='-' ){
drhc8d74412004-08-31 23:41:26 +00004198 int i;
drhf0693c82011-10-11 20:41:54 +00004199 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00004200 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00004201 char *new_argv[2], *new_colv[2];
4202 new_argv[0] = "CREATE TABLE sqlite_master (\n"
4203 " type text,\n"
4204 " name text,\n"
4205 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00004206 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00004207 " sql text\n"
4208 ")";
4209 new_argv[1] = 0;
4210 new_colv[0] = "sql";
4211 new_colv[1] = 0;
4212 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004213 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00004214 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00004215 char *new_argv[2], *new_colv[2];
4216 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
4217 " type text,\n"
4218 " name text,\n"
4219 " tbl_name text,\n"
4220 " rootpage integer,\n"
4221 " sql text\n"
4222 ")";
4223 new_argv[1] = 0;
4224 new_colv[0] = "sql";
4225 new_colv[1] = 0;
4226 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004227 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00004228 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00004229 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00004230 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004231 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004232 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004233 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004234 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00004235 "WHERE lower(tbl_name) LIKE shellstatic()"
4236 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00004237 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00004238 callback, &data, &zErrMsg);
4239 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00004240 }
drhc2ce0be2014-05-29 12:36:14 +00004241 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00004242 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004243 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004244 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004245 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004246 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00004247 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00004248 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00004249 callback, &data, &zErrMsg
4250 );
drhc2ce0be2014-05-29 12:36:14 +00004251 }else{
drh4926fec2016-04-13 15:33:42 +00004252 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00004253 rc = 1;
4254 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004255 }
drh75897232000-05-29 14:26:00 +00004256 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00004257 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004258 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00004259 rc = 1;
4260 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004261 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00004262 rc = 1;
4263 }else{
4264 rc = 0;
drh75897232000-05-29 14:26:00 +00004265 }
4266 }else
4267
drhabd4c722014-09-20 18:18:33 +00004268#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
4269 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
drh1d9be4f2015-01-22 11:29:25 +00004270 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00004271 }else
4272#endif
4273
drhe6229612014-08-18 15:08:26 +00004274#if defined(SQLITE_ENABLE_SESSION)
4275 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
4276 OpenSession *pSession = &p->aSession[0];
4277 char **azCmd = &azArg[1];
4278 int iSes = 0;
4279 int nCmd = nArg - 1;
4280 int i;
4281 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00004282 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00004283 if( nArg>=3 ){
4284 for(iSes=0; iSes<p->nSession; iSes++){
4285 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
4286 }
4287 if( iSes<p->nSession ){
4288 pSession = &p->aSession[iSes];
4289 azCmd++;
4290 nCmd--;
4291 }else{
4292 pSession = &p->aSession[0];
4293 iSes = 0;
4294 }
4295 }
4296
drh3a67b042014-08-18 17:56:31 +00004297 /* .session attach TABLE
4298 ** Invoke the sqlite3session_attach() interface to attach a particular
4299 ** table so that it is never filtered.
4300 */
4301 if( strcmp(azCmd[0],"attach")==0 ){
4302 if( nCmd!=2 ) goto session_syntax_error;
4303 if( pSession->p==0 ){
4304 session_not_open:
mistachkin899c5c92016-04-03 20:50:02 +00004305 raw_printf(stderr, "ERROR: No sessions are open\n");
drh3a67b042014-08-18 17:56:31 +00004306 }else{
4307 rc = sqlite3session_attach(pSession->p, azCmd[1]);
4308 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004309 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004310 rc = 0;
4311 }
4312 }
4313 }else
4314
4315 /* .session changeset FILE
4316 ** .session patchset FILE
4317 ** Write a changeset or patchset into a file. The file is overwritten.
4318 */
4319 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
4320 FILE *out = 0;
4321 if( nCmd!=2 ) goto session_syntax_error;
4322 if( pSession->p==0 ) goto session_not_open;
4323 out = fopen(azCmd[1], "wb");
4324 if( out==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004325 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
drh3a67b042014-08-18 17:56:31 +00004326 }else{
4327 int szChng;
4328 void *pChng;
4329 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00004330 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00004331 }else{
drh2967e0c2014-08-19 00:26:17 +00004332 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
4333 }
4334 if( rc ){
4335 printf("Error: error code %d\n", rc);
4336 rc = 0;
drh3a67b042014-08-18 17:56:31 +00004337 }
mistachkin1fe36bb2016-04-04 02:16:44 +00004338 if( pChng
drh3a67b042014-08-18 17:56:31 +00004339 && fwrite(pChng, szChng, 1, out)!=1 ){
mistachkin899c5c92016-04-03 20:50:02 +00004340 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
drh3a67b042014-08-18 17:56:31 +00004341 szChng);
4342 }
4343 sqlite3_free(pChng);
4344 fclose(out);
4345 }
4346 }else
4347
drhe6229612014-08-18 15:08:26 +00004348 /* .session close
4349 ** Close the identified session
4350 */
4351 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00004352 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00004353 if( p->nSession ){
4354 session_close(pSession);
4355 p->aSession[iSes] = p->aSession[--p->nSession];
4356 }
4357 }else
4358
drh03168ca2014-08-18 20:01:31 +00004359 /* .session enable ?BOOLEAN?
4360 ** Query or set the enable flag
4361 */
4362 if( strcmp(azCmd[0], "enable")==0 ){
4363 int ii;
4364 if( nCmd>2 ) goto session_syntax_error;
4365 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4366 if( p->nSession ){
4367 ii = sqlite3session_enable(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004368 utf8_printf(p->out, "session %s enable flag = %d\n",
4369 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004370 }
4371 }else
4372
4373 /* .session filter GLOB ....
4374 ** Set a list of GLOB patterns of table names to be excluded.
4375 */
4376 if( strcmp(azCmd[0], "filter")==0 ){
4377 int ii, nByte;
4378 if( nCmd<2 ) goto session_syntax_error;
4379 if( p->nSession ){
4380 for(ii=0; ii<pSession->nFilter; ii++){
4381 sqlite3_free(pSession->azFilter[ii]);
4382 }
4383 sqlite3_free(pSession->azFilter);
4384 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
4385 pSession->azFilter = sqlite3_malloc( nByte );
4386 if( pSession->azFilter==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004387 raw_printf(stderr, "Error: out or memory\n");
drh03168ca2014-08-18 20:01:31 +00004388 exit(1);
4389 }
4390 for(ii=1; ii<nCmd; ii++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004391 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
drh03168ca2014-08-18 20:01:31 +00004392 }
4393 pSession->nFilter = ii-1;
4394 }
4395 }else
4396
4397 /* .session indirect ?BOOLEAN?
4398 ** Query or set the indirect flag
4399 */
4400 if( strcmp(azCmd[0], "indirect")==0 ){
4401 int ii;
4402 if( nCmd>2 ) goto session_syntax_error;
4403 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4404 if( p->nSession ){
4405 ii = sqlite3session_indirect(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004406 utf8_printf(p->out, "session %s indirect flag = %d\n",
4407 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004408 }
4409 }else
4410
4411 /* .session isempty
4412 ** Determine if the session is empty
4413 */
4414 if( strcmp(azCmd[0], "isempty")==0 ){
4415 int ii;
4416 if( nCmd!=1 ) goto session_syntax_error;
4417 if( p->nSession ){
4418 ii = sqlite3session_isempty(pSession->p);
mistachkin899c5c92016-04-03 20:50:02 +00004419 utf8_printf(p->out, "session %s isempty flag = %d\n",
4420 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004421 }
4422 }else
4423
drhe6229612014-08-18 15:08:26 +00004424 /* .session list
4425 ** List all currently open sessions
4426 */
4427 if( strcmp(azCmd[0],"list")==0 ){
4428 for(i=0; i<p->nSession; i++){
mistachkin899c5c92016-04-03 20:50:02 +00004429 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
drhe6229612014-08-18 15:08:26 +00004430 }
4431 }else
4432
4433 /* .session open DB NAME
4434 ** Open a new session called NAME on the attached database DB.
4435 ** DB is normally "main".
4436 */
4437 if( strcmp(azCmd[0],"open")==0 ){
4438 char *zName;
4439 if( nCmd!=3 ) goto session_syntax_error;
4440 zName = azCmd[2];
4441 if( zName[0]==0 ) goto session_syntax_error;
4442 for(i=0; i<p->nSession; i++){
4443 if( strcmp(p->aSession[i].zName,zName)==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004444 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
drhe6229612014-08-18 15:08:26 +00004445 goto meta_command_exit;
4446 }
4447 }
4448 if( p->nSession>=ArraySize(p->aSession) ){
mistachkin899c5c92016-04-03 20:50:02 +00004449 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
drhe6229612014-08-18 15:08:26 +00004450 goto meta_command_exit;
4451 }
4452 pSession = &p->aSession[p->nSession];
4453 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
4454 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004455 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004456 rc = 0;
drhe6229612014-08-18 15:08:26 +00004457 goto meta_command_exit;
4458 }
drh03168ca2014-08-18 20:01:31 +00004459 pSession->nFilter = 0;
4460 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00004461 p->nSession++;
4462 pSession->zName = sqlite3_mprintf("%s", zName);
4463 }else
4464 /* If no command name matches, show a syntax error */
4465 session_syntax_error:
4466 session_help(p);
4467 }else
4468#endif
4469
drh340f5822013-06-27 13:01:21 +00004470#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00004471 /* Undocumented commands for internal testing. Subject to change
4472 ** without notice. */
4473 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
4474 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
4475 int i, v;
4476 for(i=1; i<nArg; i++){
4477 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00004478 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00004479 }
4480 }
4481 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
4482 int i; sqlite3_int64 v;
4483 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00004484 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00004485 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00004486 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00004487 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00004488 }
4489 }
4490 }else
drh340f5822013-06-27 13:01:21 +00004491#endif
drh348d19c2013-06-03 12:47:43 +00004492
drhc2ce0be2014-05-29 12:36:14 +00004493 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00004494 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004495 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00004496 rc = 1;
4497 }
drh6976c212014-07-24 12:09:47 +00004498 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004499 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00004500 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00004501 }
4502 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00004503 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
4504 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00004505 }
drh75897232000-05-29 14:26:00 +00004506 }else
4507
drh62cdde52014-05-28 20:22:28 +00004508 if( c=='s'
4509 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00004510 ){
4511 char *zCmd;
drh54027102014-08-06 14:36:53 +00004512 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00004513 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004514 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00004515 rc = 1;
4516 goto meta_command_exit;
4517 }
drhdcb3e3d2014-05-29 03:17:29 +00004518 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00004519 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00004520 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
4521 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00004522 }
drh54027102014-08-06 14:36:53 +00004523 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00004524 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00004525 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00004526 }else
4527
drhc2ce0be2014-05-29 12:36:14 +00004528 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drheacd29d2016-04-15 15:03:27 +00004529 static const char *azBool[] = { "off", "on", "full", "unk" };
persicom7e2dfdd2002-04-18 02:46:52 +00004530 int i;
drhc2ce0be2014-05-29 12:36:14 +00004531 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00004532 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00004533 rc = 1;
4534 goto meta_command_exit;
4535 }
drheacd29d2016-04-15 15:03:27 +00004536 utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]);
4537 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
drh700c2522016-02-09 18:39:25 +00004538 utf8_printf(p->out, "%12.12s: %s\n","explain",
4539 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
drheacd29d2016-04-15 15:03:27 +00004540 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004541 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
4542 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00004543 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00004544 raw_printf(p->out, "\n");
4545 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00004546 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00004547 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004548 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004549 raw_printf(p->out, "\n");
4550 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004551 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004552 raw_printf(p->out, "\n");
drheacd29d2016-04-15 15:03:27 +00004553 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004554 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00004555 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00004556 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00004557 }
mistachkinaae280e2015-12-31 19:06:24 +00004558 raw_printf(p->out, "\n");
drhcd0509e2016-09-16 00:26:08 +00004559 utf8_printf(p->out, "%12.12s: %s\n", "filename",
4560 p->zDbFilename ? p->zDbFilename : "");
persicom7e2dfdd2002-04-18 02:46:52 +00004561 }else
4562
drhc2ce0be2014-05-29 12:36:14 +00004563 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
4564 if( nArg==2 ){
4565 p->statsOn = booleanValue(azArg[1]);
drh34784902016-02-27 17:12:36 +00004566 }else if( nArg==1 ){
4567 display_stats(p->db, p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004568 }else{
drh34784902016-02-27 17:12:36 +00004569 raw_printf(stderr, "Usage: .stats ?on|off?\n");
drhc2ce0be2014-05-29 12:36:14 +00004570 rc = 1;
4571 }
shaneh642d8b82010-07-28 16:05:34 +00004572 }else
4573
drhc2ce0be2014-05-29 12:36:14 +00004574 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00004575 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00004576 char **azResult;
drh98781232012-04-23 12:38:05 +00004577 int nRow, nAlloc;
4578 char *zSql = 0;
4579 int ii;
drh05782482013-10-24 15:20:20 +00004580 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00004581 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00004582 if( rc ) return shellDatabaseError(p->db);
4583
4584 /* Create an SQL statement to query for the list of tables in the
4585 ** main and all attached databases where the table name matches the
4586 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00004587 zSql = sqlite3_mprintf(
4588 "SELECT name FROM sqlite_master"
4589 " WHERE type IN ('table','view')"
4590 " AND name NOT LIKE 'sqlite_%%'"
4591 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00004592 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00004593 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
4594 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
4595 if( strcmp(zDbName,"temp")==0 ){
4596 zSql = sqlite3_mprintf(
4597 "%z UNION ALL "
4598 "SELECT 'temp.' || name FROM sqlite_temp_master"
4599 " WHERE type IN ('table','view')"
4600 " AND name NOT LIKE 'sqlite_%%'"
4601 " AND name LIKE ?1", zSql);
4602 }else{
4603 zSql = sqlite3_mprintf(
4604 "%z UNION ALL "
4605 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4606 " WHERE type IN ('table','view')"
4607 " AND name NOT LIKE 'sqlite_%%'"
4608 " AND name LIKE ?1", zSql, zDbName, zDbName);
4609 }
drha50da102000-08-08 20:19:09 +00004610 }
dand95bb392015-09-30 11:19:05 +00004611 rc = sqlite3_finalize(pStmt);
4612 if( zSql && rc==SQLITE_OK ){
4613 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
4614 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4615 }
drh98781232012-04-23 12:38:05 +00004616 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00004617 if( !zSql ) return shellNomemError();
4618 if( rc ) return shellDatabaseError(p->db);
4619
4620 /* Run the SQL statement prepared by the above block. Store the results
4621 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00004622 nRow = nAlloc = 0;
4623 azResult = 0;
4624 if( nArg>1 ){
4625 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00004626 }else{
drh98781232012-04-23 12:38:05 +00004627 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
4628 }
4629 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4630 if( nRow>=nAlloc ){
4631 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00004632 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00004633 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00004634 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00004635 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00004636 break;
4637 }
mistachkin8e189222015-04-19 21:43:16 +00004638 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00004639 azResult = azNew;
4640 }
4641 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00004642 if( 0==azResult[nRow] ){
4643 rc = shellNomemError();
4644 break;
4645 }
4646 nRow++;
drh98781232012-04-23 12:38:05 +00004647 }
dand95bb392015-09-30 11:19:05 +00004648 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
4649 rc = shellDatabaseError(p->db);
4650 }
4651
4652 /* Pretty-print the contents of array azResult[] to the output */
4653 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00004654 int len, maxlen = 0;
4655 int i, j;
4656 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00004657 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00004658 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00004659 if( len>maxlen ) maxlen = len;
4660 }
4661 nPrintCol = 80/(maxlen+2);
4662 if( nPrintCol<1 ) nPrintCol = 1;
4663 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
4664 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00004665 for(j=i; j<nRow; j+=nPrintRow){
4666 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00004667 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
4668 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00004669 }
mistachkinaae280e2015-12-31 19:06:24 +00004670 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00004671 }
4672 }
dand95bb392015-09-30 11:19:05 +00004673
drh98781232012-04-23 12:38:05 +00004674 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
4675 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00004676 }else
4677
drh2db82112016-09-15 21:35:24 +00004678 /* Begin redirecting output to the file "testcase-out.txt" */
4679 if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
4680 output_reset(p);
4681 p->out = output_file_open("testcase-out.txt");
4682 if( p->out==0 ){
4683 utf8_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
4684 }
drh760c8162016-09-16 02:52:22 +00004685 if( nArg>=2 ){
4686 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
4687 }else{
4688 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
4689 }
drh2db82112016-09-15 21:35:24 +00004690 }else
drh2db82112016-09-15 21:35:24 +00004691
shaneh96887e12011-02-10 21:08:58 +00004692 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00004693 static const struct {
4694 const char *zCtrlName; /* Name of a test-control option */
4695 int ctrlCode; /* Integer code for that option */
4696 } aCtrl[] = {
4697 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
4698 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
4699 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
4700 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
4701 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
4702 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
4703 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
4704 { "assert", SQLITE_TESTCTRL_ASSERT },
4705 { "always", SQLITE_TESTCTRL_ALWAYS },
4706 { "reserve", SQLITE_TESTCTRL_RESERVE },
4707 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
4708 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00004709 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00004710 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00004711 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00004712 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00004713 };
shaneh96887e12011-02-10 21:08:58 +00004714 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00004715 int rc2 = 0;
4716 int i, n2;
drh05782482013-10-24 15:20:20 +00004717 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00004718
drhd416fe72011-03-17 16:45:50 +00004719 /* convert testctrl text option to value. allow any unique prefix
4720 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00004721 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00004722 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00004723 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00004724 if( testctrl<0 ){
4725 testctrl = aCtrl[i].ctrlCode;
4726 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004727 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00004728 testctrl = -1;
4729 break;
4730 }
4731 }
4732 }
drh348d19c2013-06-03 12:47:43 +00004733 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004734 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00004735 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004736 }else{
4737 switch(testctrl){
4738
4739 /* sqlite3_test_control(int, db, int) */
4740 case SQLITE_TESTCTRL_OPTIMIZATIONS:
mistachkin1fe36bb2016-04-04 02:16:44 +00004741 case SQLITE_TESTCTRL_RESERVE:
shaneh96887e12011-02-10 21:08:58 +00004742 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004743 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00004744 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004745 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004746 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004747 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004748 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004749 }
4750 break;
4751
4752 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004753 case SQLITE_TESTCTRL_PRNG_SAVE:
4754 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004755 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004756 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004757 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00004758 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00004759 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004760 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004761 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
4762 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004763 }
4764 break;
4765
4766 /* sqlite3_test_control(int, uint) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004767 case SQLITE_TESTCTRL_PENDING_BYTE:
shaneh96887e12011-02-10 21:08:58 +00004768 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004769 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004770 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004771 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004772 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004773 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00004774 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004775 }
4776 break;
mistachkin1fe36bb2016-04-04 02:16:44 +00004777
shaneh96887e12011-02-10 21:08:58 +00004778 /* sqlite3_test_control(int, int) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004779 case SQLITE_TESTCTRL_ASSERT:
4780 case SQLITE_TESTCTRL_ALWAYS:
4781 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004782 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004783 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004784 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004785 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004786 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004787 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004788 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004789 }
4790 break;
4791
4792 /* sqlite3_test_control(int, char *) */
4793#ifdef SQLITE_N_KEYWORD
mistachkin1fe36bb2016-04-04 02:16:44 +00004794 case SQLITE_TESTCTRL_ISKEYWORD:
shaneh96887e12011-02-10 21:08:58 +00004795 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004796 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004797 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004798 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004799 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004800 utf8_printf(stderr,
4801 "Error: testctrl %s takes a single char * option\n",
4802 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004803 }
4804 break;
4805#endif
4806
drh1ffede82015-01-30 20:59:27 +00004807 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004808 if( nArg==5 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004809 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004810 azArg[2],
drh8964b342015-01-29 17:54:52 +00004811 integerValue(azArg[3]),
4812 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00004813 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004814 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004815 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004816 }
4817 break;
4818
mistachkin1fe36bb2016-04-04 02:16:44 +00004819 case SQLITE_TESTCTRL_BITVEC_TEST:
4820 case SQLITE_TESTCTRL_FAULT_INSTALL:
4821 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4822 case SQLITE_TESTCTRL_SCRATCHMALLOC:
shaneh96887e12011-02-10 21:08:58 +00004823 default:
mistachkinaae280e2015-12-31 19:06:24 +00004824 utf8_printf(stderr,
4825 "Error: CLI support for testctrl %s not implemented\n",
4826 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004827 break;
4828 }
4829 }
4830 }else
4831
drhc2ce0be2014-05-29 12:36:14 +00004832 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004833 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004834 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004835 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004836
drhc2ce0be2014-05-29 12:36:14 +00004837 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4838 if( nArg==2 ){
4839 enableTimer = booleanValue(azArg[1]);
4840 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00004841 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00004842 enableTimer = 0;
4843 }
4844 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004845 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004846 rc = 1;
4847 }
shanehe2aa9d72009-11-06 17:20:17 +00004848 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004849
drhc2ce0be2014-05-29 12:36:14 +00004850 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004851 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004852 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004853 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004854 rc = 1;
4855 goto meta_command_exit;
4856 }
drh657b4a82015-03-19 13:30:41 +00004857 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004858 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004859#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004860 if( p->traceOut==0 ){
drh4b363a52016-07-23 20:27:41 +00004861 sqlite3_trace_v2(p->db, 0, 0, 0);
drh42f64e52012-04-04 16:56:23 +00004862 }else{
drh4b363a52016-07-23 20:27:41 +00004863 sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004864 }
4865#endif
4866 }else
4867
drhf442e332014-09-10 19:01:14 +00004868#if SQLITE_USER_AUTHENTICATION
4869 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4870 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004871 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00004872 rc = 1;
4873 goto meta_command_exit;
4874 }
drh7883ecf2014-09-11 16:19:31 +00004875 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004876 if( strcmp(azArg[1],"login")==0 ){
4877 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00004878 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00004879 rc = 1;
4880 goto meta_command_exit;
4881 }
drhd39c40f2014-09-11 00:27:53 +00004882 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4883 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004884 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004885 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00004886 rc = 1;
4887 }
4888 }else if( strcmp(azArg[1],"add")==0 ){
4889 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004890 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004891 rc = 1;
4892 goto meta_command_exit;
4893 }
drhd39c40f2014-09-11 00:27:53 +00004894 rc = sqlite3_user_add(p->db, azArg[2],
4895 azArg[3], (int)strlen(azArg[3]),
4896 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004897 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004898 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004899 rc = 1;
4900 }
4901 }else if( strcmp(azArg[1],"edit")==0 ){
4902 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004903 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004904 rc = 1;
4905 goto meta_command_exit;
4906 }
drhd39c40f2014-09-11 00:27:53 +00004907 rc = sqlite3_user_change(p->db, azArg[2],
4908 azArg[3], (int)strlen(azArg[3]),
4909 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004910 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004911 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004912 rc = 1;
4913 }
4914 }else if( strcmp(azArg[1],"delete")==0 ){
4915 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004916 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00004917 rc = 1;
4918 goto meta_command_exit;
4919 }
4920 rc = sqlite3_user_delete(p->db, azArg[2]);
4921 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004922 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004923 rc = 1;
4924 }
4925 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004926 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00004927 rc = 1;
4928 goto meta_command_exit;
mistachkin1fe36bb2016-04-04 02:16:44 +00004929 }
drhf442e332014-09-10 19:01:14 +00004930 }else
4931#endif /* SQLITE_USER_AUTHENTICATION */
4932
drh9fd301b2011-06-03 13:28:22 +00004933 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004934 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004935 sqlite3_libversion(), sqlite3_sourceid());
4936 }else
4937
drh790f2872015-11-28 18:06:36 +00004938 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
4939 const char *zDbName = nArg==2 ? azArg[1] : "main";
4940 sqlite3_vfs *pVfs;
4941 if( p->db ){
4942 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
4943 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00004944 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
4945 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4946 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4947 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00004948 }
4949 }
4950 }else
4951
drhb19e7352016-01-12 19:37:20 +00004952 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
4953 sqlite3_vfs *pVfs;
4954 sqlite3_vfs *pCurrent = 0;
4955 if( p->db ){
4956 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
4957 }
4958 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
4959 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
4960 pVfs==pCurrent ? " <--- CURRENT" : "");
4961 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4962 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4963 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
4964 if( pVfs->pNext ){
4965 raw_printf(p->out, "-----------------------------------\n");
4966 }
4967 }
4968 }else
4969
drhde60fc22011-12-14 17:53:36 +00004970 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4971 const char *zDbName = nArg==2 ? azArg[1] : "main";
4972 char *zVfsName = 0;
4973 if( p->db ){
4974 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4975 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00004976 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004977 sqlite3_free(zVfsName);
4978 }
4979 }
4980 }else
4981
drhcef4fc82012-09-21 22:50:45 +00004982#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4983 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004984 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004985 }else
4986#endif
4987
drhc2ce0be2014-05-29 12:36:14 +00004988 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004989 int j;
drh43617e92006-03-06 20:55:46 +00004990 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004991 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004992 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004993 }
4994 }else
4995
4996 {
mistachkinaae280e2015-12-31 19:06:24 +00004997 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004998 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004999 rc = 1;
drh75897232000-05-29 14:26:00 +00005000 }
drh67505e72002-04-19 12:34:06 +00005001
drhc2ce0be2014-05-29 12:36:14 +00005002meta_command_exit:
5003 if( p->outCount ){
5004 p->outCount--;
5005 if( p->outCount==0 ) output_reset(p);
5006 }
drh67505e72002-04-19 12:34:06 +00005007 return rc;
drh75897232000-05-29 14:26:00 +00005008}
5009
drh67505e72002-04-19 12:34:06 +00005010/*
drh91a66392007-09-07 01:12:32 +00005011** Return TRUE if a semicolon occurs anywhere in the first N characters
5012** of string z[].
drh324ccef2003-02-05 14:06:20 +00005013*/
drh9f099fd2013-08-06 14:01:46 +00005014static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00005015 int i;
5016 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
5017 return 0;
drh324ccef2003-02-05 14:06:20 +00005018}
5019
5020/*
drh70c7a4b2003-04-26 03:03:06 +00005021** Test to see if a line consists entirely of whitespace.
5022*/
5023static int _all_whitespace(const char *z){
5024 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00005025 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00005026 if( *z=='/' && z[1]=='*' ){
5027 z += 2;
5028 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
5029 if( *z==0 ) return 0;
5030 z++;
5031 continue;
5032 }
5033 if( *z=='-' && z[1]=='-' ){
5034 z += 2;
5035 while( *z && *z!='\n' ){ z++; }
5036 if( *z==0 ) return 1;
5037 continue;
5038 }
5039 return 0;
5040 }
5041 return 1;
5042}
5043
5044/*
drha9b17162003-04-29 18:01:28 +00005045** Return TRUE if the line typed in is an SQL command terminator other
5046** than a semi-colon. The SQL Server style "go" command is understood
5047** as is the Oracle "/".
5048*/
drh9f099fd2013-08-06 14:01:46 +00005049static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00005050 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00005051 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
5052 return 1; /* Oracle */
5053 }
drhf0693c82011-10-11 20:41:54 +00005054 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00005055 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00005056 return 1; /* SQL Server */
5057 }
5058 return 0;
5059}
5060
5061/*
drh233a5312008-12-18 22:25:13 +00005062** Return true if zSql is a complete SQL statement. Return false if it
5063** ends in the middle of a string literal or C-style comment.
5064*/
drh9f099fd2013-08-06 14:01:46 +00005065static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00005066 int rc;
5067 if( zSql==0 ) return 1;
5068 zSql[nSql] = ';';
5069 zSql[nSql+1] = 0;
5070 rc = sqlite3_complete(zSql);
5071 zSql[nSql] = 0;
5072 return rc;
5073}
5074
5075/*
drh67505e72002-04-19 12:34:06 +00005076** Read input from *in and process it. If *in==0 then input
5077** is interactive - the user is typing it it. Otherwise, input
5078** is coming from a file or device. A prompt is issued and history
5079** is saved only if input is interactive. An interrupt signal will
5080** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00005081**
5082** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00005083*/
drhdcd87a92014-08-18 13:45:42 +00005084static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00005085 char *zLine = 0; /* A single input line */
5086 char *zSql = 0; /* Accumulated SQL text */
5087 int nLine; /* Length of current line */
5088 int nSql = 0; /* Bytes of zSql[] used */
5089 int nAlloc = 0; /* Allocated zSql[] space */
5090 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
5091 char *zErrMsg; /* Error message returned */
5092 int rc; /* Error code */
5093 int errCnt = 0; /* Number of errors seen */
5094 int lineno = 0; /* Current line number */
5095 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00005096
5097 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
5098 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00005099 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00005100 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00005101 /* End of input */
drhfc8b40f2016-09-07 10:10:18 +00005102 if( in==0 && stdin_is_interactive ) printf("\n");
drh9b8d3572012-04-21 11:33:39 +00005103 break;
drhc49f44e2006-10-26 18:15:42 +00005104 }
drh67505e72002-04-19 12:34:06 +00005105 if( seenInterrupt ){
5106 if( in!=0 ) break;
5107 seenInterrupt = 0;
5108 }
drhc28490c2006-10-26 14:25:58 +00005109 lineno++;
drh849a9d92013-12-21 15:46:06 +00005110 if( nSql==0 && _all_whitespace(zLine) ){
5111 if( p->echoOn ) printf("%s\n", zLine);
5112 continue;
5113 }
drh2af0b2d2002-02-21 02:25:02 +00005114 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00005115 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00005116 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00005117 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00005118 break;
5119 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00005120 errCnt++;
5121 }
drhdaffd0e2001-04-11 14:28:42 +00005122 continue;
5123 }
drh9f099fd2013-08-06 14:01:46 +00005124 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00005125 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00005126 }
drh9f099fd2013-08-06 14:01:46 +00005127 nLine = strlen30(zLine);
5128 if( nSql+nLine+2>=nAlloc ){
5129 nAlloc = nSql+nLine+100;
5130 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00005131 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005132 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00005133 exit(1);
5134 }
drhdaffd0e2001-04-11 14:28:42 +00005135 }
drh9f099fd2013-08-06 14:01:46 +00005136 nSqlPrior = nSql;
5137 if( nSql==0 ){
5138 int i;
5139 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00005140 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00005141 memcpy(zSql, zLine+i, nLine+1-i);
5142 startline = lineno;
5143 nSql = nLine-i;
5144 }else{
5145 zSql[nSql++] = '\n';
5146 memcpy(zSql+nSql, zLine, nLine+1);
5147 nSql += nLine;
5148 }
5149 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00005150 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00005151 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00005152 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00005153 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00005154 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00005155 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00005156 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00005157 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00005158 char zPrefix[100];
5159 if( in!=0 || !stdin_is_interactive ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005160 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00005161 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00005162 }else{
shane9bd1b442009-10-23 01:27:39 +00005163 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00005164 }
drh7f953e22002-07-13 17:33:45 +00005165 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005166 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00005167 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00005168 zErrMsg = 0;
5169 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005170 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00005171 }
drhc49f44e2006-10-26 18:15:42 +00005172 errCnt++;
drhdf12f1c2015-12-07 21:46:19 +00005173 }else if( p->countChanges ){
mistachkinaae280e2015-12-31 19:06:24 +00005174 raw_printf(p->out, "changes: %3d total_changes: %d\n",
drhdf12f1c2015-12-07 21:46:19 +00005175 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
drhdaffd0e2001-04-11 14:28:42 +00005176 }
drhdaffd0e2001-04-11 14:28:42 +00005177 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00005178 if( p->outCount ){
5179 output_reset(p);
5180 p->outCount = 0;
5181 }
drh9f099fd2013-08-06 14:01:46 +00005182 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00005183 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00005184 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00005185 }
5186 }
drh9f099fd2013-08-06 14:01:46 +00005187 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00005188 if( !_all_whitespace(zSql) ){
mistachkinaae280e2015-12-31 19:06:24 +00005189 utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00005190 errCnt++;
drhd416fe72011-03-17 16:45:50 +00005191 }
drhdaffd0e2001-04-11 14:28:42 +00005192 }
drh1f9ca2c2015-08-25 16:57:52 +00005193 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00005194 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00005195 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00005196}
5197
drh67505e72002-04-19 12:34:06 +00005198/*
5199** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00005200** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00005201*/
5202static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00005203 static char *home_dir = NULL;
5204 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00005205
drh4ace5362014-11-10 14:42:28 +00005206#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
5207 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00005208 {
5209 struct passwd *pwent;
5210 uid_t uid = getuid();
5211 if( (pwent=getpwuid(uid)) != NULL) {
5212 home_dir = pwent->pw_dir;
5213 }
drh67505e72002-04-19 12:34:06 +00005214 }
5215#endif
5216
chw65d3c132007-11-12 21:09:10 +00005217#if defined(_WIN32_WCE)
5218 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
5219 */
drh85e72432012-04-11 11:38:53 +00005220 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00005221#else
5222
drh83905c92012-06-21 13:00:37 +00005223#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00005224 if (!home_dir) {
5225 home_dir = getenv("USERPROFILE");
5226 }
5227#endif
5228
drh67505e72002-04-19 12:34:06 +00005229 if (!home_dir) {
5230 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00005231 }
5232
drh83905c92012-06-21 13:00:37 +00005233#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00005234 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00005235 char *zDrive, *zPath;
5236 int n;
5237 zDrive = getenv("HOMEDRIVE");
5238 zPath = getenv("HOMEPATH");
5239 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00005240 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00005241 home_dir = malloc( n );
5242 if( home_dir==0 ) return 0;
5243 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
5244 return home_dir;
5245 }
5246 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00005247 }
5248#endif
5249
chw65d3c132007-11-12 21:09:10 +00005250#endif /* !_WIN32_WCE */
5251
drh67505e72002-04-19 12:34:06 +00005252 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00005253 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00005254 char *z = malloc( n );
5255 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00005256 home_dir = z;
5257 }
drhe98d4fa2002-04-21 19:06:22 +00005258
drh67505e72002-04-19 12:34:06 +00005259 return home_dir;
5260}
5261
5262/*
5263** Read input from the file given by sqliterc_override. Or if that
5264** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00005265**
5266** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00005267*/
drh534f4df2015-02-28 14:03:35 +00005268static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00005269 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00005270 const char *sqliterc_override /* Name of config file. NULL to use default */
5271){
persicom7e2dfdd2002-04-18 02:46:52 +00005272 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00005273 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00005274 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00005275 FILE *in = NULL;
5276
5277 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00005278 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00005279 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005280 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00005281 " cannot read ~/.sqliterc\n");
5282 return;
drhe98d4fa2002-04-21 19:06:22 +00005283 }
drh2f3de322012-06-27 16:41:31 +00005284 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00005285 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
5286 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00005287 }
drha1f9b5e2004-02-14 16:31:02 +00005288 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00005289 if( in ){
drhc28490c2006-10-26 14:25:58 +00005290 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00005291 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00005292 }
drh534f4df2015-02-28 14:03:35 +00005293 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00005294 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00005295 }
drh85e72432012-04-11 11:38:53 +00005296 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00005297}
5298
drh67505e72002-04-19 12:34:06 +00005299/*
drhe1e38c42003-05-04 18:30:59 +00005300** Show available command line options
5301*/
mistachkin1fe36bb2016-04-04 02:16:44 +00005302static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00005303 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00005304 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00005305 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005306 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00005307 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00005308 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00005309 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00005310 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00005311 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00005312#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
5313 " -heap SIZE Size of heap for memsys3 or memsys5\n"
5314#endif
drhcc3b4f82012-02-07 14:13:50 +00005315 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00005316 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00005317 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005318 " -line set output mode to 'line'\n"
5319 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00005320 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00005321 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00005322#ifdef SQLITE_ENABLE_MULTIPLEX
5323 " -multiplex enable the multiplexor VFS\n"
5324#endif
mistachkine0d68852014-12-11 03:12:33 +00005325 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00005326 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00005327 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
5328 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00005329 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00005330 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00005331 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00005332 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00005333#ifdef SQLITE_ENABLE_VFSTRACE
5334 " -vfstrace enable tracing of all VFS calls\n"
5335#endif
drhe1e38c42003-05-04 18:30:59 +00005336;
5337static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00005338 utf8_printf(stderr,
mistachkin1fe36bb2016-04-04 02:16:44 +00005339 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
drh80e8be92006-08-29 12:04:19 +00005340 "FILENAME is the name of an SQLite database. A new database is created\n"
5341 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00005342 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00005343 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00005344 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005345 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00005346 }
5347 exit(1);
5348}
5349
5350/*
drh67505e72002-04-19 12:34:06 +00005351** Initialize the state information in data
5352*/
drhdcd87a92014-08-18 13:45:42 +00005353static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00005354 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00005355 data->normalMode = data->cMode = data->mode = MODE_List;
5356 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00005357 memcpy(data->colSeparator,SEP_Column, 2);
5358 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00005359 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00005360 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00005361 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00005362 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00005363 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00005364 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
5365 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00005366}
5367
drh98d312f2012-10-25 15:23:14 +00005368/*
drh5c7976f2014-02-10 19:59:27 +00005369** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00005370*/
5371#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00005372static void printBold(const char *zText){
5373 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
5374 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
5375 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
5376 SetConsoleTextAttribute(out,
5377 FOREGROUND_RED|FOREGROUND_INTENSITY
5378 );
5379 printf("%s", zText);
5380 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00005381}
5382#else
drh5c7976f2014-02-10 19:59:27 +00005383static void printBold(const char *zText){
5384 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00005385}
5386#endif
5387
5388/*
drh98d312f2012-10-25 15:23:14 +00005389** Get the argument to an --option. Throw an error and die if no argument
5390** is available.
5391*/
5392static char *cmdline_option_value(int argc, char **argv, int i){
5393 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00005394 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00005395 argv[0], argv[argc-1]);
5396 exit(1);
5397 }
5398 return argv[i];
5399}
5400
mistachkin1fe36bb2016-04-04 02:16:44 +00005401#ifndef SQLITE_SHELL_IS_UTF8
5402# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
5403# define SQLITE_SHELL_IS_UTF8 (0)
5404# else
5405# define SQLITE_SHELL_IS_UTF8 (1)
5406# endif
5407#endif
5408
5409#if SQLITE_SHELL_IS_UTF8
mistachkin44723ce2015-03-21 02:22:37 +00005410int SQLITE_CDECL main(int argc, char **argv){
mistachkin1fe36bb2016-04-04 02:16:44 +00005411#else
5412int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
mistachkin1810f222016-04-04 02:33:34 +00005413 char **argv;
mistachkin1fe36bb2016-04-04 02:16:44 +00005414#endif
drh75897232000-05-29 14:26:00 +00005415 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00005416 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00005417 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00005418 int i;
drhc28490c2006-10-26 14:25:58 +00005419 int rc = 0;
drhb3735912014-02-10 16:13:42 +00005420 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00005421 int readStdin = 1;
5422 int nCmd = 0;
5423 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00005424
mistachkin1fe36bb2016-04-04 02:16:44 +00005425 setBinaryMode(stdin, 0);
5426 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
mistachkin1810f222016-04-04 02:33:34 +00005427 stdin_is_interactive = isatty(0);
5428 stdout_is_console = isatty(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005429
drh69b30ab2014-02-27 15:11:52 +00005430#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00005431 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005432 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00005433 sqlite3_sourceid(), SQLITE_SOURCE_ID);
5434 exit(1);
5435 }
drhc7181902014-02-27 15:04:13 +00005436#endif
persicom7e2dfdd2002-04-18 02:46:52 +00005437 main_init(&data);
mistachkin1fe36bb2016-04-04 02:16:44 +00005438#if !SQLITE_SHELL_IS_UTF8
5439 sqlite3_initialize();
5440 argv = sqlite3_malloc64(sizeof(argv[0])*argc);
5441 if( argv==0 ){
5442 raw_printf(stderr, "out of memory\n");
5443 exit(1);
5444 }
5445 for(i=0; i<argc; i++){
5446 argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
5447 if( argv[i]==0 ){
5448 raw_printf(stderr, "out of memory\n");
5449 exit(1);
5450 }
5451 }
5452#endif
mistachkin1810f222016-04-04 02:33:34 +00005453 assert( argc>=1 && argv && argv[0] );
mistachkin1fe36bb2016-04-04 02:16:44 +00005454 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00005455
drh44c2eb12003-04-30 11:38:26 +00005456 /* Make sure we have a valid signal handler early, before anything
5457 ** else is done.
5458 */
drh4c504392000-10-16 22:06:40 +00005459#ifdef SIGINT
5460 signal(SIGINT, interrupt_handler);
5461#endif
drh44c2eb12003-04-30 11:38:26 +00005462
drhac5649a2014-11-28 13:35:03 +00005463#ifdef SQLITE_SHELL_DBNAME_PROC
5464 {
5465 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
5466 ** of a C-function that will provide the name of the database file. Use
5467 ** this compile-time option to embed this shell program in larger
5468 ** applications. */
5469 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
5470 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
5471 warnInmemoryDb = 0;
5472 }
5473#endif
5474
drh22fbcb82004-02-01 01:22:50 +00005475 /* Do an initial pass through the command-line argument to locate
5476 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00005477 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00005478 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00005479 */
drh98d312f2012-10-25 15:23:14 +00005480 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00005481 char *z;
drhc28490c2006-10-26 14:25:58 +00005482 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005483 if( z[0]!='-' ){
5484 if( data.zDbFilename==0 ){
5485 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00005486 }else{
5487 /* Excesss arguments are interpreted as SQL (or dot-commands) and
5488 ** mean that nothing is read from stdin */
5489 readStdin = 0;
5490 nCmd++;
5491 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
5492 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005493 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00005494 exit(1);
5495 }
5496 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00005497 }
drh98d312f2012-10-25 15:23:14 +00005498 }
drhcc3b4f82012-02-07 14:13:50 +00005499 if( z[1]=='-' ) z++;
5500 if( strcmp(z,"-separator")==0
5501 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00005502 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00005503 || strcmp(z,"-cmd")==0
5504 ){
drh98d312f2012-10-25 15:23:14 +00005505 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005506 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00005507 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005508 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00005509 /* Need to check for batch mode here to so we can avoid printing
mistachkin1fe36bb2016-04-04 02:16:44 +00005510 ** informational messages (like from process_sqliterc) before
drh98d312f2012-10-25 15:23:14 +00005511 ** we do the actual processing of arguments later in a second pass.
5512 */
shanef69573d2009-10-24 02:06:14 +00005513 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00005514 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00005515#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00005516 const char *zSize;
5517 sqlite3_int64 szHeap;
5518
drh98d312f2012-10-25 15:23:14 +00005519 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00005520 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00005521 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00005522 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
drhc530b9c2016-07-25 11:27:22 +00005523#else
5524 (void)cmdline_option_value(argc, argv, ++i);
drh9c88d682010-12-17 14:03:01 +00005525#endif
drh44dec872014-08-30 15:49:25 +00005526 }else if( strcmp(z,"-scratch")==0 ){
5527 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005528 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005529 if( sz>400000 ) sz = 400000;
5530 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00005531 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005532 if( n>10 ) n = 10;
5533 if( n<1 ) n = 1;
5534 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
5535 data.shellFlgs |= SHFLG_Scratch;
5536 }else if( strcmp(z,"-pagecache")==0 ){
5537 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005538 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005539 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00005540 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005541 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00005542 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
5543 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00005544 data.shellFlgs |= SHFLG_Pagecache;
5545 }else if( strcmp(z,"-lookaside")==0 ){
5546 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005547 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005548 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005549 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005550 if( n<0 ) n = 0;
5551 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
5552 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00005553#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00005554 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00005555 extern int vfstrace_register(
5556 const char *zTraceName,
5557 const char *zOldVfsName,
5558 int (*xOut)(const char*,void*),
5559 void *pOutArg,
5560 int makeDefault
5561 );
drh2b625e22011-03-16 17:05:28 +00005562 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00005563#endif
drh6f25e892011-07-08 17:02:57 +00005564#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00005565 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00005566 extern int sqlite3_multiple_initialize(const char*,int);
5567 sqlite3_multiplex_initialize(0, 1);
5568#endif
drh7d9f3942013-04-03 01:26:54 +00005569 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00005570 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
5571 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00005572 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00005573 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00005574 if( pVfs ){
5575 sqlite3_vfs_register(pVfs, 1);
5576 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005577 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00005578 exit(1);
5579 }
drh44c2eb12003-04-30 11:38:26 +00005580 }
5581 }
drh98d312f2012-10-25 15:23:14 +00005582 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00005583#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00005584 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00005585 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00005586#else
mistachkinaae280e2015-12-31 19:06:24 +00005587 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00005588 return 1;
drh01b41712005-08-29 23:06:23 +00005589#endif
drh98d312f2012-10-25 15:23:14 +00005590 }
5591 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00005592
drh44c2eb12003-04-30 11:38:26 +00005593 /* Go ahead and open the database file if it already exists. If the
5594 ** file does not exist, delay opening it. This prevents empty database
5595 ** files from being created if a user mistypes the database name argument
5596 ** to the sqlite command-line tool.
5597 */
drhc8d74412004-08-31 23:41:26 +00005598 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00005599 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00005600 }
5601
drh22fbcb82004-02-01 01:22:50 +00005602 /* Process the initialization file if there is one. If no -init option
5603 ** is given on the command line, look for a file named ~/.sqliterc and
5604 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00005605 */
drh534f4df2015-02-28 14:03:35 +00005606 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00005607
drh22fbcb82004-02-01 01:22:50 +00005608 /* Make a second pass through the command-line argument and set
5609 ** options. This second pass is delayed until after the initialization
5610 ** file is processed so that the command-line arguments will override
5611 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00005612 */
drh98d312f2012-10-25 15:23:14 +00005613 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00005614 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005615 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00005616 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00005617 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00005618 i++;
5619 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005620 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00005621 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005622 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00005623 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005624 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00005625 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00005626 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00005627 }else if( strcmp(z,"-csv")==0 ){
5628 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00005629 memcpy(data.colSeparator,",",2);
5630 }else if( strcmp(z,"-ascii")==0 ){
5631 data.mode = MODE_Ascii;
5632 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005633 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00005634 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005635 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00005636 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00005637 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00005638 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00005639 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00005640 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00005641 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005642 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00005643 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00005644 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005645 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005646 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00005647 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005648 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00005649 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00005650 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00005651 }else if( strcmp(z,"-eqp")==0 ){
5652 data.autoEQP = 1;
drheacd29d2016-04-15 15:03:27 +00005653 }else if( strcmp(z,"-eqpfull")==0 ){
5654 data.autoEQP = 2;
shaneh642d8b82010-07-28 16:05:34 +00005655 }else if( strcmp(z,"-stats")==0 ){
5656 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00005657 }else if( strcmp(z,"-scanstats")==0 ){
5658 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00005659 }else if( strcmp(z,"-backslash")==0 ){
5660 /* Undocumented command-line option: -backslash
5661 ** Causes C-style backslash escapes to be evaluated in SQL statements
5662 ** prior to sending the SQL into SQLite. Useful for injecting
5663 ** crazy bytes in the middle of SQL statements for testing and debugging.
5664 */
5665 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00005666 }else if( strcmp(z,"-bail")==0 ){
5667 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00005668 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00005669 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00005670 return 0;
drhc28490c2006-10-26 14:25:58 +00005671 }else if( strcmp(z,"-interactive")==0 ){
5672 stdin_is_interactive = 1;
5673 }else if( strcmp(z,"-batch")==0 ){
5674 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00005675 }else if( strcmp(z,"-heap")==0 ){
5676 i++;
drh44dec872014-08-30 15:49:25 +00005677 }else if( strcmp(z,"-scratch")==0 ){
5678 i+=2;
5679 }else if( strcmp(z,"-pagecache")==0 ){
5680 i+=2;
5681 }else if( strcmp(z,"-lookaside")==0 ){
5682 i+=2;
drh7d9f3942013-04-03 01:26:54 +00005683 }else if( strcmp(z,"-mmap")==0 ){
5684 i++;
drha7e61d82011-03-12 17:02:57 +00005685 }else if( strcmp(z,"-vfs")==0 ){
5686 i++;
drh6f25e892011-07-08 17:02:57 +00005687#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00005688 }else if( strcmp(z,"-vfstrace")==0 ){
5689 i++;
drh6f25e892011-07-08 17:02:57 +00005690#endif
5691#ifdef SQLITE_ENABLE_MULTIPLEX
5692 }else if( strcmp(z,"-multiplex")==0 ){
5693 i++;
5694#endif
drhcc3b4f82012-02-07 14:13:50 +00005695 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00005696 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00005697 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00005698 /* Run commands that follow -cmd first and separately from commands
5699 ** that simply appear on the command-line. This seems goofy. It would
5700 ** be better if all commands ran in the order that they appear. But
5701 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00005702 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00005703 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00005704 if( z[0]=='.' ){
5705 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00005706 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00005707 }else{
drh05782482013-10-24 15:20:20 +00005708 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00005709 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
5710 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005711 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00005712 if( bail_on_error ) return rc!=0 ? rc : 1;
5713 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005714 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00005715 if( bail_on_error ) return rc;
5716 }
5717 }
drh1e5d0e92000-05-31 23:33:17 +00005718 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005719 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
5720 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00005721 return 1;
5722 }
drh700c2522016-02-09 18:39:25 +00005723 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00005724 }
drh44c2eb12003-04-30 11:38:26 +00005725
drhac5649a2014-11-28 13:35:03 +00005726 if( !readStdin ){
5727 /* Run all arguments that do not begin with '-' as if they were separate
5728 ** command-line inputs, except for the argToSkip argument which contains
5729 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00005730 */
drhac5649a2014-11-28 13:35:03 +00005731 for(i=0; i<nCmd; i++){
5732 if( azCmd[i][0]=='.' ){
5733 rc = do_meta_command(azCmd[i], &data);
5734 if( rc ) return rc==2 ? 0 : rc;
5735 }else{
5736 open_db(&data, 0);
5737 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
5738 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005739 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00005740 return rc!=0 ? rc : 1;
5741 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005742 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00005743 return rc;
5744 }
drh6ff13852001-11-25 13:18:23 +00005745 }
drh75897232000-05-29 14:26:00 +00005746 }
drhac5649a2014-11-28 13:35:03 +00005747 free(azCmd);
drh75897232000-05-29 14:26:00 +00005748 }else{
drh44c2eb12003-04-30 11:38:26 +00005749 /* Run commands received from standard input
5750 */
drhc28490c2006-10-26 14:25:58 +00005751 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00005752 char *zHome;
5753 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00005754 int nHistory;
drh75897232000-05-29 14:26:00 +00005755 printf(
drh743e0032011-12-12 16:51:50 +00005756 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00005757 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00005758 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00005759 );
drhb3735912014-02-10 16:13:42 +00005760 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00005761 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00005762 printBold("transient in-memory database");
5763 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00005764 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00005765 }
drh67505e72002-04-19 12:34:06 +00005766 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00005767 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00005768 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00005769 if( (zHistory = malloc(nHistory))!=0 ){
5770 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
5771 }
drh67505e72002-04-19 12:34:06 +00005772 }
drhf5ed7ad2015-06-15 14:43:25 +00005773 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00005774 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00005775 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00005776 shell_stifle_history(100);
5777 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00005778 free(zHistory);
drh67505e72002-04-19 12:34:06 +00005779 }
drhdaffd0e2001-04-11 14:28:42 +00005780 }else{
drhc28490c2006-10-26 14:25:58 +00005781 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00005782 }
5783 }
drh33048c02001-10-01 14:29:22 +00005784 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00005785 if( data.db ){
drhe6229612014-08-18 15:08:26 +00005786 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00005787 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00005788 }
mistachkin1fe36bb2016-04-04 02:16:44 +00005789 sqlite3_free(data.zFreeOnClose);
5790#if !SQLITE_SHELL_IS_UTF8
5791 for(i=0; i<argc; i++) sqlite3_free(argv[i]);
5792 sqlite3_free(argv);
5793#endif
drhc28490c2006-10-26 14:25:58 +00005794 return rc;
drh75897232000-05-29 14:26:00 +00005795}