blob: 9b5030bb390c2aac6af54eafa7917b6e5ef8746f [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
mistachkin2318d332015-01-12 18:02:52 +000021** If requested, include the SQLite compiler options file for MSVC.
22*/
23#if defined(INCLUDE_MSVC_H)
24#include "msvc.h"
25#endif
26
27/*
drh8cd5b252015-03-02 22:06:43 +000028** No support for loadable extensions in VxWorks.
29*/
drhada3f2b2015-03-23 21:32:50 +000030#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
drh8cd5b252015-03-02 22:06:43 +000031# define SQLITE_OMIT_LOAD_EXTENSION 1
32#endif
33
34/*
drh36f7dd32011-10-13 16:02:17 +000035** Enable large-file support for fopen() and friends on unix.
36*/
37#ifndef SQLITE_DISABLE_LFS
38# define _LARGE_FILE 1
39# ifndef _FILE_OFFSET_BITS
40# define _FILE_OFFSET_BITS 64
41# endif
42# define _LARGEFILE_SOURCE 1
43#endif
44
drh75897232000-05-29 14:26:00 +000045#include <stdlib.h>
46#include <string.h>
47#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000048#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000049#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000050#if SQLITE_USER_AUTHENTICATION
51# include "sqlite3userauth.h"
52#endif
drh75897232000-05-29 14:26:00 +000053#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000054#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000055
drh83905c92012-06-21 13:00:37 +000056#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000057# include <signal.h>
chw97185482008-11-17 08:05:31 +000058# if !defined(__RTP__) && !defined(_WRS_KERNEL)
59# include <pwd.h>
60# endif
drhdd45df82002-04-18 12:39:03 +000061# include <unistd.h>
62# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000063#endif
drh75897232000-05-29 14:26:00 +000064
drh0ede9eb2015-01-10 16:49:23 +000065#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000066# include <readline/readline.h>
67# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000068#endif
danfd34d6d2015-02-25 10:54:53 +000069
drh0ede9eb2015-01-10 16:49:23 +000070#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000071# include <editline/readline.h>
72#endif
danfd34d6d2015-02-25 10:54:53 +000073
74#if HAVE_EDITLINE || HAVE_READLINE
75
76# define shell_add_history(X) add_history(X)
77# define shell_read_history(X) read_history(X)
78# define shell_write_history(X) write_history(X)
79# define shell_stifle_history(X) stifle_history(X)
80# define shell_readline(X) readline(X)
81
82#elif HAVE_LINENOISE
83
84# include "linenoise.h"
85# define shell_add_history(X) linenoiseHistoryAdd(X)
86# define shell_read_history(X) linenoiseHistoryLoad(X)
87# define shell_write_history(X) linenoiseHistorySave(X)
88# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
89# define shell_readline(X) linenoise(X)
90
91#else
92
mistachkin1fe36bb2016-04-04 02:16:44 +000093# define shell_read_history(X)
danfd34d6d2015-02-25 10:54:53 +000094# define shell_write_history(X)
95# define shell_stifle_history(X)
96
97# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000098#endif
99
danfd34d6d2015-02-25 10:54:53 +0000100
adamd2e8464a2006-09-06 21:39:40 +0000101#if defined(_WIN32) || defined(WIN32)
102# include <io.h>
drh6976c212014-07-24 12:09:47 +0000103# include <fcntl.h>
mistachkin073664d2015-06-17 18:57:37 +0000104# define isatty(h) _isatty(h)
105# ifndef access
106# define access(f,m) _access((f),(m))
107# endif
108# undef popen
109# define popen _popen
110# undef pclose
111# define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
mistachkin073664d2015-06-17 18:57:37 +0000113 /* Make sure isatty() has a prototype. */
114 extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000115
mistachkin073664d2015-06-17 18:57:37 +0000116# if !defined(__RTP__) && !defined(_WRS_KERNEL)
117 /* popen and pclose are not C89 functions and so are
118 ** sometimes omitted from the <stdio.h> header */
119 extern FILE *popen(const char*,const char*);
120 extern int pclose(FILE*);
121# else
122# define SQLITE_OMIT_POPEN 1
123# endif
mistachkinf6418892013-08-28 01:54:12 +0000124#endif
drh53371f92013-07-25 17:07:03 +0000125
chw65d3c132007-11-12 21:09:10 +0000126#if defined(_WIN32_WCE)
127/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
128 * thus we always assume that we have a console. That can be
129 * overridden with the -batch command line option.
130 */
131#define isatty(x) 1
132#endif
133
drhf0693c82011-10-11 20:41:54 +0000134/* ctype macros that work with signed characters */
135#define IsSpace(X) isspace((unsigned char)X)
136#define IsDigit(X) isdigit((unsigned char)X)
137#define ToLower(X) (char)tolower((unsigned char)X)
138
mistachkin1fe36bb2016-04-04 02:16:44 +0000139#if defined(_WIN32) || defined(WIN32)
140#include <windows.h>
141
142/* string conversion routines only needed on Win32 */
143extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
144extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
145extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
146#endif
147
drh047d4532015-01-18 20:30:23 +0000148/* On Windows, we normally run with output mode of TEXT so that \n characters
149** are automatically translated into \r\n. However, this behavior needs
150** to be disabled in some cases (ex: when generating CSV output and when
151** rendering quoted strings that contain \n characters). The following
152** routines take care of that.
153*/
154#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000155static void setBinaryMode(FILE *file, int isOutput){
156 if( isOutput ) fflush(file);
157 _setmode(_fileno(file), _O_BINARY);
drh047d4532015-01-18 20:30:23 +0000158}
mistachkin1fe36bb2016-04-04 02:16:44 +0000159static void setTextMode(FILE *file, int isOutput){
160 if( isOutput ) fflush(file);
161 _setmode(_fileno(file), _O_TEXT);
drh047d4532015-01-18 20:30:23 +0000162}
163#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000164# define setBinaryMode(X,Y)
165# define setTextMode(X,Y)
drh047d4532015-01-18 20:30:23 +0000166#endif
167
drh43408312013-10-30 12:43:36 +0000168
169/* True if the timer is enabled */
170static int enableTimer = 0;
171
172/* Return the current wall-clock time */
173static sqlite3_int64 timeOfDay(void){
174 static sqlite3_vfs *clockVfs = 0;
175 sqlite3_int64 t;
176 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
dan3fd415b2015-11-16 08:54:10 +0000177 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drh43408312013-10-30 12:43:36 +0000178 clockVfs->xCurrentTimeInt64(clockVfs, &t);
179 }else{
180 double r;
181 clockVfs->xCurrentTime(clockVfs, &r);
182 t = (sqlite3_int64)(r*86400000.0);
183 }
184 return t;
185}
186
drh91eb93c2015-03-03 19:56:20 +0000187#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000188#include <sys/time.h>
189#include <sys/resource.h>
190
drh91eb93c2015-03-03 19:56:20 +0000191/* VxWorks does not support getrusage() as far as we can determine */
192#if defined(_WRS_KERNEL) || defined(__RTP__)
193struct rusage {
194 struct timeval ru_utime; /* user CPU time used */
195 struct timeval ru_stime; /* system CPU time used */
196};
197#define getrusage(A,B) memset(B,0,sizeof(*B))
198#endif
199
drhda108222009-02-25 19:07:24 +0000200/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000201static struct rusage sBegin; /* CPU time at start */
202static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000203
drhda108222009-02-25 19:07:24 +0000204/*
205** Begin timing an operation
206*/
207static void beginTimer(void){
208 if( enableTimer ){
209 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000210 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000211 }
212}
213
214/* Return the difference of two time_structs in seconds */
215static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
mistachkin1fe36bb2016-04-04 02:16:44 +0000216 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
drhda108222009-02-25 19:07:24 +0000217 (double)(pEnd->tv_sec - pStart->tv_sec);
218}
219
220/*
221** Print the timing results.
222*/
223static void endTimer(void){
224 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000225 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000226 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000227 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000228 printf("Run Time: real %.3f user %f sys %f\n",
229 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000230 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
231 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
232 }
233}
shaneb320ccd2009-10-21 03:42:58 +0000234
drhda108222009-02-25 19:07:24 +0000235#define BEGIN_TIMER beginTimer()
236#define END_TIMER endTimer()
237#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000238
239#elif (defined(_WIN32) || defined(WIN32))
240
shaneb320ccd2009-10-21 03:42:58 +0000241/* Saved resource information for the beginning of an operation */
242static HANDLE hProcess;
243static FILETIME ftKernelBegin;
244static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000245static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000246typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
247 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000248static GETPROCTIMES getProcessTimesAddr = NULL;
249
shaneb320ccd2009-10-21 03:42:58 +0000250/*
251** Check to see if we have timer support. Return 1 if necessary
252** support found (or found previously).
253*/
254static int hasTimer(void){
255 if( getProcessTimesAddr ){
256 return 1;
257 } else {
drh4ace5362014-11-10 14:42:28 +0000258 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
259 ** versions. See if the version we are running on has it, and if it
260 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000261 */
262 hProcess = GetCurrentProcess();
263 if( hProcess ){
264 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
265 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000266 getProcessTimesAddr =
267 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000268 if( NULL != getProcessTimesAddr ){
269 return 1;
270 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000271 FreeLibrary(hinstLib);
shaneb320ccd2009-10-21 03:42:58 +0000272 }
273 }
274 }
275 return 0;
276}
277
278/*
279** Begin timing an operation
280*/
281static void beginTimer(void){
282 if( enableTimer && getProcessTimesAddr ){
283 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000284 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
285 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000286 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000287 }
288}
289
290/* Return the difference of two FILETIME structs in seconds */
291static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
292 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
293 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
294 return (double) ((i64End - i64Start) / 10000000.0);
295}
296
297/*
298** Print the timing results.
299*/
300static void endTimer(void){
301 if( enableTimer && getProcessTimesAddr){
302 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000303 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000304 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000305 printf("Run Time: real %.3f user %f sys %f\n",
306 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000307 timeDiff(&ftUserBegin, &ftUserEnd),
308 timeDiff(&ftKernelBegin, &ftKernelEnd));
309 }
310}
311
312#define BEGIN_TIMER beginTimer()
313#define END_TIMER endTimer()
314#define HAS_TIMER hasTimer()
315
drhda108222009-02-25 19:07:24 +0000316#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000317#define BEGIN_TIMER
drhda108222009-02-25 19:07:24 +0000318#define END_TIMER
319#define HAS_TIMER 0
320#endif
321
shanec0688ea2009-03-05 03:48:06 +0000322/*
323** Used to prevent warnings about unused parameters
324*/
325#define UNUSED_PARAMETER(x) (void)(x)
326
drhe91d16b2008-12-08 18:27:31 +0000327/*
drhc49f44e2006-10-26 18:15:42 +0000328** If the following flag is set, then command execution stops
329** at an error if we are not interactive.
330*/
331static int bail_on_error = 0;
332
333/*
drhc28490c2006-10-26 14:25:58 +0000334** Threat stdin as an interactive input if the following variable
335** is true. Otherwise, assume stdin is connected to a file or pipe.
336*/
337static int stdin_is_interactive = 1;
338
339/*
drhe05461c2015-12-30 13:36:57 +0000340** On Windows systems we have to know if standard output is a console
341** in order to translate UTF-8 into MBCS. The following variable is
342** true if translation is required.
343*/
344static int stdout_is_console = 1;
345
346/*
drh4c504392000-10-16 22:06:40 +0000347** The following is the open SQLite database. We make a pointer
348** to this database a static variable so that it can be accessed
349** by the SIGINT handler to interrupt database processing.
350*/
mistachkin8e189222015-04-19 21:43:16 +0000351static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000352
353/*
drh67505e72002-04-19 12:34:06 +0000354** True if an interrupt (Control-C) has been received.
355*/
drh43617e92006-03-06 20:55:46 +0000356static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000357
358/*
persicom7e2dfdd2002-04-18 02:46:52 +0000359** This is the name of our program. It is set in main(), used
360** in a number of other places, mostly for error messages.
361*/
362static char *Argv0;
363
364/*
365** Prompt strings. Initialized in main. Settable with
366** .prompt main continue
367*/
368static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
369static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
370
drhb0603412007-02-28 04:47:26 +0000371/*
mistachkin710b33b2016-01-03 18:59:28 +0000372** Render output like fprintf(). Except, if the output is going to the
373** console and if this is running on a Windows machine, translate the
374** output from UTF-8 into MBCS.
375*/
376#if defined(_WIN32) || defined(WIN32)
377void utf8_printf(FILE *out, const char *zFormat, ...){
378 va_list ap;
379 va_start(ap, zFormat);
380 if( stdout_is_console && (out==stdout || out==stderr) ){
mistachkin710b33b2016-01-03 18:59:28 +0000381 char *z1 = sqlite3_vmprintf(zFormat, ap);
mistachkin1fe36bb2016-04-04 02:16:44 +0000382 char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
mistachkin710b33b2016-01-03 18:59:28 +0000383 sqlite3_free(z1);
384 fputs(z2, out);
385 sqlite3_free(z2);
386 }else{
387 vfprintf(out, zFormat, ap);
388 }
389 va_end(ap);
390}
391#elif !defined(utf8_printf)
392# define utf8_printf fprintf
393#endif
394
395/*
396** Render output like fprintf(). This should not be used on anything that
397** includes string formatting (e.g. "%s").
398*/
399#if !defined(raw_printf)
400# define raw_printf fprintf
401#endif
402
403/*
drhb0603412007-02-28 04:47:26 +0000404** Write I/O traces to the following stream.
405*/
rsebe0a9092007-07-30 18:24:38 +0000406#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000407static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000408#endif
drhb0603412007-02-28 04:47:26 +0000409
410/*
411** This routine works like printf in that its first argument is a
412** format string and subsequent arguments are values to be substituted
413** in place of % fields. The result of formatting this string
414** is written to iotrace.
415*/
rsebe0a9092007-07-30 18:24:38 +0000416#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000417static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000418 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000419 char *z;
drhb0603412007-02-28 04:47:26 +0000420 if( iotrace==0 ) return;
421 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000422 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000423 va_end(ap);
mistachkin710b33b2016-01-03 18:59:28 +0000424 utf8_printf(iotrace, "%s", z);
drhf075cd02007-02-28 06:14:25 +0000425 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000426}
rsebe0a9092007-07-30 18:24:38 +0000427#endif
drhb0603412007-02-28 04:47:26 +0000428
drh44c2eb12003-04-30 11:38:26 +0000429
persicom7e2dfdd2002-04-18 02:46:52 +0000430/*
drh83965662003-04-17 02:54:13 +0000431** Determines if a string is a number of not.
432*/
danielk19772e588c72005-12-09 14:25:08 +0000433static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000434 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000435 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000436 return 0;
437 }
438 z++;
439 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000440 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000441 if( *z=='.' ){
442 z++;
drhf0693c82011-10-11 20:41:54 +0000443 if( !IsDigit(*z) ) return 0;
444 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000445 if( realnum ) *realnum = 1;
446 }
447 if( *z=='e' || *z=='E' ){
448 z++;
449 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000450 if( !IsDigit(*z) ) return 0;
451 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000452 if( realnum ) *realnum = 1;
453 }
454 return *z==0;
455}
drh83965662003-04-17 02:54:13 +0000456
457/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000458** A global char* and an SQL function to access its current value
459** from within an SQL statement. This program used to use the
danielk1977bc6ada42004-06-30 08:20:16 +0000460** sqlite_exec_printf() API to substitue a string into an SQL statement.
461** The correct way to do this with sqlite3 is to use the bind API, but
462** since the shell is built around the callback paradigm it would be a lot
463** of work. Instead just use this hack, which is quite harmless.
464*/
465static const char *zShellStatic = 0;
466static void shellstaticFunc(
467 sqlite3_context *context,
468 int argc,
469 sqlite3_value **argv
470){
471 assert( 0==argc );
472 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000473 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000474 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000475 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
476}
477
478
479/*
drhe05461c2015-12-30 13:36:57 +0000480** Compute a string length that is limited to what can be stored in
481** lower 30 bits of a 32-bit signed integer.
482*/
483static int strlen30(const char *z){
484 const char *z2 = z;
485 while( *z2 ){ z2++; }
486 return 0x3fffffff & (int)(z2 - z);
487}
488
489/*
drhfeac5f82004-08-01 00:10:45 +0000490** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000491** the text in memory obtained from malloc() and returns a pointer
492** to the text. NULL is returned at end of file, or if malloc()
493** fails.
494**
drh9f099fd2013-08-06 14:01:46 +0000495** If zLine is not NULL then it is a malloced buffer returned from
496** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000497*/
drh9f099fd2013-08-06 14:01:46 +0000498static char *local_getline(char *zLine, FILE *in){
499 int nLine = zLine==0 ? 0 : 100;
500 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000501
drhb07028f2011-10-14 21:49:18 +0000502 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000503 if( n+100>nLine ){
504 nLine = nLine*2 + 100;
505 zLine = realloc(zLine, nLine);
506 if( zLine==0 ) return 0;
507 }
drhdaffd0e2001-04-11 14:28:42 +0000508 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000509 if( n==0 ){
510 free(zLine);
511 return 0;
512 }
513 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000514 break;
515 }
drh9f099fd2013-08-06 14:01:46 +0000516 while( zLine[n] ) n++;
517 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000518 n--;
shaneh13b36022009-12-17 21:07:15 +0000519 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000520 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000521 break;
drh8e7e7a22000-05-30 18:45:23 +0000522 }
523 }
drhe05461c2015-12-30 13:36:57 +0000524#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000525 /* For interactive input on Windows systems, translate the
drhe05461c2015-12-30 13:36:57 +0000526 ** multi-byte characterset characters into UTF-8. */
drhfc8b40f2016-09-07 10:10:18 +0000527 if( stdin_is_interactive && in==stdin ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000528 char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
drhe05461c2015-12-30 13:36:57 +0000529 if( zTrans ){
530 int nTrans = strlen30(zTrans)+1;
531 if( nTrans>nLine ){
532 zLine = realloc(zLine, nTrans);
533 if( zLine==0 ){
534 sqlite3_free(zTrans);
535 return 0;
536 }
537 }
538 memcpy(zLine, zTrans, nTrans);
539 sqlite3_free(zTrans);
540 }
541 }
542#endif /* defined(_WIN32) || defined(WIN32) */
drh8e7e7a22000-05-30 18:45:23 +0000543 return zLine;
544}
545
546/*
drhc28490c2006-10-26 14:25:58 +0000547** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000548**
drh9f099fd2013-08-06 14:01:46 +0000549** If in==0 then read from standard input and prompt before each line.
550** If isContinuation is true, then a continuation prompt is appropriate.
551** If isContinuation is zero, then the main prompt should be used.
552**
553** If zPrior is not NULL then it is a buffer from a prior call to this
554** routine that can be reused.
555**
556** The result is stored in space obtained from malloc() and must either
557** be freed by the caller or else passed back into this routine via the
558** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000559*/
drh9f099fd2013-08-06 14:01:46 +0000560static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000561 char *zPrompt;
562 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000563 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000564 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000565 }else{
drh9f099fd2013-08-06 14:01:46 +0000566 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000567#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000568 printf("%s", zPrompt);
569 fflush(stdout);
570 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000571#else
572 free(zPrior);
573 zResult = shell_readline(zPrompt);
574 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000575#endif
drh9f099fd2013-08-06 14:01:46 +0000576 }
drh8e7e7a22000-05-30 18:45:23 +0000577 return zResult;
578}
579
drhe6229612014-08-18 15:08:26 +0000580#if defined(SQLITE_ENABLE_SESSION)
581/*
582** State information for a single open session
583*/
584typedef struct OpenSession OpenSession;
585struct OpenSession {
586 char *zName; /* Symbolic name for this session */
587 int nFilter; /* Number of xFilter rejection GLOB patterns */
588 char **azFilter; /* Array of xFilter rejection GLOB patterns */
589 sqlite3_session *p; /* The open session */
590};
591#endif
592
drhdcd87a92014-08-18 13:45:42 +0000593/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000594** Shell output mode information from before ".explain on",
drhdcd87a92014-08-18 13:45:42 +0000595** saved so that it can be restored by ".explain off"
596*/
597typedef struct SavedModeInfo SavedModeInfo;
598struct SavedModeInfo {
599 int valid; /* Is there legit data in here? */
600 int mode; /* Mode prior to ".explain on" */
601 int showHeader; /* The ".header" setting prior to ".explain on" */
602 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000603};
drh45e29d82006-11-20 16:21:10 +0000604
drh8e7e7a22000-05-30 18:45:23 +0000605/*
drhdcd87a92014-08-18 13:45:42 +0000606** State information about the database connection is contained in an
607** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000608*/
drhdcd87a92014-08-18 13:45:42 +0000609typedef struct ShellState ShellState;
610struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000611 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000612 int echoOn; /* True to echo input commands */
drh700c2522016-02-09 18:39:25 +0000613 int autoExplain; /* Automatically turn on .explain mode */
drhc2ce0be2014-05-29 12:36:14 +0000614 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000615 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000616 int scanstatsOn; /* True to display scan stats before each finalize */
drhdf12f1c2015-12-07 21:46:19 +0000617 int countChanges; /* True to display change counts */
drh9569f602015-04-16 15:05:04 +0000618 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000619 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000620 int cnt; /* Number of records displayed so far */
621 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000622 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000623 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000624 int mode; /* An output mode setting */
drh700c2522016-02-09 18:39:25 +0000625 int cMode; /* temporary output mode for the current query */
626 int normalMode; /* Output mode before ".explain on" */
drh45e29d82006-11-20 16:21:10 +0000627 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000628 int showHeader; /* True to show column names in List or Column mode */
drh760c8162016-09-16 02:52:22 +0000629 int nCheck; /* Number of ".check" commands run */
drh44dec872014-08-30 15:49:25 +0000630 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000631 char *zDestTable; /* Name of destination table when MODE_Insert */
drh760c8162016-09-16 02:52:22 +0000632 char zTestcase[30]; /* Name of current test case */
mistachkin636bf9f2014-07-19 20:15:16 +0000633 char colSeparator[20]; /* Column separator character for several modes */
634 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000635 int colWidth[100]; /* Requested width of each column when in column mode*/
636 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000637 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000638 ** the database */
drh44c2eb12003-04-30 11:38:26 +0000639 char outfile[FILENAME_MAX]; /* Filename for *out */
640 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000641 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000642 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000643 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000644 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000645 int *aiIndent; /* Array of indents used in MODE_Explain */
646 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000647 int iIndent; /* Index of current op in aiIndent[] */
drhe6229612014-08-18 15:08:26 +0000648#if defined(SQLITE_ENABLE_SESSION)
649 int nSession; /* Number of active sessions */
650 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
651#endif
drh75897232000-05-29 14:26:00 +0000652};
653
654/*
drh44dec872014-08-30 15:49:25 +0000655** These are the allowed shellFlgs values
656*/
657#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
658#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
659#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
660
661/*
drh75897232000-05-29 14:26:00 +0000662** These are the allowed modes.
663*/
drh967e8b72000-06-21 13:59:10 +0000664#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000665#define MODE_Column 1 /* One record per line in neat columns */
666#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000667#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
668#define MODE_Html 4 /* Generate an XHTML table */
669#define MODE_Insert 5 /* Generate SQL "insert" statements */
drhfeac5f82004-08-01 00:10:45 +0000670#define MODE_Tcl 6 /* Generate ANSI-C or TCL quoted elements */
drh8e64d1c2004-10-07 00:32:39 +0000671#define MODE_Csv 7 /* Quote strings, numbers are plain */
drh66ce4d02008-02-15 17:38:06 +0000672#define MODE_Explain 8 /* Like MODE_Column, but do not truncate data */
mistachkin636bf9f2014-07-19 20:15:16 +0000673#define MODE_Ascii 9 /* Use ASCII unit and record separators (0x1F/0x1E) */
drh4926fec2016-04-13 15:33:42 +0000674#define MODE_Pretty 10 /* Pretty-print schemas */
persicom7e2dfdd2002-04-18 02:46:52 +0000675
drh66ce4d02008-02-15 17:38:06 +0000676static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000677 "line",
678 "column",
679 "list",
680 "semi",
681 "html",
drhfeac5f82004-08-01 00:10:45 +0000682 "insert",
683 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000684 "csv",
drh66ce4d02008-02-15 17:38:06 +0000685 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000686 "ascii",
drh4926fec2016-04-13 15:33:42 +0000687 "prettyprint",
persicom7e2dfdd2002-04-18 02:46:52 +0000688};
drh75897232000-05-29 14:26:00 +0000689
690/*
mistachkinfad42082014-07-24 22:13:12 +0000691** These are the column/row/line separators used by the various
692** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000693*/
mistachkinfad42082014-07-24 22:13:12 +0000694#define SEP_Column "|"
695#define SEP_Row "\n"
696#define SEP_Tab "\t"
697#define SEP_Space " "
698#define SEP_Comma ","
699#define SEP_CrLf "\r\n"
700#define SEP_Unit "\x1F"
701#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000702
703/*
drh75897232000-05-29 14:26:00 +0000704** Number of elements in an array
705*/
drh902b9ee2008-12-05 17:17:07 +0000706#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000707
708/*
drh127f9d72010-02-23 01:47:00 +0000709** A callback for the sqlite3_log() interface.
710*/
711static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000712 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000713 if( p->pLog==0 ) return;
mistachkinaae280e2015-12-31 19:06:24 +0000714 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
drh127f9d72010-02-23 01:47:00 +0000715 fflush(p->pLog);
716}
717
718/*
shane626a6e42009-10-22 17:30:15 +0000719** Output the given string as a hex-encoded blob (eg. X'1234' )
720*/
721static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
722 int i;
723 char *zBlob = (char *)pBlob;
mistachkinaae280e2015-12-31 19:06:24 +0000724 raw_printf(out,"X'");
725 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
726 raw_printf(out,"'");
shane626a6e42009-10-22 17:30:15 +0000727}
728
729/*
drh28bd4bc2000-06-15 15:57:22 +0000730** Output the given string as a quoted string using SQL quoting conventions.
731*/
732static void output_quoted_string(FILE *out, const char *z){
733 int i;
734 int nSingle = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +0000735 setBinaryMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000736 for(i=0; z[i]; i++){
737 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000738 }
739 if( nSingle==0 ){
drhe05461c2015-12-30 13:36:57 +0000740 utf8_printf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000741 }else{
mistachkinaae280e2015-12-31 19:06:24 +0000742 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000743 while( *z ){
744 for(i=0; z[i] && z[i]!='\''; i++){}
745 if( i==0 ){
mistachkinaae280e2015-12-31 19:06:24 +0000746 raw_printf(out,"''");
drh28bd4bc2000-06-15 15:57:22 +0000747 z++;
748 }else if( z[i]=='\'' ){
drhe05461c2015-12-30 13:36:57 +0000749 utf8_printf(out,"%.*s''",i,z);
drh28bd4bc2000-06-15 15:57:22 +0000750 z += i+1;
751 }else{
drhe05461c2015-12-30 13:36:57 +0000752 utf8_printf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000753 break;
754 }
755 }
mistachkinaae280e2015-12-31 19:06:24 +0000756 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000757 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000758 setTextMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000759}
760
761/*
drhfeac5f82004-08-01 00:10:45 +0000762** Output the given string as a quoted according to C or TCL quoting rules.
763*/
764static void output_c_string(FILE *out, const char *z){
765 unsigned int c;
766 fputc('"', out);
767 while( (c = *(z++))!=0 ){
768 if( c=='\\' ){
769 fputc(c, out);
770 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000771 }else if( c=='"' ){
772 fputc('\\', out);
773 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000774 }else if( c=='\t' ){
775 fputc('\\', out);
776 fputc('t', out);
777 }else if( c=='\n' ){
778 fputc('\\', out);
779 fputc('n', out);
780 }else if( c=='\r' ){
781 fputc('\\', out);
782 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000783 }else if( !isprint(c&0xff) ){
mistachkinaae280e2015-12-31 19:06:24 +0000784 raw_printf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000785 }else{
786 fputc(c, out);
787 }
788 }
789 fputc('"', out);
790}
791
792/*
drhc08a4f12000-06-15 16:49:48 +0000793** Output the given string with characters that are special to
794** HTML escaped.
795*/
796static void output_html_string(FILE *out, const char *z){
797 int i;
drhc3d6ba42014-01-13 20:38:35 +0000798 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000799 while( *z ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000800 for(i=0; z[i]
801 && z[i]!='<'
802 && z[i]!='&'
803 && z[i]!='>'
804 && z[i]!='\"'
shane43d9cb22009-10-21 14:11:48 +0000805 && z[i]!='\'';
806 i++){}
drhc08a4f12000-06-15 16:49:48 +0000807 if( i>0 ){
drhe05461c2015-12-30 13:36:57 +0000808 utf8_printf(out,"%.*s",i,z);
drhc08a4f12000-06-15 16:49:48 +0000809 }
810 if( z[i]=='<' ){
mistachkinaae280e2015-12-31 19:06:24 +0000811 raw_printf(out,"&lt;");
drhc08a4f12000-06-15 16:49:48 +0000812 }else if( z[i]=='&' ){
mistachkinaae280e2015-12-31 19:06:24 +0000813 raw_printf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000814 }else if( z[i]=='>' ){
mistachkinaae280e2015-12-31 19:06:24 +0000815 raw_printf(out,"&gt;");
shane43d9cb22009-10-21 14:11:48 +0000816 }else if( z[i]=='\"' ){
mistachkinaae280e2015-12-31 19:06:24 +0000817 raw_printf(out,"&quot;");
shane43d9cb22009-10-21 14:11:48 +0000818 }else if( z[i]=='\'' ){
mistachkinaae280e2015-12-31 19:06:24 +0000819 raw_printf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000820 }else{
821 break;
822 }
823 z += i + 1;
824 }
825}
826
827/*
drhc49f44e2006-10-26 18:15:42 +0000828** If a field contains any character identified by a 1 in the following
829** array, then the string must be quoted for CSV.
830*/
831static const char needCsvQuote[] = {
mistachkin1fe36bb2016-04-04 02:16:44 +0000832 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
833 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
834 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
836 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
838 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
839 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
840 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
841 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
842 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
843 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
844 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
845 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
846 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
847 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
drhc49f44e2006-10-26 18:15:42 +0000848};
849
850/*
mistachkindd11f2d2014-12-11 04:49:46 +0000851** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000852** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000853** the null value. Strings are quoted if necessary. The separator
854** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000855*/
drhdcd87a92014-08-18 13:45:42 +0000856static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000857 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000858 if( z==0 ){
drhe05461c2015-12-30 13:36:57 +0000859 utf8_printf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000860 }else{
drhc49f44e2006-10-26 18:15:42 +0000861 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000862 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000863 for(i=0; z[i]; i++){
mistachkin1fe36bb2016-04-04 02:16:44 +0000864 if( needCsvQuote[((unsigned char*)z)[i]]
865 || (z[i]==p->colSeparator[0] &&
mistachkin636bf9f2014-07-19 20:15:16 +0000866 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000867 i = 0;
868 break;
869 }
870 }
871 if( i==0 ){
872 putc('"', out);
873 for(i=0; z[i]; i++){
874 if( z[i]=='"' ) putc('"', out);
875 putc(z[i], out);
876 }
877 putc('"', out);
878 }else{
drhe05461c2015-12-30 13:36:57 +0000879 utf8_printf(out, "%s", z);
drhc49f44e2006-10-26 18:15:42 +0000880 }
drh8e64d1c2004-10-07 00:32:39 +0000881 }
882 if( bSep ){
drhe05461c2015-12-30 13:36:57 +0000883 utf8_printf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000884 }
885}
886
danielk19774af00c62005-01-23 23:43:21 +0000887#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000888/*
drh4c504392000-10-16 22:06:40 +0000889** This routine runs when the user presses Ctrl-C
890*/
891static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000892 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000893 seenInterrupt++;
894 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000895 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000896}
danielk19774af00c62005-01-23 23:43:21 +0000897#endif
drh4c504392000-10-16 22:06:40 +0000898
drha0daa752016-09-16 11:53:10 +0000899#ifndef SQLITE_OMIT_AUTHORIZATION
drh4c504392000-10-16 22:06:40 +0000900/*
drhde613c62016-04-04 17:23:10 +0000901** When the ".auth ON" is set, the following authorizer callback is
902** invoked. It always returns SQLITE_OK.
903*/
904static int shellAuth(
905 void *pClientData,
906 int op,
907 const char *zA1,
908 const char *zA2,
909 const char *zA3,
910 const char *zA4
911){
912 ShellState *p = (ShellState*)pClientData;
913 static const char *azAction[] = { 0,
914 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
915 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
916 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
917 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
918 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
919 "DROP_TRIGGER", "DROP_VIEW", "INSERT",
920 "PRAGMA", "READ", "SELECT",
921 "TRANSACTION", "UPDATE", "ATTACH",
922 "DETACH", "ALTER_TABLE", "REINDEX",
923 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
924 "FUNCTION", "SAVEPOINT", "RECURSIVE"
925 };
926 int i;
927 const char *az[4];
928 az[0] = zA1;
929 az[1] = zA2;
930 az[2] = zA3;
931 az[3] = zA4;
932 raw_printf(p->out, "authorizer: %s", azAction[op]);
933 for(i=0; i<4; i++){
934 raw_printf(p->out, " ");
935 if( az[i] ){
936 output_c_string(p->out, az[i]);
937 }else{
938 raw_printf(p->out, "NULL");
939 }
940 }
941 raw_printf(p->out, "\n");
942 return SQLITE_OK;
943}
drha0daa752016-09-16 11:53:10 +0000944#endif
drhde613c62016-04-04 17:23:10 +0000945
946
947/*
shane626a6e42009-10-22 17:30:15 +0000948** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000949** invokes for each row of a query result.
950*/
drh4ace5362014-11-10 14:42:28 +0000951static int shell_callback(
952 void *pArg,
953 int nArg, /* Number of result columns */
954 char **azArg, /* Text of each result column */
955 char **azCol, /* Column names */
956 int *aiType /* Column types */
957){
drh75897232000-05-29 14:26:00 +0000958 int i;
drhdcd87a92014-08-18 13:45:42 +0000959 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000960
drh700c2522016-02-09 18:39:25 +0000961 switch( p->cMode ){
drh75897232000-05-29 14:26:00 +0000962 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000963 int w = 5;
drh6a535342001-10-19 16:44:56 +0000964 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000965 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000966 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000967 if( len>w ) w = len;
968 }
drhe05461c2015-12-30 13:36:57 +0000969 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000970 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000971 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000972 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000973 }
974 break;
975 }
danielk19770d78bae2008-01-03 07:09:48 +0000976 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000977 case MODE_Column: {
drh700c2522016-02-09 18:39:25 +0000978 static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
979 const int *colWidth;
980 int showHdr;
981 char *rowSep;
982 if( p->cMode==MODE_Column ){
983 colWidth = p->colWidth;
984 showHdr = p->showHeader;
985 rowSep = p->rowSeparator;
986 }else{
987 colWidth = aExplainWidths;
988 showHdr = 1;
mistachkin6d945552016-02-09 20:31:50 +0000989 rowSep = SEP_Row;
drh700c2522016-02-09 18:39:25 +0000990 }
drha0c66f52000-07-29 13:20:21 +0000991 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000992 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000993 int w, n;
994 if( i<ArraySize(p->colWidth) ){
drh700c2522016-02-09 18:39:25 +0000995 w = colWidth[i];
drh75897232000-05-29 14:26:00 +0000996 }else{
danielk19770d78bae2008-01-03 07:09:48 +0000997 w = 0;
drh75897232000-05-29 14:26:00 +0000998 }
drh078b1fd2012-09-21 13:40:02 +0000999 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +00001000 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +00001001 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +00001002 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +00001003 if( w<n ) w = n;
1004 }
1005 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001006 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001007 }
drh700c2522016-02-09 18:39:25 +00001008 if( showHdr ){
drh078b1fd2012-09-21 13:40:02 +00001009 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001010 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001011 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001012 }else{
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 }
drha0c66f52000-07-29 13:20:21 +00001016 }
1017 }
drh700c2522016-02-09 18:39:25 +00001018 if( showHdr ){
drha0c66f52000-07-29 13:20:21 +00001019 for(i=0; i<nArg; i++){
1020 int w;
1021 if( i<ArraySize(p->actualWidth) ){
1022 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +00001023 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +00001024 }else{
1025 w = 10;
1026 }
mistachkinaae280e2015-12-31 19:06:24 +00001027 utf8_printf(p->out,"%-*.*s%s",w,w,
drhe05461c2015-12-30 13:36:57 +00001028 "----------------------------------------------------------"
drha0c66f52000-07-29 13:20:21 +00001029 "----------------------------------------------------------",
drh700c2522016-02-09 18:39:25 +00001030 i==nArg-1 ? rowSep : " ");
drha0c66f52000-07-29 13:20:21 +00001031 }
drh75897232000-05-29 14:26:00 +00001032 }
1033 }
drh6a535342001-10-19 16:44:56 +00001034 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001035 for(i=0; i<nArg; i++){
1036 int w;
drha0c66f52000-07-29 13:20:21 +00001037 if( i<ArraySize(p->actualWidth) ){
1038 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001039 }else{
1040 w = 10;
1041 }
drh700c2522016-02-09 18:39:25 +00001042 if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +00001043 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001044 }
dana98bf362013-11-13 18:35:01 +00001045 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +00001046 if( p->iIndent<p->nIndent ){
mistachkinaae280e2015-12-31 19:06:24 +00001047 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +00001048 }
danc4650bb2013-11-18 08:41:06 +00001049 p->iIndent++;
dana98bf362013-11-13 18:35:01 +00001050 }
drh078b1fd2012-09-21 13:40:02 +00001051 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001052 utf8_printf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +00001053 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001054 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001055 }else{
drhe05461c2015-12-30 13:36:57 +00001056 utf8_printf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +00001057 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001058 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001059 }
drh75897232000-05-29 14:26:00 +00001060 }
1061 break;
1062 }
drh4926fec2016-04-13 15:33:42 +00001063 case MODE_Semi: { /* .schema and .fullschema output */
1064 utf8_printf(p->out, "%s;\n", azArg[0]);
1065 break;
1066 }
1067 case MODE_Pretty: { /* .schema and .fullschema with --indent */
1068 char *z;
drh07d683f2016-04-13 21:00:36 +00001069 int j;
drh4926fec2016-04-13 15:33:42 +00001070 int nParen = 0;
1071 char cEnd = 0;
1072 char c;
1073 int nLine = 0;
1074 assert( nArg==1 );
1075 if( azArg[0]==0 ) break;
1076 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
1077 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
1078 ){
1079 utf8_printf(p->out, "%s;\n", azArg[0]);
1080 break;
1081 }
1082 z = sqlite3_mprintf("%s", azArg[0]);
1083 j = 0;
1084 for(i=0; IsSpace(z[i]); i++){}
1085 for(; (c = z[i])!=0; i++){
1086 if( IsSpace(c) ){
1087 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
1088 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
1089 j--;
1090 }
1091 z[j++] = c;
1092 }
1093 while( j>0 && IsSpace(z[j-1]) ){ j--; }
1094 z[j] = 0;
1095 if( strlen30(z)>=79 ){
drh07d683f2016-04-13 21:00:36 +00001096 for(i=j=0; (c = z[i])!=0; i++){
drh4926fec2016-04-13 15:33:42 +00001097 if( c==cEnd ){
1098 cEnd = 0;
1099 }else if( c=='"' || c=='\'' || c=='`' ){
1100 cEnd = c;
1101 }else if( c=='[' ){
1102 cEnd = ']';
1103 }else if( c=='(' ){
1104 nParen++;
1105 }else if( c==')' ){
1106 nParen--;
1107 if( nLine>0 && nParen==0 && j>0 ){
1108 utf8_printf(p->out, "%.*s\n", j, z);
1109 j = 0;
1110 }
1111 }
1112 z[j++] = c;
1113 if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
1114 if( c=='\n' ) j--;
1115 utf8_printf(p->out, "%.*s\n ", j, z);
1116 j = 0;
1117 nLine++;
1118 while( IsSpace(z[i+1]) ){ i++; }
1119 }
1120 }
1121 z[j] = 0;
1122 }
1123 utf8_printf(p->out, "%s;\n", z);
1124 sqlite3_free(z);
1125 break;
1126 }
drh75897232000-05-29 14:26:00 +00001127 case MODE_List: {
1128 if( p->cnt++==0 && p->showHeader ){
1129 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001130 utf8_printf(p->out,"%s%s",azCol[i],
mistachkin636bf9f2014-07-19 20:15:16 +00001131 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +00001132 }
1133 }
drh6a535342001-10-19 16:44:56 +00001134 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001135 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001136 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +00001137 if( z==0 ) z = p->nullValue;
drhe05461c2015-12-30 13:36:57 +00001138 utf8_printf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001139 if( i<nArg-1 ){
drhe05461c2015-12-30 13:36:57 +00001140 utf8_printf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +00001141 }else{
drhe05461c2015-12-30 13:36:57 +00001142 utf8_printf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001143 }
drh75897232000-05-29 14:26:00 +00001144 }
1145 break;
1146 }
drh1e5d0e92000-05-31 23:33:17 +00001147 case MODE_Html: {
1148 if( p->cnt++==0 && p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001149 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001150 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001151 raw_printf(p->out,"<TH>");
shane43d9cb22009-10-21 14:11:48 +00001152 output_html_string(p->out, azCol[i]);
mistachkinaae280e2015-12-31 19:06:24 +00001153 raw_printf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001154 }
mistachkinaae280e2015-12-31 19:06:24 +00001155 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001156 }
drh6a535342001-10-19 16:44:56 +00001157 if( azArg==0 ) break;
mistachkinaae280e2015-12-31 19:06:24 +00001158 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001159 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001160 raw_printf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +00001161 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00001162 raw_printf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001163 }
mistachkinaae280e2015-12-31 19:06:24 +00001164 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001165 break;
1166 }
drhfeac5f82004-08-01 00:10:45 +00001167 case MODE_Tcl: {
1168 if( p->cnt++==0 && p->showHeader ){
1169 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001170 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhe05461c2015-12-30 13:36:57 +00001171 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001172 }
drhe05461c2015-12-30 13:36:57 +00001173 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001174 }
1175 if( azArg==0 ) break;
1176 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +00001177 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
drhe05461c2015-12-30 13:36:57 +00001178 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001179 }
drhe05461c2015-12-30 13:36:57 +00001180 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001181 break;
1182 }
drh8e64d1c2004-10-07 00:32:39 +00001183 case MODE_Csv: {
mistachkin1fe36bb2016-04-04 02:16:44 +00001184 setBinaryMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001185 if( p->cnt++==0 && p->showHeader ){
1186 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001187 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001188 }
drhe05461c2015-12-30 13:36:57 +00001189 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001190 }
drh40253262014-10-17 21:35:05 +00001191 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +00001192 for(i=0; i<nArg; i++){
1193 output_csv(p, azArg[i], i<nArg-1);
1194 }
drhe05461c2015-12-30 13:36:57 +00001195 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001196 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001197 setTextMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001198 break;
1199 }
drh28bd4bc2000-06-15 15:57:22 +00001200 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001201 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001202 if( azArg==0 ) break;
drhe05461c2015-12-30 13:36:57 +00001203 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
mistachkin151c75a2015-04-07 21:16:40 +00001204 if( p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001205 raw_printf(p->out,"(");
mistachkin151c75a2015-04-07 21:16:40 +00001206 for(i=0; i<nArg; i++){
1207 char *zSep = i>0 ? ",": "";
drhe05461c2015-12-30 13:36:57 +00001208 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
mistachkin151c75a2015-04-07 21:16:40 +00001209 }
mistachkinaae280e2015-12-31 19:06:24 +00001210 raw_printf(p->out,")");
mistachkin151c75a2015-04-07 21:16:40 +00001211 }
mistachkinaae280e2015-12-31 19:06:24 +00001212 raw_printf(p->out," VALUES(");
drh28bd4bc2000-06-15 15:57:22 +00001213 for(i=0; i<nArg; i++){
1214 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001215 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
mistachkinaae280e2015-12-31 19:06:24 +00001216 utf8_printf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001217 }else if( aiType && aiType[i]==SQLITE_TEXT ){
mistachkinaae280e2015-12-31 19:06:24 +00001218 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shanead6b8d02009-10-22 18:12:58 +00001219 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001220 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1221 || aiType[i]==SQLITE_FLOAT) ){
drhe05461c2015-12-30 13:36:57 +00001222 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001223 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1224 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1225 int nBlob = sqlite3_column_bytes(p->pStmt, i);
mistachkinaae280e2015-12-31 19:06:24 +00001226 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shane626a6e42009-10-22 17:30:15 +00001227 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001228 }else if( isNumber(azArg[i], 0) ){
drhe05461c2015-12-30 13:36:57 +00001229 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
drh28bd4bc2000-06-15 15:57:22 +00001230 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001231 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
drh28bd4bc2000-06-15 15:57:22 +00001232 output_quoted_string(p->out, azArg[i]);
1233 }
1234 }
mistachkinaae280e2015-12-31 19:06:24 +00001235 raw_printf(p->out,");\n");
drh6a535342001-10-19 16:44:56 +00001236 break;
drh28bd4bc2000-06-15 15:57:22 +00001237 }
mistachkin636bf9f2014-07-19 20:15:16 +00001238 case MODE_Ascii: {
1239 if( p->cnt++==0 && p->showHeader ){
1240 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001241 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1242 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +00001243 }
drhe05461c2015-12-30 13:36:57 +00001244 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001245 }
1246 if( azArg==0 ) break;
1247 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001248 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1249 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001250 }
drhe05461c2015-12-30 13:36:57 +00001251 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001252 break;
1253 }
persicom1d0b8722002-04-18 02:53:04 +00001254 }
drh75897232000-05-29 14:26:00 +00001255 return 0;
1256}
1257
1258/*
shane626a6e42009-10-22 17:30:15 +00001259** This is the callback routine that the SQLite library
1260** invokes for each row of a query result.
1261*/
1262static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1263 /* since we don't have type info, call the shell_callback with a NULL value */
1264 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1265}
1266
1267/*
drhdcd87a92014-08-18 13:45:42 +00001268** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001269** the name of the table given. Escape any quote characters in the
1270** table name.
1271*/
drhdcd87a92014-08-18 13:45:42 +00001272static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001273 int i, n;
1274 int needQuote;
1275 char *z;
1276
1277 if( p->zDestTable ){
1278 free(p->zDestTable);
1279 p->zDestTable = 0;
1280 }
1281 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001282 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001283 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001284 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001285 needQuote = 1;
1286 if( zName[i]=='\'' ) n++;
1287 }
1288 }
1289 if( needQuote ) n += 2;
1290 z = p->zDestTable = malloc( n+1 );
1291 if( z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001292 raw_printf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001293 exit(1);
1294 }
1295 n = 0;
1296 if( needQuote ) z[n++] = '\'';
1297 for(i=0; zName[i]; i++){
1298 z[n++] = zName[i];
1299 if( zName[i]=='\'' ) z[n++] = '\'';
1300 }
1301 if( needQuote ) z[n++] = '\'';
1302 z[n] = 0;
1303}
1304
danielk19772a02e332004-06-05 08:04:36 +00001305/* zIn is either a pointer to a NULL-terminated string in memory obtained
1306** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1307** added to zIn, and the result returned in memory obtained from malloc().
1308** zIn, if it was not NULL, is freed.
1309**
mistachkin1fe36bb2016-04-04 02:16:44 +00001310** If the third argument, quote, is not '\0', then it is used as a
danielk19772a02e332004-06-05 08:04:36 +00001311** quote character for zAppend.
1312*/
drhc28490c2006-10-26 14:25:58 +00001313static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001314 int len;
1315 int i;
drh4f21c4a2008-12-10 22:15:00 +00001316 int nAppend = strlen30(zAppend);
1317 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001318
1319 len = nAppend+nIn+1;
1320 if( quote ){
1321 len += 2;
1322 for(i=0; i<nAppend; i++){
1323 if( zAppend[i]==quote ) len++;
1324 }
1325 }
1326
1327 zIn = (char *)realloc(zIn, len);
1328 if( !zIn ){
1329 return 0;
1330 }
1331
1332 if( quote ){
1333 char *zCsr = &zIn[nIn];
1334 *zCsr++ = quote;
1335 for(i=0; i<nAppend; i++){
1336 *zCsr++ = zAppend[i];
1337 if( zAppend[i]==quote ) *zCsr++ = quote;
1338 }
1339 *zCsr++ = quote;
1340 *zCsr++ = '\0';
1341 assert( (zCsr-zIn)==len );
1342 }else{
1343 memcpy(&zIn[nIn], zAppend, nAppend);
1344 zIn[len-1] = '\0';
1345 }
1346
1347 return zIn;
1348}
1349
drhdd3d4592004-08-30 01:54:05 +00001350
1351/*
drhb21a8e42012-01-28 21:08:51 +00001352** Execute a query statement that will generate SQL output. Print
1353** the result columns, comma-separated, on a line and then add a
1354** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001355**
drhb21a8e42012-01-28 21:08:51 +00001356** If the number of columns is 1 and that column contains text "--"
mistachkin1fe36bb2016-04-04 02:16:44 +00001357** then write the semicolon on a separate line. That way, if a
drhb21a8e42012-01-28 21:08:51 +00001358** "--" comment occurs at the end of the statement, the comment
1359** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001360*/
drh157e29a2009-05-21 15:15:00 +00001361static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001362 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001363 const char *zSelect, /* SELECT statement to extract content */
1364 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001365){
drhdd3d4592004-08-30 01:54:05 +00001366 sqlite3_stmt *pSelect;
1367 int rc;
drhb21a8e42012-01-28 21:08:51 +00001368 int nResult;
1369 int i;
1370 const char *z;
drhc7181902014-02-27 15:04:13 +00001371 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001372 if( rc!=SQLITE_OK || !pSelect ){
mistachkinaae280e2015-12-31 19:06:24 +00001373 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1374 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001375 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001376 return rc;
1377 }
1378 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001379 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001380 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001381 if( zFirstRow ){
drhe05461c2015-12-30 13:36:57 +00001382 utf8_printf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001383 zFirstRow = 0;
1384 }
drhb21a8e42012-01-28 21:08:51 +00001385 z = (const char*)sqlite3_column_text(pSelect, 0);
drhe05461c2015-12-30 13:36:57 +00001386 utf8_printf(p->out, "%s", z);
mistachkin1fe36bb2016-04-04 02:16:44 +00001387 for(i=1; i<nResult; i++){
drhe05461c2015-12-30 13:36:57 +00001388 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
drhb21a8e42012-01-28 21:08:51 +00001389 }
1390 if( z==0 ) z = "";
1391 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1392 if( z[0] ){
mistachkinaae280e2015-12-31 19:06:24 +00001393 raw_printf(p->out, "\n;\n");
drhb21a8e42012-01-28 21:08:51 +00001394 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001395 raw_printf(p->out, ";\n");
mistachkin1fe36bb2016-04-04 02:16:44 +00001396 }
drhdd3d4592004-08-30 01:54:05 +00001397 rc = sqlite3_step(pSelect);
1398 }
drh2f464a02011-10-13 00:41:49 +00001399 rc = sqlite3_finalize(pSelect);
1400 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00001401 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1402 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001403 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001404 }
1405 return rc;
drhdd3d4592004-08-30 01:54:05 +00001406}
1407
shane626a6e42009-10-22 17:30:15 +00001408/*
1409** Allocate space and save off current error string.
1410*/
1411static char *save_err_msg(
1412 sqlite3 *db /* Database to query */
1413){
1414 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001415 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001416 if( zErrMsg ){
1417 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1418 }
1419 return zErrMsg;
1420}
1421
drh34784902016-02-27 17:12:36 +00001422#ifdef __linux__
1423/*
1424** Attempt to display I/O stats on Linux using /proc/PID/io
1425*/
1426static void displayLinuxIoStats(FILE *out){
1427 FILE *in;
1428 char z[200];
1429 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
1430 in = fopen(z, "rb");
1431 if( in==0 ) return;
1432 while( fgets(z, sizeof(z), in)!=0 ){
1433 static const struct {
1434 const char *zPattern;
1435 const char *zDesc;
1436 } aTrans[] = {
drhfc1a84c2016-02-27 19:19:22 +00001437 { "rchar: ", "Bytes received by read():" },
1438 { "wchar: ", "Bytes sent to write():" },
1439 { "syscr: ", "Read() system calls:" },
1440 { "syscw: ", "Write() system calls:" },
1441 { "read_bytes: ", "Bytes read from storage:" },
1442 { "write_bytes: ", "Bytes written to storage:" },
1443 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
drh34784902016-02-27 17:12:36 +00001444 };
1445 int i;
1446 for(i=0; i<ArraySize(aTrans); i++){
1447 int n = (int)strlen(aTrans[i].zPattern);
1448 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
1449 raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
1450 break;
1451 }
1452 }
1453 }
1454 fclose(in);
mistachkin1fe36bb2016-04-04 02:16:44 +00001455}
drh34784902016-02-27 17:12:36 +00001456#endif
1457
1458
shane626a6e42009-10-22 17:30:15 +00001459/*
shaneh642d8b82010-07-28 16:05:34 +00001460** Display memory stats.
1461*/
1462static int display_stats(
1463 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001464 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001465 int bReset /* True to reset the stats */
1466){
1467 int iCur;
1468 int iHiwtr;
1469
1470 if( pArg && pArg->out ){
mistachkin1fe36bb2016-04-04 02:16:44 +00001471
shaneh642d8b82010-07-28 16:05:34 +00001472 iHiwtr = iCur = -1;
1473 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001474 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001475 "Memory Used: %d (max %d) bytes\n",
1476 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001477 iHiwtr = iCur = -1;
1478 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001479 raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001480 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001481 if( pArg->shellFlgs & SHFLG_Pagecache ){
1482 iHiwtr = iCur = -1;
1483 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001484 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001485 "Number of Pcache Pages Used: %d (max %d) pages\n",
1486 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001487 }
shaneh642d8b82010-07-28 16:05:34 +00001488 iHiwtr = iCur = -1;
1489 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001490 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001491 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1492 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001493 if( pArg->shellFlgs & SHFLG_Scratch ){
1494 iHiwtr = iCur = -1;
1495 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001496 raw_printf(pArg->out,
1497 "Number of Scratch Allocations Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001498 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001499 }
shaneh642d8b82010-07-28 16:05:34 +00001500 iHiwtr = iCur = -1;
1501 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001502 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001503 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1504 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001505 iHiwtr = iCur = -1;
1506 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001507 raw_printf(pArg->out, "Largest Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001508 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001509 iHiwtr = iCur = -1;
1510 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001511 raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001512 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001513 iHiwtr = iCur = -1;
1514 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001515 raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001516 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001517#ifdef YYTRACKMAXSTACKDEPTH
1518 iHiwtr = iCur = -1;
1519 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001520 raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001521 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001522#endif
1523 }
1524
1525 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001526 if( pArg->shellFlgs & SHFLG_Lookaside ){
1527 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001528 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1529 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001530 raw_printf(pArg->out,
1531 "Lookaside Slots Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001532 iCur, iHiwtr);
1533 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1534 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001535 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
1536 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001537 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1538 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001539 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
1540 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001541 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1542 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001543 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
1544 iHiwtr);
drh44dec872014-08-30 15:49:25 +00001545 }
shaneh642d8b82010-07-28 16:05:34 +00001546 iHiwtr = iCur = -1;
1547 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001548 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
1549 iCur);
drh4ace5362014-11-10 14:42:28 +00001550 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001551 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001552 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
drhc78e6e42011-09-23 18:58:23 +00001553 iHiwtr = iCur = -1;
1554 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001555 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001556 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001557 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001558 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
drhfbbcd5d2012-03-24 20:09:33 +00001559 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001560 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001561 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001562 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001563 iHiwtr = iCur = -1;
1564 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001565 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001566 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001567 }
1568
1569 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001570 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1571 bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001572 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001573 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001574 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001575 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001576 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001577 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001578 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001579 }
1580
drh34784902016-02-27 17:12:36 +00001581#ifdef __linux__
1582 displayLinuxIoStats(pArg->out);
1583#endif
1584
dan5a790282015-08-07 20:06:14 +00001585 /* Do not remove this machine readable comment: extra-stats-output-here */
1586
shaneh642d8b82010-07-28 16:05:34 +00001587 return 0;
1588}
1589
1590/*
dan8d1edb92014-11-05 09:07:28 +00001591** Display scan stats.
1592*/
1593static void display_scanstats(
1594 sqlite3 *db, /* Database to query */
1595 ShellState *pArg /* Pointer to ShellState */
1596){
drhf5ed7ad2015-06-15 14:43:25 +00001597#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1598 UNUSED_PARAMETER(db);
1599 UNUSED_PARAMETER(pArg);
1600#else
drh15f23c22014-11-06 12:46:16 +00001601 int i, k, n, mx;
mistachkinaae280e2015-12-31 19:06:24 +00001602 raw_printf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001603 mx = 0;
1604 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001605 double rEstLoop = 1.0;
1606 for(i=n=0; 1; i++){
1607 sqlite3_stmt *p = pArg->pStmt;
1608 sqlite3_int64 nLoop, nVisit;
1609 double rEst;
1610 int iSid;
1611 const char *zExplain;
1612 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1613 break;
1614 }
1615 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001616 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001617 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001618 if( n==0 ){
1619 rEstLoop = (double)nLoop;
mistachkinaae280e2015-12-31 19:06:24 +00001620 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001621 }
drh42f30bc2014-11-06 12:08:21 +00001622 n++;
1623 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1624 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1625 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
drhe05461c2015-12-30 13:36:57 +00001626 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
drh42f30bc2014-11-06 12:08:21 +00001627 rEstLoop *= rEst;
mistachkin1fe36bb2016-04-04 02:16:44 +00001628 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001629 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001630 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001631 );
dan8d1edb92014-11-05 09:07:28 +00001632 }
dan8d1edb92014-11-05 09:07:28 +00001633 }
mistachkinaae280e2015-12-31 19:06:24 +00001634 raw_printf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001635#endif
dan8d1edb92014-11-05 09:07:28 +00001636}
1637
1638/*
dana98bf362013-11-13 18:35:01 +00001639** Parameter azArray points to a zero-terminated array of strings. zStr
1640** points to a single nul-terminated string. Return non-zero if zStr
1641** is equal, according to strcmp(), to any of the strings in the array.
1642** Otherwise, return zero.
1643*/
1644static int str_in_array(const char *zStr, const char **azArray){
1645 int i;
1646 for(i=0; azArray[i]; i++){
1647 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1648 }
1649 return 0;
1650}
1651
1652/*
1653** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001654** and populate the ShellState.aiIndent[] array with the number of
mistachkin1fe36bb2016-04-04 02:16:44 +00001655** spaces each opcode should be indented before it is output.
dana98bf362013-11-13 18:35:01 +00001656**
1657** The indenting rules are:
1658**
1659** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1660** all opcodes that occur between the p2 jump destination and the opcode
1661** itself by 2 spaces.
1662**
drh01752bc2013-11-14 23:59:33 +00001663** * For each "Goto", if the jump destination is earlier in the program
1664** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001665** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001666** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001667** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001668** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001669*/
drhdcd87a92014-08-18 13:45:42 +00001670static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001671 const char *zSql; /* The text of the SQL statement */
1672 const char *z; /* Used to check if this is an EXPLAIN */
1673 int *abYield = 0; /* True if op is an OP_Yield */
1674 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001675 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001676
drh8ad0de32014-03-20 18:45:27 +00001677 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1678 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001679 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1680 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001681 const char *azGoto[] = { "Goto", 0 };
1682
1683 /* Try to figure out if this is really an EXPLAIN statement. If this
1684 ** cannot be verified, return early. */
drh87a24aa2016-02-09 20:04:07 +00001685 if( sqlite3_column_count(pSql)!=8 ){
1686 p->cMode = p->mode;
1687 return;
1688 }
dana98bf362013-11-13 18:35:01 +00001689 zSql = sqlite3_sql(pSql);
1690 if( zSql==0 ) return;
1691 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
drh87a24aa2016-02-09 20:04:07 +00001692 if( sqlite3_strnicmp(z, "explain", 7) ){
1693 p->cMode = p->mode;
1694 return;
1695 }
dana98bf362013-11-13 18:35:01 +00001696
1697 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1698 int i;
danc4650bb2013-11-18 08:41:06 +00001699 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001700 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001701
1702 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1703 ** p2 is an instruction address, set variable p2op to the index of that
1704 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1705 ** the current instruction is part of a sub-program generated by an
1706 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001707 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001708 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001709
1710 /* Grow the p->aiIndent array as required */
1711 if( iOp>=nAlloc ){
drh87a24aa2016-02-09 20:04:07 +00001712 if( iOp==0 ){
1713 /* Do further verfication that this is explain output. Abort if
1714 ** it is not */
1715 static const char *explainCols[] = {
1716 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
1717 int jj;
1718 for(jj=0; jj<ArraySize(explainCols); jj++){
1719 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
1720 p->cMode = p->mode;
1721 sqlite3_reset(pSql);
1722 return;
1723 }
1724 }
1725 }
dana98bf362013-11-13 18:35:01 +00001726 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001727 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1728 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001729 }
1730 abYield[iOp] = str_in_array(zOp, azYield);
1731 p->aiIndent[iOp] = 0;
1732 p->nIndent = iOp+1;
1733
1734 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001735 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001736 }
drhfe705102014-03-06 13:38:37 +00001737 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1738 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1739 ){
drheacd29d2016-04-15 15:03:27 +00001740 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001741 }
1742 }
1743
danc4650bb2013-11-18 08:41:06 +00001744 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001745 sqlite3_free(abYield);
1746 sqlite3_reset(pSql);
1747}
1748
1749/*
1750** Free the array allocated by explain_data_prepare().
1751*/
drhdcd87a92014-08-18 13:45:42 +00001752static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001753 sqlite3_free(p->aiIndent);
1754 p->aiIndent = 0;
1755 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001756 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001757}
1758
1759/*
drheacd29d2016-04-15 15:03:27 +00001760** Disable and restore .wheretrace and .selecttrace settings.
1761*/
1762#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1763extern int sqlite3SelectTrace;
1764static int savedSelectTrace;
1765#endif
1766#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1767extern int sqlite3WhereTrace;
1768static int savedWhereTrace;
1769#endif
1770static void disable_debug_trace_modes(void){
1771#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1772 savedSelectTrace = sqlite3SelectTrace;
1773 sqlite3SelectTrace = 0;
1774#endif
1775#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1776 savedWhereTrace = sqlite3WhereTrace;
1777 sqlite3WhereTrace = 0;
1778#endif
1779}
1780static void restore_debug_trace_modes(void){
1781#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1782 sqlite3SelectTrace = savedSelectTrace;
1783#endif
1784#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1785 sqlite3WhereTrace = savedWhereTrace;
1786#endif
1787}
1788
1789/*
1790** Run a prepared statement
1791*/
1792static void exec_prepared_stmt(
1793 ShellState *pArg, /* Pointer to ShellState */
1794 sqlite3_stmt *pStmt, /* Statment to run */
1795 int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
1796){
1797 int rc;
1798
1799 /* perform the first step. this will tell us if we
1800 ** have a result set or not and how wide it is.
1801 */
1802 rc = sqlite3_step(pStmt);
1803 /* if we have a result set... */
1804 if( SQLITE_ROW == rc ){
1805 /* if we have a callback... */
1806 if( xCallback ){
1807 /* allocate space for col name ptr, value ptr, and type */
1808 int nCol = sqlite3_column_count(pStmt);
1809 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
1810 if( !pData ){
1811 rc = SQLITE_NOMEM;
1812 }else{
1813 char **azCols = (char **)pData; /* Names of result columns */
1814 char **azVals = &azCols[nCol]; /* Results */
1815 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1816 int i, x;
1817 assert(sizeof(int) <= sizeof(char *));
1818 /* save off ptrs to column names */
1819 for(i=0; i<nCol; i++){
1820 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1821 }
1822 do{
1823 /* extract the data and data types */
1824 for(i=0; i<nCol; i++){
1825 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1826 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
1827 azVals[i] = "";
1828 }else{
1829 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1830 }
1831 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1832 rc = SQLITE_NOMEM;
1833 break; /* from for */
1834 }
1835 } /* end for */
1836
1837 /* if data and types extracted successfully... */
1838 if( SQLITE_ROW == rc ){
1839 /* call the supplied callback with the result row data */
1840 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1841 rc = SQLITE_ABORT;
1842 }else{
1843 rc = sqlite3_step(pStmt);
1844 }
1845 }
1846 } while( SQLITE_ROW == rc );
1847 sqlite3_free(pData);
1848 }
1849 }else{
1850 do{
1851 rc = sqlite3_step(pStmt);
1852 } while( rc == SQLITE_ROW );
1853 }
1854 }
1855}
1856
1857/*
mistachkin1fe36bb2016-04-04 02:16:44 +00001858** Execute a statement or set of statements. Print
1859** any result rows/columns depending on the current mode
shane626a6e42009-10-22 17:30:15 +00001860** set via the supplied callback.
1861**
mistachkin1fe36bb2016-04-04 02:16:44 +00001862** This is very similar to SQLite's built-in sqlite3_exec()
1863** function except it takes a slightly different callback
shane626a6e42009-10-22 17:30:15 +00001864** and callback data argument.
1865*/
1866static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001867 sqlite3 *db, /* An open database */
1868 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001869 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001870 /* (not the same as sqlite3_exec) */
1871 ShellState *pArg, /* Pointer to ShellState */
1872 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001873){
dan4564ced2010-01-05 04:59:56 +00001874 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1875 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001876 int rc2;
dan4564ced2010-01-05 04:59:56 +00001877 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001878
1879 if( pzErrMsg ){
1880 *pzErrMsg = NULL;
1881 }
1882
shaneb9fc17d2009-10-22 21:23:35 +00001883 while( zSql[0] && (SQLITE_OK == rc) ){
drheacd29d2016-04-15 15:03:27 +00001884 static const char *zStmtSql;
shaneb9fc17d2009-10-22 21:23:35 +00001885 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1886 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001887 if( pzErrMsg ){
1888 *pzErrMsg = save_err_msg(db);
1889 }
1890 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001891 if( !pStmt ){
1892 /* this happens for a comment or white-space */
1893 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001894 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001895 continue;
1896 }
drheacd29d2016-04-15 15:03:27 +00001897 zStmtSql = sqlite3_sql(pStmt);
1898 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
shane626a6e42009-10-22 17:30:15 +00001899
shaneh642d8b82010-07-28 16:05:34 +00001900 /* save off the prepared statment handle and reset row count */
1901 if( pArg ){
1902 pArg->pStmt = pStmt;
1903 pArg->cnt = 0;
1904 }
1905
shanehb7977c52010-01-18 18:17:10 +00001906 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001907 if( pArg && pArg->echoOn ){
drhe05461c2015-12-30 13:36:57 +00001908 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001909 }
shanehb7977c52010-01-18 18:17:10 +00001910
drhefbf3b12014-02-28 20:47:24 +00001911 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
drheacd29d2016-04-15 15:03:27 +00001912 if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
drhefbf3b12014-02-28 20:47:24 +00001913 sqlite3_stmt *pExplain;
drheacd29d2016-04-15 15:03:27 +00001914 char *zEQP;
1915 disable_debug_trace_modes();
1916 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
drhefbf3b12014-02-28 20:47:24 +00001917 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1918 if( rc==SQLITE_OK ){
1919 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001920 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1921 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1922 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001923 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001924 }
1925 }
1926 sqlite3_finalize(pExplain);
1927 sqlite3_free(zEQP);
drheacd29d2016-04-15 15:03:27 +00001928 if( pArg->autoEQP>=2 ){
1929 /* Also do an EXPLAIN for ".eqp full" mode */
1930 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
1931 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1932 if( rc==SQLITE_OK ){
1933 pArg->cMode = MODE_Explain;
1934 explain_data_prepare(pArg, pExplain);
1935 exec_prepared_stmt(pArg, pExplain, xCallback);
1936 explain_data_delete(pArg);
1937 }
1938 sqlite3_finalize(pExplain);
1939 sqlite3_free(zEQP);
1940 }
1941 restore_debug_trace_modes();
drhefbf3b12014-02-28 20:47:24 +00001942 }
1943
drh700c2522016-02-09 18:39:25 +00001944 if( pArg ){
1945 pArg->cMode = pArg->mode;
drh87a24aa2016-02-09 20:04:07 +00001946 if( pArg->autoExplain
1947 && sqlite3_column_count(pStmt)==8
drheacd29d2016-04-15 15:03:27 +00001948 && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
drh700c2522016-02-09 18:39:25 +00001949 ){
1950 pArg->cMode = MODE_Explain;
1951 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001952
drh700c2522016-02-09 18:39:25 +00001953 /* If the shell is currently in ".explain" mode, gather the extra
1954 ** data required to add indents to the output.*/
1955 if( pArg->cMode==MODE_Explain ){
1956 explain_data_prepare(pArg, pStmt);
1957 }
dana98bf362013-11-13 18:35:01 +00001958 }
1959
drheacd29d2016-04-15 15:03:27 +00001960 exec_prepared_stmt(pArg, pStmt, xCallback);
dana98bf362013-11-13 18:35:01 +00001961 explain_data_delete(pArg);
1962
shaneh642d8b82010-07-28 16:05:34 +00001963 /* print usage stats if stats on */
1964 if( pArg && pArg->statsOn ){
1965 display_stats(db, pArg, 0);
1966 }
1967
dan8d1edb92014-11-05 09:07:28 +00001968 /* print loop-counters if required */
1969 if( pArg && pArg->scanstatsOn ){
1970 display_scanstats(db, pArg);
1971 }
1972
mistachkin1fe36bb2016-04-04 02:16:44 +00001973 /* Finalize the statement just executed. If this fails, save a
dan4564ced2010-01-05 04:59:56 +00001974 ** copy of the error message. Otherwise, set zSql to point to the
1975 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001976 rc2 = sqlite3_finalize(pStmt);
1977 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001978 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001979 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001980 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001981 }else if( pzErrMsg ){
1982 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001983 }
shaneh642d8b82010-07-28 16:05:34 +00001984
1985 /* clear saved stmt handle */
1986 if( pArg ){
1987 pArg->pStmt = NULL;
1988 }
shane626a6e42009-10-22 17:30:15 +00001989 }
shaneb9fc17d2009-10-22 21:23:35 +00001990 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001991
1992 return rc;
1993}
1994
drhdd3d4592004-08-30 01:54:05 +00001995
drh33048c02001-10-01 14:29:22 +00001996/*
drh4c653a02000-06-07 01:27:47 +00001997** This is a different callback routine used for dumping the database.
1998** Each row received by this callback consists of a table name,
1999** the table type ("index" or "table") and SQL to create the table.
2000** This routine should print text sufficient to recreate the table.
2001*/
2002static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00002003 int rc;
2004 const char *zTable;
2005 const char *zType;
2006 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00002007 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00002008 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00002009
drh902b9ee2008-12-05 17:17:07 +00002010 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00002011 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00002012 zTable = azArg[0];
2013 zType = azArg[1];
2014 zSql = azArg[2];
mistachkin1fe36bb2016-04-04 02:16:44 +00002015
drh00b950d2005-09-11 02:03:03 +00002016 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00002017 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00002018 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002019 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00002020 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
2021 return 0;
drh45e29d82006-11-20 16:21:10 +00002022 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
2023 char *zIns;
2024 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00002025 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00002026 p->writableSchema = 1;
2027 }
2028 zIns = sqlite3_mprintf(
2029 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
2030 "VALUES('table','%q','%q',0,'%q');",
2031 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00002032 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00002033 sqlite3_free(zIns);
2034 return 0;
drh00b950d2005-09-11 02:03:03 +00002035 }else{
drhe05461c2015-12-30 13:36:57 +00002036 utf8_printf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00002037 }
danielk19772a02e332004-06-05 08:04:36 +00002038
2039 if( strcmp(zType, "table")==0 ){
2040 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00002041 char *zSelect = 0;
2042 char *zTableInfo = 0;
2043 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00002044 int nRow = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +00002045
danielk19772a02e332004-06-05 08:04:36 +00002046 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
2047 zTableInfo = appendText(zTableInfo, zTable, '"');
2048 zTableInfo = appendText(zTableInfo, ");", 0);
2049
drhc7181902014-02-27 15:04:13 +00002050 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00002051 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00002052 if( rc!=SQLITE_OK || !pTableInfo ){
2053 return 1;
2054 }
2055
2056 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00002057 /* Always quote the table name, even if it appears to be pure ascii,
2058 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
2059 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00002060 if( zTmp ){
2061 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00002062 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00002063 }
2064 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
2065 rc = sqlite3_step(pTableInfo);
2066 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00002067 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00002068 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00002069 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00002070 rc = sqlite3_step(pTableInfo);
2071 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00002072 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00002073 }else{
2074 zSelect = appendText(zSelect, ") ", 0);
2075 }
drh157e29a2009-05-21 15:15:00 +00002076 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00002077 }
2078 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00002079 if( rc!=SQLITE_OK || nRow==0 ){
2080 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00002081 return 1;
2082 }
2083 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
2084 zSelect = appendText(zSelect, zTable, '"');
2085
drh2f464a02011-10-13 00:41:49 +00002086 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00002087 if( rc==SQLITE_CORRUPT ){
2088 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00002089 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00002090 }
drh85e72432012-04-11 11:38:53 +00002091 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00002092 }
drh4c653a02000-06-07 01:27:47 +00002093 return 0;
2094}
2095
2096/*
drh45e29d82006-11-20 16:21:10 +00002097** Run zQuery. Use dump_callback() as the callback routine so that
2098** the contents of the query are output as SQL statements.
2099**
drhdd3d4592004-08-30 01:54:05 +00002100** If we get a SQLITE_CORRUPT error, rerun the query after appending
2101** "ORDER BY rowid DESC" to the end.
2102*/
2103static int run_schema_dump_query(
mistachkin1fe36bb2016-04-04 02:16:44 +00002104 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00002105 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00002106){
2107 int rc;
drh2f464a02011-10-13 00:41:49 +00002108 char *zErr = 0;
2109 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00002110 if( rc==SQLITE_CORRUPT ){
2111 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00002112 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00002113 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00002114 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00002115 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002116 sqlite3_free(zErr);
2117 zErr = 0;
2118 }
drhdd3d4592004-08-30 01:54:05 +00002119 zQ2 = malloc( len+100 );
2120 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00002121 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00002122 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
2123 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002124 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002125 }else{
2126 rc = SQLITE_CORRUPT;
2127 }
2128 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00002129 free(zQ2);
2130 }
2131 return rc;
2132}
2133
2134/*
drh75897232000-05-29 14:26:00 +00002135** Text of a help message
2136*/
persicom1d0b8722002-04-18 02:53:04 +00002137static char zHelp[] =
drha0daa752016-09-16 11:53:10 +00002138#ifndef SQLITE_OMIT_AUTHORIZATION
drhde613c62016-04-04 17:23:10 +00002139 ".auth ON|OFF Show authorizer callbacks\n"
drha0daa752016-09-16 11:53:10 +00002140#endif
drh9ff849f2009-02-04 20:55:57 +00002141 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00002142 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00002143 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00002144 ".changes on|off Show number of rows changed by SQL\n"
drh2db82112016-09-15 21:35:24 +00002145 ".check GLOB Fail if output since .testcase does not match\n"
drh4bbcf102014-02-06 02:46:08 +00002146 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00002147 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00002148 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00002149 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00002150 " If TABLE specified, only dump tables matching\n"
2151 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00002152 ".echo on|off Turn command echo on or off\n"
drheacd29d2016-04-15 15:03:27 +00002153 ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00002154 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00002155 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drh4926fec2016-04-13 15:33:42 +00002156 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00002157 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00002158 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00002159 ".import FILE TABLE Import data from FILE into TABLE\n"
drh0e55db12015-02-06 14:51:13 +00002160 ".indexes ?TABLE? Show names of all indexes\n"
2161 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00002162 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00002163#ifdef SQLITE_ENABLE_IOTRACE
2164 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
2165#endif
drh1a513372015-05-02 17:40:23 +00002166 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00002167#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002168 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00002169#endif
drh127f9d72010-02-23 01:47:00 +00002170 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00002171 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00002172 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00002173 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00002174 " column Left-aligned columns. (See .width)\n"
2175 " html HTML <table> code\n"
2176 " insert SQL insert statements for TABLE\n"
2177 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00002178 " list Values delimited by .separator strings\n"
drhb860bc92004-08-04 15:16:55 +00002179 " tabs Tab-separated values\n"
2180 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00002181 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00002182 ".once FILENAME Output for the next SQL command only to FILENAME\n"
drhcd0509e2016-09-16 00:26:08 +00002183 ".open ?-new? ?FILE? Close existing database and reopen FILE\n"
2184 " The --new starts with an empty file\n"
drhc2ce0be2014-05-29 12:36:14 +00002185 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00002186 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002187 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002188 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00002189 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00002190 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00002191 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00002192 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh4926fec2016-04-13 15:33:42 +00002193 ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
2194 " Add --indent for pretty-printing\n"
mistachkine0d68852014-12-11 03:12:33 +00002195 ".separator COL ?ROW? Change the column separator and optionally the row\n"
2196 " separator for both the output mode and .import\n"
drhe6229612014-08-18 15:08:26 +00002197#if defined(SQLITE_ENABLE_SESSION)
2198 ".session CMD ... Create or control sessions\n"
2199#endif
drh62cdde52014-05-28 20:22:28 +00002200 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00002201 ".show Show the current values for various settings\n"
drh34784902016-02-27 17:12:36 +00002202 ".stats ?on|off? Show stats or turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00002203 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00002204 ".tables ?TABLE? List names of tables\n"
2205 " If TABLE specified, only list tables matching\n"
2206 " LIKE pattern TABLE.\n"
drh760c8162016-09-16 02:52:22 +00002207 ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
drh2dfbbca2000-07-28 14:32:48 +00002208 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00002209 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00002210 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00002211 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00002212 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00002213 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00002214 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00002215 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00002216;
2217
drhe6229612014-08-18 15:08:26 +00002218#if defined(SQLITE_ENABLE_SESSION)
2219/*
2220** Print help information for the ".sessions" command
2221*/
2222void session_help(ShellState *p){
mistachkin899c5c92016-04-03 20:50:02 +00002223 raw_printf(p->out,
drhe6229612014-08-18 15:08:26 +00002224 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
2225 "If ?NAME? is omitted, the first defined session is used.\n"
2226 "Subcommands:\n"
2227 " attach TABLE Attach TABLE\n"
2228 " changeset FILE Write a changeset into FILE\n"
2229 " close Close one session\n"
2230 " enable ?BOOLEAN? Set or query the enable bit\n"
mistachkin1fe36bb2016-04-04 02:16:44 +00002231 " filter GLOB... Reject tables matching GLOBs\n"
drhe6229612014-08-18 15:08:26 +00002232 " indirect ?BOOLEAN? Mark or query the indirect status\n"
2233 " isempty Query whether the session is empty\n"
2234 " list List currently open session names\n"
2235 " open DB NAME Open a new session on DB\n"
2236 " patchset FILE Write a patchset into FILE\n"
2237 );
2238}
2239#endif
2240
2241
drhdaffd0e2001-04-11 14:28:42 +00002242/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00002243static int process_input(ShellState *p, FILE *in);
drh2db82112016-09-15 21:35:24 +00002244
2245
2246/*
2247** Read the content of a file into memory obtained from sqlite3_malloc64().
2248** The caller is responsible for freeing the memory.
2249**
2250** NULL is returned if any error is encountered.
2251*/
2252static char *readFile(const char *zName){
2253 FILE *in = fopen(zName, "rb");
2254 long nIn;
2255 char *pBuf;
2256 if( in==0 ) return 0;
2257 fseek(in, 0, SEEK_END);
2258 nIn = ftell(in);
2259 rewind(in);
2260 pBuf = sqlite3_malloc64( nIn );
2261 if( pBuf==0 ) return 0;
2262 if( 1!=fread(pBuf, nIn, 1, in) ){
2263 sqlite3_free(pBuf);
2264 return 0;
2265 }
2266 return pBuf;
2267}
2268
drhba5b0932014-07-24 12:39:59 +00002269/*
2270** Implementation of the "readfile(X)" SQL function. The entire content
2271** of the file named X is read and returned as a BLOB. NULL is returned
2272** if the file does not exist or is unreadable.
2273*/
2274static void readfileFunc(
2275 sqlite3_context *context,
2276 int argc,
2277 sqlite3_value **argv
2278){
2279 const char *zName;
drhba5b0932014-07-24 12:39:59 +00002280 void *pBuf;
2281
drhf5ed7ad2015-06-15 14:43:25 +00002282 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002283 zName = (const char*)sqlite3_value_text(argv[0]);
2284 if( zName==0 ) return;
drh2db82112016-09-15 21:35:24 +00002285 pBuf = readFile(zName);
2286 if( pBuf ) sqlite3_result_blob(context, pBuf, -1, sqlite3_free);
drhba5b0932014-07-24 12:39:59 +00002287}
2288
2289/*
2290** Implementation of the "writefile(X,Y)" SQL function. The argument Y
2291** is written into file X. The number of bytes written is returned. Or
2292** NULL is returned if something goes wrong, such as being unable to open
2293** file X for writing.
2294*/
2295static void writefileFunc(
2296 sqlite3_context *context,
2297 int argc,
2298 sqlite3_value **argv
2299){
2300 FILE *out;
2301 const char *z;
drhba5b0932014-07-24 12:39:59 +00002302 sqlite3_int64 rc;
2303 const char *zFile;
2304
drhf5ed7ad2015-06-15 14:43:25 +00002305 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002306 zFile = (const char*)sqlite3_value_text(argv[0]);
2307 if( zFile==0 ) return;
2308 out = fopen(zFile, "wb");
2309 if( out==0 ) return;
2310 z = (const char*)sqlite3_value_blob(argv[1]);
2311 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002312 rc = 0;
2313 }else{
drh490fe862014-08-11 14:21:32 +00002314 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002315 }
2316 fclose(out);
2317 sqlite3_result_int64(context, rc);
2318}
drhdaffd0e2001-04-11 14:28:42 +00002319
drhe6229612014-08-18 15:08:26 +00002320#if defined(SQLITE_ENABLE_SESSION)
2321/*
2322** Close a single OpenSession object and release all of its associated
2323** resources.
2324*/
2325static void session_close(OpenSession *pSession){
2326 int i;
2327 sqlite3session_delete(pSession->p);
2328 sqlite3_free(pSession->zName);
2329 for(i=0; i<pSession->nFilter; i++){
2330 sqlite3_free(pSession->azFilter[i]);
2331 }
2332 sqlite3_free(pSession->azFilter);
2333 memset(pSession, 0, sizeof(OpenSession));
2334}
2335#endif
2336
2337/*
drh51b55a32016-04-04 12:38:05 +00002338** Close all OpenSession objects and release all associated resources.
drhe6229612014-08-18 15:08:26 +00002339*/
drhe6229612014-08-18 15:08:26 +00002340#if defined(SQLITE_ENABLE_SESSION)
drh51b55a32016-04-04 12:38:05 +00002341static void session_close_all(ShellState *p){
drhe6229612014-08-18 15:08:26 +00002342 int i;
2343 for(i=0; i<p->nSession; i++){
2344 session_close(&p->aSession[i]);
2345 }
2346 p->nSession = 0;
drhe6229612014-08-18 15:08:26 +00002347}
drh51b55a32016-04-04 12:38:05 +00002348#else
2349# define session_close_all(X)
2350#endif
drhe6229612014-08-18 15:08:26 +00002351
drh75897232000-05-29 14:26:00 +00002352/*
drh03168ca2014-08-18 20:01:31 +00002353** Implementation of the xFilter function for an open session. Omit
2354** any tables named by ".session filter" but let all other table through.
2355*/
2356#if defined(SQLITE_ENABLE_SESSION)
2357static int session_filter(void *pCtx, const char *zTab){
2358 OpenSession *pSession = (OpenSession*)pCtx;
2359 int i;
2360 for(i=0; i<pSession->nFilter; i++){
2361 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
2362 }
2363 return 1;
2364}
2365#endif
2366
2367/*
drh44c2eb12003-04-30 11:38:26 +00002368** Make sure the database is open. If it is not, then open it. If
2369** the database fails to open, print an error message and exit.
2370*/
drhdcd87a92014-08-18 13:45:42 +00002371static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002372 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002373 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002374 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002375 globalDb = p->db;
2376 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2377 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002378 shellstaticFunc, 0, 0);
2379 }
mistachkin8e189222015-04-19 21:43:16 +00002380 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00002381 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002382 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002383 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002384 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002385 }
drhc2e87a32006-06-27 15:16:14 +00002386#ifndef SQLITE_OMIT_LOAD_EXTENSION
2387 sqlite3_enable_load_extension(p->db, 1);
2388#endif
mistachkin8e189222015-04-19 21:43:16 +00002389 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002390 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002391 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002392 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002393 }
2394}
2395
2396/*
drhfeac5f82004-08-01 00:10:45 +00002397** Do C-language style dequoting.
2398**
mistachkinf21979d2015-01-18 05:35:01 +00002399** \a -> alarm
2400** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002401** \t -> tab
2402** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002403** \v -> vertical tab
2404** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002405** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002406** \s -> space
drh4c56b992013-06-27 13:26:55 +00002407** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002408** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002409** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002410** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002411*/
2412static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002413 int i, j;
2414 char c;
drhc2ce0be2014-05-29 12:36:14 +00002415 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002416 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002417 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002418 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002419 if( c=='a' ){
2420 c = '\a';
2421 }else if( c=='b' ){
2422 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002423 }else if( c=='t' ){
2424 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002425 }else if( c=='n' ){
2426 c = '\n';
2427 }else if( c=='v' ){
2428 c = '\v';
2429 }else if( c=='f' ){
2430 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002431 }else if( c=='r' ){
2432 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002433 }else if( c=='"' ){
2434 c = '"';
2435 }else if( c=='\'' ){
2436 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002437 }else if( c=='\\' ){
2438 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002439 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002440 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002441 if( z[i+1]>='0' && z[i+1]<='7' ){
2442 i++;
2443 c = (c<<3) + z[i] - '0';
2444 if( z[i+1]>='0' && z[i+1]<='7' ){
2445 i++;
2446 c = (c<<3) + z[i] - '0';
2447 }
2448 }
2449 }
2450 }
2451 z[j] = c;
2452 }
drhc2ce0be2014-05-29 12:36:14 +00002453 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002454}
2455
2456/*
drh348d19c2013-06-03 12:47:43 +00002457** Return the value of a hexadecimal digit. Return -1 if the input
2458** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002459*/
drh348d19c2013-06-03 12:47:43 +00002460static int hexDigitValue(char c){
2461 if( c>='0' && c<='9' ) return c - '0';
2462 if( c>='a' && c<='f' ) return c - 'a' + 10;
2463 if( c>='A' && c<='F' ) return c - 'A' + 10;
2464 return -1;
drhc28490c2006-10-26 14:25:58 +00002465}
2466
2467/*
drh7d9f3942013-04-03 01:26:54 +00002468** Interpret zArg as an integer value, possibly with suffixes.
2469*/
2470static sqlite3_int64 integerValue(const char *zArg){
2471 sqlite3_int64 v = 0;
2472 static const struct { char *zSuffix; int iMult; } aMult[] = {
2473 { "KiB", 1024 },
2474 { "MiB", 1024*1024 },
2475 { "GiB", 1024*1024*1024 },
2476 { "KB", 1000 },
2477 { "MB", 1000000 },
2478 { "GB", 1000000000 },
2479 { "K", 1000 },
2480 { "M", 1000000 },
2481 { "G", 1000000000 },
2482 };
2483 int i;
2484 int isNeg = 0;
2485 if( zArg[0]=='-' ){
2486 isNeg = 1;
2487 zArg++;
2488 }else if( zArg[0]=='+' ){
2489 zArg++;
2490 }
drh348d19c2013-06-03 12:47:43 +00002491 if( zArg[0]=='0' && zArg[1]=='x' ){
2492 int x;
2493 zArg += 2;
2494 while( (x = hexDigitValue(zArg[0]))>=0 ){
2495 v = (v<<4) + x;
2496 zArg++;
2497 }
2498 }else{
2499 while( IsDigit(zArg[0]) ){
2500 v = v*10 + zArg[0] - '0';
2501 zArg++;
2502 }
drh7d9f3942013-04-03 01:26:54 +00002503 }
drhc2bed0a2013-05-24 11:57:50 +00002504 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002505 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2506 v *= aMult[i].iMult;
2507 break;
2508 }
2509 }
2510 return isNeg? -v : v;
2511}
2512
2513/*
drh348d19c2013-06-03 12:47:43 +00002514** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2515** for TRUE and FALSE. Return the integer value if appropriate.
2516*/
2517static int booleanValue(char *zArg){
2518 int i;
2519 if( zArg[0]=='0' && zArg[1]=='x' ){
2520 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2521 }else{
2522 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2523 }
2524 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2525 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2526 return 1;
2527 }
2528 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2529 return 0;
2530 }
mistachkinaae280e2015-12-31 19:06:24 +00002531 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002532 zArg);
2533 return 0;
2534}
2535
2536/*
drh42f64e52012-04-04 16:56:23 +00002537** Close an output file, assuming it is not stderr or stdout
2538*/
2539static void output_file_close(FILE *f){
2540 if( f && f!=stdout && f!=stderr ) fclose(f);
2541}
2542
2543/*
2544** Try to open an output file. The names "stdout" and "stderr" are
mistachkin1fe36bb2016-04-04 02:16:44 +00002545** recognized and do the right thing. NULL is returned if the output
drh42f64e52012-04-04 16:56:23 +00002546** filename is "off".
2547*/
2548static FILE *output_file_open(const char *zFile){
2549 FILE *f;
2550 if( strcmp(zFile,"stdout")==0 ){
2551 f = stdout;
2552 }else if( strcmp(zFile, "stderr")==0 ){
2553 f = stderr;
2554 }else if( strcmp(zFile, "off")==0 ){
2555 f = 0;
2556 }else{
2557 f = fopen(zFile, "wb");
2558 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002559 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002560 }
2561 }
2562 return f;
2563}
2564
2565/*
2566** A routine for handling output from sqlite3_trace().
2567*/
drh4b363a52016-07-23 20:27:41 +00002568static int sql_trace_callback(
2569 unsigned mType,
2570 void *pArg,
2571 void *pP,
2572 void *pX
2573){
drh42f64e52012-04-04 16:56:23 +00002574 FILE *f = (FILE*)pArg;
drhb0df5402016-08-01 17:06:44 +00002575 UNUSED_PARAMETER(mType);
2576 UNUSED_PARAMETER(pP);
drh4b2590e2014-08-19 19:28:00 +00002577 if( f ){
drh4b363a52016-07-23 20:27:41 +00002578 const char *z = (const char*)pX;
drh4b2590e2014-08-19 19:28:00 +00002579 int i = (int)strlen(z);
2580 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002581 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002582 }
drh4b363a52016-07-23 20:27:41 +00002583 return 0;
drh42f64e52012-04-04 16:56:23 +00002584}
2585
2586/*
drhd8621b92012-04-17 09:09:33 +00002587** A no-op routine that runs with the ".breakpoint" doc-command. This is
2588** a useful spot to set a debugger breakpoint.
2589*/
2590static void test_breakpoint(void){
2591 static int nCall = 0;
2592 nCall++;
2593}
2594
2595/*
mistachkin636bf9f2014-07-19 20:15:16 +00002596** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002597*/
mistachkin636bf9f2014-07-19 20:15:16 +00002598typedef struct ImportCtx ImportCtx;
2599struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002600 const char *zFile; /* Name of the input file */
2601 FILE *in; /* Read the CSV text from this input stream */
2602 char *z; /* Accumulated text for a field */
2603 int n; /* Number of bytes in z */
2604 int nAlloc; /* Space allocated for z[] */
2605 int nLine; /* Current line number */
2606 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002607 int cColSep; /* The column separator character. (Usually ",") */
2608 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002609};
2610
2611/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002612static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002613 if( p->n+1>=p->nAlloc ){
2614 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002615 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002616 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002617 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002618 exit(1);
2619 }
2620 }
2621 p->z[p->n++] = (char)c;
2622}
2623
2624/* Read a single field of CSV text. Compatible with rfc4180 and extended
2625** with the option of having a separator other than ",".
2626**
2627** + Input comes from p->in.
2628** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002629** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002630** + Use p->cSep as the column separator. The default is ",".
2631** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002632** + Keep track of the line number in p->nLine.
2633** + Store the character that terminates the field in p->cTerm. Store
2634** EOF on end-of-file.
2635** + Report syntax errors on stderr
2636*/
mistachkin44723ce2015-03-21 02:22:37 +00002637static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002638 int c;
2639 int cSep = p->cColSep;
2640 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002641 p->n = 0;
2642 c = fgetc(p->in);
2643 if( c==EOF || seenInterrupt ){
2644 p->cTerm = EOF;
2645 return 0;
2646 }
2647 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002648 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002649 int startLine = p->nLine;
2650 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002651 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002652 while( 1 ){
2653 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002654 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002655 if( c==cQuote ){
2656 if( pc==cQuote ){
2657 pc = 0;
2658 continue;
2659 }
2660 }
2661 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002662 || (c==rSep && pc==cQuote)
2663 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002664 || (c==EOF && pc==cQuote)
2665 ){
2666 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002667 p->cTerm = c;
2668 break;
2669 }
2670 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002671 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002672 p->zFile, p->nLine, cQuote);
2673 }
2674 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002675 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002676 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002677 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002678 break;
2679 }
mistachkin636bf9f2014-07-19 20:15:16 +00002680 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002681 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002682 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002683 }
drhdb95f682013-06-26 22:46:00 +00002684 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002685 while( c!=EOF && c!=cSep && c!=rSep ){
2686 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002687 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002688 }
mistachkin636bf9f2014-07-19 20:15:16 +00002689 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002690 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002691 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002692 }
drhdb95f682013-06-26 22:46:00 +00002693 p->cTerm = c;
2694 }
drh8dd675e2013-07-12 21:09:24 +00002695 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002696 return p->z;
2697}
2698
mistachkin636bf9f2014-07-19 20:15:16 +00002699/* Read a single field of ASCII delimited text.
2700**
2701** + Input comes from p->in.
2702** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002703** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002704** + Use p->cSep as the column separator. The default is "\x1F".
2705** + Use p->rSep as the row separator. The default is "\x1E".
2706** + Keep track of the row number in p->nLine.
2707** + Store the character that terminates the field in p->cTerm. Store
2708** EOF on end-of-file.
2709** + Report syntax errors on stderr
2710*/
mistachkin44723ce2015-03-21 02:22:37 +00002711static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002712 int c;
2713 int cSep = p->cColSep;
2714 int rSep = p->cRowSep;
2715 p->n = 0;
2716 c = fgetc(p->in);
2717 if( c==EOF || seenInterrupt ){
2718 p->cTerm = EOF;
2719 return 0;
2720 }
2721 while( c!=EOF && c!=cSep && c!=rSep ){
2722 import_append_char(p, c);
2723 c = fgetc(p->in);
2724 }
2725 if( c==rSep ){
2726 p->nLine++;
2727 }
2728 p->cTerm = c;
2729 if( p->z ) p->z[p->n] = 0;
2730 return p->z;
2731}
2732
drhdb95f682013-06-26 22:46:00 +00002733/*
drh4bbcf102014-02-06 02:46:08 +00002734** Try to transfer data for table zTable. If an error is seen while
2735** moving forward, try to go backwards. The backwards movement won't
2736** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002737*/
mistachkine31ae902014-02-06 01:15:29 +00002738static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002739 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002740 sqlite3 *newDb,
2741 const char *zTable
2742){
mistachkin1fe36bb2016-04-04 02:16:44 +00002743 sqlite3_stmt *pQuery = 0;
drh3350ce92014-02-06 00:49:12 +00002744 sqlite3_stmt *pInsert = 0;
2745 char *zQuery = 0;
2746 char *zInsert = 0;
2747 int rc;
2748 int i, j, n;
2749 int nTable = (int)strlen(zTable);
2750 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002751 int cnt = 0;
2752 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002753
2754 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2755 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2756 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002757 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002758 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2759 zQuery);
2760 goto end_data_xfer;
2761 }
2762 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002763 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002764 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002765 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002766 goto end_data_xfer;
2767 }
2768 sqlite3_snprintf(200+nTable,zInsert,
2769 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2770 i = (int)strlen(zInsert);
2771 for(j=1; j<n; j++){
2772 memcpy(zInsert+i, ",?", 2);
2773 i += 2;
2774 }
2775 memcpy(zInsert+i, ");", 3);
2776 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2777 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002778 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002779 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2780 zQuery);
2781 goto end_data_xfer;
2782 }
2783 for(k=0; k<2; k++){
2784 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2785 for(i=0; i<n; i++){
2786 switch( sqlite3_column_type(pQuery, i) ){
2787 case SQLITE_NULL: {
2788 sqlite3_bind_null(pInsert, i+1);
2789 break;
2790 }
2791 case SQLITE_INTEGER: {
2792 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2793 break;
2794 }
2795 case SQLITE_FLOAT: {
2796 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2797 break;
2798 }
2799 case SQLITE_TEXT: {
2800 sqlite3_bind_text(pInsert, i+1,
2801 (const char*)sqlite3_column_text(pQuery,i),
2802 -1, SQLITE_STATIC);
2803 break;
2804 }
2805 case SQLITE_BLOB: {
2806 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2807 sqlite3_column_bytes(pQuery,i),
2808 SQLITE_STATIC);
2809 break;
2810 }
2811 }
2812 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002813 rc = sqlite3_step(pInsert);
2814 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002815 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002816 sqlite3_errmsg(newDb));
2817 }
drh3350ce92014-02-06 00:49:12 +00002818 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002819 cnt++;
2820 if( (cnt%spinRate)==0 ){
2821 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2822 fflush(stdout);
2823 }
drh3350ce92014-02-06 00:49:12 +00002824 } /* End while */
2825 if( rc==SQLITE_DONE ) break;
2826 sqlite3_finalize(pQuery);
2827 sqlite3_free(zQuery);
2828 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2829 zTable);
2830 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2831 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002832 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002833 break;
drh3350ce92014-02-06 00:49:12 +00002834 }
2835 } /* End for(k=0...) */
2836
2837end_data_xfer:
2838 sqlite3_finalize(pQuery);
2839 sqlite3_finalize(pInsert);
2840 sqlite3_free(zQuery);
2841 sqlite3_free(zInsert);
2842}
2843
2844
2845/*
2846** Try to transfer all rows of the schema that match zWhere. For
2847** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002848** If an error is encountered while moving forward through the
2849** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002850*/
mistachkine31ae902014-02-06 01:15:29 +00002851static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002852 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002853 sqlite3 *newDb,
2854 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002855 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002856){
2857 sqlite3_stmt *pQuery = 0;
2858 char *zQuery = 0;
2859 int rc;
2860 const unsigned char *zName;
2861 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002862 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002863
2864 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2865 " WHERE %s", zWhere);
2866 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2867 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002868 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002869 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2870 zQuery);
2871 goto end_schema_xfer;
2872 }
2873 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2874 zName = sqlite3_column_text(pQuery, 0);
2875 zSql = sqlite3_column_text(pQuery, 1);
2876 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002877 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2878 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002879 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002880 sqlite3_free(zErrMsg);
2881 zErrMsg = 0;
2882 }
drh3350ce92014-02-06 00:49:12 +00002883 if( xForEach ){
2884 xForEach(p, newDb, (const char*)zName);
2885 }
2886 printf("done\n");
2887 }
2888 if( rc!=SQLITE_DONE ){
2889 sqlite3_finalize(pQuery);
2890 sqlite3_free(zQuery);
2891 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2892 " WHERE %s ORDER BY rowid DESC", zWhere);
2893 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2894 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002895 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002896 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2897 zQuery);
2898 goto end_schema_xfer;
2899 }
2900 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2901 zName = sqlite3_column_text(pQuery, 0);
2902 zSql = sqlite3_column_text(pQuery, 1);
2903 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002904 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2905 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002906 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002907 sqlite3_free(zErrMsg);
2908 zErrMsg = 0;
2909 }
drh3350ce92014-02-06 00:49:12 +00002910 if( xForEach ){
2911 xForEach(p, newDb, (const char*)zName);
2912 }
2913 printf("done\n");
2914 }
2915 }
2916end_schema_xfer:
2917 sqlite3_finalize(pQuery);
2918 sqlite3_free(zQuery);
2919}
2920
2921/*
2922** Open a new database file named "zNewDb". Try to recover as much information
2923** as possible out of the main database (which might be corrupt) and write it
2924** into zNewDb.
2925*/
drhdcd87a92014-08-18 13:45:42 +00002926static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002927 int rc;
2928 sqlite3 *newDb = 0;
2929 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002930 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002931 return;
2932 }
2933 rc = sqlite3_open(zNewDb, &newDb);
2934 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002935 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002936 sqlite3_errmsg(newDb));
2937 }else{
drh54d0d2d2014-04-03 00:32:13 +00002938 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002939 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002940 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2941 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002942 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002943 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002944 }
2945 sqlite3_close(newDb);
2946}
2947
2948/*
drhc2ce0be2014-05-29 12:36:14 +00002949** Change the output file back to stdout
2950*/
drhdcd87a92014-08-18 13:45:42 +00002951static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002952 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002953#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002954 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002955#endif
drhc2ce0be2014-05-29 12:36:14 +00002956 }else{
2957 output_file_close(p->out);
2958 }
2959 p->outfile[0] = 0;
2960 p->out = stdout;
2961}
2962
2963/*
drhf7502f02015-02-06 14:19:44 +00002964** Run an SQL command and return the single integer result.
2965*/
2966static int db_int(ShellState *p, const char *zSql){
2967 sqlite3_stmt *pStmt;
2968 int res = 0;
2969 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2970 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2971 res = sqlite3_column_int(pStmt,0);
2972 }
2973 sqlite3_finalize(pStmt);
2974 return res;
2975}
2976
2977/*
2978** Convert a 2-byte or 4-byte big-endian integer into a native integer
2979*/
drha0620ac2016-07-13 13:05:13 +00002980static unsigned int get2byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00002981 return (a[0]<<8) + a[1];
2982}
drha0620ac2016-07-13 13:05:13 +00002983static unsigned int get4byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00002984 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
2985}
2986
2987/*
2988** Implementation of the ".info" command.
2989**
2990** Return 1 on error, 2 to exit, and 0 otherwise.
2991*/
drh0e55db12015-02-06 14:51:13 +00002992static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00002993 static const struct { const char *zName; int ofst; } aField[] = {
2994 { "file change counter:", 24 },
2995 { "database page count:", 28 },
2996 { "freelist page count:", 36 },
2997 { "schema cookie:", 40 },
2998 { "schema format:", 44 },
2999 { "default cache size:", 48 },
3000 { "autovacuum top root:", 52 },
3001 { "incremental vacuum:", 64 },
3002 { "text encoding:", 56 },
3003 { "user version:", 60 },
3004 { "application id:", 68 },
3005 { "software version:", 96 },
3006 };
drh0e55db12015-02-06 14:51:13 +00003007 static const struct { const char *zName; const char *zSql; } aQuery[] = {
3008 { "number of tables:",
3009 "SELECT count(*) FROM %s WHERE type='table'" },
3010 { "number of indexes:",
3011 "SELECT count(*) FROM %s WHERE type='index'" },
3012 { "number of triggers:",
3013 "SELECT count(*) FROM %s WHERE type='trigger'" },
3014 { "number of views:",
3015 "SELECT count(*) FROM %s WHERE type='view'" },
3016 { "schema size:",
3017 "SELECT total(length(sql)) FROM %s" },
3018 };
mistachkinbfe8bd52015-11-17 19:17:14 +00003019 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00003020 int i;
3021 char *zSchemaTab;
3022 char *zDb = nArg>=2 ? azArg[1] : "main";
3023 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00003024 open_db(p, 0);
3025 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00003026 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00003027 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
3028 return 1;
3029 }
3030 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
3031 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003032 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00003033 return 1;
3034 }
3035 i = get2byteInt(aHdr+16);
3036 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00003037 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
3038 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
3039 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
3040 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00003041 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00003042 int ofst = aField[i].ofst;
3043 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00003044 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00003045 switch( ofst ){
3046 case 56: {
mistachkin1fe36bb2016-04-04 02:16:44 +00003047 if( val==1 ) raw_printf(p->out, " (utf8)");
3048 if( val==2 ) raw_printf(p->out, " (utf16le)");
3049 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00003050 }
3051 }
mistachkinaae280e2015-12-31 19:06:24 +00003052 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00003053 }
drh0e55db12015-02-06 14:51:13 +00003054 if( zDb==0 ){
3055 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
3056 }else if( strcmp(zDb,"temp")==0 ){
3057 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
3058 }else{
3059 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
3060 }
drhf5ed7ad2015-06-15 14:43:25 +00003061 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00003062 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
3063 int val = db_int(p, zSql);
3064 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00003065 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00003066 }
3067 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00003068 return 0;
3069}
3070
dand95bb392015-09-30 11:19:05 +00003071/*
3072** Print the current sqlite3_errmsg() value to stderr and return 1.
3073*/
3074static int shellDatabaseError(sqlite3 *db){
3075 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00003076 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00003077 return 1;
3078}
3079
3080/*
3081** Print an out-of-memory message to stderr and return 1.
3082*/
3083static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00003084 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00003085 return 1;
3086}
drhf7502f02015-02-06 14:19:44 +00003087
drh2db82112016-09-15 21:35:24 +00003088#ifdef SQLITE_DEBUG
3089/*
3090** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
3091** if they match and FALSE (0) if they do not match.
3092**
3093** Globbing rules:
3094**
3095** '*' Matches any sequence of zero or more characters.
3096**
3097** '?' Matches exactly one character.
3098**
3099** [...] Matches one character from the enclosed list of
3100** characters.
3101**
3102** [^...] Matches one character not in the enclosed list.
3103**
3104** '#' Matches any sequence of one or more digits with an
3105** optional + or - sign in front
3106**
3107** ' ' Any span of whitespace matches any other span of
3108** whitespace.
3109**
3110** Extra whitespace at the end of z[] is ignored.
3111*/
3112static int testcase_glob(const char *zGlob, const char *z){
3113 int c, c2;
3114 int invert;
3115 int seen;
3116
3117 while( (c = (*(zGlob++)))!=0 ){
3118 if( IsSpace(c) ){
3119 if( !IsSpace(*z) ) return 0;
3120 while( IsSpace(*zGlob) ) zGlob++;
3121 while( IsSpace(*z) ) z++;
3122 }else if( c=='*' ){
3123 while( (c=(*(zGlob++))) == '*' || c=='?' ){
3124 if( c=='?' && (*(z++))==0 ) return 0;
3125 }
3126 if( c==0 ){
3127 return 1;
3128 }else if( c=='[' ){
3129 while( *z && testcase_glob(zGlob-1,z)==0 ){
3130 z++;
3131 }
3132 return (*z)!=0;
3133 }
3134 while( (c2 = (*(z++)))!=0 ){
3135 while( c2!=c ){
3136 c2 = *(z++);
3137 if( c2==0 ) return 0;
3138 }
3139 if( testcase_glob(zGlob,z) ) return 1;
3140 }
3141 return 0;
3142 }else if( c=='?' ){
3143 if( (*(z++))==0 ) return 0;
3144 }else if( c=='[' ){
3145 int prior_c = 0;
3146 seen = 0;
3147 invert = 0;
3148 c = *(z++);
3149 if( c==0 ) return 0;
3150 c2 = *(zGlob++);
3151 if( c2=='^' ){
3152 invert = 1;
3153 c2 = *(zGlob++);
3154 }
3155 if( c2==']' ){
3156 if( c==']' ) seen = 1;
3157 c2 = *(zGlob++);
3158 }
3159 while( c2 && c2!=']' ){
3160 if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
3161 c2 = *(zGlob++);
3162 if( c>=prior_c && c<=c2 ) seen = 1;
3163 prior_c = 0;
3164 }else{
3165 if( c==c2 ){
3166 seen = 1;
3167 }
3168 prior_c = c2;
3169 }
3170 c2 = *(zGlob++);
3171 }
3172 if( c2==0 || (seen ^ invert)==0 ) return 0;
3173 }else if( c=='#' ){
3174 if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
3175 if( !IsDigit(z[0]) ) return 0;
3176 z++;
3177 while( IsDigit(z[0]) ){ z++; }
3178 }else{
3179 if( c!=(*(z++)) ) return 0;
3180 }
3181 }
3182 while( IsSpace(*z) ){ z++; }
3183 return *z==0;
3184}
3185#endif /* defined(SQLITE_DEBUG) */
3186
3187
drhf7502f02015-02-06 14:19:44 +00003188/*
drh4926fec2016-04-13 15:33:42 +00003189** Compare the string as a command-line option with either one or two
3190** initial "-" characters.
3191*/
3192static int optionMatch(const char *zStr, const char *zOpt){
3193 if( zStr[0]!='-' ) return 0;
3194 zStr++;
3195 if( zStr[0]=='-' ) zStr++;
3196 return strcmp(zStr, zOpt)==0;
3197}
3198
3199/*
drhcd0509e2016-09-16 00:26:08 +00003200** Delete a file.
3201*/
3202int shellDeleteFile(const char *zFilename){
3203 int rc;
3204#ifdef _WIN32
3205 wchar_t *z = sqlite3_utf8_to_path(zFilename, 0);
3206 rc = _wunlink(z);
3207 sqlite3_free(z);
3208#else
3209 rc = unlink(zFilename);
3210#endif
3211 return rc;
3212}
3213
3214/*
drh75897232000-05-29 14:26:00 +00003215** If an input line begins with "." then invoke this routine to
3216** process that line.
drh67505e72002-04-19 12:34:06 +00003217**
drh47ad6842006-11-08 12:25:42 +00003218** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00003219*/
drhdcd87a92014-08-18 13:45:42 +00003220static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00003221 int h = 1;
drh75897232000-05-29 14:26:00 +00003222 int nArg = 0;
3223 int n, c;
drh67505e72002-04-19 12:34:06 +00003224 int rc = 0;
drh75897232000-05-29 14:26:00 +00003225 char *azArg[50];
3226
3227 /* Parse the input line into tokens.
3228 */
mistachkin8e189222015-04-19 21:43:16 +00003229 while( zLine[h] && nArg<ArraySize(azArg) ){
3230 while( IsSpace(zLine[h]) ){ h++; }
3231 if( zLine[h]==0 ) break;
3232 if( zLine[h]=='\'' || zLine[h]=='"' ){
3233 int delim = zLine[h++];
3234 azArg[nArg++] = &zLine[h];
mistachkin1fe36bb2016-04-04 02:16:44 +00003235 while( zLine[h] && zLine[h]!=delim ){
mistachkin8e189222015-04-19 21:43:16 +00003236 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
mistachkin1fe36bb2016-04-04 02:16:44 +00003237 h++;
drh4c56b992013-06-27 13:26:55 +00003238 }
mistachkin8e189222015-04-19 21:43:16 +00003239 if( zLine[h]==delim ){
3240 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00003241 }
drhfeac5f82004-08-01 00:10:45 +00003242 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003243 }else{
mistachkin8e189222015-04-19 21:43:16 +00003244 azArg[nArg++] = &zLine[h];
3245 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
3246 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00003247 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003248 }
3249 }
3250
3251 /* Process the input line.
3252 */
shane9bd1b442009-10-23 01:27:39 +00003253 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00003254 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00003255 c = azArg[0][0];
drhde613c62016-04-04 17:23:10 +00003256
drha0daa752016-09-16 11:53:10 +00003257#ifndef SQLITE_OMIT_AUTHORIZATION
drhde613c62016-04-04 17:23:10 +00003258 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
3259 if( nArg!=2 ){
3260 raw_printf(stderr, "Usage: .auth ON|OFF\n");
3261 rc = 1;
3262 goto meta_command_exit;
3263 }
3264 open_db(p, 0);
3265 if( booleanValue(azArg[1]) ){
3266 sqlite3_set_authorizer(p->db, shellAuth, p);
3267 }else{
3268 sqlite3_set_authorizer(p->db, 0, 0);
3269 }
3270 }else
drha0daa752016-09-16 11:53:10 +00003271#endif
drhde613c62016-04-04 17:23:10 +00003272
drh5c7976f2014-02-10 19:59:27 +00003273 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
3274 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
3275 ){
drhbc46f022013-01-23 18:53:23 +00003276 const char *zDestFile = 0;
3277 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00003278 sqlite3 *pDest;
3279 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00003280 int j;
3281 for(j=1; j<nArg; j++){
3282 const char *z = azArg[j];
3283 if( z[0]=='-' ){
3284 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00003285 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00003286 {
mistachkinaae280e2015-12-31 19:06:24 +00003287 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00003288 return 1;
3289 }
3290 }else if( zDestFile==0 ){
3291 zDestFile = azArg[j];
3292 }else if( zDb==0 ){
3293 zDb = zDestFile;
3294 zDestFile = azArg[j];
3295 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003296 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00003297 return 1;
3298 }
drh9ff849f2009-02-04 20:55:57 +00003299 }
drhbc46f022013-01-23 18:53:23 +00003300 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003301 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00003302 return 1;
3303 }
3304 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00003305 rc = sqlite3_open(zDestFile, &pDest);
3306 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003307 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00003308 sqlite3_close(pDest);
3309 return 1;
3310 }
drh05782482013-10-24 15:20:20 +00003311 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003312 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
3313 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003314 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00003315 sqlite3_close(pDest);
3316 return 1;
3317 }
3318 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
3319 sqlite3_backup_finish(pBackup);
3320 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003321 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00003322 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003323 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00003324 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003325 }
3326 sqlite3_close(pDest);
3327 }else
3328
drhc2ce0be2014-05-29 12:36:14 +00003329 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
3330 if( nArg==2 ){
3331 bail_on_error = booleanValue(azArg[1]);
3332 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003333 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003334 rc = 1;
3335 }
drhc49f44e2006-10-26 18:15:42 +00003336 }else
3337
mistachkinf21979d2015-01-18 05:35:01 +00003338 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
3339 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00003340 if( booleanValue(azArg[1]) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003341 setBinaryMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003342 }else{
mistachkin1fe36bb2016-04-04 02:16:44 +00003343 setTextMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003344 }
mistachkinf21979d2015-01-18 05:35:01 +00003345 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003346 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00003347 rc = 1;
3348 }
3349 }else
3350
drhd8621b92012-04-17 09:09:33 +00003351 /* The undocumented ".breakpoint" command causes a call to the no-op
3352 ** routine named test_breakpoint().
3353 */
3354 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
3355 test_breakpoint();
3356 }else
3357
drhdf12f1c2015-12-07 21:46:19 +00003358 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
3359 if( nArg==2 ){
3360 p->countChanges = booleanValue(azArg[1]);
3361 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003362 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00003363 rc = 1;
3364 }
3365 }else
3366
drh2db82112016-09-15 21:35:24 +00003367 /* Cancel output redirection, if it is currently set (by .testcase)
3368 ** Then read the content of the testcase-out.txt file and compare against
3369 ** azArg[1]. If there are differences, report an error and exit.
3370 */
3371 if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
3372 char *zRes = 0;
3373 output_reset(p);
3374 if( nArg!=2 ){
3375 raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
drh760c8162016-09-16 02:52:22 +00003376 rc = 2;
drh2db82112016-09-15 21:35:24 +00003377 }else if( (zRes = readFile("testcase-out.txt"))==0 ){
3378 raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
3379 rc = 2;
3380 }else if( testcase_glob(azArg[1],zRes)==0 ){
drh760c8162016-09-16 02:52:22 +00003381 raw_printf(stderr,
3382 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
3383 p->zTestcase, azArg[1], zRes);
drh2db82112016-09-15 21:35:24 +00003384 rc = 2;
drh760c8162016-09-16 02:52:22 +00003385 }else{
3386 raw_printf(stdout, "testcase-%s ok\n", p->zTestcase);
3387 p->nCheck++;
drh2db82112016-09-15 21:35:24 +00003388 }
3389 sqlite3_free(zRes);
3390 }else
drh2db82112016-09-15 21:35:24 +00003391
drhc2ce0be2014-05-29 12:36:14 +00003392 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
3393 if( nArg==2 ){
3394 tryToClone(p, azArg[1]);
3395 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003396 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003397 rc = 1;
3398 }
mistachkine31ae902014-02-06 01:15:29 +00003399 }else
3400
drhc2ce0be2014-05-29 12:36:14 +00003401 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003402 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00003403 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003404 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00003405 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00003406 data.showHeader = 1;
drh700c2522016-02-09 18:39:25 +00003407 data.cMode = data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00003408 data.colWidth[0] = 3;
3409 data.colWidth[1] = 15;
3410 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00003411 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00003412 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00003413 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003414 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003415 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003416 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00003417 }
3418 }else
3419
drh0e55db12015-02-06 14:51:13 +00003420 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
3421 rc = shell_dbinfo_command(p, nArg, azArg);
3422 }else
3423
drhc2ce0be2014-05-29 12:36:14 +00003424 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00003425 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00003426 /* When playing back a "dump", the content might appear in an order
3427 ** which causes immediate foreign key constraints to be violated.
3428 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00003429 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003430 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003431 rc = 1;
3432 goto meta_command_exit;
3433 }
mistachkinaae280e2015-12-31 19:06:24 +00003434 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
3435 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00003436 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00003437 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00003438 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00003439 if( nArg==1 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003440 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003441 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003442 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00003443 );
mistachkin1fe36bb2016-04-04 02:16:44 +00003444 run_schema_dump_query(p,
drh4f324762009-05-21 14:51:03 +00003445 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003446 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00003447 );
drh2f464a02011-10-13 00:41:49 +00003448 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003449 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00003450 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00003451 );
drh4c653a02000-06-07 01:27:47 +00003452 }else{
3453 int i;
drhdd3d4592004-08-30 01:54:05 +00003454 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00003455 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00003456 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003457 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00003458 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00003459 " AND sql NOT NULL");
3460 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003461 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00003462 "WHERE sql NOT NULL"
3463 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00003464 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00003465 );
danielk1977bc6ada42004-06-30 08:20:16 +00003466 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00003467 }
3468 }
drh45e29d82006-11-20 16:21:10 +00003469 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00003470 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00003471 p->writableSchema = 0;
3472 }
drh56197952011-10-13 16:30:13 +00003473 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
3474 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00003475 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00003476 }else
drh75897232000-05-29 14:26:00 +00003477
drhc2ce0be2014-05-29 12:36:14 +00003478 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
3479 if( nArg==2 ){
3480 p->echoOn = booleanValue(azArg[1]);
3481 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003482 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003483 rc = 1;
3484 }
drhdaffd0e2001-04-11 14:28:42 +00003485 }else
3486
drhc2ce0be2014-05-29 12:36:14 +00003487 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
3488 if( nArg==2 ){
drheacd29d2016-04-15 15:03:27 +00003489 if( strcmp(azArg[1],"full")==0 ){
3490 p->autoEQP = 2;
3491 }else{
3492 p->autoEQP = booleanValue(azArg[1]);
3493 }
drhc2ce0be2014-05-29 12:36:14 +00003494 }else{
drheacd29d2016-04-15 15:03:27 +00003495 raw_printf(stderr, "Usage: .eqp on|off|full\n");
drhc2ce0be2014-05-29 12:36:14 +00003496 rc = 1;
mistachkin1fe36bb2016-04-04 02:16:44 +00003497 }
drhefbf3b12014-02-28 20:47:24 +00003498 }else
3499
drhd3ac7d92013-01-25 18:33:43 +00003500 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00003501 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00003502 rc = 2;
drh75897232000-05-29 14:26:00 +00003503 }else
3504
drhc2ce0be2014-05-29 12:36:14 +00003505 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00003506 int val = 1;
3507 if( nArg>=2 ){
3508 if( strcmp(azArg[1],"auto")==0 ){
3509 val = 99;
3510 }else{
3511 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003512 }
drh700c2522016-02-09 18:39:25 +00003513 }
3514 if( val==1 && p->mode!=MODE_Explain ){
3515 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003516 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003517 p->autoExplain = 0;
3518 }else if( val==0 ){
3519 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3520 p->autoExplain = 0;
3521 }else if( val==99 ){
3522 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3523 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003524 }
drh75897232000-05-29 14:26:00 +00003525 }else
3526
drhc1971542014-06-23 23:28:13 +00003527 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003528 ShellState data;
drhc1971542014-06-23 23:28:13 +00003529 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003530 int doStats = 0;
drh4926fec2016-04-13 15:33:42 +00003531 memcpy(&data, p, sizeof(data));
3532 data.showHeader = 0;
3533 data.cMode = data.mode = MODE_Semi;
3534 if( nArg==2 && optionMatch(azArg[1], "indent") ){
3535 data.cMode = data.mode = MODE_Pretty;
3536 nArg = 1;
3537 }
drhc1971542014-06-23 23:28:13 +00003538 if( nArg!=1 ){
drh4926fec2016-04-13 15:33:42 +00003539 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
drhc1971542014-06-23 23:28:13 +00003540 rc = 1;
3541 goto meta_command_exit;
3542 }
3543 open_db(p, 0);
drhc1971542014-06-23 23:28:13 +00003544 rc = sqlite3_exec(p->db,
3545 "SELECT sql FROM"
3546 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3547 " FROM sqlite_master UNION ALL"
3548 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003549 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003550 "ORDER BY rowid",
3551 callback, &data, &zErrMsg
3552 );
drh56f674c2014-07-18 14:43:29 +00003553 if( rc==SQLITE_OK ){
3554 sqlite3_stmt *pStmt;
3555 rc = sqlite3_prepare_v2(p->db,
3556 "SELECT rowid FROM sqlite_master"
3557 " WHERE name GLOB 'sqlite_stat[134]'",
3558 -1, &pStmt, 0);
3559 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3560 sqlite3_finalize(pStmt);
3561 }
3562 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003563 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003564 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003565 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003566 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3567 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003568 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003569 data.zDestTable = "sqlite_stat1";
3570 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3571 shell_callback, &data,&zErrMsg);
3572 data.zDestTable = "sqlite_stat3";
3573 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3574 shell_callback, &data,&zErrMsg);
3575 data.zDestTable = "sqlite_stat4";
3576 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3577 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003578 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003579 }
drhc1971542014-06-23 23:28:13 +00003580 }else
3581
drhc2ce0be2014-05-29 12:36:14 +00003582 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3583 if( nArg==2 ){
3584 p->showHeader = booleanValue(azArg[1]);
3585 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003586 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003587 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003588 }
drh75897232000-05-29 14:26:00 +00003589 }else
3590
drhc2ce0be2014-05-29 12:36:14 +00003591 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003592 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003593 }else
3594
3595 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003596 char *zTable; /* Insert data into this table */
3597 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003598 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003599 int nCol; /* Number of columns in the table */
3600 int nByte; /* Number of bytes in an SQL string */
3601 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003602 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003603 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003604 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003605 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003606 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3607 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003608
drhc2ce0be2014-05-29 12:36:14 +00003609 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003610 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003611 goto meta_command_exit;
3612 }
drh01f37542014-05-31 15:43:33 +00003613 zFile = azArg[1];
3614 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003615 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003616 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003617 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003618 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003619 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003620 raw_printf(stderr,
3621 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003622 return 1;
drhfeac5f82004-08-01 00:10:45 +00003623 }
drhdb95f682013-06-26 22:46:00 +00003624 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003625 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003626 " for import\n");
3627 return 1;
3628 }
mistachkin636bf9f2014-07-19 20:15:16 +00003629 nSep = strlen30(p->rowSeparator);
3630 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003631 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003632 return 1;
3633 }
mistachkine0d68852014-12-11 03:12:33 +00003634 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3635 /* When importing CSV (only), if the row separator is set to the
3636 ** default output row separator, change it to the default input
3637 ** row separator. This avoids having to maintain different input
3638 ** and output row separators. */
3639 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3640 nSep = strlen30(p->rowSeparator);
3641 }
mistachkin636bf9f2014-07-19 20:15:16 +00003642 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003643 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003644 " for import\n");
3645 return 1;
3646 }
3647 sCtx.zFile = zFile;
3648 sCtx.nLine = 1;
3649 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003650#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003651 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003652 return 1;
3653#else
mistachkin636bf9f2014-07-19 20:15:16 +00003654 sCtx.in = popen(sCtx.zFile+1, "r");
3655 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003656 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003657#endif
drh5bde8162013-06-27 14:07:53 +00003658 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003659 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003660 xCloser = fclose;
3661 }
mistachkin636bf9f2014-07-19 20:15:16 +00003662 if( p->mode==MODE_Ascii ){
3663 xRead = ascii_read_one_field;
3664 }else{
3665 xRead = csv_read_one_field;
3666 }
3667 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003668 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003669 return 1;
3670 }
mistachkin636bf9f2014-07-19 20:15:16 +00003671 sCtx.cColSep = p->colSeparator[0];
3672 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003673 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003674 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003675 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003676 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003677 return 1;
3678 }
drh4f21c4a2008-12-10 22:15:00 +00003679 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003680 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003681 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003682 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003683 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3684 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003685 while( xRead(&sCtx) ){
drhd8c22ac2016-02-25 13:33:02 +00003686 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003687 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003688 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003689 }
drh5bde8162013-06-27 14:07:53 +00003690 if( cSep=='(' ){
3691 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003692 sqlite3_free(sCtx.z);
3693 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003694 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003695 return 1;
3696 }
drhdb95f682013-06-26 22:46:00 +00003697 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3698 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3699 sqlite3_free(zCreate);
3700 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003701 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003702 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003703 sqlite3_free(sCtx.z);
3704 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003705 return 1;
3706 }
drhc7181902014-02-27 15:04:13 +00003707 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003708 }
drhfeac5f82004-08-01 00:10:45 +00003709 sqlite3_free(zSql);
3710 if( rc ){
shane916f9612009-10-23 00:37:15 +00003711 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00003712 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003713 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003714 return 1;
drhfeac5f82004-08-01 00:10:45 +00003715 }
shane916f9612009-10-23 00:37:15 +00003716 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003717 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003718 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003719 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003720 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003721 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003722 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003723 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003724 return 1;
3725 }
drhdb95f682013-06-26 22:46:00 +00003726 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003727 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003728 for(i=1; i<nCol; i++){
3729 zSql[j++] = ',';
3730 zSql[j++] = '?';
3731 }
3732 zSql[j++] = ')';
3733 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003734 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003735 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003736 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003737 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003738 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003739 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003740 return 1;
drhfeac5f82004-08-01 00:10:45 +00003741 }
mistachkin8e189222015-04-19 21:43:16 +00003742 needCommit = sqlite3_get_autocommit(p->db);
3743 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003744 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003745 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003746 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003747 char *z = xRead(&sCtx);
3748 /*
3749 ** Did we reach end-of-file before finding any columns?
3750 ** If so, stop instead of NULL filling the remaining columns.
3751 */
drhdb95f682013-06-26 22:46:00 +00003752 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003753 /*
3754 ** Did we reach end-of-file OR end-of-line before finding any
3755 ** columns in ASCII mode? If so, stop instead of NULL filling
3756 ** the remaining columns.
3757 */
3758 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003759 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003760 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00003761 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003762 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003763 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003764 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003765 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003766 }
drhfeac5f82004-08-01 00:10:45 +00003767 }
mistachkin636bf9f2014-07-19 20:15:16 +00003768 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003769 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003770 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003771 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003772 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00003773 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003774 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003775 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003776 }
drhdb95f682013-06-26 22:46:00 +00003777 if( i>=nCol ){
3778 sqlite3_step(pStmt);
3779 rc = sqlite3_reset(pStmt);
3780 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003781 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
3782 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003783 }
3784 }
mistachkin636bf9f2014-07-19 20:15:16 +00003785 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003786
mistachkin636bf9f2014-07-19 20:15:16 +00003787 xCloser(sCtx.in);
3788 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003789 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003790 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003791 }else
3792
drh0e55db12015-02-06 14:51:13 +00003793 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3794 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003795 ShellState data;
drh75897232000-05-29 14:26:00 +00003796 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003797 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003798 memcpy(&data, p, sizeof(data));
3799 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003800 data.cMode = data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003801 if( nArg==1 ){
3802 rc = sqlite3_exec(p->db,
3803 "SELECT name FROM sqlite_master "
3804 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3805 "UNION ALL "
3806 "SELECT name FROM sqlite_temp_master "
3807 "WHERE type='index' "
3808 "ORDER BY 1",
3809 callback, &data, &zErrMsg
3810 );
drhc2ce0be2014-05-29 12:36:14 +00003811 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003812 zShellStatic = azArg[1];
3813 rc = sqlite3_exec(p->db,
3814 "SELECT name FROM sqlite_master "
3815 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3816 "UNION ALL "
3817 "SELECT name FROM sqlite_temp_master "
3818 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3819 "ORDER BY 1",
3820 callback, &data, &zErrMsg
3821 );
3822 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003823 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003824 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003825 rc = 1;
3826 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003827 }
drh75897232000-05-29 14:26:00 +00003828 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003829 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003830 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003831 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003832 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003833 raw_printf(stderr,
3834 "Error: querying sqlite_master and sqlite_temp_master\n");
shane86f5bdb2009-10-24 02:00:07 +00003835 rc = 1;
drh75897232000-05-29 14:26:00 +00003836 }
3837 }else
3838
drhae5e4452007-05-03 17:18:36 +00003839#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003840 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003841 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003842 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3843 iotrace = 0;
3844 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003845 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003846 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003847 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003848 iotrace = stdout;
3849 }else{
3850 iotrace = fopen(azArg[1], "w");
3851 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003852 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003853 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003854 rc = 1;
drhb0603412007-02-28 04:47:26 +00003855 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003856 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003857 }
3858 }
3859 }else
drhae5e4452007-05-03 17:18:36 +00003860#endif
drh1a513372015-05-02 17:40:23 +00003861 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3862 static const struct {
3863 const char *zLimitName; /* Name of a limit */
3864 int limitCode; /* Integer code for that limit */
3865 } aLimit[] = {
3866 { "length", SQLITE_LIMIT_LENGTH },
3867 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3868 { "column", SQLITE_LIMIT_COLUMN },
3869 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3870 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3871 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3872 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3873 { "attached", SQLITE_LIMIT_ATTACHED },
3874 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3875 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3876 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3877 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3878 };
3879 int i, n2;
3880 open_db(p, 0);
3881 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003882 for(i=0; i<ArraySize(aLimit); i++){
mistachkin1fe36bb2016-04-04 02:16:44 +00003883 printf("%20s %d\n", aLimit[i].zLimitName,
drh1a513372015-05-02 17:40:23 +00003884 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3885 }
3886 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003887 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00003888 rc = 1;
3889 goto meta_command_exit;
3890 }else{
3891 int iLimit = -1;
3892 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003893 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003894 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3895 if( iLimit<0 ){
3896 iLimit = i;
3897 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003898 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00003899 rc = 1;
3900 goto meta_command_exit;
3901 }
3902 }
3903 }
3904 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003905 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00003906 "enter \".limits\" with no arguments for a list.\n",
3907 azArg[1]);
3908 rc = 1;
3909 goto meta_command_exit;
3910 }
3911 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003912 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3913 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003914 }
3915 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3916 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3917 }
3918 }else
drhb0603412007-02-28 04:47:26 +00003919
drh70df4fe2006-06-13 15:12:21 +00003920#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003921 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003922 const char *zFile, *zProc;
3923 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00003924 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003925 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00003926 rc = 1;
3927 goto meta_command_exit;
3928 }
drh1e397f82006-06-08 15:28:43 +00003929 zFile = azArg[1];
3930 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00003931 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00003932 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
3933 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003934 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00003935 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00003936 rc = 1;
drh1e397f82006-06-08 15:28:43 +00003937 }
3938 }else
drh70df4fe2006-06-13 15:12:21 +00003939#endif
drh1e397f82006-06-08 15:28:43 +00003940
drhc2ce0be2014-05-29 12:36:14 +00003941 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
3942 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003943 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003944 rc = 1;
3945 }else{
3946 const char *zFile = azArg[1];
3947 output_file_close(p->pLog);
3948 p->pLog = output_file_open(zFile);
3949 }
drh127f9d72010-02-23 01:47:00 +00003950 }else
3951
drhc2ce0be2014-05-29 12:36:14 +00003952 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
3953 const char *zMode = nArg>=2 ? azArg[1] : "";
3954 int n2 = (int)strlen(zMode);
3955 int c2 = zMode[0];
3956 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003957 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00003958 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003959 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00003960 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00003961 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00003962 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00003963 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00003964 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003965 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00003966 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00003967 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00003968 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00003969 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00003970 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00003971 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00003972 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00003973 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00003974 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00003975 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00003976 set_table_name(p, nArg>=3 ? azArg[2] : "table");
mistachkin636bf9f2014-07-19 20:15:16 +00003977 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
3978 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00003979 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
3980 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00003981 }else {
mistachkinaae280e2015-12-31 19:06:24 +00003982 raw_printf(stderr, "Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00003983 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00003984 rc = 1;
drh75897232000-05-29 14:26:00 +00003985 }
drh700c2522016-02-09 18:39:25 +00003986 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00003987 }else
3988
drhc2ce0be2014-05-29 12:36:14 +00003989 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
3990 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00003991 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
3992 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00003993 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003994 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00003995 rc = 1;
3996 }
3997 }else
3998
drh05782482013-10-24 15:20:20 +00003999 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
drhcd0509e2016-09-16 00:26:08 +00004000 char *zNewFilename; /* Name of the database file to open */
4001 int iName = 1; /* Index in azArg[] of the filename */
drh760c8162016-09-16 02:52:22 +00004002 int newFlag = 0; /* True to delete file before opening */
drhcd0509e2016-09-16 00:26:08 +00004003 /* Close the existing database */
4004 session_close_all(p);
4005 sqlite3_close(p->db);
drh05782482013-10-24 15:20:20 +00004006 p->db = 0;
drhcd0509e2016-09-16 00:26:08 +00004007 sqlite3_free(p->zFreeOnClose);
4008 p->zFreeOnClose = 0;
drh760c8162016-09-16 02:52:22 +00004009 /* Check for command-line arguments */
4010 for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
4011 const char *z = azArg[iName];
4012 if( optionMatch(z,"new") ){
4013 newFlag = 1;
4014 }else if( z[0]=='-' ){
4015 utf8_printf(stderr, "unknown option: %s\n", z);
4016 rc = 1;
4017 }
drhcd0509e2016-09-16 00:26:08 +00004018 }
4019 /* If a filename is specified, try to open it first */
4020 zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
4021 if( zNewFilename ){
drh760c8162016-09-16 02:52:22 +00004022 if( newFlag ) shellDeleteFile(zNewFilename);
drhcd0509e2016-09-16 00:26:08 +00004023 p->zDbFilename = zNewFilename;
4024 open_db(p, 1);
4025 if( p->db==0 ){
4026 utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
4027 sqlite3_free(zNewFilename);
4028 }else{
4029 p->zFreeOnClose = zNewFilename;
4030 }
4031 }
4032 if( p->db==0 ){
4033 /* As a fall-back open a TEMP database */
4034 p->zDbFilename = 0;
4035 open_db(p, 0);
drh05782482013-10-24 15:20:20 +00004036 }
4037 }else
4038
drhc2ce0be2014-05-29 12:36:14 +00004039 if( c=='o'
4040 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
4041 ){
4042 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
4043 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004044 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00004045 rc = 1;
4046 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004047 }
drhc2ce0be2014-05-29 12:36:14 +00004048 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
4049 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004050 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004051 rc = 1;
4052 goto meta_command_exit;
4053 }
4054 p->outCount = 2;
4055 }else{
4056 p->outCount = 0;
4057 }
4058 output_reset(p);
4059 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00004060#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00004061 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00004062 rc = 1;
4063 p->out = stdout;
4064#else
drhc2ce0be2014-05-29 12:36:14 +00004065 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00004066 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004067 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00004068 p->out = stdout;
4069 rc = 1;
4070 }else{
drhc2ce0be2014-05-29 12:36:14 +00004071 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00004072 }
drh8cd5b252015-03-02 22:06:43 +00004073#endif
drh75897232000-05-29 14:26:00 +00004074 }else{
drhc2ce0be2014-05-29 12:36:14 +00004075 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00004076 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004077 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004078 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00004079 }
drh75897232000-05-29 14:26:00 +00004080 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00004081 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00004082 } else {
drhc2ce0be2014-05-29 12:36:14 +00004083 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00004084 }
4085 }
4086 }else
4087
drh078b1fd2012-09-21 13:40:02 +00004088 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
4089 int i;
4090 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00004091 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00004092 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00004093 }
mistachkinaae280e2015-12-31 19:06:24 +00004094 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00004095 }else
4096
drhc2ce0be2014-05-29 12:36:14 +00004097 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00004098 if( nArg >= 2) {
4099 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
4100 }
4101 if( nArg >= 3) {
4102 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
4103 }
4104 }else
4105
drhc2ce0be2014-05-29 12:36:14 +00004106 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00004107 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00004108 }else
4109
drhc2ce0be2014-05-29 12:36:14 +00004110 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
4111 FILE *alt;
4112 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004113 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004114 rc = 1;
4115 goto meta_command_exit;
4116 }
4117 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00004118 if( alt==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004119 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
shane9bd1b442009-10-23 01:27:39 +00004120 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00004121 }else{
shane9bd1b442009-10-23 01:27:39 +00004122 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00004123 fclose(alt);
4124 }
4125 }else
4126
drhc2ce0be2014-05-29 12:36:14 +00004127 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00004128 const char *zSrcFile;
4129 const char *zDb;
4130 sqlite3 *pSrc;
4131 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00004132 int nTimeout = 0;
4133
drh9ff849f2009-02-04 20:55:57 +00004134 if( nArg==2 ){
4135 zSrcFile = azArg[1];
4136 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00004137 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00004138 zSrcFile = azArg[2];
4139 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00004140 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004141 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004142 rc = 1;
4143 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00004144 }
4145 rc = sqlite3_open(zSrcFile, &pSrc);
4146 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004147 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00004148 sqlite3_close(pSrc);
4149 return 1;
4150 }
drh05782482013-10-24 15:20:20 +00004151 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00004152 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
4153 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004154 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00004155 sqlite3_close(pSrc);
4156 return 1;
4157 }
drhdc2c4912009-02-04 22:46:47 +00004158 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
4159 || rc==SQLITE_BUSY ){
4160 if( rc==SQLITE_BUSY ){
4161 if( nTimeout++ >= 3 ) break;
4162 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00004163 }
4164 }
4165 sqlite3_backup_finish(pBackup);
4166 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00004167 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00004168 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00004169 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00004170 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004171 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004172 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00004173 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004174 }
4175 sqlite3_close(pSrc);
4176 }else
4177
dan8d1edb92014-11-05 09:07:28 +00004178
4179 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
4180 if( nArg==2 ){
4181 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00004182#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00004183 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00004184#endif
dan8d1edb92014-11-05 09:07:28 +00004185 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004186 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00004187 rc = 1;
4188 }
4189 }else
4190
drhc2ce0be2014-05-29 12:36:14 +00004191 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00004192 ShellState data;
drh75897232000-05-29 14:26:00 +00004193 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00004194 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00004195 memcpy(&data, p, sizeof(data));
4196 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00004197 data.cMode = data.mode = MODE_Semi;
drh4926fec2016-04-13 15:33:42 +00004198 if( nArg>=2 && optionMatch(azArg[1], "indent") ){
4199 data.cMode = data.mode = MODE_Pretty;
4200 nArg--;
4201 if( nArg==2 ) azArg[1] = azArg[2];
4202 }
4203 if( nArg==2 && azArg[1][0]!='-' ){
drhc8d74412004-08-31 23:41:26 +00004204 int i;
drhf0693c82011-10-11 20:41:54 +00004205 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00004206 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00004207 char *new_argv[2], *new_colv[2];
4208 new_argv[0] = "CREATE TABLE sqlite_master (\n"
4209 " type text,\n"
4210 " name text,\n"
4211 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00004212 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00004213 " sql text\n"
4214 ")";
4215 new_argv[1] = 0;
4216 new_colv[0] = "sql";
4217 new_colv[1] = 0;
4218 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004219 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00004220 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00004221 char *new_argv[2], *new_colv[2];
4222 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
4223 " type text,\n"
4224 " name text,\n"
4225 " tbl_name text,\n"
4226 " rootpage integer,\n"
4227 " sql text\n"
4228 ")";
4229 new_argv[1] = 0;
4230 new_colv[0] = "sql";
4231 new_colv[1] = 0;
4232 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004233 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00004234 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00004235 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00004236 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004237 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004238 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004239 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004240 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00004241 "WHERE lower(tbl_name) LIKE shellstatic()"
4242 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00004243 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00004244 callback, &data, &zErrMsg);
4245 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00004246 }
drhc2ce0be2014-05-29 12:36:14 +00004247 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00004248 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004249 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004250 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004251 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004252 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00004253 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00004254 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00004255 callback, &data, &zErrMsg
4256 );
drhc2ce0be2014-05-29 12:36:14 +00004257 }else{
drh4926fec2016-04-13 15:33:42 +00004258 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00004259 rc = 1;
4260 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004261 }
drh75897232000-05-29 14:26:00 +00004262 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00004263 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004264 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00004265 rc = 1;
4266 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004267 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00004268 rc = 1;
4269 }else{
4270 rc = 0;
drh75897232000-05-29 14:26:00 +00004271 }
4272 }else
4273
drhabd4c722014-09-20 18:18:33 +00004274#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
4275 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
drh1d9be4f2015-01-22 11:29:25 +00004276 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00004277 }else
4278#endif
4279
drhe6229612014-08-18 15:08:26 +00004280#if defined(SQLITE_ENABLE_SESSION)
4281 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
4282 OpenSession *pSession = &p->aSession[0];
4283 char **azCmd = &azArg[1];
4284 int iSes = 0;
4285 int nCmd = nArg - 1;
4286 int i;
4287 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00004288 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00004289 if( nArg>=3 ){
4290 for(iSes=0; iSes<p->nSession; iSes++){
4291 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
4292 }
4293 if( iSes<p->nSession ){
4294 pSession = &p->aSession[iSes];
4295 azCmd++;
4296 nCmd--;
4297 }else{
4298 pSession = &p->aSession[0];
4299 iSes = 0;
4300 }
4301 }
4302
drh3a67b042014-08-18 17:56:31 +00004303 /* .session attach TABLE
4304 ** Invoke the sqlite3session_attach() interface to attach a particular
4305 ** table so that it is never filtered.
4306 */
4307 if( strcmp(azCmd[0],"attach")==0 ){
4308 if( nCmd!=2 ) goto session_syntax_error;
4309 if( pSession->p==0 ){
4310 session_not_open:
mistachkin899c5c92016-04-03 20:50:02 +00004311 raw_printf(stderr, "ERROR: No sessions are open\n");
drh3a67b042014-08-18 17:56:31 +00004312 }else{
4313 rc = sqlite3session_attach(pSession->p, azCmd[1]);
4314 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004315 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004316 rc = 0;
4317 }
4318 }
4319 }else
4320
4321 /* .session changeset FILE
4322 ** .session patchset FILE
4323 ** Write a changeset or patchset into a file. The file is overwritten.
4324 */
4325 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
4326 FILE *out = 0;
4327 if( nCmd!=2 ) goto session_syntax_error;
4328 if( pSession->p==0 ) goto session_not_open;
4329 out = fopen(azCmd[1], "wb");
4330 if( out==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004331 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
drh3a67b042014-08-18 17:56:31 +00004332 }else{
4333 int szChng;
4334 void *pChng;
4335 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00004336 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00004337 }else{
drh2967e0c2014-08-19 00:26:17 +00004338 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
4339 }
4340 if( rc ){
4341 printf("Error: error code %d\n", rc);
4342 rc = 0;
drh3a67b042014-08-18 17:56:31 +00004343 }
mistachkin1fe36bb2016-04-04 02:16:44 +00004344 if( pChng
drh3a67b042014-08-18 17:56:31 +00004345 && fwrite(pChng, szChng, 1, out)!=1 ){
mistachkin899c5c92016-04-03 20:50:02 +00004346 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
drh3a67b042014-08-18 17:56:31 +00004347 szChng);
4348 }
4349 sqlite3_free(pChng);
4350 fclose(out);
4351 }
4352 }else
4353
drhe6229612014-08-18 15:08:26 +00004354 /* .session close
4355 ** Close the identified session
4356 */
4357 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00004358 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00004359 if( p->nSession ){
4360 session_close(pSession);
4361 p->aSession[iSes] = p->aSession[--p->nSession];
4362 }
4363 }else
4364
drh03168ca2014-08-18 20:01:31 +00004365 /* .session enable ?BOOLEAN?
4366 ** Query or set the enable flag
4367 */
4368 if( strcmp(azCmd[0], "enable")==0 ){
4369 int ii;
4370 if( nCmd>2 ) goto session_syntax_error;
4371 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4372 if( p->nSession ){
4373 ii = sqlite3session_enable(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004374 utf8_printf(p->out, "session %s enable flag = %d\n",
4375 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004376 }
4377 }else
4378
4379 /* .session filter GLOB ....
4380 ** Set a list of GLOB patterns of table names to be excluded.
4381 */
4382 if( strcmp(azCmd[0], "filter")==0 ){
4383 int ii, nByte;
4384 if( nCmd<2 ) goto session_syntax_error;
4385 if( p->nSession ){
4386 for(ii=0; ii<pSession->nFilter; ii++){
4387 sqlite3_free(pSession->azFilter[ii]);
4388 }
4389 sqlite3_free(pSession->azFilter);
4390 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
4391 pSession->azFilter = sqlite3_malloc( nByte );
4392 if( pSession->azFilter==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004393 raw_printf(stderr, "Error: out or memory\n");
drh03168ca2014-08-18 20:01:31 +00004394 exit(1);
4395 }
4396 for(ii=1; ii<nCmd; ii++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004397 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
drh03168ca2014-08-18 20:01:31 +00004398 }
4399 pSession->nFilter = ii-1;
4400 }
4401 }else
4402
4403 /* .session indirect ?BOOLEAN?
4404 ** Query or set the indirect flag
4405 */
4406 if( strcmp(azCmd[0], "indirect")==0 ){
4407 int ii;
4408 if( nCmd>2 ) goto session_syntax_error;
4409 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4410 if( p->nSession ){
4411 ii = sqlite3session_indirect(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004412 utf8_printf(p->out, "session %s indirect flag = %d\n",
4413 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004414 }
4415 }else
4416
4417 /* .session isempty
4418 ** Determine if the session is empty
4419 */
4420 if( strcmp(azCmd[0], "isempty")==0 ){
4421 int ii;
4422 if( nCmd!=1 ) goto session_syntax_error;
4423 if( p->nSession ){
4424 ii = sqlite3session_isempty(pSession->p);
mistachkin899c5c92016-04-03 20:50:02 +00004425 utf8_printf(p->out, "session %s isempty flag = %d\n",
4426 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004427 }
4428 }else
4429
drhe6229612014-08-18 15:08:26 +00004430 /* .session list
4431 ** List all currently open sessions
4432 */
4433 if( strcmp(azCmd[0],"list")==0 ){
4434 for(i=0; i<p->nSession; i++){
mistachkin899c5c92016-04-03 20:50:02 +00004435 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
drhe6229612014-08-18 15:08:26 +00004436 }
4437 }else
4438
4439 /* .session open DB NAME
4440 ** Open a new session called NAME on the attached database DB.
4441 ** DB is normally "main".
4442 */
4443 if( strcmp(azCmd[0],"open")==0 ){
4444 char *zName;
4445 if( nCmd!=3 ) goto session_syntax_error;
4446 zName = azCmd[2];
4447 if( zName[0]==0 ) goto session_syntax_error;
4448 for(i=0; i<p->nSession; i++){
4449 if( strcmp(p->aSession[i].zName,zName)==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004450 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
drhe6229612014-08-18 15:08:26 +00004451 goto meta_command_exit;
4452 }
4453 }
4454 if( p->nSession>=ArraySize(p->aSession) ){
mistachkin899c5c92016-04-03 20:50:02 +00004455 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
drhe6229612014-08-18 15:08:26 +00004456 goto meta_command_exit;
4457 }
4458 pSession = &p->aSession[p->nSession];
4459 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
4460 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004461 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004462 rc = 0;
drhe6229612014-08-18 15:08:26 +00004463 goto meta_command_exit;
4464 }
drh03168ca2014-08-18 20:01:31 +00004465 pSession->nFilter = 0;
4466 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00004467 p->nSession++;
4468 pSession->zName = sqlite3_mprintf("%s", zName);
4469 }else
4470 /* If no command name matches, show a syntax error */
4471 session_syntax_error:
4472 session_help(p);
4473 }else
4474#endif
4475
drh340f5822013-06-27 13:01:21 +00004476#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00004477 /* Undocumented commands for internal testing. Subject to change
4478 ** without notice. */
4479 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
4480 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
4481 int i, v;
4482 for(i=1; i<nArg; i++){
4483 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00004484 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00004485 }
4486 }
4487 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
4488 int i; sqlite3_int64 v;
4489 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00004490 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00004491 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00004492 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00004493 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00004494 }
4495 }
4496 }else
drh340f5822013-06-27 13:01:21 +00004497#endif
drh348d19c2013-06-03 12:47:43 +00004498
drhc2ce0be2014-05-29 12:36:14 +00004499 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00004500 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004501 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00004502 rc = 1;
4503 }
drh6976c212014-07-24 12:09:47 +00004504 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004505 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00004506 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00004507 }
4508 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00004509 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
4510 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00004511 }
drh75897232000-05-29 14:26:00 +00004512 }else
4513
drh62cdde52014-05-28 20:22:28 +00004514 if( c=='s'
4515 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00004516 ){
4517 char *zCmd;
drh54027102014-08-06 14:36:53 +00004518 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00004519 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004520 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00004521 rc = 1;
4522 goto meta_command_exit;
4523 }
drhdcb3e3d2014-05-29 03:17:29 +00004524 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00004525 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00004526 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
4527 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00004528 }
drh54027102014-08-06 14:36:53 +00004529 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00004530 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00004531 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00004532 }else
4533
drhc2ce0be2014-05-29 12:36:14 +00004534 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drheacd29d2016-04-15 15:03:27 +00004535 static const char *azBool[] = { "off", "on", "full", "unk" };
persicom7e2dfdd2002-04-18 02:46:52 +00004536 int i;
drhc2ce0be2014-05-29 12:36:14 +00004537 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00004538 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00004539 rc = 1;
4540 goto meta_command_exit;
4541 }
drheacd29d2016-04-15 15:03:27 +00004542 utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]);
4543 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
drh700c2522016-02-09 18:39:25 +00004544 utf8_printf(p->out, "%12.12s: %s\n","explain",
4545 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
drheacd29d2016-04-15 15:03:27 +00004546 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004547 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
4548 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00004549 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00004550 raw_printf(p->out, "\n");
4551 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00004552 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00004553 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004554 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004555 raw_printf(p->out, "\n");
4556 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004557 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004558 raw_printf(p->out, "\n");
drheacd29d2016-04-15 15:03:27 +00004559 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004560 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00004561 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00004562 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00004563 }
mistachkinaae280e2015-12-31 19:06:24 +00004564 raw_printf(p->out, "\n");
drhcd0509e2016-09-16 00:26:08 +00004565 utf8_printf(p->out, "%12.12s: %s\n", "filename",
4566 p->zDbFilename ? p->zDbFilename : "");
persicom7e2dfdd2002-04-18 02:46:52 +00004567 }else
4568
drhc2ce0be2014-05-29 12:36:14 +00004569 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
4570 if( nArg==2 ){
4571 p->statsOn = booleanValue(azArg[1]);
drh34784902016-02-27 17:12:36 +00004572 }else if( nArg==1 ){
4573 display_stats(p->db, p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004574 }else{
drh34784902016-02-27 17:12:36 +00004575 raw_printf(stderr, "Usage: .stats ?on|off?\n");
drhc2ce0be2014-05-29 12:36:14 +00004576 rc = 1;
4577 }
shaneh642d8b82010-07-28 16:05:34 +00004578 }else
4579
drhc2ce0be2014-05-29 12:36:14 +00004580 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00004581 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00004582 char **azResult;
drh98781232012-04-23 12:38:05 +00004583 int nRow, nAlloc;
4584 char *zSql = 0;
4585 int ii;
drh05782482013-10-24 15:20:20 +00004586 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00004587 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00004588 if( rc ) return shellDatabaseError(p->db);
4589
4590 /* Create an SQL statement to query for the list of tables in the
4591 ** main and all attached databases where the table name matches the
4592 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00004593 zSql = sqlite3_mprintf(
4594 "SELECT name FROM sqlite_master"
4595 " WHERE type IN ('table','view')"
4596 " AND name NOT LIKE 'sqlite_%%'"
4597 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00004598 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00004599 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
4600 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
4601 if( strcmp(zDbName,"temp")==0 ){
4602 zSql = sqlite3_mprintf(
4603 "%z UNION ALL "
4604 "SELECT 'temp.' || name FROM sqlite_temp_master"
4605 " WHERE type IN ('table','view')"
4606 " AND name NOT LIKE 'sqlite_%%'"
4607 " AND name LIKE ?1", zSql);
4608 }else{
4609 zSql = sqlite3_mprintf(
4610 "%z UNION ALL "
4611 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4612 " WHERE type IN ('table','view')"
4613 " AND name NOT LIKE 'sqlite_%%'"
4614 " AND name LIKE ?1", zSql, zDbName, zDbName);
4615 }
drha50da102000-08-08 20:19:09 +00004616 }
dand95bb392015-09-30 11:19:05 +00004617 rc = sqlite3_finalize(pStmt);
4618 if( zSql && rc==SQLITE_OK ){
4619 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
4620 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4621 }
drh98781232012-04-23 12:38:05 +00004622 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00004623 if( !zSql ) return shellNomemError();
4624 if( rc ) return shellDatabaseError(p->db);
4625
4626 /* Run the SQL statement prepared by the above block. Store the results
4627 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00004628 nRow = nAlloc = 0;
4629 azResult = 0;
4630 if( nArg>1 ){
4631 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00004632 }else{
drh98781232012-04-23 12:38:05 +00004633 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
4634 }
4635 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4636 if( nRow>=nAlloc ){
4637 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00004638 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00004639 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00004640 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00004641 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00004642 break;
4643 }
mistachkin8e189222015-04-19 21:43:16 +00004644 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00004645 azResult = azNew;
4646 }
4647 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00004648 if( 0==azResult[nRow] ){
4649 rc = shellNomemError();
4650 break;
4651 }
4652 nRow++;
drh98781232012-04-23 12:38:05 +00004653 }
dand95bb392015-09-30 11:19:05 +00004654 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
4655 rc = shellDatabaseError(p->db);
4656 }
4657
4658 /* Pretty-print the contents of array azResult[] to the output */
4659 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00004660 int len, maxlen = 0;
4661 int i, j;
4662 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00004663 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00004664 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00004665 if( len>maxlen ) maxlen = len;
4666 }
4667 nPrintCol = 80/(maxlen+2);
4668 if( nPrintCol<1 ) nPrintCol = 1;
4669 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
4670 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00004671 for(j=i; j<nRow; j+=nPrintRow){
4672 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00004673 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
4674 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00004675 }
mistachkinaae280e2015-12-31 19:06:24 +00004676 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00004677 }
4678 }
dand95bb392015-09-30 11:19:05 +00004679
drh98781232012-04-23 12:38:05 +00004680 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
4681 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00004682 }else
4683
drh2db82112016-09-15 21:35:24 +00004684 /* Begin redirecting output to the file "testcase-out.txt" */
4685 if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
4686 output_reset(p);
4687 p->out = output_file_open("testcase-out.txt");
4688 if( p->out==0 ){
4689 utf8_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
4690 }
drh760c8162016-09-16 02:52:22 +00004691 if( nArg>=2 ){
4692 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
4693 }else{
4694 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
4695 }
drh2db82112016-09-15 21:35:24 +00004696 }else
drh2db82112016-09-15 21:35:24 +00004697
shaneh96887e12011-02-10 21:08:58 +00004698 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00004699 static const struct {
4700 const char *zCtrlName; /* Name of a test-control option */
4701 int ctrlCode; /* Integer code for that option */
4702 } aCtrl[] = {
4703 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
4704 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
4705 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
4706 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
4707 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
4708 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
4709 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
4710 { "assert", SQLITE_TESTCTRL_ASSERT },
4711 { "always", SQLITE_TESTCTRL_ALWAYS },
4712 { "reserve", SQLITE_TESTCTRL_RESERVE },
4713 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
4714 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00004715 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00004716 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00004717 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00004718 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00004719 };
shaneh96887e12011-02-10 21:08:58 +00004720 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00004721 int rc2 = 0;
4722 int i, n2;
drh05782482013-10-24 15:20:20 +00004723 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00004724
drhd416fe72011-03-17 16:45:50 +00004725 /* convert testctrl text option to value. allow any unique prefix
4726 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00004727 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00004728 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00004729 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00004730 if( testctrl<0 ){
4731 testctrl = aCtrl[i].ctrlCode;
4732 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004733 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00004734 testctrl = -1;
4735 break;
4736 }
4737 }
4738 }
drh348d19c2013-06-03 12:47:43 +00004739 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004740 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00004741 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004742 }else{
4743 switch(testctrl){
4744
4745 /* sqlite3_test_control(int, db, int) */
4746 case SQLITE_TESTCTRL_OPTIMIZATIONS:
mistachkin1fe36bb2016-04-04 02:16:44 +00004747 case SQLITE_TESTCTRL_RESERVE:
shaneh96887e12011-02-10 21:08:58 +00004748 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004749 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00004750 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004751 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004752 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004753 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004754 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004755 }
4756 break;
4757
4758 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004759 case SQLITE_TESTCTRL_PRNG_SAVE:
4760 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004761 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004762 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004763 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00004764 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00004765 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004766 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004767 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
4768 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004769 }
4770 break;
4771
4772 /* sqlite3_test_control(int, uint) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004773 case SQLITE_TESTCTRL_PENDING_BYTE:
shaneh96887e12011-02-10 21:08:58 +00004774 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004775 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004776 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004777 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004778 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004779 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00004780 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004781 }
4782 break;
mistachkin1fe36bb2016-04-04 02:16:44 +00004783
shaneh96887e12011-02-10 21:08:58 +00004784 /* sqlite3_test_control(int, int) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004785 case SQLITE_TESTCTRL_ASSERT:
4786 case SQLITE_TESTCTRL_ALWAYS:
4787 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004788 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004789 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004790 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004791 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004792 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004793 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004794 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004795 }
4796 break;
4797
4798 /* sqlite3_test_control(int, char *) */
4799#ifdef SQLITE_N_KEYWORD
mistachkin1fe36bb2016-04-04 02:16:44 +00004800 case SQLITE_TESTCTRL_ISKEYWORD:
shaneh96887e12011-02-10 21:08:58 +00004801 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004802 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004803 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004804 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004805 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004806 utf8_printf(stderr,
4807 "Error: testctrl %s takes a single char * option\n",
4808 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004809 }
4810 break;
4811#endif
4812
drh1ffede82015-01-30 20:59:27 +00004813 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004814 if( nArg==5 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004815 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004816 azArg[2],
drh8964b342015-01-29 17:54:52 +00004817 integerValue(azArg[3]),
4818 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00004819 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004820 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004821 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004822 }
4823 break;
4824
mistachkin1fe36bb2016-04-04 02:16:44 +00004825 case SQLITE_TESTCTRL_BITVEC_TEST:
4826 case SQLITE_TESTCTRL_FAULT_INSTALL:
4827 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4828 case SQLITE_TESTCTRL_SCRATCHMALLOC:
shaneh96887e12011-02-10 21:08:58 +00004829 default:
mistachkinaae280e2015-12-31 19:06:24 +00004830 utf8_printf(stderr,
4831 "Error: CLI support for testctrl %s not implemented\n",
4832 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004833 break;
4834 }
4835 }
4836 }else
4837
drhc2ce0be2014-05-29 12:36:14 +00004838 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004839 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004840 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004841 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004842
drhc2ce0be2014-05-29 12:36:14 +00004843 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4844 if( nArg==2 ){
4845 enableTimer = booleanValue(azArg[1]);
4846 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00004847 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00004848 enableTimer = 0;
4849 }
4850 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004851 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004852 rc = 1;
4853 }
shanehe2aa9d72009-11-06 17:20:17 +00004854 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004855
drhc2ce0be2014-05-29 12:36:14 +00004856 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004857 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004858 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004859 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004860 rc = 1;
4861 goto meta_command_exit;
4862 }
drh657b4a82015-03-19 13:30:41 +00004863 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004864 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004865#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004866 if( p->traceOut==0 ){
drh4b363a52016-07-23 20:27:41 +00004867 sqlite3_trace_v2(p->db, 0, 0, 0);
drh42f64e52012-04-04 16:56:23 +00004868 }else{
drh4b363a52016-07-23 20:27:41 +00004869 sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004870 }
4871#endif
4872 }else
4873
drhf442e332014-09-10 19:01:14 +00004874#if SQLITE_USER_AUTHENTICATION
4875 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4876 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004877 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00004878 rc = 1;
4879 goto meta_command_exit;
4880 }
drh7883ecf2014-09-11 16:19:31 +00004881 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004882 if( strcmp(azArg[1],"login")==0 ){
4883 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00004884 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00004885 rc = 1;
4886 goto meta_command_exit;
4887 }
drhd39c40f2014-09-11 00:27:53 +00004888 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4889 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004890 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004891 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00004892 rc = 1;
4893 }
4894 }else if( strcmp(azArg[1],"add")==0 ){
4895 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004896 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004897 rc = 1;
4898 goto meta_command_exit;
4899 }
drhd39c40f2014-09-11 00:27:53 +00004900 rc = sqlite3_user_add(p->db, azArg[2],
4901 azArg[3], (int)strlen(azArg[3]),
4902 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004903 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004904 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004905 rc = 1;
4906 }
4907 }else if( strcmp(azArg[1],"edit")==0 ){
4908 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004909 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004910 rc = 1;
4911 goto meta_command_exit;
4912 }
drhd39c40f2014-09-11 00:27:53 +00004913 rc = sqlite3_user_change(p->db, azArg[2],
4914 azArg[3], (int)strlen(azArg[3]),
4915 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004916 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004917 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004918 rc = 1;
4919 }
4920 }else if( strcmp(azArg[1],"delete")==0 ){
4921 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004922 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00004923 rc = 1;
4924 goto meta_command_exit;
4925 }
4926 rc = sqlite3_user_delete(p->db, azArg[2]);
4927 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004928 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004929 rc = 1;
4930 }
4931 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004932 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00004933 rc = 1;
4934 goto meta_command_exit;
mistachkin1fe36bb2016-04-04 02:16:44 +00004935 }
drhf442e332014-09-10 19:01:14 +00004936 }else
4937#endif /* SQLITE_USER_AUTHENTICATION */
4938
drh9fd301b2011-06-03 13:28:22 +00004939 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004940 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00004941 sqlite3_libversion(), sqlite3_sourceid());
4942 }else
4943
drh790f2872015-11-28 18:06:36 +00004944 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
4945 const char *zDbName = nArg==2 ? azArg[1] : "main";
4946 sqlite3_vfs *pVfs;
4947 if( p->db ){
4948 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
4949 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00004950 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
4951 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4952 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4953 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00004954 }
4955 }
4956 }else
4957
drhb19e7352016-01-12 19:37:20 +00004958 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
4959 sqlite3_vfs *pVfs;
4960 sqlite3_vfs *pCurrent = 0;
4961 if( p->db ){
4962 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
4963 }
4964 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
4965 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
4966 pVfs==pCurrent ? " <--- CURRENT" : "");
4967 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
4968 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
4969 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
4970 if( pVfs->pNext ){
4971 raw_printf(p->out, "-----------------------------------\n");
4972 }
4973 }
4974 }else
4975
drhde60fc22011-12-14 17:53:36 +00004976 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
4977 const char *zDbName = nArg==2 ? azArg[1] : "main";
4978 char *zVfsName = 0;
4979 if( p->db ){
4980 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
4981 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00004982 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00004983 sqlite3_free(zVfsName);
4984 }
4985 }
4986 }else
4987
drhcef4fc82012-09-21 22:50:45 +00004988#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
4989 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004990 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00004991 }else
4992#endif
4993
drhc2ce0be2014-05-29 12:36:14 +00004994 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00004995 int j;
drh43617e92006-03-06 20:55:46 +00004996 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00004997 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00004998 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00004999 }
5000 }else
5001
5002 {
mistachkinaae280e2015-12-31 19:06:24 +00005003 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00005004 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00005005 rc = 1;
drh75897232000-05-29 14:26:00 +00005006 }
drh67505e72002-04-19 12:34:06 +00005007
drhc2ce0be2014-05-29 12:36:14 +00005008meta_command_exit:
5009 if( p->outCount ){
5010 p->outCount--;
5011 if( p->outCount==0 ) output_reset(p);
5012 }
drh67505e72002-04-19 12:34:06 +00005013 return rc;
drh75897232000-05-29 14:26:00 +00005014}
5015
drh67505e72002-04-19 12:34:06 +00005016/*
drh91a66392007-09-07 01:12:32 +00005017** Return TRUE if a semicolon occurs anywhere in the first N characters
5018** of string z[].
drh324ccef2003-02-05 14:06:20 +00005019*/
drh9f099fd2013-08-06 14:01:46 +00005020static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00005021 int i;
5022 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
5023 return 0;
drh324ccef2003-02-05 14:06:20 +00005024}
5025
5026/*
drh70c7a4b2003-04-26 03:03:06 +00005027** Test to see if a line consists entirely of whitespace.
5028*/
5029static int _all_whitespace(const char *z){
5030 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00005031 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00005032 if( *z=='/' && z[1]=='*' ){
5033 z += 2;
5034 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
5035 if( *z==0 ) return 0;
5036 z++;
5037 continue;
5038 }
5039 if( *z=='-' && z[1]=='-' ){
5040 z += 2;
5041 while( *z && *z!='\n' ){ z++; }
5042 if( *z==0 ) return 1;
5043 continue;
5044 }
5045 return 0;
5046 }
5047 return 1;
5048}
5049
5050/*
drha9b17162003-04-29 18:01:28 +00005051** Return TRUE if the line typed in is an SQL command terminator other
5052** than a semi-colon. The SQL Server style "go" command is understood
5053** as is the Oracle "/".
5054*/
drh9f099fd2013-08-06 14:01:46 +00005055static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00005056 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00005057 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
5058 return 1; /* Oracle */
5059 }
drhf0693c82011-10-11 20:41:54 +00005060 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00005061 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00005062 return 1; /* SQL Server */
5063 }
5064 return 0;
5065}
5066
5067/*
drh233a5312008-12-18 22:25:13 +00005068** Return true if zSql is a complete SQL statement. Return false if it
5069** ends in the middle of a string literal or C-style comment.
5070*/
drh9f099fd2013-08-06 14:01:46 +00005071static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00005072 int rc;
5073 if( zSql==0 ) return 1;
5074 zSql[nSql] = ';';
5075 zSql[nSql+1] = 0;
5076 rc = sqlite3_complete(zSql);
5077 zSql[nSql] = 0;
5078 return rc;
5079}
5080
5081/*
drh67505e72002-04-19 12:34:06 +00005082** Read input from *in and process it. If *in==0 then input
5083** is interactive - the user is typing it it. Otherwise, input
5084** is coming from a file or device. A prompt is issued and history
5085** is saved only if input is interactive. An interrupt signal will
5086** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00005087**
5088** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00005089*/
drhdcd87a92014-08-18 13:45:42 +00005090static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00005091 char *zLine = 0; /* A single input line */
5092 char *zSql = 0; /* Accumulated SQL text */
5093 int nLine; /* Length of current line */
5094 int nSql = 0; /* Bytes of zSql[] used */
5095 int nAlloc = 0; /* Allocated zSql[] space */
5096 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
5097 char *zErrMsg; /* Error message returned */
5098 int rc; /* Error code */
5099 int errCnt = 0; /* Number of errors seen */
5100 int lineno = 0; /* Current line number */
5101 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00005102
5103 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
5104 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00005105 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00005106 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00005107 /* End of input */
drhfc8b40f2016-09-07 10:10:18 +00005108 if( in==0 && stdin_is_interactive ) printf("\n");
drh9b8d3572012-04-21 11:33:39 +00005109 break;
drhc49f44e2006-10-26 18:15:42 +00005110 }
drh67505e72002-04-19 12:34:06 +00005111 if( seenInterrupt ){
5112 if( in!=0 ) break;
5113 seenInterrupt = 0;
5114 }
drhc28490c2006-10-26 14:25:58 +00005115 lineno++;
drh849a9d92013-12-21 15:46:06 +00005116 if( nSql==0 && _all_whitespace(zLine) ){
5117 if( p->echoOn ) printf("%s\n", zLine);
5118 continue;
5119 }
drh2af0b2d2002-02-21 02:25:02 +00005120 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00005121 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00005122 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00005123 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00005124 break;
5125 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00005126 errCnt++;
5127 }
drhdaffd0e2001-04-11 14:28:42 +00005128 continue;
5129 }
drh9f099fd2013-08-06 14:01:46 +00005130 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00005131 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00005132 }
drh9f099fd2013-08-06 14:01:46 +00005133 nLine = strlen30(zLine);
5134 if( nSql+nLine+2>=nAlloc ){
5135 nAlloc = nSql+nLine+100;
5136 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00005137 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005138 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00005139 exit(1);
5140 }
drhdaffd0e2001-04-11 14:28:42 +00005141 }
drh9f099fd2013-08-06 14:01:46 +00005142 nSqlPrior = nSql;
5143 if( nSql==0 ){
5144 int i;
5145 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00005146 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00005147 memcpy(zSql, zLine+i, nLine+1-i);
5148 startline = lineno;
5149 nSql = nLine-i;
5150 }else{
5151 zSql[nSql++] = '\n';
5152 memcpy(zSql+nSql, zLine, nLine+1);
5153 nSql += nLine;
5154 }
5155 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00005156 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00005157 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00005158 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00005159 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00005160 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00005161 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00005162 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00005163 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00005164 char zPrefix[100];
5165 if( in!=0 || !stdin_is_interactive ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005166 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00005167 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00005168 }else{
shane9bd1b442009-10-23 01:27:39 +00005169 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00005170 }
drh7f953e22002-07-13 17:33:45 +00005171 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005172 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00005173 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00005174 zErrMsg = 0;
5175 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005176 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00005177 }
drhc49f44e2006-10-26 18:15:42 +00005178 errCnt++;
drhdf12f1c2015-12-07 21:46:19 +00005179 }else if( p->countChanges ){
mistachkinaae280e2015-12-31 19:06:24 +00005180 raw_printf(p->out, "changes: %3d total_changes: %d\n",
drhdf12f1c2015-12-07 21:46:19 +00005181 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
drhdaffd0e2001-04-11 14:28:42 +00005182 }
drhdaffd0e2001-04-11 14:28:42 +00005183 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00005184 if( p->outCount ){
5185 output_reset(p);
5186 p->outCount = 0;
5187 }
drh9f099fd2013-08-06 14:01:46 +00005188 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00005189 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00005190 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00005191 }
5192 }
drh9f099fd2013-08-06 14:01:46 +00005193 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00005194 if( !_all_whitespace(zSql) ){
mistachkinaae280e2015-12-31 19:06:24 +00005195 utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00005196 errCnt++;
drhd416fe72011-03-17 16:45:50 +00005197 }
drhdaffd0e2001-04-11 14:28:42 +00005198 }
drh1f9ca2c2015-08-25 16:57:52 +00005199 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00005200 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00005201 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00005202}
5203
drh67505e72002-04-19 12:34:06 +00005204/*
5205** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00005206** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00005207*/
5208static char *find_home_dir(void){
drh85e72432012-04-11 11:38:53 +00005209 static char *home_dir = NULL;
5210 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00005211
drh4ace5362014-11-10 14:42:28 +00005212#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
5213 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00005214 {
5215 struct passwd *pwent;
5216 uid_t uid = getuid();
5217 if( (pwent=getpwuid(uid)) != NULL) {
5218 home_dir = pwent->pw_dir;
5219 }
drh67505e72002-04-19 12:34:06 +00005220 }
5221#endif
5222
chw65d3c132007-11-12 21:09:10 +00005223#if defined(_WIN32_WCE)
5224 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
5225 */
drh85e72432012-04-11 11:38:53 +00005226 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00005227#else
5228
drh83905c92012-06-21 13:00:37 +00005229#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00005230 if (!home_dir) {
5231 home_dir = getenv("USERPROFILE");
5232 }
5233#endif
5234
drh67505e72002-04-19 12:34:06 +00005235 if (!home_dir) {
5236 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00005237 }
5238
drh83905c92012-06-21 13:00:37 +00005239#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00005240 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00005241 char *zDrive, *zPath;
5242 int n;
5243 zDrive = getenv("HOMEDRIVE");
5244 zPath = getenv("HOMEPATH");
5245 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00005246 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00005247 home_dir = malloc( n );
5248 if( home_dir==0 ) return 0;
5249 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
5250 return home_dir;
5251 }
5252 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00005253 }
5254#endif
5255
chw65d3c132007-11-12 21:09:10 +00005256#endif /* !_WIN32_WCE */
5257
drh67505e72002-04-19 12:34:06 +00005258 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00005259 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00005260 char *z = malloc( n );
5261 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00005262 home_dir = z;
5263 }
drhe98d4fa2002-04-21 19:06:22 +00005264
drh67505e72002-04-19 12:34:06 +00005265 return home_dir;
5266}
5267
5268/*
5269** Read input from the file given by sqliterc_override. Or if that
5270** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00005271**
5272** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00005273*/
drh534f4df2015-02-28 14:03:35 +00005274static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00005275 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00005276 const char *sqliterc_override /* Name of config file. NULL to use default */
5277){
persicom7e2dfdd2002-04-18 02:46:52 +00005278 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00005279 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00005280 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00005281 FILE *in = NULL;
5282
5283 if (sqliterc == NULL) {
drh67505e72002-04-19 12:34:06 +00005284 home_dir = find_home_dir();
drhe98d4fa2002-04-21 19:06:22 +00005285 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005286 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00005287 " cannot read ~/.sqliterc\n");
5288 return;
drhe98d4fa2002-04-21 19:06:22 +00005289 }
drh2f3de322012-06-27 16:41:31 +00005290 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00005291 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
5292 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00005293 }
drha1f9b5e2004-02-14 16:31:02 +00005294 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00005295 if( in ){
drhc28490c2006-10-26 14:25:58 +00005296 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00005297 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00005298 }
drh534f4df2015-02-28 14:03:35 +00005299 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00005300 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00005301 }
drh85e72432012-04-11 11:38:53 +00005302 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00005303}
5304
drh67505e72002-04-19 12:34:06 +00005305/*
drhe1e38c42003-05-04 18:30:59 +00005306** Show available command line options
5307*/
mistachkin1fe36bb2016-04-04 02:16:44 +00005308static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00005309 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00005310 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00005311 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005312 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00005313 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00005314 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00005315 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00005316 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00005317 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00005318#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
5319 " -heap SIZE Size of heap for memsys3 or memsys5\n"
5320#endif
drhcc3b4f82012-02-07 14:13:50 +00005321 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00005322 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00005323 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005324 " -line set output mode to 'line'\n"
5325 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00005326 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00005327 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00005328#ifdef SQLITE_ENABLE_MULTIPLEX
5329 " -multiplex enable the multiplexor VFS\n"
5330#endif
mistachkine0d68852014-12-11 03:12:33 +00005331 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00005332 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00005333 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
5334 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00005335 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00005336 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00005337 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00005338 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00005339#ifdef SQLITE_ENABLE_VFSTRACE
5340 " -vfstrace enable tracing of all VFS calls\n"
5341#endif
drhe1e38c42003-05-04 18:30:59 +00005342;
5343static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00005344 utf8_printf(stderr,
mistachkin1fe36bb2016-04-04 02:16:44 +00005345 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
drh80e8be92006-08-29 12:04:19 +00005346 "FILENAME is the name of an SQLite database. A new database is created\n"
5347 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00005348 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00005349 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00005350 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005351 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00005352 }
5353 exit(1);
5354}
5355
5356/*
drh67505e72002-04-19 12:34:06 +00005357** Initialize the state information in data
5358*/
drhdcd87a92014-08-18 13:45:42 +00005359static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00005360 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00005361 data->normalMode = data->cMode = data->mode = MODE_List;
5362 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00005363 memcpy(data->colSeparator,SEP_Column, 2);
5364 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00005365 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00005366 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00005367 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00005368 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00005369 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00005370 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
5371 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00005372}
5373
drh98d312f2012-10-25 15:23:14 +00005374/*
drh5c7976f2014-02-10 19:59:27 +00005375** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00005376*/
5377#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00005378static void printBold(const char *zText){
5379 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
5380 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
5381 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
5382 SetConsoleTextAttribute(out,
5383 FOREGROUND_RED|FOREGROUND_INTENSITY
5384 );
5385 printf("%s", zText);
5386 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00005387}
5388#else
drh5c7976f2014-02-10 19:59:27 +00005389static void printBold(const char *zText){
5390 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00005391}
5392#endif
5393
5394/*
drh98d312f2012-10-25 15:23:14 +00005395** Get the argument to an --option. Throw an error and die if no argument
5396** is available.
5397*/
5398static char *cmdline_option_value(int argc, char **argv, int i){
5399 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00005400 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00005401 argv[0], argv[argc-1]);
5402 exit(1);
5403 }
5404 return argv[i];
5405}
5406
mistachkin1fe36bb2016-04-04 02:16:44 +00005407#ifndef SQLITE_SHELL_IS_UTF8
5408# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
5409# define SQLITE_SHELL_IS_UTF8 (0)
5410# else
5411# define SQLITE_SHELL_IS_UTF8 (1)
5412# endif
5413#endif
5414
5415#if SQLITE_SHELL_IS_UTF8
mistachkin44723ce2015-03-21 02:22:37 +00005416int SQLITE_CDECL main(int argc, char **argv){
mistachkin1fe36bb2016-04-04 02:16:44 +00005417#else
5418int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
mistachkin1810f222016-04-04 02:33:34 +00005419 char **argv;
mistachkin1fe36bb2016-04-04 02:16:44 +00005420#endif
drh75897232000-05-29 14:26:00 +00005421 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00005422 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00005423 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00005424 int i;
drhc28490c2006-10-26 14:25:58 +00005425 int rc = 0;
drhb3735912014-02-10 16:13:42 +00005426 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00005427 int readStdin = 1;
5428 int nCmd = 0;
5429 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00005430
mistachkin1fe36bb2016-04-04 02:16:44 +00005431 setBinaryMode(stdin, 0);
5432 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
mistachkin1810f222016-04-04 02:33:34 +00005433 stdin_is_interactive = isatty(0);
5434 stdout_is_console = isatty(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005435
drh69b30ab2014-02-27 15:11:52 +00005436#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00005437 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005438 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00005439 sqlite3_sourceid(), SQLITE_SOURCE_ID);
5440 exit(1);
5441 }
drhc7181902014-02-27 15:04:13 +00005442#endif
persicom7e2dfdd2002-04-18 02:46:52 +00005443 main_init(&data);
mistachkin1fe36bb2016-04-04 02:16:44 +00005444#if !SQLITE_SHELL_IS_UTF8
5445 sqlite3_initialize();
5446 argv = sqlite3_malloc64(sizeof(argv[0])*argc);
5447 if( argv==0 ){
5448 raw_printf(stderr, "out of memory\n");
5449 exit(1);
5450 }
5451 for(i=0; i<argc; i++){
5452 argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
5453 if( argv[i]==0 ){
5454 raw_printf(stderr, "out of memory\n");
5455 exit(1);
5456 }
5457 }
5458#endif
mistachkin1810f222016-04-04 02:33:34 +00005459 assert( argc>=1 && argv && argv[0] );
mistachkin1fe36bb2016-04-04 02:16:44 +00005460 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00005461
drh44c2eb12003-04-30 11:38:26 +00005462 /* Make sure we have a valid signal handler early, before anything
5463 ** else is done.
5464 */
drh4c504392000-10-16 22:06:40 +00005465#ifdef SIGINT
5466 signal(SIGINT, interrupt_handler);
5467#endif
drh44c2eb12003-04-30 11:38:26 +00005468
drhac5649a2014-11-28 13:35:03 +00005469#ifdef SQLITE_SHELL_DBNAME_PROC
5470 {
5471 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
5472 ** of a C-function that will provide the name of the database file. Use
5473 ** this compile-time option to embed this shell program in larger
5474 ** applications. */
5475 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
5476 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
5477 warnInmemoryDb = 0;
5478 }
5479#endif
5480
drh22fbcb82004-02-01 01:22:50 +00005481 /* Do an initial pass through the command-line argument to locate
5482 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00005483 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00005484 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00005485 */
drh98d312f2012-10-25 15:23:14 +00005486 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00005487 char *z;
drhc28490c2006-10-26 14:25:58 +00005488 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005489 if( z[0]!='-' ){
5490 if( data.zDbFilename==0 ){
5491 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00005492 }else{
5493 /* Excesss arguments are interpreted as SQL (or dot-commands) and
5494 ** mean that nothing is read from stdin */
5495 readStdin = 0;
5496 nCmd++;
5497 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
5498 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005499 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00005500 exit(1);
5501 }
5502 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00005503 }
drh98d312f2012-10-25 15:23:14 +00005504 }
drhcc3b4f82012-02-07 14:13:50 +00005505 if( z[1]=='-' ) z++;
5506 if( strcmp(z,"-separator")==0
5507 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00005508 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00005509 || strcmp(z,"-cmd")==0
5510 ){
drh98d312f2012-10-25 15:23:14 +00005511 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005512 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00005513 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005514 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00005515 /* Need to check for batch mode here to so we can avoid printing
mistachkin1fe36bb2016-04-04 02:16:44 +00005516 ** informational messages (like from process_sqliterc) before
drh98d312f2012-10-25 15:23:14 +00005517 ** we do the actual processing of arguments later in a second pass.
5518 */
shanef69573d2009-10-24 02:06:14 +00005519 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00005520 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00005521#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00005522 const char *zSize;
5523 sqlite3_int64 szHeap;
5524
drh98d312f2012-10-25 15:23:14 +00005525 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00005526 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00005527 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00005528 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
drhc530b9c2016-07-25 11:27:22 +00005529#else
5530 (void)cmdline_option_value(argc, argv, ++i);
drh9c88d682010-12-17 14:03:01 +00005531#endif
drh44dec872014-08-30 15:49:25 +00005532 }else if( strcmp(z,"-scratch")==0 ){
5533 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005534 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005535 if( sz>400000 ) sz = 400000;
5536 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00005537 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005538 if( n>10 ) n = 10;
5539 if( n<1 ) n = 1;
5540 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
5541 data.shellFlgs |= SHFLG_Scratch;
5542 }else if( strcmp(z,"-pagecache")==0 ){
5543 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005544 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005545 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00005546 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005547 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00005548 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
5549 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00005550 data.shellFlgs |= SHFLG_Pagecache;
5551 }else if( strcmp(z,"-lookaside")==0 ){
5552 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005553 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005554 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005555 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005556 if( n<0 ) n = 0;
5557 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
5558 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00005559#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00005560 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00005561 extern int vfstrace_register(
5562 const char *zTraceName,
5563 const char *zOldVfsName,
5564 int (*xOut)(const char*,void*),
5565 void *pOutArg,
5566 int makeDefault
5567 );
drh2b625e22011-03-16 17:05:28 +00005568 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00005569#endif
drh6f25e892011-07-08 17:02:57 +00005570#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00005571 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00005572 extern int sqlite3_multiple_initialize(const char*,int);
5573 sqlite3_multiplex_initialize(0, 1);
5574#endif
drh7d9f3942013-04-03 01:26:54 +00005575 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00005576 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
5577 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00005578 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00005579 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00005580 if( pVfs ){
5581 sqlite3_vfs_register(pVfs, 1);
5582 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005583 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00005584 exit(1);
5585 }
drh44c2eb12003-04-30 11:38:26 +00005586 }
5587 }
drh98d312f2012-10-25 15:23:14 +00005588 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00005589#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00005590 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00005591 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00005592#else
mistachkinaae280e2015-12-31 19:06:24 +00005593 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00005594 return 1;
drh01b41712005-08-29 23:06:23 +00005595#endif
drh98d312f2012-10-25 15:23:14 +00005596 }
5597 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00005598
drh44c2eb12003-04-30 11:38:26 +00005599 /* Go ahead and open the database file if it already exists. If the
5600 ** file does not exist, delay opening it. This prevents empty database
5601 ** files from being created if a user mistypes the database name argument
5602 ** to the sqlite command-line tool.
5603 */
drhc8d74412004-08-31 23:41:26 +00005604 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00005605 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00005606 }
5607
drh22fbcb82004-02-01 01:22:50 +00005608 /* Process the initialization file if there is one. If no -init option
5609 ** is given on the command line, look for a file named ~/.sqliterc and
5610 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00005611 */
drh534f4df2015-02-28 14:03:35 +00005612 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00005613
drh22fbcb82004-02-01 01:22:50 +00005614 /* Make a second pass through the command-line argument and set
5615 ** options. This second pass is delayed until after the initialization
5616 ** file is processed so that the command-line arguments will override
5617 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00005618 */
drh98d312f2012-10-25 15:23:14 +00005619 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00005620 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005621 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00005622 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00005623 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00005624 i++;
5625 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005626 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00005627 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005628 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00005629 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005630 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00005631 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00005632 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00005633 }else if( strcmp(z,"-csv")==0 ){
5634 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00005635 memcpy(data.colSeparator,",",2);
5636 }else if( strcmp(z,"-ascii")==0 ){
5637 data.mode = MODE_Ascii;
5638 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005639 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00005640 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005641 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00005642 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00005643 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00005644 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00005645 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00005646 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00005647 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005648 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00005649 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00005650 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005651 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005652 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00005653 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005654 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00005655 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00005656 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00005657 }else if( strcmp(z,"-eqp")==0 ){
5658 data.autoEQP = 1;
drheacd29d2016-04-15 15:03:27 +00005659 }else if( strcmp(z,"-eqpfull")==0 ){
5660 data.autoEQP = 2;
shaneh642d8b82010-07-28 16:05:34 +00005661 }else if( strcmp(z,"-stats")==0 ){
5662 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00005663 }else if( strcmp(z,"-scanstats")==0 ){
5664 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00005665 }else if( strcmp(z,"-backslash")==0 ){
5666 /* Undocumented command-line option: -backslash
5667 ** Causes C-style backslash escapes to be evaluated in SQL statements
5668 ** prior to sending the SQL into SQLite. Useful for injecting
5669 ** crazy bytes in the middle of SQL statements for testing and debugging.
5670 */
5671 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00005672 }else if( strcmp(z,"-bail")==0 ){
5673 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00005674 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00005675 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00005676 return 0;
drhc28490c2006-10-26 14:25:58 +00005677 }else if( strcmp(z,"-interactive")==0 ){
5678 stdin_is_interactive = 1;
5679 }else if( strcmp(z,"-batch")==0 ){
5680 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00005681 }else if( strcmp(z,"-heap")==0 ){
5682 i++;
drh44dec872014-08-30 15:49:25 +00005683 }else if( strcmp(z,"-scratch")==0 ){
5684 i+=2;
5685 }else if( strcmp(z,"-pagecache")==0 ){
5686 i+=2;
5687 }else if( strcmp(z,"-lookaside")==0 ){
5688 i+=2;
drh7d9f3942013-04-03 01:26:54 +00005689 }else if( strcmp(z,"-mmap")==0 ){
5690 i++;
drha7e61d82011-03-12 17:02:57 +00005691 }else if( strcmp(z,"-vfs")==0 ){
5692 i++;
drh6f25e892011-07-08 17:02:57 +00005693#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00005694 }else if( strcmp(z,"-vfstrace")==0 ){
5695 i++;
drh6f25e892011-07-08 17:02:57 +00005696#endif
5697#ifdef SQLITE_ENABLE_MULTIPLEX
5698 }else if( strcmp(z,"-multiplex")==0 ){
5699 i++;
5700#endif
drhcc3b4f82012-02-07 14:13:50 +00005701 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00005702 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00005703 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00005704 /* Run commands that follow -cmd first and separately from commands
5705 ** that simply appear on the command-line. This seems goofy. It would
5706 ** be better if all commands ran in the order that they appear. But
5707 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00005708 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00005709 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00005710 if( z[0]=='.' ){
5711 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00005712 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00005713 }else{
drh05782482013-10-24 15:20:20 +00005714 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00005715 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
5716 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005717 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00005718 if( bail_on_error ) return rc!=0 ? rc : 1;
5719 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005720 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00005721 if( bail_on_error ) return rc;
5722 }
5723 }
drh1e5d0e92000-05-31 23:33:17 +00005724 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005725 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
5726 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00005727 return 1;
5728 }
drh700c2522016-02-09 18:39:25 +00005729 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00005730 }
drh44c2eb12003-04-30 11:38:26 +00005731
drhac5649a2014-11-28 13:35:03 +00005732 if( !readStdin ){
5733 /* Run all arguments that do not begin with '-' as if they were separate
5734 ** command-line inputs, except for the argToSkip argument which contains
5735 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00005736 */
drhac5649a2014-11-28 13:35:03 +00005737 for(i=0; i<nCmd; i++){
5738 if( azCmd[i][0]=='.' ){
5739 rc = do_meta_command(azCmd[i], &data);
5740 if( rc ) return rc==2 ? 0 : rc;
5741 }else{
5742 open_db(&data, 0);
5743 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
5744 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005745 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00005746 return rc!=0 ? rc : 1;
5747 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005748 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00005749 return rc;
5750 }
drh6ff13852001-11-25 13:18:23 +00005751 }
drh75897232000-05-29 14:26:00 +00005752 }
drhac5649a2014-11-28 13:35:03 +00005753 free(azCmd);
drh75897232000-05-29 14:26:00 +00005754 }else{
drh44c2eb12003-04-30 11:38:26 +00005755 /* Run commands received from standard input
5756 */
drhc28490c2006-10-26 14:25:58 +00005757 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00005758 char *zHome;
5759 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00005760 int nHistory;
drh75897232000-05-29 14:26:00 +00005761 printf(
drh743e0032011-12-12 16:51:50 +00005762 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00005763 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00005764 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00005765 );
drhb3735912014-02-10 16:13:42 +00005766 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00005767 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00005768 printBold("transient in-memory database");
5769 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00005770 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00005771 }
drh67505e72002-04-19 12:34:06 +00005772 zHome = find_home_dir();
drhea678832008-12-10 19:26:22 +00005773 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00005774 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00005775 if( (zHistory = malloc(nHistory))!=0 ){
5776 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
5777 }
drh67505e72002-04-19 12:34:06 +00005778 }
drhf5ed7ad2015-06-15 14:43:25 +00005779 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00005780 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00005781 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00005782 shell_stifle_history(100);
5783 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00005784 free(zHistory);
drh67505e72002-04-19 12:34:06 +00005785 }
drhdaffd0e2001-04-11 14:28:42 +00005786 }else{
drhc28490c2006-10-26 14:25:58 +00005787 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00005788 }
5789 }
drh33048c02001-10-01 14:29:22 +00005790 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00005791 if( data.db ){
drhe6229612014-08-18 15:08:26 +00005792 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00005793 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00005794 }
mistachkin1fe36bb2016-04-04 02:16:44 +00005795 sqlite3_free(data.zFreeOnClose);
5796#if !SQLITE_SHELL_IS_UTF8
5797 for(i=0; i<argc; i++) sqlite3_free(argv[i]);
5798 sqlite3_free(argv);
5799#endif
drhc28490c2006-10-26 14:25:58 +00005800 return rc;
drh75897232000-05-29 14:26:00 +00005801}