blob: 148a534b866449c0926e39dc88f4b0a4eed37806 [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);
mistachkin8145fc62016-09-16 20:39:21 +0000146extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
mistachkin1fe36bb2016-04-04 02:16:44 +0000147#endif
148
drh047d4532015-01-18 20:30:23 +0000149/* On Windows, we normally run with output mode of TEXT so that \n characters
150** are automatically translated into \r\n. However, this behavior needs
151** to be disabled in some cases (ex: when generating CSV output and when
152** rendering quoted strings that contain \n characters). The following
153** routines take care of that.
154*/
155#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000156static void setBinaryMode(FILE *file, int isOutput){
157 if( isOutput ) fflush(file);
158 _setmode(_fileno(file), _O_BINARY);
drh047d4532015-01-18 20:30:23 +0000159}
mistachkin1fe36bb2016-04-04 02:16:44 +0000160static void setTextMode(FILE *file, int isOutput){
161 if( isOutput ) fflush(file);
162 _setmode(_fileno(file), _O_TEXT);
drh047d4532015-01-18 20:30:23 +0000163}
164#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000165# define setBinaryMode(X,Y)
166# define setTextMode(X,Y)
drh047d4532015-01-18 20:30:23 +0000167#endif
168
drh43408312013-10-30 12:43:36 +0000169
170/* True if the timer is enabled */
171static int enableTimer = 0;
172
173/* Return the current wall-clock time */
174static sqlite3_int64 timeOfDay(void){
175 static sqlite3_vfs *clockVfs = 0;
176 sqlite3_int64 t;
177 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
dan3fd415b2015-11-16 08:54:10 +0000178 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drh43408312013-10-30 12:43:36 +0000179 clockVfs->xCurrentTimeInt64(clockVfs, &t);
180 }else{
181 double r;
182 clockVfs->xCurrentTime(clockVfs, &r);
183 t = (sqlite3_int64)(r*86400000.0);
184 }
185 return t;
186}
187
drh91eb93c2015-03-03 19:56:20 +0000188#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000189#include <sys/time.h>
190#include <sys/resource.h>
191
drh91eb93c2015-03-03 19:56:20 +0000192/* VxWorks does not support getrusage() as far as we can determine */
193#if defined(_WRS_KERNEL) || defined(__RTP__)
194struct rusage {
195 struct timeval ru_utime; /* user CPU time used */
196 struct timeval ru_stime; /* system CPU time used */
197};
198#define getrusage(A,B) memset(B,0,sizeof(*B))
199#endif
200
drhda108222009-02-25 19:07:24 +0000201/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000202static struct rusage sBegin; /* CPU time at start */
203static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000204
drhda108222009-02-25 19:07:24 +0000205/*
206** Begin timing an operation
207*/
208static void beginTimer(void){
209 if( enableTimer ){
210 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000211 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000212 }
213}
214
215/* Return the difference of two time_structs in seconds */
216static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
mistachkin1fe36bb2016-04-04 02:16:44 +0000217 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
drhda108222009-02-25 19:07:24 +0000218 (double)(pEnd->tv_sec - pStart->tv_sec);
219}
220
221/*
222** Print the timing results.
223*/
224static void endTimer(void){
225 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000226 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000227 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000228 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000229 printf("Run Time: real %.3f user %f sys %f\n",
230 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000231 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
232 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
233 }
234}
shaneb320ccd2009-10-21 03:42:58 +0000235
drhda108222009-02-25 19:07:24 +0000236#define BEGIN_TIMER beginTimer()
237#define END_TIMER endTimer()
238#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000239
240#elif (defined(_WIN32) || defined(WIN32))
241
shaneb320ccd2009-10-21 03:42:58 +0000242/* Saved resource information for the beginning of an operation */
243static HANDLE hProcess;
244static FILETIME ftKernelBegin;
245static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000246static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000247typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
248 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000249static GETPROCTIMES getProcessTimesAddr = NULL;
250
shaneb320ccd2009-10-21 03:42:58 +0000251/*
252** Check to see if we have timer support. Return 1 if necessary
253** support found (or found previously).
254*/
255static int hasTimer(void){
256 if( getProcessTimesAddr ){
257 return 1;
258 } else {
drh4ace5362014-11-10 14:42:28 +0000259 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
260 ** versions. See if the version we are running on has it, and if it
261 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000262 */
263 hProcess = GetCurrentProcess();
264 if( hProcess ){
265 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
266 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000267 getProcessTimesAddr =
268 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000269 if( NULL != getProcessTimesAddr ){
270 return 1;
271 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000272 FreeLibrary(hinstLib);
shaneb320ccd2009-10-21 03:42:58 +0000273 }
274 }
275 }
276 return 0;
277}
278
279/*
280** Begin timing an operation
281*/
282static void beginTimer(void){
283 if( enableTimer && getProcessTimesAddr ){
284 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000285 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
286 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000287 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000288 }
289}
290
291/* Return the difference of two FILETIME structs in seconds */
292static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
293 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
294 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
295 return (double) ((i64End - i64Start) / 10000000.0);
296}
297
298/*
299** Print the timing results.
300*/
301static void endTimer(void){
302 if( enableTimer && getProcessTimesAddr){
303 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000304 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000305 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000306 printf("Run Time: real %.3f user %f sys %f\n",
307 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000308 timeDiff(&ftUserBegin, &ftUserEnd),
309 timeDiff(&ftKernelBegin, &ftKernelEnd));
310 }
311}
312
313#define BEGIN_TIMER beginTimer()
314#define END_TIMER endTimer()
315#define HAS_TIMER hasTimer()
316
drhda108222009-02-25 19:07:24 +0000317#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000318#define BEGIN_TIMER
drhda108222009-02-25 19:07:24 +0000319#define END_TIMER
320#define HAS_TIMER 0
321#endif
322
shanec0688ea2009-03-05 03:48:06 +0000323/*
324** Used to prevent warnings about unused parameters
325*/
326#define UNUSED_PARAMETER(x) (void)(x)
327
drhe91d16b2008-12-08 18:27:31 +0000328/*
drhc49f44e2006-10-26 18:15:42 +0000329** If the following flag is set, then command execution stops
330** at an error if we are not interactive.
331*/
332static int bail_on_error = 0;
333
334/*
drhc28490c2006-10-26 14:25:58 +0000335** Threat stdin as an interactive input if the following variable
336** is true. Otherwise, assume stdin is connected to a file or pipe.
337*/
338static int stdin_is_interactive = 1;
339
340/*
drhe05461c2015-12-30 13:36:57 +0000341** On Windows systems we have to know if standard output is a console
342** in order to translate UTF-8 into MBCS. The following variable is
343** true if translation is required.
344*/
345static int stdout_is_console = 1;
346
347/*
drh4c504392000-10-16 22:06:40 +0000348** The following is the open SQLite database. We make a pointer
349** to this database a static variable so that it can be accessed
350** by the SIGINT handler to interrupt database processing.
351*/
mistachkin8e189222015-04-19 21:43:16 +0000352static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000353
354/*
drh67505e72002-04-19 12:34:06 +0000355** True if an interrupt (Control-C) has been received.
356*/
drh43617e92006-03-06 20:55:46 +0000357static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000358
359/*
persicom7e2dfdd2002-04-18 02:46:52 +0000360** This is the name of our program. It is set in main(), used
361** in a number of other places, mostly for error messages.
362*/
363static char *Argv0;
364
365/*
366** Prompt strings. Initialized in main. Settable with
367** .prompt main continue
368*/
369static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
370static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
371
drhb0603412007-02-28 04:47:26 +0000372/*
mistachkin710b33b2016-01-03 18:59:28 +0000373** Render output like fprintf(). Except, if the output is going to the
374** console and if this is running on a Windows machine, translate the
375** output from UTF-8 into MBCS.
376*/
377#if defined(_WIN32) || defined(WIN32)
378void utf8_printf(FILE *out, const char *zFormat, ...){
379 va_list ap;
380 va_start(ap, zFormat);
381 if( stdout_is_console && (out==stdout || out==stderr) ){
mistachkin710b33b2016-01-03 18:59:28 +0000382 char *z1 = sqlite3_vmprintf(zFormat, ap);
mistachkin1fe36bb2016-04-04 02:16:44 +0000383 char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
mistachkin710b33b2016-01-03 18:59:28 +0000384 sqlite3_free(z1);
385 fputs(z2, out);
386 sqlite3_free(z2);
387 }else{
388 vfprintf(out, zFormat, ap);
389 }
390 va_end(ap);
391}
392#elif !defined(utf8_printf)
393# define utf8_printf fprintf
394#endif
395
396/*
397** Render output like fprintf(). This should not be used on anything that
398** includes string formatting (e.g. "%s").
399*/
400#if !defined(raw_printf)
401# define raw_printf fprintf
402#endif
403
404/*
drhb0603412007-02-28 04:47:26 +0000405** Write I/O traces to the following stream.
406*/
rsebe0a9092007-07-30 18:24:38 +0000407#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000408static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000409#endif
drhb0603412007-02-28 04:47:26 +0000410
411/*
412** This routine works like printf in that its first argument is a
413** format string and subsequent arguments are values to be substituted
414** in place of % fields. The result of formatting this string
415** is written to iotrace.
416*/
rsebe0a9092007-07-30 18:24:38 +0000417#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000418static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000419 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000420 char *z;
drhb0603412007-02-28 04:47:26 +0000421 if( iotrace==0 ) return;
422 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000423 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000424 va_end(ap);
mistachkin710b33b2016-01-03 18:59:28 +0000425 utf8_printf(iotrace, "%s", z);
drhf075cd02007-02-28 06:14:25 +0000426 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000427}
rsebe0a9092007-07-30 18:24:38 +0000428#endif
drhb0603412007-02-28 04:47:26 +0000429
drh44c2eb12003-04-30 11:38:26 +0000430
persicom7e2dfdd2002-04-18 02:46:52 +0000431/*
drh83965662003-04-17 02:54:13 +0000432** Determines if a string is a number of not.
433*/
danielk19772e588c72005-12-09 14:25:08 +0000434static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000435 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000436 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000437 return 0;
438 }
439 z++;
440 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000441 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000442 if( *z=='.' ){
443 z++;
drhf0693c82011-10-11 20:41:54 +0000444 if( !IsDigit(*z) ) return 0;
445 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000446 if( realnum ) *realnum = 1;
447 }
448 if( *z=='e' || *z=='E' ){
449 z++;
450 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000451 if( !IsDigit(*z) ) return 0;
452 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000453 if( realnum ) *realnum = 1;
454 }
455 return *z==0;
456}
drh83965662003-04-17 02:54:13 +0000457
458/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000459** A global char* and an SQL function to access its current value
460** from within an SQL statement. This program used to use the
danielk1977bc6ada42004-06-30 08:20:16 +0000461** sqlite_exec_printf() API to substitue a string into an SQL statement.
462** The correct way to do this with sqlite3 is to use the bind API, but
463** since the shell is built around the callback paradigm it would be a lot
464** of work. Instead just use this hack, which is quite harmless.
465*/
466static const char *zShellStatic = 0;
467static void shellstaticFunc(
468 sqlite3_context *context,
469 int argc,
470 sqlite3_value **argv
471){
472 assert( 0==argc );
473 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000474 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000475 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000476 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
477}
478
479
480/*
drhe05461c2015-12-30 13:36:57 +0000481** Compute a string length that is limited to what can be stored in
482** lower 30 bits of a 32-bit signed integer.
483*/
484static int strlen30(const char *z){
485 const char *z2 = z;
486 while( *z2 ){ z2++; }
487 return 0x3fffffff & (int)(z2 - z);
488}
489
490/*
drhfeac5f82004-08-01 00:10:45 +0000491** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000492** the text in memory obtained from malloc() and returns a pointer
493** to the text. NULL is returned at end of file, or if malloc()
494** fails.
495**
drh9f099fd2013-08-06 14:01:46 +0000496** If zLine is not NULL then it is a malloced buffer returned from
497** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000498*/
drh9f099fd2013-08-06 14:01:46 +0000499static char *local_getline(char *zLine, FILE *in){
500 int nLine = zLine==0 ? 0 : 100;
501 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000502
drhb07028f2011-10-14 21:49:18 +0000503 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000504 if( n+100>nLine ){
505 nLine = nLine*2 + 100;
506 zLine = realloc(zLine, nLine);
507 if( zLine==0 ) return 0;
508 }
drhdaffd0e2001-04-11 14:28:42 +0000509 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000510 if( n==0 ){
511 free(zLine);
512 return 0;
513 }
514 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000515 break;
516 }
drh9f099fd2013-08-06 14:01:46 +0000517 while( zLine[n] ) n++;
518 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000519 n--;
shaneh13b36022009-12-17 21:07:15 +0000520 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000521 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000522 break;
drh8e7e7a22000-05-30 18:45:23 +0000523 }
524 }
drhe05461c2015-12-30 13:36:57 +0000525#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000526 /* For interactive input on Windows systems, translate the
drhe05461c2015-12-30 13:36:57 +0000527 ** multi-byte characterset characters into UTF-8. */
drhfc8b40f2016-09-07 10:10:18 +0000528 if( stdin_is_interactive && in==stdin ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000529 char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
drhe05461c2015-12-30 13:36:57 +0000530 if( zTrans ){
531 int nTrans = strlen30(zTrans)+1;
532 if( nTrans>nLine ){
533 zLine = realloc(zLine, nTrans);
534 if( zLine==0 ){
535 sqlite3_free(zTrans);
536 return 0;
537 }
538 }
539 memcpy(zLine, zTrans, nTrans);
540 sqlite3_free(zTrans);
541 }
542 }
543#endif /* defined(_WIN32) || defined(WIN32) */
drh8e7e7a22000-05-30 18:45:23 +0000544 return zLine;
545}
546
547/*
drhc28490c2006-10-26 14:25:58 +0000548** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000549**
drh9f099fd2013-08-06 14:01:46 +0000550** If in==0 then read from standard input and prompt before each line.
551** If isContinuation is true, then a continuation prompt is appropriate.
552** If isContinuation is zero, then the main prompt should be used.
553**
554** If zPrior is not NULL then it is a buffer from a prior call to this
555** routine that can be reused.
556**
557** The result is stored in space obtained from malloc() and must either
558** be freed by the caller or else passed back into this routine via the
559** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000560*/
drh9f099fd2013-08-06 14:01:46 +0000561static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000562 char *zPrompt;
563 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000564 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000565 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000566 }else{
drh9f099fd2013-08-06 14:01:46 +0000567 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000568#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000569 printf("%s", zPrompt);
570 fflush(stdout);
571 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000572#else
573 free(zPrior);
574 zResult = shell_readline(zPrompt);
575 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000576#endif
drh9f099fd2013-08-06 14:01:46 +0000577 }
drh8e7e7a22000-05-30 18:45:23 +0000578 return zResult;
579}
580
drhe6229612014-08-18 15:08:26 +0000581#if defined(SQLITE_ENABLE_SESSION)
582/*
583** State information for a single open session
584*/
585typedef struct OpenSession OpenSession;
586struct OpenSession {
587 char *zName; /* Symbolic name for this session */
588 int nFilter; /* Number of xFilter rejection GLOB patterns */
589 char **azFilter; /* Array of xFilter rejection GLOB patterns */
590 sqlite3_session *p; /* The open session */
591};
592#endif
593
drhdcd87a92014-08-18 13:45:42 +0000594/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000595** Shell output mode information from before ".explain on",
drhdcd87a92014-08-18 13:45:42 +0000596** saved so that it can be restored by ".explain off"
597*/
598typedef struct SavedModeInfo SavedModeInfo;
599struct SavedModeInfo {
600 int valid; /* Is there legit data in here? */
601 int mode; /* Mode prior to ".explain on" */
602 int showHeader; /* The ".header" setting prior to ".explain on" */
603 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000604};
drh45e29d82006-11-20 16:21:10 +0000605
drh8e7e7a22000-05-30 18:45:23 +0000606/*
drhdcd87a92014-08-18 13:45:42 +0000607** State information about the database connection is contained in an
608** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000609*/
drhdcd87a92014-08-18 13:45:42 +0000610typedef struct ShellState ShellState;
611struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000612 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000613 int echoOn; /* True to echo input commands */
drh700c2522016-02-09 18:39:25 +0000614 int autoExplain; /* Automatically turn on .explain mode */
drhc2ce0be2014-05-29 12:36:14 +0000615 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000616 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000617 int scanstatsOn; /* True to display scan stats before each finalize */
drhdf12f1c2015-12-07 21:46:19 +0000618 int countChanges; /* True to display change counts */
drh9569f602015-04-16 15:05:04 +0000619 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000620 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000621 int cnt; /* Number of records displayed so far */
622 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000623 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000624 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000625 int mode; /* An output mode setting */
drh700c2522016-02-09 18:39:25 +0000626 int cMode; /* temporary output mode for the current query */
627 int normalMode; /* Output mode before ".explain on" */
drh45e29d82006-11-20 16:21:10 +0000628 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000629 int showHeader; /* True to show column names in List or Column mode */
drh760c8162016-09-16 02:52:22 +0000630 int nCheck; /* Number of ".check" commands run */
drh44dec872014-08-30 15:49:25 +0000631 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000632 char *zDestTable; /* Name of destination table when MODE_Insert */
drh760c8162016-09-16 02:52:22 +0000633 char zTestcase[30]; /* Name of current test case */
mistachkin636bf9f2014-07-19 20:15:16 +0000634 char colSeparator[20]; /* Column separator character for several modes */
635 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000636 int colWidth[100]; /* Requested width of each column when in column mode*/
637 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000638 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000639 ** the database */
drh44c2eb12003-04-30 11:38:26 +0000640 char outfile[FILENAME_MAX]; /* Filename for *out */
641 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000642 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000643 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000644 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000645 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000646 int *aiIndent; /* Array of indents used in MODE_Explain */
647 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000648 int iIndent; /* Index of current op in aiIndent[] */
drhe6229612014-08-18 15:08:26 +0000649#if defined(SQLITE_ENABLE_SESSION)
650 int nSession; /* Number of active sessions */
651 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
652#endif
drh75897232000-05-29 14:26:00 +0000653};
654
655/*
drh44dec872014-08-30 15:49:25 +0000656** These are the allowed shellFlgs values
657*/
658#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
659#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
660#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
661
662/*
drh75897232000-05-29 14:26:00 +0000663** These are the allowed modes.
664*/
drh967e8b72000-06-21 13:59:10 +0000665#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000666#define MODE_Column 1 /* One record per line in neat columns */
667#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000668#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
669#define MODE_Html 4 /* Generate an XHTML table */
670#define MODE_Insert 5 /* Generate SQL "insert" statements */
drh41f5f6e2016-10-21 17:39:30 +0000671#define MODE_Quote 6 /* Quote values as for SQL */
672#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
673#define MODE_Csv 8 /* Quote strings, numbers are plain */
674#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
675#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
676#define MODE_Pretty 11 /* Pretty-print schemas */
persicom7e2dfdd2002-04-18 02:46:52 +0000677
drh66ce4d02008-02-15 17:38:06 +0000678static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000679 "line",
680 "column",
681 "list",
682 "semi",
683 "html",
drhfeac5f82004-08-01 00:10:45 +0000684 "insert",
drh41f5f6e2016-10-21 17:39:30 +0000685 "quote",
drhfeac5f82004-08-01 00:10:45 +0000686 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000687 "csv",
drh66ce4d02008-02-15 17:38:06 +0000688 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000689 "ascii",
drh4926fec2016-04-13 15:33:42 +0000690 "prettyprint",
persicom7e2dfdd2002-04-18 02:46:52 +0000691};
drh75897232000-05-29 14:26:00 +0000692
693/*
mistachkinfad42082014-07-24 22:13:12 +0000694** These are the column/row/line separators used by the various
695** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000696*/
mistachkinfad42082014-07-24 22:13:12 +0000697#define SEP_Column "|"
698#define SEP_Row "\n"
699#define SEP_Tab "\t"
700#define SEP_Space " "
701#define SEP_Comma ","
702#define SEP_CrLf "\r\n"
703#define SEP_Unit "\x1F"
704#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000705
706/*
drh75897232000-05-29 14:26:00 +0000707** Number of elements in an array
708*/
drh902b9ee2008-12-05 17:17:07 +0000709#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000710
711/*
drh127f9d72010-02-23 01:47:00 +0000712** A callback for the sqlite3_log() interface.
713*/
714static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000715 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000716 if( p->pLog==0 ) return;
mistachkinaae280e2015-12-31 19:06:24 +0000717 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
drh127f9d72010-02-23 01:47:00 +0000718 fflush(p->pLog);
719}
720
721/*
shane626a6e42009-10-22 17:30:15 +0000722** Output the given string as a hex-encoded blob (eg. X'1234' )
723*/
724static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
725 int i;
726 char *zBlob = (char *)pBlob;
mistachkinaae280e2015-12-31 19:06:24 +0000727 raw_printf(out,"X'");
728 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
729 raw_printf(out,"'");
shane626a6e42009-10-22 17:30:15 +0000730}
731
732/*
drh28bd4bc2000-06-15 15:57:22 +0000733** Output the given string as a quoted string using SQL quoting conventions.
734*/
735static void output_quoted_string(FILE *out, const char *z){
736 int i;
737 int nSingle = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +0000738 setBinaryMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000739 for(i=0; z[i]; i++){
740 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000741 }
742 if( nSingle==0 ){
drhe05461c2015-12-30 13:36:57 +0000743 utf8_printf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000744 }else{
mistachkinaae280e2015-12-31 19:06:24 +0000745 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000746 while( *z ){
747 for(i=0; z[i] && z[i]!='\''; i++){}
748 if( i==0 ){
mistachkinaae280e2015-12-31 19:06:24 +0000749 raw_printf(out,"''");
drh28bd4bc2000-06-15 15:57:22 +0000750 z++;
751 }else if( z[i]=='\'' ){
drhe05461c2015-12-30 13:36:57 +0000752 utf8_printf(out,"%.*s''",i,z);
drh28bd4bc2000-06-15 15:57:22 +0000753 z += i+1;
754 }else{
drhe05461c2015-12-30 13:36:57 +0000755 utf8_printf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000756 break;
757 }
758 }
mistachkinaae280e2015-12-31 19:06:24 +0000759 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000760 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000761 setTextMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000762}
763
764/*
drhfeac5f82004-08-01 00:10:45 +0000765** Output the given string as a quoted according to C or TCL quoting rules.
766*/
767static void output_c_string(FILE *out, const char *z){
768 unsigned int c;
769 fputc('"', out);
770 while( (c = *(z++))!=0 ){
771 if( c=='\\' ){
772 fputc(c, out);
773 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000774 }else if( c=='"' ){
775 fputc('\\', out);
776 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000777 }else if( c=='\t' ){
778 fputc('\\', out);
779 fputc('t', out);
780 }else if( c=='\n' ){
781 fputc('\\', out);
782 fputc('n', out);
783 }else if( c=='\r' ){
784 fputc('\\', out);
785 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000786 }else if( !isprint(c&0xff) ){
mistachkinaae280e2015-12-31 19:06:24 +0000787 raw_printf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000788 }else{
789 fputc(c, out);
790 }
791 }
792 fputc('"', out);
793}
794
795/*
drhc08a4f12000-06-15 16:49:48 +0000796** Output the given string with characters that are special to
797** HTML escaped.
798*/
799static void output_html_string(FILE *out, const char *z){
800 int i;
drhc3d6ba42014-01-13 20:38:35 +0000801 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000802 while( *z ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000803 for(i=0; z[i]
804 && z[i]!='<'
805 && z[i]!='&'
806 && z[i]!='>'
807 && z[i]!='\"'
shane43d9cb22009-10-21 14:11:48 +0000808 && z[i]!='\'';
809 i++){}
drhc08a4f12000-06-15 16:49:48 +0000810 if( i>0 ){
drhe05461c2015-12-30 13:36:57 +0000811 utf8_printf(out,"%.*s",i,z);
drhc08a4f12000-06-15 16:49:48 +0000812 }
813 if( z[i]=='<' ){
mistachkinaae280e2015-12-31 19:06:24 +0000814 raw_printf(out,"&lt;");
drhc08a4f12000-06-15 16:49:48 +0000815 }else if( z[i]=='&' ){
mistachkinaae280e2015-12-31 19:06:24 +0000816 raw_printf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000817 }else if( z[i]=='>' ){
mistachkinaae280e2015-12-31 19:06:24 +0000818 raw_printf(out,"&gt;");
shane43d9cb22009-10-21 14:11:48 +0000819 }else if( z[i]=='\"' ){
mistachkinaae280e2015-12-31 19:06:24 +0000820 raw_printf(out,"&quot;");
shane43d9cb22009-10-21 14:11:48 +0000821 }else if( z[i]=='\'' ){
mistachkinaae280e2015-12-31 19:06:24 +0000822 raw_printf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000823 }else{
824 break;
825 }
826 z += i + 1;
827 }
828}
829
830/*
drhc49f44e2006-10-26 18:15:42 +0000831** If a field contains any character identified by a 1 in the following
832** array, then the string must be quoted for CSV.
833*/
834static const char needCsvQuote[] = {
mistachkin1fe36bb2016-04-04 02:16:44 +0000835 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
836 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
837 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
838 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
839 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
840 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
841 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
842 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
843 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
844 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
845 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
846 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
847 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
848 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
849 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
850 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
drhc49f44e2006-10-26 18:15:42 +0000851};
852
853/*
mistachkindd11f2d2014-12-11 04:49:46 +0000854** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000855** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000856** the null value. Strings are quoted if necessary. The separator
857** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000858*/
drhdcd87a92014-08-18 13:45:42 +0000859static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000860 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000861 if( z==0 ){
drhe05461c2015-12-30 13:36:57 +0000862 utf8_printf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000863 }else{
drhc49f44e2006-10-26 18:15:42 +0000864 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000865 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000866 for(i=0; z[i]; i++){
mistachkin1fe36bb2016-04-04 02:16:44 +0000867 if( needCsvQuote[((unsigned char*)z)[i]]
868 || (z[i]==p->colSeparator[0] &&
mistachkin636bf9f2014-07-19 20:15:16 +0000869 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000870 i = 0;
871 break;
872 }
873 }
874 if( i==0 ){
875 putc('"', out);
876 for(i=0; z[i]; i++){
877 if( z[i]=='"' ) putc('"', out);
878 putc(z[i], out);
879 }
880 putc('"', out);
881 }else{
drhe05461c2015-12-30 13:36:57 +0000882 utf8_printf(out, "%s", z);
drhc49f44e2006-10-26 18:15:42 +0000883 }
drh8e64d1c2004-10-07 00:32:39 +0000884 }
885 if( bSep ){
drhe05461c2015-12-30 13:36:57 +0000886 utf8_printf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000887 }
888}
889
danielk19774af00c62005-01-23 23:43:21 +0000890#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000891/*
drh4c504392000-10-16 22:06:40 +0000892** This routine runs when the user presses Ctrl-C
893*/
894static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000895 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000896 seenInterrupt++;
897 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000898 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000899}
danielk19774af00c62005-01-23 23:43:21 +0000900#endif
drh4c504392000-10-16 22:06:40 +0000901
drha0daa752016-09-16 11:53:10 +0000902#ifndef SQLITE_OMIT_AUTHORIZATION
drh4c504392000-10-16 22:06:40 +0000903/*
drhde613c62016-04-04 17:23:10 +0000904** When the ".auth ON" is set, the following authorizer callback is
905** invoked. It always returns SQLITE_OK.
906*/
907static int shellAuth(
908 void *pClientData,
909 int op,
910 const char *zA1,
911 const char *zA2,
912 const char *zA3,
913 const char *zA4
914){
915 ShellState *p = (ShellState*)pClientData;
916 static const char *azAction[] = { 0,
917 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
918 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
919 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
920 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
921 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
922 "DROP_TRIGGER", "DROP_VIEW", "INSERT",
923 "PRAGMA", "READ", "SELECT",
924 "TRANSACTION", "UPDATE", "ATTACH",
925 "DETACH", "ALTER_TABLE", "REINDEX",
926 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
927 "FUNCTION", "SAVEPOINT", "RECURSIVE"
928 };
929 int i;
930 const char *az[4];
931 az[0] = zA1;
932 az[1] = zA2;
933 az[2] = zA3;
934 az[3] = zA4;
mistachkin8145fc62016-09-16 20:39:21 +0000935 utf8_printf(p->out, "authorizer: %s", azAction[op]);
drhde613c62016-04-04 17:23:10 +0000936 for(i=0; i<4; i++){
937 raw_printf(p->out, " ");
938 if( az[i] ){
939 output_c_string(p->out, az[i]);
940 }else{
941 raw_printf(p->out, "NULL");
942 }
943 }
944 raw_printf(p->out, "\n");
945 return SQLITE_OK;
946}
drha0daa752016-09-16 11:53:10 +0000947#endif
mistachkin8145fc62016-09-16 20:39:21 +0000948
drhde613c62016-04-04 17:23:10 +0000949
950/*
shane626a6e42009-10-22 17:30:15 +0000951** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000952** invokes for each row of a query result.
953*/
drh4ace5362014-11-10 14:42:28 +0000954static int shell_callback(
955 void *pArg,
956 int nArg, /* Number of result columns */
957 char **azArg, /* Text of each result column */
958 char **azCol, /* Column names */
959 int *aiType /* Column types */
960){
drh75897232000-05-29 14:26:00 +0000961 int i;
drhdcd87a92014-08-18 13:45:42 +0000962 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000963
drh700c2522016-02-09 18:39:25 +0000964 switch( p->cMode ){
drh75897232000-05-29 14:26:00 +0000965 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000966 int w = 5;
drh6a535342001-10-19 16:44:56 +0000967 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000968 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000969 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000970 if( len>w ) w = len;
971 }
drhe05461c2015-12-30 13:36:57 +0000972 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000973 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000974 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000975 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000976 }
977 break;
978 }
danielk19770d78bae2008-01-03 07:09:48 +0000979 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000980 case MODE_Column: {
drh700c2522016-02-09 18:39:25 +0000981 static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
982 const int *colWidth;
983 int showHdr;
984 char *rowSep;
985 if( p->cMode==MODE_Column ){
986 colWidth = p->colWidth;
987 showHdr = p->showHeader;
988 rowSep = p->rowSeparator;
989 }else{
990 colWidth = aExplainWidths;
991 showHdr = 1;
mistachkin6d945552016-02-09 20:31:50 +0000992 rowSep = SEP_Row;
drh700c2522016-02-09 18:39:25 +0000993 }
drha0c66f52000-07-29 13:20:21 +0000994 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000995 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000996 int w, n;
997 if( i<ArraySize(p->colWidth) ){
drh700c2522016-02-09 18:39:25 +0000998 w = colWidth[i];
drh75897232000-05-29 14:26:00 +0000999 }else{
danielk19770d78bae2008-01-03 07:09:48 +00001000 w = 0;
drh75897232000-05-29 14:26:00 +00001001 }
drh078b1fd2012-09-21 13:40:02 +00001002 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +00001003 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +00001004 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +00001005 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +00001006 if( w<n ) w = n;
1007 }
1008 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001009 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001010 }
drh700c2522016-02-09 18:39:25 +00001011 if( showHdr ){
drh078b1fd2012-09-21 13:40:02 +00001012 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001013 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001014 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001015 }else{
drhe05461c2015-12-30 13:36:57 +00001016 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001017 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001018 }
drha0c66f52000-07-29 13:20:21 +00001019 }
1020 }
drh700c2522016-02-09 18:39:25 +00001021 if( showHdr ){
drha0c66f52000-07-29 13:20:21 +00001022 for(i=0; i<nArg; i++){
1023 int w;
1024 if( i<ArraySize(p->actualWidth) ){
1025 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +00001026 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +00001027 }else{
1028 w = 10;
1029 }
mistachkinaae280e2015-12-31 19:06:24 +00001030 utf8_printf(p->out,"%-*.*s%s",w,w,
drhe05461c2015-12-30 13:36:57 +00001031 "----------------------------------------------------------"
drha0c66f52000-07-29 13:20:21 +00001032 "----------------------------------------------------------",
drh700c2522016-02-09 18:39:25 +00001033 i==nArg-1 ? rowSep : " ");
drha0c66f52000-07-29 13:20:21 +00001034 }
drh75897232000-05-29 14:26:00 +00001035 }
1036 }
drh6a535342001-10-19 16:44:56 +00001037 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001038 for(i=0; i<nArg; i++){
1039 int w;
drha0c66f52000-07-29 13:20:21 +00001040 if( i<ArraySize(p->actualWidth) ){
1041 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001042 }else{
1043 w = 10;
1044 }
drh700c2522016-02-09 18:39:25 +00001045 if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +00001046 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001047 }
dana98bf362013-11-13 18:35:01 +00001048 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +00001049 if( p->iIndent<p->nIndent ){
mistachkinaae280e2015-12-31 19:06:24 +00001050 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +00001051 }
danc4650bb2013-11-18 08:41:06 +00001052 p->iIndent++;
dana98bf362013-11-13 18:35:01 +00001053 }
drh078b1fd2012-09-21 13:40:02 +00001054 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001055 utf8_printf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +00001056 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001057 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001058 }else{
drhe05461c2015-12-30 13:36:57 +00001059 utf8_printf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +00001060 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001061 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001062 }
drh75897232000-05-29 14:26:00 +00001063 }
1064 break;
1065 }
drh4926fec2016-04-13 15:33:42 +00001066 case MODE_Semi: { /* .schema and .fullschema output */
1067 utf8_printf(p->out, "%s;\n", azArg[0]);
1068 break;
1069 }
1070 case MODE_Pretty: { /* .schema and .fullschema with --indent */
1071 char *z;
drh07d683f2016-04-13 21:00:36 +00001072 int j;
drh4926fec2016-04-13 15:33:42 +00001073 int nParen = 0;
1074 char cEnd = 0;
1075 char c;
1076 int nLine = 0;
1077 assert( nArg==1 );
1078 if( azArg[0]==0 ) break;
1079 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
1080 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
1081 ){
1082 utf8_printf(p->out, "%s;\n", azArg[0]);
1083 break;
1084 }
1085 z = sqlite3_mprintf("%s", azArg[0]);
1086 j = 0;
1087 for(i=0; IsSpace(z[i]); i++){}
1088 for(; (c = z[i])!=0; i++){
1089 if( IsSpace(c) ){
1090 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
1091 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
1092 j--;
1093 }
1094 z[j++] = c;
1095 }
1096 while( j>0 && IsSpace(z[j-1]) ){ j--; }
1097 z[j] = 0;
1098 if( strlen30(z)>=79 ){
drh07d683f2016-04-13 21:00:36 +00001099 for(i=j=0; (c = z[i])!=0; i++){
drh4926fec2016-04-13 15:33:42 +00001100 if( c==cEnd ){
1101 cEnd = 0;
1102 }else if( c=='"' || c=='\'' || c=='`' ){
1103 cEnd = c;
1104 }else if( c=='[' ){
1105 cEnd = ']';
1106 }else if( c=='(' ){
1107 nParen++;
1108 }else if( c==')' ){
1109 nParen--;
1110 if( nLine>0 && nParen==0 && j>0 ){
1111 utf8_printf(p->out, "%.*s\n", j, z);
1112 j = 0;
1113 }
1114 }
1115 z[j++] = c;
1116 if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
1117 if( c=='\n' ) j--;
1118 utf8_printf(p->out, "%.*s\n ", j, z);
1119 j = 0;
1120 nLine++;
1121 while( IsSpace(z[i+1]) ){ i++; }
1122 }
1123 }
1124 z[j] = 0;
1125 }
1126 utf8_printf(p->out, "%s;\n", z);
1127 sqlite3_free(z);
1128 break;
1129 }
drh75897232000-05-29 14:26:00 +00001130 case MODE_List: {
1131 if( p->cnt++==0 && p->showHeader ){
1132 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001133 utf8_printf(p->out,"%s%s",azCol[i],
mistachkin636bf9f2014-07-19 20:15:16 +00001134 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +00001135 }
1136 }
drh6a535342001-10-19 16:44:56 +00001137 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001138 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001139 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +00001140 if( z==0 ) z = p->nullValue;
drhe05461c2015-12-30 13:36:57 +00001141 utf8_printf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001142 if( i<nArg-1 ){
drhe05461c2015-12-30 13:36:57 +00001143 utf8_printf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +00001144 }else{
drhe05461c2015-12-30 13:36:57 +00001145 utf8_printf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001146 }
drh75897232000-05-29 14:26:00 +00001147 }
1148 break;
1149 }
drh1e5d0e92000-05-31 23:33:17 +00001150 case MODE_Html: {
1151 if( p->cnt++==0 && p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001152 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001153 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001154 raw_printf(p->out,"<TH>");
shane43d9cb22009-10-21 14:11:48 +00001155 output_html_string(p->out, azCol[i]);
mistachkinaae280e2015-12-31 19:06:24 +00001156 raw_printf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001157 }
mistachkinaae280e2015-12-31 19:06:24 +00001158 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001159 }
drh6a535342001-10-19 16:44:56 +00001160 if( azArg==0 ) break;
mistachkinaae280e2015-12-31 19:06:24 +00001161 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001162 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001163 raw_printf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +00001164 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00001165 raw_printf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001166 }
mistachkinaae280e2015-12-31 19:06:24 +00001167 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001168 break;
1169 }
drhfeac5f82004-08-01 00:10:45 +00001170 case MODE_Tcl: {
1171 if( p->cnt++==0 && p->showHeader ){
1172 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001173 output_c_string(p->out,azCol[i] ? azCol[i] : "");
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 }
1178 if( azArg==0 ) break;
1179 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +00001180 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
drhe05461c2015-12-30 13:36:57 +00001181 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001182 }
drhe05461c2015-12-30 13:36:57 +00001183 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001184 break;
1185 }
drh8e64d1c2004-10-07 00:32:39 +00001186 case MODE_Csv: {
mistachkin1fe36bb2016-04-04 02:16:44 +00001187 setBinaryMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001188 if( p->cnt++==0 && p->showHeader ){
1189 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001190 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001191 }
drhe05461c2015-12-30 13:36:57 +00001192 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001193 }
drh40253262014-10-17 21:35:05 +00001194 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +00001195 for(i=0; i<nArg; i++){
1196 output_csv(p, azArg[i], i<nArg-1);
1197 }
drhe05461c2015-12-30 13:36:57 +00001198 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001199 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001200 setTextMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001201 break;
1202 }
drh41f5f6e2016-10-21 17:39:30 +00001203 case MODE_Quote:
drh28bd4bc2000-06-15 15:57:22 +00001204 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +00001205 if( azArg==0 ) break;
drh41f5f6e2016-10-21 17:39:30 +00001206 if( p->cMode==MODE_Insert ){
1207 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
1208 if( p->showHeader ){
1209 raw_printf(p->out,"(");
1210 for(i=0; i<nArg; i++){
1211 char *zSep = i>0 ? ",": "";
1212 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
1213 }
1214 raw_printf(p->out,")");
mistachkin151c75a2015-04-07 21:16:40 +00001215 }
drh41f5f6e2016-10-21 17:39:30 +00001216 raw_printf(p->out," VALUES(");
drh59ce2c42016-11-03 13:12:28 +00001217 }else if( p->cnt==0 && p->showHeader ){
1218 for(i=0; i<nArg; i++){
mistachkin2f9a6132016-11-11 05:19:45 +00001219 if( i>0 ) raw_printf(p->out, ",");
drh59ce2c42016-11-03 13:12:28 +00001220 output_quoted_string(p->out, azCol[i]);
1221 }
mistachkin2f9a6132016-11-11 05:19:45 +00001222 raw_printf(p->out,"\n");
mistachkin151c75a2015-04-07 21:16:40 +00001223 }
drh59ce2c42016-11-03 13:12:28 +00001224 p->cnt++;
drh28bd4bc2000-06-15 15:57:22 +00001225 for(i=0; i<nArg; i++){
1226 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001227 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
mistachkinaae280e2015-12-31 19:06:24 +00001228 utf8_printf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001229 }else if( aiType && aiType[i]==SQLITE_TEXT ){
mistachkinaae280e2015-12-31 19:06:24 +00001230 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shanead6b8d02009-10-22 18:12:58 +00001231 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001232 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1233 || aiType[i]==SQLITE_FLOAT) ){
drhe05461c2015-12-30 13:36:57 +00001234 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001235 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1236 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1237 int nBlob = sqlite3_column_bytes(p->pStmt, i);
mistachkinaae280e2015-12-31 19:06:24 +00001238 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shane626a6e42009-10-22 17:30:15 +00001239 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001240 }else if( isNumber(azArg[i], 0) ){
drhe05461c2015-12-30 13:36:57 +00001241 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
drh28bd4bc2000-06-15 15:57:22 +00001242 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001243 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
drh28bd4bc2000-06-15 15:57:22 +00001244 output_quoted_string(p->out, azArg[i]);
1245 }
1246 }
drh41f5f6e2016-10-21 17:39:30 +00001247 raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n");
drh6a535342001-10-19 16:44:56 +00001248 break;
drh28bd4bc2000-06-15 15:57:22 +00001249 }
mistachkin636bf9f2014-07-19 20:15:16 +00001250 case MODE_Ascii: {
1251 if( p->cnt++==0 && p->showHeader ){
1252 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001253 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1254 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +00001255 }
drhe05461c2015-12-30 13:36:57 +00001256 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001257 }
1258 if( azArg==0 ) break;
1259 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001260 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1261 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001262 }
drhe05461c2015-12-30 13:36:57 +00001263 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001264 break;
1265 }
persicom1d0b8722002-04-18 02:53:04 +00001266 }
drh75897232000-05-29 14:26:00 +00001267 return 0;
1268}
1269
1270/*
shane626a6e42009-10-22 17:30:15 +00001271** This is the callback routine that the SQLite library
1272** invokes for each row of a query result.
1273*/
1274static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1275 /* since we don't have type info, call the shell_callback with a NULL value */
1276 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1277}
1278
1279/*
drhdcd87a92014-08-18 13:45:42 +00001280** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001281** the name of the table given. Escape any quote characters in the
1282** table name.
1283*/
drhdcd87a92014-08-18 13:45:42 +00001284static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001285 int i, n;
1286 int needQuote;
1287 char *z;
1288
1289 if( p->zDestTable ){
1290 free(p->zDestTable);
1291 p->zDestTable = 0;
1292 }
1293 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001294 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001295 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001296 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001297 needQuote = 1;
1298 if( zName[i]=='\'' ) n++;
1299 }
1300 }
1301 if( needQuote ) n += 2;
1302 z = p->zDestTable = malloc( n+1 );
1303 if( z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001304 raw_printf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001305 exit(1);
1306 }
1307 n = 0;
1308 if( needQuote ) z[n++] = '\'';
1309 for(i=0; zName[i]; i++){
1310 z[n++] = zName[i];
1311 if( zName[i]=='\'' ) z[n++] = '\'';
1312 }
1313 if( needQuote ) z[n++] = '\'';
1314 z[n] = 0;
1315}
1316
danielk19772a02e332004-06-05 08:04:36 +00001317/* zIn is either a pointer to a NULL-terminated string in memory obtained
1318** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1319** added to zIn, and the result returned in memory obtained from malloc().
1320** zIn, if it was not NULL, is freed.
1321**
mistachkin1fe36bb2016-04-04 02:16:44 +00001322** If the third argument, quote, is not '\0', then it is used as a
danielk19772a02e332004-06-05 08:04:36 +00001323** quote character for zAppend.
1324*/
drhc28490c2006-10-26 14:25:58 +00001325static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001326 int len;
1327 int i;
drh4f21c4a2008-12-10 22:15:00 +00001328 int nAppend = strlen30(zAppend);
1329 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001330
1331 len = nAppend+nIn+1;
1332 if( quote ){
1333 len += 2;
1334 for(i=0; i<nAppend; i++){
1335 if( zAppend[i]==quote ) len++;
1336 }
1337 }
1338
1339 zIn = (char *)realloc(zIn, len);
1340 if( !zIn ){
1341 return 0;
1342 }
1343
1344 if( quote ){
1345 char *zCsr = &zIn[nIn];
1346 *zCsr++ = quote;
1347 for(i=0; i<nAppend; i++){
1348 *zCsr++ = zAppend[i];
1349 if( zAppend[i]==quote ) *zCsr++ = quote;
1350 }
1351 *zCsr++ = quote;
1352 *zCsr++ = '\0';
1353 assert( (zCsr-zIn)==len );
1354 }else{
1355 memcpy(&zIn[nIn], zAppend, nAppend);
1356 zIn[len-1] = '\0';
1357 }
1358
1359 return zIn;
1360}
1361
drhdd3d4592004-08-30 01:54:05 +00001362
1363/*
drhb21a8e42012-01-28 21:08:51 +00001364** Execute a query statement that will generate SQL output. Print
1365** the result columns, comma-separated, on a line and then add a
1366** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001367**
drhb21a8e42012-01-28 21:08:51 +00001368** If the number of columns is 1 and that column contains text "--"
mistachkin1fe36bb2016-04-04 02:16:44 +00001369** then write the semicolon on a separate line. That way, if a
drhb21a8e42012-01-28 21:08:51 +00001370** "--" comment occurs at the end of the statement, the comment
1371** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001372*/
drh157e29a2009-05-21 15:15:00 +00001373static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001374 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001375 const char *zSelect, /* SELECT statement to extract content */
1376 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001377){
drhdd3d4592004-08-30 01:54:05 +00001378 sqlite3_stmt *pSelect;
1379 int rc;
drhb21a8e42012-01-28 21:08:51 +00001380 int nResult;
1381 int i;
1382 const char *z;
drhc7181902014-02-27 15:04:13 +00001383 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001384 if( rc!=SQLITE_OK || !pSelect ){
mistachkinaae280e2015-12-31 19:06:24 +00001385 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1386 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001387 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001388 return rc;
1389 }
1390 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001391 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001392 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001393 if( zFirstRow ){
drhe05461c2015-12-30 13:36:57 +00001394 utf8_printf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001395 zFirstRow = 0;
1396 }
drhb21a8e42012-01-28 21:08:51 +00001397 z = (const char*)sqlite3_column_text(pSelect, 0);
drhe05461c2015-12-30 13:36:57 +00001398 utf8_printf(p->out, "%s", z);
mistachkin1fe36bb2016-04-04 02:16:44 +00001399 for(i=1; i<nResult; i++){
drhe05461c2015-12-30 13:36:57 +00001400 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
drhb21a8e42012-01-28 21:08:51 +00001401 }
1402 if( z==0 ) z = "";
1403 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1404 if( z[0] ){
mistachkinaae280e2015-12-31 19:06:24 +00001405 raw_printf(p->out, "\n;\n");
drhb21a8e42012-01-28 21:08:51 +00001406 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001407 raw_printf(p->out, ";\n");
mistachkin1fe36bb2016-04-04 02:16:44 +00001408 }
drhdd3d4592004-08-30 01:54:05 +00001409 rc = sqlite3_step(pSelect);
1410 }
drh2f464a02011-10-13 00:41:49 +00001411 rc = sqlite3_finalize(pSelect);
1412 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00001413 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1414 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001415 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001416 }
1417 return rc;
drhdd3d4592004-08-30 01:54:05 +00001418}
1419
shane626a6e42009-10-22 17:30:15 +00001420/*
1421** Allocate space and save off current error string.
1422*/
1423static char *save_err_msg(
1424 sqlite3 *db /* Database to query */
1425){
1426 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001427 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001428 if( zErrMsg ){
1429 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1430 }
1431 return zErrMsg;
1432}
1433
drh34784902016-02-27 17:12:36 +00001434#ifdef __linux__
1435/*
1436** Attempt to display I/O stats on Linux using /proc/PID/io
1437*/
1438static void displayLinuxIoStats(FILE *out){
1439 FILE *in;
1440 char z[200];
1441 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
1442 in = fopen(z, "rb");
1443 if( in==0 ) return;
1444 while( fgets(z, sizeof(z), in)!=0 ){
1445 static const struct {
1446 const char *zPattern;
1447 const char *zDesc;
1448 } aTrans[] = {
drhfc1a84c2016-02-27 19:19:22 +00001449 { "rchar: ", "Bytes received by read():" },
1450 { "wchar: ", "Bytes sent to write():" },
1451 { "syscr: ", "Read() system calls:" },
1452 { "syscw: ", "Write() system calls:" },
1453 { "read_bytes: ", "Bytes read from storage:" },
1454 { "write_bytes: ", "Bytes written to storage:" },
1455 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
drh34784902016-02-27 17:12:36 +00001456 };
1457 int i;
1458 for(i=0; i<ArraySize(aTrans); i++){
1459 int n = (int)strlen(aTrans[i].zPattern);
1460 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
mistachkin8145fc62016-09-16 20:39:21 +00001461 utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
drh34784902016-02-27 17:12:36 +00001462 break;
1463 }
1464 }
1465 }
1466 fclose(in);
mistachkin1fe36bb2016-04-04 02:16:44 +00001467}
drh34784902016-02-27 17:12:36 +00001468#endif
1469
1470
shane626a6e42009-10-22 17:30:15 +00001471/*
shaneh642d8b82010-07-28 16:05:34 +00001472** Display memory stats.
1473*/
1474static int display_stats(
1475 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001476 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001477 int bReset /* True to reset the stats */
1478){
1479 int iCur;
1480 int iHiwtr;
1481
1482 if( pArg && pArg->out ){
mistachkin1fe36bb2016-04-04 02:16:44 +00001483
shaneh642d8b82010-07-28 16:05:34 +00001484 iHiwtr = iCur = -1;
1485 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001486 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001487 "Memory Used: %d (max %d) bytes\n",
1488 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001489 iHiwtr = iCur = -1;
1490 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001491 raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001492 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001493 if( pArg->shellFlgs & SHFLG_Pagecache ){
1494 iHiwtr = iCur = -1;
1495 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001496 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001497 "Number of Pcache Pages Used: %d (max %d) pages\n",
1498 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001499 }
shaneh642d8b82010-07-28 16:05:34 +00001500 iHiwtr = iCur = -1;
1501 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001502 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001503 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1504 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001505 if( pArg->shellFlgs & SHFLG_Scratch ){
1506 iHiwtr = iCur = -1;
1507 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001508 raw_printf(pArg->out,
1509 "Number of Scratch Allocations Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001510 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001511 }
shaneh642d8b82010-07-28 16:05:34 +00001512 iHiwtr = iCur = -1;
1513 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001514 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001515 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1516 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001517 iHiwtr = iCur = -1;
1518 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001519 raw_printf(pArg->out, "Largest Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001520 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001521 iHiwtr = iCur = -1;
1522 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001523 raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001524 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001525 iHiwtr = iCur = -1;
1526 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001527 raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001528 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001529#ifdef YYTRACKMAXSTACKDEPTH
1530 iHiwtr = iCur = -1;
1531 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001532 raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001533 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001534#endif
1535 }
1536
1537 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001538 if( pArg->shellFlgs & SHFLG_Lookaside ){
1539 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001540 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1541 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001542 raw_printf(pArg->out,
1543 "Lookaside Slots Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001544 iCur, iHiwtr);
1545 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1546 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001547 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
1548 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001549 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1550 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001551 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
1552 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001553 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1554 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001555 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
1556 iHiwtr);
drh44dec872014-08-30 15:49:25 +00001557 }
shaneh642d8b82010-07-28 16:05:34 +00001558 iHiwtr = iCur = -1;
1559 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001560 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
1561 iCur);
drh4ace5362014-11-10 14:42:28 +00001562 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001563 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001564 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
drhc78e6e42011-09-23 18:58:23 +00001565 iHiwtr = iCur = -1;
1566 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001567 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001568 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001569 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001570 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
drhfbbcd5d2012-03-24 20:09:33 +00001571 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001572 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001573 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001574 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001575 iHiwtr = iCur = -1;
1576 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001577 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001578 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001579 }
1580
1581 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001582 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1583 bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001584 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001585 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001586 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001587 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001588 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001589 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001590 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001591 }
1592
drh34784902016-02-27 17:12:36 +00001593#ifdef __linux__
1594 displayLinuxIoStats(pArg->out);
1595#endif
1596
dan5a790282015-08-07 20:06:14 +00001597 /* Do not remove this machine readable comment: extra-stats-output-here */
1598
shaneh642d8b82010-07-28 16:05:34 +00001599 return 0;
1600}
1601
1602/*
dan8d1edb92014-11-05 09:07:28 +00001603** Display scan stats.
1604*/
1605static void display_scanstats(
1606 sqlite3 *db, /* Database to query */
1607 ShellState *pArg /* Pointer to ShellState */
1608){
drhf5ed7ad2015-06-15 14:43:25 +00001609#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1610 UNUSED_PARAMETER(db);
1611 UNUSED_PARAMETER(pArg);
1612#else
drh15f23c22014-11-06 12:46:16 +00001613 int i, k, n, mx;
mistachkinaae280e2015-12-31 19:06:24 +00001614 raw_printf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001615 mx = 0;
1616 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001617 double rEstLoop = 1.0;
1618 for(i=n=0; 1; i++){
1619 sqlite3_stmt *p = pArg->pStmt;
1620 sqlite3_int64 nLoop, nVisit;
1621 double rEst;
1622 int iSid;
1623 const char *zExplain;
1624 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1625 break;
1626 }
1627 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001628 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001629 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001630 if( n==0 ){
1631 rEstLoop = (double)nLoop;
mistachkinaae280e2015-12-31 19:06:24 +00001632 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001633 }
drh42f30bc2014-11-06 12:08:21 +00001634 n++;
1635 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1636 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1637 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
drhe05461c2015-12-30 13:36:57 +00001638 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
drh42f30bc2014-11-06 12:08:21 +00001639 rEstLoop *= rEst;
mistachkin1fe36bb2016-04-04 02:16:44 +00001640 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001641 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001642 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001643 );
dan8d1edb92014-11-05 09:07:28 +00001644 }
dan8d1edb92014-11-05 09:07:28 +00001645 }
mistachkinaae280e2015-12-31 19:06:24 +00001646 raw_printf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001647#endif
dan8d1edb92014-11-05 09:07:28 +00001648}
1649
1650/*
dana98bf362013-11-13 18:35:01 +00001651** Parameter azArray points to a zero-terminated array of strings. zStr
1652** points to a single nul-terminated string. Return non-zero if zStr
1653** is equal, according to strcmp(), to any of the strings in the array.
1654** Otherwise, return zero.
1655*/
1656static int str_in_array(const char *zStr, const char **azArray){
1657 int i;
1658 for(i=0; azArray[i]; i++){
1659 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1660 }
1661 return 0;
1662}
1663
1664/*
1665** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001666** and populate the ShellState.aiIndent[] array with the number of
mistachkin1fe36bb2016-04-04 02:16:44 +00001667** spaces each opcode should be indented before it is output.
dana98bf362013-11-13 18:35:01 +00001668**
1669** The indenting rules are:
1670**
1671** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1672** all opcodes that occur between the p2 jump destination and the opcode
1673** itself by 2 spaces.
1674**
drh01752bc2013-11-14 23:59:33 +00001675** * For each "Goto", if the jump destination is earlier in the program
1676** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001677** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001678** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001679** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001680** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001681*/
drhdcd87a92014-08-18 13:45:42 +00001682static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001683 const char *zSql; /* The text of the SQL statement */
1684 const char *z; /* Used to check if this is an EXPLAIN */
1685 int *abYield = 0; /* True if op is an OP_Yield */
1686 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001687 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001688
drh8ad0de32014-03-20 18:45:27 +00001689 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1690 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001691 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1692 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001693 const char *azGoto[] = { "Goto", 0 };
1694
1695 /* Try to figure out if this is really an EXPLAIN statement. If this
1696 ** cannot be verified, return early. */
drh87a24aa2016-02-09 20:04:07 +00001697 if( sqlite3_column_count(pSql)!=8 ){
1698 p->cMode = p->mode;
1699 return;
1700 }
dana98bf362013-11-13 18:35:01 +00001701 zSql = sqlite3_sql(pSql);
1702 if( zSql==0 ) return;
1703 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
drh87a24aa2016-02-09 20:04:07 +00001704 if( sqlite3_strnicmp(z, "explain", 7) ){
1705 p->cMode = p->mode;
1706 return;
1707 }
dana98bf362013-11-13 18:35:01 +00001708
1709 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1710 int i;
danc4650bb2013-11-18 08:41:06 +00001711 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001712 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001713
1714 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1715 ** p2 is an instruction address, set variable p2op to the index of that
1716 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1717 ** the current instruction is part of a sub-program generated by an
1718 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001719 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001720 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001721
1722 /* Grow the p->aiIndent array as required */
1723 if( iOp>=nAlloc ){
drh87a24aa2016-02-09 20:04:07 +00001724 if( iOp==0 ){
1725 /* Do further verfication that this is explain output. Abort if
1726 ** it is not */
1727 static const char *explainCols[] = {
1728 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
1729 int jj;
1730 for(jj=0; jj<ArraySize(explainCols); jj++){
1731 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
1732 p->cMode = p->mode;
1733 sqlite3_reset(pSql);
1734 return;
1735 }
1736 }
1737 }
dana98bf362013-11-13 18:35:01 +00001738 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001739 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1740 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001741 }
1742 abYield[iOp] = str_in_array(zOp, azYield);
1743 p->aiIndent[iOp] = 0;
1744 p->nIndent = iOp+1;
1745
1746 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001747 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001748 }
drhfe705102014-03-06 13:38:37 +00001749 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1750 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1751 ){
drheacd29d2016-04-15 15:03:27 +00001752 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001753 }
1754 }
1755
danc4650bb2013-11-18 08:41:06 +00001756 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001757 sqlite3_free(abYield);
1758 sqlite3_reset(pSql);
1759}
1760
1761/*
1762** Free the array allocated by explain_data_prepare().
1763*/
drhdcd87a92014-08-18 13:45:42 +00001764static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001765 sqlite3_free(p->aiIndent);
1766 p->aiIndent = 0;
1767 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001768 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001769}
1770
1771/*
drheacd29d2016-04-15 15:03:27 +00001772** Disable and restore .wheretrace and .selecttrace settings.
1773*/
1774#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1775extern int sqlite3SelectTrace;
1776static int savedSelectTrace;
1777#endif
1778#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1779extern int sqlite3WhereTrace;
1780static int savedWhereTrace;
1781#endif
1782static void disable_debug_trace_modes(void){
1783#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1784 savedSelectTrace = sqlite3SelectTrace;
1785 sqlite3SelectTrace = 0;
1786#endif
1787#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1788 savedWhereTrace = sqlite3WhereTrace;
1789 sqlite3WhereTrace = 0;
1790#endif
1791}
1792static void restore_debug_trace_modes(void){
1793#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1794 sqlite3SelectTrace = savedSelectTrace;
1795#endif
1796#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1797 sqlite3WhereTrace = savedWhereTrace;
1798#endif
1799}
1800
1801/*
1802** Run a prepared statement
1803*/
1804static void exec_prepared_stmt(
1805 ShellState *pArg, /* Pointer to ShellState */
1806 sqlite3_stmt *pStmt, /* Statment to run */
1807 int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
1808){
1809 int rc;
1810
1811 /* perform the first step. this will tell us if we
1812 ** have a result set or not and how wide it is.
1813 */
1814 rc = sqlite3_step(pStmt);
1815 /* if we have a result set... */
1816 if( SQLITE_ROW == rc ){
1817 /* if we have a callback... */
1818 if( xCallback ){
1819 /* allocate space for col name ptr, value ptr, and type */
1820 int nCol = sqlite3_column_count(pStmt);
1821 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
1822 if( !pData ){
1823 rc = SQLITE_NOMEM;
1824 }else{
1825 char **azCols = (char **)pData; /* Names of result columns */
1826 char **azVals = &azCols[nCol]; /* Results */
1827 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1828 int i, x;
1829 assert(sizeof(int) <= sizeof(char *));
1830 /* save off ptrs to column names */
1831 for(i=0; i<nCol; i++){
1832 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1833 }
1834 do{
1835 /* extract the data and data types */
1836 for(i=0; i<nCol; i++){
1837 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1838 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
1839 azVals[i] = "";
1840 }else{
1841 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1842 }
1843 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1844 rc = SQLITE_NOMEM;
1845 break; /* from for */
1846 }
1847 } /* end for */
1848
1849 /* if data and types extracted successfully... */
1850 if( SQLITE_ROW == rc ){
1851 /* call the supplied callback with the result row data */
1852 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1853 rc = SQLITE_ABORT;
1854 }else{
1855 rc = sqlite3_step(pStmt);
1856 }
1857 }
1858 } while( SQLITE_ROW == rc );
1859 sqlite3_free(pData);
1860 }
1861 }else{
1862 do{
1863 rc = sqlite3_step(pStmt);
1864 } while( rc == SQLITE_ROW );
1865 }
1866 }
1867}
1868
1869/*
mistachkin1fe36bb2016-04-04 02:16:44 +00001870** Execute a statement or set of statements. Print
1871** any result rows/columns depending on the current mode
shane626a6e42009-10-22 17:30:15 +00001872** set via the supplied callback.
1873**
mistachkin1fe36bb2016-04-04 02:16:44 +00001874** This is very similar to SQLite's built-in sqlite3_exec()
1875** function except it takes a slightly different callback
shane626a6e42009-10-22 17:30:15 +00001876** and callback data argument.
1877*/
1878static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001879 sqlite3 *db, /* An open database */
1880 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001881 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001882 /* (not the same as sqlite3_exec) */
1883 ShellState *pArg, /* Pointer to ShellState */
1884 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001885){
dan4564ced2010-01-05 04:59:56 +00001886 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1887 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001888 int rc2;
dan4564ced2010-01-05 04:59:56 +00001889 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001890
1891 if( pzErrMsg ){
1892 *pzErrMsg = NULL;
1893 }
1894
shaneb9fc17d2009-10-22 21:23:35 +00001895 while( zSql[0] && (SQLITE_OK == rc) ){
drheacd29d2016-04-15 15:03:27 +00001896 static const char *zStmtSql;
shaneb9fc17d2009-10-22 21:23:35 +00001897 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1898 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001899 if( pzErrMsg ){
1900 *pzErrMsg = save_err_msg(db);
1901 }
1902 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001903 if( !pStmt ){
1904 /* this happens for a comment or white-space */
1905 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001906 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001907 continue;
1908 }
drheacd29d2016-04-15 15:03:27 +00001909 zStmtSql = sqlite3_sql(pStmt);
drh60275612016-11-03 02:25:30 +00001910 if( zStmtSql==0 ) zStmtSql = "";
drheacd29d2016-04-15 15:03:27 +00001911 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
shane626a6e42009-10-22 17:30:15 +00001912
shaneh642d8b82010-07-28 16:05:34 +00001913 /* save off the prepared statment handle and reset row count */
1914 if( pArg ){
1915 pArg->pStmt = pStmt;
1916 pArg->cnt = 0;
1917 }
1918
shanehb7977c52010-01-18 18:17:10 +00001919 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001920 if( pArg && pArg->echoOn ){
drhe05461c2015-12-30 13:36:57 +00001921 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001922 }
shanehb7977c52010-01-18 18:17:10 +00001923
drhefbf3b12014-02-28 20:47:24 +00001924 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
drheacd29d2016-04-15 15:03:27 +00001925 if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
drhefbf3b12014-02-28 20:47:24 +00001926 sqlite3_stmt *pExplain;
drheacd29d2016-04-15 15:03:27 +00001927 char *zEQP;
1928 disable_debug_trace_modes();
1929 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
drhefbf3b12014-02-28 20:47:24 +00001930 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1931 if( rc==SQLITE_OK ){
1932 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001933 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1934 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1935 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001936 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001937 }
1938 }
1939 sqlite3_finalize(pExplain);
1940 sqlite3_free(zEQP);
drheacd29d2016-04-15 15:03:27 +00001941 if( pArg->autoEQP>=2 ){
1942 /* Also do an EXPLAIN for ".eqp full" mode */
1943 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
1944 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1945 if( rc==SQLITE_OK ){
1946 pArg->cMode = MODE_Explain;
1947 explain_data_prepare(pArg, pExplain);
1948 exec_prepared_stmt(pArg, pExplain, xCallback);
1949 explain_data_delete(pArg);
1950 }
1951 sqlite3_finalize(pExplain);
1952 sqlite3_free(zEQP);
1953 }
1954 restore_debug_trace_modes();
drhefbf3b12014-02-28 20:47:24 +00001955 }
1956
drh700c2522016-02-09 18:39:25 +00001957 if( pArg ){
1958 pArg->cMode = pArg->mode;
drh87a24aa2016-02-09 20:04:07 +00001959 if( pArg->autoExplain
1960 && sqlite3_column_count(pStmt)==8
drheacd29d2016-04-15 15:03:27 +00001961 && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
drh700c2522016-02-09 18:39:25 +00001962 ){
1963 pArg->cMode = MODE_Explain;
1964 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001965
drh700c2522016-02-09 18:39:25 +00001966 /* If the shell is currently in ".explain" mode, gather the extra
1967 ** data required to add indents to the output.*/
1968 if( pArg->cMode==MODE_Explain ){
1969 explain_data_prepare(pArg, pStmt);
1970 }
dana98bf362013-11-13 18:35:01 +00001971 }
1972
drheacd29d2016-04-15 15:03:27 +00001973 exec_prepared_stmt(pArg, pStmt, xCallback);
dana98bf362013-11-13 18:35:01 +00001974 explain_data_delete(pArg);
1975
shaneh642d8b82010-07-28 16:05:34 +00001976 /* print usage stats if stats on */
1977 if( pArg && pArg->statsOn ){
1978 display_stats(db, pArg, 0);
1979 }
1980
dan8d1edb92014-11-05 09:07:28 +00001981 /* print loop-counters if required */
1982 if( pArg && pArg->scanstatsOn ){
1983 display_scanstats(db, pArg);
1984 }
1985
mistachkin1fe36bb2016-04-04 02:16:44 +00001986 /* Finalize the statement just executed. If this fails, save a
dan4564ced2010-01-05 04:59:56 +00001987 ** copy of the error message. Otherwise, set zSql to point to the
1988 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001989 rc2 = sqlite3_finalize(pStmt);
1990 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001991 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001992 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001993 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001994 }else if( pzErrMsg ){
1995 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001996 }
shaneh642d8b82010-07-28 16:05:34 +00001997
1998 /* clear saved stmt handle */
1999 if( pArg ){
2000 pArg->pStmt = NULL;
2001 }
shane626a6e42009-10-22 17:30:15 +00002002 }
shaneb9fc17d2009-10-22 21:23:35 +00002003 } /* end while */
shane626a6e42009-10-22 17:30:15 +00002004
2005 return rc;
2006}
2007
drhdd3d4592004-08-30 01:54:05 +00002008
drh33048c02001-10-01 14:29:22 +00002009/*
drh4c653a02000-06-07 01:27:47 +00002010** This is a different callback routine used for dumping the database.
2011** Each row received by this callback consists of a table name,
2012** the table type ("index" or "table") and SQL to create the table.
2013** This routine should print text sufficient to recreate the table.
2014*/
2015static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00002016 int rc;
2017 const char *zTable;
2018 const char *zType;
2019 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00002020 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00002021 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00002022
drh902b9ee2008-12-05 17:17:07 +00002023 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00002024 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00002025 zTable = azArg[0];
2026 zType = azArg[1];
2027 zSql = azArg[2];
mistachkin1fe36bb2016-04-04 02:16:44 +00002028
drh00b950d2005-09-11 02:03:03 +00002029 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00002030 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00002031 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002032 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00002033 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
2034 return 0;
drh45e29d82006-11-20 16:21:10 +00002035 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
2036 char *zIns;
2037 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00002038 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00002039 p->writableSchema = 1;
2040 }
2041 zIns = sqlite3_mprintf(
2042 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
2043 "VALUES('table','%q','%q',0,'%q');",
2044 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00002045 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00002046 sqlite3_free(zIns);
2047 return 0;
drh00b950d2005-09-11 02:03:03 +00002048 }else{
drhe05461c2015-12-30 13:36:57 +00002049 utf8_printf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00002050 }
danielk19772a02e332004-06-05 08:04:36 +00002051
2052 if( strcmp(zType, "table")==0 ){
2053 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00002054 char *zSelect = 0;
2055 char *zTableInfo = 0;
2056 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00002057 int nRow = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +00002058
danielk19772a02e332004-06-05 08:04:36 +00002059 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
2060 zTableInfo = appendText(zTableInfo, zTable, '"');
2061 zTableInfo = appendText(zTableInfo, ");", 0);
2062
drhc7181902014-02-27 15:04:13 +00002063 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00002064 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00002065 if( rc!=SQLITE_OK || !pTableInfo ){
2066 return 1;
2067 }
2068
2069 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00002070 /* Always quote the table name, even if it appears to be pure ascii,
2071 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
2072 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00002073 if( zTmp ){
2074 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00002075 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00002076 }
2077 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
2078 rc = sqlite3_step(pTableInfo);
2079 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00002080 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00002081 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00002082 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00002083 rc = sqlite3_step(pTableInfo);
2084 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00002085 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00002086 }else{
2087 zSelect = appendText(zSelect, ") ", 0);
2088 }
drh157e29a2009-05-21 15:15:00 +00002089 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00002090 }
2091 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00002092 if( rc!=SQLITE_OK || nRow==0 ){
2093 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00002094 return 1;
2095 }
2096 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
2097 zSelect = appendText(zSelect, zTable, '"');
2098
drh2f464a02011-10-13 00:41:49 +00002099 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00002100 if( rc==SQLITE_CORRUPT ){
2101 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00002102 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00002103 }
drh85e72432012-04-11 11:38:53 +00002104 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00002105 }
drh4c653a02000-06-07 01:27:47 +00002106 return 0;
2107}
2108
2109/*
drh45e29d82006-11-20 16:21:10 +00002110** Run zQuery. Use dump_callback() as the callback routine so that
2111** the contents of the query are output as SQL statements.
2112**
drhdd3d4592004-08-30 01:54:05 +00002113** If we get a SQLITE_CORRUPT error, rerun the query after appending
2114** "ORDER BY rowid DESC" to the end.
2115*/
2116static int run_schema_dump_query(
mistachkin1fe36bb2016-04-04 02:16:44 +00002117 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00002118 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00002119){
2120 int rc;
drh2f464a02011-10-13 00:41:49 +00002121 char *zErr = 0;
2122 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00002123 if( rc==SQLITE_CORRUPT ){
2124 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00002125 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00002126 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00002127 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00002128 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002129 sqlite3_free(zErr);
2130 zErr = 0;
2131 }
drhdd3d4592004-08-30 01:54:05 +00002132 zQ2 = malloc( len+100 );
2133 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00002134 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00002135 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
2136 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002137 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002138 }else{
2139 rc = SQLITE_CORRUPT;
2140 }
2141 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00002142 free(zQ2);
2143 }
2144 return rc;
2145}
2146
2147/*
drh75897232000-05-29 14:26:00 +00002148** Text of a help message
2149*/
persicom1d0b8722002-04-18 02:53:04 +00002150static char zHelp[] =
drha0daa752016-09-16 11:53:10 +00002151#ifndef SQLITE_OMIT_AUTHORIZATION
drhde613c62016-04-04 17:23:10 +00002152 ".auth ON|OFF Show authorizer callbacks\n"
drha0daa752016-09-16 11:53:10 +00002153#endif
drh9ff849f2009-02-04 20:55:57 +00002154 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00002155 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00002156 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00002157 ".changes on|off Show number of rows changed by SQL\n"
drh2db82112016-09-15 21:35:24 +00002158 ".check GLOB Fail if output since .testcase does not match\n"
drh4bbcf102014-02-06 02:46:08 +00002159 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00002160 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00002161 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00002162 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00002163 " If TABLE specified, only dump tables matching\n"
2164 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00002165 ".echo on|off Turn command echo on or off\n"
drheacd29d2016-04-15 15:03:27 +00002166 ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00002167 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00002168 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drh4926fec2016-04-13 15:33:42 +00002169 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00002170 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00002171 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00002172 ".import FILE TABLE Import data from FILE into TABLE\n"
drh16eb5942016-11-03 13:01:38 +00002173#ifndef SQLITE_OMIT_TEST_CONTROL
2174 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n"
2175#endif
drh0e55db12015-02-06 14:51:13 +00002176 ".indexes ?TABLE? Show names of all indexes\n"
2177 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00002178 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00002179#ifdef SQLITE_ENABLE_IOTRACE
2180 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
2181#endif
drh1a513372015-05-02 17:40:23 +00002182 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00002183#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002184 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00002185#endif
drh127f9d72010-02-23 01:47:00 +00002186 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00002187 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00002188 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00002189 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00002190 " column Left-aligned columns. (See .width)\n"
2191 " html HTML <table> code\n"
2192 " insert SQL insert statements for TABLE\n"
2193 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00002194 " list Values delimited by .separator strings\n"
drh41f5f6e2016-10-21 17:39:30 +00002195 " quote Escape answers as for SQL\n"
drhb860bc92004-08-04 15:16:55 +00002196 " tabs Tab-separated values\n"
2197 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00002198 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00002199 ".once FILENAME Output for the next SQL command only to FILENAME\n"
mistachkin8145fc62016-09-16 20:39:21 +00002200 ".open ?--new? ?FILE? Close existing database and reopen FILE\n"
drhcd0509e2016-09-16 00:26:08 +00002201 " The --new starts with an empty file\n"
drhc2ce0be2014-05-29 12:36:14 +00002202 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00002203 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002204 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002205 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00002206 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00002207 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00002208 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00002209 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh4926fec2016-04-13 15:33:42 +00002210 ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
2211 " Add --indent for pretty-printing\n"
mistachkine0d68852014-12-11 03:12:33 +00002212 ".separator COL ?ROW? Change the column separator and optionally the row\n"
2213 " separator for both the output mode and .import\n"
drhe6229612014-08-18 15:08:26 +00002214#if defined(SQLITE_ENABLE_SESSION)
2215 ".session CMD ... Create or control sessions\n"
2216#endif
drh62cdde52014-05-28 20:22:28 +00002217 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00002218 ".show Show the current values for various settings\n"
drh34784902016-02-27 17:12:36 +00002219 ".stats ?on|off? Show stats or turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00002220 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00002221 ".tables ?TABLE? List names of tables\n"
2222 " If TABLE specified, only list tables matching\n"
2223 " LIKE pattern TABLE.\n"
drh760c8162016-09-16 02:52:22 +00002224 ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
drh2dfbbca2000-07-28 14:32:48 +00002225 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00002226 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00002227 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00002228 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00002229 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00002230 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00002231 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00002232 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00002233;
2234
drhe6229612014-08-18 15:08:26 +00002235#if defined(SQLITE_ENABLE_SESSION)
2236/*
2237** Print help information for the ".sessions" command
2238*/
2239void session_help(ShellState *p){
mistachkin899c5c92016-04-03 20:50:02 +00002240 raw_printf(p->out,
drhe6229612014-08-18 15:08:26 +00002241 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
2242 "If ?NAME? is omitted, the first defined session is used.\n"
2243 "Subcommands:\n"
2244 " attach TABLE Attach TABLE\n"
2245 " changeset FILE Write a changeset into FILE\n"
2246 " close Close one session\n"
2247 " enable ?BOOLEAN? Set or query the enable bit\n"
mistachkin1fe36bb2016-04-04 02:16:44 +00002248 " filter GLOB... Reject tables matching GLOBs\n"
drhe6229612014-08-18 15:08:26 +00002249 " indirect ?BOOLEAN? Mark or query the indirect status\n"
2250 " isempty Query whether the session is empty\n"
2251 " list List currently open session names\n"
2252 " open DB NAME Open a new session on DB\n"
2253 " patchset FILE Write a patchset into FILE\n"
2254 );
2255}
2256#endif
2257
2258
drhdaffd0e2001-04-11 14:28:42 +00002259/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00002260static int process_input(ShellState *p, FILE *in);
drh2db82112016-09-15 21:35:24 +00002261
2262
2263/*
2264** Read the content of a file into memory obtained from sqlite3_malloc64().
2265** The caller is responsible for freeing the memory.
2266**
2267** NULL is returned if any error is encountered.
2268*/
2269static char *readFile(const char *zName){
2270 FILE *in = fopen(zName, "rb");
2271 long nIn;
drhd1459152016-09-16 19:11:03 +00002272 size_t nRead;
drh2db82112016-09-15 21:35:24 +00002273 char *pBuf;
2274 if( in==0 ) return 0;
2275 fseek(in, 0, SEEK_END);
2276 nIn = ftell(in);
2277 rewind(in);
drhd1459152016-09-16 19:11:03 +00002278 pBuf = sqlite3_malloc64( nIn+1 );
drh2db82112016-09-15 21:35:24 +00002279 if( pBuf==0 ) return 0;
drhd1459152016-09-16 19:11:03 +00002280 nRead = fread(pBuf, nIn, 1, in);
2281 fclose(in);
2282 if( nRead!=1 ){
drh2db82112016-09-15 21:35:24 +00002283 sqlite3_free(pBuf);
2284 return 0;
2285 }
drhd1459152016-09-16 19:11:03 +00002286 pBuf[nIn] = 0;
drh2db82112016-09-15 21:35:24 +00002287 return pBuf;
2288}
2289
drhba5b0932014-07-24 12:39:59 +00002290/*
2291** Implementation of the "readfile(X)" SQL function. The entire content
2292** of the file named X is read and returned as a BLOB. NULL is returned
2293** if the file does not exist or is unreadable.
2294*/
2295static void readfileFunc(
2296 sqlite3_context *context,
2297 int argc,
2298 sqlite3_value **argv
2299){
2300 const char *zName;
drhba5b0932014-07-24 12:39:59 +00002301 void *pBuf;
2302
drhf5ed7ad2015-06-15 14:43:25 +00002303 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002304 zName = (const char*)sqlite3_value_text(argv[0]);
2305 if( zName==0 ) return;
drh2db82112016-09-15 21:35:24 +00002306 pBuf = readFile(zName);
2307 if( pBuf ) sqlite3_result_blob(context, pBuf, -1, sqlite3_free);
drhba5b0932014-07-24 12:39:59 +00002308}
2309
2310/*
2311** Implementation of the "writefile(X,Y)" SQL function. The argument Y
2312** is written into file X. The number of bytes written is returned. Or
2313** NULL is returned if something goes wrong, such as being unable to open
2314** file X for writing.
2315*/
2316static void writefileFunc(
2317 sqlite3_context *context,
2318 int argc,
2319 sqlite3_value **argv
2320){
2321 FILE *out;
2322 const char *z;
drhba5b0932014-07-24 12:39:59 +00002323 sqlite3_int64 rc;
2324 const char *zFile;
2325
drhf5ed7ad2015-06-15 14:43:25 +00002326 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002327 zFile = (const char*)sqlite3_value_text(argv[0]);
2328 if( zFile==0 ) return;
2329 out = fopen(zFile, "wb");
2330 if( out==0 ) return;
2331 z = (const char*)sqlite3_value_blob(argv[1]);
2332 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002333 rc = 0;
2334 }else{
drh490fe862014-08-11 14:21:32 +00002335 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002336 }
2337 fclose(out);
2338 sqlite3_result_int64(context, rc);
2339}
drhdaffd0e2001-04-11 14:28:42 +00002340
drhe6229612014-08-18 15:08:26 +00002341#if defined(SQLITE_ENABLE_SESSION)
2342/*
2343** Close a single OpenSession object and release all of its associated
2344** resources.
2345*/
2346static void session_close(OpenSession *pSession){
2347 int i;
2348 sqlite3session_delete(pSession->p);
2349 sqlite3_free(pSession->zName);
2350 for(i=0; i<pSession->nFilter; i++){
2351 sqlite3_free(pSession->azFilter[i]);
2352 }
2353 sqlite3_free(pSession->azFilter);
2354 memset(pSession, 0, sizeof(OpenSession));
2355}
2356#endif
2357
2358/*
drh51b55a32016-04-04 12:38:05 +00002359** Close all OpenSession objects and release all associated resources.
drhe6229612014-08-18 15:08:26 +00002360*/
drhe6229612014-08-18 15:08:26 +00002361#if defined(SQLITE_ENABLE_SESSION)
drh51b55a32016-04-04 12:38:05 +00002362static void session_close_all(ShellState *p){
drhe6229612014-08-18 15:08:26 +00002363 int i;
2364 for(i=0; i<p->nSession; i++){
2365 session_close(&p->aSession[i]);
2366 }
2367 p->nSession = 0;
drhe6229612014-08-18 15:08:26 +00002368}
drh51b55a32016-04-04 12:38:05 +00002369#else
2370# define session_close_all(X)
2371#endif
drhe6229612014-08-18 15:08:26 +00002372
drh75897232000-05-29 14:26:00 +00002373/*
drh03168ca2014-08-18 20:01:31 +00002374** Implementation of the xFilter function for an open session. Omit
2375** any tables named by ".session filter" but let all other table through.
2376*/
2377#if defined(SQLITE_ENABLE_SESSION)
2378static int session_filter(void *pCtx, const char *zTab){
2379 OpenSession *pSession = (OpenSession*)pCtx;
2380 int i;
2381 for(i=0; i<pSession->nFilter; i++){
2382 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
2383 }
2384 return 1;
2385}
2386#endif
2387
2388/*
drh44c2eb12003-04-30 11:38:26 +00002389** Make sure the database is open. If it is not, then open it. If
2390** the database fails to open, print an error message and exit.
2391*/
drhdcd87a92014-08-18 13:45:42 +00002392static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002393 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002394 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002395 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002396 globalDb = p->db;
2397 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2398 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002399 shellstaticFunc, 0, 0);
2400 }
mistachkin8e189222015-04-19 21:43:16 +00002401 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00002402 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002403 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002404 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002405 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002406 }
drhc2e87a32006-06-27 15:16:14 +00002407#ifndef SQLITE_OMIT_LOAD_EXTENSION
2408 sqlite3_enable_load_extension(p->db, 1);
2409#endif
mistachkin8e189222015-04-19 21:43:16 +00002410 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002411 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002412 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002413 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002414 }
2415}
2416
2417/*
drhfeac5f82004-08-01 00:10:45 +00002418** Do C-language style dequoting.
2419**
mistachkinf21979d2015-01-18 05:35:01 +00002420** \a -> alarm
2421** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002422** \t -> tab
2423** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002424** \v -> vertical tab
2425** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002426** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002427** \s -> space
drh4c56b992013-06-27 13:26:55 +00002428** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002429** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002430** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002431** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002432*/
2433static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002434 int i, j;
2435 char c;
drhc2ce0be2014-05-29 12:36:14 +00002436 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002437 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002438 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002439 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002440 if( c=='a' ){
2441 c = '\a';
2442 }else if( c=='b' ){
2443 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002444 }else if( c=='t' ){
2445 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002446 }else if( c=='n' ){
2447 c = '\n';
2448 }else if( c=='v' ){
2449 c = '\v';
2450 }else if( c=='f' ){
2451 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002452 }else if( c=='r' ){
2453 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002454 }else if( c=='"' ){
2455 c = '"';
2456 }else if( c=='\'' ){
2457 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002458 }else if( c=='\\' ){
2459 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002460 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002461 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002462 if( z[i+1]>='0' && z[i+1]<='7' ){
2463 i++;
2464 c = (c<<3) + z[i] - '0';
2465 if( z[i+1]>='0' && z[i+1]<='7' ){
2466 i++;
2467 c = (c<<3) + z[i] - '0';
2468 }
2469 }
2470 }
2471 }
2472 z[j] = c;
2473 }
drhc2ce0be2014-05-29 12:36:14 +00002474 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002475}
2476
2477/*
drh348d19c2013-06-03 12:47:43 +00002478** Return the value of a hexadecimal digit. Return -1 if the input
2479** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002480*/
drh348d19c2013-06-03 12:47:43 +00002481static int hexDigitValue(char c){
2482 if( c>='0' && c<='9' ) return c - '0';
2483 if( c>='a' && c<='f' ) return c - 'a' + 10;
2484 if( c>='A' && c<='F' ) return c - 'A' + 10;
2485 return -1;
drhc28490c2006-10-26 14:25:58 +00002486}
2487
2488/*
drh7d9f3942013-04-03 01:26:54 +00002489** Interpret zArg as an integer value, possibly with suffixes.
2490*/
2491static sqlite3_int64 integerValue(const char *zArg){
2492 sqlite3_int64 v = 0;
2493 static const struct { char *zSuffix; int iMult; } aMult[] = {
2494 { "KiB", 1024 },
2495 { "MiB", 1024*1024 },
2496 { "GiB", 1024*1024*1024 },
2497 { "KB", 1000 },
2498 { "MB", 1000000 },
2499 { "GB", 1000000000 },
2500 { "K", 1000 },
2501 { "M", 1000000 },
2502 { "G", 1000000000 },
2503 };
2504 int i;
2505 int isNeg = 0;
2506 if( zArg[0]=='-' ){
2507 isNeg = 1;
2508 zArg++;
2509 }else if( zArg[0]=='+' ){
2510 zArg++;
2511 }
drh348d19c2013-06-03 12:47:43 +00002512 if( zArg[0]=='0' && zArg[1]=='x' ){
2513 int x;
2514 zArg += 2;
2515 while( (x = hexDigitValue(zArg[0]))>=0 ){
2516 v = (v<<4) + x;
2517 zArg++;
2518 }
2519 }else{
2520 while( IsDigit(zArg[0]) ){
2521 v = v*10 + zArg[0] - '0';
2522 zArg++;
2523 }
drh7d9f3942013-04-03 01:26:54 +00002524 }
drhc2bed0a2013-05-24 11:57:50 +00002525 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002526 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2527 v *= aMult[i].iMult;
2528 break;
2529 }
2530 }
2531 return isNeg? -v : v;
2532}
2533
2534/*
drh348d19c2013-06-03 12:47:43 +00002535** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2536** for TRUE and FALSE. Return the integer value if appropriate.
2537*/
2538static int booleanValue(char *zArg){
2539 int i;
2540 if( zArg[0]=='0' && zArg[1]=='x' ){
2541 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2542 }else{
2543 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2544 }
2545 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2546 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2547 return 1;
2548 }
2549 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2550 return 0;
2551 }
mistachkinaae280e2015-12-31 19:06:24 +00002552 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002553 zArg);
2554 return 0;
2555}
2556
2557/*
drh42f64e52012-04-04 16:56:23 +00002558** Close an output file, assuming it is not stderr or stdout
2559*/
2560static void output_file_close(FILE *f){
2561 if( f && f!=stdout && f!=stderr ) fclose(f);
2562}
2563
2564/*
2565** Try to open an output file. The names "stdout" and "stderr" are
mistachkin1fe36bb2016-04-04 02:16:44 +00002566** recognized and do the right thing. NULL is returned if the output
drh42f64e52012-04-04 16:56:23 +00002567** filename is "off".
2568*/
2569static FILE *output_file_open(const char *zFile){
2570 FILE *f;
2571 if( strcmp(zFile,"stdout")==0 ){
2572 f = stdout;
2573 }else if( strcmp(zFile, "stderr")==0 ){
2574 f = stderr;
2575 }else if( strcmp(zFile, "off")==0 ){
2576 f = 0;
2577 }else{
2578 f = fopen(zFile, "wb");
2579 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002580 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002581 }
2582 }
2583 return f;
2584}
2585
drhc10b9da2016-11-20 17:59:59 +00002586#if !defined(SQLITE_OMIT_BUILTIN_TEST)
2587#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002588/*
2589** A routine for handling output from sqlite3_trace().
2590*/
drh4b363a52016-07-23 20:27:41 +00002591static int sql_trace_callback(
2592 unsigned mType,
2593 void *pArg,
2594 void *pP,
2595 void *pX
2596){
drh42f64e52012-04-04 16:56:23 +00002597 FILE *f = (FILE*)pArg;
drhb0df5402016-08-01 17:06:44 +00002598 UNUSED_PARAMETER(mType);
2599 UNUSED_PARAMETER(pP);
drh4b2590e2014-08-19 19:28:00 +00002600 if( f ){
drh4b363a52016-07-23 20:27:41 +00002601 const char *z = (const char*)pX;
drh4b2590e2014-08-19 19:28:00 +00002602 int i = (int)strlen(z);
2603 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002604 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002605 }
drh4b363a52016-07-23 20:27:41 +00002606 return 0;
drh42f64e52012-04-04 16:56:23 +00002607}
drhc10b9da2016-11-20 17:59:59 +00002608#endif
2609#endif
drh42f64e52012-04-04 16:56:23 +00002610
2611/*
drhd8621b92012-04-17 09:09:33 +00002612** A no-op routine that runs with the ".breakpoint" doc-command. This is
2613** a useful spot to set a debugger breakpoint.
2614*/
2615static void test_breakpoint(void){
2616 static int nCall = 0;
2617 nCall++;
2618}
2619
2620/*
mistachkin636bf9f2014-07-19 20:15:16 +00002621** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002622*/
mistachkin636bf9f2014-07-19 20:15:16 +00002623typedef struct ImportCtx ImportCtx;
2624struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002625 const char *zFile; /* Name of the input file */
2626 FILE *in; /* Read the CSV text from this input stream */
2627 char *z; /* Accumulated text for a field */
2628 int n; /* Number of bytes in z */
2629 int nAlloc; /* Space allocated for z[] */
2630 int nLine; /* Current line number */
2631 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002632 int cColSep; /* The column separator character. (Usually ",") */
2633 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002634};
2635
2636/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002637static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002638 if( p->n+1>=p->nAlloc ){
2639 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002640 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002641 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002642 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002643 exit(1);
2644 }
2645 }
2646 p->z[p->n++] = (char)c;
2647}
2648
2649/* Read a single field of CSV text. Compatible with rfc4180 and extended
2650** with the option of having a separator other than ",".
2651**
2652** + Input comes from p->in.
2653** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002654** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002655** + Use p->cSep as the column separator. The default is ",".
2656** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002657** + Keep track of the line number in p->nLine.
2658** + Store the character that terminates the field in p->cTerm. Store
2659** EOF on end-of-file.
2660** + Report syntax errors on stderr
2661*/
mistachkin44723ce2015-03-21 02:22:37 +00002662static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002663 int c;
2664 int cSep = p->cColSep;
2665 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002666 p->n = 0;
2667 c = fgetc(p->in);
2668 if( c==EOF || seenInterrupt ){
2669 p->cTerm = EOF;
2670 return 0;
2671 }
2672 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002673 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002674 int startLine = p->nLine;
2675 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002676 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002677 while( 1 ){
2678 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002679 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002680 if( c==cQuote ){
2681 if( pc==cQuote ){
2682 pc = 0;
2683 continue;
2684 }
2685 }
2686 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002687 || (c==rSep && pc==cQuote)
2688 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002689 || (c==EOF && pc==cQuote)
2690 ){
2691 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002692 p->cTerm = c;
2693 break;
2694 }
2695 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002696 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002697 p->zFile, p->nLine, cQuote);
2698 }
2699 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002700 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002701 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002702 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002703 break;
2704 }
mistachkin636bf9f2014-07-19 20:15:16 +00002705 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002706 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002707 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002708 }
drhdb95f682013-06-26 22:46:00 +00002709 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002710 while( c!=EOF && c!=cSep && c!=rSep ){
2711 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002712 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002713 }
mistachkin636bf9f2014-07-19 20:15:16 +00002714 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002715 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002716 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002717 }
drhdb95f682013-06-26 22:46:00 +00002718 p->cTerm = c;
2719 }
drh8dd675e2013-07-12 21:09:24 +00002720 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002721 return p->z;
2722}
2723
mistachkin636bf9f2014-07-19 20:15:16 +00002724/* Read a single field of ASCII delimited text.
2725**
2726** + Input comes from p->in.
2727** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002728** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002729** + Use p->cSep as the column separator. The default is "\x1F".
2730** + Use p->rSep as the row separator. The default is "\x1E".
2731** + Keep track of the row number in p->nLine.
2732** + Store the character that terminates the field in p->cTerm. Store
2733** EOF on end-of-file.
2734** + Report syntax errors on stderr
2735*/
mistachkin44723ce2015-03-21 02:22:37 +00002736static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002737 int c;
2738 int cSep = p->cColSep;
2739 int rSep = p->cRowSep;
2740 p->n = 0;
2741 c = fgetc(p->in);
2742 if( c==EOF || seenInterrupt ){
2743 p->cTerm = EOF;
2744 return 0;
2745 }
2746 while( c!=EOF && c!=cSep && c!=rSep ){
2747 import_append_char(p, c);
2748 c = fgetc(p->in);
2749 }
2750 if( c==rSep ){
2751 p->nLine++;
2752 }
2753 p->cTerm = c;
2754 if( p->z ) p->z[p->n] = 0;
2755 return p->z;
2756}
2757
drhdb95f682013-06-26 22:46:00 +00002758/*
drh4bbcf102014-02-06 02:46:08 +00002759** Try to transfer data for table zTable. If an error is seen while
2760** moving forward, try to go backwards. The backwards movement won't
2761** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002762*/
mistachkine31ae902014-02-06 01:15:29 +00002763static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002764 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002765 sqlite3 *newDb,
2766 const char *zTable
2767){
mistachkin1fe36bb2016-04-04 02:16:44 +00002768 sqlite3_stmt *pQuery = 0;
drh3350ce92014-02-06 00:49:12 +00002769 sqlite3_stmt *pInsert = 0;
2770 char *zQuery = 0;
2771 char *zInsert = 0;
2772 int rc;
2773 int i, j, n;
2774 int nTable = (int)strlen(zTable);
2775 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002776 int cnt = 0;
2777 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002778
2779 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2780 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2781 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002782 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002783 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2784 zQuery);
2785 goto end_data_xfer;
2786 }
2787 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002788 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002789 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002790 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002791 goto end_data_xfer;
2792 }
2793 sqlite3_snprintf(200+nTable,zInsert,
2794 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2795 i = (int)strlen(zInsert);
2796 for(j=1; j<n; j++){
2797 memcpy(zInsert+i, ",?", 2);
2798 i += 2;
2799 }
2800 memcpy(zInsert+i, ");", 3);
2801 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2802 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002803 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002804 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2805 zQuery);
2806 goto end_data_xfer;
2807 }
2808 for(k=0; k<2; k++){
2809 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2810 for(i=0; i<n; i++){
2811 switch( sqlite3_column_type(pQuery, i) ){
2812 case SQLITE_NULL: {
2813 sqlite3_bind_null(pInsert, i+1);
2814 break;
2815 }
2816 case SQLITE_INTEGER: {
2817 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2818 break;
2819 }
2820 case SQLITE_FLOAT: {
2821 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2822 break;
2823 }
2824 case SQLITE_TEXT: {
2825 sqlite3_bind_text(pInsert, i+1,
2826 (const char*)sqlite3_column_text(pQuery,i),
2827 -1, SQLITE_STATIC);
2828 break;
2829 }
2830 case SQLITE_BLOB: {
2831 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2832 sqlite3_column_bytes(pQuery,i),
2833 SQLITE_STATIC);
2834 break;
2835 }
2836 }
2837 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002838 rc = sqlite3_step(pInsert);
2839 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002840 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002841 sqlite3_errmsg(newDb));
2842 }
drh3350ce92014-02-06 00:49:12 +00002843 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002844 cnt++;
2845 if( (cnt%spinRate)==0 ){
2846 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2847 fflush(stdout);
2848 }
drh3350ce92014-02-06 00:49:12 +00002849 } /* End while */
2850 if( rc==SQLITE_DONE ) break;
2851 sqlite3_finalize(pQuery);
2852 sqlite3_free(zQuery);
2853 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2854 zTable);
2855 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2856 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002857 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002858 break;
drh3350ce92014-02-06 00:49:12 +00002859 }
2860 } /* End for(k=0...) */
2861
2862end_data_xfer:
2863 sqlite3_finalize(pQuery);
2864 sqlite3_finalize(pInsert);
2865 sqlite3_free(zQuery);
2866 sqlite3_free(zInsert);
2867}
2868
2869
2870/*
2871** Try to transfer all rows of the schema that match zWhere. For
2872** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002873** If an error is encountered while moving forward through the
2874** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002875*/
mistachkine31ae902014-02-06 01:15:29 +00002876static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002877 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002878 sqlite3 *newDb,
2879 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002880 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002881){
2882 sqlite3_stmt *pQuery = 0;
2883 char *zQuery = 0;
2884 int rc;
2885 const unsigned char *zName;
2886 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002887 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002888
2889 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2890 " WHERE %s", zWhere);
2891 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2892 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002893 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002894 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2895 zQuery);
2896 goto end_schema_xfer;
2897 }
2898 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2899 zName = sqlite3_column_text(pQuery, 0);
2900 zSql = sqlite3_column_text(pQuery, 1);
2901 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002902 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2903 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002904 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002905 sqlite3_free(zErrMsg);
2906 zErrMsg = 0;
2907 }
drh3350ce92014-02-06 00:49:12 +00002908 if( xForEach ){
2909 xForEach(p, newDb, (const char*)zName);
2910 }
2911 printf("done\n");
2912 }
2913 if( rc!=SQLITE_DONE ){
2914 sqlite3_finalize(pQuery);
2915 sqlite3_free(zQuery);
2916 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2917 " WHERE %s ORDER BY rowid DESC", zWhere);
2918 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2919 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002920 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002921 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2922 zQuery);
2923 goto end_schema_xfer;
2924 }
2925 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2926 zName = sqlite3_column_text(pQuery, 0);
2927 zSql = sqlite3_column_text(pQuery, 1);
2928 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002929 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2930 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002931 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002932 sqlite3_free(zErrMsg);
2933 zErrMsg = 0;
2934 }
drh3350ce92014-02-06 00:49:12 +00002935 if( xForEach ){
2936 xForEach(p, newDb, (const char*)zName);
2937 }
2938 printf("done\n");
2939 }
2940 }
2941end_schema_xfer:
2942 sqlite3_finalize(pQuery);
2943 sqlite3_free(zQuery);
2944}
2945
2946/*
2947** Open a new database file named "zNewDb". Try to recover as much information
2948** as possible out of the main database (which might be corrupt) and write it
2949** into zNewDb.
2950*/
drhdcd87a92014-08-18 13:45:42 +00002951static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002952 int rc;
2953 sqlite3 *newDb = 0;
2954 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002955 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002956 return;
2957 }
2958 rc = sqlite3_open(zNewDb, &newDb);
2959 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002960 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002961 sqlite3_errmsg(newDb));
2962 }else{
drh54d0d2d2014-04-03 00:32:13 +00002963 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002964 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002965 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2966 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002967 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002968 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002969 }
2970 sqlite3_close(newDb);
2971}
2972
2973/*
drhc2ce0be2014-05-29 12:36:14 +00002974** Change the output file back to stdout
2975*/
drhdcd87a92014-08-18 13:45:42 +00002976static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002977 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002978#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002979 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002980#endif
drhc2ce0be2014-05-29 12:36:14 +00002981 }else{
2982 output_file_close(p->out);
2983 }
2984 p->outfile[0] = 0;
2985 p->out = stdout;
2986}
2987
2988/*
drhf7502f02015-02-06 14:19:44 +00002989** Run an SQL command and return the single integer result.
2990*/
2991static int db_int(ShellState *p, const char *zSql){
2992 sqlite3_stmt *pStmt;
2993 int res = 0;
2994 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2995 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2996 res = sqlite3_column_int(pStmt,0);
2997 }
2998 sqlite3_finalize(pStmt);
2999 return res;
3000}
3001
3002/*
3003** Convert a 2-byte or 4-byte big-endian integer into a native integer
3004*/
drha0620ac2016-07-13 13:05:13 +00003005static unsigned int get2byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00003006 return (a[0]<<8) + a[1];
3007}
drha0620ac2016-07-13 13:05:13 +00003008static unsigned int get4byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00003009 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
3010}
3011
3012/*
3013** Implementation of the ".info" command.
3014**
3015** Return 1 on error, 2 to exit, and 0 otherwise.
3016*/
drh0e55db12015-02-06 14:51:13 +00003017static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00003018 static const struct { const char *zName; int ofst; } aField[] = {
3019 { "file change counter:", 24 },
3020 { "database page count:", 28 },
3021 { "freelist page count:", 36 },
3022 { "schema cookie:", 40 },
3023 { "schema format:", 44 },
3024 { "default cache size:", 48 },
3025 { "autovacuum top root:", 52 },
3026 { "incremental vacuum:", 64 },
3027 { "text encoding:", 56 },
3028 { "user version:", 60 },
3029 { "application id:", 68 },
3030 { "software version:", 96 },
3031 };
drh0e55db12015-02-06 14:51:13 +00003032 static const struct { const char *zName; const char *zSql; } aQuery[] = {
3033 { "number of tables:",
3034 "SELECT count(*) FROM %s WHERE type='table'" },
3035 { "number of indexes:",
3036 "SELECT count(*) FROM %s WHERE type='index'" },
3037 { "number of triggers:",
3038 "SELECT count(*) FROM %s WHERE type='trigger'" },
3039 { "number of views:",
3040 "SELECT count(*) FROM %s WHERE type='view'" },
3041 { "schema size:",
3042 "SELECT total(length(sql)) FROM %s" },
3043 };
mistachkinbfe8bd52015-11-17 19:17:14 +00003044 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00003045 int i;
3046 char *zSchemaTab;
3047 char *zDb = nArg>=2 ? azArg[1] : "main";
3048 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00003049 open_db(p, 0);
3050 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00003051 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00003052 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
3053 return 1;
3054 }
3055 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
3056 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003057 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00003058 return 1;
3059 }
3060 i = get2byteInt(aHdr+16);
3061 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00003062 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
3063 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
3064 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
3065 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00003066 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00003067 int ofst = aField[i].ofst;
3068 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00003069 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00003070 switch( ofst ){
3071 case 56: {
mistachkin1fe36bb2016-04-04 02:16:44 +00003072 if( val==1 ) raw_printf(p->out, " (utf8)");
3073 if( val==2 ) raw_printf(p->out, " (utf16le)");
3074 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00003075 }
3076 }
mistachkinaae280e2015-12-31 19:06:24 +00003077 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00003078 }
drh0e55db12015-02-06 14:51:13 +00003079 if( zDb==0 ){
3080 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
3081 }else if( strcmp(zDb,"temp")==0 ){
3082 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
3083 }else{
3084 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
3085 }
drhf5ed7ad2015-06-15 14:43:25 +00003086 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00003087 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
3088 int val = db_int(p, zSql);
3089 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00003090 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00003091 }
3092 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00003093 return 0;
3094}
3095
dand95bb392015-09-30 11:19:05 +00003096/*
3097** Print the current sqlite3_errmsg() value to stderr and return 1.
3098*/
3099static int shellDatabaseError(sqlite3 *db){
3100 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00003101 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00003102 return 1;
3103}
3104
3105/*
3106** Print an out-of-memory message to stderr and return 1.
3107*/
3108static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00003109 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00003110 return 1;
3111}
drhf7502f02015-02-06 14:19:44 +00003112
drh2db82112016-09-15 21:35:24 +00003113/*
3114** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
3115** if they match and FALSE (0) if they do not match.
3116**
3117** Globbing rules:
3118**
3119** '*' Matches any sequence of zero or more characters.
3120**
3121** '?' Matches exactly one character.
3122**
3123** [...] Matches one character from the enclosed list of
3124** characters.
3125**
3126** [^...] Matches one character not in the enclosed list.
3127**
3128** '#' Matches any sequence of one or more digits with an
3129** optional + or - sign in front
3130**
3131** ' ' Any span of whitespace matches any other span of
3132** whitespace.
3133**
3134** Extra whitespace at the end of z[] is ignored.
3135*/
3136static int testcase_glob(const char *zGlob, const char *z){
3137 int c, c2;
3138 int invert;
3139 int seen;
3140
3141 while( (c = (*(zGlob++)))!=0 ){
3142 if( IsSpace(c) ){
3143 if( !IsSpace(*z) ) return 0;
3144 while( IsSpace(*zGlob) ) zGlob++;
3145 while( IsSpace(*z) ) z++;
3146 }else if( c=='*' ){
3147 while( (c=(*(zGlob++))) == '*' || c=='?' ){
3148 if( c=='?' && (*(z++))==0 ) return 0;
3149 }
3150 if( c==0 ){
3151 return 1;
3152 }else if( c=='[' ){
3153 while( *z && testcase_glob(zGlob-1,z)==0 ){
3154 z++;
3155 }
3156 return (*z)!=0;
3157 }
3158 while( (c2 = (*(z++)))!=0 ){
3159 while( c2!=c ){
3160 c2 = *(z++);
3161 if( c2==0 ) return 0;
3162 }
3163 if( testcase_glob(zGlob,z) ) return 1;
3164 }
3165 return 0;
3166 }else if( c=='?' ){
3167 if( (*(z++))==0 ) return 0;
3168 }else if( c=='[' ){
3169 int prior_c = 0;
3170 seen = 0;
3171 invert = 0;
3172 c = *(z++);
3173 if( c==0 ) return 0;
3174 c2 = *(zGlob++);
3175 if( c2=='^' ){
3176 invert = 1;
3177 c2 = *(zGlob++);
3178 }
3179 if( c2==']' ){
3180 if( c==']' ) seen = 1;
3181 c2 = *(zGlob++);
3182 }
3183 while( c2 && c2!=']' ){
3184 if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
3185 c2 = *(zGlob++);
3186 if( c>=prior_c && c<=c2 ) seen = 1;
3187 prior_c = 0;
3188 }else{
3189 if( c==c2 ){
3190 seen = 1;
3191 }
3192 prior_c = c2;
3193 }
3194 c2 = *(zGlob++);
3195 }
3196 if( c2==0 || (seen ^ invert)==0 ) return 0;
3197 }else if( c=='#' ){
3198 if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
3199 if( !IsDigit(z[0]) ) return 0;
3200 z++;
3201 while( IsDigit(z[0]) ){ z++; }
3202 }else{
3203 if( c!=(*(z++)) ) return 0;
3204 }
3205 }
3206 while( IsSpace(*z) ){ z++; }
3207 return *z==0;
3208}
drh2db82112016-09-15 21:35:24 +00003209
3210
drhf7502f02015-02-06 14:19:44 +00003211/*
drh4926fec2016-04-13 15:33:42 +00003212** Compare the string as a command-line option with either one or two
3213** initial "-" characters.
3214*/
3215static int optionMatch(const char *zStr, const char *zOpt){
3216 if( zStr[0]!='-' ) return 0;
3217 zStr++;
3218 if( zStr[0]=='-' ) zStr++;
3219 return strcmp(zStr, zOpt)==0;
3220}
3221
3222/*
drhcd0509e2016-09-16 00:26:08 +00003223** Delete a file.
3224*/
3225int shellDeleteFile(const char *zFilename){
3226 int rc;
3227#ifdef _WIN32
mistachkin8145fc62016-09-16 20:39:21 +00003228 wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
drhcd0509e2016-09-16 00:26:08 +00003229 rc = _wunlink(z);
3230 sqlite3_free(z);
3231#else
3232 rc = unlink(zFilename);
3233#endif
3234 return rc;
3235}
3236
3237/*
drh75897232000-05-29 14:26:00 +00003238** If an input line begins with "." then invoke this routine to
3239** process that line.
drh67505e72002-04-19 12:34:06 +00003240**
drh47ad6842006-11-08 12:25:42 +00003241** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00003242*/
drhdcd87a92014-08-18 13:45:42 +00003243static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00003244 int h = 1;
drh75897232000-05-29 14:26:00 +00003245 int nArg = 0;
3246 int n, c;
drh67505e72002-04-19 12:34:06 +00003247 int rc = 0;
drh75897232000-05-29 14:26:00 +00003248 char *azArg[50];
3249
3250 /* Parse the input line into tokens.
3251 */
mistachkin8e189222015-04-19 21:43:16 +00003252 while( zLine[h] && nArg<ArraySize(azArg) ){
3253 while( IsSpace(zLine[h]) ){ h++; }
3254 if( zLine[h]==0 ) break;
3255 if( zLine[h]=='\'' || zLine[h]=='"' ){
3256 int delim = zLine[h++];
3257 azArg[nArg++] = &zLine[h];
mistachkin1fe36bb2016-04-04 02:16:44 +00003258 while( zLine[h] && zLine[h]!=delim ){
mistachkin8e189222015-04-19 21:43:16 +00003259 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
mistachkin1fe36bb2016-04-04 02:16:44 +00003260 h++;
drh4c56b992013-06-27 13:26:55 +00003261 }
mistachkin8e189222015-04-19 21:43:16 +00003262 if( zLine[h]==delim ){
3263 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00003264 }
drhfeac5f82004-08-01 00:10:45 +00003265 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003266 }else{
mistachkin8e189222015-04-19 21:43:16 +00003267 azArg[nArg++] = &zLine[h];
3268 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
3269 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00003270 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003271 }
3272 }
3273
3274 /* Process the input line.
3275 */
shane9bd1b442009-10-23 01:27:39 +00003276 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00003277 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00003278 c = azArg[0][0];
drhde613c62016-04-04 17:23:10 +00003279
drha0daa752016-09-16 11:53:10 +00003280#ifndef SQLITE_OMIT_AUTHORIZATION
drhde613c62016-04-04 17:23:10 +00003281 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
3282 if( nArg!=2 ){
3283 raw_printf(stderr, "Usage: .auth ON|OFF\n");
3284 rc = 1;
3285 goto meta_command_exit;
3286 }
3287 open_db(p, 0);
3288 if( booleanValue(azArg[1]) ){
3289 sqlite3_set_authorizer(p->db, shellAuth, p);
3290 }else{
3291 sqlite3_set_authorizer(p->db, 0, 0);
3292 }
3293 }else
drha0daa752016-09-16 11:53:10 +00003294#endif
drhde613c62016-04-04 17:23:10 +00003295
drh5c7976f2014-02-10 19:59:27 +00003296 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
3297 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
3298 ){
drhbc46f022013-01-23 18:53:23 +00003299 const char *zDestFile = 0;
3300 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00003301 sqlite3 *pDest;
3302 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00003303 int j;
3304 for(j=1; j<nArg; j++){
3305 const char *z = azArg[j];
3306 if( z[0]=='-' ){
3307 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00003308 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00003309 {
mistachkinaae280e2015-12-31 19:06:24 +00003310 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00003311 return 1;
3312 }
3313 }else if( zDestFile==0 ){
3314 zDestFile = azArg[j];
3315 }else if( zDb==0 ){
3316 zDb = zDestFile;
3317 zDestFile = azArg[j];
3318 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003319 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00003320 return 1;
3321 }
drh9ff849f2009-02-04 20:55:57 +00003322 }
drhbc46f022013-01-23 18:53:23 +00003323 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003324 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00003325 return 1;
3326 }
3327 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00003328 rc = sqlite3_open(zDestFile, &pDest);
3329 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003330 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00003331 sqlite3_close(pDest);
3332 return 1;
3333 }
drh05782482013-10-24 15:20:20 +00003334 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003335 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
3336 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003337 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00003338 sqlite3_close(pDest);
3339 return 1;
3340 }
3341 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
3342 sqlite3_backup_finish(pBackup);
3343 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003344 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00003345 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003346 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00003347 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003348 }
3349 sqlite3_close(pDest);
3350 }else
3351
drhc2ce0be2014-05-29 12:36:14 +00003352 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
3353 if( nArg==2 ){
3354 bail_on_error = booleanValue(azArg[1]);
3355 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003356 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003357 rc = 1;
3358 }
drhc49f44e2006-10-26 18:15:42 +00003359 }else
3360
mistachkinf21979d2015-01-18 05:35:01 +00003361 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
3362 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00003363 if( booleanValue(azArg[1]) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003364 setBinaryMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003365 }else{
mistachkin1fe36bb2016-04-04 02:16:44 +00003366 setTextMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003367 }
mistachkinf21979d2015-01-18 05:35:01 +00003368 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003369 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00003370 rc = 1;
3371 }
3372 }else
3373
drhd8621b92012-04-17 09:09:33 +00003374 /* The undocumented ".breakpoint" command causes a call to the no-op
3375 ** routine named test_breakpoint().
3376 */
3377 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
3378 test_breakpoint();
3379 }else
3380
drhdf12f1c2015-12-07 21:46:19 +00003381 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
3382 if( nArg==2 ){
3383 p->countChanges = booleanValue(azArg[1]);
3384 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003385 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00003386 rc = 1;
3387 }
3388 }else
3389
drh2db82112016-09-15 21:35:24 +00003390 /* Cancel output redirection, if it is currently set (by .testcase)
3391 ** Then read the content of the testcase-out.txt file and compare against
3392 ** azArg[1]. If there are differences, report an error and exit.
3393 */
3394 if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
3395 char *zRes = 0;
3396 output_reset(p);
3397 if( nArg!=2 ){
3398 raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
drh760c8162016-09-16 02:52:22 +00003399 rc = 2;
drh2db82112016-09-15 21:35:24 +00003400 }else if( (zRes = readFile("testcase-out.txt"))==0 ){
3401 raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
3402 rc = 2;
3403 }else if( testcase_glob(azArg[1],zRes)==0 ){
mistachkin8145fc62016-09-16 20:39:21 +00003404 utf8_printf(stderr,
drh760c8162016-09-16 02:52:22 +00003405 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
3406 p->zTestcase, azArg[1], zRes);
drh2db82112016-09-15 21:35:24 +00003407 rc = 2;
drh760c8162016-09-16 02:52:22 +00003408 }else{
mistachkin8145fc62016-09-16 20:39:21 +00003409 utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
drh760c8162016-09-16 02:52:22 +00003410 p->nCheck++;
drh2db82112016-09-15 21:35:24 +00003411 }
3412 sqlite3_free(zRes);
3413 }else
drh2db82112016-09-15 21:35:24 +00003414
drhc2ce0be2014-05-29 12:36:14 +00003415 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
3416 if( nArg==2 ){
3417 tryToClone(p, azArg[1]);
3418 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003419 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003420 rc = 1;
3421 }
mistachkine31ae902014-02-06 01:15:29 +00003422 }else
3423
drhc2ce0be2014-05-29 12:36:14 +00003424 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003425 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00003426 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003427 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00003428 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00003429 data.showHeader = 1;
drh700c2522016-02-09 18:39:25 +00003430 data.cMode = data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00003431 data.colWidth[0] = 3;
3432 data.colWidth[1] = 15;
3433 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00003434 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00003435 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00003436 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003437 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003438 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003439 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00003440 }
3441 }else
3442
drh0e55db12015-02-06 14:51:13 +00003443 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
3444 rc = shell_dbinfo_command(p, nArg, azArg);
3445 }else
3446
drhc2ce0be2014-05-29 12:36:14 +00003447 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00003448 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00003449 /* When playing back a "dump", the content might appear in an order
3450 ** which causes immediate foreign key constraints to be violated.
3451 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00003452 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003453 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003454 rc = 1;
3455 goto meta_command_exit;
3456 }
mistachkinaae280e2015-12-31 19:06:24 +00003457 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
3458 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00003459 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00003460 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00003461 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00003462 if( nArg==1 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003463 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003464 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003465 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00003466 );
mistachkin1fe36bb2016-04-04 02:16:44 +00003467 run_schema_dump_query(p,
drh4f324762009-05-21 14:51:03 +00003468 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003469 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00003470 );
drh2f464a02011-10-13 00:41:49 +00003471 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003472 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00003473 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00003474 );
drh4c653a02000-06-07 01:27:47 +00003475 }else{
3476 int i;
drhdd3d4592004-08-30 01:54:05 +00003477 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00003478 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00003479 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003480 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00003481 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00003482 " AND sql NOT NULL");
3483 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003484 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00003485 "WHERE sql NOT NULL"
3486 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00003487 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00003488 );
danielk1977bc6ada42004-06-30 08:20:16 +00003489 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00003490 }
3491 }
drh45e29d82006-11-20 16:21:10 +00003492 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00003493 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00003494 p->writableSchema = 0;
3495 }
drh56197952011-10-13 16:30:13 +00003496 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
3497 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00003498 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00003499 }else
drh75897232000-05-29 14:26:00 +00003500
drhc2ce0be2014-05-29 12:36:14 +00003501 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
3502 if( nArg==2 ){
3503 p->echoOn = booleanValue(azArg[1]);
3504 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003505 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003506 rc = 1;
3507 }
drhdaffd0e2001-04-11 14:28:42 +00003508 }else
3509
drhc2ce0be2014-05-29 12:36:14 +00003510 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
3511 if( nArg==2 ){
drheacd29d2016-04-15 15:03:27 +00003512 if( strcmp(azArg[1],"full")==0 ){
3513 p->autoEQP = 2;
3514 }else{
3515 p->autoEQP = booleanValue(azArg[1]);
3516 }
drhc2ce0be2014-05-29 12:36:14 +00003517 }else{
drheacd29d2016-04-15 15:03:27 +00003518 raw_printf(stderr, "Usage: .eqp on|off|full\n");
drhc2ce0be2014-05-29 12:36:14 +00003519 rc = 1;
mistachkin1fe36bb2016-04-04 02:16:44 +00003520 }
drhefbf3b12014-02-28 20:47:24 +00003521 }else
3522
drhd3ac7d92013-01-25 18:33:43 +00003523 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00003524 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00003525 rc = 2;
drh75897232000-05-29 14:26:00 +00003526 }else
3527
drhc2ce0be2014-05-29 12:36:14 +00003528 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00003529 int val = 1;
3530 if( nArg>=2 ){
3531 if( strcmp(azArg[1],"auto")==0 ){
3532 val = 99;
3533 }else{
3534 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003535 }
drh700c2522016-02-09 18:39:25 +00003536 }
3537 if( val==1 && p->mode!=MODE_Explain ){
3538 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003539 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003540 p->autoExplain = 0;
3541 }else if( val==0 ){
3542 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3543 p->autoExplain = 0;
3544 }else if( val==99 ){
3545 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3546 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003547 }
drh75897232000-05-29 14:26:00 +00003548 }else
3549
drhc1971542014-06-23 23:28:13 +00003550 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003551 ShellState data;
drhc1971542014-06-23 23:28:13 +00003552 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003553 int doStats = 0;
drh4926fec2016-04-13 15:33:42 +00003554 memcpy(&data, p, sizeof(data));
3555 data.showHeader = 0;
3556 data.cMode = data.mode = MODE_Semi;
3557 if( nArg==2 && optionMatch(azArg[1], "indent") ){
3558 data.cMode = data.mode = MODE_Pretty;
3559 nArg = 1;
3560 }
drhc1971542014-06-23 23:28:13 +00003561 if( nArg!=1 ){
drh4926fec2016-04-13 15:33:42 +00003562 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
drhc1971542014-06-23 23:28:13 +00003563 rc = 1;
3564 goto meta_command_exit;
3565 }
3566 open_db(p, 0);
drhc1971542014-06-23 23:28:13 +00003567 rc = sqlite3_exec(p->db,
3568 "SELECT sql FROM"
3569 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3570 " FROM sqlite_master UNION ALL"
3571 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003572 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003573 "ORDER BY rowid",
3574 callback, &data, &zErrMsg
3575 );
drh56f674c2014-07-18 14:43:29 +00003576 if( rc==SQLITE_OK ){
3577 sqlite3_stmt *pStmt;
3578 rc = sqlite3_prepare_v2(p->db,
3579 "SELECT rowid FROM sqlite_master"
3580 " WHERE name GLOB 'sqlite_stat[134]'",
3581 -1, &pStmt, 0);
3582 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3583 sqlite3_finalize(pStmt);
3584 }
3585 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003586 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003587 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003588 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003589 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3590 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003591 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003592 data.zDestTable = "sqlite_stat1";
3593 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3594 shell_callback, &data,&zErrMsg);
3595 data.zDestTable = "sqlite_stat3";
3596 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3597 shell_callback, &data,&zErrMsg);
3598 data.zDestTable = "sqlite_stat4";
3599 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3600 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003601 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003602 }
drhc1971542014-06-23 23:28:13 +00003603 }else
3604
drhc2ce0be2014-05-29 12:36:14 +00003605 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3606 if( nArg==2 ){
3607 p->showHeader = booleanValue(azArg[1]);
3608 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003609 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003610 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003611 }
drh75897232000-05-29 14:26:00 +00003612 }else
3613
drhc2ce0be2014-05-29 12:36:14 +00003614 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003615 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003616 }else
3617
3618 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003619 char *zTable; /* Insert data into this table */
3620 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003621 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003622 int nCol; /* Number of columns in the table */
3623 int nByte; /* Number of bytes in an SQL string */
3624 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003625 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003626 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003627 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003628 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003629 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3630 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003631
drhc2ce0be2014-05-29 12:36:14 +00003632 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003633 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003634 goto meta_command_exit;
3635 }
drh01f37542014-05-31 15:43:33 +00003636 zFile = azArg[1];
3637 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003638 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003639 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003640 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003641 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003642 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003643 raw_printf(stderr,
3644 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003645 return 1;
drhfeac5f82004-08-01 00:10:45 +00003646 }
drhdb95f682013-06-26 22:46:00 +00003647 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003648 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003649 " for import\n");
3650 return 1;
3651 }
mistachkin636bf9f2014-07-19 20:15:16 +00003652 nSep = strlen30(p->rowSeparator);
3653 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003654 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003655 return 1;
3656 }
mistachkine0d68852014-12-11 03:12:33 +00003657 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3658 /* When importing CSV (only), if the row separator is set to the
3659 ** default output row separator, change it to the default input
3660 ** row separator. This avoids having to maintain different input
3661 ** and output row separators. */
3662 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3663 nSep = strlen30(p->rowSeparator);
3664 }
mistachkin636bf9f2014-07-19 20:15:16 +00003665 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003666 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003667 " for import\n");
3668 return 1;
3669 }
3670 sCtx.zFile = zFile;
3671 sCtx.nLine = 1;
3672 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003673#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003674 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003675 return 1;
3676#else
mistachkin636bf9f2014-07-19 20:15:16 +00003677 sCtx.in = popen(sCtx.zFile+1, "r");
3678 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003679 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003680#endif
drh5bde8162013-06-27 14:07:53 +00003681 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003682 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003683 xCloser = fclose;
3684 }
mistachkin636bf9f2014-07-19 20:15:16 +00003685 if( p->mode==MODE_Ascii ){
3686 xRead = ascii_read_one_field;
3687 }else{
3688 xRead = csv_read_one_field;
3689 }
3690 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003691 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003692 return 1;
3693 }
mistachkin636bf9f2014-07-19 20:15:16 +00003694 sCtx.cColSep = p->colSeparator[0];
3695 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003696 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003697 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003698 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003699 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003700 return 1;
3701 }
drh4f21c4a2008-12-10 22:15:00 +00003702 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003703 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003704 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003705 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003706 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3707 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003708 while( xRead(&sCtx) ){
drhd8c22ac2016-02-25 13:33:02 +00003709 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003710 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003711 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003712 }
drh5bde8162013-06-27 14:07:53 +00003713 if( cSep=='(' ){
3714 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003715 sqlite3_free(sCtx.z);
3716 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003717 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003718 return 1;
3719 }
drhdb95f682013-06-26 22:46:00 +00003720 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3721 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3722 sqlite3_free(zCreate);
3723 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003724 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003725 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003726 sqlite3_free(sCtx.z);
3727 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003728 return 1;
3729 }
drhc7181902014-02-27 15:04:13 +00003730 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003731 }
drhfeac5f82004-08-01 00:10:45 +00003732 sqlite3_free(zSql);
3733 if( rc ){
shane916f9612009-10-23 00:37:15 +00003734 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00003735 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003736 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003737 return 1;
drhfeac5f82004-08-01 00:10:45 +00003738 }
shane916f9612009-10-23 00:37:15 +00003739 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003740 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003741 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003742 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003743 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003744 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003745 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003746 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003747 return 1;
3748 }
drhdb95f682013-06-26 22:46:00 +00003749 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003750 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003751 for(i=1; i<nCol; i++){
3752 zSql[j++] = ',';
3753 zSql[j++] = '?';
3754 }
3755 zSql[j++] = ')';
3756 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003757 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003758 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003759 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003760 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003761 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003762 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003763 return 1;
drhfeac5f82004-08-01 00:10:45 +00003764 }
mistachkin8e189222015-04-19 21:43:16 +00003765 needCommit = sqlite3_get_autocommit(p->db);
3766 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003767 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003768 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003769 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003770 char *z = xRead(&sCtx);
3771 /*
3772 ** Did we reach end-of-file before finding any columns?
3773 ** If so, stop instead of NULL filling the remaining columns.
3774 */
drhdb95f682013-06-26 22:46:00 +00003775 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003776 /*
3777 ** Did we reach end-of-file OR end-of-line before finding any
3778 ** columns in ASCII mode? If so, stop instead of NULL filling
3779 ** the remaining columns.
3780 */
3781 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003782 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003783 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00003784 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003785 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003786 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003787 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003788 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003789 }
drhfeac5f82004-08-01 00:10:45 +00003790 }
mistachkin636bf9f2014-07-19 20:15:16 +00003791 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003792 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003793 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003794 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003795 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00003796 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003797 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003798 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003799 }
drhdb95f682013-06-26 22:46:00 +00003800 if( i>=nCol ){
3801 sqlite3_step(pStmt);
3802 rc = sqlite3_reset(pStmt);
3803 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003804 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
3805 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003806 }
3807 }
mistachkin636bf9f2014-07-19 20:15:16 +00003808 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003809
mistachkin636bf9f2014-07-19 20:15:16 +00003810 xCloser(sCtx.in);
3811 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003812 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003813 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003814 }else
3815
drh0e55db12015-02-06 14:51:13 +00003816 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3817 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003818 ShellState data;
drh75897232000-05-29 14:26:00 +00003819 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003820 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003821 memcpy(&data, p, sizeof(data));
3822 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003823 data.cMode = data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003824 if( nArg==1 ){
3825 rc = sqlite3_exec(p->db,
3826 "SELECT name FROM sqlite_master "
3827 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3828 "UNION ALL "
3829 "SELECT name FROM sqlite_temp_master "
3830 "WHERE type='index' "
3831 "ORDER BY 1",
3832 callback, &data, &zErrMsg
3833 );
drhc2ce0be2014-05-29 12:36:14 +00003834 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003835 zShellStatic = azArg[1];
3836 rc = sqlite3_exec(p->db,
3837 "SELECT name FROM sqlite_master "
3838 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3839 "UNION ALL "
3840 "SELECT name FROM sqlite_temp_master "
3841 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3842 "ORDER BY 1",
3843 callback, &data, &zErrMsg
3844 );
3845 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003846 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003847 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003848 rc = 1;
3849 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003850 }
drh75897232000-05-29 14:26:00 +00003851 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003852 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003853 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003854 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003855 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003856 raw_printf(stderr,
3857 "Error: querying sqlite_master and sqlite_temp_master\n");
shane86f5bdb2009-10-24 02:00:07 +00003858 rc = 1;
drh75897232000-05-29 14:26:00 +00003859 }
3860 }else
3861
drh16eb5942016-11-03 13:01:38 +00003862#ifndef SQLITE_OMIT_BUILTIN_TEST
3863 if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
3864 char *zSql;
3865 char *zCollist = 0;
3866 sqlite3_stmt *pStmt;
3867 int tnum = 0;
drh59ce2c42016-11-03 13:12:28 +00003868 int i;
drh16eb5942016-11-03 13:01:38 +00003869 if( nArg!=3 ){
3870 utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n");
3871 rc = 1;
3872 goto meta_command_exit;
3873 }
3874 open_db(p, 0);
3875 zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
3876 " WHERE name='%q' AND type='index'", azArg[1]);
3877 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3878 sqlite3_free(zSql);
3879 if( sqlite3_step(pStmt)==SQLITE_ROW ){
3880 tnum = sqlite3_column_int(pStmt, 0);
3881 }
3882 sqlite3_finalize(pStmt);
3883 if( tnum==0 ){
3884 utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
3885 rc = 1;
3886 goto meta_command_exit;
3887 }
3888 zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
3889 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3890 sqlite3_free(zSql);
drh59ce2c42016-11-03 13:12:28 +00003891 i = 0;
drh16eb5942016-11-03 13:01:38 +00003892 while( sqlite3_step(pStmt)==SQLITE_ROW ){
drh59ce2c42016-11-03 13:12:28 +00003893 char zLabel[20];
drh16eb5942016-11-03 13:01:38 +00003894 const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
drh59ce2c42016-11-03 13:12:28 +00003895 i++;
3896 if( zCol==0 ){
3897 if( sqlite3_column_int(pStmt,1)==-1 ){
3898 zCol = "_ROWID_";
3899 }else{
3900 sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i);
3901 zCol = zLabel;
3902 }
3903 }
drh16eb5942016-11-03 13:01:38 +00003904 if( zCollist==0 ){
3905 zCollist = sqlite3_mprintf("\"%w\"", zCol);
3906 }else{
3907 zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
3908 }
3909 }
3910 sqlite3_finalize(pStmt);
3911 zSql = sqlite3_mprintf(
3912 "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID",
3913 azArg[2], zCollist, zCollist);
3914 sqlite3_free(zCollist);
3915 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
3916 if( rc==SQLITE_OK ){
3917 rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
3918 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
3919 if( rc ){
3920 utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
3921 }else{
3922 utf8_printf(stdout, "%s;\n", zSql);
mistachkin2f9a6132016-11-11 05:19:45 +00003923 raw_printf(stdout,
drh16eb5942016-11-03 13:01:38 +00003924 "WARNING: writing to an imposter table will corrupt the index!\n"
3925 );
3926 }
3927 }else{
mistachkin2f9a6132016-11-11 05:19:45 +00003928 raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
drh16eb5942016-11-03 13:01:38 +00003929 rc = 1;
3930 }
3931 sqlite3_free(zSql);
3932 }else
3933#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
3934
drhae5e4452007-05-03 17:18:36 +00003935#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003936 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003937 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003938 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3939 iotrace = 0;
3940 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003941 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003942 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003943 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003944 iotrace = stdout;
3945 }else{
3946 iotrace = fopen(azArg[1], "w");
3947 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003948 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003949 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003950 rc = 1;
drhb0603412007-02-28 04:47:26 +00003951 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003952 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003953 }
3954 }
3955 }else
drhae5e4452007-05-03 17:18:36 +00003956#endif
drh16eb5942016-11-03 13:01:38 +00003957
drh1a513372015-05-02 17:40:23 +00003958 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3959 static const struct {
3960 const char *zLimitName; /* Name of a limit */
3961 int limitCode; /* Integer code for that limit */
3962 } aLimit[] = {
3963 { "length", SQLITE_LIMIT_LENGTH },
3964 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3965 { "column", SQLITE_LIMIT_COLUMN },
3966 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3967 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3968 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3969 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3970 { "attached", SQLITE_LIMIT_ATTACHED },
3971 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3972 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3973 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3974 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3975 };
3976 int i, n2;
3977 open_db(p, 0);
3978 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003979 for(i=0; i<ArraySize(aLimit); i++){
mistachkin1fe36bb2016-04-04 02:16:44 +00003980 printf("%20s %d\n", aLimit[i].zLimitName,
drh1a513372015-05-02 17:40:23 +00003981 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3982 }
3983 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003984 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00003985 rc = 1;
3986 goto meta_command_exit;
3987 }else{
3988 int iLimit = -1;
3989 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003990 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003991 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3992 if( iLimit<0 ){
3993 iLimit = i;
3994 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003995 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00003996 rc = 1;
3997 goto meta_command_exit;
3998 }
3999 }
4000 }
4001 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004002 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00004003 "enter \".limits\" with no arguments for a list.\n",
4004 azArg[1]);
4005 rc = 1;
4006 goto meta_command_exit;
4007 }
4008 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00004009 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
4010 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00004011 }
4012 printf("%20s %d\n", aLimit[iLimit].zLimitName,
4013 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
4014 }
4015 }else
drhb0603412007-02-28 04:47:26 +00004016
drh70df4fe2006-06-13 15:12:21 +00004017#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00004018 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00004019 const char *zFile, *zProc;
4020 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00004021 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004022 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00004023 rc = 1;
4024 goto meta_command_exit;
4025 }
drh1e397f82006-06-08 15:28:43 +00004026 zFile = azArg[1];
4027 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00004028 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00004029 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
4030 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004031 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00004032 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00004033 rc = 1;
drh1e397f82006-06-08 15:28:43 +00004034 }
4035 }else
drh70df4fe2006-06-13 15:12:21 +00004036#endif
drh1e397f82006-06-08 15:28:43 +00004037
drhc2ce0be2014-05-29 12:36:14 +00004038 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
4039 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004040 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00004041 rc = 1;
4042 }else{
4043 const char *zFile = azArg[1];
4044 output_file_close(p->pLog);
4045 p->pLog = output_file_open(zFile);
4046 }
drh127f9d72010-02-23 01:47:00 +00004047 }else
4048
drhc2ce0be2014-05-29 12:36:14 +00004049 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
4050 const char *zMode = nArg>=2 ? azArg[1] : "";
4051 int n2 = (int)strlen(zMode);
4052 int c2 = zMode[0];
4053 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004054 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00004055 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004056 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00004057 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004058 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00004059 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004060 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00004061 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00004062 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00004063 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00004064 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00004065 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00004066 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00004067 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00004068 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00004069 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004070 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00004071 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00004072 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00004073 set_table_name(p, nArg>=3 ? azArg[2] : "table");
drh41f5f6e2016-10-21 17:39:30 +00004074 }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
4075 p->mode = MODE_Quote;
mistachkin636bf9f2014-07-19 20:15:16 +00004076 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
4077 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00004078 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
4079 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00004080 }else {
mistachkinaae280e2015-12-31 19:06:24 +00004081 raw_printf(stderr, "Error: mode should be one of: "
drh36f49d02016-11-23 23:18:45 +00004082 "ascii column csv html insert line list quote tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00004083 rc = 1;
drh75897232000-05-29 14:26:00 +00004084 }
drh700c2522016-02-09 18:39:25 +00004085 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00004086 }else
4087
drhc2ce0be2014-05-29 12:36:14 +00004088 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
4089 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00004090 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
4091 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00004092 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004093 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00004094 rc = 1;
4095 }
4096 }else
4097
drh05782482013-10-24 15:20:20 +00004098 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
drhcd0509e2016-09-16 00:26:08 +00004099 char *zNewFilename; /* Name of the database file to open */
4100 int iName = 1; /* Index in azArg[] of the filename */
drh760c8162016-09-16 02:52:22 +00004101 int newFlag = 0; /* True to delete file before opening */
drhcd0509e2016-09-16 00:26:08 +00004102 /* Close the existing database */
4103 session_close_all(p);
4104 sqlite3_close(p->db);
drh05782482013-10-24 15:20:20 +00004105 p->db = 0;
drhcd0509e2016-09-16 00:26:08 +00004106 sqlite3_free(p->zFreeOnClose);
4107 p->zFreeOnClose = 0;
drh760c8162016-09-16 02:52:22 +00004108 /* Check for command-line arguments */
4109 for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
4110 const char *z = azArg[iName];
4111 if( optionMatch(z,"new") ){
4112 newFlag = 1;
4113 }else if( z[0]=='-' ){
4114 utf8_printf(stderr, "unknown option: %s\n", z);
4115 rc = 1;
mistachkin8145fc62016-09-16 20:39:21 +00004116 goto meta_command_exit;
drh760c8162016-09-16 02:52:22 +00004117 }
drhcd0509e2016-09-16 00:26:08 +00004118 }
4119 /* If a filename is specified, try to open it first */
4120 zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
4121 if( zNewFilename ){
drh760c8162016-09-16 02:52:22 +00004122 if( newFlag ) shellDeleteFile(zNewFilename);
drhcd0509e2016-09-16 00:26:08 +00004123 p->zDbFilename = zNewFilename;
4124 open_db(p, 1);
4125 if( p->db==0 ){
4126 utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
4127 sqlite3_free(zNewFilename);
4128 }else{
4129 p->zFreeOnClose = zNewFilename;
4130 }
4131 }
4132 if( p->db==0 ){
4133 /* As a fall-back open a TEMP database */
4134 p->zDbFilename = 0;
4135 open_db(p, 0);
drh05782482013-10-24 15:20:20 +00004136 }
4137 }else
4138
drhc2ce0be2014-05-29 12:36:14 +00004139 if( c=='o'
4140 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
4141 ){
4142 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
4143 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004144 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00004145 rc = 1;
4146 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004147 }
drhc2ce0be2014-05-29 12:36:14 +00004148 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
4149 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004150 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004151 rc = 1;
4152 goto meta_command_exit;
4153 }
4154 p->outCount = 2;
4155 }else{
4156 p->outCount = 0;
4157 }
4158 output_reset(p);
4159 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00004160#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00004161 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00004162 rc = 1;
4163 p->out = stdout;
4164#else
drhc2ce0be2014-05-29 12:36:14 +00004165 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00004166 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004167 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00004168 p->out = stdout;
4169 rc = 1;
4170 }else{
drhc2ce0be2014-05-29 12:36:14 +00004171 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00004172 }
drh8cd5b252015-03-02 22:06:43 +00004173#endif
drh75897232000-05-29 14:26:00 +00004174 }else{
drhc2ce0be2014-05-29 12:36:14 +00004175 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00004176 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004177 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004178 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00004179 }
drh75897232000-05-29 14:26:00 +00004180 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00004181 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00004182 } else {
drhc2ce0be2014-05-29 12:36:14 +00004183 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00004184 }
4185 }
4186 }else
4187
drh078b1fd2012-09-21 13:40:02 +00004188 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
4189 int i;
4190 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00004191 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00004192 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00004193 }
mistachkinaae280e2015-12-31 19:06:24 +00004194 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00004195 }else
4196
drhc2ce0be2014-05-29 12:36:14 +00004197 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00004198 if( nArg >= 2) {
4199 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
4200 }
4201 if( nArg >= 3) {
4202 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
4203 }
4204 }else
4205
drhc2ce0be2014-05-29 12:36:14 +00004206 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00004207 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00004208 }else
4209
drhc2ce0be2014-05-29 12:36:14 +00004210 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
4211 FILE *alt;
drh4e8142c2016-11-11 14:54:22 +00004212 if( nArg!=2 ){
4213 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004214 rc = 1;
4215 goto meta_command_exit;
4216 }
drh4e8142c2016-11-11 14:54:22 +00004217 alt = fopen(azArg[1], "rb");
4218 if( alt==0 ){
4219 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
4220 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00004221 }else{
drh4e8142c2016-11-11 14:54:22 +00004222 rc = process_input(p, alt);
4223 fclose(alt);
drhdaffd0e2001-04-11 14:28:42 +00004224 }
4225 }else
4226
drhc2ce0be2014-05-29 12:36:14 +00004227 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00004228 const char *zSrcFile;
4229 const char *zDb;
4230 sqlite3 *pSrc;
4231 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00004232 int nTimeout = 0;
4233
drh9ff849f2009-02-04 20:55:57 +00004234 if( nArg==2 ){
4235 zSrcFile = azArg[1];
4236 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00004237 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00004238 zSrcFile = azArg[2];
4239 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00004240 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004241 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004242 rc = 1;
4243 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00004244 }
4245 rc = sqlite3_open(zSrcFile, &pSrc);
4246 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004247 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00004248 sqlite3_close(pSrc);
4249 return 1;
4250 }
drh05782482013-10-24 15:20:20 +00004251 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00004252 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
4253 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004254 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00004255 sqlite3_close(pSrc);
4256 return 1;
4257 }
drhdc2c4912009-02-04 22:46:47 +00004258 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
4259 || rc==SQLITE_BUSY ){
4260 if( rc==SQLITE_BUSY ){
4261 if( nTimeout++ >= 3 ) break;
4262 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00004263 }
4264 }
4265 sqlite3_backup_finish(pBackup);
4266 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00004267 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00004268 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00004269 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00004270 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004271 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004272 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00004273 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004274 }
4275 sqlite3_close(pSrc);
4276 }else
4277
dan8d1edb92014-11-05 09:07:28 +00004278
4279 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
4280 if( nArg==2 ){
4281 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00004282#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00004283 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00004284#endif
dan8d1edb92014-11-05 09:07:28 +00004285 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004286 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00004287 rc = 1;
4288 }
4289 }else
4290
drhc2ce0be2014-05-29 12:36:14 +00004291 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00004292 ShellState data;
drh75897232000-05-29 14:26:00 +00004293 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00004294 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00004295 memcpy(&data, p, sizeof(data));
4296 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00004297 data.cMode = data.mode = MODE_Semi;
drh4926fec2016-04-13 15:33:42 +00004298 if( nArg>=2 && optionMatch(azArg[1], "indent") ){
4299 data.cMode = data.mode = MODE_Pretty;
4300 nArg--;
4301 if( nArg==2 ) azArg[1] = azArg[2];
4302 }
4303 if( nArg==2 && azArg[1][0]!='-' ){
drhc8d74412004-08-31 23:41:26 +00004304 int i;
drhf0693c82011-10-11 20:41:54 +00004305 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00004306 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00004307 char *new_argv[2], *new_colv[2];
4308 new_argv[0] = "CREATE TABLE sqlite_master (\n"
4309 " type text,\n"
4310 " name text,\n"
4311 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00004312 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00004313 " sql text\n"
4314 ")";
4315 new_argv[1] = 0;
4316 new_colv[0] = "sql";
4317 new_colv[1] = 0;
4318 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004319 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00004320 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00004321 char *new_argv[2], *new_colv[2];
4322 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
4323 " type text,\n"
4324 " name text,\n"
4325 " tbl_name text,\n"
4326 " rootpage integer,\n"
4327 " sql text\n"
4328 ")";
4329 new_argv[1] = 0;
4330 new_colv[0] = "sql";
4331 new_colv[1] = 0;
4332 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004333 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00004334 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00004335 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00004336 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004337 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004338 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004339 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004340 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00004341 "WHERE lower(tbl_name) LIKE shellstatic()"
4342 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00004343 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00004344 callback, &data, &zErrMsg);
4345 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00004346 }
drhc2ce0be2014-05-29 12:36:14 +00004347 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00004348 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004349 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004350 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004351 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004352 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00004353 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00004354 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00004355 callback, &data, &zErrMsg
4356 );
drhc2ce0be2014-05-29 12:36:14 +00004357 }else{
drh4926fec2016-04-13 15:33:42 +00004358 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00004359 rc = 1;
4360 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004361 }
drh75897232000-05-29 14:26:00 +00004362 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00004363 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004364 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00004365 rc = 1;
4366 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004367 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00004368 rc = 1;
4369 }else{
4370 rc = 0;
drh75897232000-05-29 14:26:00 +00004371 }
4372 }else
4373
drhabd4c722014-09-20 18:18:33 +00004374#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
4375 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
drh1d9be4f2015-01-22 11:29:25 +00004376 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00004377 }else
4378#endif
4379
drhe6229612014-08-18 15:08:26 +00004380#if defined(SQLITE_ENABLE_SESSION)
4381 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
4382 OpenSession *pSession = &p->aSession[0];
4383 char **azCmd = &azArg[1];
4384 int iSes = 0;
4385 int nCmd = nArg - 1;
4386 int i;
4387 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00004388 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00004389 if( nArg>=3 ){
4390 for(iSes=0; iSes<p->nSession; iSes++){
4391 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
4392 }
4393 if( iSes<p->nSession ){
4394 pSession = &p->aSession[iSes];
4395 azCmd++;
4396 nCmd--;
4397 }else{
4398 pSession = &p->aSession[0];
4399 iSes = 0;
4400 }
4401 }
4402
drh3a67b042014-08-18 17:56:31 +00004403 /* .session attach TABLE
4404 ** Invoke the sqlite3session_attach() interface to attach a particular
4405 ** table so that it is never filtered.
4406 */
4407 if( strcmp(azCmd[0],"attach")==0 ){
4408 if( nCmd!=2 ) goto session_syntax_error;
4409 if( pSession->p==0 ){
4410 session_not_open:
mistachkin899c5c92016-04-03 20:50:02 +00004411 raw_printf(stderr, "ERROR: No sessions are open\n");
drh3a67b042014-08-18 17:56:31 +00004412 }else{
4413 rc = sqlite3session_attach(pSession->p, azCmd[1]);
4414 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004415 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004416 rc = 0;
4417 }
4418 }
4419 }else
4420
4421 /* .session changeset FILE
4422 ** .session patchset FILE
4423 ** Write a changeset or patchset into a file. The file is overwritten.
4424 */
4425 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
4426 FILE *out = 0;
4427 if( nCmd!=2 ) goto session_syntax_error;
4428 if( pSession->p==0 ) goto session_not_open;
4429 out = fopen(azCmd[1], "wb");
4430 if( out==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004431 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
drh3a67b042014-08-18 17:56:31 +00004432 }else{
4433 int szChng;
4434 void *pChng;
4435 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00004436 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00004437 }else{
drh2967e0c2014-08-19 00:26:17 +00004438 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
4439 }
4440 if( rc ){
4441 printf("Error: error code %d\n", rc);
4442 rc = 0;
drh3a67b042014-08-18 17:56:31 +00004443 }
mistachkin1fe36bb2016-04-04 02:16:44 +00004444 if( pChng
drh3a67b042014-08-18 17:56:31 +00004445 && fwrite(pChng, szChng, 1, out)!=1 ){
mistachkin899c5c92016-04-03 20:50:02 +00004446 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
drh3a67b042014-08-18 17:56:31 +00004447 szChng);
4448 }
4449 sqlite3_free(pChng);
4450 fclose(out);
4451 }
4452 }else
4453
drhe6229612014-08-18 15:08:26 +00004454 /* .session close
4455 ** Close the identified session
4456 */
4457 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00004458 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00004459 if( p->nSession ){
4460 session_close(pSession);
4461 p->aSession[iSes] = p->aSession[--p->nSession];
4462 }
4463 }else
4464
drh03168ca2014-08-18 20:01:31 +00004465 /* .session enable ?BOOLEAN?
4466 ** Query or set the enable flag
4467 */
4468 if( strcmp(azCmd[0], "enable")==0 ){
4469 int ii;
4470 if( nCmd>2 ) goto session_syntax_error;
4471 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4472 if( p->nSession ){
4473 ii = sqlite3session_enable(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004474 utf8_printf(p->out, "session %s enable flag = %d\n",
4475 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004476 }
4477 }else
4478
4479 /* .session filter GLOB ....
4480 ** Set a list of GLOB patterns of table names to be excluded.
4481 */
4482 if( strcmp(azCmd[0], "filter")==0 ){
4483 int ii, nByte;
4484 if( nCmd<2 ) goto session_syntax_error;
4485 if( p->nSession ){
4486 for(ii=0; ii<pSession->nFilter; ii++){
4487 sqlite3_free(pSession->azFilter[ii]);
4488 }
4489 sqlite3_free(pSession->azFilter);
4490 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
4491 pSession->azFilter = sqlite3_malloc( nByte );
4492 if( pSession->azFilter==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004493 raw_printf(stderr, "Error: out or memory\n");
drh03168ca2014-08-18 20:01:31 +00004494 exit(1);
4495 }
4496 for(ii=1; ii<nCmd; ii++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004497 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
drh03168ca2014-08-18 20:01:31 +00004498 }
4499 pSession->nFilter = ii-1;
4500 }
4501 }else
4502
4503 /* .session indirect ?BOOLEAN?
4504 ** Query or set the indirect flag
4505 */
4506 if( strcmp(azCmd[0], "indirect")==0 ){
4507 int ii;
4508 if( nCmd>2 ) goto session_syntax_error;
4509 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4510 if( p->nSession ){
4511 ii = sqlite3session_indirect(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004512 utf8_printf(p->out, "session %s indirect flag = %d\n",
4513 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004514 }
4515 }else
4516
4517 /* .session isempty
4518 ** Determine if the session is empty
4519 */
4520 if( strcmp(azCmd[0], "isempty")==0 ){
4521 int ii;
4522 if( nCmd!=1 ) goto session_syntax_error;
4523 if( p->nSession ){
4524 ii = sqlite3session_isempty(pSession->p);
mistachkin899c5c92016-04-03 20:50:02 +00004525 utf8_printf(p->out, "session %s isempty flag = %d\n",
4526 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004527 }
4528 }else
4529
drhe6229612014-08-18 15:08:26 +00004530 /* .session list
4531 ** List all currently open sessions
4532 */
4533 if( strcmp(azCmd[0],"list")==0 ){
4534 for(i=0; i<p->nSession; i++){
mistachkin899c5c92016-04-03 20:50:02 +00004535 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
drhe6229612014-08-18 15:08:26 +00004536 }
4537 }else
4538
4539 /* .session open DB NAME
4540 ** Open a new session called NAME on the attached database DB.
4541 ** DB is normally "main".
4542 */
4543 if( strcmp(azCmd[0],"open")==0 ){
4544 char *zName;
4545 if( nCmd!=3 ) goto session_syntax_error;
4546 zName = azCmd[2];
4547 if( zName[0]==0 ) goto session_syntax_error;
4548 for(i=0; i<p->nSession; i++){
4549 if( strcmp(p->aSession[i].zName,zName)==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004550 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
drhe6229612014-08-18 15:08:26 +00004551 goto meta_command_exit;
4552 }
4553 }
4554 if( p->nSession>=ArraySize(p->aSession) ){
mistachkin899c5c92016-04-03 20:50:02 +00004555 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
drhe6229612014-08-18 15:08:26 +00004556 goto meta_command_exit;
4557 }
4558 pSession = &p->aSession[p->nSession];
4559 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
4560 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004561 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004562 rc = 0;
drhe6229612014-08-18 15:08:26 +00004563 goto meta_command_exit;
4564 }
drh03168ca2014-08-18 20:01:31 +00004565 pSession->nFilter = 0;
4566 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00004567 p->nSession++;
4568 pSession->zName = sqlite3_mprintf("%s", zName);
4569 }else
4570 /* If no command name matches, show a syntax error */
4571 session_syntax_error:
4572 session_help(p);
4573 }else
4574#endif
4575
drh340f5822013-06-27 13:01:21 +00004576#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00004577 /* Undocumented commands for internal testing. Subject to change
4578 ** without notice. */
4579 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
4580 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
4581 int i, v;
4582 for(i=1; i<nArg; i++){
4583 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00004584 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00004585 }
4586 }
4587 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
4588 int i; sqlite3_int64 v;
4589 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00004590 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00004591 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00004592 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00004593 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00004594 }
4595 }
4596 }else
drh340f5822013-06-27 13:01:21 +00004597#endif
drh348d19c2013-06-03 12:47:43 +00004598
drhc2ce0be2014-05-29 12:36:14 +00004599 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00004600 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004601 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00004602 rc = 1;
4603 }
drh6976c212014-07-24 12:09:47 +00004604 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004605 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00004606 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00004607 }
4608 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00004609 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
4610 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00004611 }
drh75897232000-05-29 14:26:00 +00004612 }else
4613
drh62cdde52014-05-28 20:22:28 +00004614 if( c=='s'
4615 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00004616 ){
4617 char *zCmd;
drh54027102014-08-06 14:36:53 +00004618 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00004619 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004620 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00004621 rc = 1;
4622 goto meta_command_exit;
4623 }
drhdcb3e3d2014-05-29 03:17:29 +00004624 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00004625 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00004626 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
4627 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00004628 }
drh54027102014-08-06 14:36:53 +00004629 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00004630 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00004631 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00004632 }else
4633
drhc2ce0be2014-05-29 12:36:14 +00004634 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drheacd29d2016-04-15 15:03:27 +00004635 static const char *azBool[] = { "off", "on", "full", "unk" };
persicom7e2dfdd2002-04-18 02:46:52 +00004636 int i;
drhc2ce0be2014-05-29 12:36:14 +00004637 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00004638 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00004639 rc = 1;
4640 goto meta_command_exit;
4641 }
drheacd29d2016-04-15 15:03:27 +00004642 utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]);
4643 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
drh700c2522016-02-09 18:39:25 +00004644 utf8_printf(p->out, "%12.12s: %s\n","explain",
4645 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
drheacd29d2016-04-15 15:03:27 +00004646 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004647 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
4648 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00004649 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00004650 raw_printf(p->out, "\n");
4651 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00004652 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00004653 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004654 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004655 raw_printf(p->out, "\n");
4656 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004657 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004658 raw_printf(p->out, "\n");
drheacd29d2016-04-15 15:03:27 +00004659 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004660 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00004661 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00004662 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00004663 }
mistachkinaae280e2015-12-31 19:06:24 +00004664 raw_printf(p->out, "\n");
drhcd0509e2016-09-16 00:26:08 +00004665 utf8_printf(p->out, "%12.12s: %s\n", "filename",
4666 p->zDbFilename ? p->zDbFilename : "");
persicom7e2dfdd2002-04-18 02:46:52 +00004667 }else
4668
drhc2ce0be2014-05-29 12:36:14 +00004669 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
4670 if( nArg==2 ){
4671 p->statsOn = booleanValue(azArg[1]);
drh34784902016-02-27 17:12:36 +00004672 }else if( nArg==1 ){
4673 display_stats(p->db, p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004674 }else{
drh34784902016-02-27 17:12:36 +00004675 raw_printf(stderr, "Usage: .stats ?on|off?\n");
drhc2ce0be2014-05-29 12:36:14 +00004676 rc = 1;
4677 }
shaneh642d8b82010-07-28 16:05:34 +00004678 }else
4679
drhc2ce0be2014-05-29 12:36:14 +00004680 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00004681 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00004682 char **azResult;
drh98781232012-04-23 12:38:05 +00004683 int nRow, nAlloc;
4684 char *zSql = 0;
4685 int ii;
drh05782482013-10-24 15:20:20 +00004686 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00004687 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00004688 if( rc ) return shellDatabaseError(p->db);
4689
4690 /* Create an SQL statement to query for the list of tables in the
4691 ** main and all attached databases where the table name matches the
4692 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00004693 zSql = sqlite3_mprintf(
4694 "SELECT name FROM sqlite_master"
4695 " WHERE type IN ('table','view')"
4696 " AND name NOT LIKE 'sqlite_%%'"
4697 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00004698 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00004699 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
4700 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
4701 if( strcmp(zDbName,"temp")==0 ){
4702 zSql = sqlite3_mprintf(
4703 "%z UNION ALL "
4704 "SELECT 'temp.' || name FROM sqlite_temp_master"
4705 " WHERE type IN ('table','view')"
4706 " AND name NOT LIKE 'sqlite_%%'"
4707 " AND name LIKE ?1", zSql);
4708 }else{
4709 zSql = sqlite3_mprintf(
4710 "%z UNION ALL "
4711 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4712 " WHERE type IN ('table','view')"
4713 " AND name NOT LIKE 'sqlite_%%'"
4714 " AND name LIKE ?1", zSql, zDbName, zDbName);
4715 }
drha50da102000-08-08 20:19:09 +00004716 }
dand95bb392015-09-30 11:19:05 +00004717 rc = sqlite3_finalize(pStmt);
4718 if( zSql && rc==SQLITE_OK ){
4719 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
4720 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4721 }
drh98781232012-04-23 12:38:05 +00004722 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00004723 if( !zSql ) return shellNomemError();
4724 if( rc ) return shellDatabaseError(p->db);
4725
4726 /* Run the SQL statement prepared by the above block. Store the results
4727 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00004728 nRow = nAlloc = 0;
4729 azResult = 0;
4730 if( nArg>1 ){
4731 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00004732 }else{
drh98781232012-04-23 12:38:05 +00004733 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
4734 }
4735 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4736 if( nRow>=nAlloc ){
4737 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00004738 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00004739 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00004740 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00004741 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00004742 break;
4743 }
mistachkin8e189222015-04-19 21:43:16 +00004744 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00004745 azResult = azNew;
4746 }
4747 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00004748 if( 0==azResult[nRow] ){
4749 rc = shellNomemError();
4750 break;
4751 }
4752 nRow++;
drh98781232012-04-23 12:38:05 +00004753 }
dand95bb392015-09-30 11:19:05 +00004754 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
4755 rc = shellDatabaseError(p->db);
4756 }
4757
4758 /* Pretty-print the contents of array azResult[] to the output */
4759 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00004760 int len, maxlen = 0;
4761 int i, j;
4762 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00004763 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00004764 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00004765 if( len>maxlen ) maxlen = len;
4766 }
4767 nPrintCol = 80/(maxlen+2);
4768 if( nPrintCol<1 ) nPrintCol = 1;
4769 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
4770 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00004771 for(j=i; j<nRow; j+=nPrintRow){
4772 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00004773 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
4774 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00004775 }
mistachkinaae280e2015-12-31 19:06:24 +00004776 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00004777 }
4778 }
dand95bb392015-09-30 11:19:05 +00004779
drh98781232012-04-23 12:38:05 +00004780 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
4781 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00004782 }else
4783
drh2db82112016-09-15 21:35:24 +00004784 /* Begin redirecting output to the file "testcase-out.txt" */
4785 if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
4786 output_reset(p);
4787 p->out = output_file_open("testcase-out.txt");
4788 if( p->out==0 ){
mistachkin2f9a6132016-11-11 05:19:45 +00004789 raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
drh2db82112016-09-15 21:35:24 +00004790 }
drh760c8162016-09-16 02:52:22 +00004791 if( nArg>=2 ){
4792 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
4793 }else{
4794 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
4795 }
drh2db82112016-09-15 21:35:24 +00004796 }else
drh2db82112016-09-15 21:35:24 +00004797
drh16eb5942016-11-03 13:01:38 +00004798#ifndef SQLITE_OMIT_BUILTIN_TEST
shaneh96887e12011-02-10 21:08:58 +00004799 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00004800 static const struct {
4801 const char *zCtrlName; /* Name of a test-control option */
4802 int ctrlCode; /* Integer code for that option */
4803 } aCtrl[] = {
4804 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
4805 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
4806 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
4807 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
4808 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
4809 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
4810 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
4811 { "assert", SQLITE_TESTCTRL_ASSERT },
4812 { "always", SQLITE_TESTCTRL_ALWAYS },
4813 { "reserve", SQLITE_TESTCTRL_RESERVE },
4814 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
4815 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00004816 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00004817 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00004818 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00004819 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00004820 };
shaneh96887e12011-02-10 21:08:58 +00004821 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00004822 int rc2 = 0;
4823 int i, n2;
drh05782482013-10-24 15:20:20 +00004824 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00004825
drhd416fe72011-03-17 16:45:50 +00004826 /* convert testctrl text option to value. allow any unique prefix
4827 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00004828 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00004829 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00004830 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00004831 if( testctrl<0 ){
4832 testctrl = aCtrl[i].ctrlCode;
4833 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004834 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00004835 testctrl = -1;
4836 break;
4837 }
4838 }
4839 }
drh348d19c2013-06-03 12:47:43 +00004840 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004841 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00004842 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004843 }else{
4844 switch(testctrl){
4845
4846 /* sqlite3_test_control(int, db, int) */
4847 case SQLITE_TESTCTRL_OPTIMIZATIONS:
mistachkin1fe36bb2016-04-04 02:16:44 +00004848 case SQLITE_TESTCTRL_RESERVE:
shaneh96887e12011-02-10 21:08:58 +00004849 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004850 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00004851 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004852 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004853 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004854 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004855 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004856 }
4857 break;
4858
4859 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004860 case SQLITE_TESTCTRL_PRNG_SAVE:
4861 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004862 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004863 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004864 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00004865 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00004866 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004867 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004868 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
4869 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004870 }
4871 break;
4872
4873 /* sqlite3_test_control(int, uint) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004874 case SQLITE_TESTCTRL_PENDING_BYTE:
shaneh96887e12011-02-10 21:08:58 +00004875 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004876 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004877 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004878 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004879 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004880 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00004881 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004882 }
4883 break;
mistachkin1fe36bb2016-04-04 02:16:44 +00004884
shaneh96887e12011-02-10 21:08:58 +00004885 /* sqlite3_test_control(int, int) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004886 case SQLITE_TESTCTRL_ASSERT:
4887 case SQLITE_TESTCTRL_ALWAYS:
4888 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004889 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004890 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004891 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004892 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004893 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004894 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004895 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004896 }
4897 break;
4898
4899 /* sqlite3_test_control(int, char *) */
4900#ifdef SQLITE_N_KEYWORD
mistachkin1fe36bb2016-04-04 02:16:44 +00004901 case SQLITE_TESTCTRL_ISKEYWORD:
shaneh96887e12011-02-10 21:08:58 +00004902 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004903 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004904 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004905 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004906 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004907 utf8_printf(stderr,
4908 "Error: testctrl %s takes a single char * option\n",
4909 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004910 }
4911 break;
4912#endif
4913
drh1ffede82015-01-30 20:59:27 +00004914 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004915 if( nArg==5 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004916 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004917 azArg[2],
drh8964b342015-01-29 17:54:52 +00004918 integerValue(azArg[3]),
4919 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00004920 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004921 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004922 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004923 }
4924 break;
4925
mistachkin1fe36bb2016-04-04 02:16:44 +00004926 case SQLITE_TESTCTRL_BITVEC_TEST:
4927 case SQLITE_TESTCTRL_FAULT_INSTALL:
4928 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4929 case SQLITE_TESTCTRL_SCRATCHMALLOC:
shaneh96887e12011-02-10 21:08:58 +00004930 default:
mistachkinaae280e2015-12-31 19:06:24 +00004931 utf8_printf(stderr,
4932 "Error: CLI support for testctrl %s not implemented\n",
4933 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004934 break;
4935 }
4936 }
4937 }else
4938
drhc2ce0be2014-05-29 12:36:14 +00004939 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004940 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004941 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004942 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004943
drhc2ce0be2014-05-29 12:36:14 +00004944 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4945 if( nArg==2 ){
4946 enableTimer = booleanValue(azArg[1]);
4947 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00004948 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00004949 enableTimer = 0;
4950 }
4951 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004952 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004953 rc = 1;
4954 }
shanehe2aa9d72009-11-06 17:20:17 +00004955 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004956
drhc2ce0be2014-05-29 12:36:14 +00004957 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004958 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004959 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004960 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004961 rc = 1;
4962 goto meta_command_exit;
4963 }
drh657b4a82015-03-19 13:30:41 +00004964 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004965 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004966#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004967 if( p->traceOut==0 ){
drh4b363a52016-07-23 20:27:41 +00004968 sqlite3_trace_v2(p->db, 0, 0, 0);
drh42f64e52012-04-04 16:56:23 +00004969 }else{
drh4b363a52016-07-23 20:27:41 +00004970 sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004971 }
4972#endif
4973 }else
drh16eb5942016-11-03 13:01:38 +00004974#endif /* !defined(SQLITE_OMIT_BUILTIN_TEST) */
drh42f64e52012-04-04 16:56:23 +00004975
drhf442e332014-09-10 19:01:14 +00004976#if SQLITE_USER_AUTHENTICATION
4977 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4978 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004979 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00004980 rc = 1;
4981 goto meta_command_exit;
4982 }
drh7883ecf2014-09-11 16:19:31 +00004983 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004984 if( strcmp(azArg[1],"login")==0 ){
4985 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00004986 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00004987 rc = 1;
4988 goto meta_command_exit;
4989 }
drhd39c40f2014-09-11 00:27:53 +00004990 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4991 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004992 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004993 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00004994 rc = 1;
4995 }
4996 }else if( strcmp(azArg[1],"add")==0 ){
4997 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004998 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004999 rc = 1;
5000 goto meta_command_exit;
5001 }
drhd39c40f2014-09-11 00:27:53 +00005002 rc = sqlite3_user_add(p->db, azArg[2],
5003 azArg[3], (int)strlen(azArg[3]),
5004 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00005005 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005006 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00005007 rc = 1;
5008 }
5009 }else if( strcmp(azArg[1],"edit")==0 ){
5010 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00005011 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00005012 rc = 1;
5013 goto meta_command_exit;
5014 }
drhd39c40f2014-09-11 00:27:53 +00005015 rc = sqlite3_user_change(p->db, azArg[2],
5016 azArg[3], (int)strlen(azArg[3]),
5017 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00005018 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005019 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00005020 rc = 1;
5021 }
5022 }else if( strcmp(azArg[1],"delete")==0 ){
5023 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00005024 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00005025 rc = 1;
5026 goto meta_command_exit;
5027 }
5028 rc = sqlite3_user_delete(p->db, azArg[2]);
5029 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005030 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00005031 rc = 1;
5032 }
5033 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005034 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00005035 rc = 1;
5036 goto meta_command_exit;
mistachkin1fe36bb2016-04-04 02:16:44 +00005037 }
drhf442e332014-09-10 19:01:14 +00005038 }else
5039#endif /* SQLITE_USER_AUTHENTICATION */
5040
drh9fd301b2011-06-03 13:28:22 +00005041 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005042 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00005043 sqlite3_libversion(), sqlite3_sourceid());
5044 }else
5045
drh790f2872015-11-28 18:06:36 +00005046 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
5047 const char *zDbName = nArg==2 ? azArg[1] : "main";
5048 sqlite3_vfs *pVfs;
5049 if( p->db ){
5050 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
5051 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00005052 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
5053 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
5054 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
5055 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00005056 }
5057 }
5058 }else
5059
drhb19e7352016-01-12 19:37:20 +00005060 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
5061 sqlite3_vfs *pVfs;
5062 sqlite3_vfs *pCurrent = 0;
5063 if( p->db ){
5064 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
5065 }
5066 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
5067 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
5068 pVfs==pCurrent ? " <--- CURRENT" : "");
5069 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
5070 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
5071 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
5072 if( pVfs->pNext ){
5073 raw_printf(p->out, "-----------------------------------\n");
5074 }
5075 }
5076 }else
5077
drhde60fc22011-12-14 17:53:36 +00005078 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
5079 const char *zDbName = nArg==2 ? azArg[1] : "main";
5080 char *zVfsName = 0;
5081 if( p->db ){
5082 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
5083 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00005084 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00005085 sqlite3_free(zVfsName);
5086 }
5087 }
5088 }else
5089
drhcef4fc82012-09-21 22:50:45 +00005090#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
5091 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
drhc2ce0be2014-05-29 12:36:14 +00005092 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00005093 }else
5094#endif
5095
drhc2ce0be2014-05-29 12:36:14 +00005096 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00005097 int j;
drh43617e92006-03-06 20:55:46 +00005098 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00005099 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00005100 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00005101 }
5102 }else
5103
5104 {
mistachkinaae280e2015-12-31 19:06:24 +00005105 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00005106 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00005107 rc = 1;
drh75897232000-05-29 14:26:00 +00005108 }
drh67505e72002-04-19 12:34:06 +00005109
drhc2ce0be2014-05-29 12:36:14 +00005110meta_command_exit:
5111 if( p->outCount ){
5112 p->outCount--;
5113 if( p->outCount==0 ) output_reset(p);
5114 }
drh67505e72002-04-19 12:34:06 +00005115 return rc;
drh75897232000-05-29 14:26:00 +00005116}
5117
drh67505e72002-04-19 12:34:06 +00005118/*
drh91a66392007-09-07 01:12:32 +00005119** Return TRUE if a semicolon occurs anywhere in the first N characters
5120** of string z[].
drh324ccef2003-02-05 14:06:20 +00005121*/
drh9f099fd2013-08-06 14:01:46 +00005122static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00005123 int i;
5124 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
5125 return 0;
drh324ccef2003-02-05 14:06:20 +00005126}
5127
5128/*
drh70c7a4b2003-04-26 03:03:06 +00005129** Test to see if a line consists entirely of whitespace.
5130*/
5131static int _all_whitespace(const char *z){
5132 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00005133 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00005134 if( *z=='/' && z[1]=='*' ){
5135 z += 2;
5136 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
5137 if( *z==0 ) return 0;
5138 z++;
5139 continue;
5140 }
5141 if( *z=='-' && z[1]=='-' ){
5142 z += 2;
5143 while( *z && *z!='\n' ){ z++; }
5144 if( *z==0 ) return 1;
5145 continue;
5146 }
5147 return 0;
5148 }
5149 return 1;
5150}
5151
5152/*
drha9b17162003-04-29 18:01:28 +00005153** Return TRUE if the line typed in is an SQL command terminator other
5154** than a semi-colon. The SQL Server style "go" command is understood
5155** as is the Oracle "/".
5156*/
drh9f099fd2013-08-06 14:01:46 +00005157static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00005158 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00005159 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
5160 return 1; /* Oracle */
5161 }
drhf0693c82011-10-11 20:41:54 +00005162 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00005163 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00005164 return 1; /* SQL Server */
5165 }
5166 return 0;
5167}
5168
5169/*
drh233a5312008-12-18 22:25:13 +00005170** Return true if zSql is a complete SQL statement. Return false if it
5171** ends in the middle of a string literal or C-style comment.
5172*/
drh9f099fd2013-08-06 14:01:46 +00005173static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00005174 int rc;
5175 if( zSql==0 ) return 1;
5176 zSql[nSql] = ';';
5177 zSql[nSql+1] = 0;
5178 rc = sqlite3_complete(zSql);
5179 zSql[nSql] = 0;
5180 return rc;
5181}
5182
5183/*
drh4e8142c2016-11-11 14:54:22 +00005184** Run a single line of SQL
5185*/
5186static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
5187 int rc;
5188 char *zErrMsg = 0;
5189
5190 open_db(p, 0);
5191 if( p->backslashOn ) resolve_backslashes(zSql);
5192 BEGIN_TIMER;
5193 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
5194 END_TIMER;
5195 if( rc || zErrMsg ){
5196 char zPrefix[100];
5197 if( in!=0 || !stdin_is_interactive ){
5198 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
5199 "Error: near line %d:", startline);
5200 }else{
5201 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
5202 }
5203 if( zErrMsg!=0 ){
5204 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
5205 sqlite3_free(zErrMsg);
5206 zErrMsg = 0;
5207 }else{
5208 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
5209 }
5210 return 1;
5211 }else if( p->countChanges ){
5212 raw_printf(p->out, "changes: %3d total_changes: %d\n",
5213 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
5214 }
5215 return 0;
5216}
5217
5218
5219/*
drh67505e72002-04-19 12:34:06 +00005220** Read input from *in and process it. If *in==0 then input
5221** is interactive - the user is typing it it. Otherwise, input
5222** is coming from a file or device. A prompt is issued and history
5223** is saved only if input is interactive. An interrupt signal will
5224** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00005225**
5226** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00005227*/
drhdcd87a92014-08-18 13:45:42 +00005228static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00005229 char *zLine = 0; /* A single input line */
5230 char *zSql = 0; /* Accumulated SQL text */
5231 int nLine; /* Length of current line */
5232 int nSql = 0; /* Bytes of zSql[] used */
5233 int nAlloc = 0; /* Allocated zSql[] space */
5234 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
drh9f099fd2013-08-06 14:01:46 +00005235 int rc; /* Error code */
5236 int errCnt = 0; /* Number of errors seen */
5237 int lineno = 0; /* Current line number */
5238 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00005239
5240 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
5241 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00005242 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00005243 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00005244 /* End of input */
drhfc8b40f2016-09-07 10:10:18 +00005245 if( in==0 && stdin_is_interactive ) printf("\n");
drh9b8d3572012-04-21 11:33:39 +00005246 break;
drhc49f44e2006-10-26 18:15:42 +00005247 }
drh67505e72002-04-19 12:34:06 +00005248 if( seenInterrupt ){
5249 if( in!=0 ) break;
5250 seenInterrupt = 0;
5251 }
drhc28490c2006-10-26 14:25:58 +00005252 lineno++;
drh849a9d92013-12-21 15:46:06 +00005253 if( nSql==0 && _all_whitespace(zLine) ){
5254 if( p->echoOn ) printf("%s\n", zLine);
5255 continue;
5256 }
drh2af0b2d2002-02-21 02:25:02 +00005257 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00005258 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00005259 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00005260 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00005261 break;
5262 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00005263 errCnt++;
5264 }
drhdaffd0e2001-04-11 14:28:42 +00005265 continue;
5266 }
drh9f099fd2013-08-06 14:01:46 +00005267 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00005268 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00005269 }
drh9f099fd2013-08-06 14:01:46 +00005270 nLine = strlen30(zLine);
5271 if( nSql+nLine+2>=nAlloc ){
5272 nAlloc = nSql+nLine+100;
5273 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00005274 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005275 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00005276 exit(1);
5277 }
drhdaffd0e2001-04-11 14:28:42 +00005278 }
drh9f099fd2013-08-06 14:01:46 +00005279 nSqlPrior = nSql;
5280 if( nSql==0 ){
5281 int i;
5282 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00005283 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00005284 memcpy(zSql, zLine+i, nLine+1-i);
5285 startline = lineno;
5286 nSql = nLine-i;
5287 }else{
5288 zSql[nSql++] = '\n';
5289 memcpy(zSql+nSql, zLine, nLine+1);
5290 nSql += nLine;
5291 }
5292 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00005293 && sqlite3_complete(zSql) ){
drh4e8142c2016-11-11 14:54:22 +00005294 errCnt += runOneSqlLine(p, zSql, in, startline);
drhdaffd0e2001-04-11 14:28:42 +00005295 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00005296 if( p->outCount ){
5297 output_reset(p);
5298 p->outCount = 0;
5299 }
drh9f099fd2013-08-06 14:01:46 +00005300 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00005301 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00005302 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00005303 }
5304 }
drh4e8142c2016-11-11 14:54:22 +00005305 if( nSql && !_all_whitespace(zSql) ){
5306 runOneSqlLine(p, zSql, in, startline);
drhdaffd0e2001-04-11 14:28:42 +00005307 }
drh1f9ca2c2015-08-25 16:57:52 +00005308 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00005309 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00005310 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00005311}
5312
drh67505e72002-04-19 12:34:06 +00005313/*
5314** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00005315** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00005316*/
drhd1459152016-09-16 19:11:03 +00005317static char *find_home_dir(int clearFlag){
drh85e72432012-04-11 11:38:53 +00005318 static char *home_dir = NULL;
drhd1459152016-09-16 19:11:03 +00005319 if( clearFlag ){
5320 free(home_dir);
5321 home_dir = 0;
5322 return 0;
5323 }
drh85e72432012-04-11 11:38:53 +00005324 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00005325
drh4ace5362014-11-10 14:42:28 +00005326#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
5327 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00005328 {
5329 struct passwd *pwent;
5330 uid_t uid = getuid();
5331 if( (pwent=getpwuid(uid)) != NULL) {
5332 home_dir = pwent->pw_dir;
5333 }
drh67505e72002-04-19 12:34:06 +00005334 }
5335#endif
5336
chw65d3c132007-11-12 21:09:10 +00005337#if defined(_WIN32_WCE)
5338 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
5339 */
drh85e72432012-04-11 11:38:53 +00005340 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00005341#else
5342
drh83905c92012-06-21 13:00:37 +00005343#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00005344 if (!home_dir) {
5345 home_dir = getenv("USERPROFILE");
5346 }
5347#endif
5348
drh67505e72002-04-19 12:34:06 +00005349 if (!home_dir) {
5350 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00005351 }
5352
drh83905c92012-06-21 13:00:37 +00005353#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00005354 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00005355 char *zDrive, *zPath;
5356 int n;
5357 zDrive = getenv("HOMEDRIVE");
5358 zPath = getenv("HOMEPATH");
5359 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00005360 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00005361 home_dir = malloc( n );
5362 if( home_dir==0 ) return 0;
5363 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
5364 return home_dir;
5365 }
5366 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00005367 }
5368#endif
5369
chw65d3c132007-11-12 21:09:10 +00005370#endif /* !_WIN32_WCE */
5371
drh67505e72002-04-19 12:34:06 +00005372 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00005373 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00005374 char *z = malloc( n );
5375 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00005376 home_dir = z;
5377 }
drhe98d4fa2002-04-21 19:06:22 +00005378
drh67505e72002-04-19 12:34:06 +00005379 return home_dir;
5380}
5381
5382/*
5383** Read input from the file given by sqliterc_override. Or if that
5384** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00005385**
5386** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00005387*/
drh534f4df2015-02-28 14:03:35 +00005388static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00005389 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00005390 const char *sqliterc_override /* Name of config file. NULL to use default */
5391){
persicom7e2dfdd2002-04-18 02:46:52 +00005392 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00005393 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00005394 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00005395 FILE *in = NULL;
5396
5397 if (sqliterc == NULL) {
drhd1459152016-09-16 19:11:03 +00005398 home_dir = find_home_dir(0);
drhe98d4fa2002-04-21 19:06:22 +00005399 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005400 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00005401 " cannot read ~/.sqliterc\n");
5402 return;
drhe98d4fa2002-04-21 19:06:22 +00005403 }
drh2f3de322012-06-27 16:41:31 +00005404 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00005405 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
5406 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00005407 }
drha1f9b5e2004-02-14 16:31:02 +00005408 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00005409 if( in ){
drhc28490c2006-10-26 14:25:58 +00005410 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00005411 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00005412 }
drh534f4df2015-02-28 14:03:35 +00005413 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00005414 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00005415 }
drh85e72432012-04-11 11:38:53 +00005416 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00005417}
5418
drh67505e72002-04-19 12:34:06 +00005419/*
drhe1e38c42003-05-04 18:30:59 +00005420** Show available command line options
5421*/
mistachkin1fe36bb2016-04-04 02:16:44 +00005422static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00005423 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00005424 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00005425 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005426 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00005427 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00005428 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00005429 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00005430 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00005431 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00005432#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
5433 " -heap SIZE Size of heap for memsys3 or memsys5\n"
5434#endif
drhcc3b4f82012-02-07 14:13:50 +00005435 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00005436 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00005437 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005438 " -line set output mode to 'line'\n"
5439 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00005440 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00005441 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00005442#ifdef SQLITE_ENABLE_MULTIPLEX
5443 " -multiplex enable the multiplexor VFS\n"
5444#endif
mistachkine0d68852014-12-11 03:12:33 +00005445 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00005446 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00005447 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
5448 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00005449 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00005450 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00005451 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00005452 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00005453#ifdef SQLITE_ENABLE_VFSTRACE
5454 " -vfstrace enable tracing of all VFS calls\n"
5455#endif
drhe1e38c42003-05-04 18:30:59 +00005456;
5457static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00005458 utf8_printf(stderr,
mistachkin1fe36bb2016-04-04 02:16:44 +00005459 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
drh80e8be92006-08-29 12:04:19 +00005460 "FILENAME is the name of an SQLite database. A new database is created\n"
5461 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00005462 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00005463 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00005464 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005465 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00005466 }
5467 exit(1);
5468}
5469
5470/*
drh67505e72002-04-19 12:34:06 +00005471** Initialize the state information in data
5472*/
drhdcd87a92014-08-18 13:45:42 +00005473static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00005474 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00005475 data->normalMode = data->cMode = data->mode = MODE_List;
5476 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00005477 memcpy(data->colSeparator,SEP_Column, 2);
5478 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00005479 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00005480 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00005481 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00005482 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00005483 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00005484 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
5485 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00005486}
5487
drh98d312f2012-10-25 15:23:14 +00005488/*
drh5c7976f2014-02-10 19:59:27 +00005489** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00005490*/
5491#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00005492static void printBold(const char *zText){
5493 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
5494 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
5495 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
5496 SetConsoleTextAttribute(out,
5497 FOREGROUND_RED|FOREGROUND_INTENSITY
5498 );
5499 printf("%s", zText);
5500 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00005501}
5502#else
drh5c7976f2014-02-10 19:59:27 +00005503static void printBold(const char *zText){
5504 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00005505}
5506#endif
5507
5508/*
drh98d312f2012-10-25 15:23:14 +00005509** Get the argument to an --option. Throw an error and die if no argument
5510** is available.
5511*/
5512static char *cmdline_option_value(int argc, char **argv, int i){
5513 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00005514 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00005515 argv[0], argv[argc-1]);
5516 exit(1);
5517 }
5518 return argv[i];
5519}
5520
mistachkin1fe36bb2016-04-04 02:16:44 +00005521#ifndef SQLITE_SHELL_IS_UTF8
5522# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
5523# define SQLITE_SHELL_IS_UTF8 (0)
5524# else
5525# define SQLITE_SHELL_IS_UTF8 (1)
5526# endif
5527#endif
5528
5529#if SQLITE_SHELL_IS_UTF8
mistachkin44723ce2015-03-21 02:22:37 +00005530int SQLITE_CDECL main(int argc, char **argv){
mistachkin1fe36bb2016-04-04 02:16:44 +00005531#else
5532int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
mistachkin1810f222016-04-04 02:33:34 +00005533 char **argv;
mistachkin1fe36bb2016-04-04 02:16:44 +00005534#endif
drh75897232000-05-29 14:26:00 +00005535 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00005536 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00005537 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00005538 int i;
drhc28490c2006-10-26 14:25:58 +00005539 int rc = 0;
drhb3735912014-02-10 16:13:42 +00005540 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00005541 int readStdin = 1;
5542 int nCmd = 0;
5543 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00005544
mistachkin1fe36bb2016-04-04 02:16:44 +00005545 setBinaryMode(stdin, 0);
5546 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
mistachkin1810f222016-04-04 02:33:34 +00005547 stdin_is_interactive = isatty(0);
5548 stdout_is_console = isatty(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005549
drh69b30ab2014-02-27 15:11:52 +00005550#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00005551 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005552 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00005553 sqlite3_sourceid(), SQLITE_SOURCE_ID);
5554 exit(1);
5555 }
drhc7181902014-02-27 15:04:13 +00005556#endif
persicom7e2dfdd2002-04-18 02:46:52 +00005557 main_init(&data);
mistachkin1fe36bb2016-04-04 02:16:44 +00005558#if !SQLITE_SHELL_IS_UTF8
5559 sqlite3_initialize();
5560 argv = sqlite3_malloc64(sizeof(argv[0])*argc);
5561 if( argv==0 ){
5562 raw_printf(stderr, "out of memory\n");
5563 exit(1);
5564 }
5565 for(i=0; i<argc; i++){
5566 argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
5567 if( argv[i]==0 ){
5568 raw_printf(stderr, "out of memory\n");
5569 exit(1);
5570 }
5571 }
5572#endif
mistachkin1810f222016-04-04 02:33:34 +00005573 assert( argc>=1 && argv && argv[0] );
mistachkin1fe36bb2016-04-04 02:16:44 +00005574 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00005575
drh44c2eb12003-04-30 11:38:26 +00005576 /* Make sure we have a valid signal handler early, before anything
5577 ** else is done.
5578 */
drh4c504392000-10-16 22:06:40 +00005579#ifdef SIGINT
5580 signal(SIGINT, interrupt_handler);
5581#endif
drh44c2eb12003-04-30 11:38:26 +00005582
drhac5649a2014-11-28 13:35:03 +00005583#ifdef SQLITE_SHELL_DBNAME_PROC
5584 {
5585 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
5586 ** of a C-function that will provide the name of the database file. Use
5587 ** this compile-time option to embed this shell program in larger
5588 ** applications. */
5589 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
5590 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
5591 warnInmemoryDb = 0;
5592 }
5593#endif
5594
drh22fbcb82004-02-01 01:22:50 +00005595 /* Do an initial pass through the command-line argument to locate
5596 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00005597 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00005598 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00005599 */
drh98d312f2012-10-25 15:23:14 +00005600 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00005601 char *z;
drhc28490c2006-10-26 14:25:58 +00005602 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005603 if( z[0]!='-' ){
5604 if( data.zDbFilename==0 ){
5605 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00005606 }else{
5607 /* Excesss arguments are interpreted as SQL (or dot-commands) and
5608 ** mean that nothing is read from stdin */
5609 readStdin = 0;
5610 nCmd++;
5611 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
5612 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005613 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00005614 exit(1);
5615 }
5616 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00005617 }
drh98d312f2012-10-25 15:23:14 +00005618 }
drhcc3b4f82012-02-07 14:13:50 +00005619 if( z[1]=='-' ) z++;
5620 if( strcmp(z,"-separator")==0
5621 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00005622 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00005623 || strcmp(z,"-cmd")==0
5624 ){
drh98d312f2012-10-25 15:23:14 +00005625 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005626 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00005627 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005628 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00005629 /* Need to check for batch mode here to so we can avoid printing
mistachkin1fe36bb2016-04-04 02:16:44 +00005630 ** informational messages (like from process_sqliterc) before
drh98d312f2012-10-25 15:23:14 +00005631 ** we do the actual processing of arguments later in a second pass.
5632 */
shanef69573d2009-10-24 02:06:14 +00005633 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00005634 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00005635#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00005636 const char *zSize;
5637 sqlite3_int64 szHeap;
5638
drh98d312f2012-10-25 15:23:14 +00005639 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00005640 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00005641 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00005642 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
drhc530b9c2016-07-25 11:27:22 +00005643#else
5644 (void)cmdline_option_value(argc, argv, ++i);
drh9c88d682010-12-17 14:03:01 +00005645#endif
drh44dec872014-08-30 15:49:25 +00005646 }else if( strcmp(z,"-scratch")==0 ){
5647 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005648 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005649 if( sz>400000 ) sz = 400000;
5650 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00005651 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005652 if( n>10 ) n = 10;
5653 if( n<1 ) n = 1;
5654 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
5655 data.shellFlgs |= SHFLG_Scratch;
5656 }else if( strcmp(z,"-pagecache")==0 ){
5657 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005658 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005659 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00005660 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005661 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00005662 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
5663 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00005664 data.shellFlgs |= SHFLG_Pagecache;
5665 }else if( strcmp(z,"-lookaside")==0 ){
5666 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005667 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005668 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005669 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005670 if( n<0 ) n = 0;
5671 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
5672 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00005673#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00005674 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00005675 extern int vfstrace_register(
5676 const char *zTraceName,
5677 const char *zOldVfsName,
5678 int (*xOut)(const char*,void*),
5679 void *pOutArg,
5680 int makeDefault
5681 );
drh2b625e22011-03-16 17:05:28 +00005682 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00005683#endif
drh6f25e892011-07-08 17:02:57 +00005684#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00005685 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00005686 extern int sqlite3_multiple_initialize(const char*,int);
5687 sqlite3_multiplex_initialize(0, 1);
5688#endif
drh7d9f3942013-04-03 01:26:54 +00005689 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00005690 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
5691 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00005692 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00005693 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00005694 if( pVfs ){
5695 sqlite3_vfs_register(pVfs, 1);
5696 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005697 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00005698 exit(1);
5699 }
drh44c2eb12003-04-30 11:38:26 +00005700 }
5701 }
drh98d312f2012-10-25 15:23:14 +00005702 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00005703#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00005704 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00005705 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00005706#else
mistachkinaae280e2015-12-31 19:06:24 +00005707 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00005708 return 1;
drh01b41712005-08-29 23:06:23 +00005709#endif
drh98d312f2012-10-25 15:23:14 +00005710 }
5711 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00005712
drh44c2eb12003-04-30 11:38:26 +00005713 /* Go ahead and open the database file if it already exists. If the
5714 ** file does not exist, delay opening it. This prevents empty database
5715 ** files from being created if a user mistypes the database name argument
5716 ** to the sqlite command-line tool.
5717 */
drhc8d74412004-08-31 23:41:26 +00005718 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00005719 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00005720 }
5721
drh22fbcb82004-02-01 01:22:50 +00005722 /* Process the initialization file if there is one. If no -init option
5723 ** is given on the command line, look for a file named ~/.sqliterc and
5724 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00005725 */
drh534f4df2015-02-28 14:03:35 +00005726 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00005727
drh22fbcb82004-02-01 01:22:50 +00005728 /* Make a second pass through the command-line argument and set
5729 ** options. This second pass is delayed until after the initialization
5730 ** file is processed so that the command-line arguments will override
5731 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00005732 */
drh98d312f2012-10-25 15:23:14 +00005733 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00005734 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005735 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00005736 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00005737 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00005738 i++;
5739 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005740 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00005741 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005742 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00005743 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005744 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00005745 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00005746 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00005747 }else if( strcmp(z,"-csv")==0 ){
5748 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00005749 memcpy(data.colSeparator,",",2);
5750 }else if( strcmp(z,"-ascii")==0 ){
5751 data.mode = MODE_Ascii;
5752 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005753 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00005754 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005755 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00005756 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00005757 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00005758 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00005759 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00005760 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00005761 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005762 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00005763 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00005764 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005765 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005766 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00005767 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005768 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00005769 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00005770 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00005771 }else if( strcmp(z,"-eqp")==0 ){
5772 data.autoEQP = 1;
drheacd29d2016-04-15 15:03:27 +00005773 }else if( strcmp(z,"-eqpfull")==0 ){
5774 data.autoEQP = 2;
shaneh642d8b82010-07-28 16:05:34 +00005775 }else if( strcmp(z,"-stats")==0 ){
5776 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00005777 }else if( strcmp(z,"-scanstats")==0 ){
5778 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00005779 }else if( strcmp(z,"-backslash")==0 ){
5780 /* Undocumented command-line option: -backslash
5781 ** Causes C-style backslash escapes to be evaluated in SQL statements
5782 ** prior to sending the SQL into SQLite. Useful for injecting
5783 ** crazy bytes in the middle of SQL statements for testing and debugging.
5784 */
5785 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00005786 }else if( strcmp(z,"-bail")==0 ){
5787 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00005788 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00005789 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00005790 return 0;
drhc28490c2006-10-26 14:25:58 +00005791 }else if( strcmp(z,"-interactive")==0 ){
5792 stdin_is_interactive = 1;
5793 }else if( strcmp(z,"-batch")==0 ){
5794 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00005795 }else if( strcmp(z,"-heap")==0 ){
5796 i++;
drh44dec872014-08-30 15:49:25 +00005797 }else if( strcmp(z,"-scratch")==0 ){
5798 i+=2;
5799 }else if( strcmp(z,"-pagecache")==0 ){
5800 i+=2;
5801 }else if( strcmp(z,"-lookaside")==0 ){
5802 i+=2;
drh7d9f3942013-04-03 01:26:54 +00005803 }else if( strcmp(z,"-mmap")==0 ){
5804 i++;
drha7e61d82011-03-12 17:02:57 +00005805 }else if( strcmp(z,"-vfs")==0 ){
5806 i++;
drh6f25e892011-07-08 17:02:57 +00005807#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00005808 }else if( strcmp(z,"-vfstrace")==0 ){
5809 i++;
drh6f25e892011-07-08 17:02:57 +00005810#endif
5811#ifdef SQLITE_ENABLE_MULTIPLEX
5812 }else if( strcmp(z,"-multiplex")==0 ){
5813 i++;
5814#endif
drhcc3b4f82012-02-07 14:13:50 +00005815 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00005816 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00005817 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00005818 /* Run commands that follow -cmd first and separately from commands
5819 ** that simply appear on the command-line. This seems goofy. It would
5820 ** be better if all commands ran in the order that they appear. But
5821 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00005822 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00005823 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00005824 if( z[0]=='.' ){
5825 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00005826 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00005827 }else{
drh05782482013-10-24 15:20:20 +00005828 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00005829 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
5830 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005831 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00005832 if( bail_on_error ) return rc!=0 ? rc : 1;
5833 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005834 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00005835 if( bail_on_error ) return rc;
5836 }
5837 }
drh1e5d0e92000-05-31 23:33:17 +00005838 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005839 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
5840 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00005841 return 1;
5842 }
drh700c2522016-02-09 18:39:25 +00005843 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00005844 }
drh44c2eb12003-04-30 11:38:26 +00005845
drhac5649a2014-11-28 13:35:03 +00005846 if( !readStdin ){
5847 /* Run all arguments that do not begin with '-' as if they were separate
5848 ** command-line inputs, except for the argToSkip argument which contains
5849 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00005850 */
drhac5649a2014-11-28 13:35:03 +00005851 for(i=0; i<nCmd; i++){
5852 if( azCmd[i][0]=='.' ){
5853 rc = do_meta_command(azCmd[i], &data);
5854 if( rc ) return rc==2 ? 0 : rc;
5855 }else{
5856 open_db(&data, 0);
5857 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
5858 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005859 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00005860 return rc!=0 ? rc : 1;
5861 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005862 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00005863 return rc;
5864 }
drh6ff13852001-11-25 13:18:23 +00005865 }
drh75897232000-05-29 14:26:00 +00005866 }
drhac5649a2014-11-28 13:35:03 +00005867 free(azCmd);
drh75897232000-05-29 14:26:00 +00005868 }else{
drh44c2eb12003-04-30 11:38:26 +00005869 /* Run commands received from standard input
5870 */
drhc28490c2006-10-26 14:25:58 +00005871 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00005872 char *zHome;
5873 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00005874 int nHistory;
drh75897232000-05-29 14:26:00 +00005875 printf(
drh743e0032011-12-12 16:51:50 +00005876 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00005877 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00005878 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00005879 );
drhb3735912014-02-10 16:13:42 +00005880 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00005881 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00005882 printBold("transient in-memory database");
5883 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00005884 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00005885 }
drhd1459152016-09-16 19:11:03 +00005886 zHome = find_home_dir(0);
drhea678832008-12-10 19:26:22 +00005887 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00005888 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00005889 if( (zHistory = malloc(nHistory))!=0 ){
5890 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
5891 }
drh67505e72002-04-19 12:34:06 +00005892 }
drhf5ed7ad2015-06-15 14:43:25 +00005893 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00005894 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00005895 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00005896 shell_stifle_history(100);
5897 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00005898 free(zHistory);
drh67505e72002-04-19 12:34:06 +00005899 }
drhdaffd0e2001-04-11 14:28:42 +00005900 }else{
drhc28490c2006-10-26 14:25:58 +00005901 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00005902 }
5903 }
drh33048c02001-10-01 14:29:22 +00005904 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00005905 if( data.db ){
drhe6229612014-08-18 15:08:26 +00005906 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00005907 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00005908 }
mistachkin1fe36bb2016-04-04 02:16:44 +00005909 sqlite3_free(data.zFreeOnClose);
drhd1459152016-09-16 19:11:03 +00005910 find_home_dir(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005911#if !SQLITE_SHELL_IS_UTF8
5912 for(i=0; i<argc; i++) sqlite3_free(argv[i]);
5913 sqlite3_free(argv);
5914#endif
drhc28490c2006-10-26 14:25:58 +00005915 return rc;
drh75897232000-05-29 14:26:00 +00005916}