blob: 444d7e856e345a620706afe231c681d2eb777d74 [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
mistachkin2318d332015-01-12 18:02:52 +000021** If requested, include the SQLite compiler options file for MSVC.
22*/
23#if defined(INCLUDE_MSVC_H)
24#include "msvc.h"
25#endif
26
27/*
drh8cd5b252015-03-02 22:06:43 +000028** No support for loadable extensions in VxWorks.
29*/
drhada3f2b2015-03-23 21:32:50 +000030#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
drh8cd5b252015-03-02 22:06:43 +000031# define SQLITE_OMIT_LOAD_EXTENSION 1
32#endif
33
34/*
drh36f7dd32011-10-13 16:02:17 +000035** Enable large-file support for fopen() and friends on unix.
36*/
37#ifndef SQLITE_DISABLE_LFS
38# define _LARGE_FILE 1
39# ifndef _FILE_OFFSET_BITS
40# define _FILE_OFFSET_BITS 64
41# endif
42# define _LARGEFILE_SOURCE 1
43#endif
44
drh75897232000-05-29 14:26:00 +000045#include <stdlib.h>
46#include <string.h>
47#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000048#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000049#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000050#if SQLITE_USER_AUTHENTICATION
51# include "sqlite3userauth.h"
52#endif
drh75897232000-05-29 14:26:00 +000053#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000054#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000055
drh83905c92012-06-21 13:00:37 +000056#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000057# include <signal.h>
chw97185482008-11-17 08:05:31 +000058# if !defined(__RTP__) && !defined(_WRS_KERNEL)
59# include <pwd.h>
60# endif
drhdd45df82002-04-18 12:39:03 +000061# include <unistd.h>
62# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000063#endif
drh75897232000-05-29 14:26:00 +000064
drh0ede9eb2015-01-10 16:49:23 +000065#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000066# include <readline/readline.h>
67# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000068#endif
danfd34d6d2015-02-25 10:54:53 +000069
drh0ede9eb2015-01-10 16:49:23 +000070#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000071# include <editline/readline.h>
72#endif
danfd34d6d2015-02-25 10:54:53 +000073
74#if HAVE_EDITLINE || HAVE_READLINE
75
76# define shell_add_history(X) add_history(X)
77# define shell_read_history(X) read_history(X)
78# define shell_write_history(X) write_history(X)
79# define shell_stifle_history(X) stifle_history(X)
80# define shell_readline(X) readline(X)
81
82#elif HAVE_LINENOISE
83
84# include "linenoise.h"
85# define shell_add_history(X) linenoiseHistoryAdd(X)
86# define shell_read_history(X) linenoiseHistoryLoad(X)
87# define shell_write_history(X) linenoiseHistorySave(X)
88# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
89# define shell_readline(X) linenoise(X)
90
91#else
92
mistachkin1fe36bb2016-04-04 02:16:44 +000093# define shell_read_history(X)
danfd34d6d2015-02-25 10:54:53 +000094# define shell_write_history(X)
95# define shell_stifle_history(X)
96
97# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000098#endif
99
danfd34d6d2015-02-25 10:54:53 +0000100
adamd2e8464a2006-09-06 21:39:40 +0000101#if defined(_WIN32) || defined(WIN32)
102# include <io.h>
drh6976c212014-07-24 12:09:47 +0000103# include <fcntl.h>
mistachkin073664d2015-06-17 18:57:37 +0000104# define isatty(h) _isatty(h)
105# ifndef access
106# define access(f,m) _access((f),(m))
107# endif
108# undef popen
109# define popen _popen
110# undef pclose
111# define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
mistachkin073664d2015-06-17 18:57:37 +0000113 /* Make sure isatty() has a prototype. */
114 extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000115
mistachkin073664d2015-06-17 18:57:37 +0000116# if !defined(__RTP__) && !defined(_WRS_KERNEL)
117 /* popen and pclose are not C89 functions and so are
118 ** sometimes omitted from the <stdio.h> header */
119 extern FILE *popen(const char*,const char*);
120 extern int pclose(FILE*);
121# else
122# define SQLITE_OMIT_POPEN 1
123# endif
mistachkinf6418892013-08-28 01:54:12 +0000124#endif
drh53371f92013-07-25 17:07:03 +0000125
chw65d3c132007-11-12 21:09:10 +0000126#if defined(_WIN32_WCE)
127/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
128 * thus we always assume that we have a console. That can be
129 * overridden with the -batch command line option.
130 */
131#define isatty(x) 1
132#endif
133
drhf0693c82011-10-11 20:41:54 +0000134/* ctype macros that work with signed characters */
135#define IsSpace(X) isspace((unsigned char)X)
136#define IsDigit(X) isdigit((unsigned char)X)
137#define ToLower(X) (char)tolower((unsigned char)X)
138
mistachkin1fe36bb2016-04-04 02:16:44 +0000139#if defined(_WIN32) || defined(WIN32)
140#include <windows.h>
141
142/* string conversion routines only needed on Win32 */
143extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
144extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
145extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
mistachkin8145fc62016-09-16 20:39:21 +0000146extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
mistachkin1fe36bb2016-04-04 02:16:44 +0000147#endif
148
drh047d4532015-01-18 20:30:23 +0000149/* On Windows, we normally run with output mode of TEXT so that \n characters
150** are automatically translated into \r\n. However, this behavior needs
151** to be disabled in some cases (ex: when generating CSV output and when
152** rendering quoted strings that contain \n characters). The following
153** routines take care of that.
154*/
155#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000156static void setBinaryMode(FILE *file, int isOutput){
157 if( isOutput ) fflush(file);
158 _setmode(_fileno(file), _O_BINARY);
drh047d4532015-01-18 20:30:23 +0000159}
mistachkin1fe36bb2016-04-04 02:16:44 +0000160static void setTextMode(FILE *file, int isOutput){
161 if( isOutput ) fflush(file);
162 _setmode(_fileno(file), _O_TEXT);
drh047d4532015-01-18 20:30:23 +0000163}
164#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000165# define setBinaryMode(X,Y)
166# define setTextMode(X,Y)
drh047d4532015-01-18 20:30:23 +0000167#endif
168
drh43408312013-10-30 12:43:36 +0000169
170/* True if the timer is enabled */
171static int enableTimer = 0;
172
173/* Return the current wall-clock time */
174static sqlite3_int64 timeOfDay(void){
175 static sqlite3_vfs *clockVfs = 0;
176 sqlite3_int64 t;
177 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
dan3fd415b2015-11-16 08:54:10 +0000178 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drh43408312013-10-30 12:43:36 +0000179 clockVfs->xCurrentTimeInt64(clockVfs, &t);
180 }else{
181 double r;
182 clockVfs->xCurrentTime(clockVfs, &r);
183 t = (sqlite3_int64)(r*86400000.0);
184 }
185 return t;
186}
187
drh91eb93c2015-03-03 19:56:20 +0000188#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000189#include <sys/time.h>
190#include <sys/resource.h>
191
drh91eb93c2015-03-03 19:56:20 +0000192/* VxWorks does not support getrusage() as far as we can determine */
193#if defined(_WRS_KERNEL) || defined(__RTP__)
194struct rusage {
195 struct timeval ru_utime; /* user CPU time used */
196 struct timeval ru_stime; /* system CPU time used */
197};
198#define getrusage(A,B) memset(B,0,sizeof(*B))
199#endif
200
drhda108222009-02-25 19:07:24 +0000201/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000202static struct rusage sBegin; /* CPU time at start */
203static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000204
drhda108222009-02-25 19:07:24 +0000205/*
206** Begin timing an operation
207*/
208static void beginTimer(void){
209 if( enableTimer ){
210 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000211 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000212 }
213}
214
215/* Return the difference of two time_structs in seconds */
216static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
mistachkin1fe36bb2016-04-04 02:16:44 +0000217 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
drhda108222009-02-25 19:07:24 +0000218 (double)(pEnd->tv_sec - pStart->tv_sec);
219}
220
221/*
222** Print the timing results.
223*/
224static void endTimer(void){
225 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000226 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000227 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000228 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000229 printf("Run Time: real %.3f user %f sys %f\n",
230 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000231 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
232 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
233 }
234}
shaneb320ccd2009-10-21 03:42:58 +0000235
drhda108222009-02-25 19:07:24 +0000236#define BEGIN_TIMER beginTimer()
237#define END_TIMER endTimer()
238#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000239
240#elif (defined(_WIN32) || defined(WIN32))
241
shaneb320ccd2009-10-21 03:42:58 +0000242/* Saved resource information for the beginning of an operation */
243static HANDLE hProcess;
244static FILETIME ftKernelBegin;
245static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000246static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000247typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
248 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000249static GETPROCTIMES getProcessTimesAddr = NULL;
250
shaneb320ccd2009-10-21 03:42:58 +0000251/*
252** Check to see if we have timer support. Return 1 if necessary
253** support found (or found previously).
254*/
255static int hasTimer(void){
256 if( getProcessTimesAddr ){
257 return 1;
258 } else {
drh4ace5362014-11-10 14:42:28 +0000259 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
260 ** versions. See if the version we are running on has it, and if it
261 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000262 */
263 hProcess = GetCurrentProcess();
264 if( hProcess ){
265 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
266 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000267 getProcessTimesAddr =
268 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000269 if( NULL != getProcessTimesAddr ){
270 return 1;
271 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000272 FreeLibrary(hinstLib);
shaneb320ccd2009-10-21 03:42:58 +0000273 }
274 }
275 }
276 return 0;
277}
278
279/*
280** Begin timing an operation
281*/
282static void beginTimer(void){
283 if( enableTimer && getProcessTimesAddr ){
284 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000285 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
286 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000287 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000288 }
289}
290
291/* Return the difference of two FILETIME structs in seconds */
292static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
293 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
294 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
295 return (double) ((i64End - i64Start) / 10000000.0);
296}
297
298/*
299** Print the timing results.
300*/
301static void endTimer(void){
302 if( enableTimer && getProcessTimesAddr){
303 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000304 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000305 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000306 printf("Run Time: real %.3f user %f sys %f\n",
307 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000308 timeDiff(&ftUserBegin, &ftUserEnd),
309 timeDiff(&ftKernelBegin, &ftKernelEnd));
310 }
311}
312
313#define BEGIN_TIMER beginTimer()
314#define END_TIMER endTimer()
315#define HAS_TIMER hasTimer()
316
drhda108222009-02-25 19:07:24 +0000317#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000318#define BEGIN_TIMER
drhda108222009-02-25 19:07:24 +0000319#define END_TIMER
320#define HAS_TIMER 0
321#endif
322
shanec0688ea2009-03-05 03:48:06 +0000323/*
324** Used to prevent warnings about unused parameters
325*/
326#define UNUSED_PARAMETER(x) (void)(x)
327
drhe91d16b2008-12-08 18:27:31 +0000328/*
drhc49f44e2006-10-26 18:15:42 +0000329** If the following flag is set, then command execution stops
330** at an error if we are not interactive.
331*/
332static int bail_on_error = 0;
333
334/*
drhc28490c2006-10-26 14:25:58 +0000335** Threat stdin as an interactive input if the following variable
336** is true. Otherwise, assume stdin is connected to a file or pipe.
337*/
338static int stdin_is_interactive = 1;
339
340/*
drhe05461c2015-12-30 13:36:57 +0000341** On Windows systems we have to know if standard output is a console
342** in order to translate UTF-8 into MBCS. The following variable is
343** true if translation is required.
344*/
345static int stdout_is_console = 1;
346
347/*
drh4c504392000-10-16 22:06:40 +0000348** The following is the open SQLite database. We make a pointer
349** to this database a static variable so that it can be accessed
350** by the SIGINT handler to interrupt database processing.
351*/
mistachkin8e189222015-04-19 21:43:16 +0000352static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000353
354/*
drh67505e72002-04-19 12:34:06 +0000355** True if an interrupt (Control-C) has been received.
356*/
drh43617e92006-03-06 20:55:46 +0000357static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000358
359/*
persicom7e2dfdd2002-04-18 02:46:52 +0000360** This is the name of our program. It is set in main(), used
361** in a number of other places, mostly for error messages.
362*/
363static char *Argv0;
364
365/*
366** Prompt strings. Initialized in main. Settable with
367** .prompt main continue
368*/
369static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
370static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
371
drhb0603412007-02-28 04:47:26 +0000372/*
mistachkin710b33b2016-01-03 18:59:28 +0000373** Render output like fprintf(). Except, if the output is going to the
374** console and if this is running on a Windows machine, translate the
375** output from UTF-8 into MBCS.
376*/
377#if defined(_WIN32) || defined(WIN32)
378void utf8_printf(FILE *out, const char *zFormat, ...){
379 va_list ap;
380 va_start(ap, zFormat);
381 if( stdout_is_console && (out==stdout || out==stderr) ){
mistachkin710b33b2016-01-03 18:59:28 +0000382 char *z1 = sqlite3_vmprintf(zFormat, ap);
mistachkin1fe36bb2016-04-04 02:16:44 +0000383 char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
mistachkin710b33b2016-01-03 18:59:28 +0000384 sqlite3_free(z1);
385 fputs(z2, out);
386 sqlite3_free(z2);
387 }else{
388 vfprintf(out, zFormat, ap);
389 }
390 va_end(ap);
391}
392#elif !defined(utf8_printf)
393# define utf8_printf fprintf
394#endif
395
396/*
397** Render output like fprintf(). This should not be used on anything that
398** includes string formatting (e.g. "%s").
399*/
400#if !defined(raw_printf)
401# define raw_printf fprintf
402#endif
403
404/*
drhb0603412007-02-28 04:47:26 +0000405** Write I/O traces to the following stream.
406*/
rsebe0a9092007-07-30 18:24:38 +0000407#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000408static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000409#endif
drhb0603412007-02-28 04:47:26 +0000410
411/*
412** This routine works like printf in that its first argument is a
413** format string and subsequent arguments are values to be substituted
414** in place of % fields. The result of formatting this string
415** is written to iotrace.
416*/
rsebe0a9092007-07-30 18:24:38 +0000417#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000418static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000419 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000420 char *z;
drhb0603412007-02-28 04:47:26 +0000421 if( iotrace==0 ) return;
422 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000423 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000424 va_end(ap);
mistachkin710b33b2016-01-03 18:59:28 +0000425 utf8_printf(iotrace, "%s", z);
drhf075cd02007-02-28 06:14:25 +0000426 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000427}
rsebe0a9092007-07-30 18:24:38 +0000428#endif
drhb0603412007-02-28 04:47:26 +0000429
drh44c2eb12003-04-30 11:38:26 +0000430
persicom7e2dfdd2002-04-18 02:46:52 +0000431/*
drh83965662003-04-17 02:54:13 +0000432** Determines if a string is a number of not.
433*/
danielk19772e588c72005-12-09 14:25:08 +0000434static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000435 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000436 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000437 return 0;
438 }
439 z++;
440 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000441 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000442 if( *z=='.' ){
443 z++;
drhf0693c82011-10-11 20:41:54 +0000444 if( !IsDigit(*z) ) return 0;
445 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000446 if( realnum ) *realnum = 1;
447 }
448 if( *z=='e' || *z=='E' ){
449 z++;
450 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000451 if( !IsDigit(*z) ) return 0;
452 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000453 if( realnum ) *realnum = 1;
454 }
455 return *z==0;
456}
drh83965662003-04-17 02:54:13 +0000457
458/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000459** A global char* and an SQL function to access its current value
460** from within an SQL statement. This program used to use the
danielk1977bc6ada42004-06-30 08:20:16 +0000461** sqlite_exec_printf() API to substitue a string into an SQL statement.
462** The correct way to do this with sqlite3 is to use the bind API, but
463** since the shell is built around the callback paradigm it would be a lot
464** of work. Instead just use this hack, which is quite harmless.
465*/
466static const char *zShellStatic = 0;
467static void shellstaticFunc(
468 sqlite3_context *context,
469 int argc,
470 sqlite3_value **argv
471){
472 assert( 0==argc );
473 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000474 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000475 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000476 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
477}
478
479
480/*
drhe05461c2015-12-30 13:36:57 +0000481** Compute a string length that is limited to what can be stored in
482** lower 30 bits of a 32-bit signed integer.
483*/
484static int strlen30(const char *z){
485 const char *z2 = z;
486 while( *z2 ){ z2++; }
487 return 0x3fffffff & (int)(z2 - z);
488}
489
490/*
drhfeac5f82004-08-01 00:10:45 +0000491** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000492** the text in memory obtained from malloc() and returns a pointer
493** to the text. NULL is returned at end of file, or if malloc()
494** fails.
495**
drh9f099fd2013-08-06 14:01:46 +0000496** If zLine is not NULL then it is a malloced buffer returned from
497** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000498*/
drh9f099fd2013-08-06 14:01:46 +0000499static char *local_getline(char *zLine, FILE *in){
500 int nLine = zLine==0 ? 0 : 100;
501 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000502
drhb07028f2011-10-14 21:49:18 +0000503 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000504 if( n+100>nLine ){
505 nLine = nLine*2 + 100;
506 zLine = realloc(zLine, nLine);
507 if( zLine==0 ) return 0;
508 }
drhdaffd0e2001-04-11 14:28:42 +0000509 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000510 if( n==0 ){
511 free(zLine);
512 return 0;
513 }
514 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000515 break;
516 }
drh9f099fd2013-08-06 14:01:46 +0000517 while( zLine[n] ) n++;
518 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000519 n--;
shaneh13b36022009-12-17 21:07:15 +0000520 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000521 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000522 break;
drh8e7e7a22000-05-30 18:45:23 +0000523 }
524 }
drhe05461c2015-12-30 13:36:57 +0000525#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000526 /* For interactive input on Windows systems, translate the
drhe05461c2015-12-30 13:36:57 +0000527 ** multi-byte characterset characters into UTF-8. */
drhfc8b40f2016-09-07 10:10:18 +0000528 if( stdin_is_interactive && in==stdin ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000529 char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
drhe05461c2015-12-30 13:36:57 +0000530 if( zTrans ){
531 int nTrans = strlen30(zTrans)+1;
532 if( nTrans>nLine ){
533 zLine = realloc(zLine, nTrans);
534 if( zLine==0 ){
535 sqlite3_free(zTrans);
536 return 0;
537 }
538 }
539 memcpy(zLine, zTrans, nTrans);
540 sqlite3_free(zTrans);
541 }
542 }
543#endif /* defined(_WIN32) || defined(WIN32) */
drh8e7e7a22000-05-30 18:45:23 +0000544 return zLine;
545}
546
547/*
drhc28490c2006-10-26 14:25:58 +0000548** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000549**
drh9f099fd2013-08-06 14:01:46 +0000550** If in==0 then read from standard input and prompt before each line.
551** If isContinuation is true, then a continuation prompt is appropriate.
552** If isContinuation is zero, then the main prompt should be used.
553**
554** If zPrior is not NULL then it is a buffer from a prior call to this
555** routine that can be reused.
556**
557** The result is stored in space obtained from malloc() and must either
558** be freed by the caller or else passed back into this routine via the
559** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000560*/
drh9f099fd2013-08-06 14:01:46 +0000561static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000562 char *zPrompt;
563 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000564 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000565 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000566 }else{
drh9f099fd2013-08-06 14:01:46 +0000567 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000568#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000569 printf("%s", zPrompt);
570 fflush(stdout);
571 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000572#else
573 free(zPrior);
574 zResult = shell_readline(zPrompt);
575 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000576#endif
drh9f099fd2013-08-06 14:01:46 +0000577 }
drh8e7e7a22000-05-30 18:45:23 +0000578 return zResult;
579}
580
drhe6229612014-08-18 15:08:26 +0000581#if defined(SQLITE_ENABLE_SESSION)
582/*
583** State information for a single open session
584*/
585typedef struct OpenSession OpenSession;
586struct OpenSession {
587 char *zName; /* Symbolic name for this session */
588 int nFilter; /* Number of xFilter rejection GLOB patterns */
589 char **azFilter; /* Array of xFilter rejection GLOB patterns */
590 sqlite3_session *p; /* The open session */
591};
592#endif
593
drhdcd87a92014-08-18 13:45:42 +0000594/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000595** Shell output mode information from before ".explain on",
drhdcd87a92014-08-18 13:45:42 +0000596** saved so that it can be restored by ".explain off"
597*/
598typedef struct SavedModeInfo SavedModeInfo;
599struct SavedModeInfo {
600 int valid; /* Is there legit data in here? */
601 int mode; /* Mode prior to ".explain on" */
602 int showHeader; /* The ".header" setting prior to ".explain on" */
603 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000604};
drh45e29d82006-11-20 16:21:10 +0000605
drh8e7e7a22000-05-30 18:45:23 +0000606/*
drhdcd87a92014-08-18 13:45:42 +0000607** State information about the database connection is contained in an
608** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000609*/
drhdcd87a92014-08-18 13:45:42 +0000610typedef struct ShellState ShellState;
611struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000612 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000613 int echoOn; /* True to echo input commands */
drh700c2522016-02-09 18:39:25 +0000614 int autoExplain; /* Automatically turn on .explain mode */
drhc2ce0be2014-05-29 12:36:14 +0000615 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000616 int statsOn; /* True to display memory stats before each finalize */
dan0fbee292017-01-21 15:58:42 +0000617 int vmstepsOn; /* Display VM steps before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000618 int scanstatsOn; /* True to display scan stats before each finalize */
drhdf12f1c2015-12-07 21:46:19 +0000619 int countChanges; /* True to display change counts */
drh9569f602015-04-16 15:05:04 +0000620 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000621 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000622 int cnt; /* Number of records displayed so far */
623 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000624 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000625 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000626 int mode; /* An output mode setting */
drh700c2522016-02-09 18:39:25 +0000627 int cMode; /* temporary output mode for the current query */
628 int normalMode; /* Output mode before ".explain on" */
drh45e29d82006-11-20 16:21:10 +0000629 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000630 int showHeader; /* True to show column names in List or Column mode */
drh760c8162016-09-16 02:52:22 +0000631 int nCheck; /* Number of ".check" commands run */
drh44dec872014-08-30 15:49:25 +0000632 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000633 char *zDestTable; /* Name of destination table when MODE_Insert */
drh760c8162016-09-16 02:52:22 +0000634 char zTestcase[30]; /* Name of current test case */
mistachkin636bf9f2014-07-19 20:15:16 +0000635 char colSeparator[20]; /* Column separator character for several modes */
636 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000637 int colWidth[100]; /* Requested width of each column when in column mode*/
638 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000639 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000640 ** the database */
drh44c2eb12003-04-30 11:38:26 +0000641 char outfile[FILENAME_MAX]; /* Filename for *out */
642 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000643 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000644 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000645 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000646 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000647 int *aiIndent; /* Array of indents used in MODE_Explain */
648 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000649 int iIndent; /* Index of current op in aiIndent[] */
drhe6229612014-08-18 15:08:26 +0000650#if defined(SQLITE_ENABLE_SESSION)
651 int nSession; /* Number of active sessions */
652 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
653#endif
drh75897232000-05-29 14:26:00 +0000654};
655
656/*
drh44dec872014-08-30 15:49:25 +0000657** These are the allowed shellFlgs values
658*/
659#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
660#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
661#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
662
663/*
drh75897232000-05-29 14:26:00 +0000664** These are the allowed modes.
665*/
drh967e8b72000-06-21 13:59:10 +0000666#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000667#define MODE_Column 1 /* One record per line in neat columns */
668#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000669#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
670#define MODE_Html 4 /* Generate an XHTML table */
671#define MODE_Insert 5 /* Generate SQL "insert" statements */
drh41f5f6e2016-10-21 17:39:30 +0000672#define MODE_Quote 6 /* Quote values as for SQL */
673#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
674#define MODE_Csv 8 /* Quote strings, numbers are plain */
675#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
676#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
677#define MODE_Pretty 11 /* Pretty-print schemas */
persicom7e2dfdd2002-04-18 02:46:52 +0000678
drh66ce4d02008-02-15 17:38:06 +0000679static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000680 "line",
681 "column",
682 "list",
683 "semi",
684 "html",
drhfeac5f82004-08-01 00:10:45 +0000685 "insert",
drh41f5f6e2016-10-21 17:39:30 +0000686 "quote",
drhfeac5f82004-08-01 00:10:45 +0000687 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000688 "csv",
drh66ce4d02008-02-15 17:38:06 +0000689 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000690 "ascii",
drh4926fec2016-04-13 15:33:42 +0000691 "prettyprint",
persicom7e2dfdd2002-04-18 02:46:52 +0000692};
drh75897232000-05-29 14:26:00 +0000693
694/*
mistachkinfad42082014-07-24 22:13:12 +0000695** These are the column/row/line separators used by the various
696** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000697*/
mistachkinfad42082014-07-24 22:13:12 +0000698#define SEP_Column "|"
699#define SEP_Row "\n"
700#define SEP_Tab "\t"
701#define SEP_Space " "
702#define SEP_Comma ","
703#define SEP_CrLf "\r\n"
704#define SEP_Unit "\x1F"
705#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000706
707/*
drh75897232000-05-29 14:26:00 +0000708** Number of elements in an array
709*/
drh902b9ee2008-12-05 17:17:07 +0000710#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000711
712/*
drh127f9d72010-02-23 01:47:00 +0000713** A callback for the sqlite3_log() interface.
714*/
715static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000716 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000717 if( p->pLog==0 ) return;
mistachkinaae280e2015-12-31 19:06:24 +0000718 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
drh127f9d72010-02-23 01:47:00 +0000719 fflush(p->pLog);
720}
721
722/*
shane626a6e42009-10-22 17:30:15 +0000723** Output the given string as a hex-encoded blob (eg. X'1234' )
724*/
725static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
726 int i;
727 char *zBlob = (char *)pBlob;
mistachkinaae280e2015-12-31 19:06:24 +0000728 raw_printf(out,"X'");
729 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
730 raw_printf(out,"'");
shane626a6e42009-10-22 17:30:15 +0000731}
732
733/*
drh28bd4bc2000-06-15 15:57:22 +0000734** Output the given string as a quoted string using SQL quoting conventions.
735*/
736static void output_quoted_string(FILE *out, const char *z){
737 int i;
738 int nSingle = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +0000739 setBinaryMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000740 for(i=0; z[i]; i++){
741 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000742 }
743 if( nSingle==0 ){
drhe05461c2015-12-30 13:36:57 +0000744 utf8_printf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000745 }else{
mistachkinaae280e2015-12-31 19:06:24 +0000746 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000747 while( *z ){
748 for(i=0; z[i] && z[i]!='\''; i++){}
749 if( i==0 ){
mistachkinaae280e2015-12-31 19:06:24 +0000750 raw_printf(out,"''");
drh28bd4bc2000-06-15 15:57:22 +0000751 z++;
752 }else if( z[i]=='\'' ){
drhe05461c2015-12-30 13:36:57 +0000753 utf8_printf(out,"%.*s''",i,z);
drh28bd4bc2000-06-15 15:57:22 +0000754 z += i+1;
755 }else{
drhe05461c2015-12-30 13:36:57 +0000756 utf8_printf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000757 break;
758 }
759 }
mistachkinaae280e2015-12-31 19:06:24 +0000760 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000761 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000762 setTextMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000763}
764
765/*
drhfeac5f82004-08-01 00:10:45 +0000766** Output the given string as a quoted according to C or TCL quoting rules.
767*/
768static void output_c_string(FILE *out, const char *z){
769 unsigned int c;
770 fputc('"', out);
771 while( (c = *(z++))!=0 ){
772 if( c=='\\' ){
773 fputc(c, out);
774 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000775 }else if( c=='"' ){
776 fputc('\\', out);
777 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000778 }else if( c=='\t' ){
779 fputc('\\', out);
780 fputc('t', out);
781 }else if( c=='\n' ){
782 fputc('\\', out);
783 fputc('n', out);
784 }else if( c=='\r' ){
785 fputc('\\', out);
786 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000787 }else if( !isprint(c&0xff) ){
mistachkinaae280e2015-12-31 19:06:24 +0000788 raw_printf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000789 }else{
790 fputc(c, out);
791 }
792 }
793 fputc('"', out);
794}
795
796/*
drhc08a4f12000-06-15 16:49:48 +0000797** Output the given string with characters that are special to
798** HTML escaped.
799*/
800static void output_html_string(FILE *out, const char *z){
801 int i;
drhc3d6ba42014-01-13 20:38:35 +0000802 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000803 while( *z ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000804 for(i=0; z[i]
805 && z[i]!='<'
806 && z[i]!='&'
807 && z[i]!='>'
808 && z[i]!='\"'
shane43d9cb22009-10-21 14:11:48 +0000809 && z[i]!='\'';
810 i++){}
drhc08a4f12000-06-15 16:49:48 +0000811 if( i>0 ){
drhe05461c2015-12-30 13:36:57 +0000812 utf8_printf(out,"%.*s",i,z);
drhc08a4f12000-06-15 16:49:48 +0000813 }
814 if( z[i]=='<' ){
mistachkinaae280e2015-12-31 19:06:24 +0000815 raw_printf(out,"&lt;");
drhc08a4f12000-06-15 16:49:48 +0000816 }else if( z[i]=='&' ){
mistachkinaae280e2015-12-31 19:06:24 +0000817 raw_printf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000818 }else if( z[i]=='>' ){
mistachkinaae280e2015-12-31 19:06:24 +0000819 raw_printf(out,"&gt;");
shane43d9cb22009-10-21 14:11:48 +0000820 }else if( z[i]=='\"' ){
mistachkinaae280e2015-12-31 19:06:24 +0000821 raw_printf(out,"&quot;");
shane43d9cb22009-10-21 14:11:48 +0000822 }else if( z[i]=='\'' ){
mistachkinaae280e2015-12-31 19:06:24 +0000823 raw_printf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000824 }else{
825 break;
826 }
827 z += i + 1;
828 }
829}
830
831/*
drhc49f44e2006-10-26 18:15:42 +0000832** If a field contains any character identified by a 1 in the following
833** array, then the string must be quoted for CSV.
834*/
835static const char needCsvQuote[] = {
mistachkin1fe36bb2016-04-04 02:16:44 +0000836 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
837 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
838 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
839 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
840 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
841 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
842 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
843 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
844 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
845 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
846 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
847 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
848 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
849 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
850 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
851 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
drhc49f44e2006-10-26 18:15:42 +0000852};
853
854/*
mistachkindd11f2d2014-12-11 04:49:46 +0000855** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000856** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000857** the null value. Strings are quoted if necessary. The separator
858** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000859*/
drhdcd87a92014-08-18 13:45:42 +0000860static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000861 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000862 if( z==0 ){
drhe05461c2015-12-30 13:36:57 +0000863 utf8_printf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000864 }else{
drhc49f44e2006-10-26 18:15:42 +0000865 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000866 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000867 for(i=0; z[i]; i++){
mistachkin1fe36bb2016-04-04 02:16:44 +0000868 if( needCsvQuote[((unsigned char*)z)[i]]
869 || (z[i]==p->colSeparator[0] &&
mistachkin636bf9f2014-07-19 20:15:16 +0000870 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000871 i = 0;
872 break;
873 }
874 }
875 if( i==0 ){
876 putc('"', out);
877 for(i=0; z[i]; i++){
878 if( z[i]=='"' ) putc('"', out);
879 putc(z[i], out);
880 }
881 putc('"', out);
882 }else{
drhe05461c2015-12-30 13:36:57 +0000883 utf8_printf(out, "%s", z);
drhc49f44e2006-10-26 18:15:42 +0000884 }
drh8e64d1c2004-10-07 00:32:39 +0000885 }
886 if( bSep ){
drhe05461c2015-12-30 13:36:57 +0000887 utf8_printf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000888 }
889}
890
danielk19774af00c62005-01-23 23:43:21 +0000891#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000892/*
drh4c504392000-10-16 22:06:40 +0000893** This routine runs when the user presses Ctrl-C
894*/
895static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000896 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000897 seenInterrupt++;
898 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000899 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000900}
danielk19774af00c62005-01-23 23:43:21 +0000901#endif
drh4c504392000-10-16 22:06:40 +0000902
drha0daa752016-09-16 11:53:10 +0000903#ifndef SQLITE_OMIT_AUTHORIZATION
drh4c504392000-10-16 22:06:40 +0000904/*
drhde613c62016-04-04 17:23:10 +0000905** When the ".auth ON" is set, the following authorizer callback is
906** invoked. It always returns SQLITE_OK.
907*/
908static int shellAuth(
909 void *pClientData,
910 int op,
911 const char *zA1,
912 const char *zA2,
913 const char *zA3,
914 const char *zA4
915){
916 ShellState *p = (ShellState*)pClientData;
917 static const char *azAction[] = { 0,
918 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
919 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
920 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
921 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
922 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
923 "DROP_TRIGGER", "DROP_VIEW", "INSERT",
924 "PRAGMA", "READ", "SELECT",
925 "TRANSACTION", "UPDATE", "ATTACH",
926 "DETACH", "ALTER_TABLE", "REINDEX",
927 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
928 "FUNCTION", "SAVEPOINT", "RECURSIVE"
929 };
930 int i;
931 const char *az[4];
932 az[0] = zA1;
933 az[1] = zA2;
934 az[2] = zA3;
935 az[3] = zA4;
mistachkin8145fc62016-09-16 20:39:21 +0000936 utf8_printf(p->out, "authorizer: %s", azAction[op]);
drhde613c62016-04-04 17:23:10 +0000937 for(i=0; i<4; i++){
938 raw_printf(p->out, " ");
939 if( az[i] ){
940 output_c_string(p->out, az[i]);
941 }else{
942 raw_printf(p->out, "NULL");
943 }
944 }
945 raw_printf(p->out, "\n");
946 return SQLITE_OK;
947}
drha0daa752016-09-16 11:53:10 +0000948#endif
mistachkin8145fc62016-09-16 20:39:21 +0000949
drh79f20e92016-12-13 23:22:39 +0000950/*
951** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
952**
953** This routine converts some CREATE TABLE statements for shadow tables
954** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
955*/
956static void printSchemaLine(FILE *out, const char *z, const char *zTail){
957 if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
958 utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
959 }else{
960 utf8_printf(out, "%s%s", z, zTail);
961 }
962}
963static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
964 char c = z[n];
965 z[n] = 0;
966 printSchemaLine(out, z, zTail);
967 z[n] = c;
968}
drhde613c62016-04-04 17:23:10 +0000969
970/*
shane626a6e42009-10-22 17:30:15 +0000971** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000972** invokes for each row of a query result.
973*/
drh4ace5362014-11-10 14:42:28 +0000974static int shell_callback(
975 void *pArg,
976 int nArg, /* Number of result columns */
977 char **azArg, /* Text of each result column */
978 char **azCol, /* Column names */
979 int *aiType /* Column types */
980){
drh75897232000-05-29 14:26:00 +0000981 int i;
drhdcd87a92014-08-18 13:45:42 +0000982 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000983
drh700c2522016-02-09 18:39:25 +0000984 switch( p->cMode ){
drh75897232000-05-29 14:26:00 +0000985 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000986 int w = 5;
drh6a535342001-10-19 16:44:56 +0000987 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000988 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000989 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000990 if( len>w ) w = len;
991 }
drhe05461c2015-12-30 13:36:57 +0000992 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000993 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000994 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000995 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000996 }
997 break;
998 }
danielk19770d78bae2008-01-03 07:09:48 +0000999 case MODE_Explain:
drh75897232000-05-29 14:26:00 +00001000 case MODE_Column: {
drh700c2522016-02-09 18:39:25 +00001001 static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
1002 const int *colWidth;
1003 int showHdr;
1004 char *rowSep;
1005 if( p->cMode==MODE_Column ){
1006 colWidth = p->colWidth;
1007 showHdr = p->showHeader;
1008 rowSep = p->rowSeparator;
1009 }else{
1010 colWidth = aExplainWidths;
1011 showHdr = 1;
mistachkin6d945552016-02-09 20:31:50 +00001012 rowSep = SEP_Row;
drh700c2522016-02-09 18:39:25 +00001013 }
drha0c66f52000-07-29 13:20:21 +00001014 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +00001015 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +00001016 int w, n;
1017 if( i<ArraySize(p->colWidth) ){
drh700c2522016-02-09 18:39:25 +00001018 w = colWidth[i];
drh75897232000-05-29 14:26:00 +00001019 }else{
danielk19770d78bae2008-01-03 07:09:48 +00001020 w = 0;
drh75897232000-05-29 14:26:00 +00001021 }
drh078b1fd2012-09-21 13:40:02 +00001022 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +00001023 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +00001024 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +00001025 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +00001026 if( w<n ) w = n;
1027 }
1028 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001029 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001030 }
drh700c2522016-02-09 18:39:25 +00001031 if( showHdr ){
drh078b1fd2012-09-21 13:40:02 +00001032 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001033 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001034 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001035 }else{
drhe05461c2015-12-30 13:36:57 +00001036 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001037 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001038 }
drha0c66f52000-07-29 13:20:21 +00001039 }
1040 }
drh700c2522016-02-09 18:39:25 +00001041 if( showHdr ){
drha0c66f52000-07-29 13:20:21 +00001042 for(i=0; i<nArg; i++){
1043 int w;
1044 if( i<ArraySize(p->actualWidth) ){
1045 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +00001046 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +00001047 }else{
1048 w = 10;
1049 }
mistachkinaae280e2015-12-31 19:06:24 +00001050 utf8_printf(p->out,"%-*.*s%s",w,w,
drhe05461c2015-12-30 13:36:57 +00001051 "----------------------------------------------------------"
drha0c66f52000-07-29 13:20:21 +00001052 "----------------------------------------------------------",
drh700c2522016-02-09 18:39:25 +00001053 i==nArg-1 ? rowSep : " ");
drha0c66f52000-07-29 13:20:21 +00001054 }
drh75897232000-05-29 14:26:00 +00001055 }
1056 }
drh6a535342001-10-19 16:44:56 +00001057 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001058 for(i=0; i<nArg; i++){
1059 int w;
drha0c66f52000-07-29 13:20:21 +00001060 if( i<ArraySize(p->actualWidth) ){
1061 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001062 }else{
1063 w = 10;
1064 }
drh700c2522016-02-09 18:39:25 +00001065 if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +00001066 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001067 }
dana98bf362013-11-13 18:35:01 +00001068 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +00001069 if( p->iIndent<p->nIndent ){
mistachkinaae280e2015-12-31 19:06:24 +00001070 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +00001071 }
danc4650bb2013-11-18 08:41:06 +00001072 p->iIndent++;
dana98bf362013-11-13 18:35:01 +00001073 }
drh078b1fd2012-09-21 13:40:02 +00001074 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001075 utf8_printf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +00001076 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001077 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001078 }else{
drhe05461c2015-12-30 13:36:57 +00001079 utf8_printf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +00001080 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001081 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001082 }
drh75897232000-05-29 14:26:00 +00001083 }
1084 break;
1085 }
drh4926fec2016-04-13 15:33:42 +00001086 case MODE_Semi: { /* .schema and .fullschema output */
drh79f20e92016-12-13 23:22:39 +00001087 printSchemaLine(p->out, azArg[0], ";\n");
drh4926fec2016-04-13 15:33:42 +00001088 break;
1089 }
1090 case MODE_Pretty: { /* .schema and .fullschema with --indent */
1091 char *z;
drh07d683f2016-04-13 21:00:36 +00001092 int j;
drh4926fec2016-04-13 15:33:42 +00001093 int nParen = 0;
1094 char cEnd = 0;
1095 char c;
1096 int nLine = 0;
1097 assert( nArg==1 );
1098 if( azArg[0]==0 ) break;
1099 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
1100 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
1101 ){
1102 utf8_printf(p->out, "%s;\n", azArg[0]);
1103 break;
1104 }
1105 z = sqlite3_mprintf("%s", azArg[0]);
1106 j = 0;
1107 for(i=0; IsSpace(z[i]); i++){}
1108 for(; (c = z[i])!=0; i++){
1109 if( IsSpace(c) ){
1110 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
1111 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
1112 j--;
1113 }
1114 z[j++] = c;
1115 }
1116 while( j>0 && IsSpace(z[j-1]) ){ j--; }
1117 z[j] = 0;
1118 if( strlen30(z)>=79 ){
drh07d683f2016-04-13 21:00:36 +00001119 for(i=j=0; (c = z[i])!=0; i++){
drh4926fec2016-04-13 15:33:42 +00001120 if( c==cEnd ){
1121 cEnd = 0;
1122 }else if( c=='"' || c=='\'' || c=='`' ){
1123 cEnd = c;
1124 }else if( c=='[' ){
1125 cEnd = ']';
1126 }else if( c=='(' ){
1127 nParen++;
1128 }else if( c==')' ){
1129 nParen--;
1130 if( nLine>0 && nParen==0 && j>0 ){
drh79f20e92016-12-13 23:22:39 +00001131 printSchemaLineN(p->out, z, j, "\n");
drh4926fec2016-04-13 15:33:42 +00001132 j = 0;
1133 }
1134 }
1135 z[j++] = c;
1136 if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
1137 if( c=='\n' ) j--;
drh79f20e92016-12-13 23:22:39 +00001138 printSchemaLineN(p->out, z, j, "\n ");
drh4926fec2016-04-13 15:33:42 +00001139 j = 0;
1140 nLine++;
1141 while( IsSpace(z[i+1]) ){ i++; }
1142 }
1143 }
1144 z[j] = 0;
1145 }
drh79f20e92016-12-13 23:22:39 +00001146 printSchemaLine(p->out, z, ";\n");
drh4926fec2016-04-13 15:33:42 +00001147 sqlite3_free(z);
1148 break;
1149 }
drh75897232000-05-29 14:26:00 +00001150 case MODE_List: {
1151 if( p->cnt++==0 && p->showHeader ){
1152 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001153 utf8_printf(p->out,"%s%s",azCol[i],
mistachkin636bf9f2014-07-19 20:15:16 +00001154 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +00001155 }
1156 }
drh6a535342001-10-19 16:44:56 +00001157 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001158 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001159 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +00001160 if( z==0 ) z = p->nullValue;
drhe05461c2015-12-30 13:36:57 +00001161 utf8_printf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001162 if( i<nArg-1 ){
drhe05461c2015-12-30 13:36:57 +00001163 utf8_printf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +00001164 }else{
drhe05461c2015-12-30 13:36:57 +00001165 utf8_printf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001166 }
drh75897232000-05-29 14:26:00 +00001167 }
1168 break;
1169 }
drh1e5d0e92000-05-31 23:33:17 +00001170 case MODE_Html: {
1171 if( p->cnt++==0 && p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001172 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001173 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001174 raw_printf(p->out,"<TH>");
shane43d9cb22009-10-21 14:11:48 +00001175 output_html_string(p->out, azCol[i]);
mistachkinaae280e2015-12-31 19:06:24 +00001176 raw_printf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001177 }
mistachkinaae280e2015-12-31 19:06:24 +00001178 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001179 }
drh6a535342001-10-19 16:44:56 +00001180 if( azArg==0 ) break;
mistachkinaae280e2015-12-31 19:06:24 +00001181 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001182 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001183 raw_printf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +00001184 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00001185 raw_printf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001186 }
mistachkinaae280e2015-12-31 19:06:24 +00001187 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001188 break;
1189 }
drhfeac5f82004-08-01 00:10:45 +00001190 case MODE_Tcl: {
1191 if( p->cnt++==0 && p->showHeader ){
1192 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001193 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhe05461c2015-12-30 13:36:57 +00001194 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001195 }
drhe05461c2015-12-30 13:36:57 +00001196 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001197 }
1198 if( azArg==0 ) break;
1199 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +00001200 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
drhe05461c2015-12-30 13:36:57 +00001201 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001202 }
drhe05461c2015-12-30 13:36:57 +00001203 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001204 break;
1205 }
drh8e64d1c2004-10-07 00:32:39 +00001206 case MODE_Csv: {
mistachkin1fe36bb2016-04-04 02:16:44 +00001207 setBinaryMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001208 if( p->cnt++==0 && p->showHeader ){
1209 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001210 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001211 }
drhe05461c2015-12-30 13:36:57 +00001212 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001213 }
drh40253262014-10-17 21:35:05 +00001214 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +00001215 for(i=0; i<nArg; i++){
1216 output_csv(p, azArg[i], i<nArg-1);
1217 }
drhe05461c2015-12-30 13:36:57 +00001218 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001219 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001220 setTextMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001221 break;
1222 }
drh41f5f6e2016-10-21 17:39:30 +00001223 case MODE_Quote:
drh28bd4bc2000-06-15 15:57:22 +00001224 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +00001225 if( azArg==0 ) break;
drh41f5f6e2016-10-21 17:39:30 +00001226 if( p->cMode==MODE_Insert ){
1227 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
1228 if( p->showHeader ){
1229 raw_printf(p->out,"(");
1230 for(i=0; i<nArg; i++){
1231 char *zSep = i>0 ? ",": "";
1232 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
1233 }
1234 raw_printf(p->out,")");
mistachkin151c75a2015-04-07 21:16:40 +00001235 }
drh41f5f6e2016-10-21 17:39:30 +00001236 raw_printf(p->out," VALUES(");
drh59ce2c42016-11-03 13:12:28 +00001237 }else if( p->cnt==0 && p->showHeader ){
1238 for(i=0; i<nArg; i++){
mistachkin2f9a6132016-11-11 05:19:45 +00001239 if( i>0 ) raw_printf(p->out, ",");
drh59ce2c42016-11-03 13:12:28 +00001240 output_quoted_string(p->out, azCol[i]);
1241 }
mistachkin2f9a6132016-11-11 05:19:45 +00001242 raw_printf(p->out,"\n");
mistachkin151c75a2015-04-07 21:16:40 +00001243 }
drh59ce2c42016-11-03 13:12:28 +00001244 p->cnt++;
drh28bd4bc2000-06-15 15:57:22 +00001245 for(i=0; i<nArg; i++){
1246 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001247 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
mistachkinaae280e2015-12-31 19:06:24 +00001248 utf8_printf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001249 }else if( aiType && aiType[i]==SQLITE_TEXT ){
mistachkinaae280e2015-12-31 19:06:24 +00001250 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shanead6b8d02009-10-22 18:12:58 +00001251 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001252 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1253 || aiType[i]==SQLITE_FLOAT) ){
drhe05461c2015-12-30 13:36:57 +00001254 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001255 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1256 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1257 int nBlob = sqlite3_column_bytes(p->pStmt, i);
mistachkinaae280e2015-12-31 19:06:24 +00001258 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shane626a6e42009-10-22 17:30:15 +00001259 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001260 }else if( isNumber(azArg[i], 0) ){
drhe05461c2015-12-30 13:36:57 +00001261 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
drh28bd4bc2000-06-15 15:57:22 +00001262 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001263 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
drh28bd4bc2000-06-15 15:57:22 +00001264 output_quoted_string(p->out, azArg[i]);
1265 }
1266 }
drh41f5f6e2016-10-21 17:39:30 +00001267 raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n");
drh6a535342001-10-19 16:44:56 +00001268 break;
drh28bd4bc2000-06-15 15:57:22 +00001269 }
mistachkin636bf9f2014-07-19 20:15:16 +00001270 case MODE_Ascii: {
1271 if( p->cnt++==0 && p->showHeader ){
1272 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001273 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1274 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +00001275 }
drhe05461c2015-12-30 13:36:57 +00001276 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001277 }
1278 if( azArg==0 ) break;
1279 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001280 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1281 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001282 }
drhe05461c2015-12-30 13:36:57 +00001283 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001284 break;
1285 }
persicom1d0b8722002-04-18 02:53:04 +00001286 }
drh75897232000-05-29 14:26:00 +00001287 return 0;
1288}
1289
1290/*
shane626a6e42009-10-22 17:30:15 +00001291** This is the callback routine that the SQLite library
1292** invokes for each row of a query result.
1293*/
1294static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1295 /* since we don't have type info, call the shell_callback with a NULL value */
1296 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1297}
1298
1299/*
drhdcd87a92014-08-18 13:45:42 +00001300** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001301** the name of the table given. Escape any quote characters in the
1302** table name.
1303*/
drhdcd87a92014-08-18 13:45:42 +00001304static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001305 int i, n;
1306 int needQuote;
1307 char *z;
1308
1309 if( p->zDestTable ){
1310 free(p->zDestTable);
1311 p->zDestTable = 0;
1312 }
1313 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001314 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001315 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001316 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001317 needQuote = 1;
1318 if( zName[i]=='\'' ) n++;
1319 }
1320 }
1321 if( needQuote ) n += 2;
1322 z = p->zDestTable = malloc( n+1 );
1323 if( z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001324 raw_printf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001325 exit(1);
1326 }
1327 n = 0;
1328 if( needQuote ) z[n++] = '\'';
1329 for(i=0; zName[i]; i++){
1330 z[n++] = zName[i];
1331 if( zName[i]=='\'' ) z[n++] = '\'';
1332 }
1333 if( needQuote ) z[n++] = '\'';
1334 z[n] = 0;
1335}
1336
danielk19772a02e332004-06-05 08:04:36 +00001337/* zIn is either a pointer to a NULL-terminated string in memory obtained
1338** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1339** added to zIn, and the result returned in memory obtained from malloc().
1340** zIn, if it was not NULL, is freed.
1341**
mistachkin1fe36bb2016-04-04 02:16:44 +00001342** If the third argument, quote, is not '\0', then it is used as a
danielk19772a02e332004-06-05 08:04:36 +00001343** quote character for zAppend.
1344*/
drhc28490c2006-10-26 14:25:58 +00001345static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001346 int len;
1347 int i;
drh4f21c4a2008-12-10 22:15:00 +00001348 int nAppend = strlen30(zAppend);
1349 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001350
1351 len = nAppend+nIn+1;
1352 if( quote ){
1353 len += 2;
1354 for(i=0; i<nAppend; i++){
1355 if( zAppend[i]==quote ) len++;
1356 }
1357 }
1358
1359 zIn = (char *)realloc(zIn, len);
1360 if( !zIn ){
1361 return 0;
1362 }
1363
1364 if( quote ){
1365 char *zCsr = &zIn[nIn];
1366 *zCsr++ = quote;
1367 for(i=0; i<nAppend; i++){
1368 *zCsr++ = zAppend[i];
1369 if( zAppend[i]==quote ) *zCsr++ = quote;
1370 }
1371 *zCsr++ = quote;
1372 *zCsr++ = '\0';
1373 assert( (zCsr-zIn)==len );
1374 }else{
1375 memcpy(&zIn[nIn], zAppend, nAppend);
1376 zIn[len-1] = '\0';
1377 }
1378
1379 return zIn;
1380}
1381
drhdd3d4592004-08-30 01:54:05 +00001382
1383/*
drhb21a8e42012-01-28 21:08:51 +00001384** Execute a query statement that will generate SQL output. Print
1385** the result columns, comma-separated, on a line and then add a
1386** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001387**
drhb21a8e42012-01-28 21:08:51 +00001388** If the number of columns is 1 and that column contains text "--"
mistachkin1fe36bb2016-04-04 02:16:44 +00001389** then write the semicolon on a separate line. That way, if a
drhb21a8e42012-01-28 21:08:51 +00001390** "--" comment occurs at the end of the statement, the comment
1391** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001392*/
drh157e29a2009-05-21 15:15:00 +00001393static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001394 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001395 const char *zSelect, /* SELECT statement to extract content */
1396 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001397){
drhdd3d4592004-08-30 01:54:05 +00001398 sqlite3_stmt *pSelect;
1399 int rc;
drhb21a8e42012-01-28 21:08:51 +00001400 int nResult;
1401 int i;
1402 const char *z;
drhc7181902014-02-27 15:04:13 +00001403 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001404 if( rc!=SQLITE_OK || !pSelect ){
mistachkinaae280e2015-12-31 19:06:24 +00001405 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1406 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001407 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001408 return rc;
1409 }
1410 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001411 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001412 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001413 if( zFirstRow ){
drhe05461c2015-12-30 13:36:57 +00001414 utf8_printf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001415 zFirstRow = 0;
1416 }
drhb21a8e42012-01-28 21:08:51 +00001417 z = (const char*)sqlite3_column_text(pSelect, 0);
drhe05461c2015-12-30 13:36:57 +00001418 utf8_printf(p->out, "%s", z);
mistachkin1fe36bb2016-04-04 02:16:44 +00001419 for(i=1; i<nResult; i++){
drhe05461c2015-12-30 13:36:57 +00001420 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
drhb21a8e42012-01-28 21:08:51 +00001421 }
1422 if( z==0 ) z = "";
1423 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1424 if( z[0] ){
mistachkinaae280e2015-12-31 19:06:24 +00001425 raw_printf(p->out, "\n;\n");
drhb21a8e42012-01-28 21:08:51 +00001426 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001427 raw_printf(p->out, ";\n");
mistachkin1fe36bb2016-04-04 02:16:44 +00001428 }
drhdd3d4592004-08-30 01:54:05 +00001429 rc = sqlite3_step(pSelect);
1430 }
drh2f464a02011-10-13 00:41:49 +00001431 rc = sqlite3_finalize(pSelect);
1432 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00001433 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1434 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001435 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001436 }
1437 return rc;
drhdd3d4592004-08-30 01:54:05 +00001438}
1439
shane626a6e42009-10-22 17:30:15 +00001440/*
1441** Allocate space and save off current error string.
1442*/
1443static char *save_err_msg(
1444 sqlite3 *db /* Database to query */
1445){
1446 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001447 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001448 if( zErrMsg ){
1449 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1450 }
1451 return zErrMsg;
1452}
1453
drh34784902016-02-27 17:12:36 +00001454#ifdef __linux__
1455/*
1456** Attempt to display I/O stats on Linux using /proc/PID/io
1457*/
1458static void displayLinuxIoStats(FILE *out){
1459 FILE *in;
1460 char z[200];
1461 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
1462 in = fopen(z, "rb");
1463 if( in==0 ) return;
1464 while( fgets(z, sizeof(z), in)!=0 ){
1465 static const struct {
1466 const char *zPattern;
1467 const char *zDesc;
1468 } aTrans[] = {
drhfc1a84c2016-02-27 19:19:22 +00001469 { "rchar: ", "Bytes received by read():" },
1470 { "wchar: ", "Bytes sent to write():" },
1471 { "syscr: ", "Read() system calls:" },
1472 { "syscw: ", "Write() system calls:" },
1473 { "read_bytes: ", "Bytes read from storage:" },
1474 { "write_bytes: ", "Bytes written to storage:" },
1475 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
drh34784902016-02-27 17:12:36 +00001476 };
1477 int i;
1478 for(i=0; i<ArraySize(aTrans); i++){
1479 int n = (int)strlen(aTrans[i].zPattern);
1480 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
mistachkin8145fc62016-09-16 20:39:21 +00001481 utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
drh34784902016-02-27 17:12:36 +00001482 break;
1483 }
1484 }
1485 }
1486 fclose(in);
mistachkin1fe36bb2016-04-04 02:16:44 +00001487}
drh34784902016-02-27 17:12:36 +00001488#endif
1489
1490
shane626a6e42009-10-22 17:30:15 +00001491/*
shaneh642d8b82010-07-28 16:05:34 +00001492** Display memory stats.
1493*/
1494static int display_stats(
1495 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001496 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001497 int bReset /* True to reset the stats */
1498){
1499 int iCur;
1500 int iHiwtr;
1501
1502 if( pArg && pArg->out ){
mistachkin1fe36bb2016-04-04 02:16:44 +00001503
shaneh642d8b82010-07-28 16:05:34 +00001504 iHiwtr = iCur = -1;
1505 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001506 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001507 "Memory Used: %d (max %d) bytes\n",
1508 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001509 iHiwtr = iCur = -1;
1510 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001511 raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001512 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001513 if( pArg->shellFlgs & SHFLG_Pagecache ){
1514 iHiwtr = iCur = -1;
1515 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001516 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001517 "Number of Pcache Pages Used: %d (max %d) pages\n",
1518 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001519 }
shaneh642d8b82010-07-28 16:05:34 +00001520 iHiwtr = iCur = -1;
1521 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001522 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001523 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1524 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001525 if( pArg->shellFlgs & SHFLG_Scratch ){
1526 iHiwtr = iCur = -1;
1527 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001528 raw_printf(pArg->out,
1529 "Number of Scratch Allocations Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001530 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001531 }
shaneh642d8b82010-07-28 16:05:34 +00001532 iHiwtr = iCur = -1;
1533 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001534 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001535 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1536 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001537 iHiwtr = iCur = -1;
1538 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001539 raw_printf(pArg->out, "Largest Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001540 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001541 iHiwtr = iCur = -1;
1542 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001543 raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001544 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001545 iHiwtr = iCur = -1;
1546 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001547 raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001548 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001549#ifdef YYTRACKMAXSTACKDEPTH
1550 iHiwtr = iCur = -1;
1551 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001552 raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001553 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001554#endif
1555 }
1556
1557 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001558 if( pArg->shellFlgs & SHFLG_Lookaside ){
1559 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001560 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1561 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001562 raw_printf(pArg->out,
1563 "Lookaside Slots Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001564 iCur, iHiwtr);
1565 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1566 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001567 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
1568 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001569 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1570 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001571 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
1572 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001573 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1574 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001575 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
1576 iHiwtr);
drh44dec872014-08-30 15:49:25 +00001577 }
shaneh642d8b82010-07-28 16:05:34 +00001578 iHiwtr = iCur = -1;
1579 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001580 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
1581 iCur);
drh4ace5362014-11-10 14:42:28 +00001582 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001583 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001584 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
drhc78e6e42011-09-23 18:58:23 +00001585 iHiwtr = iCur = -1;
1586 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001587 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001588 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001589 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001590 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
drhfbbcd5d2012-03-24 20:09:33 +00001591 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001592 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001593 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001594 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001595 iHiwtr = iCur = -1;
1596 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001597 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001598 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001599 }
1600
1601 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001602 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1603 bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001604 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001605 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001606 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001607 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001608 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001609 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001610 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001611 }
1612
drh34784902016-02-27 17:12:36 +00001613#ifdef __linux__
1614 displayLinuxIoStats(pArg->out);
1615#endif
1616
dan5a790282015-08-07 20:06:14 +00001617 /* Do not remove this machine readable comment: extra-stats-output-here */
1618
shaneh642d8b82010-07-28 16:05:34 +00001619 return 0;
1620}
1621
1622/*
dan8d1edb92014-11-05 09:07:28 +00001623** Display scan stats.
1624*/
1625static void display_scanstats(
1626 sqlite3 *db, /* Database to query */
1627 ShellState *pArg /* Pointer to ShellState */
1628){
drhf5ed7ad2015-06-15 14:43:25 +00001629#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1630 UNUSED_PARAMETER(db);
1631 UNUSED_PARAMETER(pArg);
1632#else
drh15f23c22014-11-06 12:46:16 +00001633 int i, k, n, mx;
mistachkinaae280e2015-12-31 19:06:24 +00001634 raw_printf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001635 mx = 0;
1636 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001637 double rEstLoop = 1.0;
1638 for(i=n=0; 1; i++){
1639 sqlite3_stmt *p = pArg->pStmt;
1640 sqlite3_int64 nLoop, nVisit;
1641 double rEst;
1642 int iSid;
1643 const char *zExplain;
1644 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1645 break;
1646 }
1647 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001648 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001649 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001650 if( n==0 ){
1651 rEstLoop = (double)nLoop;
mistachkinaae280e2015-12-31 19:06:24 +00001652 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001653 }
drh42f30bc2014-11-06 12:08:21 +00001654 n++;
1655 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1656 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1657 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
drhe05461c2015-12-30 13:36:57 +00001658 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
drh42f30bc2014-11-06 12:08:21 +00001659 rEstLoop *= rEst;
mistachkin1fe36bb2016-04-04 02:16:44 +00001660 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001661 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001662 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001663 );
dan8d1edb92014-11-05 09:07:28 +00001664 }
dan8d1edb92014-11-05 09:07:28 +00001665 }
mistachkinaae280e2015-12-31 19:06:24 +00001666 raw_printf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001667#endif
dan8d1edb92014-11-05 09:07:28 +00001668}
1669
1670/*
dana98bf362013-11-13 18:35:01 +00001671** Parameter azArray points to a zero-terminated array of strings. zStr
1672** points to a single nul-terminated string. Return non-zero if zStr
1673** is equal, according to strcmp(), to any of the strings in the array.
1674** Otherwise, return zero.
1675*/
1676static int str_in_array(const char *zStr, const char **azArray){
1677 int i;
1678 for(i=0; azArray[i]; i++){
1679 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1680 }
1681 return 0;
1682}
1683
1684/*
1685** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001686** and populate the ShellState.aiIndent[] array with the number of
mistachkin1fe36bb2016-04-04 02:16:44 +00001687** spaces each opcode should be indented before it is output.
dana98bf362013-11-13 18:35:01 +00001688**
1689** The indenting rules are:
1690**
1691** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1692** all opcodes that occur between the p2 jump destination and the opcode
1693** itself by 2 spaces.
1694**
drh01752bc2013-11-14 23:59:33 +00001695** * For each "Goto", if the jump destination is earlier in the program
1696** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001697** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001698** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001699** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001700** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001701*/
drhdcd87a92014-08-18 13:45:42 +00001702static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001703 const char *zSql; /* The text of the SQL statement */
1704 const char *z; /* Used to check if this is an EXPLAIN */
1705 int *abYield = 0; /* True if op is an OP_Yield */
1706 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001707 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001708
drh8ad0de32014-03-20 18:45:27 +00001709 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1710 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001711 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1712 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001713 const char *azGoto[] = { "Goto", 0 };
1714
1715 /* Try to figure out if this is really an EXPLAIN statement. If this
1716 ** cannot be verified, return early. */
drh87a24aa2016-02-09 20:04:07 +00001717 if( sqlite3_column_count(pSql)!=8 ){
1718 p->cMode = p->mode;
1719 return;
1720 }
dana98bf362013-11-13 18:35:01 +00001721 zSql = sqlite3_sql(pSql);
1722 if( zSql==0 ) return;
1723 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
drh87a24aa2016-02-09 20:04:07 +00001724 if( sqlite3_strnicmp(z, "explain", 7) ){
1725 p->cMode = p->mode;
1726 return;
1727 }
dana98bf362013-11-13 18:35:01 +00001728
1729 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1730 int i;
danc4650bb2013-11-18 08:41:06 +00001731 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001732 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001733
1734 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1735 ** p2 is an instruction address, set variable p2op to the index of that
1736 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1737 ** the current instruction is part of a sub-program generated by an
1738 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001739 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001740 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001741
1742 /* Grow the p->aiIndent array as required */
1743 if( iOp>=nAlloc ){
drh87a24aa2016-02-09 20:04:07 +00001744 if( iOp==0 ){
1745 /* Do further verfication that this is explain output. Abort if
1746 ** it is not */
1747 static const char *explainCols[] = {
1748 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
1749 int jj;
1750 for(jj=0; jj<ArraySize(explainCols); jj++){
1751 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
1752 p->cMode = p->mode;
1753 sqlite3_reset(pSql);
1754 return;
1755 }
1756 }
1757 }
dana98bf362013-11-13 18:35:01 +00001758 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001759 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1760 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001761 }
1762 abYield[iOp] = str_in_array(zOp, azYield);
1763 p->aiIndent[iOp] = 0;
1764 p->nIndent = iOp+1;
1765
1766 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001767 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001768 }
drhfe705102014-03-06 13:38:37 +00001769 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1770 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1771 ){
drheacd29d2016-04-15 15:03:27 +00001772 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001773 }
1774 }
1775
danc4650bb2013-11-18 08:41:06 +00001776 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001777 sqlite3_free(abYield);
1778 sqlite3_reset(pSql);
1779}
1780
1781/*
1782** Free the array allocated by explain_data_prepare().
1783*/
drhdcd87a92014-08-18 13:45:42 +00001784static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001785 sqlite3_free(p->aiIndent);
1786 p->aiIndent = 0;
1787 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001788 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001789}
1790
1791/*
drheacd29d2016-04-15 15:03:27 +00001792** Disable and restore .wheretrace and .selecttrace settings.
1793*/
1794#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1795extern int sqlite3SelectTrace;
1796static int savedSelectTrace;
1797#endif
1798#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1799extern int sqlite3WhereTrace;
1800static int savedWhereTrace;
1801#endif
1802static void disable_debug_trace_modes(void){
1803#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1804 savedSelectTrace = sqlite3SelectTrace;
1805 sqlite3SelectTrace = 0;
1806#endif
1807#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1808 savedWhereTrace = sqlite3WhereTrace;
1809 sqlite3WhereTrace = 0;
1810#endif
1811}
1812static void restore_debug_trace_modes(void){
1813#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1814 sqlite3SelectTrace = savedSelectTrace;
1815#endif
1816#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1817 sqlite3WhereTrace = savedWhereTrace;
1818#endif
1819}
1820
1821/*
1822** Run a prepared statement
1823*/
1824static void exec_prepared_stmt(
1825 ShellState *pArg, /* Pointer to ShellState */
1826 sqlite3_stmt *pStmt, /* Statment to run */
1827 int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
1828){
1829 int rc;
1830
1831 /* perform the first step. this will tell us if we
1832 ** have a result set or not and how wide it is.
1833 */
1834 rc = sqlite3_step(pStmt);
1835 /* if we have a result set... */
1836 if( SQLITE_ROW == rc ){
1837 /* if we have a callback... */
1838 if( xCallback ){
1839 /* allocate space for col name ptr, value ptr, and type */
1840 int nCol = sqlite3_column_count(pStmt);
1841 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
1842 if( !pData ){
1843 rc = SQLITE_NOMEM;
1844 }else{
1845 char **azCols = (char **)pData; /* Names of result columns */
1846 char **azVals = &azCols[nCol]; /* Results */
1847 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1848 int i, x;
1849 assert(sizeof(int) <= sizeof(char *));
1850 /* save off ptrs to column names */
1851 for(i=0; i<nCol; i++){
1852 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1853 }
1854 do{
1855 /* extract the data and data types */
1856 for(i=0; i<nCol; i++){
1857 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1858 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
1859 azVals[i] = "";
1860 }else{
1861 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1862 }
1863 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1864 rc = SQLITE_NOMEM;
1865 break; /* from for */
1866 }
1867 } /* end for */
1868
1869 /* if data and types extracted successfully... */
1870 if( SQLITE_ROW == rc ){
1871 /* call the supplied callback with the result row data */
1872 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1873 rc = SQLITE_ABORT;
1874 }else{
1875 rc = sqlite3_step(pStmt);
1876 }
1877 }
1878 } while( SQLITE_ROW == rc );
1879 sqlite3_free(pData);
1880 }
1881 }else{
1882 do{
1883 rc = sqlite3_step(pStmt);
1884 } while( rc == SQLITE_ROW );
1885 }
1886 }
1887}
1888
1889/*
mistachkin1fe36bb2016-04-04 02:16:44 +00001890** Execute a statement or set of statements. Print
1891** any result rows/columns depending on the current mode
shane626a6e42009-10-22 17:30:15 +00001892** set via the supplied callback.
1893**
mistachkin1fe36bb2016-04-04 02:16:44 +00001894** This is very similar to SQLite's built-in sqlite3_exec()
1895** function except it takes a slightly different callback
shane626a6e42009-10-22 17:30:15 +00001896** and callback data argument.
1897*/
1898static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001899 sqlite3 *db, /* An open database */
1900 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001901 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001902 /* (not the same as sqlite3_exec) */
1903 ShellState *pArg, /* Pointer to ShellState */
1904 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001905){
dan4564ced2010-01-05 04:59:56 +00001906 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1907 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001908 int rc2;
dan4564ced2010-01-05 04:59:56 +00001909 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001910
1911 if( pzErrMsg ){
1912 *pzErrMsg = NULL;
1913 }
1914
shaneb9fc17d2009-10-22 21:23:35 +00001915 while( zSql[0] && (SQLITE_OK == rc) ){
drheacd29d2016-04-15 15:03:27 +00001916 static const char *zStmtSql;
shaneb9fc17d2009-10-22 21:23:35 +00001917 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1918 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001919 if( pzErrMsg ){
1920 *pzErrMsg = save_err_msg(db);
1921 }
1922 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001923 if( !pStmt ){
1924 /* this happens for a comment or white-space */
1925 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001926 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001927 continue;
1928 }
drheacd29d2016-04-15 15:03:27 +00001929 zStmtSql = sqlite3_sql(pStmt);
drh60275612016-11-03 02:25:30 +00001930 if( zStmtSql==0 ) zStmtSql = "";
drheacd29d2016-04-15 15:03:27 +00001931 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
shane626a6e42009-10-22 17:30:15 +00001932
shaneh642d8b82010-07-28 16:05:34 +00001933 /* save off the prepared statment handle and reset row count */
1934 if( pArg ){
1935 pArg->pStmt = pStmt;
1936 pArg->cnt = 0;
1937 }
1938
shanehb7977c52010-01-18 18:17:10 +00001939 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001940 if( pArg && pArg->echoOn ){
drhe05461c2015-12-30 13:36:57 +00001941 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001942 }
shanehb7977c52010-01-18 18:17:10 +00001943
drhefbf3b12014-02-28 20:47:24 +00001944 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
drheacd29d2016-04-15 15:03:27 +00001945 if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
drhefbf3b12014-02-28 20:47:24 +00001946 sqlite3_stmt *pExplain;
drheacd29d2016-04-15 15:03:27 +00001947 char *zEQP;
1948 disable_debug_trace_modes();
1949 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
drhefbf3b12014-02-28 20:47:24 +00001950 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1951 if( rc==SQLITE_OK ){
1952 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001953 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1954 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1955 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001956 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001957 }
1958 }
1959 sqlite3_finalize(pExplain);
1960 sqlite3_free(zEQP);
drheacd29d2016-04-15 15:03:27 +00001961 if( pArg->autoEQP>=2 ){
1962 /* Also do an EXPLAIN for ".eqp full" mode */
1963 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
1964 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1965 if( rc==SQLITE_OK ){
1966 pArg->cMode = MODE_Explain;
1967 explain_data_prepare(pArg, pExplain);
1968 exec_prepared_stmt(pArg, pExplain, xCallback);
1969 explain_data_delete(pArg);
1970 }
1971 sqlite3_finalize(pExplain);
1972 sqlite3_free(zEQP);
1973 }
1974 restore_debug_trace_modes();
drhefbf3b12014-02-28 20:47:24 +00001975 }
1976
drh700c2522016-02-09 18:39:25 +00001977 if( pArg ){
1978 pArg->cMode = pArg->mode;
drh87a24aa2016-02-09 20:04:07 +00001979 if( pArg->autoExplain
1980 && sqlite3_column_count(pStmt)==8
drheacd29d2016-04-15 15:03:27 +00001981 && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
drh700c2522016-02-09 18:39:25 +00001982 ){
1983 pArg->cMode = MODE_Explain;
1984 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001985
drh700c2522016-02-09 18:39:25 +00001986 /* If the shell is currently in ".explain" mode, gather the extra
1987 ** data required to add indents to the output.*/
1988 if( pArg->cMode==MODE_Explain ){
1989 explain_data_prepare(pArg, pStmt);
1990 }
dana98bf362013-11-13 18:35:01 +00001991 }
1992
drheacd29d2016-04-15 15:03:27 +00001993 exec_prepared_stmt(pArg, pStmt, xCallback);
dana98bf362013-11-13 18:35:01 +00001994 explain_data_delete(pArg);
1995
shaneh642d8b82010-07-28 16:05:34 +00001996 /* print usage stats if stats on */
1997 if( pArg && pArg->statsOn ){
1998 display_stats(db, pArg, 0);
1999 }
2000
dan0fbee292017-01-21 15:58:42 +00002001 if( pArg && pArg->vmstepsOn && pStmt ){
2002 int iCur = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_VM_STEP, 0);
2003 FILE *out = pArg->traceOut ? pArg->traceOut : pArg->out;
2004 raw_printf(out, "VM steps: %d\n", iCur);
2005 }
2006
dan8d1edb92014-11-05 09:07:28 +00002007 /* print loop-counters if required */
2008 if( pArg && pArg->scanstatsOn ){
2009 display_scanstats(db, pArg);
2010 }
2011
mistachkin1fe36bb2016-04-04 02:16:44 +00002012 /* Finalize the statement just executed. If this fails, save a
dan4564ced2010-01-05 04:59:56 +00002013 ** copy of the error message. Otherwise, set zSql to point to the
2014 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00002015 rc2 = sqlite3_finalize(pStmt);
2016 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00002017 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00002018 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00002019 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00002020 }else if( pzErrMsg ){
2021 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00002022 }
shaneh642d8b82010-07-28 16:05:34 +00002023
2024 /* clear saved stmt handle */
2025 if( pArg ){
2026 pArg->pStmt = NULL;
2027 }
shane626a6e42009-10-22 17:30:15 +00002028 }
shaneb9fc17d2009-10-22 21:23:35 +00002029 } /* end while */
shane626a6e42009-10-22 17:30:15 +00002030
2031 return rc;
2032}
2033
drhdd3d4592004-08-30 01:54:05 +00002034
drh33048c02001-10-01 14:29:22 +00002035/*
drh4c653a02000-06-07 01:27:47 +00002036** This is a different callback routine used for dumping the database.
2037** Each row received by this callback consists of a table name,
2038** the table type ("index" or "table") and SQL to create the table.
2039** This routine should print text sufficient to recreate the table.
2040*/
2041static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00002042 int rc;
2043 const char *zTable;
2044 const char *zType;
2045 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00002046 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00002047 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00002048
drh902b9ee2008-12-05 17:17:07 +00002049 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00002050 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00002051 zTable = azArg[0];
2052 zType = azArg[1];
2053 zSql = azArg[2];
mistachkin1fe36bb2016-04-04 02:16:44 +00002054
drh00b950d2005-09-11 02:03:03 +00002055 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00002056 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00002057 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002058 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00002059 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
2060 return 0;
drh45e29d82006-11-20 16:21:10 +00002061 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
2062 char *zIns;
2063 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00002064 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00002065 p->writableSchema = 1;
2066 }
2067 zIns = sqlite3_mprintf(
2068 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
2069 "VALUES('table','%q','%q',0,'%q');",
2070 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00002071 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00002072 sqlite3_free(zIns);
2073 return 0;
drh00b950d2005-09-11 02:03:03 +00002074 }else{
drh79f20e92016-12-13 23:22:39 +00002075 printSchemaLine(p->out, zSql, ";\n");
drhf8eb96a2005-02-03 00:42:34 +00002076 }
danielk19772a02e332004-06-05 08:04:36 +00002077
2078 if( strcmp(zType, "table")==0 ){
2079 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00002080 char *zSelect = 0;
2081 char *zTableInfo = 0;
2082 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00002083 int nRow = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +00002084
danielk19772a02e332004-06-05 08:04:36 +00002085 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
2086 zTableInfo = appendText(zTableInfo, zTable, '"');
2087 zTableInfo = appendText(zTableInfo, ");", 0);
2088
drhc7181902014-02-27 15:04:13 +00002089 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00002090 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00002091 if( rc!=SQLITE_OK || !pTableInfo ){
2092 return 1;
2093 }
2094
2095 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00002096 /* Always quote the table name, even if it appears to be pure ascii,
2097 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
2098 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00002099 if( zTmp ){
2100 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00002101 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00002102 }
2103 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
2104 rc = sqlite3_step(pTableInfo);
2105 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00002106 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00002107 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00002108 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00002109 rc = sqlite3_step(pTableInfo);
2110 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00002111 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00002112 }else{
2113 zSelect = appendText(zSelect, ") ", 0);
2114 }
drh157e29a2009-05-21 15:15:00 +00002115 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00002116 }
2117 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00002118 if( rc!=SQLITE_OK || nRow==0 ){
2119 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00002120 return 1;
2121 }
2122 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
2123 zSelect = appendText(zSelect, zTable, '"');
2124
drh2f464a02011-10-13 00:41:49 +00002125 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00002126 if( rc==SQLITE_CORRUPT ){
2127 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00002128 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00002129 }
drh85e72432012-04-11 11:38:53 +00002130 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00002131 }
drh4c653a02000-06-07 01:27:47 +00002132 return 0;
2133}
2134
2135/*
drh45e29d82006-11-20 16:21:10 +00002136** Run zQuery. Use dump_callback() as the callback routine so that
2137** the contents of the query are output as SQL statements.
2138**
drhdd3d4592004-08-30 01:54:05 +00002139** If we get a SQLITE_CORRUPT error, rerun the query after appending
2140** "ORDER BY rowid DESC" to the end.
2141*/
2142static int run_schema_dump_query(
mistachkin1fe36bb2016-04-04 02:16:44 +00002143 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00002144 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00002145){
2146 int rc;
drh2f464a02011-10-13 00:41:49 +00002147 char *zErr = 0;
2148 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00002149 if( rc==SQLITE_CORRUPT ){
2150 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00002151 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00002152 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00002153 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00002154 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002155 sqlite3_free(zErr);
2156 zErr = 0;
2157 }
drhdd3d4592004-08-30 01:54:05 +00002158 zQ2 = malloc( len+100 );
2159 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00002160 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00002161 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
2162 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002163 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002164 }else{
2165 rc = SQLITE_CORRUPT;
2166 }
2167 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00002168 free(zQ2);
2169 }
2170 return rc;
2171}
2172
2173/*
drh75897232000-05-29 14:26:00 +00002174** Text of a help message
2175*/
persicom1d0b8722002-04-18 02:53:04 +00002176static char zHelp[] =
drha0daa752016-09-16 11:53:10 +00002177#ifndef SQLITE_OMIT_AUTHORIZATION
drhde613c62016-04-04 17:23:10 +00002178 ".auth ON|OFF Show authorizer callbacks\n"
drha0daa752016-09-16 11:53:10 +00002179#endif
drh9ff849f2009-02-04 20:55:57 +00002180 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00002181 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00002182 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00002183 ".changes on|off Show number of rows changed by SQL\n"
drh2db82112016-09-15 21:35:24 +00002184 ".check GLOB Fail if output since .testcase does not match\n"
drh4bbcf102014-02-06 02:46:08 +00002185 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00002186 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00002187 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00002188 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00002189 " If TABLE specified, only dump tables matching\n"
2190 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00002191 ".echo on|off Turn command echo on or off\n"
drheacd29d2016-04-15 15:03:27 +00002192 ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00002193 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00002194 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drh4926fec2016-04-13 15:33:42 +00002195 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00002196 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00002197 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00002198 ".import FILE TABLE Import data from FILE into TABLE\n"
drh16eb5942016-11-03 13:01:38 +00002199#ifndef SQLITE_OMIT_TEST_CONTROL
2200 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n"
2201#endif
drh0e55db12015-02-06 14:51:13 +00002202 ".indexes ?TABLE? Show names of all indexes\n"
2203 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00002204 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00002205#ifdef SQLITE_ENABLE_IOTRACE
2206 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
2207#endif
drh1a513372015-05-02 17:40:23 +00002208 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh3fd9f332016-12-16 18:41:11 +00002209 ".lint OPTIONS Report potential schema issues. Options:\n"
2210 " fkey-indexes Find missing foreign key indexes\n"
drh70df4fe2006-06-13 15:12:21 +00002211#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002212 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00002213#endif
drh127f9d72010-02-23 01:47:00 +00002214 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00002215 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00002216 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00002217 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00002218 " column Left-aligned columns. (See .width)\n"
2219 " html HTML <table> code\n"
2220 " insert SQL insert statements for TABLE\n"
2221 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00002222 " list Values delimited by .separator strings\n"
drh41f5f6e2016-10-21 17:39:30 +00002223 " quote Escape answers as for SQL\n"
drhb860bc92004-08-04 15:16:55 +00002224 " tabs Tab-separated values\n"
2225 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00002226 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00002227 ".once FILENAME Output for the next SQL command only to FILENAME\n"
mistachkin8145fc62016-09-16 20:39:21 +00002228 ".open ?--new? ?FILE? Close existing database and reopen FILE\n"
drhcd0509e2016-09-16 00:26:08 +00002229 " The --new starts with an empty file\n"
drhc2ce0be2014-05-29 12:36:14 +00002230 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00002231 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002232 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002233 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00002234 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00002235 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00002236 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00002237 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh4926fec2016-04-13 15:33:42 +00002238 ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
2239 " Add --indent for pretty-printing\n"
mistachkine0d68852014-12-11 03:12:33 +00002240 ".separator COL ?ROW? Change the column separator and optionally the row\n"
2241 " separator for both the output mode and .import\n"
drhe6229612014-08-18 15:08:26 +00002242#if defined(SQLITE_ENABLE_SESSION)
2243 ".session CMD ... Create or control sessions\n"
2244#endif
drh62cdde52014-05-28 20:22:28 +00002245 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00002246 ".show Show the current values for various settings\n"
drh34784902016-02-27 17:12:36 +00002247 ".stats ?on|off? Show stats or turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00002248 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00002249 ".tables ?TABLE? List names of tables\n"
2250 " If TABLE specified, only list tables matching\n"
2251 " LIKE pattern TABLE.\n"
drh760c8162016-09-16 02:52:22 +00002252 ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
drh2dfbbca2000-07-28 14:32:48 +00002253 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00002254 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00002255 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00002256 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00002257 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00002258 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00002259 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00002260 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00002261;
2262
drhe6229612014-08-18 15:08:26 +00002263#if defined(SQLITE_ENABLE_SESSION)
2264/*
2265** Print help information for the ".sessions" command
2266*/
2267void session_help(ShellState *p){
mistachkin899c5c92016-04-03 20:50:02 +00002268 raw_printf(p->out,
drhe6229612014-08-18 15:08:26 +00002269 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
2270 "If ?NAME? is omitted, the first defined session is used.\n"
2271 "Subcommands:\n"
2272 " attach TABLE Attach TABLE\n"
2273 " changeset FILE Write a changeset into FILE\n"
2274 " close Close one session\n"
2275 " enable ?BOOLEAN? Set or query the enable bit\n"
mistachkin1fe36bb2016-04-04 02:16:44 +00002276 " filter GLOB... Reject tables matching GLOBs\n"
drhe6229612014-08-18 15:08:26 +00002277 " indirect ?BOOLEAN? Mark or query the indirect status\n"
2278 " isempty Query whether the session is empty\n"
2279 " list List currently open session names\n"
2280 " open DB NAME Open a new session on DB\n"
2281 " patchset FILE Write a patchset into FILE\n"
2282 );
2283}
2284#endif
2285
2286
drhdaffd0e2001-04-11 14:28:42 +00002287/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00002288static int process_input(ShellState *p, FILE *in);
drh2db82112016-09-15 21:35:24 +00002289
drh2db82112016-09-15 21:35:24 +00002290/*
dan11da0022016-12-17 08:18:05 +00002291** Read the content of file zName into memory obtained from sqlite3_malloc64()
2292** and return a pointer to the buffer. The caller is responsible for freeing
2293** the memory.
drh2db82112016-09-15 21:35:24 +00002294**
dan11da0022016-12-17 08:18:05 +00002295** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes
2296** read.
2297**
2298** For convenience, a nul-terminator byte is always appended to the data read
2299** from the file before the buffer is returned. This byte is not included in
2300** the final value of (*pnByte), if applicable.
2301**
2302** NULL is returned if any error is encountered. The final value of *pnByte
2303** is undefined in this case.
drh2db82112016-09-15 21:35:24 +00002304*/
dan11da0022016-12-17 08:18:05 +00002305static char *readFile(const char *zName, int *pnByte){
drh2db82112016-09-15 21:35:24 +00002306 FILE *in = fopen(zName, "rb");
2307 long nIn;
drhd1459152016-09-16 19:11:03 +00002308 size_t nRead;
drh2db82112016-09-15 21:35:24 +00002309 char *pBuf;
2310 if( in==0 ) return 0;
2311 fseek(in, 0, SEEK_END);
2312 nIn = ftell(in);
2313 rewind(in);
drhd1459152016-09-16 19:11:03 +00002314 pBuf = sqlite3_malloc64( nIn+1 );
drh2db82112016-09-15 21:35:24 +00002315 if( pBuf==0 ) return 0;
drhd1459152016-09-16 19:11:03 +00002316 nRead = fread(pBuf, nIn, 1, in);
2317 fclose(in);
2318 if( nRead!=1 ){
drh2db82112016-09-15 21:35:24 +00002319 sqlite3_free(pBuf);
2320 return 0;
2321 }
drhd1459152016-09-16 19:11:03 +00002322 pBuf[nIn] = 0;
dan11da0022016-12-17 08:18:05 +00002323 if( pnByte ) *pnByte = nIn;
drh2db82112016-09-15 21:35:24 +00002324 return pBuf;
2325}
2326
drhba5b0932014-07-24 12:39:59 +00002327/*
2328** Implementation of the "readfile(X)" SQL function. The entire content
2329** of the file named X is read and returned as a BLOB. NULL is returned
2330** if the file does not exist or is unreadable.
2331*/
2332static void readfileFunc(
2333 sqlite3_context *context,
2334 int argc,
2335 sqlite3_value **argv
2336){
2337 const char *zName;
drhba5b0932014-07-24 12:39:59 +00002338 void *pBuf;
dan11da0022016-12-17 08:18:05 +00002339 int nBuf;
drhba5b0932014-07-24 12:39:59 +00002340
drhf5ed7ad2015-06-15 14:43:25 +00002341 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002342 zName = (const char*)sqlite3_value_text(argv[0]);
2343 if( zName==0 ) return;
dan11da0022016-12-17 08:18:05 +00002344 pBuf = readFile(zName, &nBuf);
2345 if( pBuf ) sqlite3_result_blob(context, pBuf, nBuf, sqlite3_free);
drhba5b0932014-07-24 12:39:59 +00002346}
2347
2348/*
2349** Implementation of the "writefile(X,Y)" SQL function. The argument Y
2350** is written into file X. The number of bytes written is returned. Or
2351** NULL is returned if something goes wrong, such as being unable to open
2352** file X for writing.
2353*/
2354static void writefileFunc(
2355 sqlite3_context *context,
2356 int argc,
2357 sqlite3_value **argv
2358){
2359 FILE *out;
2360 const char *z;
drhba5b0932014-07-24 12:39:59 +00002361 sqlite3_int64 rc;
2362 const char *zFile;
2363
drhf5ed7ad2015-06-15 14:43:25 +00002364 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002365 zFile = (const char*)sqlite3_value_text(argv[0]);
2366 if( zFile==0 ) return;
2367 out = fopen(zFile, "wb");
2368 if( out==0 ) return;
2369 z = (const char*)sqlite3_value_blob(argv[1]);
2370 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002371 rc = 0;
2372 }else{
drh490fe862014-08-11 14:21:32 +00002373 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002374 }
2375 fclose(out);
2376 sqlite3_result_int64(context, rc);
2377}
drhdaffd0e2001-04-11 14:28:42 +00002378
drhe6229612014-08-18 15:08:26 +00002379#if defined(SQLITE_ENABLE_SESSION)
2380/*
2381** Close a single OpenSession object and release all of its associated
2382** resources.
2383*/
2384static void session_close(OpenSession *pSession){
2385 int i;
2386 sqlite3session_delete(pSession->p);
2387 sqlite3_free(pSession->zName);
2388 for(i=0; i<pSession->nFilter; i++){
2389 sqlite3_free(pSession->azFilter[i]);
2390 }
2391 sqlite3_free(pSession->azFilter);
2392 memset(pSession, 0, sizeof(OpenSession));
2393}
2394#endif
2395
2396/*
drh51b55a32016-04-04 12:38:05 +00002397** Close all OpenSession objects and release all associated resources.
drhe6229612014-08-18 15:08:26 +00002398*/
drhe6229612014-08-18 15:08:26 +00002399#if defined(SQLITE_ENABLE_SESSION)
drh51b55a32016-04-04 12:38:05 +00002400static void session_close_all(ShellState *p){
drhe6229612014-08-18 15:08:26 +00002401 int i;
2402 for(i=0; i<p->nSession; i++){
2403 session_close(&p->aSession[i]);
2404 }
2405 p->nSession = 0;
drhe6229612014-08-18 15:08:26 +00002406}
drh51b55a32016-04-04 12:38:05 +00002407#else
2408# define session_close_all(X)
2409#endif
drhe6229612014-08-18 15:08:26 +00002410
drh75897232000-05-29 14:26:00 +00002411/*
drh03168ca2014-08-18 20:01:31 +00002412** Implementation of the xFilter function for an open session. Omit
2413** any tables named by ".session filter" but let all other table through.
2414*/
2415#if defined(SQLITE_ENABLE_SESSION)
2416static int session_filter(void *pCtx, const char *zTab){
2417 OpenSession *pSession = (OpenSession*)pCtx;
2418 int i;
2419 for(i=0; i<pSession->nFilter; i++){
2420 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
2421 }
2422 return 1;
2423}
2424#endif
2425
2426/*
drh44c2eb12003-04-30 11:38:26 +00002427** Make sure the database is open. If it is not, then open it. If
2428** the database fails to open, print an error message and exit.
2429*/
drhdcd87a92014-08-18 13:45:42 +00002430static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002431 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002432 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002433 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002434 globalDb = p->db;
2435 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2436 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002437 shellstaticFunc, 0, 0);
2438 }
mistachkin8e189222015-04-19 21:43:16 +00002439 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00002440 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002441 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002442 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002443 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002444 }
drhc2e87a32006-06-27 15:16:14 +00002445#ifndef SQLITE_OMIT_LOAD_EXTENSION
2446 sqlite3_enable_load_extension(p->db, 1);
2447#endif
mistachkin8e189222015-04-19 21:43:16 +00002448 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002449 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002450 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002451 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002452 }
2453}
2454
2455/*
drhfeac5f82004-08-01 00:10:45 +00002456** Do C-language style dequoting.
2457**
mistachkinf21979d2015-01-18 05:35:01 +00002458** \a -> alarm
2459** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002460** \t -> tab
2461** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002462** \v -> vertical tab
2463** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002464** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002465** \s -> space
drh4c56b992013-06-27 13:26:55 +00002466** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002467** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002468** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002469** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002470*/
2471static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002472 int i, j;
2473 char c;
drhc2ce0be2014-05-29 12:36:14 +00002474 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002475 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002476 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002477 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002478 if( c=='a' ){
2479 c = '\a';
2480 }else if( c=='b' ){
2481 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002482 }else if( c=='t' ){
2483 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002484 }else if( c=='n' ){
2485 c = '\n';
2486 }else if( c=='v' ){
2487 c = '\v';
2488 }else if( c=='f' ){
2489 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002490 }else if( c=='r' ){
2491 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002492 }else if( c=='"' ){
2493 c = '"';
2494 }else if( c=='\'' ){
2495 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002496 }else if( c=='\\' ){
2497 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002498 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002499 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002500 if( z[i+1]>='0' && z[i+1]<='7' ){
2501 i++;
2502 c = (c<<3) + z[i] - '0';
2503 if( z[i+1]>='0' && z[i+1]<='7' ){
2504 i++;
2505 c = (c<<3) + z[i] - '0';
2506 }
2507 }
2508 }
2509 }
2510 z[j] = c;
2511 }
drhc2ce0be2014-05-29 12:36:14 +00002512 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002513}
2514
2515/*
drh348d19c2013-06-03 12:47:43 +00002516** Return the value of a hexadecimal digit. Return -1 if the input
2517** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002518*/
drh348d19c2013-06-03 12:47:43 +00002519static int hexDigitValue(char c){
2520 if( c>='0' && c<='9' ) return c - '0';
2521 if( c>='a' && c<='f' ) return c - 'a' + 10;
2522 if( c>='A' && c<='F' ) return c - 'A' + 10;
2523 return -1;
drhc28490c2006-10-26 14:25:58 +00002524}
2525
2526/*
drh7d9f3942013-04-03 01:26:54 +00002527** Interpret zArg as an integer value, possibly with suffixes.
2528*/
2529static sqlite3_int64 integerValue(const char *zArg){
2530 sqlite3_int64 v = 0;
2531 static const struct { char *zSuffix; int iMult; } aMult[] = {
2532 { "KiB", 1024 },
2533 { "MiB", 1024*1024 },
2534 { "GiB", 1024*1024*1024 },
2535 { "KB", 1000 },
2536 { "MB", 1000000 },
2537 { "GB", 1000000000 },
2538 { "K", 1000 },
2539 { "M", 1000000 },
2540 { "G", 1000000000 },
2541 };
2542 int i;
2543 int isNeg = 0;
2544 if( zArg[0]=='-' ){
2545 isNeg = 1;
2546 zArg++;
2547 }else if( zArg[0]=='+' ){
2548 zArg++;
2549 }
drh348d19c2013-06-03 12:47:43 +00002550 if( zArg[0]=='0' && zArg[1]=='x' ){
2551 int x;
2552 zArg += 2;
2553 while( (x = hexDigitValue(zArg[0]))>=0 ){
2554 v = (v<<4) + x;
2555 zArg++;
2556 }
2557 }else{
2558 while( IsDigit(zArg[0]) ){
2559 v = v*10 + zArg[0] - '0';
2560 zArg++;
2561 }
drh7d9f3942013-04-03 01:26:54 +00002562 }
drhc2bed0a2013-05-24 11:57:50 +00002563 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002564 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2565 v *= aMult[i].iMult;
2566 break;
2567 }
2568 }
2569 return isNeg? -v : v;
2570}
2571
2572/*
drh348d19c2013-06-03 12:47:43 +00002573** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2574** for TRUE and FALSE. Return the integer value if appropriate.
2575*/
2576static int booleanValue(char *zArg){
2577 int i;
2578 if( zArg[0]=='0' && zArg[1]=='x' ){
2579 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2580 }else{
2581 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2582 }
2583 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2584 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2585 return 1;
2586 }
2587 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2588 return 0;
2589 }
mistachkinaae280e2015-12-31 19:06:24 +00002590 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002591 zArg);
2592 return 0;
2593}
2594
2595/*
drh42f64e52012-04-04 16:56:23 +00002596** Close an output file, assuming it is not stderr or stdout
2597*/
2598static void output_file_close(FILE *f){
2599 if( f && f!=stdout && f!=stderr ) fclose(f);
2600}
2601
2602/*
2603** Try to open an output file. The names "stdout" and "stderr" are
mistachkin1fe36bb2016-04-04 02:16:44 +00002604** recognized and do the right thing. NULL is returned if the output
drh42f64e52012-04-04 16:56:23 +00002605** filename is "off".
2606*/
2607static FILE *output_file_open(const char *zFile){
2608 FILE *f;
2609 if( strcmp(zFile,"stdout")==0 ){
2610 f = stdout;
2611 }else if( strcmp(zFile, "stderr")==0 ){
2612 f = stderr;
2613 }else if( strcmp(zFile, "off")==0 ){
2614 f = 0;
2615 }else{
2616 f = fopen(zFile, "wb");
2617 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002618 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002619 }
2620 }
2621 return f;
2622}
2623
drhd12602a2016-12-07 15:49:02 +00002624#if !defined(SQLITE_UNTESTABLE)
drhc10b9da2016-11-20 17:59:59 +00002625#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002626/*
2627** A routine for handling output from sqlite3_trace().
2628*/
drh4b363a52016-07-23 20:27:41 +00002629static int sql_trace_callback(
2630 unsigned mType,
2631 void *pArg,
2632 void *pP,
2633 void *pX
2634){
drh42f64e52012-04-04 16:56:23 +00002635 FILE *f = (FILE*)pArg;
drhb0df5402016-08-01 17:06:44 +00002636 UNUSED_PARAMETER(mType);
2637 UNUSED_PARAMETER(pP);
drh4b2590e2014-08-19 19:28:00 +00002638 if( f ){
drh4b363a52016-07-23 20:27:41 +00002639 const char *z = (const char*)pX;
drh4b2590e2014-08-19 19:28:00 +00002640 int i = (int)strlen(z);
2641 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002642 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002643 }
drh4b363a52016-07-23 20:27:41 +00002644 return 0;
drh42f64e52012-04-04 16:56:23 +00002645}
drhc10b9da2016-11-20 17:59:59 +00002646#endif
2647#endif
drh42f64e52012-04-04 16:56:23 +00002648
2649/*
drhd8621b92012-04-17 09:09:33 +00002650** A no-op routine that runs with the ".breakpoint" doc-command. This is
2651** a useful spot to set a debugger breakpoint.
2652*/
2653static void test_breakpoint(void){
2654 static int nCall = 0;
2655 nCall++;
2656}
2657
2658/*
mistachkin636bf9f2014-07-19 20:15:16 +00002659** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002660*/
mistachkin636bf9f2014-07-19 20:15:16 +00002661typedef struct ImportCtx ImportCtx;
2662struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002663 const char *zFile; /* Name of the input file */
2664 FILE *in; /* Read the CSV text from this input stream */
2665 char *z; /* Accumulated text for a field */
2666 int n; /* Number of bytes in z */
2667 int nAlloc; /* Space allocated for z[] */
2668 int nLine; /* Current line number */
2669 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002670 int cColSep; /* The column separator character. (Usually ",") */
2671 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002672};
2673
2674/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002675static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002676 if( p->n+1>=p->nAlloc ){
2677 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002678 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002679 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002680 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002681 exit(1);
2682 }
2683 }
2684 p->z[p->n++] = (char)c;
2685}
2686
2687/* Read a single field of CSV text. Compatible with rfc4180 and extended
2688** with the option of having a separator other than ",".
2689**
2690** + Input comes from p->in.
2691** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002692** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002693** + Use p->cSep as the column separator. The default is ",".
2694** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002695** + Keep track of the line number in p->nLine.
2696** + Store the character that terminates the field in p->cTerm. Store
2697** EOF on end-of-file.
2698** + Report syntax errors on stderr
2699*/
mistachkin44723ce2015-03-21 02:22:37 +00002700static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002701 int c;
2702 int cSep = p->cColSep;
2703 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002704 p->n = 0;
2705 c = fgetc(p->in);
2706 if( c==EOF || seenInterrupt ){
2707 p->cTerm = EOF;
2708 return 0;
2709 }
2710 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002711 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002712 int startLine = p->nLine;
2713 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002714 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002715 while( 1 ){
2716 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002717 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002718 if( c==cQuote ){
2719 if( pc==cQuote ){
2720 pc = 0;
2721 continue;
2722 }
2723 }
2724 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002725 || (c==rSep && pc==cQuote)
2726 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002727 || (c==EOF && pc==cQuote)
2728 ){
2729 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002730 p->cTerm = c;
2731 break;
2732 }
2733 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002734 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002735 p->zFile, p->nLine, cQuote);
2736 }
2737 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002738 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002739 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002740 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002741 break;
2742 }
mistachkin636bf9f2014-07-19 20:15:16 +00002743 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002744 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002745 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002746 }
drhdb95f682013-06-26 22:46:00 +00002747 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002748 while( c!=EOF && c!=cSep && c!=rSep ){
2749 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002750 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002751 }
mistachkin636bf9f2014-07-19 20:15:16 +00002752 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002753 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002754 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002755 }
drhdb95f682013-06-26 22:46:00 +00002756 p->cTerm = c;
2757 }
drh8dd675e2013-07-12 21:09:24 +00002758 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002759 return p->z;
2760}
2761
mistachkin636bf9f2014-07-19 20:15:16 +00002762/* Read a single field of ASCII delimited text.
2763**
2764** + Input comes from p->in.
2765** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002766** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002767** + Use p->cSep as the column separator. The default is "\x1F".
2768** + Use p->rSep as the row separator. The default is "\x1E".
2769** + Keep track of the row number in p->nLine.
2770** + Store the character that terminates the field in p->cTerm. Store
2771** EOF on end-of-file.
2772** + Report syntax errors on stderr
2773*/
mistachkin44723ce2015-03-21 02:22:37 +00002774static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002775 int c;
2776 int cSep = p->cColSep;
2777 int rSep = p->cRowSep;
2778 p->n = 0;
2779 c = fgetc(p->in);
2780 if( c==EOF || seenInterrupt ){
2781 p->cTerm = EOF;
2782 return 0;
2783 }
2784 while( c!=EOF && c!=cSep && c!=rSep ){
2785 import_append_char(p, c);
2786 c = fgetc(p->in);
2787 }
2788 if( c==rSep ){
2789 p->nLine++;
2790 }
2791 p->cTerm = c;
2792 if( p->z ) p->z[p->n] = 0;
2793 return p->z;
2794}
2795
drhdb95f682013-06-26 22:46:00 +00002796/*
drh4bbcf102014-02-06 02:46:08 +00002797** Try to transfer data for table zTable. If an error is seen while
2798** moving forward, try to go backwards. The backwards movement won't
2799** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002800*/
mistachkine31ae902014-02-06 01:15:29 +00002801static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002802 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002803 sqlite3 *newDb,
2804 const char *zTable
2805){
mistachkin1fe36bb2016-04-04 02:16:44 +00002806 sqlite3_stmt *pQuery = 0;
drh3350ce92014-02-06 00:49:12 +00002807 sqlite3_stmt *pInsert = 0;
2808 char *zQuery = 0;
2809 char *zInsert = 0;
2810 int rc;
2811 int i, j, n;
2812 int nTable = (int)strlen(zTable);
2813 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002814 int cnt = 0;
2815 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002816
2817 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2818 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2819 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002820 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002821 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2822 zQuery);
2823 goto end_data_xfer;
2824 }
2825 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002826 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002827 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002828 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002829 goto end_data_xfer;
2830 }
2831 sqlite3_snprintf(200+nTable,zInsert,
2832 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2833 i = (int)strlen(zInsert);
2834 for(j=1; j<n; j++){
2835 memcpy(zInsert+i, ",?", 2);
2836 i += 2;
2837 }
2838 memcpy(zInsert+i, ");", 3);
2839 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2840 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002841 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002842 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2843 zQuery);
2844 goto end_data_xfer;
2845 }
2846 for(k=0; k<2; k++){
2847 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2848 for(i=0; i<n; i++){
2849 switch( sqlite3_column_type(pQuery, i) ){
2850 case SQLITE_NULL: {
2851 sqlite3_bind_null(pInsert, i+1);
2852 break;
2853 }
2854 case SQLITE_INTEGER: {
2855 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2856 break;
2857 }
2858 case SQLITE_FLOAT: {
2859 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2860 break;
2861 }
2862 case SQLITE_TEXT: {
2863 sqlite3_bind_text(pInsert, i+1,
2864 (const char*)sqlite3_column_text(pQuery,i),
2865 -1, SQLITE_STATIC);
2866 break;
2867 }
2868 case SQLITE_BLOB: {
2869 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2870 sqlite3_column_bytes(pQuery,i),
2871 SQLITE_STATIC);
2872 break;
2873 }
2874 }
2875 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002876 rc = sqlite3_step(pInsert);
2877 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002878 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002879 sqlite3_errmsg(newDb));
2880 }
drh3350ce92014-02-06 00:49:12 +00002881 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002882 cnt++;
2883 if( (cnt%spinRate)==0 ){
2884 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2885 fflush(stdout);
2886 }
drh3350ce92014-02-06 00:49:12 +00002887 } /* End while */
2888 if( rc==SQLITE_DONE ) break;
2889 sqlite3_finalize(pQuery);
2890 sqlite3_free(zQuery);
2891 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2892 zTable);
2893 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2894 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002895 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002896 break;
drh3350ce92014-02-06 00:49:12 +00002897 }
2898 } /* End for(k=0...) */
2899
2900end_data_xfer:
2901 sqlite3_finalize(pQuery);
2902 sqlite3_finalize(pInsert);
2903 sqlite3_free(zQuery);
2904 sqlite3_free(zInsert);
2905}
2906
2907
2908/*
2909** Try to transfer all rows of the schema that match zWhere. For
2910** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002911** If an error is encountered while moving forward through the
2912** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002913*/
mistachkine31ae902014-02-06 01:15:29 +00002914static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002915 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002916 sqlite3 *newDb,
2917 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002918 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002919){
2920 sqlite3_stmt *pQuery = 0;
2921 char *zQuery = 0;
2922 int rc;
2923 const unsigned char *zName;
2924 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002925 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002926
2927 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2928 " WHERE %s", zWhere);
2929 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2930 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002931 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002932 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2933 zQuery);
2934 goto end_schema_xfer;
2935 }
2936 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2937 zName = sqlite3_column_text(pQuery, 0);
2938 zSql = sqlite3_column_text(pQuery, 1);
2939 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002940 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2941 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002942 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002943 sqlite3_free(zErrMsg);
2944 zErrMsg = 0;
2945 }
drh3350ce92014-02-06 00:49:12 +00002946 if( xForEach ){
2947 xForEach(p, newDb, (const char*)zName);
2948 }
2949 printf("done\n");
2950 }
2951 if( rc!=SQLITE_DONE ){
2952 sqlite3_finalize(pQuery);
2953 sqlite3_free(zQuery);
2954 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2955 " WHERE %s ORDER BY rowid DESC", zWhere);
2956 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2957 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002958 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002959 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2960 zQuery);
2961 goto end_schema_xfer;
2962 }
2963 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2964 zName = sqlite3_column_text(pQuery, 0);
2965 zSql = sqlite3_column_text(pQuery, 1);
2966 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002967 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2968 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002969 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002970 sqlite3_free(zErrMsg);
2971 zErrMsg = 0;
2972 }
drh3350ce92014-02-06 00:49:12 +00002973 if( xForEach ){
2974 xForEach(p, newDb, (const char*)zName);
2975 }
2976 printf("done\n");
2977 }
2978 }
2979end_schema_xfer:
2980 sqlite3_finalize(pQuery);
2981 sqlite3_free(zQuery);
2982}
2983
2984/*
2985** Open a new database file named "zNewDb". Try to recover as much information
2986** as possible out of the main database (which might be corrupt) and write it
2987** into zNewDb.
2988*/
drhdcd87a92014-08-18 13:45:42 +00002989static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002990 int rc;
2991 sqlite3 *newDb = 0;
2992 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002993 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002994 return;
2995 }
2996 rc = sqlite3_open(zNewDb, &newDb);
2997 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002998 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002999 sqlite3_errmsg(newDb));
3000 }else{
drh54d0d2d2014-04-03 00:32:13 +00003001 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00003002 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00003003 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
3004 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00003005 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00003006 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00003007 }
3008 sqlite3_close(newDb);
3009}
3010
3011/*
drhc2ce0be2014-05-29 12:36:14 +00003012** Change the output file back to stdout
3013*/
drhdcd87a92014-08-18 13:45:42 +00003014static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00003015 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003016#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00003017 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00003018#endif
drhc2ce0be2014-05-29 12:36:14 +00003019 }else{
3020 output_file_close(p->out);
3021 }
3022 p->outfile[0] = 0;
3023 p->out = stdout;
3024}
3025
3026/*
drhf7502f02015-02-06 14:19:44 +00003027** Run an SQL command and return the single integer result.
3028*/
3029static int db_int(ShellState *p, const char *zSql){
3030 sqlite3_stmt *pStmt;
3031 int res = 0;
3032 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3033 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
3034 res = sqlite3_column_int(pStmt,0);
3035 }
3036 sqlite3_finalize(pStmt);
3037 return res;
3038}
3039
3040/*
3041** Convert a 2-byte or 4-byte big-endian integer into a native integer
3042*/
drha0620ac2016-07-13 13:05:13 +00003043static unsigned int get2byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00003044 return (a[0]<<8) + a[1];
3045}
drha0620ac2016-07-13 13:05:13 +00003046static unsigned int get4byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00003047 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
3048}
3049
3050/*
3051** Implementation of the ".info" command.
3052**
3053** Return 1 on error, 2 to exit, and 0 otherwise.
3054*/
drh0e55db12015-02-06 14:51:13 +00003055static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00003056 static const struct { const char *zName; int ofst; } aField[] = {
3057 { "file change counter:", 24 },
3058 { "database page count:", 28 },
3059 { "freelist page count:", 36 },
3060 { "schema cookie:", 40 },
3061 { "schema format:", 44 },
3062 { "default cache size:", 48 },
3063 { "autovacuum top root:", 52 },
3064 { "incremental vacuum:", 64 },
3065 { "text encoding:", 56 },
3066 { "user version:", 60 },
3067 { "application id:", 68 },
3068 { "software version:", 96 },
3069 };
drh0e55db12015-02-06 14:51:13 +00003070 static const struct { const char *zName; const char *zSql; } aQuery[] = {
3071 { "number of tables:",
3072 "SELECT count(*) FROM %s WHERE type='table'" },
3073 { "number of indexes:",
3074 "SELECT count(*) FROM %s WHERE type='index'" },
3075 { "number of triggers:",
3076 "SELECT count(*) FROM %s WHERE type='trigger'" },
3077 { "number of views:",
3078 "SELECT count(*) FROM %s WHERE type='view'" },
3079 { "schema size:",
3080 "SELECT total(length(sql)) FROM %s" },
3081 };
mistachkinbfe8bd52015-11-17 19:17:14 +00003082 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00003083 int i;
3084 char *zSchemaTab;
3085 char *zDb = nArg>=2 ? azArg[1] : "main";
3086 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00003087 open_db(p, 0);
3088 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00003089 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00003090 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
3091 return 1;
3092 }
3093 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
3094 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003095 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00003096 return 1;
3097 }
3098 i = get2byteInt(aHdr+16);
3099 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00003100 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
3101 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
3102 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
3103 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00003104 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00003105 int ofst = aField[i].ofst;
3106 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00003107 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00003108 switch( ofst ){
3109 case 56: {
mistachkin1fe36bb2016-04-04 02:16:44 +00003110 if( val==1 ) raw_printf(p->out, " (utf8)");
3111 if( val==2 ) raw_printf(p->out, " (utf16le)");
3112 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00003113 }
3114 }
mistachkinaae280e2015-12-31 19:06:24 +00003115 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00003116 }
drh0e55db12015-02-06 14:51:13 +00003117 if( zDb==0 ){
3118 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
3119 }else if( strcmp(zDb,"temp")==0 ){
3120 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
3121 }else{
3122 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
3123 }
drhf5ed7ad2015-06-15 14:43:25 +00003124 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00003125 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
3126 int val = db_int(p, zSql);
3127 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00003128 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00003129 }
3130 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00003131 return 0;
3132}
3133
dand95bb392015-09-30 11:19:05 +00003134/*
3135** Print the current sqlite3_errmsg() value to stderr and return 1.
3136*/
3137static int shellDatabaseError(sqlite3 *db){
3138 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00003139 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00003140 return 1;
3141}
3142
3143/*
3144** Print an out-of-memory message to stderr and return 1.
3145*/
3146static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00003147 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00003148 return 1;
3149}
drhf7502f02015-02-06 14:19:44 +00003150
drh2db82112016-09-15 21:35:24 +00003151/*
3152** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
3153** if they match and FALSE (0) if they do not match.
3154**
3155** Globbing rules:
3156**
3157** '*' Matches any sequence of zero or more characters.
3158**
3159** '?' Matches exactly one character.
3160**
3161** [...] Matches one character from the enclosed list of
3162** characters.
3163**
3164** [^...] Matches one character not in the enclosed list.
3165**
3166** '#' Matches any sequence of one or more digits with an
3167** optional + or - sign in front
3168**
3169** ' ' Any span of whitespace matches any other span of
3170** whitespace.
3171**
3172** Extra whitespace at the end of z[] is ignored.
3173*/
3174static int testcase_glob(const char *zGlob, const char *z){
3175 int c, c2;
3176 int invert;
3177 int seen;
3178
3179 while( (c = (*(zGlob++)))!=0 ){
3180 if( IsSpace(c) ){
3181 if( !IsSpace(*z) ) return 0;
3182 while( IsSpace(*zGlob) ) zGlob++;
3183 while( IsSpace(*z) ) z++;
3184 }else if( c=='*' ){
3185 while( (c=(*(zGlob++))) == '*' || c=='?' ){
3186 if( c=='?' && (*(z++))==0 ) return 0;
3187 }
3188 if( c==0 ){
3189 return 1;
3190 }else if( c=='[' ){
3191 while( *z && testcase_glob(zGlob-1,z)==0 ){
3192 z++;
3193 }
3194 return (*z)!=0;
3195 }
3196 while( (c2 = (*(z++)))!=0 ){
3197 while( c2!=c ){
3198 c2 = *(z++);
3199 if( c2==0 ) return 0;
3200 }
3201 if( testcase_glob(zGlob,z) ) return 1;
3202 }
3203 return 0;
3204 }else if( c=='?' ){
3205 if( (*(z++))==0 ) return 0;
3206 }else if( c=='[' ){
3207 int prior_c = 0;
3208 seen = 0;
3209 invert = 0;
3210 c = *(z++);
3211 if( c==0 ) return 0;
3212 c2 = *(zGlob++);
3213 if( c2=='^' ){
3214 invert = 1;
3215 c2 = *(zGlob++);
3216 }
3217 if( c2==']' ){
3218 if( c==']' ) seen = 1;
3219 c2 = *(zGlob++);
3220 }
3221 while( c2 && c2!=']' ){
3222 if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
3223 c2 = *(zGlob++);
3224 if( c>=prior_c && c<=c2 ) seen = 1;
3225 prior_c = 0;
3226 }else{
3227 if( c==c2 ){
3228 seen = 1;
3229 }
3230 prior_c = c2;
3231 }
3232 c2 = *(zGlob++);
3233 }
3234 if( c2==0 || (seen ^ invert)==0 ) return 0;
3235 }else if( c=='#' ){
3236 if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
3237 if( !IsDigit(z[0]) ) return 0;
3238 z++;
3239 while( IsDigit(z[0]) ){ z++; }
3240 }else{
3241 if( c!=(*(z++)) ) return 0;
3242 }
3243 }
3244 while( IsSpace(*z) ){ z++; }
3245 return *z==0;
3246}
drh2db82112016-09-15 21:35:24 +00003247
3248
drhf7502f02015-02-06 14:19:44 +00003249/*
drh4926fec2016-04-13 15:33:42 +00003250** Compare the string as a command-line option with either one or two
3251** initial "-" characters.
3252*/
3253static int optionMatch(const char *zStr, const char *zOpt){
3254 if( zStr[0]!='-' ) return 0;
3255 zStr++;
3256 if( zStr[0]=='-' ) zStr++;
3257 return strcmp(zStr, zOpt)==0;
3258}
3259
3260/*
drhcd0509e2016-09-16 00:26:08 +00003261** Delete a file.
3262*/
3263int shellDeleteFile(const char *zFilename){
3264 int rc;
3265#ifdef _WIN32
mistachkin8145fc62016-09-16 20:39:21 +00003266 wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
drhcd0509e2016-09-16 00:26:08 +00003267 rc = _wunlink(z);
3268 sqlite3_free(z);
3269#else
3270 rc = unlink(zFilename);
3271#endif
3272 return rc;
3273}
3274
dan35ac58e2016-12-14 19:28:27 +00003275
dan35ac58e2016-12-14 19:28:27 +00003276/*
dandd9e0be2016-12-16 16:44:27 +00003277** The implementation of SQL scalar function fkey_collate_clause(), used
dan3c7ebeb2016-12-16 17:28:56 +00003278** by the ".lint fkey-indexes" command. This scalar function is always
dandd9e0be2016-12-16 16:44:27 +00003279** called with four arguments - the parent table name, the parent column name,
3280** the child table name and the child column name.
dan35ac58e2016-12-14 19:28:27 +00003281**
3282** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col')
3283**
3284** If either of the named tables or columns do not exist, this function
3285** returns an empty string. An empty string is also returned if both tables
3286** and columns exist but have the same default collation sequence. Or,
3287** if both exist but the default collation sequences are different, this
3288** function returns the string " COLLATE <parent-collation>", where
3289** <parent-collation> is the default collation sequence of the parent column.
3290*/
3291static void shellFkeyCollateClause(
3292 sqlite3_context *pCtx,
3293 int nVal,
3294 sqlite3_value **apVal
3295){
3296 sqlite3 *db = sqlite3_context_db_handle(pCtx);
3297 const char *zParent;
3298 const char *zParentCol;
3299 const char *zParentSeq;
3300 const char *zChild;
3301 const char *zChildCol;
drh96ada592016-12-29 19:48:46 +00003302 const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */
dan35ac58e2016-12-14 19:28:27 +00003303 int rc;
3304
3305 assert( nVal==4 );
3306 zParent = (const char*)sqlite3_value_text(apVal[0]);
3307 zParentCol = (const char*)sqlite3_value_text(apVal[1]);
3308 zChild = (const char*)sqlite3_value_text(apVal[2]);
3309 zChildCol = (const char*)sqlite3_value_text(apVal[3]);
3310
3311 sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
3312 rc = sqlite3_table_column_metadata(
3313 db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0
3314 );
3315 if( rc==SQLITE_OK ){
3316 rc = sqlite3_table_column_metadata(
3317 db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0
3318 );
3319 }
3320
3321 if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){
3322 char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq);
3323 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
3324 sqlite3_free(z);
3325 }
3326}
3327
3328
3329/*
dan3c7ebeb2016-12-16 17:28:56 +00003330** The implementation of dot-command ".lint fkey-indexes".
dan35ac58e2016-12-14 19:28:27 +00003331*/
dan3c7ebeb2016-12-16 17:28:56 +00003332static int lintFkeyIndexes(
dan35ac58e2016-12-14 19:28:27 +00003333 ShellState *pState, /* Current shell tool state */
3334 char **azArg, /* Array of arguments passed to dot command */
3335 int nArg /* Number of entries in azArg[] */
3336){
dandd9e0be2016-12-16 16:44:27 +00003337 sqlite3 *db = pState->db; /* Database handle to query "main" db of */
3338 FILE *out = pState->out; /* Stream to write non-error output to */
danf9647b62016-12-15 06:01:40 +00003339 int bVerbose = 0; /* If -verbose is present */
3340 int bGroupByParent = 0; /* If -groupbyparent is present */
dandd9e0be2016-12-16 16:44:27 +00003341 int i; /* To iterate through azArg[] */
3342 const char *zIndent = ""; /* How much to indent CREATE INDEX by */
3343 int rc; /* Return code */
3344 sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */
dan35ac58e2016-12-14 19:28:27 +00003345
dandd9e0be2016-12-16 16:44:27 +00003346 /*
3347 ** This SELECT statement returns one row for each foreign key constraint
3348 ** in the schema of the main database. The column values are:
3349 **
3350 ** 0. The text of an SQL statement similar to:
3351 **
3352 ** "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?"
3353 **
3354 ** This is the same SELECT that the foreign keys implementation needs
3355 ** to run internally on child tables. If there is an index that can
3356 ** be used to optimize this query, then it can also be used by the FK
3357 ** implementation to optimize DELETE or UPDATE statements on the parent
3358 ** table.
3359 **
3360 ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by
3361 ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema
3362 ** contains an index that can be used to optimize the query.
3363 **
3364 ** 2. Human readable text that describes the child table and columns. e.g.
3365 **
3366 ** "child_table(child_key1, child_key2)"
3367 **
3368 ** 3. Human readable text that describes the parent table and columns. e.g.
3369 **
3370 ** "parent_table(parent_key1, parent_key2)"
3371 **
3372 ** 4. A full CREATE INDEX statement for an index that could be used to
3373 ** optimize DELETE or UPDATE statements on the parent table. e.g.
3374 **
3375 ** "CREATE INDEX child_table_child_key ON child_table(child_key)"
3376 **
3377 ** 5. The name of the parent table.
3378 **
3379 ** These six values are used by the C logic below to generate the report.
3380 */
dan35ac58e2016-12-14 19:28:27 +00003381 const char *zSql =
dandd9e0be2016-12-16 16:44:27 +00003382 "SELECT "
3383 " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '"
3384 " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' "
3385 " || fkey_collate_clause(f.[table], f.[to], s.name, f.[from]),' AND ')"
dan35ac58e2016-12-14 19:28:27 +00003386 ", "
dandd9e0be2016-12-16 16:44:27 +00003387 " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('"
dan35ac58e2016-12-14 19:28:27 +00003388 " || group_concat('*=?', ' AND ') || ')'"
3389 ", "
dandd9e0be2016-12-16 16:44:27 +00003390 " s.name || '(' || group_concat(f.[from], ', ') || ')'"
dan35ac58e2016-12-14 19:28:27 +00003391 ", "
dandd9e0be2016-12-16 16:44:27 +00003392 " f.[table] || '(' || group_concat(COALESCE(f.[to], "
3393 " (SELECT name FROM pragma_table_info(f.[table]) WHERE pk=seq+1)"
dan35ac58e2016-12-14 19:28:27 +00003394 " )) || ')'"
3395 ", "
dandd9e0be2016-12-16 16:44:27 +00003396 " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))"
3397 " || ' ON ' || quote(s.name) || '('"
3398 " || group_concat(quote(f.[from]) ||"
3399 " fkey_collate_clause(f.[table], f.[to], s.name, f.[from]), ', ')"
dan35ac58e2016-12-14 19:28:27 +00003400 " || ');'"
danf9647b62016-12-15 06:01:40 +00003401 ", "
dandd9e0be2016-12-16 16:44:27 +00003402 " f.[table] "
dan35ac58e2016-12-14 19:28:27 +00003403
dandd9e0be2016-12-16 16:44:27 +00003404 "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f "
3405 "GROUP BY s.name, f.id "
3406 "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
dan35ac58e2016-12-14 19:28:27 +00003407 ;
3408
dan3c7ebeb2016-12-16 17:28:56 +00003409 for(i=2; i<nArg; i++){
drh344a1bf2016-12-22 14:53:25 +00003410 int n = (int)strlen(azArg[i]);
danf9647b62016-12-15 06:01:40 +00003411 if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
3412 bVerbose = 1;
3413 }
3414 else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
3415 bGroupByParent = 1;
3416 zIndent = " ";
3417 }
3418 else{
dan3c7ebeb2016-12-16 17:28:56 +00003419 raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
3420 azArg[0], azArg[1]
3421 );
danf9647b62016-12-15 06:01:40 +00003422 return SQLITE_ERROR;
3423 }
dan35ac58e2016-12-14 19:28:27 +00003424 }
dan35ac58e2016-12-14 19:28:27 +00003425
3426 /* Register the fkey_collate_clause() SQL function */
dandd9e0be2016-12-16 16:44:27 +00003427 rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8,
3428 0, shellFkeyCollateClause, 0, 0
3429 );
dan35ac58e2016-12-14 19:28:27 +00003430
3431
3432 if( rc==SQLITE_OK ){
3433 rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0);
3434 }
danf9647b62016-12-15 06:01:40 +00003435 if( rc==SQLITE_OK ){
3436 sqlite3_bind_int(pSql, 1, bGroupByParent);
3437 }
dan35ac58e2016-12-14 19:28:27 +00003438
3439 if( rc==SQLITE_OK ){
3440 int rc2;
danf9647b62016-12-15 06:01:40 +00003441 char *zPrev = 0;
dan35ac58e2016-12-14 19:28:27 +00003442 while( SQLITE_ROW==sqlite3_step(pSql) ){
3443 int res = -1;
3444 sqlite3_stmt *pExplain = 0;
3445 const char *zEQP = (const char*)sqlite3_column_text(pSql, 0);
3446 const char *zGlob = (const char*)sqlite3_column_text(pSql, 1);
3447 const char *zFrom = (const char*)sqlite3_column_text(pSql, 2);
3448 const char *zTarget = (const char*)sqlite3_column_text(pSql, 3);
3449 const char *zCI = (const char*)sqlite3_column_text(pSql, 4);
danf9647b62016-12-15 06:01:40 +00003450 const char *zParent = (const char*)sqlite3_column_text(pSql, 5);
dan35ac58e2016-12-14 19:28:27 +00003451
3452 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
3453 if( rc!=SQLITE_OK ) break;
3454 if( SQLITE_ROW==sqlite3_step(pExplain) ){
3455 const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3);
3456 res = (0==sqlite3_strglob(zGlob, zPlan));
3457 }
3458 rc = sqlite3_finalize(pExplain);
3459 if( rc!=SQLITE_OK ) break;
3460
3461 if( res<0 ){
3462 raw_printf(stderr, "Error: internal error");
3463 break;
danf9647b62016-12-15 06:01:40 +00003464 }else{
3465 if( bGroupByParent
3466 && (bVerbose || res==0)
3467 && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
3468 ){
3469 raw_printf(out, "-- Parent table %s\n", zParent);
3470 sqlite3_free(zPrev);
3471 zPrev = sqlite3_mprintf("%s", zParent);
3472 }
3473
3474 if( res==0 ){
3475 raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
3476 }else if( bVerbose ){
3477 raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
3478 zIndent, zFrom, zTarget
3479 );
3480 }
dan35ac58e2016-12-14 19:28:27 +00003481 }
3482 }
danf9647b62016-12-15 06:01:40 +00003483 sqlite3_free(zPrev);
dan35ac58e2016-12-14 19:28:27 +00003484
3485 if( rc!=SQLITE_OK ){
3486 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
3487 }
3488
3489 rc2 = sqlite3_finalize(pSql);
3490 if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
3491 rc = rc2;
3492 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
3493 }
3494 }else{
3495 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
3496 }
3497
3498 return rc;
3499}
dan3c7ebeb2016-12-16 17:28:56 +00003500
dan35ac58e2016-12-14 19:28:27 +00003501/*
dan3c7ebeb2016-12-16 17:28:56 +00003502** Implementation of ".lint" dot command.
3503*/
3504static int lintDotCommand(
3505 ShellState *pState, /* Current shell tool state */
3506 char **azArg, /* Array of arguments passed to dot command */
3507 int nArg /* Number of entries in azArg[] */
3508){
3509 int n;
drh96ada592016-12-29 19:48:46 +00003510 n = (nArg>=2 ? (int)strlen(azArg[1]) : 0);
dan3c7ebeb2016-12-16 17:28:56 +00003511 if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
3512 return lintFkeyIndexes(pState, azArg, nArg);
3513
3514 usage:
3515 raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
3516 raw_printf(stderr, "Where sub-commands are:\n");
3517 raw_printf(stderr, " fkey-indexes\n");
3518 return SQLITE_ERROR;
3519}
3520
dan35ac58e2016-12-14 19:28:27 +00003521
drhcd0509e2016-09-16 00:26:08 +00003522/*
drh75897232000-05-29 14:26:00 +00003523** If an input line begins with "." then invoke this routine to
3524** process that line.
drh67505e72002-04-19 12:34:06 +00003525**
drh47ad6842006-11-08 12:25:42 +00003526** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00003527*/
drhdcd87a92014-08-18 13:45:42 +00003528static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00003529 int h = 1;
drh75897232000-05-29 14:26:00 +00003530 int nArg = 0;
3531 int n, c;
drh67505e72002-04-19 12:34:06 +00003532 int rc = 0;
drh75897232000-05-29 14:26:00 +00003533 char *azArg[50];
3534
3535 /* Parse the input line into tokens.
3536 */
mistachkin8e189222015-04-19 21:43:16 +00003537 while( zLine[h] && nArg<ArraySize(azArg) ){
3538 while( IsSpace(zLine[h]) ){ h++; }
3539 if( zLine[h]==0 ) break;
3540 if( zLine[h]=='\'' || zLine[h]=='"' ){
3541 int delim = zLine[h++];
3542 azArg[nArg++] = &zLine[h];
mistachkin1fe36bb2016-04-04 02:16:44 +00003543 while( zLine[h] && zLine[h]!=delim ){
mistachkin8e189222015-04-19 21:43:16 +00003544 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
mistachkin1fe36bb2016-04-04 02:16:44 +00003545 h++;
drh4c56b992013-06-27 13:26:55 +00003546 }
mistachkin8e189222015-04-19 21:43:16 +00003547 if( zLine[h]==delim ){
3548 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00003549 }
drhfeac5f82004-08-01 00:10:45 +00003550 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003551 }else{
mistachkin8e189222015-04-19 21:43:16 +00003552 azArg[nArg++] = &zLine[h];
3553 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
3554 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00003555 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003556 }
3557 }
3558
3559 /* Process the input line.
3560 */
shane9bd1b442009-10-23 01:27:39 +00003561 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00003562 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00003563 c = azArg[0][0];
drhde613c62016-04-04 17:23:10 +00003564
drha0daa752016-09-16 11:53:10 +00003565#ifndef SQLITE_OMIT_AUTHORIZATION
drhde613c62016-04-04 17:23:10 +00003566 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
3567 if( nArg!=2 ){
3568 raw_printf(stderr, "Usage: .auth ON|OFF\n");
3569 rc = 1;
3570 goto meta_command_exit;
3571 }
3572 open_db(p, 0);
3573 if( booleanValue(azArg[1]) ){
3574 sqlite3_set_authorizer(p->db, shellAuth, p);
3575 }else{
3576 sqlite3_set_authorizer(p->db, 0, 0);
3577 }
3578 }else
drha0daa752016-09-16 11:53:10 +00003579#endif
drhde613c62016-04-04 17:23:10 +00003580
drh5c7976f2014-02-10 19:59:27 +00003581 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
3582 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
3583 ){
drhbc46f022013-01-23 18:53:23 +00003584 const char *zDestFile = 0;
3585 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00003586 sqlite3 *pDest;
3587 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00003588 int j;
3589 for(j=1; j<nArg; j++){
3590 const char *z = azArg[j];
3591 if( z[0]=='-' ){
3592 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00003593 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00003594 {
mistachkinaae280e2015-12-31 19:06:24 +00003595 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00003596 return 1;
3597 }
3598 }else if( zDestFile==0 ){
3599 zDestFile = azArg[j];
3600 }else if( zDb==0 ){
3601 zDb = zDestFile;
3602 zDestFile = azArg[j];
3603 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003604 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00003605 return 1;
3606 }
drh9ff849f2009-02-04 20:55:57 +00003607 }
drhbc46f022013-01-23 18:53:23 +00003608 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003609 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00003610 return 1;
3611 }
3612 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00003613 rc = sqlite3_open(zDestFile, &pDest);
3614 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003615 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00003616 sqlite3_close(pDest);
3617 return 1;
3618 }
drh05782482013-10-24 15:20:20 +00003619 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003620 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
3621 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003622 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00003623 sqlite3_close(pDest);
3624 return 1;
3625 }
3626 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
3627 sqlite3_backup_finish(pBackup);
3628 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003629 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00003630 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003631 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00003632 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003633 }
3634 sqlite3_close(pDest);
3635 }else
3636
drhc2ce0be2014-05-29 12:36:14 +00003637 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
3638 if( nArg==2 ){
3639 bail_on_error = booleanValue(azArg[1]);
3640 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003641 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003642 rc = 1;
3643 }
drhc49f44e2006-10-26 18:15:42 +00003644 }else
3645
mistachkinf21979d2015-01-18 05:35:01 +00003646 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
3647 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00003648 if( booleanValue(azArg[1]) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003649 setBinaryMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003650 }else{
mistachkin1fe36bb2016-04-04 02:16:44 +00003651 setTextMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003652 }
mistachkinf21979d2015-01-18 05:35:01 +00003653 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003654 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00003655 rc = 1;
3656 }
3657 }else
3658
drhd8621b92012-04-17 09:09:33 +00003659 /* The undocumented ".breakpoint" command causes a call to the no-op
3660 ** routine named test_breakpoint().
3661 */
3662 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
3663 test_breakpoint();
3664 }else
3665
drhdf12f1c2015-12-07 21:46:19 +00003666 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
3667 if( nArg==2 ){
3668 p->countChanges = booleanValue(azArg[1]);
3669 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003670 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00003671 rc = 1;
3672 }
3673 }else
3674
drh2db82112016-09-15 21:35:24 +00003675 /* Cancel output redirection, if it is currently set (by .testcase)
3676 ** Then read the content of the testcase-out.txt file and compare against
3677 ** azArg[1]. If there are differences, report an error and exit.
3678 */
3679 if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
3680 char *zRes = 0;
3681 output_reset(p);
3682 if( nArg!=2 ){
3683 raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
drh760c8162016-09-16 02:52:22 +00003684 rc = 2;
dan11da0022016-12-17 08:18:05 +00003685 }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
drh2db82112016-09-15 21:35:24 +00003686 raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
3687 rc = 2;
3688 }else if( testcase_glob(azArg[1],zRes)==0 ){
mistachkin8145fc62016-09-16 20:39:21 +00003689 utf8_printf(stderr,
drh760c8162016-09-16 02:52:22 +00003690 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
3691 p->zTestcase, azArg[1], zRes);
drh2db82112016-09-15 21:35:24 +00003692 rc = 2;
drh760c8162016-09-16 02:52:22 +00003693 }else{
mistachkin8145fc62016-09-16 20:39:21 +00003694 utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
drh760c8162016-09-16 02:52:22 +00003695 p->nCheck++;
drh2db82112016-09-15 21:35:24 +00003696 }
3697 sqlite3_free(zRes);
3698 }else
drh2db82112016-09-15 21:35:24 +00003699
drhc2ce0be2014-05-29 12:36:14 +00003700 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
3701 if( nArg==2 ){
3702 tryToClone(p, azArg[1]);
3703 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003704 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003705 rc = 1;
3706 }
mistachkine31ae902014-02-06 01:15:29 +00003707 }else
3708
drhc2ce0be2014-05-29 12:36:14 +00003709 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003710 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00003711 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003712 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00003713 memcpy(&data, p, sizeof(data));
drhb20a61b2016-12-24 18:18:58 +00003714 data.showHeader = 0;
3715 data.cMode = data.mode = MODE_List;
3716 sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": ");
drh0b2110c2004-10-26 00:08:10 +00003717 data.cnt = 0;
drhb20a61b2016-12-24 18:18:58 +00003718 sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list",
3719 callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00003720 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003721 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003722 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003723 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00003724 }
3725 }else
3726
drh0e55db12015-02-06 14:51:13 +00003727 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
3728 rc = shell_dbinfo_command(p, nArg, azArg);
3729 }else
3730
drhc2ce0be2014-05-29 12:36:14 +00003731 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00003732 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00003733 /* When playing back a "dump", the content might appear in an order
3734 ** which causes immediate foreign key constraints to be violated.
3735 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00003736 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003737 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003738 rc = 1;
3739 goto meta_command_exit;
3740 }
mistachkinaae280e2015-12-31 19:06:24 +00003741 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
3742 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00003743 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00003744 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00003745 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00003746 if( nArg==1 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003747 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003748 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003749 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00003750 );
mistachkin1fe36bb2016-04-04 02:16:44 +00003751 run_schema_dump_query(p,
drh4f324762009-05-21 14:51:03 +00003752 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003753 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00003754 );
drh2f464a02011-10-13 00:41:49 +00003755 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003756 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00003757 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00003758 );
drh4c653a02000-06-07 01:27:47 +00003759 }else{
3760 int i;
drhdd3d4592004-08-30 01:54:05 +00003761 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00003762 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00003763 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003764 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00003765 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00003766 " AND sql NOT NULL");
3767 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003768 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00003769 "WHERE sql NOT NULL"
3770 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00003771 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00003772 );
danielk1977bc6ada42004-06-30 08:20:16 +00003773 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00003774 }
3775 }
drh45e29d82006-11-20 16:21:10 +00003776 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00003777 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00003778 p->writableSchema = 0;
3779 }
drh56197952011-10-13 16:30:13 +00003780 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
3781 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00003782 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00003783 }else
drh75897232000-05-29 14:26:00 +00003784
drhc2ce0be2014-05-29 12:36:14 +00003785 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
3786 if( nArg==2 ){
3787 p->echoOn = booleanValue(azArg[1]);
3788 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003789 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003790 rc = 1;
3791 }
drhdaffd0e2001-04-11 14:28:42 +00003792 }else
3793
drhc2ce0be2014-05-29 12:36:14 +00003794 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
3795 if( nArg==2 ){
drheacd29d2016-04-15 15:03:27 +00003796 if( strcmp(azArg[1],"full")==0 ){
3797 p->autoEQP = 2;
3798 }else{
3799 p->autoEQP = booleanValue(azArg[1]);
3800 }
drhc2ce0be2014-05-29 12:36:14 +00003801 }else{
drheacd29d2016-04-15 15:03:27 +00003802 raw_printf(stderr, "Usage: .eqp on|off|full\n");
drhc2ce0be2014-05-29 12:36:14 +00003803 rc = 1;
mistachkin1fe36bb2016-04-04 02:16:44 +00003804 }
drhefbf3b12014-02-28 20:47:24 +00003805 }else
3806
drhd3ac7d92013-01-25 18:33:43 +00003807 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00003808 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00003809 rc = 2;
drh75897232000-05-29 14:26:00 +00003810 }else
3811
drhc2ce0be2014-05-29 12:36:14 +00003812 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00003813 int val = 1;
3814 if( nArg>=2 ){
3815 if( strcmp(azArg[1],"auto")==0 ){
3816 val = 99;
3817 }else{
3818 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003819 }
drh700c2522016-02-09 18:39:25 +00003820 }
3821 if( val==1 && p->mode!=MODE_Explain ){
3822 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003823 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003824 p->autoExplain = 0;
3825 }else if( val==0 ){
3826 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3827 p->autoExplain = 0;
3828 }else if( val==99 ){
3829 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3830 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003831 }
drh75897232000-05-29 14:26:00 +00003832 }else
3833
drhc1971542014-06-23 23:28:13 +00003834 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003835 ShellState data;
drhc1971542014-06-23 23:28:13 +00003836 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003837 int doStats = 0;
drh4926fec2016-04-13 15:33:42 +00003838 memcpy(&data, p, sizeof(data));
3839 data.showHeader = 0;
3840 data.cMode = data.mode = MODE_Semi;
3841 if( nArg==2 && optionMatch(azArg[1], "indent") ){
3842 data.cMode = data.mode = MODE_Pretty;
3843 nArg = 1;
3844 }
drhc1971542014-06-23 23:28:13 +00003845 if( nArg!=1 ){
drh4926fec2016-04-13 15:33:42 +00003846 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
drhc1971542014-06-23 23:28:13 +00003847 rc = 1;
3848 goto meta_command_exit;
3849 }
3850 open_db(p, 0);
drhc1971542014-06-23 23:28:13 +00003851 rc = sqlite3_exec(p->db,
3852 "SELECT sql FROM"
3853 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3854 " FROM sqlite_master UNION ALL"
3855 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003856 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003857 "ORDER BY rowid",
3858 callback, &data, &zErrMsg
3859 );
drh56f674c2014-07-18 14:43:29 +00003860 if( rc==SQLITE_OK ){
3861 sqlite3_stmt *pStmt;
3862 rc = sqlite3_prepare_v2(p->db,
3863 "SELECT rowid FROM sqlite_master"
3864 " WHERE name GLOB 'sqlite_stat[134]'",
3865 -1, &pStmt, 0);
3866 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3867 sqlite3_finalize(pStmt);
3868 }
3869 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003870 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003871 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003872 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003873 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3874 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003875 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003876 data.zDestTable = "sqlite_stat1";
3877 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3878 shell_callback, &data,&zErrMsg);
3879 data.zDestTable = "sqlite_stat3";
3880 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3881 shell_callback, &data,&zErrMsg);
3882 data.zDestTable = "sqlite_stat4";
3883 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3884 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003885 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003886 }
drhc1971542014-06-23 23:28:13 +00003887 }else
3888
drhc2ce0be2014-05-29 12:36:14 +00003889 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3890 if( nArg==2 ){
3891 p->showHeader = booleanValue(azArg[1]);
3892 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003893 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003894 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003895 }
drh75897232000-05-29 14:26:00 +00003896 }else
3897
drhc2ce0be2014-05-29 12:36:14 +00003898 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003899 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003900 }else
3901
3902 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003903 char *zTable; /* Insert data into this table */
3904 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003905 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003906 int nCol; /* Number of columns in the table */
3907 int nByte; /* Number of bytes in an SQL string */
3908 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003909 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003910 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003911 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003912 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003913 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3914 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003915
drhc2ce0be2014-05-29 12:36:14 +00003916 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003917 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003918 goto meta_command_exit;
3919 }
drh01f37542014-05-31 15:43:33 +00003920 zFile = azArg[1];
3921 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003922 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003923 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003924 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003925 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003926 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003927 raw_printf(stderr,
3928 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003929 return 1;
drhfeac5f82004-08-01 00:10:45 +00003930 }
drhdb95f682013-06-26 22:46:00 +00003931 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003932 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003933 " for import\n");
3934 return 1;
3935 }
mistachkin636bf9f2014-07-19 20:15:16 +00003936 nSep = strlen30(p->rowSeparator);
3937 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003938 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003939 return 1;
3940 }
mistachkine0d68852014-12-11 03:12:33 +00003941 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3942 /* When importing CSV (only), if the row separator is set to the
3943 ** default output row separator, change it to the default input
3944 ** row separator. This avoids having to maintain different input
3945 ** and output row separators. */
3946 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3947 nSep = strlen30(p->rowSeparator);
3948 }
mistachkin636bf9f2014-07-19 20:15:16 +00003949 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003950 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003951 " for import\n");
3952 return 1;
3953 }
3954 sCtx.zFile = zFile;
3955 sCtx.nLine = 1;
3956 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003957#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003958 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003959 return 1;
3960#else
mistachkin636bf9f2014-07-19 20:15:16 +00003961 sCtx.in = popen(sCtx.zFile+1, "r");
3962 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003963 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003964#endif
drh5bde8162013-06-27 14:07:53 +00003965 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003966 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003967 xCloser = fclose;
3968 }
mistachkin636bf9f2014-07-19 20:15:16 +00003969 if( p->mode==MODE_Ascii ){
3970 xRead = ascii_read_one_field;
3971 }else{
3972 xRead = csv_read_one_field;
3973 }
3974 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003975 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003976 return 1;
3977 }
mistachkin636bf9f2014-07-19 20:15:16 +00003978 sCtx.cColSep = p->colSeparator[0];
3979 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003980 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003981 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003982 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003983 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003984 return 1;
3985 }
drh4f21c4a2008-12-10 22:15:00 +00003986 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003987 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003988 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003989 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003990 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3991 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003992 while( xRead(&sCtx) ){
drhd8c22ac2016-02-25 13:33:02 +00003993 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003994 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003995 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003996 }
drh5bde8162013-06-27 14:07:53 +00003997 if( cSep=='(' ){
3998 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003999 sqlite3_free(sCtx.z);
4000 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00004001 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00004002 return 1;
4003 }
drhdb95f682013-06-26 22:46:00 +00004004 zCreate = sqlite3_mprintf("%z\n)", zCreate);
4005 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
4006 sqlite3_free(zCreate);
4007 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004008 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00004009 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00004010 sqlite3_free(sCtx.z);
4011 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00004012 return 1;
4013 }
drhc7181902014-02-27 15:04:13 +00004014 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00004015 }
drhfeac5f82004-08-01 00:10:45 +00004016 sqlite3_free(zSql);
4017 if( rc ){
shane916f9612009-10-23 00:37:15 +00004018 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00004019 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00004020 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00004021 return 1;
drhfeac5f82004-08-01 00:10:45 +00004022 }
shane916f9612009-10-23 00:37:15 +00004023 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00004024 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00004025 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00004026 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00004027 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00004028 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004029 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00004030 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00004031 return 1;
4032 }
drhdb95f682013-06-26 22:46:00 +00004033 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00004034 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00004035 for(i=1; i<nCol; i++){
4036 zSql[j++] = ',';
4037 zSql[j++] = '?';
4038 }
4039 zSql[j++] = ')';
4040 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00004041 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00004042 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00004043 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004044 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00004045 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00004046 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00004047 return 1;
drhfeac5f82004-08-01 00:10:45 +00004048 }
mistachkin8e189222015-04-19 21:43:16 +00004049 needCommit = sqlite3_get_autocommit(p->db);
4050 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00004051 do{
mistachkin636bf9f2014-07-19 20:15:16 +00004052 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00004053 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00004054 char *z = xRead(&sCtx);
4055 /*
4056 ** Did we reach end-of-file before finding any columns?
4057 ** If so, stop instead of NULL filling the remaining columns.
4058 */
drhdb95f682013-06-26 22:46:00 +00004059 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00004060 /*
4061 ** Did we reach end-of-file OR end-of-line before finding any
4062 ** columns in ASCII mode? If so, stop instead of NULL filling
4063 ** the remaining columns.
4064 */
4065 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00004066 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00004067 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00004068 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00004069 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00004070 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00004071 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00004072 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00004073 }
drhfeac5f82004-08-01 00:10:45 +00004074 }
mistachkin636bf9f2014-07-19 20:15:16 +00004075 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00004076 do{
mistachkin636bf9f2014-07-19 20:15:16 +00004077 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00004078 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00004079 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00004080 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00004081 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00004082 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00004083 }
drhdb95f682013-06-26 22:46:00 +00004084 if( i>=nCol ){
4085 sqlite3_step(pStmt);
4086 rc = sqlite3_reset(pStmt);
4087 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004088 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
4089 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00004090 }
4091 }
mistachkin636bf9f2014-07-19 20:15:16 +00004092 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00004093
mistachkin636bf9f2014-07-19 20:15:16 +00004094 xCloser(sCtx.in);
4095 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00004096 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00004097 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00004098 }else
4099
drhd12602a2016-12-07 15:49:02 +00004100#ifndef SQLITE_UNTESTABLE
drh16eb5942016-11-03 13:01:38 +00004101 if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
4102 char *zSql;
4103 char *zCollist = 0;
4104 sqlite3_stmt *pStmt;
4105 int tnum = 0;
drh59ce2c42016-11-03 13:12:28 +00004106 int i;
drh16eb5942016-11-03 13:01:38 +00004107 if( nArg!=3 ){
4108 utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n");
4109 rc = 1;
4110 goto meta_command_exit;
4111 }
4112 open_db(p, 0);
4113 zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
4114 " WHERE name='%q' AND type='index'", azArg[1]);
4115 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4116 sqlite3_free(zSql);
4117 if( sqlite3_step(pStmt)==SQLITE_ROW ){
4118 tnum = sqlite3_column_int(pStmt, 0);
4119 }
4120 sqlite3_finalize(pStmt);
4121 if( tnum==0 ){
4122 utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
4123 rc = 1;
4124 goto meta_command_exit;
4125 }
4126 zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
4127 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4128 sqlite3_free(zSql);
drh59ce2c42016-11-03 13:12:28 +00004129 i = 0;
drh16eb5942016-11-03 13:01:38 +00004130 while( sqlite3_step(pStmt)==SQLITE_ROW ){
drh59ce2c42016-11-03 13:12:28 +00004131 char zLabel[20];
drh16eb5942016-11-03 13:01:38 +00004132 const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
drh59ce2c42016-11-03 13:12:28 +00004133 i++;
4134 if( zCol==0 ){
4135 if( sqlite3_column_int(pStmt,1)==-1 ){
4136 zCol = "_ROWID_";
4137 }else{
4138 sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i);
4139 zCol = zLabel;
4140 }
4141 }
drh16eb5942016-11-03 13:01:38 +00004142 if( zCollist==0 ){
4143 zCollist = sqlite3_mprintf("\"%w\"", zCol);
4144 }else{
4145 zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
4146 }
4147 }
4148 sqlite3_finalize(pStmt);
4149 zSql = sqlite3_mprintf(
4150 "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID",
4151 azArg[2], zCollist, zCollist);
4152 sqlite3_free(zCollist);
4153 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
4154 if( rc==SQLITE_OK ){
4155 rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
4156 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
4157 if( rc ){
4158 utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
4159 }else{
4160 utf8_printf(stdout, "%s;\n", zSql);
mistachkin2f9a6132016-11-11 05:19:45 +00004161 raw_printf(stdout,
drh16eb5942016-11-03 13:01:38 +00004162 "WARNING: writing to an imposter table will corrupt the index!\n"
4163 );
4164 }
4165 }else{
mistachkin2f9a6132016-11-11 05:19:45 +00004166 raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
drh16eb5942016-11-03 13:01:38 +00004167 rc = 1;
4168 }
4169 sqlite3_free(zSql);
4170 }else
4171#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
4172
drhae5e4452007-05-03 17:18:36 +00004173#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00004174 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00004175 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00004176 if( iotrace && iotrace!=stdout ) fclose(iotrace);
4177 iotrace = 0;
4178 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00004179 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00004180 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00004181 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00004182 iotrace = stdout;
4183 }else{
4184 iotrace = fopen(azArg[1], "w");
4185 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004186 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00004187 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00004188 rc = 1;
drhb0603412007-02-28 04:47:26 +00004189 }else{
mlcreech3a00f902008-03-04 17:45:01 +00004190 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00004191 }
4192 }
4193 }else
drhae5e4452007-05-03 17:18:36 +00004194#endif
drh16eb5942016-11-03 13:01:38 +00004195
drh1a513372015-05-02 17:40:23 +00004196 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
4197 static const struct {
4198 const char *zLimitName; /* Name of a limit */
4199 int limitCode; /* Integer code for that limit */
4200 } aLimit[] = {
4201 { "length", SQLITE_LIMIT_LENGTH },
4202 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
4203 { "column", SQLITE_LIMIT_COLUMN },
4204 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
4205 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
4206 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
4207 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
4208 { "attached", SQLITE_LIMIT_ATTACHED },
4209 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
4210 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
4211 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
4212 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
4213 };
4214 int i, n2;
4215 open_db(p, 0);
4216 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00004217 for(i=0; i<ArraySize(aLimit); i++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004218 printf("%20s %d\n", aLimit[i].zLimitName,
drh1a513372015-05-02 17:40:23 +00004219 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
4220 }
4221 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004222 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00004223 rc = 1;
4224 goto meta_command_exit;
4225 }else{
4226 int iLimit = -1;
4227 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00004228 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00004229 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
4230 if( iLimit<0 ){
4231 iLimit = i;
4232 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004233 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00004234 rc = 1;
4235 goto meta_command_exit;
4236 }
4237 }
4238 }
4239 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004240 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00004241 "enter \".limits\" with no arguments for a list.\n",
4242 azArg[1]);
4243 rc = 1;
4244 goto meta_command_exit;
4245 }
4246 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00004247 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
4248 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00004249 }
4250 printf("%20s %d\n", aLimit[iLimit].zLimitName,
4251 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
4252 }
4253 }else
drhb0603412007-02-28 04:47:26 +00004254
dan3c7ebeb2016-12-16 17:28:56 +00004255 if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
drh3fd9f332016-12-16 18:41:11 +00004256 open_db(p, 0);
dan3c7ebeb2016-12-16 17:28:56 +00004257 lintDotCommand(p, azArg, nArg);
4258 }else
4259
drh70df4fe2006-06-13 15:12:21 +00004260#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00004261 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00004262 const char *zFile, *zProc;
4263 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00004264 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004265 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00004266 rc = 1;
4267 goto meta_command_exit;
4268 }
drh1e397f82006-06-08 15:28:43 +00004269 zFile = azArg[1];
4270 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00004271 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00004272 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
4273 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004274 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00004275 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00004276 rc = 1;
drh1e397f82006-06-08 15:28:43 +00004277 }
4278 }else
drh70df4fe2006-06-13 15:12:21 +00004279#endif
drh1e397f82006-06-08 15:28:43 +00004280
drhc2ce0be2014-05-29 12:36:14 +00004281 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
4282 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004283 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00004284 rc = 1;
4285 }else{
4286 const char *zFile = azArg[1];
4287 output_file_close(p->pLog);
4288 p->pLog = output_file_open(zFile);
4289 }
drh127f9d72010-02-23 01:47:00 +00004290 }else
4291
drhc2ce0be2014-05-29 12:36:14 +00004292 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
4293 const char *zMode = nArg>=2 ? azArg[1] : "";
4294 int n2 = (int)strlen(zMode);
4295 int c2 = zMode[0];
4296 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004297 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00004298 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004299 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00004300 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004301 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00004302 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004303 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00004304 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00004305 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00004306 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00004307 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00004308 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00004309 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00004310 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00004311 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00004312 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004313 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00004314 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00004315 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00004316 set_table_name(p, nArg>=3 ? azArg[2] : "table");
drh41f5f6e2016-10-21 17:39:30 +00004317 }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
4318 p->mode = MODE_Quote;
mistachkin636bf9f2014-07-19 20:15:16 +00004319 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
4320 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00004321 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
4322 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00004323 }else {
mistachkinaae280e2015-12-31 19:06:24 +00004324 raw_printf(stderr, "Error: mode should be one of: "
drh36f49d02016-11-23 23:18:45 +00004325 "ascii column csv html insert line list quote tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00004326 rc = 1;
drh75897232000-05-29 14:26:00 +00004327 }
drh700c2522016-02-09 18:39:25 +00004328 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00004329 }else
4330
drhc2ce0be2014-05-29 12:36:14 +00004331 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
4332 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00004333 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
4334 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00004335 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004336 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00004337 rc = 1;
4338 }
4339 }else
4340
drh05782482013-10-24 15:20:20 +00004341 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
drhcd0509e2016-09-16 00:26:08 +00004342 char *zNewFilename; /* Name of the database file to open */
4343 int iName = 1; /* Index in azArg[] of the filename */
drh760c8162016-09-16 02:52:22 +00004344 int newFlag = 0; /* True to delete file before opening */
drhcd0509e2016-09-16 00:26:08 +00004345 /* Close the existing database */
4346 session_close_all(p);
4347 sqlite3_close(p->db);
drh05782482013-10-24 15:20:20 +00004348 p->db = 0;
drhcd0509e2016-09-16 00:26:08 +00004349 sqlite3_free(p->zFreeOnClose);
4350 p->zFreeOnClose = 0;
drh760c8162016-09-16 02:52:22 +00004351 /* Check for command-line arguments */
4352 for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
4353 const char *z = azArg[iName];
4354 if( optionMatch(z,"new") ){
4355 newFlag = 1;
4356 }else if( z[0]=='-' ){
4357 utf8_printf(stderr, "unknown option: %s\n", z);
4358 rc = 1;
mistachkin8145fc62016-09-16 20:39:21 +00004359 goto meta_command_exit;
drh760c8162016-09-16 02:52:22 +00004360 }
drhcd0509e2016-09-16 00:26:08 +00004361 }
4362 /* If a filename is specified, try to open it first */
4363 zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
4364 if( zNewFilename ){
drh760c8162016-09-16 02:52:22 +00004365 if( newFlag ) shellDeleteFile(zNewFilename);
drhcd0509e2016-09-16 00:26:08 +00004366 p->zDbFilename = zNewFilename;
4367 open_db(p, 1);
4368 if( p->db==0 ){
4369 utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
4370 sqlite3_free(zNewFilename);
4371 }else{
4372 p->zFreeOnClose = zNewFilename;
4373 }
4374 }
4375 if( p->db==0 ){
4376 /* As a fall-back open a TEMP database */
4377 p->zDbFilename = 0;
4378 open_db(p, 0);
drh05782482013-10-24 15:20:20 +00004379 }
4380 }else
4381
drhc2ce0be2014-05-29 12:36:14 +00004382 if( c=='o'
4383 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
4384 ){
4385 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
4386 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004387 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00004388 rc = 1;
4389 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004390 }
drhc2ce0be2014-05-29 12:36:14 +00004391 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
4392 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004393 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004394 rc = 1;
4395 goto meta_command_exit;
4396 }
4397 p->outCount = 2;
4398 }else{
4399 p->outCount = 0;
4400 }
4401 output_reset(p);
4402 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00004403#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00004404 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00004405 rc = 1;
4406 p->out = stdout;
4407#else
drhc2ce0be2014-05-29 12:36:14 +00004408 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00004409 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004410 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00004411 p->out = stdout;
4412 rc = 1;
4413 }else{
drhc2ce0be2014-05-29 12:36:14 +00004414 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00004415 }
drh8cd5b252015-03-02 22:06:43 +00004416#endif
drh75897232000-05-29 14:26:00 +00004417 }else{
drhc2ce0be2014-05-29 12:36:14 +00004418 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00004419 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004420 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004421 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00004422 }
drh75897232000-05-29 14:26:00 +00004423 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00004424 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00004425 } else {
drhc2ce0be2014-05-29 12:36:14 +00004426 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00004427 }
4428 }
4429 }else
4430
drh078b1fd2012-09-21 13:40:02 +00004431 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
4432 int i;
4433 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00004434 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00004435 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00004436 }
mistachkinaae280e2015-12-31 19:06:24 +00004437 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00004438 }else
4439
drhc2ce0be2014-05-29 12:36:14 +00004440 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00004441 if( nArg >= 2) {
4442 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
4443 }
4444 if( nArg >= 3) {
4445 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
4446 }
4447 }else
4448
drhc2ce0be2014-05-29 12:36:14 +00004449 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00004450 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00004451 }else
4452
drhc2ce0be2014-05-29 12:36:14 +00004453 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
4454 FILE *alt;
drh4e8142c2016-11-11 14:54:22 +00004455 if( nArg!=2 ){
4456 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004457 rc = 1;
4458 goto meta_command_exit;
4459 }
drh4e8142c2016-11-11 14:54:22 +00004460 alt = fopen(azArg[1], "rb");
4461 if( alt==0 ){
4462 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
4463 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00004464 }else{
drh4e8142c2016-11-11 14:54:22 +00004465 rc = process_input(p, alt);
4466 fclose(alt);
drhdaffd0e2001-04-11 14:28:42 +00004467 }
4468 }else
4469
drhc2ce0be2014-05-29 12:36:14 +00004470 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00004471 const char *zSrcFile;
4472 const char *zDb;
4473 sqlite3 *pSrc;
4474 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00004475 int nTimeout = 0;
4476
drh9ff849f2009-02-04 20:55:57 +00004477 if( nArg==2 ){
4478 zSrcFile = azArg[1];
4479 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00004480 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00004481 zSrcFile = azArg[2];
4482 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00004483 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004484 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004485 rc = 1;
4486 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00004487 }
4488 rc = sqlite3_open(zSrcFile, &pSrc);
4489 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004490 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00004491 sqlite3_close(pSrc);
4492 return 1;
4493 }
drh05782482013-10-24 15:20:20 +00004494 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00004495 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
4496 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004497 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00004498 sqlite3_close(pSrc);
4499 return 1;
4500 }
drhdc2c4912009-02-04 22:46:47 +00004501 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
4502 || rc==SQLITE_BUSY ){
4503 if( rc==SQLITE_BUSY ){
4504 if( nTimeout++ >= 3 ) break;
4505 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00004506 }
4507 }
4508 sqlite3_backup_finish(pBackup);
4509 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00004510 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00004511 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00004512 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00004513 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004514 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004515 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00004516 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004517 }
4518 sqlite3_close(pSrc);
4519 }else
4520
dan8d1edb92014-11-05 09:07:28 +00004521
4522 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
4523 if( nArg==2 ){
4524 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00004525#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00004526 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00004527#endif
dan8d1edb92014-11-05 09:07:28 +00004528 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004529 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00004530 rc = 1;
4531 }
4532 }else
4533
drhc2ce0be2014-05-29 12:36:14 +00004534 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00004535 ShellState data;
drh75897232000-05-29 14:26:00 +00004536 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00004537 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00004538 memcpy(&data, p, sizeof(data));
4539 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00004540 data.cMode = data.mode = MODE_Semi;
drh4926fec2016-04-13 15:33:42 +00004541 if( nArg>=2 && optionMatch(azArg[1], "indent") ){
4542 data.cMode = data.mode = MODE_Pretty;
4543 nArg--;
4544 if( nArg==2 ) azArg[1] = azArg[2];
4545 }
4546 if( nArg==2 && azArg[1][0]!='-' ){
drhc8d74412004-08-31 23:41:26 +00004547 int i;
drhf0693c82011-10-11 20:41:54 +00004548 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00004549 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00004550 char *new_argv[2], *new_colv[2];
4551 new_argv[0] = "CREATE TABLE sqlite_master (\n"
4552 " type text,\n"
4553 " name text,\n"
4554 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00004555 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00004556 " sql text\n"
4557 ")";
4558 new_argv[1] = 0;
4559 new_colv[0] = "sql";
4560 new_colv[1] = 0;
4561 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004562 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00004563 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00004564 char *new_argv[2], *new_colv[2];
4565 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
4566 " type text,\n"
4567 " name text,\n"
4568 " tbl_name text,\n"
4569 " rootpage integer,\n"
4570 " sql text\n"
4571 ")";
4572 new_argv[1] = 0;
4573 new_colv[0] = "sql";
4574 new_colv[1] = 0;
4575 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004576 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00004577 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00004578 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00004579 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004580 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004581 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004582 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004583 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00004584 "WHERE lower(tbl_name) LIKE shellstatic()"
4585 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00004586 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00004587 callback, &data, &zErrMsg);
4588 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00004589 }
drhc2ce0be2014-05-29 12:36:14 +00004590 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00004591 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004592 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004593 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004594 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004595 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00004596 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00004597 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00004598 callback, &data, &zErrMsg
4599 );
drhc2ce0be2014-05-29 12:36:14 +00004600 }else{
drh4926fec2016-04-13 15:33:42 +00004601 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00004602 rc = 1;
4603 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004604 }
drh75897232000-05-29 14:26:00 +00004605 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00004606 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004607 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00004608 rc = 1;
4609 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004610 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00004611 rc = 1;
4612 }else{
4613 rc = 0;
drh75897232000-05-29 14:26:00 +00004614 }
4615 }else
4616
drhabd4c722014-09-20 18:18:33 +00004617#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
4618 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
drh1d9be4f2015-01-22 11:29:25 +00004619 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00004620 }else
4621#endif
4622
drhe6229612014-08-18 15:08:26 +00004623#if defined(SQLITE_ENABLE_SESSION)
4624 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
4625 OpenSession *pSession = &p->aSession[0];
4626 char **azCmd = &azArg[1];
4627 int iSes = 0;
4628 int nCmd = nArg - 1;
4629 int i;
4630 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00004631 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00004632 if( nArg>=3 ){
4633 for(iSes=0; iSes<p->nSession; iSes++){
4634 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
4635 }
4636 if( iSes<p->nSession ){
4637 pSession = &p->aSession[iSes];
4638 azCmd++;
4639 nCmd--;
4640 }else{
4641 pSession = &p->aSession[0];
4642 iSes = 0;
4643 }
4644 }
4645
drh3a67b042014-08-18 17:56:31 +00004646 /* .session attach TABLE
4647 ** Invoke the sqlite3session_attach() interface to attach a particular
4648 ** table so that it is never filtered.
4649 */
4650 if( strcmp(azCmd[0],"attach")==0 ){
4651 if( nCmd!=2 ) goto session_syntax_error;
4652 if( pSession->p==0 ){
4653 session_not_open:
mistachkin899c5c92016-04-03 20:50:02 +00004654 raw_printf(stderr, "ERROR: No sessions are open\n");
drh3a67b042014-08-18 17:56:31 +00004655 }else{
4656 rc = sqlite3session_attach(pSession->p, azCmd[1]);
4657 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004658 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004659 rc = 0;
4660 }
4661 }
4662 }else
4663
4664 /* .session changeset FILE
4665 ** .session patchset FILE
4666 ** Write a changeset or patchset into a file. The file is overwritten.
4667 */
4668 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
4669 FILE *out = 0;
4670 if( nCmd!=2 ) goto session_syntax_error;
4671 if( pSession->p==0 ) goto session_not_open;
4672 out = fopen(azCmd[1], "wb");
4673 if( out==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004674 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
drh3a67b042014-08-18 17:56:31 +00004675 }else{
4676 int szChng;
4677 void *pChng;
4678 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00004679 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00004680 }else{
drh2967e0c2014-08-19 00:26:17 +00004681 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
4682 }
4683 if( rc ){
4684 printf("Error: error code %d\n", rc);
4685 rc = 0;
drh3a67b042014-08-18 17:56:31 +00004686 }
mistachkin1fe36bb2016-04-04 02:16:44 +00004687 if( pChng
drh3a67b042014-08-18 17:56:31 +00004688 && fwrite(pChng, szChng, 1, out)!=1 ){
mistachkin899c5c92016-04-03 20:50:02 +00004689 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
drh3a67b042014-08-18 17:56:31 +00004690 szChng);
4691 }
4692 sqlite3_free(pChng);
4693 fclose(out);
4694 }
4695 }else
4696
drhe6229612014-08-18 15:08:26 +00004697 /* .session close
4698 ** Close the identified session
4699 */
4700 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00004701 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00004702 if( p->nSession ){
4703 session_close(pSession);
4704 p->aSession[iSes] = p->aSession[--p->nSession];
4705 }
4706 }else
4707
drh03168ca2014-08-18 20:01:31 +00004708 /* .session enable ?BOOLEAN?
4709 ** Query or set the enable flag
4710 */
4711 if( strcmp(azCmd[0], "enable")==0 ){
4712 int ii;
4713 if( nCmd>2 ) goto session_syntax_error;
4714 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4715 if( p->nSession ){
4716 ii = sqlite3session_enable(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004717 utf8_printf(p->out, "session %s enable flag = %d\n",
4718 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004719 }
4720 }else
4721
4722 /* .session filter GLOB ....
4723 ** Set a list of GLOB patterns of table names to be excluded.
4724 */
4725 if( strcmp(azCmd[0], "filter")==0 ){
4726 int ii, nByte;
4727 if( nCmd<2 ) goto session_syntax_error;
4728 if( p->nSession ){
4729 for(ii=0; ii<pSession->nFilter; ii++){
4730 sqlite3_free(pSession->azFilter[ii]);
4731 }
4732 sqlite3_free(pSession->azFilter);
4733 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
4734 pSession->azFilter = sqlite3_malloc( nByte );
4735 if( pSession->azFilter==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004736 raw_printf(stderr, "Error: out or memory\n");
drh03168ca2014-08-18 20:01:31 +00004737 exit(1);
4738 }
4739 for(ii=1; ii<nCmd; ii++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004740 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
drh03168ca2014-08-18 20:01:31 +00004741 }
4742 pSession->nFilter = ii-1;
4743 }
4744 }else
4745
4746 /* .session indirect ?BOOLEAN?
4747 ** Query or set the indirect flag
4748 */
4749 if( strcmp(azCmd[0], "indirect")==0 ){
4750 int ii;
4751 if( nCmd>2 ) goto session_syntax_error;
4752 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4753 if( p->nSession ){
4754 ii = sqlite3session_indirect(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004755 utf8_printf(p->out, "session %s indirect flag = %d\n",
4756 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004757 }
4758 }else
4759
4760 /* .session isempty
4761 ** Determine if the session is empty
4762 */
4763 if( strcmp(azCmd[0], "isempty")==0 ){
4764 int ii;
4765 if( nCmd!=1 ) goto session_syntax_error;
4766 if( p->nSession ){
4767 ii = sqlite3session_isempty(pSession->p);
mistachkin899c5c92016-04-03 20:50:02 +00004768 utf8_printf(p->out, "session %s isempty flag = %d\n",
4769 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004770 }
4771 }else
4772
drhe6229612014-08-18 15:08:26 +00004773 /* .session list
4774 ** List all currently open sessions
4775 */
4776 if( strcmp(azCmd[0],"list")==0 ){
4777 for(i=0; i<p->nSession; i++){
mistachkin899c5c92016-04-03 20:50:02 +00004778 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
drhe6229612014-08-18 15:08:26 +00004779 }
4780 }else
4781
4782 /* .session open DB NAME
4783 ** Open a new session called NAME on the attached database DB.
4784 ** DB is normally "main".
4785 */
4786 if( strcmp(azCmd[0],"open")==0 ){
4787 char *zName;
4788 if( nCmd!=3 ) goto session_syntax_error;
4789 zName = azCmd[2];
4790 if( zName[0]==0 ) goto session_syntax_error;
4791 for(i=0; i<p->nSession; i++){
4792 if( strcmp(p->aSession[i].zName,zName)==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004793 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
drhe6229612014-08-18 15:08:26 +00004794 goto meta_command_exit;
4795 }
4796 }
4797 if( p->nSession>=ArraySize(p->aSession) ){
mistachkin899c5c92016-04-03 20:50:02 +00004798 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
drhe6229612014-08-18 15:08:26 +00004799 goto meta_command_exit;
4800 }
4801 pSession = &p->aSession[p->nSession];
4802 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
4803 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004804 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004805 rc = 0;
drhe6229612014-08-18 15:08:26 +00004806 goto meta_command_exit;
4807 }
drh03168ca2014-08-18 20:01:31 +00004808 pSession->nFilter = 0;
4809 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00004810 p->nSession++;
4811 pSession->zName = sqlite3_mprintf("%s", zName);
4812 }else
4813 /* If no command name matches, show a syntax error */
4814 session_syntax_error:
4815 session_help(p);
4816 }else
4817#endif
4818
drh340f5822013-06-27 13:01:21 +00004819#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00004820 /* Undocumented commands for internal testing. Subject to change
4821 ** without notice. */
4822 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
4823 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
4824 int i, v;
4825 for(i=1; i<nArg; i++){
4826 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00004827 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00004828 }
4829 }
4830 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
4831 int i; sqlite3_int64 v;
4832 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00004833 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00004834 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00004835 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00004836 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00004837 }
4838 }
4839 }else
drh340f5822013-06-27 13:01:21 +00004840#endif
drh348d19c2013-06-03 12:47:43 +00004841
drhc2ce0be2014-05-29 12:36:14 +00004842 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00004843 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004844 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00004845 rc = 1;
4846 }
drh6976c212014-07-24 12:09:47 +00004847 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004848 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00004849 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00004850 }
4851 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00004852 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
4853 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00004854 }
drh75897232000-05-29 14:26:00 +00004855 }else
4856
drh62cdde52014-05-28 20:22:28 +00004857 if( c=='s'
4858 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00004859 ){
4860 char *zCmd;
drh54027102014-08-06 14:36:53 +00004861 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00004862 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004863 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00004864 rc = 1;
4865 goto meta_command_exit;
4866 }
drhdcb3e3d2014-05-29 03:17:29 +00004867 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00004868 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00004869 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
4870 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00004871 }
drh54027102014-08-06 14:36:53 +00004872 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00004873 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00004874 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00004875 }else
4876
drhc2ce0be2014-05-29 12:36:14 +00004877 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drheacd29d2016-04-15 15:03:27 +00004878 static const char *azBool[] = { "off", "on", "full", "unk" };
persicom7e2dfdd2002-04-18 02:46:52 +00004879 int i;
drhc2ce0be2014-05-29 12:36:14 +00004880 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00004881 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00004882 rc = 1;
4883 goto meta_command_exit;
4884 }
drheacd29d2016-04-15 15:03:27 +00004885 utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]);
4886 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
drh700c2522016-02-09 18:39:25 +00004887 utf8_printf(p->out, "%12.12s: %s\n","explain",
4888 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
drheacd29d2016-04-15 15:03:27 +00004889 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004890 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
4891 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00004892 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00004893 raw_printf(p->out, "\n");
4894 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00004895 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00004896 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004897 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004898 raw_printf(p->out, "\n");
4899 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004900 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004901 raw_printf(p->out, "\n");
drheacd29d2016-04-15 15:03:27 +00004902 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004903 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00004904 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00004905 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00004906 }
mistachkinaae280e2015-12-31 19:06:24 +00004907 raw_printf(p->out, "\n");
drhcd0509e2016-09-16 00:26:08 +00004908 utf8_printf(p->out, "%12.12s: %s\n", "filename",
4909 p->zDbFilename ? p->zDbFilename : "");
persicom7e2dfdd2002-04-18 02:46:52 +00004910 }else
4911
drhc2ce0be2014-05-29 12:36:14 +00004912 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
4913 if( nArg==2 ){
4914 p->statsOn = booleanValue(azArg[1]);
drh34784902016-02-27 17:12:36 +00004915 }else if( nArg==1 ){
4916 display_stats(p->db, p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004917 }else{
drh34784902016-02-27 17:12:36 +00004918 raw_printf(stderr, "Usage: .stats ?on|off?\n");
drhc2ce0be2014-05-29 12:36:14 +00004919 rc = 1;
4920 }
shaneh642d8b82010-07-28 16:05:34 +00004921 }else
4922
drh6a5a4202016-12-24 21:32:40 +00004923 if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
4924 || (c=='i' && (strncmp(azArg[0], "indices", n)==0
4925 || strncmp(azArg[0], "indexes", n)==0) )
4926 ){
drh98781232012-04-23 12:38:05 +00004927 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00004928 char **azResult;
drh98781232012-04-23 12:38:05 +00004929 int nRow, nAlloc;
4930 char *zSql = 0;
4931 int ii;
drh05782482013-10-24 15:20:20 +00004932 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00004933 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00004934 if( rc ) return shellDatabaseError(p->db);
4935
4936 /* Create an SQL statement to query for the list of tables in the
4937 ** main and all attached databases where the table name matches the
4938 ** LIKE pattern bound to variable "?1". */
drh6a5a4202016-12-24 21:32:40 +00004939 if( c=='t' ){
4940 zSql = sqlite3_mprintf(
4941 "SELECT name FROM sqlite_master"
4942 " WHERE type IN ('table','view')"
4943 " AND name NOT LIKE 'sqlite_%%'"
4944 " AND name LIKE ?1");
4945 }else if( nArg>2 ){
4946 /* It is an historical accident that the .indexes command shows an error
4947 ** when called with the wrong number of arguments whereas the .tables
4948 ** command does not. */
4949 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
4950 rc = 1;
4951 goto meta_command_exit;
4952 }else{
4953 zSql = sqlite3_mprintf(
4954 "SELECT name FROM sqlite_master"
4955 " WHERE type='index'"
4956 " AND tbl_name LIKE ?1");
4957 }
drha4b81d22016-12-24 18:04:28 +00004958 for(ii=0; zSql && sqlite3_step(pStmt)==SQLITE_ROW; ii++){
drh98781232012-04-23 12:38:05 +00004959 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
drha4b81d22016-12-24 18:04:28 +00004960 if( zDbName==0 || ii==0 ) continue;
drh6a5a4202016-12-24 21:32:40 +00004961 if( c=='t' ){
drh98781232012-04-23 12:38:05 +00004962 zSql = sqlite3_mprintf(
4963 "%z UNION ALL "
4964 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4965 " WHERE type IN ('table','view')"
4966 " AND name NOT LIKE 'sqlite_%%'"
4967 " AND name LIKE ?1", zSql, zDbName, zDbName);
drh6a5a4202016-12-24 21:32:40 +00004968 }else{
4969 zSql = sqlite3_mprintf(
4970 "%z UNION ALL "
4971 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4972 " WHERE type='index'"
4973 " AND tbl_name LIKE ?1", zSql, zDbName, zDbName);
drh98781232012-04-23 12:38:05 +00004974 }
drha50da102000-08-08 20:19:09 +00004975 }
dand95bb392015-09-30 11:19:05 +00004976 rc = sqlite3_finalize(pStmt);
4977 if( zSql && rc==SQLITE_OK ){
4978 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
4979 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4980 }
drh98781232012-04-23 12:38:05 +00004981 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00004982 if( !zSql ) return shellNomemError();
4983 if( rc ) return shellDatabaseError(p->db);
4984
4985 /* Run the SQL statement prepared by the above block. Store the results
4986 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00004987 nRow = nAlloc = 0;
4988 azResult = 0;
4989 if( nArg>1 ){
4990 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00004991 }else{
drh98781232012-04-23 12:38:05 +00004992 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
4993 }
4994 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4995 if( nRow>=nAlloc ){
4996 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00004997 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00004998 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00004999 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00005000 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00005001 break;
5002 }
mistachkin8e189222015-04-19 21:43:16 +00005003 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00005004 azResult = azNew;
5005 }
5006 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00005007 if( 0==azResult[nRow] ){
5008 rc = shellNomemError();
5009 break;
5010 }
5011 nRow++;
drh98781232012-04-23 12:38:05 +00005012 }
dand95bb392015-09-30 11:19:05 +00005013 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
5014 rc = shellDatabaseError(p->db);
5015 }
5016
5017 /* Pretty-print the contents of array azResult[] to the output */
5018 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00005019 int len, maxlen = 0;
5020 int i, j;
5021 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00005022 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00005023 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00005024 if( len>maxlen ) maxlen = len;
5025 }
5026 nPrintCol = 80/(maxlen+2);
5027 if( nPrintCol<1 ) nPrintCol = 1;
5028 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
5029 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00005030 for(j=i; j<nRow; j+=nPrintRow){
5031 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00005032 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
5033 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00005034 }
mistachkinaae280e2015-12-31 19:06:24 +00005035 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00005036 }
5037 }
dand95bb392015-09-30 11:19:05 +00005038
drh98781232012-04-23 12:38:05 +00005039 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
5040 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00005041 }else
5042
drh2db82112016-09-15 21:35:24 +00005043 /* Begin redirecting output to the file "testcase-out.txt" */
5044 if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
5045 output_reset(p);
5046 p->out = output_file_open("testcase-out.txt");
5047 if( p->out==0 ){
mistachkin2f9a6132016-11-11 05:19:45 +00005048 raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
drh2db82112016-09-15 21:35:24 +00005049 }
drh760c8162016-09-16 02:52:22 +00005050 if( nArg>=2 ){
5051 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
5052 }else{
5053 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
5054 }
drh2db82112016-09-15 21:35:24 +00005055 }else
drh2db82112016-09-15 21:35:24 +00005056
drhd12602a2016-12-07 15:49:02 +00005057#ifndef SQLITE_UNTESTABLE
shaneh96887e12011-02-10 21:08:58 +00005058 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00005059 static const struct {
5060 const char *zCtrlName; /* Name of a test-control option */
5061 int ctrlCode; /* Integer code for that option */
5062 } aCtrl[] = {
5063 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
5064 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
5065 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
5066 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
5067 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
5068 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
5069 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
5070 { "assert", SQLITE_TESTCTRL_ASSERT },
5071 { "always", SQLITE_TESTCTRL_ALWAYS },
5072 { "reserve", SQLITE_TESTCTRL_RESERVE },
5073 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
5074 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00005075 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00005076 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00005077 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00005078 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00005079 };
shaneh96887e12011-02-10 21:08:58 +00005080 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00005081 int rc2 = 0;
5082 int i, n2;
drh05782482013-10-24 15:20:20 +00005083 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00005084
drhd416fe72011-03-17 16:45:50 +00005085 /* convert testctrl text option to value. allow any unique prefix
5086 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00005087 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00005088 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00005089 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00005090 if( testctrl<0 ){
5091 testctrl = aCtrl[i].ctrlCode;
5092 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005093 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00005094 testctrl = -1;
5095 break;
5096 }
5097 }
5098 }
drh348d19c2013-06-03 12:47:43 +00005099 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005100 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00005101 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005102 }else{
5103 switch(testctrl){
5104
5105 /* sqlite3_test_control(int, db, int) */
5106 case SQLITE_TESTCTRL_OPTIMIZATIONS:
mistachkin1fe36bb2016-04-04 02:16:44 +00005107 case SQLITE_TESTCTRL_RESERVE:
shaneh96887e12011-02-10 21:08:58 +00005108 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005109 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00005110 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00005111 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00005112 } else {
mistachkinaae280e2015-12-31 19:06:24 +00005113 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00005114 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005115 }
5116 break;
5117
5118 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00005119 case SQLITE_TESTCTRL_PRNG_SAVE:
5120 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00005121 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00005122 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00005123 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00005124 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00005125 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00005126 } else {
mistachkinaae280e2015-12-31 19:06:24 +00005127 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
5128 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005129 }
5130 break;
5131
5132 /* sqlite3_test_control(int, uint) */
mistachkin1fe36bb2016-04-04 02:16:44 +00005133 case SQLITE_TESTCTRL_PENDING_BYTE:
shaneh96887e12011-02-10 21:08:58 +00005134 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00005135 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00005136 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00005137 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00005138 } else {
mistachkinaae280e2015-12-31 19:06:24 +00005139 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00005140 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005141 }
5142 break;
mistachkin1fe36bb2016-04-04 02:16:44 +00005143
shaneh96887e12011-02-10 21:08:58 +00005144 /* sqlite3_test_control(int, int) */
mistachkin1fe36bb2016-04-04 02:16:44 +00005145 case SQLITE_TESTCTRL_ASSERT:
5146 case SQLITE_TESTCTRL_ALWAYS:
5147 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00005148 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005149 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00005150 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00005151 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00005152 } else {
mistachkinaae280e2015-12-31 19:06:24 +00005153 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00005154 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005155 }
5156 break;
5157
5158 /* sqlite3_test_control(int, char *) */
5159#ifdef SQLITE_N_KEYWORD
mistachkin1fe36bb2016-04-04 02:16:44 +00005160 case SQLITE_TESTCTRL_ISKEYWORD:
shaneh96887e12011-02-10 21:08:58 +00005161 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005162 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00005163 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00005164 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00005165 } else {
mistachkinaae280e2015-12-31 19:06:24 +00005166 utf8_printf(stderr,
5167 "Error: testctrl %s takes a single char * option\n",
5168 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005169 }
5170 break;
5171#endif
5172
drh1ffede82015-01-30 20:59:27 +00005173 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00005174 if( nArg==5 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005175 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00005176 azArg[2],
drh8964b342015-01-29 17:54:52 +00005177 integerValue(azArg[3]),
5178 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00005179 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00005180 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005181 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00005182 }
5183 break;
5184
mistachkin1fe36bb2016-04-04 02:16:44 +00005185 case SQLITE_TESTCTRL_BITVEC_TEST:
5186 case SQLITE_TESTCTRL_FAULT_INSTALL:
5187 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
5188 case SQLITE_TESTCTRL_SCRATCHMALLOC:
shaneh96887e12011-02-10 21:08:58 +00005189 default:
mistachkinaae280e2015-12-31 19:06:24 +00005190 utf8_printf(stderr,
5191 "Error: CLI support for testctrl %s not implemented\n",
5192 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005193 break;
5194 }
5195 }
5196 }else
5197
drhc2ce0be2014-05-29 12:36:14 +00005198 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00005199 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00005200 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00005201 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00005202
drhc2ce0be2014-05-29 12:36:14 +00005203 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
5204 if( nArg==2 ){
5205 enableTimer = booleanValue(azArg[1]);
5206 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00005207 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00005208 enableTimer = 0;
5209 }
5210 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005211 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00005212 rc = 1;
5213 }
shanehe2aa9d72009-11-06 17:20:17 +00005214 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00005215
drhc2ce0be2014-05-29 12:36:14 +00005216 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00005217 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00005218 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00005219 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00005220 rc = 1;
5221 goto meta_command_exit;
5222 }
drh657b4a82015-03-19 13:30:41 +00005223 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00005224 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00005225#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00005226 if( p->traceOut==0 ){
drh4b363a52016-07-23 20:27:41 +00005227 sqlite3_trace_v2(p->db, 0, 0, 0);
drh42f64e52012-04-04 16:56:23 +00005228 }else{
drh4b363a52016-07-23 20:27:41 +00005229 sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
drh42f64e52012-04-04 16:56:23 +00005230 }
5231#endif
5232 }else
drhd12602a2016-12-07 15:49:02 +00005233#endif /* !defined(SQLITE_UNTESTABLE) */
drh42f64e52012-04-04 16:56:23 +00005234
drhf442e332014-09-10 19:01:14 +00005235#if SQLITE_USER_AUTHENTICATION
5236 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
5237 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00005238 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00005239 rc = 1;
5240 goto meta_command_exit;
5241 }
drh7883ecf2014-09-11 16:19:31 +00005242 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00005243 if( strcmp(azArg[1],"login")==0 ){
5244 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00005245 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00005246 rc = 1;
5247 goto meta_command_exit;
5248 }
drhd39c40f2014-09-11 00:27:53 +00005249 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
5250 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00005251 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005252 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00005253 rc = 1;
5254 }
5255 }else if( strcmp(azArg[1],"add")==0 ){
5256 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00005257 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00005258 rc = 1;
5259 goto meta_command_exit;
5260 }
drhd39c40f2014-09-11 00:27:53 +00005261 rc = sqlite3_user_add(p->db, azArg[2],
5262 azArg[3], (int)strlen(azArg[3]),
5263 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00005264 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005265 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00005266 rc = 1;
5267 }
5268 }else if( strcmp(azArg[1],"edit")==0 ){
5269 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00005270 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00005271 rc = 1;
5272 goto meta_command_exit;
5273 }
drhd39c40f2014-09-11 00:27:53 +00005274 rc = sqlite3_user_change(p->db, azArg[2],
5275 azArg[3], (int)strlen(azArg[3]),
5276 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00005277 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005278 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00005279 rc = 1;
5280 }
5281 }else if( strcmp(azArg[1],"delete")==0 ){
5282 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00005283 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00005284 rc = 1;
5285 goto meta_command_exit;
5286 }
5287 rc = sqlite3_user_delete(p->db, azArg[2]);
5288 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005289 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00005290 rc = 1;
5291 }
5292 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005293 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00005294 rc = 1;
5295 goto meta_command_exit;
mistachkin1fe36bb2016-04-04 02:16:44 +00005296 }
drhf442e332014-09-10 19:01:14 +00005297 }else
5298#endif /* SQLITE_USER_AUTHENTICATION */
5299
drh9fd301b2011-06-03 13:28:22 +00005300 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005301 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00005302 sqlite3_libversion(), sqlite3_sourceid());
5303 }else
5304
drh790f2872015-11-28 18:06:36 +00005305 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
5306 const char *zDbName = nArg==2 ? azArg[1] : "main";
5307 sqlite3_vfs *pVfs;
5308 if( p->db ){
5309 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
5310 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00005311 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
5312 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
5313 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
5314 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00005315 }
5316 }
5317 }else
5318
drhb19e7352016-01-12 19:37:20 +00005319 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
5320 sqlite3_vfs *pVfs;
5321 sqlite3_vfs *pCurrent = 0;
5322 if( p->db ){
5323 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
5324 }
5325 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
5326 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
5327 pVfs==pCurrent ? " <--- CURRENT" : "");
5328 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
5329 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
5330 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
5331 if( pVfs->pNext ){
5332 raw_printf(p->out, "-----------------------------------\n");
5333 }
5334 }
5335 }else
5336
drhde60fc22011-12-14 17:53:36 +00005337 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
5338 const char *zDbName = nArg==2 ? azArg[1] : "main";
5339 char *zVfsName = 0;
5340 if( p->db ){
5341 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
5342 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00005343 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00005344 sqlite3_free(zVfsName);
5345 }
5346 }
5347 }else
5348
dan0fbee292017-01-21 15:58:42 +00005349 if( c=='v' && strncmp(azArg[0], "vmsteps", n)==0 ){
5350 if( nArg==2 ){
5351 p->vmstepsOn = booleanValue(azArg[1]);
5352 }else{
5353 raw_printf(stderr, "Usage: .vmsteps ?on|off?\n");
5354 rc = 1;
5355 }
5356 }else
5357
5358
drhcef4fc82012-09-21 22:50:45 +00005359#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
5360 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
drhc2ce0be2014-05-29 12:36:14 +00005361 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00005362 }else
5363#endif
5364
drhc2ce0be2014-05-29 12:36:14 +00005365 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00005366 int j;
drh43617e92006-03-06 20:55:46 +00005367 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00005368 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00005369 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00005370 }
5371 }else
5372
5373 {
mistachkinaae280e2015-12-31 19:06:24 +00005374 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00005375 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00005376 rc = 1;
drh75897232000-05-29 14:26:00 +00005377 }
drh67505e72002-04-19 12:34:06 +00005378
drhc2ce0be2014-05-29 12:36:14 +00005379meta_command_exit:
5380 if( p->outCount ){
5381 p->outCount--;
5382 if( p->outCount==0 ) output_reset(p);
5383 }
drh67505e72002-04-19 12:34:06 +00005384 return rc;
drh75897232000-05-29 14:26:00 +00005385}
5386
drh67505e72002-04-19 12:34:06 +00005387/*
drh91a66392007-09-07 01:12:32 +00005388** Return TRUE if a semicolon occurs anywhere in the first N characters
5389** of string z[].
drh324ccef2003-02-05 14:06:20 +00005390*/
drh9f099fd2013-08-06 14:01:46 +00005391static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00005392 int i;
5393 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
5394 return 0;
drh324ccef2003-02-05 14:06:20 +00005395}
5396
5397/*
drh70c7a4b2003-04-26 03:03:06 +00005398** Test to see if a line consists entirely of whitespace.
5399*/
5400static int _all_whitespace(const char *z){
5401 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00005402 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00005403 if( *z=='/' && z[1]=='*' ){
5404 z += 2;
5405 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
5406 if( *z==0 ) return 0;
5407 z++;
5408 continue;
5409 }
5410 if( *z=='-' && z[1]=='-' ){
5411 z += 2;
5412 while( *z && *z!='\n' ){ z++; }
5413 if( *z==0 ) return 1;
5414 continue;
5415 }
5416 return 0;
5417 }
5418 return 1;
5419}
5420
5421/*
drha9b17162003-04-29 18:01:28 +00005422** Return TRUE if the line typed in is an SQL command terminator other
5423** than a semi-colon. The SQL Server style "go" command is understood
5424** as is the Oracle "/".
5425*/
drh9f099fd2013-08-06 14:01:46 +00005426static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00005427 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00005428 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
5429 return 1; /* Oracle */
5430 }
drhf0693c82011-10-11 20:41:54 +00005431 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00005432 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00005433 return 1; /* SQL Server */
5434 }
5435 return 0;
5436}
5437
5438/*
drh233a5312008-12-18 22:25:13 +00005439** Return true if zSql is a complete SQL statement. Return false if it
5440** ends in the middle of a string literal or C-style comment.
5441*/
drh9f099fd2013-08-06 14:01:46 +00005442static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00005443 int rc;
5444 if( zSql==0 ) return 1;
5445 zSql[nSql] = ';';
5446 zSql[nSql+1] = 0;
5447 rc = sqlite3_complete(zSql);
5448 zSql[nSql] = 0;
5449 return rc;
5450}
5451
5452/*
drh4e8142c2016-11-11 14:54:22 +00005453** Run a single line of SQL
5454*/
5455static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
5456 int rc;
5457 char *zErrMsg = 0;
5458
5459 open_db(p, 0);
5460 if( p->backslashOn ) resolve_backslashes(zSql);
5461 BEGIN_TIMER;
5462 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
5463 END_TIMER;
5464 if( rc || zErrMsg ){
5465 char zPrefix[100];
5466 if( in!=0 || !stdin_is_interactive ){
5467 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
5468 "Error: near line %d:", startline);
5469 }else{
5470 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
5471 }
5472 if( zErrMsg!=0 ){
5473 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
5474 sqlite3_free(zErrMsg);
5475 zErrMsg = 0;
5476 }else{
5477 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
5478 }
5479 return 1;
5480 }else if( p->countChanges ){
5481 raw_printf(p->out, "changes: %3d total_changes: %d\n",
5482 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
5483 }
5484 return 0;
5485}
5486
5487
5488/*
drh67505e72002-04-19 12:34:06 +00005489** Read input from *in and process it. If *in==0 then input
5490** is interactive - the user is typing it it. Otherwise, input
5491** is coming from a file or device. A prompt is issued and history
5492** is saved only if input is interactive. An interrupt signal will
5493** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00005494**
5495** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00005496*/
drhdcd87a92014-08-18 13:45:42 +00005497static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00005498 char *zLine = 0; /* A single input line */
5499 char *zSql = 0; /* Accumulated SQL text */
5500 int nLine; /* Length of current line */
5501 int nSql = 0; /* Bytes of zSql[] used */
5502 int nAlloc = 0; /* Allocated zSql[] space */
5503 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
drh9f099fd2013-08-06 14:01:46 +00005504 int rc; /* Error code */
5505 int errCnt = 0; /* Number of errors seen */
5506 int lineno = 0; /* Current line number */
5507 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00005508
5509 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
5510 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00005511 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00005512 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00005513 /* End of input */
drhfc8b40f2016-09-07 10:10:18 +00005514 if( in==0 && stdin_is_interactive ) printf("\n");
drh9b8d3572012-04-21 11:33:39 +00005515 break;
drhc49f44e2006-10-26 18:15:42 +00005516 }
drh67505e72002-04-19 12:34:06 +00005517 if( seenInterrupt ){
5518 if( in!=0 ) break;
5519 seenInterrupt = 0;
5520 }
drhc28490c2006-10-26 14:25:58 +00005521 lineno++;
drh849a9d92013-12-21 15:46:06 +00005522 if( nSql==0 && _all_whitespace(zLine) ){
5523 if( p->echoOn ) printf("%s\n", zLine);
5524 continue;
5525 }
drh2af0b2d2002-02-21 02:25:02 +00005526 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00005527 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00005528 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00005529 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00005530 break;
5531 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00005532 errCnt++;
5533 }
drhdaffd0e2001-04-11 14:28:42 +00005534 continue;
5535 }
drh9f099fd2013-08-06 14:01:46 +00005536 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00005537 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00005538 }
drh9f099fd2013-08-06 14:01:46 +00005539 nLine = strlen30(zLine);
5540 if( nSql+nLine+2>=nAlloc ){
5541 nAlloc = nSql+nLine+100;
5542 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00005543 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005544 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00005545 exit(1);
5546 }
drhdaffd0e2001-04-11 14:28:42 +00005547 }
drh9f099fd2013-08-06 14:01:46 +00005548 nSqlPrior = nSql;
5549 if( nSql==0 ){
5550 int i;
5551 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00005552 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00005553 memcpy(zSql, zLine+i, nLine+1-i);
5554 startline = lineno;
5555 nSql = nLine-i;
5556 }else{
5557 zSql[nSql++] = '\n';
5558 memcpy(zSql+nSql, zLine, nLine+1);
5559 nSql += nLine;
5560 }
5561 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00005562 && sqlite3_complete(zSql) ){
drh4e8142c2016-11-11 14:54:22 +00005563 errCnt += runOneSqlLine(p, zSql, in, startline);
drhdaffd0e2001-04-11 14:28:42 +00005564 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00005565 if( p->outCount ){
5566 output_reset(p);
5567 p->outCount = 0;
5568 }
drh9f099fd2013-08-06 14:01:46 +00005569 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00005570 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00005571 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00005572 }
5573 }
drh4e8142c2016-11-11 14:54:22 +00005574 if( nSql && !_all_whitespace(zSql) ){
5575 runOneSqlLine(p, zSql, in, startline);
drhdaffd0e2001-04-11 14:28:42 +00005576 }
drh1f9ca2c2015-08-25 16:57:52 +00005577 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00005578 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00005579 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00005580}
5581
drh67505e72002-04-19 12:34:06 +00005582/*
5583** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00005584** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00005585*/
drhd1459152016-09-16 19:11:03 +00005586static char *find_home_dir(int clearFlag){
drh85e72432012-04-11 11:38:53 +00005587 static char *home_dir = NULL;
drhd1459152016-09-16 19:11:03 +00005588 if( clearFlag ){
5589 free(home_dir);
5590 home_dir = 0;
5591 return 0;
5592 }
drh85e72432012-04-11 11:38:53 +00005593 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00005594
drh4ace5362014-11-10 14:42:28 +00005595#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
5596 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00005597 {
5598 struct passwd *pwent;
5599 uid_t uid = getuid();
5600 if( (pwent=getpwuid(uid)) != NULL) {
5601 home_dir = pwent->pw_dir;
5602 }
drh67505e72002-04-19 12:34:06 +00005603 }
5604#endif
5605
chw65d3c132007-11-12 21:09:10 +00005606#if defined(_WIN32_WCE)
5607 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
5608 */
drh85e72432012-04-11 11:38:53 +00005609 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00005610#else
5611
drh83905c92012-06-21 13:00:37 +00005612#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00005613 if (!home_dir) {
5614 home_dir = getenv("USERPROFILE");
5615 }
5616#endif
5617
drh67505e72002-04-19 12:34:06 +00005618 if (!home_dir) {
5619 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00005620 }
5621
drh83905c92012-06-21 13:00:37 +00005622#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00005623 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00005624 char *zDrive, *zPath;
5625 int n;
5626 zDrive = getenv("HOMEDRIVE");
5627 zPath = getenv("HOMEPATH");
5628 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00005629 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00005630 home_dir = malloc( n );
5631 if( home_dir==0 ) return 0;
5632 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
5633 return home_dir;
5634 }
5635 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00005636 }
5637#endif
5638
chw65d3c132007-11-12 21:09:10 +00005639#endif /* !_WIN32_WCE */
5640
drh67505e72002-04-19 12:34:06 +00005641 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00005642 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00005643 char *z = malloc( n );
5644 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00005645 home_dir = z;
5646 }
drhe98d4fa2002-04-21 19:06:22 +00005647
drh67505e72002-04-19 12:34:06 +00005648 return home_dir;
5649}
5650
5651/*
5652** Read input from the file given by sqliterc_override. Or if that
5653** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00005654**
5655** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00005656*/
drh534f4df2015-02-28 14:03:35 +00005657static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00005658 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00005659 const char *sqliterc_override /* Name of config file. NULL to use default */
5660){
persicom7e2dfdd2002-04-18 02:46:52 +00005661 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00005662 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00005663 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00005664 FILE *in = NULL;
5665
5666 if (sqliterc == NULL) {
drhd1459152016-09-16 19:11:03 +00005667 home_dir = find_home_dir(0);
drhe98d4fa2002-04-21 19:06:22 +00005668 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005669 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00005670 " cannot read ~/.sqliterc\n");
5671 return;
drhe98d4fa2002-04-21 19:06:22 +00005672 }
drh2f3de322012-06-27 16:41:31 +00005673 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00005674 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
5675 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00005676 }
drha1f9b5e2004-02-14 16:31:02 +00005677 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00005678 if( in ){
drhc28490c2006-10-26 14:25:58 +00005679 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00005680 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00005681 }
drh534f4df2015-02-28 14:03:35 +00005682 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00005683 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00005684 }
drh85e72432012-04-11 11:38:53 +00005685 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00005686}
5687
drh67505e72002-04-19 12:34:06 +00005688/*
drhe1e38c42003-05-04 18:30:59 +00005689** Show available command line options
5690*/
mistachkin1fe36bb2016-04-04 02:16:44 +00005691static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00005692 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00005693 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00005694 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005695 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00005696 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00005697 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00005698 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00005699 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00005700 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00005701#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
5702 " -heap SIZE Size of heap for memsys3 or memsys5\n"
5703#endif
drhcc3b4f82012-02-07 14:13:50 +00005704 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00005705 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00005706 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005707 " -line set output mode to 'line'\n"
5708 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00005709 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00005710 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00005711#ifdef SQLITE_ENABLE_MULTIPLEX
5712 " -multiplex enable the multiplexor VFS\n"
5713#endif
mistachkine0d68852014-12-11 03:12:33 +00005714 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00005715 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00005716 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
5717 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00005718 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00005719 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00005720 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00005721 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00005722#ifdef SQLITE_ENABLE_VFSTRACE
5723 " -vfstrace enable tracing of all VFS calls\n"
5724#endif
drhe1e38c42003-05-04 18:30:59 +00005725;
5726static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00005727 utf8_printf(stderr,
mistachkin1fe36bb2016-04-04 02:16:44 +00005728 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
drh80e8be92006-08-29 12:04:19 +00005729 "FILENAME is the name of an SQLite database. A new database is created\n"
5730 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00005731 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00005732 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00005733 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005734 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00005735 }
5736 exit(1);
5737}
5738
5739/*
drh67505e72002-04-19 12:34:06 +00005740** Initialize the state information in data
5741*/
drhdcd87a92014-08-18 13:45:42 +00005742static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00005743 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00005744 data->normalMode = data->cMode = data->mode = MODE_List;
5745 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00005746 memcpy(data->colSeparator,SEP_Column, 2);
5747 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00005748 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00005749 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00005750 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00005751 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00005752 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00005753 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
5754 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00005755}
5756
drh98d312f2012-10-25 15:23:14 +00005757/*
drh5c7976f2014-02-10 19:59:27 +00005758** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00005759*/
5760#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00005761static void printBold(const char *zText){
5762 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
5763 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
5764 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
5765 SetConsoleTextAttribute(out,
5766 FOREGROUND_RED|FOREGROUND_INTENSITY
5767 );
5768 printf("%s", zText);
5769 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00005770}
5771#else
drh5c7976f2014-02-10 19:59:27 +00005772static void printBold(const char *zText){
5773 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00005774}
5775#endif
5776
5777/*
drh98d312f2012-10-25 15:23:14 +00005778** Get the argument to an --option. Throw an error and die if no argument
5779** is available.
5780*/
5781static char *cmdline_option_value(int argc, char **argv, int i){
5782 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00005783 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00005784 argv[0], argv[argc-1]);
5785 exit(1);
5786 }
5787 return argv[i];
5788}
5789
mistachkin1fe36bb2016-04-04 02:16:44 +00005790#ifndef SQLITE_SHELL_IS_UTF8
5791# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
5792# define SQLITE_SHELL_IS_UTF8 (0)
5793# else
5794# define SQLITE_SHELL_IS_UTF8 (1)
5795# endif
5796#endif
5797
5798#if SQLITE_SHELL_IS_UTF8
mistachkin44723ce2015-03-21 02:22:37 +00005799int SQLITE_CDECL main(int argc, char **argv){
mistachkin1fe36bb2016-04-04 02:16:44 +00005800#else
5801int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
mistachkin1810f222016-04-04 02:33:34 +00005802 char **argv;
mistachkin1fe36bb2016-04-04 02:16:44 +00005803#endif
drh75897232000-05-29 14:26:00 +00005804 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00005805 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00005806 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00005807 int i;
drhc28490c2006-10-26 14:25:58 +00005808 int rc = 0;
drhb3735912014-02-10 16:13:42 +00005809 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00005810 int readStdin = 1;
5811 int nCmd = 0;
5812 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00005813
mistachkin1fe36bb2016-04-04 02:16:44 +00005814 setBinaryMode(stdin, 0);
5815 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
mistachkin1810f222016-04-04 02:33:34 +00005816 stdin_is_interactive = isatty(0);
5817 stdout_is_console = isatty(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005818
drh69b30ab2014-02-27 15:11:52 +00005819#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00005820 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005821 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00005822 sqlite3_sourceid(), SQLITE_SOURCE_ID);
5823 exit(1);
5824 }
drhc7181902014-02-27 15:04:13 +00005825#endif
persicom7e2dfdd2002-04-18 02:46:52 +00005826 main_init(&data);
mistachkin1fe36bb2016-04-04 02:16:44 +00005827#if !SQLITE_SHELL_IS_UTF8
5828 sqlite3_initialize();
5829 argv = sqlite3_malloc64(sizeof(argv[0])*argc);
5830 if( argv==0 ){
5831 raw_printf(stderr, "out of memory\n");
5832 exit(1);
5833 }
5834 for(i=0; i<argc; i++){
5835 argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
5836 if( argv[i]==0 ){
5837 raw_printf(stderr, "out of memory\n");
5838 exit(1);
5839 }
5840 }
5841#endif
mistachkin1810f222016-04-04 02:33:34 +00005842 assert( argc>=1 && argv && argv[0] );
mistachkin1fe36bb2016-04-04 02:16:44 +00005843 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00005844
drh44c2eb12003-04-30 11:38:26 +00005845 /* Make sure we have a valid signal handler early, before anything
5846 ** else is done.
5847 */
drh4c504392000-10-16 22:06:40 +00005848#ifdef SIGINT
5849 signal(SIGINT, interrupt_handler);
5850#endif
drh44c2eb12003-04-30 11:38:26 +00005851
drhac5649a2014-11-28 13:35:03 +00005852#ifdef SQLITE_SHELL_DBNAME_PROC
5853 {
5854 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
5855 ** of a C-function that will provide the name of the database file. Use
5856 ** this compile-time option to embed this shell program in larger
5857 ** applications. */
5858 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
5859 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
5860 warnInmemoryDb = 0;
5861 }
5862#endif
5863
drh22fbcb82004-02-01 01:22:50 +00005864 /* Do an initial pass through the command-line argument to locate
5865 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00005866 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00005867 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00005868 */
drh98d312f2012-10-25 15:23:14 +00005869 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00005870 char *z;
drhc28490c2006-10-26 14:25:58 +00005871 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005872 if( z[0]!='-' ){
5873 if( data.zDbFilename==0 ){
5874 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00005875 }else{
5876 /* Excesss arguments are interpreted as SQL (or dot-commands) and
5877 ** mean that nothing is read from stdin */
5878 readStdin = 0;
5879 nCmd++;
5880 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
5881 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005882 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00005883 exit(1);
5884 }
5885 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00005886 }
drh98d312f2012-10-25 15:23:14 +00005887 }
drhcc3b4f82012-02-07 14:13:50 +00005888 if( z[1]=='-' ) z++;
5889 if( strcmp(z,"-separator")==0
5890 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00005891 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00005892 || strcmp(z,"-cmd")==0
5893 ){
drh98d312f2012-10-25 15:23:14 +00005894 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005895 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00005896 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005897 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00005898 /* Need to check for batch mode here to so we can avoid printing
mistachkin1fe36bb2016-04-04 02:16:44 +00005899 ** informational messages (like from process_sqliterc) before
drh98d312f2012-10-25 15:23:14 +00005900 ** we do the actual processing of arguments later in a second pass.
5901 */
shanef69573d2009-10-24 02:06:14 +00005902 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00005903 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00005904#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00005905 const char *zSize;
5906 sqlite3_int64 szHeap;
5907
drh98d312f2012-10-25 15:23:14 +00005908 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00005909 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00005910 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00005911 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
drhc530b9c2016-07-25 11:27:22 +00005912#else
5913 (void)cmdline_option_value(argc, argv, ++i);
drh9c88d682010-12-17 14:03:01 +00005914#endif
drh44dec872014-08-30 15:49:25 +00005915 }else if( strcmp(z,"-scratch")==0 ){
5916 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005917 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005918 if( sz>400000 ) sz = 400000;
5919 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00005920 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005921 if( n>10 ) n = 10;
5922 if( n<1 ) n = 1;
5923 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
5924 data.shellFlgs |= SHFLG_Scratch;
5925 }else if( strcmp(z,"-pagecache")==0 ){
5926 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005927 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005928 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00005929 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005930 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00005931 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
5932 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00005933 data.shellFlgs |= SHFLG_Pagecache;
5934 }else if( strcmp(z,"-lookaside")==0 ){
5935 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005936 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005937 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005938 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005939 if( n<0 ) n = 0;
5940 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
5941 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00005942#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00005943 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00005944 extern int vfstrace_register(
5945 const char *zTraceName,
5946 const char *zOldVfsName,
5947 int (*xOut)(const char*,void*),
5948 void *pOutArg,
5949 int makeDefault
5950 );
drh2b625e22011-03-16 17:05:28 +00005951 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00005952#endif
drh6f25e892011-07-08 17:02:57 +00005953#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00005954 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00005955 extern int sqlite3_multiple_initialize(const char*,int);
5956 sqlite3_multiplex_initialize(0, 1);
5957#endif
drh7d9f3942013-04-03 01:26:54 +00005958 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00005959 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
5960 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00005961 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00005962 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00005963 if( pVfs ){
5964 sqlite3_vfs_register(pVfs, 1);
5965 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005966 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00005967 exit(1);
5968 }
drh44c2eb12003-04-30 11:38:26 +00005969 }
5970 }
drh98d312f2012-10-25 15:23:14 +00005971 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00005972#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00005973 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00005974 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00005975#else
mistachkinaae280e2015-12-31 19:06:24 +00005976 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00005977 return 1;
drh01b41712005-08-29 23:06:23 +00005978#endif
drh98d312f2012-10-25 15:23:14 +00005979 }
5980 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00005981
drh44c2eb12003-04-30 11:38:26 +00005982 /* Go ahead and open the database file if it already exists. If the
5983 ** file does not exist, delay opening it. This prevents empty database
5984 ** files from being created if a user mistypes the database name argument
5985 ** to the sqlite command-line tool.
5986 */
drhc8d74412004-08-31 23:41:26 +00005987 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00005988 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00005989 }
5990
drh22fbcb82004-02-01 01:22:50 +00005991 /* Process the initialization file if there is one. If no -init option
5992 ** is given on the command line, look for a file named ~/.sqliterc and
5993 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00005994 */
drh534f4df2015-02-28 14:03:35 +00005995 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00005996
drh22fbcb82004-02-01 01:22:50 +00005997 /* Make a second pass through the command-line argument and set
5998 ** options. This second pass is delayed until after the initialization
5999 ** file is processed so that the command-line arguments will override
6000 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00006001 */
drh98d312f2012-10-25 15:23:14 +00006002 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00006003 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00006004 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00006005 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00006006 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00006007 i++;
6008 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00006009 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00006010 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00006011 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00006012 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00006013 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00006014 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00006015 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00006016 }else if( strcmp(z,"-csv")==0 ){
6017 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00006018 memcpy(data.colSeparator,",",2);
6019 }else if( strcmp(z,"-ascii")==0 ){
6020 data.mode = MODE_Ascii;
6021 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00006022 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00006023 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00006024 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00006025 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00006026 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00006027 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00006028 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00006029 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00006030 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00006031 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00006032 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00006033 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00006034 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00006035 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00006036 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00006037 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00006038 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00006039 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00006040 }else if( strcmp(z,"-eqp")==0 ){
6041 data.autoEQP = 1;
drheacd29d2016-04-15 15:03:27 +00006042 }else if( strcmp(z,"-eqpfull")==0 ){
6043 data.autoEQP = 2;
shaneh642d8b82010-07-28 16:05:34 +00006044 }else if( strcmp(z,"-stats")==0 ){
6045 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00006046 }else if( strcmp(z,"-scanstats")==0 ){
6047 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00006048 }else if( strcmp(z,"-backslash")==0 ){
6049 /* Undocumented command-line option: -backslash
6050 ** Causes C-style backslash escapes to be evaluated in SQL statements
6051 ** prior to sending the SQL into SQLite. Useful for injecting
6052 ** crazy bytes in the middle of SQL statements for testing and debugging.
6053 */
6054 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00006055 }else if( strcmp(z,"-bail")==0 ){
6056 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00006057 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00006058 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00006059 return 0;
drhc28490c2006-10-26 14:25:58 +00006060 }else if( strcmp(z,"-interactive")==0 ){
6061 stdin_is_interactive = 1;
6062 }else if( strcmp(z,"-batch")==0 ){
6063 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00006064 }else if( strcmp(z,"-heap")==0 ){
6065 i++;
drh44dec872014-08-30 15:49:25 +00006066 }else if( strcmp(z,"-scratch")==0 ){
6067 i+=2;
6068 }else if( strcmp(z,"-pagecache")==0 ){
6069 i+=2;
6070 }else if( strcmp(z,"-lookaside")==0 ){
6071 i+=2;
drh7d9f3942013-04-03 01:26:54 +00006072 }else if( strcmp(z,"-mmap")==0 ){
6073 i++;
drha7e61d82011-03-12 17:02:57 +00006074 }else if( strcmp(z,"-vfs")==0 ){
6075 i++;
drh6f25e892011-07-08 17:02:57 +00006076#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00006077 }else if( strcmp(z,"-vfstrace")==0 ){
6078 i++;
drh6f25e892011-07-08 17:02:57 +00006079#endif
6080#ifdef SQLITE_ENABLE_MULTIPLEX
6081 }else if( strcmp(z,"-multiplex")==0 ){
6082 i++;
6083#endif
drhcc3b4f82012-02-07 14:13:50 +00006084 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00006085 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00006086 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00006087 /* Run commands that follow -cmd first and separately from commands
6088 ** that simply appear on the command-line. This seems goofy. It would
6089 ** be better if all commands ran in the order that they appear. But
6090 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00006091 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00006092 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00006093 if( z[0]=='.' ){
6094 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00006095 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00006096 }else{
drh05782482013-10-24 15:20:20 +00006097 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00006098 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
6099 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00006100 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00006101 if( bail_on_error ) return rc!=0 ? rc : 1;
6102 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00006103 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00006104 if( bail_on_error ) return rc;
6105 }
6106 }
drh1e5d0e92000-05-31 23:33:17 +00006107 }else{
mistachkinaae280e2015-12-31 19:06:24 +00006108 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
6109 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00006110 return 1;
6111 }
drh700c2522016-02-09 18:39:25 +00006112 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00006113 }
drh44c2eb12003-04-30 11:38:26 +00006114
drhac5649a2014-11-28 13:35:03 +00006115 if( !readStdin ){
6116 /* Run all arguments that do not begin with '-' as if they were separate
6117 ** command-line inputs, except for the argToSkip argument which contains
6118 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00006119 */
drhac5649a2014-11-28 13:35:03 +00006120 for(i=0; i<nCmd; i++){
6121 if( azCmd[i][0]=='.' ){
6122 rc = do_meta_command(azCmd[i], &data);
6123 if( rc ) return rc==2 ? 0 : rc;
6124 }else{
6125 open_db(&data, 0);
6126 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
6127 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00006128 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00006129 return rc!=0 ? rc : 1;
6130 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00006131 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00006132 return rc;
6133 }
drh6ff13852001-11-25 13:18:23 +00006134 }
drh75897232000-05-29 14:26:00 +00006135 }
drhac5649a2014-11-28 13:35:03 +00006136 free(azCmd);
drh75897232000-05-29 14:26:00 +00006137 }else{
drh44c2eb12003-04-30 11:38:26 +00006138 /* Run commands received from standard input
6139 */
drhc28490c2006-10-26 14:25:58 +00006140 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00006141 char *zHome;
6142 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00006143 int nHistory;
drh75897232000-05-29 14:26:00 +00006144 printf(
drh743e0032011-12-12 16:51:50 +00006145 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00006146 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00006147 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00006148 );
drhb3735912014-02-10 16:13:42 +00006149 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00006150 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00006151 printBold("transient in-memory database");
6152 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00006153 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00006154 }
drhd1459152016-09-16 19:11:03 +00006155 zHome = find_home_dir(0);
drhea678832008-12-10 19:26:22 +00006156 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00006157 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00006158 if( (zHistory = malloc(nHistory))!=0 ){
6159 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
6160 }
drh67505e72002-04-19 12:34:06 +00006161 }
drhf5ed7ad2015-06-15 14:43:25 +00006162 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00006163 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00006164 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00006165 shell_stifle_history(100);
6166 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00006167 free(zHistory);
drh67505e72002-04-19 12:34:06 +00006168 }
drhdaffd0e2001-04-11 14:28:42 +00006169 }else{
drhc28490c2006-10-26 14:25:58 +00006170 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00006171 }
6172 }
drh33048c02001-10-01 14:29:22 +00006173 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00006174 if( data.db ){
drhe6229612014-08-18 15:08:26 +00006175 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00006176 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00006177 }
mistachkin1fe36bb2016-04-04 02:16:44 +00006178 sqlite3_free(data.zFreeOnClose);
drhd1459152016-09-16 19:11:03 +00006179 find_home_dir(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00006180#if !SQLITE_SHELL_IS_UTF8
6181 for(i=0; i<argc; i++) sqlite3_free(argv[i]);
6182 sqlite3_free(argv);
6183#endif
drhc28490c2006-10-26 14:25:58 +00006184 return rc;
drh75897232000-05-29 14:26:00 +00006185}