blob: 21cba66b1c29a8d1c4ac8c66e617bd17dd77f99d [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 */
drh44dec872014-08-30 15:49:25 +0000629 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000630 char *zDestTable; /* Name of destination table when MODE_Insert */
mistachkin636bf9f2014-07-19 20:15:16 +0000631 char colSeparator[20]; /* Column separator character for several modes */
632 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000633 int colWidth[100]; /* Requested width of each column when in column mode*/
634 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000635 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000636 ** the database */
drh44c2eb12003-04-30 11:38:26 +0000637 char outfile[FILENAME_MAX]; /* Filename for *out */
638 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000639 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000640 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000641 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000642 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000643 int *aiIndent; /* Array of indents used in MODE_Explain */
644 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000645 int iIndent; /* Index of current op in aiIndent[] */
drhe6229612014-08-18 15:08:26 +0000646#if defined(SQLITE_ENABLE_SESSION)
647 int nSession; /* Number of active sessions */
648 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
649#endif
drh75897232000-05-29 14:26:00 +0000650};
651
652/*
drh44dec872014-08-30 15:49:25 +0000653** These are the allowed shellFlgs values
654*/
655#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
656#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
657#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
658
659/*
drh75897232000-05-29 14:26:00 +0000660** These are the allowed modes.
661*/
drh967e8b72000-06-21 13:59:10 +0000662#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000663#define MODE_Column 1 /* One record per line in neat columns */
664#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000665#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
666#define MODE_Html 4 /* Generate an XHTML table */
667#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000668#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000669#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000670#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000671#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
drh4926fec2016-04-13 15:33:42 +0000672#define MODE_Pretty 10 /* Pretty-print schemas */
persicom7e2dfdd2002-04-18 02:46:52 +0000673
drh66ce4d02008-02-15 17:38:06 +0000674static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000675 "line",
676 "column",
677 "list",
678 "semi",
679 "html",
drhfeac5f82004-08-01 00:10:45 +0000680 "insert",
681 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000682 "csv",
drh66ce4d02008-02-15 17:38:06 +0000683 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000684 "ascii",
drh4926fec2016-04-13 15:33:42 +0000685 "prettyprint",
persicom7e2dfdd2002-04-18 02:46:52 +0000686};
drh75897232000-05-29 14:26:00 +0000687
688/*
mistachkinfad42082014-07-24 22:13:12 +0000689** These are the column/row/line separators used by the various
690** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000691*/
mistachkinfad42082014-07-24 22:13:12 +0000692#define SEP_Column "|"
693#define SEP_Row "\n"
694#define SEP_Tab "\t"
695#define SEP_Space " "
696#define SEP_Comma ","
697#define SEP_CrLf "\r\n"
698#define SEP_Unit "\x1F"
699#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000700
701/*
drh75897232000-05-29 14:26:00 +0000702** Number of elements in an array
703*/
drh902b9ee2008-12-05 17:17:07 +0000704#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000705
706/*
drh127f9d72010-02-23 01:47:00 +0000707** A callback for the sqlite3_log() interface.
708*/
709static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000710 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000711 if( p->pLog==0 ) return;
mistachkinaae280e2015-12-31 19:06:24 +0000712 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
drh127f9d72010-02-23 01:47:00 +0000713 fflush(p->pLog);
714}
715
716/*
shane626a6e42009-10-22 17:30:15 +0000717** Output the given string as a hex-encoded blob (eg. X'1234' )
718*/
719static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
720 int i;
721 char *zBlob = (char *)pBlob;
mistachkinaae280e2015-12-31 19:06:24 +0000722 raw_printf(out,"X'");
723 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
724 raw_printf(out,"'");
shane626a6e42009-10-22 17:30:15 +0000725}
726
727/*
drh28bd4bc2000-06-15 15:57:22 +0000728** Output the given string as a quoted string using SQL quoting conventions.
729*/
730static void output_quoted_string(FILE *out, const char *z){
731 int i;
732 int nSingle = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +0000733 setBinaryMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000734 for(i=0; z[i]; i++){
735 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000736 }
737 if( nSingle==0 ){
drhe05461c2015-12-30 13:36:57 +0000738 utf8_printf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000739 }else{
mistachkinaae280e2015-12-31 19:06:24 +0000740 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000741 while( *z ){
742 for(i=0; z[i] && z[i]!='\''; i++){}
743 if( i==0 ){
mistachkinaae280e2015-12-31 19:06:24 +0000744 raw_printf(out,"''");
drh28bd4bc2000-06-15 15:57:22 +0000745 z++;
746 }else if( z[i]=='\'' ){
drhe05461c2015-12-30 13:36:57 +0000747 utf8_printf(out,"%.*s''",i,z);
drh28bd4bc2000-06-15 15:57:22 +0000748 z += i+1;
749 }else{
drhe05461c2015-12-30 13:36:57 +0000750 utf8_printf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000751 break;
752 }
753 }
mistachkinaae280e2015-12-31 19:06:24 +0000754 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000755 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000756 setTextMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000757}
758
759/*
drhfeac5f82004-08-01 00:10:45 +0000760** Output the given string as a quoted according to C or TCL quoting rules.
761*/
762static void output_c_string(FILE *out, const char *z){
763 unsigned int c;
764 fputc('"', out);
765 while( (c = *(z++))!=0 ){
766 if( c=='\\' ){
767 fputc(c, out);
768 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000769 }else if( c=='"' ){
770 fputc('\\', out);
771 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000772 }else if( c=='\t' ){
773 fputc('\\', out);
774 fputc('t', out);
775 }else if( c=='\n' ){
776 fputc('\\', out);
777 fputc('n', out);
778 }else if( c=='\r' ){
779 fputc('\\', out);
780 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000781 }else if( !isprint(c&0xff) ){
mistachkinaae280e2015-12-31 19:06:24 +0000782 raw_printf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000783 }else{
784 fputc(c, out);
785 }
786 }
787 fputc('"', out);
788}
789
790/*
drhc08a4f12000-06-15 16:49:48 +0000791** Output the given string with characters that are special to
792** HTML escaped.
793*/
794static void output_html_string(FILE *out, const char *z){
795 int i;
drhc3d6ba42014-01-13 20:38:35 +0000796 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000797 while( *z ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000798 for(i=0; z[i]
799 && z[i]!='<'
800 && z[i]!='&'
801 && z[i]!='>'
802 && z[i]!='\"'
shane43d9cb22009-10-21 14:11:48 +0000803 && z[i]!='\'';
804 i++){}
drhc08a4f12000-06-15 16:49:48 +0000805 if( i>0 ){
drhe05461c2015-12-30 13:36:57 +0000806 utf8_printf(out,"%.*s",i,z);
drhc08a4f12000-06-15 16:49:48 +0000807 }
808 if( z[i]=='<' ){
mistachkinaae280e2015-12-31 19:06:24 +0000809 raw_printf(out,"&lt;");
drhc08a4f12000-06-15 16:49:48 +0000810 }else if( z[i]=='&' ){
mistachkinaae280e2015-12-31 19:06:24 +0000811 raw_printf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000812 }else if( z[i]=='>' ){
mistachkinaae280e2015-12-31 19:06:24 +0000813 raw_printf(out,"&gt;");
shane43d9cb22009-10-21 14:11:48 +0000814 }else if( z[i]=='\"' ){
mistachkinaae280e2015-12-31 19:06:24 +0000815 raw_printf(out,"&quot;");
shane43d9cb22009-10-21 14:11:48 +0000816 }else if( z[i]=='\'' ){
mistachkinaae280e2015-12-31 19:06:24 +0000817 raw_printf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000818 }else{
819 break;
820 }
821 z += i + 1;
822 }
823}
824
825/*
drhc49f44e2006-10-26 18:15:42 +0000826** If a field contains any character identified by a 1 in the following
827** array, then the string must be quoted for CSV.
828*/
829static const char needCsvQuote[] = {
mistachkin1fe36bb2016-04-04 02:16:44 +0000830 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
831 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
832 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
833 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
834 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
836 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
838 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
839 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
840 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
841 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
842 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
843 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
844 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
845 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
drhc49f44e2006-10-26 18:15:42 +0000846};
847
848/*
mistachkindd11f2d2014-12-11 04:49:46 +0000849** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000850** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000851** the null value. Strings are quoted if necessary. The separator
852** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000853*/
drhdcd87a92014-08-18 13:45:42 +0000854static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000855 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000856 if( z==0 ){
drhe05461c2015-12-30 13:36:57 +0000857 utf8_printf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000858 }else{
drhc49f44e2006-10-26 18:15:42 +0000859 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000860 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000861 for(i=0; z[i]; i++){
mistachkin1fe36bb2016-04-04 02:16:44 +0000862 if( needCsvQuote[((unsigned char*)z)[i]]
863 || (z[i]==p->colSeparator[0] &&
mistachkin636bf9f2014-07-19 20:15:16 +0000864 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000865 i = 0;
866 break;
867 }
868 }
869 if( i==0 ){
870 putc('"', out);
871 for(i=0; z[i]; i++){
872 if( z[i]=='"' ) putc('"', out);
873 putc(z[i], out);
874 }
875 putc('"', out);
876 }else{
drhe05461c2015-12-30 13:36:57 +0000877 utf8_printf(out, "%s", z);
drhc49f44e2006-10-26 18:15:42 +0000878 }
drh8e64d1c2004-10-07 00:32:39 +0000879 }
880 if( bSep ){
drhe05461c2015-12-30 13:36:57 +0000881 utf8_printf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000882 }
883}
884
danielk19774af00c62005-01-23 23:43:21 +0000885#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000886/*
drh4c504392000-10-16 22:06:40 +0000887** This routine runs when the user presses Ctrl-C
888*/
889static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000890 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000891 seenInterrupt++;
892 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000893 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000894}
danielk19774af00c62005-01-23 23:43:21 +0000895#endif
drh4c504392000-10-16 22:06:40 +0000896
897/*
drhde613c62016-04-04 17:23:10 +0000898** When the ".auth ON" is set, the following authorizer callback is
899** invoked. It always returns SQLITE_OK.
900*/
901static int shellAuth(
902 void *pClientData,
903 int op,
904 const char *zA1,
905 const char *zA2,
906 const char *zA3,
907 const char *zA4
908){
909 ShellState *p = (ShellState*)pClientData;
910 static const char *azAction[] = { 0,
911 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
912 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
913 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
914 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
915 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
916 "DROP_TRIGGER", "DROP_VIEW", "INSERT",
917 "PRAGMA", "READ", "SELECT",
918 "TRANSACTION", "UPDATE", "ATTACH",
919 "DETACH", "ALTER_TABLE", "REINDEX",
920 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
921 "FUNCTION", "SAVEPOINT", "RECURSIVE"
922 };
923 int i;
924 const char *az[4];
925 az[0] = zA1;
926 az[1] = zA2;
927 az[2] = zA3;
928 az[3] = zA4;
929 raw_printf(p->out, "authorizer: %s", azAction[op]);
930 for(i=0; i<4; i++){
931 raw_printf(p->out, " ");
932 if( az[i] ){
933 output_c_string(p->out, az[i]);
934 }else{
935 raw_printf(p->out, "NULL");
936 }
937 }
938 raw_printf(p->out, "\n");
939 return SQLITE_OK;
940}
941
942
943/*
shane626a6e42009-10-22 17:30:15 +0000944** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000945** invokes for each row of a query result.
946*/
drh4ace5362014-11-10 14:42:28 +0000947static int shell_callback(
948 void *pArg,
949 int nArg, /* Number of result columns */
950 char **azArg, /* Text of each result column */
951 char **azCol, /* Column names */
952 int *aiType /* Column types */
953){
drh75897232000-05-29 14:26:00 +0000954 int i;
drhdcd87a92014-08-18 13:45:42 +0000955 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000956
drh700c2522016-02-09 18:39:25 +0000957 switch( p->cMode ){
drh75897232000-05-29 14:26:00 +0000958 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000959 int w = 5;
drh6a535342001-10-19 16:44:56 +0000960 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000961 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000962 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000963 if( len>w ) w = len;
964 }
drhe05461c2015-12-30 13:36:57 +0000965 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000966 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000967 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000968 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000969 }
970 break;
971 }
danielk19770d78bae2008-01-03 07:09:48 +0000972 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000973 case MODE_Column: {
drh700c2522016-02-09 18:39:25 +0000974 static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
975 const int *colWidth;
976 int showHdr;
977 char *rowSep;
978 if( p->cMode==MODE_Column ){
979 colWidth = p->colWidth;
980 showHdr = p->showHeader;
981 rowSep = p->rowSeparator;
982 }else{
983 colWidth = aExplainWidths;
984 showHdr = 1;
mistachkin6d945552016-02-09 20:31:50 +0000985 rowSep = SEP_Row;
drh700c2522016-02-09 18:39:25 +0000986 }
drha0c66f52000-07-29 13:20:21 +0000987 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000988 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000989 int w, n;
990 if( i<ArraySize(p->colWidth) ){
drh700c2522016-02-09 18:39:25 +0000991 w = colWidth[i];
drh75897232000-05-29 14:26:00 +0000992 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000993 w = 0;
drh75897232000-05-29 14:26:00 +0000994 }
drh078b1fd2012-09-21 13:40:02 +0000995 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +0000996 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +0000997 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +0000998 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +0000999 if( w<n ) w = n;
1000 }
1001 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001002 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001003 }
drh700c2522016-02-09 18:39:25 +00001004 if( showHdr ){
drh078b1fd2012-09-21 13:40:02 +00001005 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001006 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001007 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001008 }else{
drhe05461c2015-12-30 13:36:57 +00001009 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001010 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001011 }
drha0c66f52000-07-29 13:20:21 +00001012 }
1013 }
drh700c2522016-02-09 18:39:25 +00001014 if( showHdr ){
drha0c66f52000-07-29 13:20:21 +00001015 for(i=0; i<nArg; i++){
1016 int w;
1017 if( i<ArraySize(p->actualWidth) ){
1018 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +00001019 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +00001020 }else{
1021 w = 10;
1022 }
mistachkinaae280e2015-12-31 19:06:24 +00001023 utf8_printf(p->out,"%-*.*s%s",w,w,
drhe05461c2015-12-30 13:36:57 +00001024 "----------------------------------------------------------"
drha0c66f52000-07-29 13:20:21 +00001025 "----------------------------------------------------------",
drh700c2522016-02-09 18:39:25 +00001026 i==nArg-1 ? rowSep : " ");
drha0c66f52000-07-29 13:20:21 +00001027 }
drh75897232000-05-29 14:26:00 +00001028 }
1029 }
drh6a535342001-10-19 16:44:56 +00001030 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001031 for(i=0; i<nArg; i++){
1032 int w;
drha0c66f52000-07-29 13:20:21 +00001033 if( i<ArraySize(p->actualWidth) ){
1034 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001035 }else{
1036 w = 10;
1037 }
drh700c2522016-02-09 18:39:25 +00001038 if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +00001039 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001040 }
dana98bf362013-11-13 18:35:01 +00001041 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +00001042 if( p->iIndent<p->nIndent ){
mistachkinaae280e2015-12-31 19:06:24 +00001043 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +00001044 }
danc4650bb2013-11-18 08:41:06 +00001045 p->iIndent++;
dana98bf362013-11-13 18:35:01 +00001046 }
drh078b1fd2012-09-21 13:40:02 +00001047 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001048 utf8_printf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +00001049 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001050 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001051 }else{
drhe05461c2015-12-30 13:36:57 +00001052 utf8_printf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +00001053 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001054 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001055 }
drh75897232000-05-29 14:26:00 +00001056 }
1057 break;
1058 }
drh4926fec2016-04-13 15:33:42 +00001059 case MODE_Semi: { /* .schema and .fullschema output */
1060 utf8_printf(p->out, "%s;\n", azArg[0]);
1061 break;
1062 }
1063 case MODE_Pretty: { /* .schema and .fullschema with --indent */
1064 char *z;
drh07d683f2016-04-13 21:00:36 +00001065 int j;
drh4926fec2016-04-13 15:33:42 +00001066 int nParen = 0;
1067 char cEnd = 0;
1068 char c;
1069 int nLine = 0;
1070 assert( nArg==1 );
1071 if( azArg[0]==0 ) break;
1072 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
1073 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
1074 ){
1075 utf8_printf(p->out, "%s;\n", azArg[0]);
1076 break;
1077 }
1078 z = sqlite3_mprintf("%s", azArg[0]);
1079 j = 0;
1080 for(i=0; IsSpace(z[i]); i++){}
1081 for(; (c = z[i])!=0; i++){
1082 if( IsSpace(c) ){
1083 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
1084 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
1085 j--;
1086 }
1087 z[j++] = c;
1088 }
1089 while( j>0 && IsSpace(z[j-1]) ){ j--; }
1090 z[j] = 0;
1091 if( strlen30(z)>=79 ){
drh07d683f2016-04-13 21:00:36 +00001092 for(i=j=0; (c = z[i])!=0; i++){
drh4926fec2016-04-13 15:33:42 +00001093 if( c==cEnd ){
1094 cEnd = 0;
1095 }else if( c=='"' || c=='\'' || c=='`' ){
1096 cEnd = c;
1097 }else if( c=='[' ){
1098 cEnd = ']';
1099 }else if( c=='(' ){
1100 nParen++;
1101 }else if( c==')' ){
1102 nParen--;
1103 if( nLine>0 && nParen==0 && j>0 ){
1104 utf8_printf(p->out, "%.*s\n", j, z);
1105 j = 0;
1106 }
1107 }
1108 z[j++] = c;
1109 if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
1110 if( c=='\n' ) j--;
1111 utf8_printf(p->out, "%.*s\n ", j, z);
1112 j = 0;
1113 nLine++;
1114 while( IsSpace(z[i+1]) ){ i++; }
1115 }
1116 }
1117 z[j] = 0;
1118 }
1119 utf8_printf(p->out, "%s;\n", z);
1120 sqlite3_free(z);
1121 break;
1122 }
drh75897232000-05-29 14:26:00 +00001123 case MODE_List: {
1124 if( p->cnt++==0 && p->showHeader ){
1125 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001126 utf8_printf(p->out,"%s%s",azCol[i],
mistachkin636bf9f2014-07-19 20:15:16 +00001127 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +00001128 }
1129 }
drh6a535342001-10-19 16:44:56 +00001130 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001131 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001132 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +00001133 if( z==0 ) z = p->nullValue;
drhe05461c2015-12-30 13:36:57 +00001134 utf8_printf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001135 if( i<nArg-1 ){
drhe05461c2015-12-30 13:36:57 +00001136 utf8_printf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +00001137 }else{
drhe05461c2015-12-30 13:36:57 +00001138 utf8_printf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001139 }
drh75897232000-05-29 14:26:00 +00001140 }
1141 break;
1142 }
drh1e5d0e92000-05-31 23:33:17 +00001143 case MODE_Html: {
1144 if( p->cnt++==0 && p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001145 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001146 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001147 raw_printf(p->out,"<TH>");
shane43d9cb22009-10-21 14:11:48 +00001148 output_html_string(p->out, azCol[i]);
mistachkinaae280e2015-12-31 19:06:24 +00001149 raw_printf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001150 }
mistachkinaae280e2015-12-31 19:06:24 +00001151 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001152 }
drh6a535342001-10-19 16:44:56 +00001153 if( azArg==0 ) break;
mistachkinaae280e2015-12-31 19:06:24 +00001154 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001155 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001156 raw_printf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +00001157 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00001158 raw_printf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001159 }
mistachkinaae280e2015-12-31 19:06:24 +00001160 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001161 break;
1162 }
drhfeac5f82004-08-01 00:10:45 +00001163 case MODE_Tcl: {
1164 if( p->cnt++==0 && p->showHeader ){
1165 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001166 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhe05461c2015-12-30 13:36:57 +00001167 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001168 }
drhe05461c2015-12-30 13:36:57 +00001169 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001170 }
1171 if( azArg==0 ) break;
1172 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +00001173 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
drhe05461c2015-12-30 13:36:57 +00001174 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001175 }
drhe05461c2015-12-30 13:36:57 +00001176 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001177 break;
1178 }
drh8e64d1c2004-10-07 00:32:39 +00001179 case MODE_Csv: {
mistachkin1fe36bb2016-04-04 02:16:44 +00001180 setBinaryMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001181 if( p->cnt++==0 && p->showHeader ){
1182 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001183 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001184 }
drhe05461c2015-12-30 13:36:57 +00001185 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001186 }
drh40253262014-10-17 21:35:05 +00001187 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +00001188 for(i=0; i<nArg; i++){
1189 output_csv(p, azArg[i], i<nArg-1);
1190 }
drhe05461c2015-12-30 13:36:57 +00001191 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001192 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001193 setTextMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001194 break;
1195 }
drh28bd4bc2000-06-15 15:57:22 +00001196 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001197 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001198 if( azArg==0 ) break;
drhe05461c2015-12-30 13:36:57 +00001199 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
mistachkin151c75a2015-04-07 21:16:40 +00001200 if( p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001201 raw_printf(p->out,"(");
mistachkin151c75a2015-04-07 21:16:40 +00001202 for(i=0; i<nArg; i++){
1203 char *zSep = i>0 ? ",": "";
drhe05461c2015-12-30 13:36:57 +00001204 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
mistachkin151c75a2015-04-07 21:16:40 +00001205 }
mistachkinaae280e2015-12-31 19:06:24 +00001206 raw_printf(p->out,")");
mistachkin151c75a2015-04-07 21:16:40 +00001207 }
mistachkinaae280e2015-12-31 19:06:24 +00001208 raw_printf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001209 for(i=0; i<nArg; i++){
1210 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001211 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
mistachkinaae280e2015-12-31 19:06:24 +00001212 utf8_printf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001213 }else if( aiType && aiType[i]==SQLITE_TEXT ){
mistachkinaae280e2015-12-31 19:06:24 +00001214 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shanead6b8d02009-10-22 18:12:58 +00001215 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001216 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1217 || aiType[i]==SQLITE_FLOAT) ){
drhe05461c2015-12-30 13:36:57 +00001218 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001219 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1220 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1221 int nBlob = sqlite3_column_bytes(p->pStmt, i);
mistachkinaae280e2015-12-31 19:06:24 +00001222 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shane626a6e42009-10-22 17:30:15 +00001223 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001224 }else if( isNumber(azArg[i], 0) ){
drhe05461c2015-12-30 13:36:57 +00001225 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
drh28bd4bc2000-06-15 15:57:22 +00001226 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001227 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
drh28bd4bc2000-06-15 15:57:22 +00001228 output_quoted_string(p->out, azArg[i]);
1229 }
1230 }
mistachkinaae280e2015-12-31 19:06:24 +00001231 raw_printf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001232 break;
drh28bd4bc2000-06-15 15:57:22 +00001233 }
mistachkin636bf9f2014-07-19 20:15:16 +00001234 case MODE_Ascii: {
1235 if( p->cnt++==0 && p->showHeader ){
1236 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001237 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1238 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +00001239 }
drhe05461c2015-12-30 13:36:57 +00001240 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001241 }
1242 if( azArg==0 ) break;
1243 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001244 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1245 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001246 }
drhe05461c2015-12-30 13:36:57 +00001247 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001248 break;
1249 }
persicom1d0b8722002-04-18 02:53:04 +00001250 }
drh75897232000-05-29 14:26:00 +00001251 return 0;
1252}
1253
1254/*
shane626a6e42009-10-22 17:30:15 +00001255** This is the callback routine that the SQLite library
1256** invokes for each row of a query result.
1257*/
1258static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1259 /* since we don't have type info, call the shell_callback with a NULL value */
1260 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1261}
1262
1263/*
drhdcd87a92014-08-18 13:45:42 +00001264** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001265** the name of the table given. Escape any quote characters in the
1266** table name.
1267*/
drhdcd87a92014-08-18 13:45:42 +00001268static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001269 int i, n;
1270 int needQuote;
1271 char *z;
1272
1273 if( p->zDestTable ){
1274 free(p->zDestTable);
1275 p->zDestTable = 0;
1276 }
1277 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001278 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001279 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001280 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001281 needQuote = 1;
1282 if( zName[i]=='\'' ) n++;
1283 }
1284 }
1285 if( needQuote ) n += 2;
1286 z = p->zDestTable = malloc( n+1 );
1287 if( z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001288 raw_printf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001289 exit(1);
1290 }
1291 n = 0;
1292 if( needQuote ) z[n++] = '\'';
1293 for(i=0; zName[i]; i++){
1294 z[n++] = zName[i];
1295 if( zName[i]=='\'' ) z[n++] = '\'';
1296 }
1297 if( needQuote ) z[n++] = '\'';
1298 z[n] = 0;
1299}
1300
danielk19772a02e332004-06-05 08:04:36 +00001301/* zIn is either a pointer to a NULL-terminated string in memory obtained
1302** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1303** added to zIn, and the result returned in memory obtained from malloc().
1304** zIn, if it was not NULL, is freed.
1305**
mistachkin1fe36bb2016-04-04 02:16:44 +00001306** If the third argument, quote, is not '\0', then it is used as a
danielk19772a02e332004-06-05 08:04:36 +00001307** quote character for zAppend.
1308*/
drhc28490c2006-10-26 14:25:58 +00001309static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001310 int len;
1311 int i;
drh4f21c4a2008-12-10 22:15:00 +00001312 int nAppend = strlen30(zAppend);
1313 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001314
1315 len = nAppend+nIn+1;
1316 if( quote ){
1317 len += 2;
1318 for(i=0; i<nAppend; i++){
1319 if( zAppend[i]==quote ) len++;
1320 }
1321 }
1322
1323 zIn = (char *)realloc(zIn, len);
1324 if( !zIn ){
1325 return 0;
1326 }
1327
1328 if( quote ){
1329 char *zCsr = &zIn[nIn];
1330 *zCsr++ = quote;
1331 for(i=0; i<nAppend; i++){
1332 *zCsr++ = zAppend[i];
1333 if( zAppend[i]==quote ) *zCsr++ = quote;
1334 }
1335 *zCsr++ = quote;
1336 *zCsr++ = '\0';
1337 assert( (zCsr-zIn)==len );
1338 }else{
1339 memcpy(&zIn[nIn], zAppend, nAppend);
1340 zIn[len-1] = '\0';
1341 }
1342
1343 return zIn;
1344}
1345
drhdd3d4592004-08-30 01:54:05 +00001346
1347/*
drhb21a8e42012-01-28 21:08:51 +00001348** Execute a query statement that will generate SQL output. Print
1349** the result columns, comma-separated, on a line and then add a
1350** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001351**
drhb21a8e42012-01-28 21:08:51 +00001352** If the number of columns is 1 and that column contains text "--"
mistachkin1fe36bb2016-04-04 02:16:44 +00001353** then write the semicolon on a separate line. That way, if a
drhb21a8e42012-01-28 21:08:51 +00001354** "--" comment occurs at the end of the statement, the comment
1355** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001356*/
drh157e29a2009-05-21 15:15:00 +00001357static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001358 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001359 const char *zSelect, /* SELECT statement to extract content */
1360 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001361){
drhdd3d4592004-08-30 01:54:05 +00001362 sqlite3_stmt *pSelect;
1363 int rc;
drhb21a8e42012-01-28 21:08:51 +00001364 int nResult;
1365 int i;
1366 const char *z;
drhc7181902014-02-27 15:04:13 +00001367 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001368 if( rc!=SQLITE_OK || !pSelect ){
mistachkinaae280e2015-12-31 19:06:24 +00001369 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1370 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001371 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001372 return rc;
1373 }
1374 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001375 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001376 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001377 if( zFirstRow ){
drhe05461c2015-12-30 13:36:57 +00001378 utf8_printf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001379 zFirstRow = 0;
1380 }
drhb21a8e42012-01-28 21:08:51 +00001381 z = (const char*)sqlite3_column_text(pSelect, 0);
drhe05461c2015-12-30 13:36:57 +00001382 utf8_printf(p->out, "%s", z);
mistachkin1fe36bb2016-04-04 02:16:44 +00001383 for(i=1; i<nResult; i++){
drhe05461c2015-12-30 13:36:57 +00001384 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
drhb21a8e42012-01-28 21:08:51 +00001385 }
1386 if( z==0 ) z = "";
1387 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1388 if( z[0] ){
mistachkinaae280e2015-12-31 19:06:24 +00001389 raw_printf(p->out, "\n;\n");
drhb21a8e42012-01-28 21:08:51 +00001390 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001391 raw_printf(p->out, ";\n");
mistachkin1fe36bb2016-04-04 02:16:44 +00001392 }
drhdd3d4592004-08-30 01:54:05 +00001393 rc = sqlite3_step(pSelect);
1394 }
drh2f464a02011-10-13 00:41:49 +00001395 rc = sqlite3_finalize(pSelect);
1396 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00001397 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1398 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001399 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001400 }
1401 return rc;
drhdd3d4592004-08-30 01:54:05 +00001402}
1403
shane626a6e42009-10-22 17:30:15 +00001404/*
1405** Allocate space and save off current error string.
1406*/
1407static char *save_err_msg(
1408 sqlite3 *db /* Database to query */
1409){
1410 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001411 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001412 if( zErrMsg ){
1413 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1414 }
1415 return zErrMsg;
1416}
1417
drh34784902016-02-27 17:12:36 +00001418#ifdef __linux__
1419/*
1420** Attempt to display I/O stats on Linux using /proc/PID/io
1421*/
1422static void displayLinuxIoStats(FILE *out){
1423 FILE *in;
1424 char z[200];
1425 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
1426 in = fopen(z, "rb");
1427 if( in==0 ) return;
1428 while( fgets(z, sizeof(z), in)!=0 ){
1429 static const struct {
1430 const char *zPattern;
1431 const char *zDesc;
1432 } aTrans[] = {
drhfc1a84c2016-02-27 19:19:22 +00001433 { "rchar: ", "Bytes received by read():" },
1434 { "wchar: ", "Bytes sent to write():" },
1435 { "syscr: ", "Read() system calls:" },
1436 { "syscw: ", "Write() system calls:" },
1437 { "read_bytes: ", "Bytes read from storage:" },
1438 { "write_bytes: ", "Bytes written to storage:" },
1439 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
drh34784902016-02-27 17:12:36 +00001440 };
1441 int i;
1442 for(i=0; i<ArraySize(aTrans); i++){
1443 int n = (int)strlen(aTrans[i].zPattern);
1444 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
1445 raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
1446 break;
1447 }
1448 }
1449 }
1450 fclose(in);
mistachkin1fe36bb2016-04-04 02:16:44 +00001451}
drh34784902016-02-27 17:12:36 +00001452#endif
1453
1454
shane626a6e42009-10-22 17:30:15 +00001455/*
shaneh642d8b82010-07-28 16:05:34 +00001456** Display memory stats.
1457*/
1458static int display_stats(
1459 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001460 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001461 int bReset /* True to reset the stats */
1462){
1463 int iCur;
1464 int iHiwtr;
1465
1466 if( pArg && pArg->out ){
mistachkin1fe36bb2016-04-04 02:16:44 +00001467
shaneh642d8b82010-07-28 16:05:34 +00001468 iHiwtr = iCur = -1;
1469 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001470 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001471 "Memory Used: %d (max %d) bytes\n",
1472 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001473 iHiwtr = iCur = -1;
1474 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001475 raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001476 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001477 if( pArg->shellFlgs & SHFLG_Pagecache ){
1478 iHiwtr = iCur = -1;
1479 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001480 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001481 "Number of Pcache Pages Used: %d (max %d) pages\n",
1482 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001483 }
shaneh642d8b82010-07-28 16:05:34 +00001484 iHiwtr = iCur = -1;
1485 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001486 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001487 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1488 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001489 if( pArg->shellFlgs & SHFLG_Scratch ){
1490 iHiwtr = iCur = -1;
1491 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001492 raw_printf(pArg->out,
1493 "Number of Scratch Allocations Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001494 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001495 }
shaneh642d8b82010-07-28 16:05:34 +00001496 iHiwtr = iCur = -1;
1497 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001498 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001499 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1500 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001501 iHiwtr = iCur = -1;
1502 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001503 raw_printf(pArg->out, "Largest Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001504 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001505 iHiwtr = iCur = -1;
1506 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001507 raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001508 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001509 iHiwtr = iCur = -1;
1510 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001511 raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001512 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001513#ifdef YYTRACKMAXSTACKDEPTH
1514 iHiwtr = iCur = -1;
1515 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001516 raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001517 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001518#endif
1519 }
1520
1521 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001522 if( pArg->shellFlgs & SHFLG_Lookaside ){
1523 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001524 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1525 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001526 raw_printf(pArg->out,
1527 "Lookaside Slots Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001528 iCur, iHiwtr);
1529 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1530 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001531 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
1532 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001533 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1534 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001535 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
1536 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001537 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1538 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001539 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
1540 iHiwtr);
drh44dec872014-08-30 15:49:25 +00001541 }
shaneh642d8b82010-07-28 16:05:34 +00001542 iHiwtr = iCur = -1;
1543 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001544 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
1545 iCur);
drh4ace5362014-11-10 14:42:28 +00001546 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001547 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001548 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
drhc78e6e42011-09-23 18:58:23 +00001549 iHiwtr = iCur = -1;
1550 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001551 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001552 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001553 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001554 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
drhfbbcd5d2012-03-24 20:09:33 +00001555 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001556 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001557 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001558 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001559 iHiwtr = iCur = -1;
1560 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001561 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001562 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001563 }
1564
1565 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001566 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1567 bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001568 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001569 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001570 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001571 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001572 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001573 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001574 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001575 }
1576
drh34784902016-02-27 17:12:36 +00001577#ifdef __linux__
1578 displayLinuxIoStats(pArg->out);
1579#endif
1580
dan5a790282015-08-07 20:06:14 +00001581 /* Do not remove this machine readable comment: extra-stats-output-here */
1582
shaneh642d8b82010-07-28 16:05:34 +00001583 return 0;
1584}
1585
1586/*
dan8d1edb92014-11-05 09:07:28 +00001587** Display scan stats.
1588*/
1589static void display_scanstats(
1590 sqlite3 *db, /* Database to query */
1591 ShellState *pArg /* Pointer to ShellState */
1592){
drhf5ed7ad2015-06-15 14:43:25 +00001593#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1594 UNUSED_PARAMETER(db);
1595 UNUSED_PARAMETER(pArg);
1596#else
drh15f23c22014-11-06 12:46:16 +00001597 int i, k, n, mx;
mistachkinaae280e2015-12-31 19:06:24 +00001598 raw_printf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001599 mx = 0;
1600 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001601 double rEstLoop = 1.0;
1602 for(i=n=0; 1; i++){
1603 sqlite3_stmt *p = pArg->pStmt;
1604 sqlite3_int64 nLoop, nVisit;
1605 double rEst;
1606 int iSid;
1607 const char *zExplain;
1608 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1609 break;
1610 }
1611 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001612 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001613 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001614 if( n==0 ){
1615 rEstLoop = (double)nLoop;
mistachkinaae280e2015-12-31 19:06:24 +00001616 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001617 }
drh42f30bc2014-11-06 12:08:21 +00001618 n++;
1619 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1620 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1621 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
drhe05461c2015-12-30 13:36:57 +00001622 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
drh42f30bc2014-11-06 12:08:21 +00001623 rEstLoop *= rEst;
mistachkin1fe36bb2016-04-04 02:16:44 +00001624 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001625 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001626 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001627 );
dan8d1edb92014-11-05 09:07:28 +00001628 }
dan8d1edb92014-11-05 09:07:28 +00001629 }
mistachkinaae280e2015-12-31 19:06:24 +00001630 raw_printf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001631#endif
dan8d1edb92014-11-05 09:07:28 +00001632}
1633
1634/*
dana98bf362013-11-13 18:35:01 +00001635** Parameter azArray points to a zero-terminated array of strings. zStr
1636** points to a single nul-terminated string. Return non-zero if zStr
1637** is equal, according to strcmp(), to any of the strings in the array.
1638** Otherwise, return zero.
1639*/
1640static int str_in_array(const char *zStr, const char **azArray){
1641 int i;
1642 for(i=0; azArray[i]; i++){
1643 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1644 }
1645 return 0;
1646}
1647
1648/*
1649** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001650** and populate the ShellState.aiIndent[] array with the number of
mistachkin1fe36bb2016-04-04 02:16:44 +00001651** spaces each opcode should be indented before it is output.
dana98bf362013-11-13 18:35:01 +00001652**
1653** The indenting rules are:
1654**
1655** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1656** all opcodes that occur between the p2 jump destination and the opcode
1657** itself by 2 spaces.
1658**
drh01752bc2013-11-14 23:59:33 +00001659** * For each "Goto", if the jump destination is earlier in the program
1660** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001661** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001662** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001663** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001664** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001665*/
drhdcd87a92014-08-18 13:45:42 +00001666static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001667 const char *zSql; /* The text of the SQL statement */
1668 const char *z; /* Used to check if this is an EXPLAIN */
1669 int *abYield = 0; /* True if op is an OP_Yield */
1670 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001671 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001672
drh8ad0de32014-03-20 18:45:27 +00001673 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1674 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001675 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1676 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001677 const char *azGoto[] = { "Goto", 0 };
1678
1679 /* Try to figure out if this is really an EXPLAIN statement. If this
1680 ** cannot be verified, return early. */
drh87a24aa2016-02-09 20:04:07 +00001681 if( sqlite3_column_count(pSql)!=8 ){
1682 p->cMode = p->mode;
1683 return;
1684 }
dana98bf362013-11-13 18:35:01 +00001685 zSql = sqlite3_sql(pSql);
1686 if( zSql==0 ) return;
1687 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
drh87a24aa2016-02-09 20:04:07 +00001688 if( sqlite3_strnicmp(z, "explain", 7) ){
1689 p->cMode = p->mode;
1690 return;
1691 }
dana98bf362013-11-13 18:35:01 +00001692
1693 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1694 int i;
danc4650bb2013-11-18 08:41:06 +00001695 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001696 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001697
1698 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1699 ** p2 is an instruction address, set variable p2op to the index of that
1700 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1701 ** the current instruction is part of a sub-program generated by an
1702 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001703 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001704 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001705
1706 /* Grow the p->aiIndent array as required */
1707 if( iOp>=nAlloc ){
drh87a24aa2016-02-09 20:04:07 +00001708 if( iOp==0 ){
1709 /* Do further verfication that this is explain output. Abort if
1710 ** it is not */
1711 static const char *explainCols[] = {
1712 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
1713 int jj;
1714 for(jj=0; jj<ArraySize(explainCols); jj++){
1715 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
1716 p->cMode = p->mode;
1717 sqlite3_reset(pSql);
1718 return;
1719 }
1720 }
1721 }
dana98bf362013-11-13 18:35:01 +00001722 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001723 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1724 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001725 }
1726 abYield[iOp] = str_in_array(zOp, azYield);
1727 p->aiIndent[iOp] = 0;
1728 p->nIndent = iOp+1;
1729
1730 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001731 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001732 }
drhfe705102014-03-06 13:38:37 +00001733 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1734 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1735 ){
drheacd29d2016-04-15 15:03:27 +00001736 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001737 }
1738 }
1739
danc4650bb2013-11-18 08:41:06 +00001740 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001741 sqlite3_free(abYield);
1742 sqlite3_reset(pSql);
1743}
1744
1745/*
1746** Free the array allocated by explain_data_prepare().
1747*/
drhdcd87a92014-08-18 13:45:42 +00001748static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001749 sqlite3_free(p->aiIndent);
1750 p->aiIndent = 0;
1751 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001752 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001753}
1754
1755/*
drheacd29d2016-04-15 15:03:27 +00001756** Disable and restore .wheretrace and .selecttrace settings.
1757*/
1758#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1759extern int sqlite3SelectTrace;
1760static int savedSelectTrace;
1761#endif
1762#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1763extern int sqlite3WhereTrace;
1764static int savedWhereTrace;
1765#endif
1766static void disable_debug_trace_modes(void){
1767#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1768 savedSelectTrace = sqlite3SelectTrace;
1769 sqlite3SelectTrace = 0;
1770#endif
1771#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1772 savedWhereTrace = sqlite3WhereTrace;
1773 sqlite3WhereTrace = 0;
1774#endif
1775}
1776static void restore_debug_trace_modes(void){
1777#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1778 sqlite3SelectTrace = savedSelectTrace;
1779#endif
1780#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1781 sqlite3WhereTrace = savedWhereTrace;
1782#endif
1783}
1784
1785/*
1786** Run a prepared statement
1787*/
1788static void exec_prepared_stmt(
1789 ShellState *pArg, /* Pointer to ShellState */
1790 sqlite3_stmt *pStmt, /* Statment to run */
1791 int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
1792){
1793 int rc;
1794
1795 /* perform the first step. this will tell us if we
1796 ** have a result set or not and how wide it is.
1797 */
1798 rc = sqlite3_step(pStmt);
1799 /* if we have a result set... */
1800 if( SQLITE_ROW == rc ){
1801 /* if we have a callback... */
1802 if( xCallback ){
1803 /* allocate space for col name ptr, value ptr, and type */
1804 int nCol = sqlite3_column_count(pStmt);
1805 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
1806 if( !pData ){
1807 rc = SQLITE_NOMEM;
1808 }else{
1809 char **azCols = (char **)pData; /* Names of result columns */
1810 char **azVals = &azCols[nCol]; /* Results */
1811 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1812 int i, x;
1813 assert(sizeof(int) <= sizeof(char *));
1814 /* save off ptrs to column names */
1815 for(i=0; i<nCol; i++){
1816 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1817 }
1818 do{
1819 /* extract the data and data types */
1820 for(i=0; i<nCol; i++){
1821 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1822 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
1823 azVals[i] = "";
1824 }else{
1825 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1826 }
1827 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1828 rc = SQLITE_NOMEM;
1829 break; /* from for */
1830 }
1831 } /* end for */
1832
1833 /* if data and types extracted successfully... */
1834 if( SQLITE_ROW == rc ){
1835 /* call the supplied callback with the result row data */
1836 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1837 rc = SQLITE_ABORT;
1838 }else{
1839 rc = sqlite3_step(pStmt);
1840 }
1841 }
1842 } while( SQLITE_ROW == rc );
1843 sqlite3_free(pData);
1844 }
1845 }else{
1846 do{
1847 rc = sqlite3_step(pStmt);
1848 } while( rc == SQLITE_ROW );
1849 }
1850 }
1851}
1852
1853/*
mistachkin1fe36bb2016-04-04 02:16:44 +00001854** Execute a statement or set of statements. Print
1855** any result rows/columns depending on the current mode
shane626a6e42009-10-22 17:30:15 +00001856** set via the supplied callback.
1857**
mistachkin1fe36bb2016-04-04 02:16:44 +00001858** This is very similar to SQLite's built-in sqlite3_exec()
1859** function except it takes a slightly different callback
shane626a6e42009-10-22 17:30:15 +00001860** and callback data argument.
1861*/
1862static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001863 sqlite3 *db, /* An open database */
1864 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001865 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001866 /* (not the same as sqlite3_exec) */
1867 ShellState *pArg, /* Pointer to ShellState */
1868 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001869){
dan4564ced2010-01-05 04:59:56 +00001870 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1871 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001872 int rc2;
dan4564ced2010-01-05 04:59:56 +00001873 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001874
1875 if( pzErrMsg ){
1876 *pzErrMsg = NULL;
1877 }
1878
shaneb9fc17d2009-10-22 21:23:35 +00001879 while( zSql[0] && (SQLITE_OK == rc) ){
drheacd29d2016-04-15 15:03:27 +00001880 static const char *zStmtSql;
shaneb9fc17d2009-10-22 21:23:35 +00001881 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1882 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001883 if( pzErrMsg ){
1884 *pzErrMsg = save_err_msg(db);
1885 }
1886 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001887 if( !pStmt ){
1888 /* this happens for a comment or white-space */
1889 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001890 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001891 continue;
1892 }
drheacd29d2016-04-15 15:03:27 +00001893 zStmtSql = sqlite3_sql(pStmt);
1894 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
shane626a6e42009-10-22 17:30:15 +00001895
shaneh642d8b82010-07-28 16:05:34 +00001896 /* save off the prepared statment handle and reset row count */
1897 if( pArg ){
1898 pArg->pStmt = pStmt;
1899 pArg->cnt = 0;
1900 }
1901
shanehb7977c52010-01-18 18:17:10 +00001902 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001903 if( pArg && pArg->echoOn ){
drhe05461c2015-12-30 13:36:57 +00001904 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001905 }
shanehb7977c52010-01-18 18:17:10 +00001906
drhefbf3b12014-02-28 20:47:24 +00001907 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
drheacd29d2016-04-15 15:03:27 +00001908 if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
drhefbf3b12014-02-28 20:47:24 +00001909 sqlite3_stmt *pExplain;
drheacd29d2016-04-15 15:03:27 +00001910 char *zEQP;
1911 disable_debug_trace_modes();
1912 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
drhefbf3b12014-02-28 20:47:24 +00001913 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1914 if( rc==SQLITE_OK ){
1915 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001916 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1917 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1918 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001919 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001920 }
1921 }
1922 sqlite3_finalize(pExplain);
1923 sqlite3_free(zEQP);
drheacd29d2016-04-15 15:03:27 +00001924 if( pArg->autoEQP>=2 ){
1925 /* Also do an EXPLAIN for ".eqp full" mode */
1926 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
1927 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1928 if( rc==SQLITE_OK ){
1929 pArg->cMode = MODE_Explain;
1930 explain_data_prepare(pArg, pExplain);
1931 exec_prepared_stmt(pArg, pExplain, xCallback);
1932 explain_data_delete(pArg);
1933 }
1934 sqlite3_finalize(pExplain);
1935 sqlite3_free(zEQP);
1936 }
1937 restore_debug_trace_modes();
drhefbf3b12014-02-28 20:47:24 +00001938 }
1939
drh700c2522016-02-09 18:39:25 +00001940 if( pArg ){
1941 pArg->cMode = pArg->mode;
drh87a24aa2016-02-09 20:04:07 +00001942 if( pArg->autoExplain
1943 && sqlite3_column_count(pStmt)==8
drheacd29d2016-04-15 15:03:27 +00001944 && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
drh700c2522016-02-09 18:39:25 +00001945 ){
1946 pArg->cMode = MODE_Explain;
1947 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001948
drh700c2522016-02-09 18:39:25 +00001949 /* If the shell is currently in ".explain" mode, gather the extra
1950 ** data required to add indents to the output.*/
1951 if( pArg->cMode==MODE_Explain ){
1952 explain_data_prepare(pArg, pStmt);
1953 }
dana98bf362013-11-13 18:35:01 +00001954 }
1955
drheacd29d2016-04-15 15:03:27 +00001956 exec_prepared_stmt(pArg, pStmt, xCallback);
dana98bf362013-11-13 18:35:01 +00001957 explain_data_delete(pArg);
1958
shaneh642d8b82010-07-28 16:05:34 +00001959 /* print usage stats if stats on */
1960 if( pArg && pArg->statsOn ){
1961 display_stats(db, pArg, 0);
1962 }
1963
dan8d1edb92014-11-05 09:07:28 +00001964 /* print loop-counters if required */
1965 if( pArg && pArg->scanstatsOn ){
1966 display_scanstats(db, pArg);
1967 }
1968
mistachkin1fe36bb2016-04-04 02:16:44 +00001969 /* Finalize the statement just executed. If this fails, save a
dan4564ced2010-01-05 04:59:56 +00001970 ** copy of the error message. Otherwise, set zSql to point to the
1971 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001972 rc2 = sqlite3_finalize(pStmt);
1973 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001974 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001975 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001976 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001977 }else if( pzErrMsg ){
1978 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001979 }
shaneh642d8b82010-07-28 16:05:34 +00001980
1981 /* clear saved stmt handle */
1982 if( pArg ){
1983 pArg->pStmt = NULL;
1984 }
shane626a6e42009-10-22 17:30:15 +00001985 }
shaneb9fc17d2009-10-22 21:23:35 +00001986 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001987
1988 return rc;
1989}
1990
drhdd3d4592004-08-30 01:54:05 +00001991
drh33048c02001-10-01 14:29:22 +00001992/*
drh4c653a02000-06-07 01:27:47 +00001993** This is a different callback routine used for dumping the database.
1994** Each row received by this callback consists of a table name,
1995** the table type ("index" or "table") and SQL to create the table.
1996** This routine should print text sufficient to recreate the table.
1997*/
1998static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00001999 int rc;
2000 const char *zTable;
2001 const char *zType;
2002 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00002003 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00002004 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00002005
drh902b9ee2008-12-05 17:17:07 +00002006 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00002007 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00002008 zTable = azArg[0];
2009 zType = azArg[1];
2010 zSql = azArg[2];
mistachkin1fe36bb2016-04-04 02:16:44 +00002011
drh00b950d2005-09-11 02:03:03 +00002012 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00002013 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00002014 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002015 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00002016 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
2017 return 0;
drh45e29d82006-11-20 16:21:10 +00002018 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
2019 char *zIns;
2020 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00002021 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00002022 p->writableSchema = 1;
2023 }
2024 zIns = sqlite3_mprintf(
2025 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
2026 "VALUES('table','%q','%q',0,'%q');",
2027 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00002028 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00002029 sqlite3_free(zIns);
2030 return 0;
drh00b950d2005-09-11 02:03:03 +00002031 }else{
drhe05461c2015-12-30 13:36:57 +00002032 utf8_printf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00002033 }
danielk19772a02e332004-06-05 08:04:36 +00002034
2035 if( strcmp(zType, "table")==0 ){
2036 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00002037 char *zSelect = 0;
2038 char *zTableInfo = 0;
2039 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00002040 int nRow = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +00002041
danielk19772a02e332004-06-05 08:04:36 +00002042 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
2043 zTableInfo = appendText(zTableInfo, zTable, '"');
2044 zTableInfo = appendText(zTableInfo, ");", 0);
2045
drhc7181902014-02-27 15:04:13 +00002046 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00002047 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00002048 if( rc!=SQLITE_OK || !pTableInfo ){
2049 return 1;
2050 }
2051
2052 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00002053 /* Always quote the table name, even if it appears to be pure ascii,
2054 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
2055 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00002056 if( zTmp ){
2057 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00002058 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00002059 }
2060 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
2061 rc = sqlite3_step(pTableInfo);
2062 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00002063 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00002064 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00002065 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00002066 rc = sqlite3_step(pTableInfo);
2067 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00002068 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00002069 }else{
2070 zSelect = appendText(zSelect, ") ", 0);
2071 }
drh157e29a2009-05-21 15:15:00 +00002072 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00002073 }
2074 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00002075 if( rc!=SQLITE_OK || nRow==0 ){
2076 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00002077 return 1;
2078 }
2079 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
2080 zSelect = appendText(zSelect, zTable, '"');
2081
drh2f464a02011-10-13 00:41:49 +00002082 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00002083 if( rc==SQLITE_CORRUPT ){
2084 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00002085 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00002086 }
drh85e72432012-04-11 11:38:53 +00002087 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00002088 }
drh4c653a02000-06-07 01:27:47 +00002089 return 0;
2090}
2091
2092/*
drh45e29d82006-11-20 16:21:10 +00002093** Run zQuery. Use dump_callback() as the callback routine so that
2094** the contents of the query are output as SQL statements.
2095**
drhdd3d4592004-08-30 01:54:05 +00002096** If we get a SQLITE_CORRUPT error, rerun the query after appending
2097** "ORDER BY rowid DESC" to the end.
2098*/
2099static int run_schema_dump_query(
mistachkin1fe36bb2016-04-04 02:16:44 +00002100 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00002101 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00002102){
2103 int rc;
drh2f464a02011-10-13 00:41:49 +00002104 char *zErr = 0;
2105 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00002106 if( rc==SQLITE_CORRUPT ){
2107 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00002108 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00002109 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00002110 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00002111 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002112 sqlite3_free(zErr);
2113 zErr = 0;
2114 }
drhdd3d4592004-08-30 01:54:05 +00002115 zQ2 = malloc( len+100 );
2116 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00002117 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00002118 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
2119 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002120 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002121 }else{
2122 rc = SQLITE_CORRUPT;
2123 }
2124 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00002125 free(zQ2);
2126 }
2127 return rc;
2128}
2129
2130/*
drh75897232000-05-29 14:26:00 +00002131** Text of a help message
2132*/
persicom1d0b8722002-04-18 02:53:04 +00002133static char zHelp[] =
drhde613c62016-04-04 17:23:10 +00002134 ".auth ON|OFF Show authorizer callbacks\n"
drh9ff849f2009-02-04 20:55:57 +00002135 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00002136 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00002137 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00002138 ".changes on|off Show number of rows changed by SQL\n"
drh4bbcf102014-02-06 02:46:08 +00002139 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00002140 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00002141 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00002142 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00002143 " If TABLE specified, only dump tables matching\n"
2144 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00002145 ".echo on|off Turn command echo on or off\n"
drheacd29d2016-04-15 15:03:27 +00002146 ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00002147 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00002148 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drh4926fec2016-04-13 15:33:42 +00002149 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00002150 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00002151 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00002152 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00002153 ".indexes ?TABLE? Show names of all indexes\n"
2154 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00002155 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00002156#ifdef SQLITE_ENABLE_IOTRACE
2157 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
2158#endif
drh1a513372015-05-02 17:40:23 +00002159 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00002160#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002161 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00002162#endif
drh127f9d72010-02-23 01:47:00 +00002163 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00002164 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00002165 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00002166 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00002167 " column Left-aligned columns. (See .width)\n"
2168 " html HTML <table> code\n"
2169 " insert SQL insert statements for TABLE\n"
2170 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00002171 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00002172 " tabs Tab-separated values\n"
2173 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00002174 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00002175 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drh05782482013-10-24 15:20:20 +00002176 ".open ?FILENAME? Close existing database and reopen FILENAME\n"
drhc2ce0be2014-05-29 12:36:14 +00002177 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00002178 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002179 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002180 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00002181 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00002182 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00002183 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00002184 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh4926fec2016-04-13 15:33:42 +00002185 ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
2186 " Add --indent for pretty-printing\n"
mistachkine0d68852014-12-11 03:12:33 +00002187 ".separator COL ?ROW? Change the column separator and optionally the row\n"
2188 " separator for both the output mode and .import\n"
drhe6229612014-08-18 15:08:26 +00002189#if defined(SQLITE_ENABLE_SESSION)
2190 ".session CMD ... Create or control sessions\n"
2191#endif
drh62cdde52014-05-28 20:22:28 +00002192 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00002193 ".show Show the current values for various settings\n"
drh34784902016-02-27 17:12:36 +00002194 ".stats ?on|off? Show stats or turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00002195 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00002196 ".tables ?TABLE? List names of tables\n"
2197 " If TABLE specified, only list tables matching\n"
2198 " LIKE pattern TABLE.\n"
drh2dfbbca2000-07-28 14:32:48 +00002199 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00002200 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00002201 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00002202 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00002203 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00002204 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00002205 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00002206 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00002207;
2208
drhe6229612014-08-18 15:08:26 +00002209#if defined(SQLITE_ENABLE_SESSION)
2210/*
2211** Print help information for the ".sessions" command
2212*/
2213void session_help(ShellState *p){
mistachkin899c5c92016-04-03 20:50:02 +00002214 raw_printf(p->out,
drhe6229612014-08-18 15:08:26 +00002215 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
2216 "If ?NAME? is omitted, the first defined session is used.\n"
2217 "Subcommands:\n"
2218 " attach TABLE Attach TABLE\n"
2219 " changeset FILE Write a changeset into FILE\n"
2220 " close Close one session\n"
2221 " enable ?BOOLEAN? Set or query the enable bit\n"
mistachkin1fe36bb2016-04-04 02:16:44 +00002222 " filter GLOB... Reject tables matching GLOBs\n"
drhe6229612014-08-18 15:08:26 +00002223 " indirect ?BOOLEAN? Mark or query the indirect status\n"
2224 " isempty Query whether the session is empty\n"
2225 " list List currently open session names\n"
2226 " open DB NAME Open a new session on DB\n"
2227 " patchset FILE Write a patchset into FILE\n"
2228 );
2229}
2230#endif
2231
2232
drhdaffd0e2001-04-11 14:28:42 +00002233/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00002234static int process_input(ShellState *p, FILE *in);
drhba5b0932014-07-24 12:39:59 +00002235/*
2236** Implementation of the "readfile(X)" SQL function. The entire content
2237** of the file named X is read and returned as a BLOB. NULL is returned
2238** if the file does not exist or is unreadable.
2239*/
2240static void readfileFunc(
2241 sqlite3_context *context,
2242 int argc,
2243 sqlite3_value **argv
2244){
2245 const char *zName;
2246 FILE *in;
2247 long nIn;
2248 void *pBuf;
2249
drhf5ed7ad2015-06-15 14:43:25 +00002250 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002251 zName = (const char*)sqlite3_value_text(argv[0]);
2252 if( zName==0 ) return;
2253 in = fopen(zName, "rb");
2254 if( in==0 ) return;
2255 fseek(in, 0, SEEK_END);
2256 nIn = ftell(in);
2257 rewind(in);
drhf3cdcdc2015-04-29 16:50:28 +00002258 pBuf = sqlite3_malloc64( nIn );
drhba5b0932014-07-24 12:39:59 +00002259 if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
2260 sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
2261 }else{
2262 sqlite3_free(pBuf);
2263 }
2264 fclose(in);
2265}
2266
2267/*
2268** Implementation of the "writefile(X,Y)" SQL function. The argument Y
2269** is written into file X. The number of bytes written is returned. Or
2270** NULL is returned if something goes wrong, such as being unable to open
2271** file X for writing.
2272*/
2273static void writefileFunc(
2274 sqlite3_context *context,
2275 int argc,
2276 sqlite3_value **argv
2277){
2278 FILE *out;
2279 const char *z;
drhba5b0932014-07-24 12:39:59 +00002280 sqlite3_int64 rc;
2281 const char *zFile;
2282
drhf5ed7ad2015-06-15 14:43:25 +00002283 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002284 zFile = (const char*)sqlite3_value_text(argv[0]);
2285 if( zFile==0 ) return;
2286 out = fopen(zFile, "wb");
2287 if( out==0 ) return;
2288 z = (const char*)sqlite3_value_blob(argv[1]);
2289 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002290 rc = 0;
2291 }else{
drh490fe862014-08-11 14:21:32 +00002292 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002293 }
2294 fclose(out);
2295 sqlite3_result_int64(context, rc);
2296}
drhdaffd0e2001-04-11 14:28:42 +00002297
drhe6229612014-08-18 15:08:26 +00002298#if defined(SQLITE_ENABLE_SESSION)
2299/*
2300** Close a single OpenSession object and release all of its associated
2301** resources.
2302*/
2303static void session_close(OpenSession *pSession){
2304 int i;
2305 sqlite3session_delete(pSession->p);
2306 sqlite3_free(pSession->zName);
2307 for(i=0; i<pSession->nFilter; i++){
2308 sqlite3_free(pSession->azFilter[i]);
2309 }
2310 sqlite3_free(pSession->azFilter);
2311 memset(pSession, 0, sizeof(OpenSession));
2312}
2313#endif
2314
2315/*
drh51b55a32016-04-04 12:38:05 +00002316** Close all OpenSession objects and release all associated resources.
drhe6229612014-08-18 15:08:26 +00002317*/
drhe6229612014-08-18 15:08:26 +00002318#if defined(SQLITE_ENABLE_SESSION)
drh51b55a32016-04-04 12:38:05 +00002319static void session_close_all(ShellState *p){
drhe6229612014-08-18 15:08:26 +00002320 int i;
2321 for(i=0; i<p->nSession; i++){
2322 session_close(&p->aSession[i]);
2323 }
2324 p->nSession = 0;
drhe6229612014-08-18 15:08:26 +00002325}
drh51b55a32016-04-04 12:38:05 +00002326#else
2327# define session_close_all(X)
2328#endif
drhe6229612014-08-18 15:08:26 +00002329
drh75897232000-05-29 14:26:00 +00002330/*
drh03168ca2014-08-18 20:01:31 +00002331** Implementation of the xFilter function for an open session. Omit
2332** any tables named by ".session filter" but let all other table through.
2333*/
2334#if defined(SQLITE_ENABLE_SESSION)
2335static int session_filter(void *pCtx, const char *zTab){
2336 OpenSession *pSession = (OpenSession*)pCtx;
2337 int i;
2338 for(i=0; i<pSession->nFilter; i++){
2339 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
2340 }
2341 return 1;
2342}
2343#endif
2344
2345/*
drh44c2eb12003-04-30 11:38:26 +00002346** Make sure the database is open. If it is not, then open it. If
2347** the database fails to open, print an error message and exit.
2348*/
drhdcd87a92014-08-18 13:45:42 +00002349static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002350 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002351 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002352 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002353 globalDb = p->db;
2354 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2355 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002356 shellstaticFunc, 0, 0);
2357 }
mistachkin8e189222015-04-19 21:43:16 +00002358 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00002359 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002360 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002361 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002362 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002363 }
drhc2e87a32006-06-27 15:16:14 +00002364#ifndef SQLITE_OMIT_LOAD_EXTENSION
2365 sqlite3_enable_load_extension(p->db, 1);
2366#endif
mistachkin8e189222015-04-19 21:43:16 +00002367 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002368 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002369 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002370 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002371 }
2372}
2373
2374/*
drhfeac5f82004-08-01 00:10:45 +00002375** Do C-language style dequoting.
2376**
mistachkinf21979d2015-01-18 05:35:01 +00002377** \a -> alarm
2378** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002379** \t -> tab
2380** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002381** \v -> vertical tab
2382** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002383** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002384** \s -> space
drh4c56b992013-06-27 13:26:55 +00002385** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002386** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002387** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002388** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002389*/
2390static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002391 int i, j;
2392 char c;
drhc2ce0be2014-05-29 12:36:14 +00002393 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002394 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002395 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002396 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002397 if( c=='a' ){
2398 c = '\a';
2399 }else if( c=='b' ){
2400 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002401 }else if( c=='t' ){
2402 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002403 }else if( c=='n' ){
2404 c = '\n';
2405 }else if( c=='v' ){
2406 c = '\v';
2407 }else if( c=='f' ){
2408 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002409 }else if( c=='r' ){
2410 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002411 }else if( c=='"' ){
2412 c = '"';
2413 }else if( c=='\'' ){
2414 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002415 }else if( c=='\\' ){
2416 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002417 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002418 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002419 if( z[i+1]>='0' && z[i+1]<='7' ){
2420 i++;
2421 c = (c<<3) + z[i] - '0';
2422 if( z[i+1]>='0' && z[i+1]<='7' ){
2423 i++;
2424 c = (c<<3) + z[i] - '0';
2425 }
2426 }
2427 }
2428 }
2429 z[j] = c;
2430 }
drhc2ce0be2014-05-29 12:36:14 +00002431 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002432}
2433
2434/*
drh348d19c2013-06-03 12:47:43 +00002435** Return the value of a hexadecimal digit. Return -1 if the input
2436** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002437*/
drh348d19c2013-06-03 12:47:43 +00002438static int hexDigitValue(char c){
2439 if( c>='0' && c<='9' ) return c - '0';
2440 if( c>='a' && c<='f' ) return c - 'a' + 10;
2441 if( c>='A' && c<='F' ) return c - 'A' + 10;
2442 return -1;
drhc28490c2006-10-26 14:25:58 +00002443}
2444
2445/*
drh7d9f3942013-04-03 01:26:54 +00002446** Interpret zArg as an integer value, possibly with suffixes.
2447*/
2448static sqlite3_int64 integerValue(const char *zArg){
2449 sqlite3_int64 v = 0;
2450 static const struct { char *zSuffix; int iMult; } aMult[] = {
2451 { "KiB", 1024 },
2452 { "MiB", 1024*1024 },
2453 { "GiB", 1024*1024*1024 },
2454 { "KB", 1000 },
2455 { "MB", 1000000 },
2456 { "GB", 1000000000 },
2457 { "K", 1000 },
2458 { "M", 1000000 },
2459 { "G", 1000000000 },
2460 };
2461 int i;
2462 int isNeg = 0;
2463 if( zArg[0]=='-' ){
2464 isNeg = 1;
2465 zArg++;
2466 }else if( zArg[0]=='+' ){
2467 zArg++;
2468 }
drh348d19c2013-06-03 12:47:43 +00002469 if( zArg[0]=='0' && zArg[1]=='x' ){
2470 int x;
2471 zArg += 2;
2472 while( (x = hexDigitValue(zArg[0]))>=0 ){
2473 v = (v<<4) + x;
2474 zArg++;
2475 }
2476 }else{
2477 while( IsDigit(zArg[0]) ){
2478 v = v*10 + zArg[0] - '0';
2479 zArg++;
2480 }
drh7d9f3942013-04-03 01:26:54 +00002481 }
drhc2bed0a2013-05-24 11:57:50 +00002482 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002483 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2484 v *= aMult[i].iMult;
2485 break;
2486 }
2487 }
2488 return isNeg? -v : v;
2489}
2490
2491/*
drh348d19c2013-06-03 12:47:43 +00002492** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2493** for TRUE and FALSE. Return the integer value if appropriate.
2494*/
2495static int booleanValue(char *zArg){
2496 int i;
2497 if( zArg[0]=='0' && zArg[1]=='x' ){
2498 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2499 }else{
2500 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2501 }
2502 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2503 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2504 return 1;
2505 }
2506 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2507 return 0;
2508 }
mistachkinaae280e2015-12-31 19:06:24 +00002509 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002510 zArg);
2511 return 0;
2512}
2513
2514/*
drh42f64e52012-04-04 16:56:23 +00002515** Close an output file, assuming it is not stderr or stdout
2516*/
2517static void output_file_close(FILE *f){
2518 if( f && f!=stdout && f!=stderr ) fclose(f);
2519}
2520
2521/*
2522** Try to open an output file. The names "stdout" and "stderr" are
mistachkin1fe36bb2016-04-04 02:16:44 +00002523** recognized and do the right thing. NULL is returned if the output
drh42f64e52012-04-04 16:56:23 +00002524** filename is "off".
2525*/
2526static FILE *output_file_open(const char *zFile){
2527 FILE *f;
2528 if( strcmp(zFile,"stdout")==0 ){
2529 f = stdout;
2530 }else if( strcmp(zFile, "stderr")==0 ){
2531 f = stderr;
2532 }else if( strcmp(zFile, "off")==0 ){
2533 f = 0;
2534 }else{
2535 f = fopen(zFile, "wb");
2536 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002537 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002538 }
2539 }
2540 return f;
2541}
2542
2543/*
2544** A routine for handling output from sqlite3_trace().
2545*/
drh4b363a52016-07-23 20:27:41 +00002546static int sql_trace_callback(
2547 unsigned mType,
2548 void *pArg,
2549 void *pP,
2550 void *pX
2551){
drh42f64e52012-04-04 16:56:23 +00002552 FILE *f = (FILE*)pArg;
drhb0df5402016-08-01 17:06:44 +00002553 UNUSED_PARAMETER(mType);
2554 UNUSED_PARAMETER(pP);
drh4b2590e2014-08-19 19:28:00 +00002555 if( f ){
drh4b363a52016-07-23 20:27:41 +00002556 const char *z = (const char*)pX;
drh4b2590e2014-08-19 19:28:00 +00002557 int i = (int)strlen(z);
2558 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002559 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002560 }
drh4b363a52016-07-23 20:27:41 +00002561 return 0;
drh42f64e52012-04-04 16:56:23 +00002562}
2563
2564/*
drhd8621b92012-04-17 09:09:33 +00002565** A no-op routine that runs with the ".breakpoint" doc-command. This is
2566** a useful spot to set a debugger breakpoint.
2567*/
2568static void test_breakpoint(void){
2569 static int nCall = 0;
2570 nCall++;
2571}
2572
2573/*
mistachkin636bf9f2014-07-19 20:15:16 +00002574** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002575*/
mistachkin636bf9f2014-07-19 20:15:16 +00002576typedef struct ImportCtx ImportCtx;
2577struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002578 const char *zFile; /* Name of the input file */
2579 FILE *in; /* Read the CSV text from this input stream */
2580 char *z; /* Accumulated text for a field */
2581 int n; /* Number of bytes in z */
2582 int nAlloc; /* Space allocated for z[] */
2583 int nLine; /* Current line number */
2584 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002585 int cColSep; /* The column separator character. (Usually ",") */
2586 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002587};
2588
2589/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002590static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002591 if( p->n+1>=p->nAlloc ){
2592 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002593 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002594 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002595 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002596 exit(1);
2597 }
2598 }
2599 p->z[p->n++] = (char)c;
2600}
2601
2602/* Read a single field of CSV text. Compatible with rfc4180 and extended
2603** with the option of having a separator other than ",".
2604**
2605** + Input comes from p->in.
2606** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002607** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002608** + Use p->cSep as the column separator. The default is ",".
2609** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002610** + Keep track of the line number in p->nLine.
2611** + Store the character that terminates the field in p->cTerm. Store
2612** EOF on end-of-file.
2613** + Report syntax errors on stderr
2614*/
mistachkin44723ce2015-03-21 02:22:37 +00002615static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002616 int c;
2617 int cSep = p->cColSep;
2618 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002619 p->n = 0;
2620 c = fgetc(p->in);
2621 if( c==EOF || seenInterrupt ){
2622 p->cTerm = EOF;
2623 return 0;
2624 }
2625 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002626 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002627 int startLine = p->nLine;
2628 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002629 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002630 while( 1 ){
2631 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002632 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002633 if( c==cQuote ){
2634 if( pc==cQuote ){
2635 pc = 0;
2636 continue;
2637 }
2638 }
2639 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002640 || (c==rSep && pc==cQuote)
2641 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002642 || (c==EOF && pc==cQuote)
2643 ){
2644 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002645 p->cTerm = c;
2646 break;
2647 }
2648 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002649 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002650 p->zFile, p->nLine, cQuote);
2651 }
2652 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002653 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002654 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002655 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002656 break;
2657 }
mistachkin636bf9f2014-07-19 20:15:16 +00002658 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002659 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002660 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002661 }
drhdb95f682013-06-26 22:46:00 +00002662 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002663 while( c!=EOF && c!=cSep && c!=rSep ){
2664 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002665 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002666 }
mistachkin636bf9f2014-07-19 20:15:16 +00002667 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002668 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002669 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002670 }
drhdb95f682013-06-26 22:46:00 +00002671 p->cTerm = c;
2672 }
drh8dd675e2013-07-12 21:09:24 +00002673 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002674 return p->z;
2675}
2676
mistachkin636bf9f2014-07-19 20:15:16 +00002677/* Read a single field of ASCII delimited text.
2678**
2679** + Input comes from p->in.
2680** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002681** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002682** + Use p->cSep as the column separator. The default is "\x1F".
2683** + Use p->rSep as the row separator. The default is "\x1E".
2684** + Keep track of the row number in p->nLine.
2685** + Store the character that terminates the field in p->cTerm. Store
2686** EOF on end-of-file.
2687** + Report syntax errors on stderr
2688*/
mistachkin44723ce2015-03-21 02:22:37 +00002689static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002690 int c;
2691 int cSep = p->cColSep;
2692 int rSep = p->cRowSep;
2693 p->n = 0;
2694 c = fgetc(p->in);
2695 if( c==EOF || seenInterrupt ){
2696 p->cTerm = EOF;
2697 return 0;
2698 }
2699 while( c!=EOF && c!=cSep && c!=rSep ){
2700 import_append_char(p, c);
2701 c = fgetc(p->in);
2702 }
2703 if( c==rSep ){
2704 p->nLine++;
2705 }
2706 p->cTerm = c;
2707 if( p->z ) p->z[p->n] = 0;
2708 return p->z;
2709}
2710
drhdb95f682013-06-26 22:46:00 +00002711/*
drh4bbcf102014-02-06 02:46:08 +00002712** Try to transfer data for table zTable. If an error is seen while
2713** moving forward, try to go backwards. The backwards movement won't
2714** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002715*/
mistachkine31ae902014-02-06 01:15:29 +00002716static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002717 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002718 sqlite3 *newDb,
2719 const char *zTable
2720){
mistachkin1fe36bb2016-04-04 02:16:44 +00002721 sqlite3_stmt *pQuery = 0;
drh3350ce92014-02-06 00:49:12 +00002722 sqlite3_stmt *pInsert = 0;
2723 char *zQuery = 0;
2724 char *zInsert = 0;
2725 int rc;
2726 int i, j, n;
2727 int nTable = (int)strlen(zTable);
2728 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002729 int cnt = 0;
2730 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002731
2732 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2733 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2734 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002735 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002736 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2737 zQuery);
2738 goto end_data_xfer;
2739 }
2740 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002741 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002742 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002743 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002744 goto end_data_xfer;
2745 }
2746 sqlite3_snprintf(200+nTable,zInsert,
2747 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2748 i = (int)strlen(zInsert);
2749 for(j=1; j<n; j++){
2750 memcpy(zInsert+i, ",?", 2);
2751 i += 2;
2752 }
2753 memcpy(zInsert+i, ");", 3);
2754 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2755 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002756 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002757 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2758 zQuery);
2759 goto end_data_xfer;
2760 }
2761 for(k=0; k<2; k++){
2762 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2763 for(i=0; i<n; i++){
2764 switch( sqlite3_column_type(pQuery, i) ){
2765 case SQLITE_NULL: {
2766 sqlite3_bind_null(pInsert, i+1);
2767 break;
2768 }
2769 case SQLITE_INTEGER: {
2770 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2771 break;
2772 }
2773 case SQLITE_FLOAT: {
2774 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2775 break;
2776 }
2777 case SQLITE_TEXT: {
2778 sqlite3_bind_text(pInsert, i+1,
2779 (const char*)sqlite3_column_text(pQuery,i),
2780 -1, SQLITE_STATIC);
2781 break;
2782 }
2783 case SQLITE_BLOB: {
2784 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2785 sqlite3_column_bytes(pQuery,i),
2786 SQLITE_STATIC);
2787 break;
2788 }
2789 }
2790 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002791 rc = sqlite3_step(pInsert);
2792 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002793 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002794 sqlite3_errmsg(newDb));
2795 }
drh3350ce92014-02-06 00:49:12 +00002796 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002797 cnt++;
2798 if( (cnt%spinRate)==0 ){
2799 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2800 fflush(stdout);
2801 }
drh3350ce92014-02-06 00:49:12 +00002802 } /* End while */
2803 if( rc==SQLITE_DONE ) break;
2804 sqlite3_finalize(pQuery);
2805 sqlite3_free(zQuery);
2806 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2807 zTable);
2808 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2809 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002810 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002811 break;
drh3350ce92014-02-06 00:49:12 +00002812 }
2813 } /* End for(k=0...) */
2814
2815end_data_xfer:
2816 sqlite3_finalize(pQuery);
2817 sqlite3_finalize(pInsert);
2818 sqlite3_free(zQuery);
2819 sqlite3_free(zInsert);
2820}
2821
2822
2823/*
2824** Try to transfer all rows of the schema that match zWhere. For
2825** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002826** If an error is encountered while moving forward through the
2827** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002828*/
mistachkine31ae902014-02-06 01:15:29 +00002829static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002830 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002831 sqlite3 *newDb,
2832 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002833 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002834){
2835 sqlite3_stmt *pQuery = 0;
2836 char *zQuery = 0;
2837 int rc;
2838 const unsigned char *zName;
2839 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002840 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002841
2842 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2843 " WHERE %s", zWhere);
2844 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2845 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002846 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002847 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2848 zQuery);
2849 goto end_schema_xfer;
2850 }
2851 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2852 zName = sqlite3_column_text(pQuery, 0);
2853 zSql = sqlite3_column_text(pQuery, 1);
2854 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002855 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2856 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002857 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002858 sqlite3_free(zErrMsg);
2859 zErrMsg = 0;
2860 }
drh3350ce92014-02-06 00:49:12 +00002861 if( xForEach ){
2862 xForEach(p, newDb, (const char*)zName);
2863 }
2864 printf("done\n");
2865 }
2866 if( rc!=SQLITE_DONE ){
2867 sqlite3_finalize(pQuery);
2868 sqlite3_free(zQuery);
2869 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2870 " WHERE %s ORDER BY rowid DESC", zWhere);
2871 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2872 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002873 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002874 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2875 zQuery);
2876 goto end_schema_xfer;
2877 }
2878 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2879 zName = sqlite3_column_text(pQuery, 0);
2880 zSql = sqlite3_column_text(pQuery, 1);
2881 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002882 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2883 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002884 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002885 sqlite3_free(zErrMsg);
2886 zErrMsg = 0;
2887 }
drh3350ce92014-02-06 00:49:12 +00002888 if( xForEach ){
2889 xForEach(p, newDb, (const char*)zName);
2890 }
2891 printf("done\n");
2892 }
2893 }
2894end_schema_xfer:
2895 sqlite3_finalize(pQuery);
2896 sqlite3_free(zQuery);
2897}
2898
2899/*
2900** Open a new database file named "zNewDb". Try to recover as much information
2901** as possible out of the main database (which might be corrupt) and write it
2902** into zNewDb.
2903*/
drhdcd87a92014-08-18 13:45:42 +00002904static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002905 int rc;
2906 sqlite3 *newDb = 0;
2907 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002908 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002909 return;
2910 }
2911 rc = sqlite3_open(zNewDb, &newDb);
2912 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002913 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002914 sqlite3_errmsg(newDb));
2915 }else{
drh54d0d2d2014-04-03 00:32:13 +00002916 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002917 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002918 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2919 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002920 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002921 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002922 }
2923 sqlite3_close(newDb);
2924}
2925
2926/*
drhc2ce0be2014-05-29 12:36:14 +00002927** Change the output file back to stdout
2928*/
drhdcd87a92014-08-18 13:45:42 +00002929static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002930 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002931#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002932 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002933#endif
drhc2ce0be2014-05-29 12:36:14 +00002934 }else{
2935 output_file_close(p->out);
2936 }
2937 p->outfile[0] = 0;
2938 p->out = stdout;
2939}
2940
2941/*
drhf7502f02015-02-06 14:19:44 +00002942** Run an SQL command and return the single integer result.
2943*/
2944static int db_int(ShellState *p, const char *zSql){
2945 sqlite3_stmt *pStmt;
2946 int res = 0;
2947 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2948 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2949 res = sqlite3_column_int(pStmt,0);
2950 }
2951 sqlite3_finalize(pStmt);
2952 return res;
2953}
2954
2955/*
2956** Convert a 2-byte or 4-byte big-endian integer into a native integer
2957*/
drha0620ac2016-07-13 13:05:13 +00002958static unsigned int get2byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00002959 return (a[0]<<8) + a[1];
2960}
drha0620ac2016-07-13 13:05:13 +00002961static unsigned int get4byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00002962 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2963}
2964
2965/*
2966** Implementation of the ".info" command.
2967**
2968** Return 1 on error, 2 to exit, and 0 otherwise.
2969*/
drh0e55db12015-02-06 14:51:13 +00002970static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002971 static const struct { const char *zName; int ofst; } aField[] = {
2972 { "file change counter:", 24 },
2973 { "database page count:", 28 },
2974 { "freelist page count:", 36 },
2975 { "schema cookie:", 40 },
2976 { "schema format:", 44 },
2977 { "default cache size:", 48 },
2978 { "autovacuum top root:", 52 },
2979 { "incremental vacuum:", 64 },
2980 { "text encoding:", 56 },
2981 { "user version:", 60 },
2982 { "application id:", 68 },
2983 { "software version:", 96 },
2984 };
drh0e55db12015-02-06 14:51:13 +00002985 static const struct { const char *zName; const char *zSql; } aQuery[] = {
2986 { "number of tables:",
2987 "SELECT count(*) FROM %s WHERE type='table'" },
2988 { "number of indexes:",
2989 "SELECT count(*) FROM %s WHERE type='index'" },
2990 { "number of triggers:",
2991 "SELECT count(*) FROM %s WHERE type='trigger'" },
2992 { "number of views:",
2993 "SELECT count(*) FROM %s WHERE type='view'" },
2994 { "schema size:",
2995 "SELECT total(length(sql)) FROM %s" },
2996 };
mistachkinbfe8bd52015-11-17 19:17:14 +00002997 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00002998 int i;
2999 char *zSchemaTab;
3000 char *zDb = nArg>=2 ? azArg[1] : "main";
3001 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00003002 open_db(p, 0);
3003 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00003004 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00003005 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
3006 return 1;
3007 }
3008 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
3009 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003010 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00003011 return 1;
3012 }
3013 i = get2byteInt(aHdr+16);
3014 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00003015 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
3016 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
3017 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
3018 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00003019 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00003020 int ofst = aField[i].ofst;
3021 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00003022 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00003023 switch( ofst ){
3024 case 56: {
mistachkin1fe36bb2016-04-04 02:16:44 +00003025 if( val==1 ) raw_printf(p->out, " (utf8)");
3026 if( val==2 ) raw_printf(p->out, " (utf16le)");
3027 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00003028 }
3029 }
mistachkinaae280e2015-12-31 19:06:24 +00003030 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00003031 }
drh0e55db12015-02-06 14:51:13 +00003032 if( zDb==0 ){
3033 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
3034 }else if( strcmp(zDb,"temp")==0 ){
3035 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
3036 }else{
3037 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
3038 }
drhf5ed7ad2015-06-15 14:43:25 +00003039 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00003040 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
3041 int val = db_int(p, zSql);
3042 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00003043 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00003044 }
3045 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00003046 return 0;
3047}
3048
dand95bb392015-09-30 11:19:05 +00003049/*
3050** Print the current sqlite3_errmsg() value to stderr and return 1.
3051*/
3052static int shellDatabaseError(sqlite3 *db){
3053 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00003054 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00003055 return 1;
3056}
3057
3058/*
3059** Print an out-of-memory message to stderr and return 1.
3060*/
3061static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00003062 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00003063 return 1;
3064}
drhf7502f02015-02-06 14:19:44 +00003065
3066/*
drh4926fec2016-04-13 15:33:42 +00003067** Compare the string as a command-line option with either one or two
3068** initial "-" characters.
3069*/
3070static int optionMatch(const char *zStr, const char *zOpt){
3071 if( zStr[0]!='-' ) return 0;
3072 zStr++;
3073 if( zStr[0]=='-' ) zStr++;
3074 return strcmp(zStr, zOpt)==0;
3075}
3076
3077/*
drh75897232000-05-29 14:26:00 +00003078** If an input line begins with "." then invoke this routine to
3079** process that line.
drh67505e72002-04-19 12:34:06 +00003080**
drh47ad6842006-11-08 12:25:42 +00003081** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00003082*/
drhdcd87a92014-08-18 13:45:42 +00003083static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00003084 int h = 1;
drh75897232000-05-29 14:26:00 +00003085 int nArg = 0;
3086 int n, c;
drh67505e72002-04-19 12:34:06 +00003087 int rc = 0;
drh75897232000-05-29 14:26:00 +00003088 char *azArg[50];
3089
3090 /* Parse the input line into tokens.
3091 */
mistachkin8e189222015-04-19 21:43:16 +00003092 while( zLine[h] && nArg<ArraySize(azArg) ){
3093 while( IsSpace(zLine[h]) ){ h++; }
3094 if( zLine[h]==0 ) break;
3095 if( zLine[h]=='\'' || zLine[h]=='"' ){
3096 int delim = zLine[h++];
3097 azArg[nArg++] = &zLine[h];
mistachkin1fe36bb2016-04-04 02:16:44 +00003098 while( zLine[h] && zLine[h]!=delim ){
mistachkin8e189222015-04-19 21:43:16 +00003099 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
mistachkin1fe36bb2016-04-04 02:16:44 +00003100 h++;
drh4c56b992013-06-27 13:26:55 +00003101 }
mistachkin8e189222015-04-19 21:43:16 +00003102 if( zLine[h]==delim ){
3103 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00003104 }
drhfeac5f82004-08-01 00:10:45 +00003105 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003106 }else{
mistachkin8e189222015-04-19 21:43:16 +00003107 azArg[nArg++] = &zLine[h];
3108 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
3109 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00003110 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003111 }
3112 }
3113
3114 /* Process the input line.
3115 */
shane9bd1b442009-10-23 01:27:39 +00003116 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00003117 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00003118 c = azArg[0][0];
drhde613c62016-04-04 17:23:10 +00003119
3120 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
3121 if( nArg!=2 ){
3122 raw_printf(stderr, "Usage: .auth ON|OFF\n");
3123 rc = 1;
3124 goto meta_command_exit;
3125 }
3126 open_db(p, 0);
3127 if( booleanValue(azArg[1]) ){
3128 sqlite3_set_authorizer(p->db, shellAuth, p);
3129 }else{
3130 sqlite3_set_authorizer(p->db, 0, 0);
3131 }
3132 }else
3133
drh5c7976f2014-02-10 19:59:27 +00003134 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
3135 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
3136 ){
drhbc46f022013-01-23 18:53:23 +00003137 const char *zDestFile = 0;
3138 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00003139 sqlite3 *pDest;
3140 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00003141 int j;
3142 for(j=1; j<nArg; j++){
3143 const char *z = azArg[j];
3144 if( z[0]=='-' ){
3145 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00003146 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00003147 {
mistachkinaae280e2015-12-31 19:06:24 +00003148 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00003149 return 1;
3150 }
3151 }else if( zDestFile==0 ){
3152 zDestFile = azArg[j];
3153 }else if( zDb==0 ){
3154 zDb = zDestFile;
3155 zDestFile = azArg[j];
3156 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003157 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00003158 return 1;
3159 }
drh9ff849f2009-02-04 20:55:57 +00003160 }
drhbc46f022013-01-23 18:53:23 +00003161 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003162 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00003163 return 1;
3164 }
3165 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00003166 rc = sqlite3_open(zDestFile, &pDest);
3167 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003168 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00003169 sqlite3_close(pDest);
3170 return 1;
3171 }
drh05782482013-10-24 15:20:20 +00003172 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003173 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
3174 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003175 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00003176 sqlite3_close(pDest);
3177 return 1;
3178 }
3179 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
3180 sqlite3_backup_finish(pBackup);
3181 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003182 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00003183 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003184 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00003185 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003186 }
3187 sqlite3_close(pDest);
3188 }else
3189
drhc2ce0be2014-05-29 12:36:14 +00003190 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
3191 if( nArg==2 ){
3192 bail_on_error = booleanValue(azArg[1]);
3193 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003194 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003195 rc = 1;
3196 }
drhc49f44e2006-10-26 18:15:42 +00003197 }else
3198
mistachkinf21979d2015-01-18 05:35:01 +00003199 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
3200 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00003201 if( booleanValue(azArg[1]) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003202 setBinaryMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003203 }else{
mistachkin1fe36bb2016-04-04 02:16:44 +00003204 setTextMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003205 }
mistachkinf21979d2015-01-18 05:35:01 +00003206 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003207 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00003208 rc = 1;
3209 }
3210 }else
3211
drhd8621b92012-04-17 09:09:33 +00003212 /* The undocumented ".breakpoint" command causes a call to the no-op
3213 ** routine named test_breakpoint().
3214 */
3215 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
3216 test_breakpoint();
3217 }else
3218
drhdf12f1c2015-12-07 21:46:19 +00003219 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
3220 if( nArg==2 ){
3221 p->countChanges = booleanValue(azArg[1]);
3222 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003223 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00003224 rc = 1;
3225 }
3226 }else
3227
drhc2ce0be2014-05-29 12:36:14 +00003228 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
3229 if( nArg==2 ){
3230 tryToClone(p, azArg[1]);
3231 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003232 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003233 rc = 1;
3234 }
mistachkine31ae902014-02-06 01:15:29 +00003235 }else
3236
drhc2ce0be2014-05-29 12:36:14 +00003237 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003238 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00003239 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003240 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00003241 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00003242 data.showHeader = 1;
drh700c2522016-02-09 18:39:25 +00003243 data.cMode = data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00003244 data.colWidth[0] = 3;
3245 data.colWidth[1] = 15;
3246 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00003247 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00003248 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00003249 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003250 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003251 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003252 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00003253 }
3254 }else
3255
drh0e55db12015-02-06 14:51:13 +00003256 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
3257 rc = shell_dbinfo_command(p, nArg, azArg);
3258 }else
3259
drhc2ce0be2014-05-29 12:36:14 +00003260 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00003261 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00003262 /* When playing back a "dump", the content might appear in an order
3263 ** which causes immediate foreign key constraints to be violated.
3264 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00003265 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003266 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003267 rc = 1;
3268 goto meta_command_exit;
3269 }
mistachkinaae280e2015-12-31 19:06:24 +00003270 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
3271 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00003272 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00003273 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00003274 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00003275 if( nArg==1 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003276 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003277 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003278 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00003279 );
mistachkin1fe36bb2016-04-04 02:16:44 +00003280 run_schema_dump_query(p,
drh4f324762009-05-21 14:51:03 +00003281 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003282 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00003283 );
drh2f464a02011-10-13 00:41:49 +00003284 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003285 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00003286 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00003287 );
drh4c653a02000-06-07 01:27:47 +00003288 }else{
3289 int i;
drhdd3d4592004-08-30 01:54:05 +00003290 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00003291 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00003292 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003293 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00003294 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00003295 " AND sql NOT NULL");
3296 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003297 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00003298 "WHERE sql NOT NULL"
3299 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00003300 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00003301 );
danielk1977bc6ada42004-06-30 08:20:16 +00003302 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00003303 }
3304 }
drh45e29d82006-11-20 16:21:10 +00003305 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00003306 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00003307 p->writableSchema = 0;
3308 }
drh56197952011-10-13 16:30:13 +00003309 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
3310 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00003311 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00003312 }else
drh75897232000-05-29 14:26:00 +00003313
drhc2ce0be2014-05-29 12:36:14 +00003314 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
3315 if( nArg==2 ){
3316 p->echoOn = booleanValue(azArg[1]);
3317 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003318 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003319 rc = 1;
3320 }
drhdaffd0e2001-04-11 14:28:42 +00003321 }else
3322
drhc2ce0be2014-05-29 12:36:14 +00003323 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
3324 if( nArg==2 ){
drheacd29d2016-04-15 15:03:27 +00003325 if( strcmp(azArg[1],"full")==0 ){
3326 p->autoEQP = 2;
3327 }else{
3328 p->autoEQP = booleanValue(azArg[1]);
3329 }
drhc2ce0be2014-05-29 12:36:14 +00003330 }else{
drheacd29d2016-04-15 15:03:27 +00003331 raw_printf(stderr, "Usage: .eqp on|off|full\n");
drhc2ce0be2014-05-29 12:36:14 +00003332 rc = 1;
mistachkin1fe36bb2016-04-04 02:16:44 +00003333 }
drhefbf3b12014-02-28 20:47:24 +00003334 }else
3335
drhd3ac7d92013-01-25 18:33:43 +00003336 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00003337 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00003338 rc = 2;
drh75897232000-05-29 14:26:00 +00003339 }else
3340
drhc2ce0be2014-05-29 12:36:14 +00003341 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00003342 int val = 1;
3343 if( nArg>=2 ){
3344 if( strcmp(azArg[1],"auto")==0 ){
3345 val = 99;
3346 }else{
3347 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003348 }
drh700c2522016-02-09 18:39:25 +00003349 }
3350 if( val==1 && p->mode!=MODE_Explain ){
3351 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003352 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003353 p->autoExplain = 0;
3354 }else if( val==0 ){
3355 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3356 p->autoExplain = 0;
3357 }else if( val==99 ){
3358 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3359 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003360 }
drh75897232000-05-29 14:26:00 +00003361 }else
3362
drhc1971542014-06-23 23:28:13 +00003363 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003364 ShellState data;
drhc1971542014-06-23 23:28:13 +00003365 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003366 int doStats = 0;
drh4926fec2016-04-13 15:33:42 +00003367 memcpy(&data, p, sizeof(data));
3368 data.showHeader = 0;
3369 data.cMode = data.mode = MODE_Semi;
3370 if( nArg==2 && optionMatch(azArg[1], "indent") ){
3371 data.cMode = data.mode = MODE_Pretty;
3372 nArg = 1;
3373 }
drhc1971542014-06-23 23:28:13 +00003374 if( nArg!=1 ){
drh4926fec2016-04-13 15:33:42 +00003375 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
drhc1971542014-06-23 23:28:13 +00003376 rc = 1;
3377 goto meta_command_exit;
3378 }
3379 open_db(p, 0);
drhc1971542014-06-23 23:28:13 +00003380 rc = sqlite3_exec(p->db,
3381 "SELECT sql FROM"
3382 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3383 " FROM sqlite_master UNION ALL"
3384 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003385 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003386 "ORDER BY rowid",
3387 callback, &data, &zErrMsg
3388 );
drh56f674c2014-07-18 14:43:29 +00003389 if( rc==SQLITE_OK ){
3390 sqlite3_stmt *pStmt;
3391 rc = sqlite3_prepare_v2(p->db,
3392 "SELECT rowid FROM sqlite_master"
3393 " WHERE name GLOB 'sqlite_stat[134]'",
3394 -1, &pStmt, 0);
3395 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3396 sqlite3_finalize(pStmt);
3397 }
3398 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003399 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003400 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003401 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003402 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3403 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003404 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003405 data.zDestTable = "sqlite_stat1";
3406 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3407 shell_callback, &data,&zErrMsg);
3408 data.zDestTable = "sqlite_stat3";
3409 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3410 shell_callback, &data,&zErrMsg);
3411 data.zDestTable = "sqlite_stat4";
3412 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3413 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003414 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003415 }
drhc1971542014-06-23 23:28:13 +00003416 }else
3417
drhc2ce0be2014-05-29 12:36:14 +00003418 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3419 if( nArg==2 ){
3420 p->showHeader = booleanValue(azArg[1]);
3421 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003422 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003423 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003424 }
drh75897232000-05-29 14:26:00 +00003425 }else
3426
drhc2ce0be2014-05-29 12:36:14 +00003427 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003428 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003429 }else
3430
3431 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003432 char *zTable; /* Insert data into this table */
3433 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003434 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003435 int nCol; /* Number of columns in the table */
3436 int nByte; /* Number of bytes in an SQL string */
3437 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003438 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003439 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003440 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003441 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003442 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3443 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003444
drhc2ce0be2014-05-29 12:36:14 +00003445 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003446 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003447 goto meta_command_exit;
3448 }
drh01f37542014-05-31 15:43:33 +00003449 zFile = azArg[1];
3450 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003451 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003452 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003453 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003454 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003455 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003456 raw_printf(stderr,
3457 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003458 return 1;
drhfeac5f82004-08-01 00:10:45 +00003459 }
drhdb95f682013-06-26 22:46:00 +00003460 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003461 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003462 " for import\n");
3463 return 1;
3464 }
mistachkin636bf9f2014-07-19 20:15:16 +00003465 nSep = strlen30(p->rowSeparator);
3466 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003467 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003468 return 1;
3469 }
mistachkine0d68852014-12-11 03:12:33 +00003470 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3471 /* When importing CSV (only), if the row separator is set to the
3472 ** default output row separator, change it to the default input
3473 ** row separator. This avoids having to maintain different input
3474 ** and output row separators. */
3475 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3476 nSep = strlen30(p->rowSeparator);
3477 }
mistachkin636bf9f2014-07-19 20:15:16 +00003478 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003479 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003480 " for import\n");
3481 return 1;
3482 }
3483 sCtx.zFile = zFile;
3484 sCtx.nLine = 1;
3485 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003486#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003487 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003488 return 1;
3489#else
mistachkin636bf9f2014-07-19 20:15:16 +00003490 sCtx.in = popen(sCtx.zFile+1, "r");
3491 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003492 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003493#endif
drh5bde8162013-06-27 14:07:53 +00003494 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003495 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003496 xCloser = fclose;
3497 }
mistachkin636bf9f2014-07-19 20:15:16 +00003498 if( p->mode==MODE_Ascii ){
3499 xRead = ascii_read_one_field;
3500 }else{
3501 xRead = csv_read_one_field;
3502 }
3503 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003504 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003505 return 1;
3506 }
mistachkin636bf9f2014-07-19 20:15:16 +00003507 sCtx.cColSep = p->colSeparator[0];
3508 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003509 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003510 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003511 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003512 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003513 return 1;
3514 }
drh4f21c4a2008-12-10 22:15:00 +00003515 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003516 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003517 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003518 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003519 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3520 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003521 while( xRead(&sCtx) ){
drhd8c22ac2016-02-25 13:33:02 +00003522 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003523 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003524 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003525 }
drh5bde8162013-06-27 14:07:53 +00003526 if( cSep=='(' ){
3527 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003528 sqlite3_free(sCtx.z);
3529 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003530 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003531 return 1;
3532 }
drhdb95f682013-06-26 22:46:00 +00003533 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3534 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3535 sqlite3_free(zCreate);
3536 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003537 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003538 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003539 sqlite3_free(sCtx.z);
3540 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003541 return 1;
3542 }
drhc7181902014-02-27 15:04:13 +00003543 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003544 }
drhfeac5f82004-08-01 00:10:45 +00003545 sqlite3_free(zSql);
3546 if( rc ){
shane916f9612009-10-23 00:37:15 +00003547 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00003548 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003549 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003550 return 1;
drhfeac5f82004-08-01 00:10:45 +00003551 }
shane916f9612009-10-23 00:37:15 +00003552 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003553 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003554 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003555 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003556 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003557 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003558 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003559 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003560 return 1;
3561 }
drhdb95f682013-06-26 22:46:00 +00003562 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003563 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003564 for(i=1; i<nCol; i++){
3565 zSql[j++] = ',';
3566 zSql[j++] = '?';
3567 }
3568 zSql[j++] = ')';
3569 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003570 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003571 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003572 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003573 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003574 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003575 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003576 return 1;
drhfeac5f82004-08-01 00:10:45 +00003577 }
mistachkin8e189222015-04-19 21:43:16 +00003578 needCommit = sqlite3_get_autocommit(p->db);
3579 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003580 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003581 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003582 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003583 char *z = xRead(&sCtx);
3584 /*
3585 ** Did we reach end-of-file before finding any columns?
3586 ** If so, stop instead of NULL filling the remaining columns.
3587 */
drhdb95f682013-06-26 22:46:00 +00003588 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003589 /*
3590 ** Did we reach end-of-file OR end-of-line before finding any
3591 ** columns in ASCII mode? If so, stop instead of NULL filling
3592 ** the remaining columns.
3593 */
3594 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003595 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003596 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00003597 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003598 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003599 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003600 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003601 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003602 }
drhfeac5f82004-08-01 00:10:45 +00003603 }
mistachkin636bf9f2014-07-19 20:15:16 +00003604 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003605 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003606 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003607 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003608 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00003609 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003610 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003611 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003612 }
drhdb95f682013-06-26 22:46:00 +00003613 if( i>=nCol ){
3614 sqlite3_step(pStmt);
3615 rc = sqlite3_reset(pStmt);
3616 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003617 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
3618 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003619 }
3620 }
mistachkin636bf9f2014-07-19 20:15:16 +00003621 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003622
mistachkin636bf9f2014-07-19 20:15:16 +00003623 xCloser(sCtx.in);
3624 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003625 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003626 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003627 }else
3628
drh0e55db12015-02-06 14:51:13 +00003629 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3630 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003631 ShellState data;
drh75897232000-05-29 14:26:00 +00003632 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003633 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003634 memcpy(&data, p, sizeof(data));
3635 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003636 data.cMode = data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003637 if( nArg==1 ){
3638 rc = sqlite3_exec(p->db,
3639 "SELECT name FROM sqlite_master "
3640 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3641 "UNION ALL "
3642 "SELECT name FROM sqlite_temp_master "
3643 "WHERE type='index' "
3644 "ORDER BY 1",
3645 callback, &data, &zErrMsg
3646 );
drhc2ce0be2014-05-29 12:36:14 +00003647 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003648 zShellStatic = azArg[1];
3649 rc = sqlite3_exec(p->db,
3650 "SELECT name FROM sqlite_master "
3651 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3652 "UNION ALL "
3653 "SELECT name FROM sqlite_temp_master "
3654 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3655 "ORDER BY 1",
3656 callback, &data, &zErrMsg
3657 );
3658 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003659 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003660 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003661 rc = 1;
3662 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003663 }
drh75897232000-05-29 14:26:00 +00003664 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003665 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003666 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003667 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003668 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003669 raw_printf(stderr,
3670 "Error: querying sqlite_master and sqlite_temp_master\n");
shane86f5bdb2009-10-24 02:00:07 +00003671 rc = 1;
drh75897232000-05-29 14:26:00 +00003672 }
3673 }else
3674
drhae5e4452007-05-03 17:18:36 +00003675#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003676 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003677 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003678 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3679 iotrace = 0;
3680 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003681 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003682 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003683 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003684 iotrace = stdout;
3685 }else{
3686 iotrace = fopen(azArg[1], "w");
3687 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003688 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003689 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003690 rc = 1;
drhb0603412007-02-28 04:47:26 +00003691 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003692 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003693 }
3694 }
3695 }else
drhae5e4452007-05-03 17:18:36 +00003696#endif
drh1a513372015-05-02 17:40:23 +00003697 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3698 static const struct {
3699 const char *zLimitName; /* Name of a limit */
3700 int limitCode; /* Integer code for that limit */
3701 } aLimit[] = {
3702 { "length", SQLITE_LIMIT_LENGTH },
3703 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3704 { "column", SQLITE_LIMIT_COLUMN },
3705 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3706 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3707 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3708 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3709 { "attached", SQLITE_LIMIT_ATTACHED },
3710 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3711 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3712 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3713 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3714 };
3715 int i, n2;
3716 open_db(p, 0);
3717 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003718 for(i=0; i<ArraySize(aLimit); i++){
mistachkin1fe36bb2016-04-04 02:16:44 +00003719 printf("%20s %d\n", aLimit[i].zLimitName,
drh1a513372015-05-02 17:40:23 +00003720 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3721 }
3722 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003723 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00003724 rc = 1;
3725 goto meta_command_exit;
3726 }else{
3727 int iLimit = -1;
3728 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003729 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003730 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3731 if( iLimit<0 ){
3732 iLimit = i;
3733 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003734 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00003735 rc = 1;
3736 goto meta_command_exit;
3737 }
3738 }
3739 }
3740 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003741 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00003742 "enter \".limits\" with no arguments for a list.\n",
3743 azArg[1]);
3744 rc = 1;
3745 goto meta_command_exit;
3746 }
3747 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003748 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3749 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003750 }
3751 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3752 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3753 }
3754 }else
drhb0603412007-02-28 04:47:26 +00003755
drh70df4fe2006-06-13 15:12:21 +00003756#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003757 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003758 const char *zFile, *zProc;
3759 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003760 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003761 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00003762 rc = 1;
3763 goto meta_command_exit;
3764 }
drh1e397f82006-06-08 15:28:43 +00003765 zFile = azArg[1];
3766 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003767 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003768 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3769 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003770 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003771 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003772 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003773 }
3774 }else
drh70df4fe2006-06-13 15:12:21 +00003775#endif
drh1e397f82006-06-08 15:28:43 +00003776
drhc2ce0be2014-05-29 12:36:14 +00003777 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3778 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003779 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003780 rc = 1;
3781 }else{
3782 const char *zFile = azArg[1];
3783 output_file_close(p->pLog);
3784 p->pLog = output_file_open(zFile);
3785 }
drh127f9d72010-02-23 01:47:00 +00003786 }else
3787
drhc2ce0be2014-05-29 12:36:14 +00003788 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3789 const char *zMode = nArg>=2 ? azArg[1] : "";
3790 int n2 = (int)strlen(zMode);
3791 int c2 = zMode[0];
3792 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003793 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003794 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003795 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003796 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003797 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003798 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003799 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003800 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003801 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003802 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003803 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003804 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003805 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003806 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003807 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003808 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003809 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003810 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003811 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003812 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003813 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3814 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003815 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3816 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003817 }else {
mistachkinaae280e2015-12-31 19:06:24 +00003818 raw_printf(stderr, "Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003819 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003820 rc = 1;
drh75897232000-05-29 14:26:00 +00003821 }
drh700c2522016-02-09 18:39:25 +00003822 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00003823 }else
3824
drhc2ce0be2014-05-29 12:36:14 +00003825 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3826 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003827 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3828 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003829 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003830 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003831 rc = 1;
3832 }
3833 }else
3834
drh05782482013-10-24 15:20:20 +00003835 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
3836 sqlite3 *savedDb = p->db;
3837 const char *zSavedFilename = p->zDbFilename;
3838 char *zNewFilename = 0;
3839 p->db = 0;
drhbbe031f2015-06-17 17:08:22 +00003840 if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
3841 p->zDbFilename = zNewFilename;
drh05782482013-10-24 15:20:20 +00003842 open_db(p, 1);
3843 if( p->db!=0 ){
drhe6229612014-08-18 15:08:26 +00003844 session_close_all(p);
drh05782482013-10-24 15:20:20 +00003845 sqlite3_close(savedDb);
3846 sqlite3_free(p->zFreeOnClose);
3847 p->zFreeOnClose = zNewFilename;
3848 }else{
3849 sqlite3_free(zNewFilename);
3850 p->db = savedDb;
3851 p->zDbFilename = zSavedFilename;
3852 }
3853 }else
3854
drhc2ce0be2014-05-29 12:36:14 +00003855 if( c=='o'
3856 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
3857 ){
3858 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
3859 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003860 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00003861 rc = 1;
3862 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00003863 }
drhc2ce0be2014-05-29 12:36:14 +00003864 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
3865 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003866 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003867 rc = 1;
3868 goto meta_command_exit;
3869 }
3870 p->outCount = 2;
3871 }else{
3872 p->outCount = 0;
3873 }
3874 output_reset(p);
3875 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003876#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003877 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003878 rc = 1;
3879 p->out = stdout;
3880#else
drhc2ce0be2014-05-29 12:36:14 +00003881 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00003882 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003883 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00003884 p->out = stdout;
3885 rc = 1;
3886 }else{
drhc2ce0be2014-05-29 12:36:14 +00003887 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00003888 }
drh8cd5b252015-03-02 22:06:43 +00003889#endif
drh75897232000-05-29 14:26:00 +00003890 }else{
drhc2ce0be2014-05-29 12:36:14 +00003891 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00003892 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00003893 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003894 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00003895 }
drh75897232000-05-29 14:26:00 +00003896 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00003897 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003898 } else {
drhc2ce0be2014-05-29 12:36:14 +00003899 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00003900 }
3901 }
3902 }else
3903
drh078b1fd2012-09-21 13:40:02 +00003904 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
3905 int i;
3906 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00003907 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00003908 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00003909 }
mistachkinaae280e2015-12-31 19:06:24 +00003910 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00003911 }else
3912
drhc2ce0be2014-05-29 12:36:14 +00003913 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00003914 if( nArg >= 2) {
3915 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
3916 }
3917 if( nArg >= 3) {
3918 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
3919 }
3920 }else
3921
drhc2ce0be2014-05-29 12:36:14 +00003922 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00003923 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00003924 }else
3925
drhc2ce0be2014-05-29 12:36:14 +00003926 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
3927 FILE *alt;
3928 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003929 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003930 rc = 1;
3931 goto meta_command_exit;
3932 }
3933 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00003934 if( alt==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003935 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
shane9bd1b442009-10-23 01:27:39 +00003936 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00003937 }else{
shane9bd1b442009-10-23 01:27:39 +00003938 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00003939 fclose(alt);
3940 }
3941 }else
3942
drhc2ce0be2014-05-29 12:36:14 +00003943 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00003944 const char *zSrcFile;
3945 const char *zDb;
3946 sqlite3 *pSrc;
3947 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00003948 int nTimeout = 0;
3949
drh9ff849f2009-02-04 20:55:57 +00003950 if( nArg==2 ){
3951 zSrcFile = azArg[1];
3952 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00003953 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00003954 zSrcFile = azArg[2];
3955 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00003956 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003957 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00003958 rc = 1;
3959 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00003960 }
3961 rc = sqlite3_open(zSrcFile, &pSrc);
3962 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003963 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00003964 sqlite3_close(pSrc);
3965 return 1;
3966 }
drh05782482013-10-24 15:20:20 +00003967 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003968 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
3969 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003970 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00003971 sqlite3_close(pSrc);
3972 return 1;
3973 }
drhdc2c4912009-02-04 22:46:47 +00003974 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
3975 || rc==SQLITE_BUSY ){
3976 if( rc==SQLITE_BUSY ){
3977 if( nTimeout++ >= 3 ) break;
3978 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00003979 }
3980 }
3981 sqlite3_backup_finish(pBackup);
3982 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003983 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00003984 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00003985 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00003986 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003987 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003988 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00003989 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003990 }
3991 sqlite3_close(pSrc);
3992 }else
3993
dan8d1edb92014-11-05 09:07:28 +00003994
3995 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
3996 if( nArg==2 ){
3997 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00003998#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00003999 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00004000#endif
dan8d1edb92014-11-05 09:07:28 +00004001 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004002 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00004003 rc = 1;
4004 }
4005 }else
4006
drhc2ce0be2014-05-29 12:36:14 +00004007 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00004008 ShellState data;
drh75897232000-05-29 14:26:00 +00004009 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00004010 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00004011 memcpy(&data, p, sizeof(data));
4012 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00004013 data.cMode = data.mode = MODE_Semi;
drh4926fec2016-04-13 15:33:42 +00004014 if( nArg>=2 && optionMatch(azArg[1], "indent") ){
4015 data.cMode = data.mode = MODE_Pretty;
4016 nArg--;
4017 if( nArg==2 ) azArg[1] = azArg[2];
4018 }
4019 if( nArg==2 && azArg[1][0]!='-' ){
drhc8d74412004-08-31 23:41:26 +00004020 int i;
drhf0693c82011-10-11 20:41:54 +00004021 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00004022 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00004023 char *new_argv[2], *new_colv[2];
4024 new_argv[0] = "CREATE TABLE sqlite_master (\n"
4025 " type text,\n"
4026 " name text,\n"
4027 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00004028 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00004029 " sql text\n"
4030 ")";
4031 new_argv[1] = 0;
4032 new_colv[0] = "sql";
4033 new_colv[1] = 0;
4034 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004035 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00004036 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00004037 char *new_argv[2], *new_colv[2];
4038 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
4039 " type text,\n"
4040 " name text,\n"
4041 " tbl_name text,\n"
4042 " rootpage integer,\n"
4043 " sql text\n"
4044 ")";
4045 new_argv[1] = 0;
4046 new_colv[0] = "sql";
4047 new_colv[1] = 0;
4048 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004049 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00004050 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00004051 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00004052 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004053 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004054 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004055 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004056 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00004057 "WHERE lower(tbl_name) LIKE shellstatic()"
4058 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00004059 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00004060 callback, &data, &zErrMsg);
4061 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00004062 }
drhc2ce0be2014-05-29 12:36:14 +00004063 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00004064 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004065 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004066 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004067 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004068 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00004069 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00004070 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00004071 callback, &data, &zErrMsg
4072 );
drhc2ce0be2014-05-29 12:36:14 +00004073 }else{
drh4926fec2016-04-13 15:33:42 +00004074 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00004075 rc = 1;
4076 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004077 }
drh75897232000-05-29 14:26:00 +00004078 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00004079 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004080 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00004081 rc = 1;
4082 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004083 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00004084 rc = 1;
4085 }else{
4086 rc = 0;
drh75897232000-05-29 14:26:00 +00004087 }
4088 }else
4089
drhabd4c722014-09-20 18:18:33 +00004090#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
4091 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
drh1d9be4f2015-01-22 11:29:25 +00004092 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00004093 }else
4094#endif
4095
drhe6229612014-08-18 15:08:26 +00004096#if defined(SQLITE_ENABLE_SESSION)
4097 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
4098 OpenSession *pSession = &p->aSession[0];
4099 char **azCmd = &azArg[1];
4100 int iSes = 0;
4101 int nCmd = nArg - 1;
4102 int i;
4103 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00004104 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00004105 if( nArg>=3 ){
4106 for(iSes=0; iSes<p->nSession; iSes++){
4107 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
4108 }
4109 if( iSes<p->nSession ){
4110 pSession = &p->aSession[iSes];
4111 azCmd++;
4112 nCmd--;
4113 }else{
4114 pSession = &p->aSession[0];
4115 iSes = 0;
4116 }
4117 }
4118
drh3a67b042014-08-18 17:56:31 +00004119 /* .session attach TABLE
4120 ** Invoke the sqlite3session_attach() interface to attach a particular
4121 ** table so that it is never filtered.
4122 */
4123 if( strcmp(azCmd[0],"attach")==0 ){
4124 if( nCmd!=2 ) goto session_syntax_error;
4125 if( pSession->p==0 ){
4126 session_not_open:
mistachkin899c5c92016-04-03 20:50:02 +00004127 raw_printf(stderr, "ERROR: No sessions are open\n");
drh3a67b042014-08-18 17:56:31 +00004128 }else{
4129 rc = sqlite3session_attach(pSession->p, azCmd[1]);
4130 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004131 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004132 rc = 0;
4133 }
4134 }
4135 }else
4136
4137 /* .session changeset FILE
4138 ** .session patchset FILE
4139 ** Write a changeset or patchset into a file. The file is overwritten.
4140 */
4141 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
4142 FILE *out = 0;
4143 if( nCmd!=2 ) goto session_syntax_error;
4144 if( pSession->p==0 ) goto session_not_open;
4145 out = fopen(azCmd[1], "wb");
4146 if( out==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004147 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
drh3a67b042014-08-18 17:56:31 +00004148 }else{
4149 int szChng;
4150 void *pChng;
4151 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00004152 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00004153 }else{
drh2967e0c2014-08-19 00:26:17 +00004154 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
4155 }
4156 if( rc ){
4157 printf("Error: error code %d\n", rc);
4158 rc = 0;
drh3a67b042014-08-18 17:56:31 +00004159 }
mistachkin1fe36bb2016-04-04 02:16:44 +00004160 if( pChng
drh3a67b042014-08-18 17:56:31 +00004161 && fwrite(pChng, szChng, 1, out)!=1 ){
mistachkin899c5c92016-04-03 20:50:02 +00004162 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
drh3a67b042014-08-18 17:56:31 +00004163 szChng);
4164 }
4165 sqlite3_free(pChng);
4166 fclose(out);
4167 }
4168 }else
4169
drhe6229612014-08-18 15:08:26 +00004170 /* .session close
4171 ** Close the identified session
4172 */
4173 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00004174 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00004175 if( p->nSession ){
4176 session_close(pSession);
4177 p->aSession[iSes] = p->aSession[--p->nSession];
4178 }
4179 }else
4180
drh03168ca2014-08-18 20:01:31 +00004181 /* .session enable ?BOOLEAN?
4182 ** Query or set the enable flag
4183 */
4184 if( strcmp(azCmd[0], "enable")==0 ){
4185 int ii;
4186 if( nCmd>2 ) goto session_syntax_error;
4187 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4188 if( p->nSession ){
4189 ii = sqlite3session_enable(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004190 utf8_printf(p->out, "session %s enable flag = %d\n",
4191 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004192 }
4193 }else
4194
4195 /* .session filter GLOB ....
4196 ** Set a list of GLOB patterns of table names to be excluded.
4197 */
4198 if( strcmp(azCmd[0], "filter")==0 ){
4199 int ii, nByte;
4200 if( nCmd<2 ) goto session_syntax_error;
4201 if( p->nSession ){
4202 for(ii=0; ii<pSession->nFilter; ii++){
4203 sqlite3_free(pSession->azFilter[ii]);
4204 }
4205 sqlite3_free(pSession->azFilter);
4206 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
4207 pSession->azFilter = sqlite3_malloc( nByte );
4208 if( pSession->azFilter==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004209 raw_printf(stderr, "Error: out or memory\n");
drh03168ca2014-08-18 20:01:31 +00004210 exit(1);
4211 }
4212 for(ii=1; ii<nCmd; ii++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004213 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
drh03168ca2014-08-18 20:01:31 +00004214 }
4215 pSession->nFilter = ii-1;
4216 }
4217 }else
4218
4219 /* .session indirect ?BOOLEAN?
4220 ** Query or set the indirect flag
4221 */
4222 if( strcmp(azCmd[0], "indirect")==0 ){
4223 int ii;
4224 if( nCmd>2 ) goto session_syntax_error;
4225 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4226 if( p->nSession ){
4227 ii = sqlite3session_indirect(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004228 utf8_printf(p->out, "session %s indirect flag = %d\n",
4229 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004230 }
4231 }else
4232
4233 /* .session isempty
4234 ** Determine if the session is empty
4235 */
4236 if( strcmp(azCmd[0], "isempty")==0 ){
4237 int ii;
4238 if( nCmd!=1 ) goto session_syntax_error;
4239 if( p->nSession ){
4240 ii = sqlite3session_isempty(pSession->p);
mistachkin899c5c92016-04-03 20:50:02 +00004241 utf8_printf(p->out, "session %s isempty flag = %d\n",
4242 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004243 }
4244 }else
4245
drhe6229612014-08-18 15:08:26 +00004246 /* .session list
4247 ** List all currently open sessions
4248 */
4249 if( strcmp(azCmd[0],"list")==0 ){
4250 for(i=0; i<p->nSession; i++){
mistachkin899c5c92016-04-03 20:50:02 +00004251 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
drhe6229612014-08-18 15:08:26 +00004252 }
4253 }else
4254
4255 /* .session open DB NAME
4256 ** Open a new session called NAME on the attached database DB.
4257 ** DB is normally "main".
4258 */
4259 if( strcmp(azCmd[0],"open")==0 ){
4260 char *zName;
4261 if( nCmd!=3 ) goto session_syntax_error;
4262 zName = azCmd[2];
4263 if( zName[0]==0 ) goto session_syntax_error;
4264 for(i=0; i<p->nSession; i++){
4265 if( strcmp(p->aSession[i].zName,zName)==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004266 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
drhe6229612014-08-18 15:08:26 +00004267 goto meta_command_exit;
4268 }
4269 }
4270 if( p->nSession>=ArraySize(p->aSession) ){
mistachkin899c5c92016-04-03 20:50:02 +00004271 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
drhe6229612014-08-18 15:08:26 +00004272 goto meta_command_exit;
4273 }
4274 pSession = &p->aSession[p->nSession];
4275 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
4276 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004277 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004278 rc = 0;
drhe6229612014-08-18 15:08:26 +00004279 goto meta_command_exit;
4280 }
drh03168ca2014-08-18 20:01:31 +00004281 pSession->nFilter = 0;
4282 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00004283 p->nSession++;
4284 pSession->zName = sqlite3_mprintf("%s", zName);
4285 }else
4286 /* If no command name matches, show a syntax error */
4287 session_syntax_error:
4288 session_help(p);
4289 }else
4290#endif
4291
drh340f5822013-06-27 13:01:21 +00004292#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00004293 /* Undocumented commands for internal testing. Subject to change
4294 ** without notice. */
4295 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
4296 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
4297 int i, v;
4298 for(i=1; i<nArg; i++){
4299 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00004300 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00004301 }
4302 }
4303 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
4304 int i; sqlite3_int64 v;
4305 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00004306 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00004307 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00004308 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00004309 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00004310 }
4311 }
4312 }else
drh340f5822013-06-27 13:01:21 +00004313#endif
drh348d19c2013-06-03 12:47:43 +00004314
drhc2ce0be2014-05-29 12:36:14 +00004315 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00004316 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004317 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00004318 rc = 1;
4319 }
drh6976c212014-07-24 12:09:47 +00004320 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004321 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00004322 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00004323 }
4324 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00004325 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
4326 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00004327 }
drh75897232000-05-29 14:26:00 +00004328 }else
4329
drh62cdde52014-05-28 20:22:28 +00004330 if( c=='s'
4331 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00004332 ){
4333 char *zCmd;
drh54027102014-08-06 14:36:53 +00004334 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00004335 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004336 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00004337 rc = 1;
4338 goto meta_command_exit;
4339 }
drhdcb3e3d2014-05-29 03:17:29 +00004340 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00004341 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00004342 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
4343 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00004344 }
drh54027102014-08-06 14:36:53 +00004345 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00004346 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00004347 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00004348 }else
4349
drhc2ce0be2014-05-29 12:36:14 +00004350 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drheacd29d2016-04-15 15:03:27 +00004351 static const char *azBool[] = { "off", "on", "full", "unk" };
persicom7e2dfdd2002-04-18 02:46:52 +00004352 int i;
drhc2ce0be2014-05-29 12:36:14 +00004353 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00004354 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00004355 rc = 1;
4356 goto meta_command_exit;
4357 }
drheacd29d2016-04-15 15:03:27 +00004358 utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]);
4359 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
drh700c2522016-02-09 18:39:25 +00004360 utf8_printf(p->out, "%12.12s: %s\n","explain",
4361 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
drheacd29d2016-04-15 15:03:27 +00004362 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004363 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
4364 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00004365 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00004366 raw_printf(p->out, "\n");
4367 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00004368 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00004369 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004370 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004371 raw_printf(p->out, "\n");
4372 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004373 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004374 raw_printf(p->out, "\n");
drheacd29d2016-04-15 15:03:27 +00004375 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004376 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00004377 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00004378 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00004379 }
mistachkinaae280e2015-12-31 19:06:24 +00004380 raw_printf(p->out, "\n");
persicom7e2dfdd2002-04-18 02:46:52 +00004381 }else
4382
drhc2ce0be2014-05-29 12:36:14 +00004383 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
4384 if( nArg==2 ){
4385 p->statsOn = booleanValue(azArg[1]);
drh34784902016-02-27 17:12:36 +00004386 }else if( nArg==1 ){
4387 display_stats(p->db, p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004388 }else{
drh34784902016-02-27 17:12:36 +00004389 raw_printf(stderr, "Usage: .stats ?on|off?\n");
drhc2ce0be2014-05-29 12:36:14 +00004390 rc = 1;
4391 }
shaneh642d8b82010-07-28 16:05:34 +00004392 }else
4393
drhc2ce0be2014-05-29 12:36:14 +00004394 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00004395 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00004396 char **azResult;
drh98781232012-04-23 12:38:05 +00004397 int nRow, nAlloc;
4398 char *zSql = 0;
4399 int ii;
drh05782482013-10-24 15:20:20 +00004400 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00004401 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00004402 if( rc ) return shellDatabaseError(p->db);
4403
4404 /* Create an SQL statement to query for the list of tables in the
4405 ** main and all attached databases where the table name matches the
4406 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00004407 zSql = sqlite3_mprintf(
4408 "SELECT name FROM sqlite_master"
4409 " WHERE type IN ('table','view')"
4410 " AND name NOT LIKE 'sqlite_%%'"
4411 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00004412 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00004413 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
4414 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
4415 if( strcmp(zDbName,"temp")==0 ){
4416 zSql = sqlite3_mprintf(
4417 "%z UNION ALL "
4418 "SELECT 'temp.' || name FROM sqlite_temp_master"
4419 " WHERE type IN ('table','view')"
4420 " AND name NOT LIKE 'sqlite_%%'"
4421 " AND name LIKE ?1", zSql);
4422 }else{
4423 zSql = sqlite3_mprintf(
4424 "%z UNION ALL "
4425 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4426 " WHERE type IN ('table','view')"
4427 " AND name NOT LIKE 'sqlite_%%'"
4428 " AND name LIKE ?1", zSql, zDbName, zDbName);
4429 }
drha50da102000-08-08 20:19:09 +00004430 }
dand95bb392015-09-30 11:19:05 +00004431 rc = sqlite3_finalize(pStmt);
4432 if( zSql && rc==SQLITE_OK ){
4433 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
4434 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4435 }
drh98781232012-04-23 12:38:05 +00004436 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00004437 if( !zSql ) return shellNomemError();
4438 if( rc ) return shellDatabaseError(p->db);
4439
4440 /* Run the SQL statement prepared by the above block. Store the results
4441 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00004442 nRow = nAlloc = 0;
4443 azResult = 0;
4444 if( nArg>1 ){
4445 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00004446 }else{
drh98781232012-04-23 12:38:05 +00004447 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
4448 }
4449 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4450 if( nRow>=nAlloc ){
4451 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00004452 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00004453 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00004454 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00004455 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00004456 break;
4457 }
mistachkin8e189222015-04-19 21:43:16 +00004458 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00004459 azResult = azNew;
4460 }
4461 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00004462 if( 0==azResult[nRow] ){
4463 rc = shellNomemError();
4464 break;
4465 }
4466 nRow++;
drh98781232012-04-23 12:38:05 +00004467 }
dand95bb392015-09-30 11:19:05 +00004468 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
4469 rc = shellDatabaseError(p->db);
4470 }
4471
4472 /* Pretty-print the contents of array azResult[] to the output */
4473 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00004474 int len, maxlen = 0;
4475 int i, j;
4476 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00004477 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00004478 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00004479 if( len>maxlen ) maxlen = len;
4480 }
4481 nPrintCol = 80/(maxlen+2);
4482 if( nPrintCol<1 ) nPrintCol = 1;
4483 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
4484 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00004485 for(j=i; j<nRow; j+=nPrintRow){
4486 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00004487 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
4488 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00004489 }
mistachkinaae280e2015-12-31 19:06:24 +00004490 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00004491 }
4492 }
dand95bb392015-09-30 11:19:05 +00004493
drh98781232012-04-23 12:38:05 +00004494 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
4495 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00004496 }else
4497
shaneh96887e12011-02-10 21:08:58 +00004498 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00004499 static const struct {
4500 const char *zCtrlName; /* Name of a test-control option */
4501 int ctrlCode; /* Integer code for that option */
4502 } aCtrl[] = {
4503 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
4504 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
4505 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
4506 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
4507 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
4508 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
4509 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
4510 { "assert", SQLITE_TESTCTRL_ASSERT },
4511 { "always", SQLITE_TESTCTRL_ALWAYS },
4512 { "reserve", SQLITE_TESTCTRL_RESERVE },
4513 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
4514 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00004515 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00004516 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00004517 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00004518 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00004519 };
shaneh96887e12011-02-10 21:08:58 +00004520 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00004521 int rc2 = 0;
4522 int i, n2;
drh05782482013-10-24 15:20:20 +00004523 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00004524
drhd416fe72011-03-17 16:45:50 +00004525 /* convert testctrl text option to value. allow any unique prefix
4526 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00004527 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00004528 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00004529 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00004530 if( testctrl<0 ){
4531 testctrl = aCtrl[i].ctrlCode;
4532 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004533 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00004534 testctrl = -1;
4535 break;
4536 }
4537 }
4538 }
drh348d19c2013-06-03 12:47:43 +00004539 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004540 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00004541 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004542 }else{
4543 switch(testctrl){
4544
4545 /* sqlite3_test_control(int, db, int) */
4546 case SQLITE_TESTCTRL_OPTIMIZATIONS:
mistachkin1fe36bb2016-04-04 02:16:44 +00004547 case SQLITE_TESTCTRL_RESERVE:
shaneh96887e12011-02-10 21:08:58 +00004548 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004549 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00004550 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004551 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004552 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004553 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004554 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004555 }
4556 break;
4557
4558 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004559 case SQLITE_TESTCTRL_PRNG_SAVE:
4560 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004561 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004562 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004563 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00004564 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00004565 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004566 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004567 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
4568 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004569 }
4570 break;
4571
4572 /* sqlite3_test_control(int, uint) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004573 case SQLITE_TESTCTRL_PENDING_BYTE:
shaneh96887e12011-02-10 21:08:58 +00004574 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004575 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004576 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004577 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004578 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004579 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00004580 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004581 }
4582 break;
mistachkin1fe36bb2016-04-04 02:16:44 +00004583
shaneh96887e12011-02-10 21:08:58 +00004584 /* sqlite3_test_control(int, int) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004585 case SQLITE_TESTCTRL_ASSERT:
4586 case SQLITE_TESTCTRL_ALWAYS:
4587 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004588 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004589 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004590 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004591 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004592 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004593 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004594 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004595 }
4596 break;
4597
4598 /* sqlite3_test_control(int, char *) */
4599#ifdef SQLITE_N_KEYWORD
mistachkin1fe36bb2016-04-04 02:16:44 +00004600 case SQLITE_TESTCTRL_ISKEYWORD:
shaneh96887e12011-02-10 21:08:58 +00004601 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004602 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004603 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004604 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004605 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004606 utf8_printf(stderr,
4607 "Error: testctrl %s takes a single char * option\n",
4608 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004609 }
4610 break;
4611#endif
4612
drh1ffede82015-01-30 20:59:27 +00004613 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004614 if( nArg==5 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004615 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004616 azArg[2],
drh8964b342015-01-29 17:54:52 +00004617 integerValue(azArg[3]),
4618 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00004619 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004620 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004621 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004622 }
4623 break;
4624
mistachkin1fe36bb2016-04-04 02:16:44 +00004625 case SQLITE_TESTCTRL_BITVEC_TEST:
4626 case SQLITE_TESTCTRL_FAULT_INSTALL:
4627 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4628 case SQLITE_TESTCTRL_SCRATCHMALLOC:
shaneh96887e12011-02-10 21:08:58 +00004629 default:
mistachkinaae280e2015-12-31 19:06:24 +00004630 utf8_printf(stderr,
4631 "Error: CLI support for testctrl %s not implemented\n",
4632 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004633 break;
4634 }
4635 }
4636 }else
4637
drhc2ce0be2014-05-29 12:36:14 +00004638 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004639 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004640 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004641 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004642
drhc2ce0be2014-05-29 12:36:14 +00004643 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4644 if( nArg==2 ){
4645 enableTimer = booleanValue(azArg[1]);
4646 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00004647 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00004648 enableTimer = 0;
4649 }
4650 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004651 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004652 rc = 1;
4653 }
shanehe2aa9d72009-11-06 17:20:17 +00004654 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004655
drhc2ce0be2014-05-29 12:36:14 +00004656 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004657 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004658 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004659 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004660 rc = 1;
4661 goto meta_command_exit;
4662 }
drh657b4a82015-03-19 13:30:41 +00004663 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004664 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004665#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004666 if( p->traceOut==0 ){
drh4b363a52016-07-23 20:27:41 +00004667 sqlite3_trace_v2(p->db, 0, 0, 0);
drh42f64e52012-04-04 16:56:23 +00004668 }else{
drh4b363a52016-07-23 20:27:41 +00004669 sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004670 }
4671#endif
4672 }else
4673
drhf442e332014-09-10 19:01:14 +00004674#if SQLITE_USER_AUTHENTICATION
4675 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4676 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004677 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00004678 rc = 1;
4679 goto meta_command_exit;
4680 }
drh7883ecf2014-09-11 16:19:31 +00004681 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004682 if( strcmp(azArg[1],"login")==0 ){
4683 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00004684 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00004685 rc = 1;
4686 goto meta_command_exit;
4687 }
drhd39c40f2014-09-11 00:27:53 +00004688 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4689 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004690 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004691 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00004692 rc = 1;
4693 }
4694 }else if( strcmp(azArg[1],"add")==0 ){
4695 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004696 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004697 rc = 1;
4698 goto meta_command_exit;
4699 }
drhd39c40f2014-09-11 00:27:53 +00004700 rc = sqlite3_user_add(p->db, azArg[2],
4701 azArg[3], (int)strlen(azArg[3]),
4702 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004703 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004704 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004705 rc = 1;
4706 }
4707 }else if( strcmp(azArg[1],"edit")==0 ){
4708 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004709 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004710 rc = 1;
4711 goto meta_command_exit;
4712 }
drhd39c40f2014-09-11 00:27:53 +00004713 rc = sqlite3_user_change(p->db, azArg[2],
4714 azArg[3], (int)strlen(azArg[3]),
4715 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004716 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004717 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004718 rc = 1;
4719 }
4720 }else if( strcmp(azArg[1],"delete")==0 ){
4721 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004722 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00004723 rc = 1;
4724 goto meta_command_exit;
4725 }
4726 rc = sqlite3_user_delete(p->db, azArg[2]);
4727 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004728 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004729 rc = 1;
4730 }
4731 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004732 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00004733 rc = 1;
4734 goto meta_command_exit;
mistachkin1fe36bb2016-04-04 02:16:44 +00004735 }
drhf442e332014-09-10 19:01:14 +00004736 }else
4737#endif /* SQLITE_USER_AUTHENTICATION */
4738
drh9fd301b2011-06-03 13:28:22 +00004739 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004740 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004741 sqlite3_libversion(), sqlite3_sourceid());
4742 }else
4743
drh790f2872015-11-28 18:06:36 +00004744 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
4745 const char *zDbName = nArg==2 ? azArg[1] : "main";
4746 sqlite3_vfs *pVfs;
4747 if( p->db ){
4748 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
4749 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00004750 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
4751 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4752 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4753 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00004754 }
4755 }
4756 }else
4757
drhb19e7352016-01-12 19:37:20 +00004758 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
4759 sqlite3_vfs *pVfs;
4760 sqlite3_vfs *pCurrent = 0;
4761 if( p->db ){
4762 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
4763 }
4764 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
4765 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
4766 pVfs==pCurrent ? " <--- CURRENT" : "");
4767 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4768 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4769 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
4770 if( pVfs->pNext ){
4771 raw_printf(p->out, "-----------------------------------\n");
4772 }
4773 }
4774 }else
4775
drhde60fc22011-12-14 17:53:36 +00004776 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4777 const char *zDbName = nArg==2 ? azArg[1] : "main";
4778 char *zVfsName = 0;
4779 if( p->db ){
4780 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4781 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00004782 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004783 sqlite3_free(zVfsName);
4784 }
4785 }
4786 }else
4787
drhcef4fc82012-09-21 22:50:45 +00004788#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4789 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004790 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004791 }else
4792#endif
4793
drhc2ce0be2014-05-29 12:36:14 +00004794 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004795 int j;
drh43617e92006-03-06 20:55:46 +00004796 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004797 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004798 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004799 }
4800 }else
4801
4802 {
mistachkinaae280e2015-12-31 19:06:24 +00004803 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00004804 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00004805 rc = 1;
drh75897232000-05-29 14:26:00 +00004806 }
drh67505e72002-04-19 12:34:06 +00004807
drhc2ce0be2014-05-29 12:36:14 +00004808meta_command_exit:
4809 if( p->outCount ){
4810 p->outCount--;
4811 if( p->outCount==0 ) output_reset(p);
4812 }
drh67505e72002-04-19 12:34:06 +00004813 return rc;
drh75897232000-05-29 14:26:00 +00004814}
4815
drh67505e72002-04-19 12:34:06 +00004816/*
drh91a66392007-09-07 01:12:32 +00004817** Return TRUE if a semicolon occurs anywhere in the first N characters
4818** of string z[].
drh324ccef2003-02-05 14:06:20 +00004819*/
drh9f099fd2013-08-06 14:01:46 +00004820static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00004821 int i;
4822 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
4823 return 0;
drh324ccef2003-02-05 14:06:20 +00004824}
4825
4826/*
drh70c7a4b2003-04-26 03:03:06 +00004827** Test to see if a line consists entirely of whitespace.
4828*/
4829static int _all_whitespace(const char *z){
4830 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00004831 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00004832 if( *z=='/' && z[1]=='*' ){
4833 z += 2;
4834 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
4835 if( *z==0 ) return 0;
4836 z++;
4837 continue;
4838 }
4839 if( *z=='-' && z[1]=='-' ){
4840 z += 2;
4841 while( *z && *z!='\n' ){ z++; }
4842 if( *z==0 ) return 1;
4843 continue;
4844 }
4845 return 0;
4846 }
4847 return 1;
4848}
4849
4850/*
drha9b17162003-04-29 18:01:28 +00004851** Return TRUE if the line typed in is an SQL command terminator other
4852** than a semi-colon. The SQL Server style "go" command is understood
4853** as is the Oracle "/".
4854*/
drh9f099fd2013-08-06 14:01:46 +00004855static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00004856 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00004857 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
4858 return 1; /* Oracle */
4859 }
drhf0693c82011-10-11 20:41:54 +00004860 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00004861 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00004862 return 1; /* SQL Server */
4863 }
4864 return 0;
4865}
4866
4867/*
drh233a5312008-12-18 22:25:13 +00004868** Return true if zSql is a complete SQL statement. Return false if it
4869** ends in the middle of a string literal or C-style comment.
4870*/
drh9f099fd2013-08-06 14:01:46 +00004871static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00004872 int rc;
4873 if( zSql==0 ) return 1;
4874 zSql[nSql] = ';';
4875 zSql[nSql+1] = 0;
4876 rc = sqlite3_complete(zSql);
4877 zSql[nSql] = 0;
4878 return rc;
4879}
4880
4881/*
drh67505e72002-04-19 12:34:06 +00004882** Read input from *in and process it. If *in==0 then input
4883** is interactive - the user is typing it it. Otherwise, input
4884** is coming from a file or device. A prompt is issued and history
4885** is saved only if input is interactive. An interrupt signal will
4886** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00004887**
4888** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00004889*/
drhdcd87a92014-08-18 13:45:42 +00004890static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00004891 char *zLine = 0; /* A single input line */
4892 char *zSql = 0; /* Accumulated SQL text */
4893 int nLine; /* Length of current line */
4894 int nSql = 0; /* Bytes of zSql[] used */
4895 int nAlloc = 0; /* Allocated zSql[] space */
4896 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
4897 char *zErrMsg; /* Error message returned */
4898 int rc; /* Error code */
4899 int errCnt = 0; /* Number of errors seen */
4900 int lineno = 0; /* Current line number */
4901 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00004902
4903 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
4904 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00004905 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00004906 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00004907 /* End of input */
drhfc8b40f2016-09-07 10:10:18 +00004908 if( in==0 && stdin_is_interactive ) printf("\n");
drh9b8d3572012-04-21 11:33:39 +00004909 break;
drhc49f44e2006-10-26 18:15:42 +00004910 }
drh67505e72002-04-19 12:34:06 +00004911 if( seenInterrupt ){
4912 if( in!=0 ) break;
4913 seenInterrupt = 0;
4914 }
drhc28490c2006-10-26 14:25:58 +00004915 lineno++;
drh849a9d92013-12-21 15:46:06 +00004916 if( nSql==0 && _all_whitespace(zLine) ){
4917 if( p->echoOn ) printf("%s\n", zLine);
4918 continue;
4919 }
drh2af0b2d2002-02-21 02:25:02 +00004920 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00004921 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00004922 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00004923 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00004924 break;
4925 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00004926 errCnt++;
4927 }
drhdaffd0e2001-04-11 14:28:42 +00004928 continue;
4929 }
drh9f099fd2013-08-06 14:01:46 +00004930 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00004931 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00004932 }
drh9f099fd2013-08-06 14:01:46 +00004933 nLine = strlen30(zLine);
4934 if( nSql+nLine+2>=nAlloc ){
4935 nAlloc = nSql+nLine+100;
4936 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00004937 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004938 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00004939 exit(1);
4940 }
drhdaffd0e2001-04-11 14:28:42 +00004941 }
drh9f099fd2013-08-06 14:01:46 +00004942 nSqlPrior = nSql;
4943 if( nSql==0 ){
4944 int i;
4945 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00004946 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00004947 memcpy(zSql, zLine+i, nLine+1-i);
4948 startline = lineno;
4949 nSql = nLine-i;
4950 }else{
4951 zSql[nSql++] = '\n';
4952 memcpy(zSql+nSql, zLine, nLine+1);
4953 nSql += nLine;
4954 }
4955 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00004956 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00004957 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00004958 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00004959 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00004960 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00004961 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00004962 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00004963 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00004964 char zPrefix[100];
4965 if( in!=0 || !stdin_is_interactive ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004966 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00004967 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00004968 }else{
shane9bd1b442009-10-23 01:27:39 +00004969 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00004970 }
drh7f953e22002-07-13 17:33:45 +00004971 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004972 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004973 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00004974 zErrMsg = 0;
4975 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004976 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00004977 }
drhc49f44e2006-10-26 18:15:42 +00004978 errCnt++;
drhdf12f1c2015-12-07 21:46:19 +00004979 }else if( p->countChanges ){
mistachkinaae280e2015-12-31 19:06:24 +00004980 raw_printf(p->out, "changes: %3d total_changes: %d\n",
drhdf12f1c2015-12-07 21:46:19 +00004981 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
drhdaffd0e2001-04-11 14:28:42 +00004982 }
drhdaffd0e2001-04-11 14:28:42 +00004983 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00004984 if( p->outCount ){
4985 output_reset(p);
4986 p->outCount = 0;
4987 }
drh9f099fd2013-08-06 14:01:46 +00004988 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00004989 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00004990 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00004991 }
4992 }
drh9f099fd2013-08-06 14:01:46 +00004993 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00004994 if( !_all_whitespace(zSql) ){
mistachkinaae280e2015-12-31 19:06:24 +00004995 utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00004996 errCnt++;
drhd416fe72011-03-17 16:45:50 +00004997 }
drhdaffd0e2001-04-11 14:28:42 +00004998 }
drh1f9ca2c2015-08-25 16:57:52 +00004999 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00005000 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00005001 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00005002}
5003
drh67505e72002-04-19 12:34:06 +00005004/*
5005** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00005006** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00005007*/
5008static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00005009 static char *home_dir = NULL;
5010 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00005011
drh4ace5362014-11-10 14:42:28 +00005012#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
5013 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00005014 {
5015 struct passwd *pwent;
5016 uid_t uid = getuid();
5017 if( (pwent=getpwuid(uid)) != NULL) {
5018 home_dir = pwent->pw_dir;
5019 }
drh67505e72002-04-19 12:34:06 +00005020 }
5021#endif
5022
chw65d3c132007-11-12 21:09:10 +00005023#if defined(_WIN32_WCE)
5024 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
5025 */
drh85e72432012-04-11 11:38:53 +00005026 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00005027#else
5028
drh83905c92012-06-21 13:00:37 +00005029#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00005030 if (!home_dir) {
5031 home_dir = getenv("USERPROFILE");
5032 }
5033#endif
5034
drh67505e72002-04-19 12:34:06 +00005035 if (!home_dir) {
5036 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00005037 }
5038
drh83905c92012-06-21 13:00:37 +00005039#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00005040 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00005041 char *zDrive, *zPath;
5042 int n;
5043 zDrive = getenv("HOMEDRIVE");
5044 zPath = getenv("HOMEPATH");
5045 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00005046 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00005047 home_dir = malloc( n );
5048 if( home_dir==0 ) return 0;
5049 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
5050 return home_dir;
5051 }
5052 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00005053 }
5054#endif
5055
chw65d3c132007-11-12 21:09:10 +00005056#endif /* !_WIN32_WCE */
5057
drh67505e72002-04-19 12:34:06 +00005058 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00005059 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00005060 char *z = malloc( n );
5061 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00005062 home_dir = z;
5063 }
drhe98d4fa2002-04-21 19:06:22 +00005064
drh67505e72002-04-19 12:34:06 +00005065 return home_dir;
5066}
5067
5068/*
5069** Read input from the file given by sqliterc_override. Or if that
5070** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00005071**
5072** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00005073*/
drh534f4df2015-02-28 14:03:35 +00005074static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00005075 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00005076 const char *sqliterc_override /* Name of config file. NULL to use default */
5077){
persicom7e2dfdd2002-04-18 02:46:52 +00005078 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00005079 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00005080 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00005081 FILE *in = NULL;
5082
5083 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00005084 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00005085 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005086 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00005087 " cannot read ~/.sqliterc\n");
5088 return;
drhe98d4fa2002-04-21 19:06:22 +00005089 }
drh2f3de322012-06-27 16:41:31 +00005090 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00005091 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
5092 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00005093 }
drha1f9b5e2004-02-14 16:31:02 +00005094 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00005095 if( in ){
drhc28490c2006-10-26 14:25:58 +00005096 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00005097 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00005098 }
drh534f4df2015-02-28 14:03:35 +00005099 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00005100 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00005101 }
drh85e72432012-04-11 11:38:53 +00005102 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00005103}
5104
drh67505e72002-04-19 12:34:06 +00005105/*
drhe1e38c42003-05-04 18:30:59 +00005106** Show available command line options
5107*/
mistachkin1fe36bb2016-04-04 02:16:44 +00005108static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00005109 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00005110 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00005111 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005112 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00005113 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00005114 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00005115 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00005116 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00005117 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00005118#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
5119 " -heap SIZE Size of heap for memsys3 or memsys5\n"
5120#endif
drhcc3b4f82012-02-07 14:13:50 +00005121 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00005122 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00005123 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005124 " -line set output mode to 'line'\n"
5125 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00005126 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00005127 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00005128#ifdef SQLITE_ENABLE_MULTIPLEX
5129 " -multiplex enable the multiplexor VFS\n"
5130#endif
mistachkine0d68852014-12-11 03:12:33 +00005131 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00005132 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00005133 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
5134 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00005135 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00005136 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00005137 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00005138 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00005139#ifdef SQLITE_ENABLE_VFSTRACE
5140 " -vfstrace enable tracing of all VFS calls\n"
5141#endif
drhe1e38c42003-05-04 18:30:59 +00005142;
5143static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00005144 utf8_printf(stderr,
mistachkin1fe36bb2016-04-04 02:16:44 +00005145 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
drh80e8be92006-08-29 12:04:19 +00005146 "FILENAME is the name of an SQLite database. A new database is created\n"
5147 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00005148 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00005149 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00005150 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005151 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00005152 }
5153 exit(1);
5154}
5155
5156/*
drh67505e72002-04-19 12:34:06 +00005157** Initialize the state information in data
5158*/
drhdcd87a92014-08-18 13:45:42 +00005159static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00005160 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00005161 data->normalMode = data->cMode = data->mode = MODE_List;
5162 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00005163 memcpy(data->colSeparator,SEP_Column, 2);
5164 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00005165 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00005166 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00005167 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00005168 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00005169 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00005170 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
5171 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00005172}
5173
drh98d312f2012-10-25 15:23:14 +00005174/*
drh5c7976f2014-02-10 19:59:27 +00005175** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00005176*/
5177#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00005178static void printBold(const char *zText){
5179 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
5180 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
5181 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
5182 SetConsoleTextAttribute(out,
5183 FOREGROUND_RED|FOREGROUND_INTENSITY
5184 );
5185 printf("%s", zText);
5186 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00005187}
5188#else
drh5c7976f2014-02-10 19:59:27 +00005189static void printBold(const char *zText){
5190 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00005191}
5192#endif
5193
5194/*
drh98d312f2012-10-25 15:23:14 +00005195** Get the argument to an --option. Throw an error and die if no argument
5196** is available.
5197*/
5198static char *cmdline_option_value(int argc, char **argv, int i){
5199 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00005200 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00005201 argv[0], argv[argc-1]);
5202 exit(1);
5203 }
5204 return argv[i];
5205}
5206
mistachkin1fe36bb2016-04-04 02:16:44 +00005207#ifndef SQLITE_SHELL_IS_UTF8
5208# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
5209# define SQLITE_SHELL_IS_UTF8 (0)
5210# else
5211# define SQLITE_SHELL_IS_UTF8 (1)
5212# endif
5213#endif
5214
5215#if SQLITE_SHELL_IS_UTF8
mistachkin44723ce2015-03-21 02:22:37 +00005216int SQLITE_CDECL main(int argc, char **argv){
mistachkin1fe36bb2016-04-04 02:16:44 +00005217#else
5218int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
mistachkin1810f222016-04-04 02:33:34 +00005219 char **argv;
mistachkin1fe36bb2016-04-04 02:16:44 +00005220#endif
drh75897232000-05-29 14:26:00 +00005221 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00005222 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00005223 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00005224 int i;
drhc28490c2006-10-26 14:25:58 +00005225 int rc = 0;
drhb3735912014-02-10 16:13:42 +00005226 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00005227 int readStdin = 1;
5228 int nCmd = 0;
5229 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00005230
mistachkin1fe36bb2016-04-04 02:16:44 +00005231 setBinaryMode(stdin, 0);
5232 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
mistachkin1810f222016-04-04 02:33:34 +00005233 stdin_is_interactive = isatty(0);
5234 stdout_is_console = isatty(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005235
drh69b30ab2014-02-27 15:11:52 +00005236#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00005237 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005238 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00005239 sqlite3_sourceid(), SQLITE_SOURCE_ID);
5240 exit(1);
5241 }
drhc7181902014-02-27 15:04:13 +00005242#endif
persicom7e2dfdd2002-04-18 02:46:52 +00005243 main_init(&data);
mistachkin1fe36bb2016-04-04 02:16:44 +00005244#if !SQLITE_SHELL_IS_UTF8
5245 sqlite3_initialize();
5246 argv = sqlite3_malloc64(sizeof(argv[0])*argc);
5247 if( argv==0 ){
5248 raw_printf(stderr, "out of memory\n");
5249 exit(1);
5250 }
5251 for(i=0; i<argc; i++){
5252 argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
5253 if( argv[i]==0 ){
5254 raw_printf(stderr, "out of memory\n");
5255 exit(1);
5256 }
5257 }
5258#endif
mistachkin1810f222016-04-04 02:33:34 +00005259 assert( argc>=1 && argv && argv[0] );
mistachkin1fe36bb2016-04-04 02:16:44 +00005260 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00005261
drh44c2eb12003-04-30 11:38:26 +00005262 /* Make sure we have a valid signal handler early, before anything
5263 ** else is done.
5264 */
drh4c504392000-10-16 22:06:40 +00005265#ifdef SIGINT
5266 signal(SIGINT, interrupt_handler);
5267#endif
drh44c2eb12003-04-30 11:38:26 +00005268
drhac5649a2014-11-28 13:35:03 +00005269#ifdef SQLITE_SHELL_DBNAME_PROC
5270 {
5271 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
5272 ** of a C-function that will provide the name of the database file. Use
5273 ** this compile-time option to embed this shell program in larger
5274 ** applications. */
5275 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
5276 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
5277 warnInmemoryDb = 0;
5278 }
5279#endif
5280
drh22fbcb82004-02-01 01:22:50 +00005281 /* Do an initial pass through the command-line argument to locate
5282 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00005283 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00005284 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00005285 */
drh98d312f2012-10-25 15:23:14 +00005286 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00005287 char *z;
drhc28490c2006-10-26 14:25:58 +00005288 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005289 if( z[0]!='-' ){
5290 if( data.zDbFilename==0 ){
5291 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00005292 }else{
5293 /* Excesss arguments are interpreted as SQL (or dot-commands) and
5294 ** mean that nothing is read from stdin */
5295 readStdin = 0;
5296 nCmd++;
5297 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
5298 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005299 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00005300 exit(1);
5301 }
5302 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00005303 }
drh98d312f2012-10-25 15:23:14 +00005304 }
drhcc3b4f82012-02-07 14:13:50 +00005305 if( z[1]=='-' ) z++;
5306 if( strcmp(z,"-separator")==0
5307 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00005308 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00005309 || strcmp(z,"-cmd")==0
5310 ){
drh98d312f2012-10-25 15:23:14 +00005311 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005312 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00005313 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005314 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00005315 /* Need to check for batch mode here to so we can avoid printing
mistachkin1fe36bb2016-04-04 02:16:44 +00005316 ** informational messages (like from process_sqliterc) before
drh98d312f2012-10-25 15:23:14 +00005317 ** we do the actual processing of arguments later in a second pass.
5318 */
shanef69573d2009-10-24 02:06:14 +00005319 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00005320 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00005321#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00005322 const char *zSize;
5323 sqlite3_int64 szHeap;
5324
drh98d312f2012-10-25 15:23:14 +00005325 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00005326 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00005327 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00005328 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
drhc530b9c2016-07-25 11:27:22 +00005329#else
5330 (void)cmdline_option_value(argc, argv, ++i);
drh9c88d682010-12-17 14:03:01 +00005331#endif
drh44dec872014-08-30 15:49:25 +00005332 }else if( strcmp(z,"-scratch")==0 ){
5333 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005334 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005335 if( sz>400000 ) sz = 400000;
5336 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00005337 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005338 if( n>10 ) n = 10;
5339 if( n<1 ) n = 1;
5340 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
5341 data.shellFlgs |= SHFLG_Scratch;
5342 }else if( strcmp(z,"-pagecache")==0 ){
5343 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005344 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005345 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00005346 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005347 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00005348 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
5349 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00005350 data.shellFlgs |= SHFLG_Pagecache;
5351 }else if( strcmp(z,"-lookaside")==0 ){
5352 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005353 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005354 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005355 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005356 if( n<0 ) n = 0;
5357 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
5358 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00005359#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00005360 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00005361 extern int vfstrace_register(
5362 const char *zTraceName,
5363 const char *zOldVfsName,
5364 int (*xOut)(const char*,void*),
5365 void *pOutArg,
5366 int makeDefault
5367 );
drh2b625e22011-03-16 17:05:28 +00005368 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00005369#endif
drh6f25e892011-07-08 17:02:57 +00005370#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00005371 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00005372 extern int sqlite3_multiple_initialize(const char*,int);
5373 sqlite3_multiplex_initialize(0, 1);
5374#endif
drh7d9f3942013-04-03 01:26:54 +00005375 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00005376 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
5377 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00005378 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00005379 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00005380 if( pVfs ){
5381 sqlite3_vfs_register(pVfs, 1);
5382 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005383 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00005384 exit(1);
5385 }
drh44c2eb12003-04-30 11:38:26 +00005386 }
5387 }
drh98d312f2012-10-25 15:23:14 +00005388 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00005389#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00005390 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00005391 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00005392#else
mistachkinaae280e2015-12-31 19:06:24 +00005393 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00005394 return 1;
drh01b41712005-08-29 23:06:23 +00005395#endif
drh98d312f2012-10-25 15:23:14 +00005396 }
5397 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00005398
drh44c2eb12003-04-30 11:38:26 +00005399 /* Go ahead and open the database file if it already exists. If the
5400 ** file does not exist, delay opening it. This prevents empty database
5401 ** files from being created if a user mistypes the database name argument
5402 ** to the sqlite command-line tool.
5403 */
drhc8d74412004-08-31 23:41:26 +00005404 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00005405 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00005406 }
5407
drh22fbcb82004-02-01 01:22:50 +00005408 /* Process the initialization file if there is one. If no -init option
5409 ** is given on the command line, look for a file named ~/.sqliterc and
5410 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00005411 */
drh534f4df2015-02-28 14:03:35 +00005412 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00005413
drh22fbcb82004-02-01 01:22:50 +00005414 /* Make a second pass through the command-line argument and set
5415 ** options. This second pass is delayed until after the initialization
5416 ** file is processed so that the command-line arguments will override
5417 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00005418 */
drh98d312f2012-10-25 15:23:14 +00005419 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00005420 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005421 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00005422 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00005423 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00005424 i++;
5425 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005426 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00005427 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005428 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00005429 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005430 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00005431 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00005432 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00005433 }else if( strcmp(z,"-csv")==0 ){
5434 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00005435 memcpy(data.colSeparator,",",2);
5436 }else if( strcmp(z,"-ascii")==0 ){
5437 data.mode = MODE_Ascii;
5438 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005439 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00005440 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005441 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00005442 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00005443 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00005444 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00005445 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00005446 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00005447 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005448 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00005449 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00005450 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005451 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005452 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00005453 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005454 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00005455 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00005456 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00005457 }else if( strcmp(z,"-eqp")==0 ){
5458 data.autoEQP = 1;
drheacd29d2016-04-15 15:03:27 +00005459 }else if( strcmp(z,"-eqpfull")==0 ){
5460 data.autoEQP = 2;
shaneh642d8b82010-07-28 16:05:34 +00005461 }else if( strcmp(z,"-stats")==0 ){
5462 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00005463 }else if( strcmp(z,"-scanstats")==0 ){
5464 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00005465 }else if( strcmp(z,"-backslash")==0 ){
5466 /* Undocumented command-line option: -backslash
5467 ** Causes C-style backslash escapes to be evaluated in SQL statements
5468 ** prior to sending the SQL into SQLite. Useful for injecting
5469 ** crazy bytes in the middle of SQL statements for testing and debugging.
5470 */
5471 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00005472 }else if( strcmp(z,"-bail")==0 ){
5473 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00005474 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00005475 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00005476 return 0;
drhc28490c2006-10-26 14:25:58 +00005477 }else if( strcmp(z,"-interactive")==0 ){
5478 stdin_is_interactive = 1;
5479 }else if( strcmp(z,"-batch")==0 ){
5480 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00005481 }else if( strcmp(z,"-heap")==0 ){
5482 i++;
drh44dec872014-08-30 15:49:25 +00005483 }else if( strcmp(z,"-scratch")==0 ){
5484 i+=2;
5485 }else if( strcmp(z,"-pagecache")==0 ){
5486 i+=2;
5487 }else if( strcmp(z,"-lookaside")==0 ){
5488 i+=2;
drh7d9f3942013-04-03 01:26:54 +00005489 }else if( strcmp(z,"-mmap")==0 ){
5490 i++;
drha7e61d82011-03-12 17:02:57 +00005491 }else if( strcmp(z,"-vfs")==0 ){
5492 i++;
drh6f25e892011-07-08 17:02:57 +00005493#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00005494 }else if( strcmp(z,"-vfstrace")==0 ){
5495 i++;
drh6f25e892011-07-08 17:02:57 +00005496#endif
5497#ifdef SQLITE_ENABLE_MULTIPLEX
5498 }else if( strcmp(z,"-multiplex")==0 ){
5499 i++;
5500#endif
drhcc3b4f82012-02-07 14:13:50 +00005501 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00005502 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00005503 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00005504 /* Run commands that follow -cmd first and separately from commands
5505 ** that simply appear on the command-line. This seems goofy. It would
5506 ** be better if all commands ran in the order that they appear. But
5507 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00005508 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00005509 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00005510 if( z[0]=='.' ){
5511 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00005512 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00005513 }else{
drh05782482013-10-24 15:20:20 +00005514 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00005515 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
5516 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005517 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00005518 if( bail_on_error ) return rc!=0 ? rc : 1;
5519 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005520 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00005521 if( bail_on_error ) return rc;
5522 }
5523 }
drh1e5d0e92000-05-31 23:33:17 +00005524 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005525 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
5526 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00005527 return 1;
5528 }
drh700c2522016-02-09 18:39:25 +00005529 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00005530 }
drh44c2eb12003-04-30 11:38:26 +00005531
drhac5649a2014-11-28 13:35:03 +00005532 if( !readStdin ){
5533 /* Run all arguments that do not begin with '-' as if they were separate
5534 ** command-line inputs, except for the argToSkip argument which contains
5535 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00005536 */
drhac5649a2014-11-28 13:35:03 +00005537 for(i=0; i<nCmd; i++){
5538 if( azCmd[i][0]=='.' ){
5539 rc = do_meta_command(azCmd[i], &data);
5540 if( rc ) return rc==2 ? 0 : rc;
5541 }else{
5542 open_db(&data, 0);
5543 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
5544 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005545 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00005546 return rc!=0 ? rc : 1;
5547 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005548 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00005549 return rc;
5550 }
drh6ff13852001-11-25 13:18:23 +00005551 }
drh75897232000-05-29 14:26:00 +00005552 }
drhac5649a2014-11-28 13:35:03 +00005553 free(azCmd);
drh75897232000-05-29 14:26:00 +00005554 }else{
drh44c2eb12003-04-30 11:38:26 +00005555 /* Run commands received from standard input
5556 */
drhc28490c2006-10-26 14:25:58 +00005557 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00005558 char *zHome;
5559 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00005560 int nHistory;
drh75897232000-05-29 14:26:00 +00005561 printf(
drh743e0032011-12-12 16:51:50 +00005562 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00005563 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00005564 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00005565 );
drhb3735912014-02-10 16:13:42 +00005566 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00005567 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00005568 printBold("transient in-memory database");
5569 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00005570 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00005571 }
drh67505e72002-04-19 12:34:06 +00005572 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00005573 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00005574 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00005575 if( (zHistory = malloc(nHistory))!=0 ){
5576 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
5577 }
drh67505e72002-04-19 12:34:06 +00005578 }
drhf5ed7ad2015-06-15 14:43:25 +00005579 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00005580 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00005581 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00005582 shell_stifle_history(100);
5583 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00005584 free(zHistory);
drh67505e72002-04-19 12:34:06 +00005585 }
drhdaffd0e2001-04-11 14:28:42 +00005586 }else{
drhc28490c2006-10-26 14:25:58 +00005587 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00005588 }
5589 }
drh33048c02001-10-01 14:29:22 +00005590 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00005591 if( data.db ){
drhe6229612014-08-18 15:08:26 +00005592 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00005593 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00005594 }
mistachkin1fe36bb2016-04-04 02:16:44 +00005595 sqlite3_free(data.zFreeOnClose);
5596#if !SQLITE_SHELL_IS_UTF8
5597 for(i=0; i<argc; i++) sqlite3_free(argv[i]);
5598 sqlite3_free(argv);
5599#endif
drhc28490c2006-10-26 14:25:58 +00005600 return rc;
drh75897232000-05-29 14:26:00 +00005601}