blob: b0928ce7928917dbd3203a3cb59bb6c1c8701c61 [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
mistachkin2318d332015-01-12 18:02:52 +000021** If requested, include the SQLite compiler options file for MSVC.
22*/
23#if defined(INCLUDE_MSVC_H)
24#include "msvc.h"
25#endif
26
27/*
drh8cd5b252015-03-02 22:06:43 +000028** No support for loadable extensions in VxWorks.
29*/
drhada3f2b2015-03-23 21:32:50 +000030#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
drh8cd5b252015-03-02 22:06:43 +000031# define SQLITE_OMIT_LOAD_EXTENSION 1
32#endif
33
34/*
drh36f7dd32011-10-13 16:02:17 +000035** Enable large-file support for fopen() and friends on unix.
36*/
37#ifndef SQLITE_DISABLE_LFS
38# define _LARGE_FILE 1
39# ifndef _FILE_OFFSET_BITS
40# define _FILE_OFFSET_BITS 64
41# endif
42# define _LARGEFILE_SOURCE 1
43#endif
44
drh75897232000-05-29 14:26:00 +000045#include <stdlib.h>
46#include <string.h>
47#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000048#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000049#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000050#if SQLITE_USER_AUTHENTICATION
51# include "sqlite3userauth.h"
52#endif
drh75897232000-05-29 14:26:00 +000053#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000054#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000055
drh83905c92012-06-21 13:00:37 +000056#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000057# include <signal.h>
chw97185482008-11-17 08:05:31 +000058# if !defined(__RTP__) && !defined(_WRS_KERNEL)
59# include <pwd.h>
60# endif
drhdd45df82002-04-18 12:39:03 +000061# include <unistd.h>
62# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000063#endif
drh75897232000-05-29 14:26:00 +000064
drh0ede9eb2015-01-10 16:49:23 +000065#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000066# include <readline/readline.h>
67# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000068#endif
danfd34d6d2015-02-25 10:54:53 +000069
drh0ede9eb2015-01-10 16:49:23 +000070#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000071# include <editline/readline.h>
72#endif
danfd34d6d2015-02-25 10:54:53 +000073
74#if HAVE_EDITLINE || HAVE_READLINE
75
76# define shell_add_history(X) add_history(X)
77# define shell_read_history(X) read_history(X)
78# define shell_write_history(X) write_history(X)
79# define shell_stifle_history(X) stifle_history(X)
80# define shell_readline(X) readline(X)
81
82#elif HAVE_LINENOISE
83
84# include "linenoise.h"
85# define shell_add_history(X) linenoiseHistoryAdd(X)
86# define shell_read_history(X) linenoiseHistoryLoad(X)
87# define shell_write_history(X) linenoiseHistorySave(X)
88# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
89# define shell_readline(X) linenoise(X)
90
91#else
92
mistachkin1fe36bb2016-04-04 02:16:44 +000093# define shell_read_history(X)
danfd34d6d2015-02-25 10:54:53 +000094# define shell_write_history(X)
95# define shell_stifle_history(X)
96
97# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000098#endif
99
danfd34d6d2015-02-25 10:54:53 +0000100
adamd2e8464a2006-09-06 21:39:40 +0000101#if defined(_WIN32) || defined(WIN32)
102# include <io.h>
drh6976c212014-07-24 12:09:47 +0000103# include <fcntl.h>
mistachkin073664d2015-06-17 18:57:37 +0000104# define isatty(h) _isatty(h)
105# ifndef access
106# define access(f,m) _access((f),(m))
107# endif
108# undef popen
109# define popen _popen
110# undef pclose
111# define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
mistachkin073664d2015-06-17 18:57:37 +0000113 /* Make sure isatty() has a prototype. */
114 extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000115
mistachkin073664d2015-06-17 18:57:37 +0000116# if !defined(__RTP__) && !defined(_WRS_KERNEL)
117 /* popen and pclose are not C89 functions and so are
118 ** sometimes omitted from the <stdio.h> header */
119 extern FILE *popen(const char*,const char*);
120 extern int pclose(FILE*);
121# else
122# define SQLITE_OMIT_POPEN 1
123# endif
mistachkinf6418892013-08-28 01:54:12 +0000124#endif
drh53371f92013-07-25 17:07:03 +0000125
chw65d3c132007-11-12 21:09:10 +0000126#if defined(_WIN32_WCE)
127/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
128 * thus we always assume that we have a console. That can be
129 * overridden with the -batch command line option.
130 */
131#define isatty(x) 1
132#endif
133
drhf0693c82011-10-11 20:41:54 +0000134/* ctype macros that work with signed characters */
135#define IsSpace(X) isspace((unsigned char)X)
136#define IsDigit(X) isdigit((unsigned char)X)
137#define ToLower(X) (char)tolower((unsigned char)X)
138
mistachkin1fe36bb2016-04-04 02:16:44 +0000139#if defined(_WIN32) || defined(WIN32)
140#include <windows.h>
141
142/* string conversion routines only needed on Win32 */
143extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
144extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
145extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
mistachkin8145fc62016-09-16 20:39:21 +0000146extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
mistachkin1fe36bb2016-04-04 02:16:44 +0000147#endif
148
drh047d4532015-01-18 20:30:23 +0000149/* On Windows, we normally run with output mode of TEXT so that \n characters
150** are automatically translated into \r\n. However, this behavior needs
151** to be disabled in some cases (ex: when generating CSV output and when
152** rendering quoted strings that contain \n characters). The following
153** routines take care of that.
154*/
155#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000156static void setBinaryMode(FILE *file, int isOutput){
157 if( isOutput ) fflush(file);
158 _setmode(_fileno(file), _O_BINARY);
drh047d4532015-01-18 20:30:23 +0000159}
mistachkin1fe36bb2016-04-04 02:16:44 +0000160static void setTextMode(FILE *file, int isOutput){
161 if( isOutput ) fflush(file);
162 _setmode(_fileno(file), _O_TEXT);
drh047d4532015-01-18 20:30:23 +0000163}
164#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000165# define setBinaryMode(X,Y)
166# define setTextMode(X,Y)
drh047d4532015-01-18 20:30:23 +0000167#endif
168
drh43408312013-10-30 12:43:36 +0000169
170/* True if the timer is enabled */
171static int enableTimer = 0;
172
173/* Return the current wall-clock time */
174static sqlite3_int64 timeOfDay(void){
175 static sqlite3_vfs *clockVfs = 0;
176 sqlite3_int64 t;
177 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
dan3fd415b2015-11-16 08:54:10 +0000178 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drh43408312013-10-30 12:43:36 +0000179 clockVfs->xCurrentTimeInt64(clockVfs, &t);
180 }else{
181 double r;
182 clockVfs->xCurrentTime(clockVfs, &r);
183 t = (sqlite3_int64)(r*86400000.0);
184 }
185 return t;
186}
187
drh91eb93c2015-03-03 19:56:20 +0000188#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000189#include <sys/time.h>
190#include <sys/resource.h>
191
drh91eb93c2015-03-03 19:56:20 +0000192/* VxWorks does not support getrusage() as far as we can determine */
193#if defined(_WRS_KERNEL) || defined(__RTP__)
194struct rusage {
195 struct timeval ru_utime; /* user CPU time used */
196 struct timeval ru_stime; /* system CPU time used */
197};
198#define getrusage(A,B) memset(B,0,sizeof(*B))
199#endif
200
drhda108222009-02-25 19:07:24 +0000201/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000202static struct rusage sBegin; /* CPU time at start */
203static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000204
drhda108222009-02-25 19:07:24 +0000205/*
206** Begin timing an operation
207*/
208static void beginTimer(void){
209 if( enableTimer ){
210 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000211 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000212 }
213}
214
215/* Return the difference of two time_structs in seconds */
216static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
mistachkin1fe36bb2016-04-04 02:16:44 +0000217 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
drhda108222009-02-25 19:07:24 +0000218 (double)(pEnd->tv_sec - pStart->tv_sec);
219}
220
221/*
222** Print the timing results.
223*/
224static void endTimer(void){
225 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000226 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000227 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000228 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000229 printf("Run Time: real %.3f user %f sys %f\n",
230 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000231 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
232 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
233 }
234}
shaneb320ccd2009-10-21 03:42:58 +0000235
drhda108222009-02-25 19:07:24 +0000236#define BEGIN_TIMER beginTimer()
237#define END_TIMER endTimer()
238#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000239
240#elif (defined(_WIN32) || defined(WIN32))
241
shaneb320ccd2009-10-21 03:42:58 +0000242/* Saved resource information for the beginning of an operation */
243static HANDLE hProcess;
244static FILETIME ftKernelBegin;
245static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000246static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000247typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
248 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000249static GETPROCTIMES getProcessTimesAddr = NULL;
250
shaneb320ccd2009-10-21 03:42:58 +0000251/*
252** Check to see if we have timer support. Return 1 if necessary
253** support found (or found previously).
254*/
255static int hasTimer(void){
256 if( getProcessTimesAddr ){
257 return 1;
258 } else {
drh4ace5362014-11-10 14:42:28 +0000259 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
260 ** versions. See if the version we are running on has it, and if it
261 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000262 */
263 hProcess = GetCurrentProcess();
264 if( hProcess ){
265 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
266 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000267 getProcessTimesAddr =
268 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000269 if( NULL != getProcessTimesAddr ){
270 return 1;
271 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000272 FreeLibrary(hinstLib);
shaneb320ccd2009-10-21 03:42:58 +0000273 }
274 }
275 }
276 return 0;
277}
278
279/*
280** Begin timing an operation
281*/
282static void beginTimer(void){
283 if( enableTimer && getProcessTimesAddr ){
284 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000285 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
286 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000287 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000288 }
289}
290
291/* Return the difference of two FILETIME structs in seconds */
292static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
293 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
294 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
295 return (double) ((i64End - i64Start) / 10000000.0);
296}
297
298/*
299** Print the timing results.
300*/
301static void endTimer(void){
302 if( enableTimer && getProcessTimesAddr){
303 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000304 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000305 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000306 printf("Run Time: real %.3f user %f sys %f\n",
307 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000308 timeDiff(&ftUserBegin, &ftUserEnd),
309 timeDiff(&ftKernelBegin, &ftKernelEnd));
310 }
311}
312
313#define BEGIN_TIMER beginTimer()
314#define END_TIMER endTimer()
315#define HAS_TIMER hasTimer()
316
drhda108222009-02-25 19:07:24 +0000317#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000318#define BEGIN_TIMER
drhda108222009-02-25 19:07:24 +0000319#define END_TIMER
320#define HAS_TIMER 0
321#endif
322
shanec0688ea2009-03-05 03:48:06 +0000323/*
324** Used to prevent warnings about unused parameters
325*/
326#define UNUSED_PARAMETER(x) (void)(x)
327
drhe91d16b2008-12-08 18:27:31 +0000328/*
drhc49f44e2006-10-26 18:15:42 +0000329** If the following flag is set, then command execution stops
330** at an error if we are not interactive.
331*/
332static int bail_on_error = 0;
333
334/*
drhc28490c2006-10-26 14:25:58 +0000335** Threat stdin as an interactive input if the following variable
336** is true. Otherwise, assume stdin is connected to a file or pipe.
337*/
338static int stdin_is_interactive = 1;
339
340/*
drhe05461c2015-12-30 13:36:57 +0000341** On Windows systems we have to know if standard output is a console
342** in order to translate UTF-8 into MBCS. The following variable is
343** true if translation is required.
344*/
345static int stdout_is_console = 1;
346
347/*
drh4c504392000-10-16 22:06:40 +0000348** The following is the open SQLite database. We make a pointer
349** to this database a static variable so that it can be accessed
350** by the SIGINT handler to interrupt database processing.
351*/
mistachkin8e189222015-04-19 21:43:16 +0000352static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000353
354/*
drh67505e72002-04-19 12:34:06 +0000355** True if an interrupt (Control-C) has been received.
356*/
drh43617e92006-03-06 20:55:46 +0000357static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000358
359/*
persicom7e2dfdd2002-04-18 02:46:52 +0000360** This is the name of our program. It is set in main(), used
361** in a number of other places, mostly for error messages.
362*/
363static char *Argv0;
364
365/*
366** Prompt strings. Initialized in main. Settable with
367** .prompt main continue
368*/
369static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
370static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
371
drhb0603412007-02-28 04:47:26 +0000372/*
mistachkin710b33b2016-01-03 18:59:28 +0000373** Render output like fprintf(). Except, if the output is going to the
374** console and if this is running on a Windows machine, translate the
375** output from UTF-8 into MBCS.
376*/
377#if defined(_WIN32) || defined(WIN32)
378void utf8_printf(FILE *out, const char *zFormat, ...){
379 va_list ap;
380 va_start(ap, zFormat);
381 if( stdout_is_console && (out==stdout || out==stderr) ){
mistachkin710b33b2016-01-03 18:59:28 +0000382 char *z1 = sqlite3_vmprintf(zFormat, ap);
mistachkin1fe36bb2016-04-04 02:16:44 +0000383 char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
mistachkin710b33b2016-01-03 18:59:28 +0000384 sqlite3_free(z1);
385 fputs(z2, out);
386 sqlite3_free(z2);
387 }else{
388 vfprintf(out, zFormat, ap);
389 }
390 va_end(ap);
391}
392#elif !defined(utf8_printf)
393# define utf8_printf fprintf
394#endif
395
396/*
397** Render output like fprintf(). This should not be used on anything that
398** includes string formatting (e.g. "%s").
399*/
400#if !defined(raw_printf)
401# define raw_printf fprintf
402#endif
403
404/*
drhb0603412007-02-28 04:47:26 +0000405** Write I/O traces to the following stream.
406*/
rsebe0a9092007-07-30 18:24:38 +0000407#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000408static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000409#endif
drhb0603412007-02-28 04:47:26 +0000410
411/*
412** This routine works like printf in that its first argument is a
413** format string and subsequent arguments are values to be substituted
414** in place of % fields. The result of formatting this string
415** is written to iotrace.
416*/
rsebe0a9092007-07-30 18:24:38 +0000417#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000418static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000419 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000420 char *z;
drhb0603412007-02-28 04:47:26 +0000421 if( iotrace==0 ) return;
422 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000423 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000424 va_end(ap);
mistachkin710b33b2016-01-03 18:59:28 +0000425 utf8_printf(iotrace, "%s", z);
drhf075cd02007-02-28 06:14:25 +0000426 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000427}
rsebe0a9092007-07-30 18:24:38 +0000428#endif
drhb0603412007-02-28 04:47:26 +0000429
drh44c2eb12003-04-30 11:38:26 +0000430
persicom7e2dfdd2002-04-18 02:46:52 +0000431/*
drh83965662003-04-17 02:54:13 +0000432** Determines if a string is a number of not.
433*/
danielk19772e588c72005-12-09 14:25:08 +0000434static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000435 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000436 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000437 return 0;
438 }
439 z++;
440 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000441 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000442 if( *z=='.' ){
443 z++;
drhf0693c82011-10-11 20:41:54 +0000444 if( !IsDigit(*z) ) return 0;
445 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000446 if( realnum ) *realnum = 1;
447 }
448 if( *z=='e' || *z=='E' ){
449 z++;
450 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000451 if( !IsDigit(*z) ) return 0;
452 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000453 if( realnum ) *realnum = 1;
454 }
455 return *z==0;
456}
drh83965662003-04-17 02:54:13 +0000457
458/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000459** A global char* and an SQL function to access its current value
460** from within an SQL statement. This program used to use the
danielk1977bc6ada42004-06-30 08:20:16 +0000461** sqlite_exec_printf() API to substitue a string into an SQL statement.
462** The correct way to do this with sqlite3 is to use the bind API, but
463** since the shell is built around the callback paradigm it would be a lot
464** of work. Instead just use this hack, which is quite harmless.
465*/
466static const char *zShellStatic = 0;
467static void shellstaticFunc(
468 sqlite3_context *context,
469 int argc,
470 sqlite3_value **argv
471){
472 assert( 0==argc );
473 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000474 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000475 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000476 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
477}
478
479
480/*
drhe05461c2015-12-30 13:36:57 +0000481** Compute a string length that is limited to what can be stored in
482** lower 30 bits of a 32-bit signed integer.
483*/
484static int strlen30(const char *z){
485 const char *z2 = z;
486 while( *z2 ){ z2++; }
487 return 0x3fffffff & (int)(z2 - z);
488}
489
490/*
drhfeac5f82004-08-01 00:10:45 +0000491** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000492** the text in memory obtained from malloc() and returns a pointer
493** to the text. NULL is returned at end of file, or if malloc()
494** fails.
495**
drh9f099fd2013-08-06 14:01:46 +0000496** If zLine is not NULL then it is a malloced buffer returned from
497** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000498*/
drh9f099fd2013-08-06 14:01:46 +0000499static char *local_getline(char *zLine, FILE *in){
500 int nLine = zLine==0 ? 0 : 100;
501 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000502
drhb07028f2011-10-14 21:49:18 +0000503 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000504 if( n+100>nLine ){
505 nLine = nLine*2 + 100;
506 zLine = realloc(zLine, nLine);
507 if( zLine==0 ) return 0;
508 }
drhdaffd0e2001-04-11 14:28:42 +0000509 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000510 if( n==0 ){
511 free(zLine);
512 return 0;
513 }
514 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000515 break;
516 }
drh9f099fd2013-08-06 14:01:46 +0000517 while( zLine[n] ) n++;
518 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000519 n--;
shaneh13b36022009-12-17 21:07:15 +0000520 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000521 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000522 break;
drh8e7e7a22000-05-30 18:45:23 +0000523 }
524 }
drhe05461c2015-12-30 13:36:57 +0000525#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000526 /* For interactive input on Windows systems, translate the
drhe05461c2015-12-30 13:36:57 +0000527 ** multi-byte characterset characters into UTF-8. */
drhfc8b40f2016-09-07 10:10:18 +0000528 if( stdin_is_interactive && in==stdin ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000529 char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
drhe05461c2015-12-30 13:36:57 +0000530 if( zTrans ){
531 int nTrans = strlen30(zTrans)+1;
532 if( nTrans>nLine ){
533 zLine = realloc(zLine, nTrans);
534 if( zLine==0 ){
535 sqlite3_free(zTrans);
536 return 0;
537 }
538 }
539 memcpy(zLine, zTrans, nTrans);
540 sqlite3_free(zTrans);
541 }
542 }
543#endif /* defined(_WIN32) || defined(WIN32) */
drh8e7e7a22000-05-30 18:45:23 +0000544 return zLine;
545}
546
547/*
drhc28490c2006-10-26 14:25:58 +0000548** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000549**
drh9f099fd2013-08-06 14:01:46 +0000550** If in==0 then read from standard input and prompt before each line.
551** If isContinuation is true, then a continuation prompt is appropriate.
552** If isContinuation is zero, then the main prompt should be used.
553**
554** If zPrior is not NULL then it is a buffer from a prior call to this
555** routine that can be reused.
556**
557** The result is stored in space obtained from malloc() and must either
558** be freed by the caller or else passed back into this routine via the
559** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000560*/
drh9f099fd2013-08-06 14:01:46 +0000561static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000562 char *zPrompt;
563 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000564 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000565 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000566 }else{
drh9f099fd2013-08-06 14:01:46 +0000567 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000568#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000569 printf("%s", zPrompt);
570 fflush(stdout);
571 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000572#else
573 free(zPrior);
574 zResult = shell_readline(zPrompt);
575 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000576#endif
drh9f099fd2013-08-06 14:01:46 +0000577 }
drh8e7e7a22000-05-30 18:45:23 +0000578 return zResult;
579}
580
drhe6229612014-08-18 15:08:26 +0000581#if defined(SQLITE_ENABLE_SESSION)
582/*
583** State information for a single open session
584*/
585typedef struct OpenSession OpenSession;
586struct OpenSession {
587 char *zName; /* Symbolic name for this session */
588 int nFilter; /* Number of xFilter rejection GLOB patterns */
589 char **azFilter; /* Array of xFilter rejection GLOB patterns */
590 sqlite3_session *p; /* The open session */
591};
592#endif
593
drhdcd87a92014-08-18 13:45:42 +0000594/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000595** Shell output mode information from before ".explain on",
drhdcd87a92014-08-18 13:45:42 +0000596** saved so that it can be restored by ".explain off"
597*/
598typedef struct SavedModeInfo SavedModeInfo;
599struct SavedModeInfo {
600 int valid; /* Is there legit data in here? */
601 int mode; /* Mode prior to ".explain on" */
602 int showHeader; /* The ".header" setting prior to ".explain on" */
603 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000604};
drh45e29d82006-11-20 16:21:10 +0000605
drh8e7e7a22000-05-30 18:45:23 +0000606/*
drhdcd87a92014-08-18 13:45:42 +0000607** State information about the database connection is contained in an
608** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000609*/
drhdcd87a92014-08-18 13:45:42 +0000610typedef struct ShellState ShellState;
611struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000612 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000613 int echoOn; /* True to echo input commands */
drh700c2522016-02-09 18:39:25 +0000614 int autoExplain; /* Automatically turn on .explain mode */
drhc2ce0be2014-05-29 12:36:14 +0000615 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000616 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000617 int scanstatsOn; /* True to display scan stats before each finalize */
drhdf12f1c2015-12-07 21:46:19 +0000618 int countChanges; /* True to display change counts */
drh9569f602015-04-16 15:05:04 +0000619 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000620 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000621 int cnt; /* Number of records displayed so far */
622 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000623 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000624 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000625 int mode; /* An output mode setting */
drh700c2522016-02-09 18:39:25 +0000626 int cMode; /* temporary output mode for the current query */
627 int normalMode; /* Output mode before ".explain on" */
drh45e29d82006-11-20 16:21:10 +0000628 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000629 int showHeader; /* True to show column names in List or Column mode */
drh760c8162016-09-16 02:52:22 +0000630 int nCheck; /* Number of ".check" commands run */
drh44dec872014-08-30 15:49:25 +0000631 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000632 char *zDestTable; /* Name of destination table when MODE_Insert */
drh760c8162016-09-16 02:52:22 +0000633 char zTestcase[30]; /* Name of current test case */
mistachkin636bf9f2014-07-19 20:15:16 +0000634 char colSeparator[20]; /* Column separator character for several modes */
635 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000636 int colWidth[100]; /* Requested width of each column when in column mode*/
637 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000638 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000639 ** the database */
drh44c2eb12003-04-30 11:38:26 +0000640 char outfile[FILENAME_MAX]; /* Filename for *out */
641 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000642 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000643 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000644 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000645 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000646 int *aiIndent; /* Array of indents used in MODE_Explain */
647 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000648 int iIndent; /* Index of current op in aiIndent[] */
drhe6229612014-08-18 15:08:26 +0000649#if defined(SQLITE_ENABLE_SESSION)
650 int nSession; /* Number of active sessions */
651 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
652#endif
drh75897232000-05-29 14:26:00 +0000653};
654
655/*
drh44dec872014-08-30 15:49:25 +0000656** These are the allowed shellFlgs values
657*/
658#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
659#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
660#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
661
662/*
drh75897232000-05-29 14:26:00 +0000663** These are the allowed modes.
664*/
drh967e8b72000-06-21 13:59:10 +0000665#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000666#define MODE_Column 1 /* One record per line in neat columns */
667#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000668#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
669#define MODE_Html 4 /* Generate an XHTML table */
670#define MODE_Insert 5 /* Generate SQL "insert" statements */
drh41f5f6e2016-10-21 17:39:30 +0000671#define MODE_Quote 6 /* Quote values as for SQL */
672#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
673#define MODE_Csv 8 /* Quote strings, numbers are plain */
674#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
675#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
676#define MODE_Pretty 11 /* Pretty-print schemas */
persicom7e2dfdd2002-04-18 02:46:52 +0000677
drh66ce4d02008-02-15 17:38:06 +0000678static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000679 "line",
680 "column",
681 "list",
682 "semi",
683 "html",
drhfeac5f82004-08-01 00:10:45 +0000684 "insert",
drh41f5f6e2016-10-21 17:39:30 +0000685 "quote",
drhfeac5f82004-08-01 00:10:45 +0000686 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000687 "csv",
drh66ce4d02008-02-15 17:38:06 +0000688 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000689 "ascii",
drh4926fec2016-04-13 15:33:42 +0000690 "prettyprint",
persicom7e2dfdd2002-04-18 02:46:52 +0000691};
drh75897232000-05-29 14:26:00 +0000692
693/*
mistachkinfad42082014-07-24 22:13:12 +0000694** These are the column/row/line separators used by the various
695** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000696*/
mistachkinfad42082014-07-24 22:13:12 +0000697#define SEP_Column "|"
698#define SEP_Row "\n"
699#define SEP_Tab "\t"
700#define SEP_Space " "
701#define SEP_Comma ","
702#define SEP_CrLf "\r\n"
703#define SEP_Unit "\x1F"
704#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000705
706/*
drh75897232000-05-29 14:26:00 +0000707** Number of elements in an array
708*/
drh902b9ee2008-12-05 17:17:07 +0000709#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000710
711/*
drh127f9d72010-02-23 01:47:00 +0000712** A callback for the sqlite3_log() interface.
713*/
714static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000715 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000716 if( p->pLog==0 ) return;
mistachkinaae280e2015-12-31 19:06:24 +0000717 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
drh127f9d72010-02-23 01:47:00 +0000718 fflush(p->pLog);
719}
720
721/*
shane626a6e42009-10-22 17:30:15 +0000722** Output the given string as a hex-encoded blob (eg. X'1234' )
723*/
724static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
725 int i;
726 char *zBlob = (char *)pBlob;
mistachkinaae280e2015-12-31 19:06:24 +0000727 raw_printf(out,"X'");
728 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
729 raw_printf(out,"'");
shane626a6e42009-10-22 17:30:15 +0000730}
731
732/*
drh28bd4bc2000-06-15 15:57:22 +0000733** Output the given string as a quoted string using SQL quoting conventions.
734*/
735static void output_quoted_string(FILE *out, const char *z){
736 int i;
737 int nSingle = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +0000738 setBinaryMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000739 for(i=0; z[i]; i++){
740 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000741 }
742 if( nSingle==0 ){
drhe05461c2015-12-30 13:36:57 +0000743 utf8_printf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000744 }else{
mistachkinaae280e2015-12-31 19:06:24 +0000745 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000746 while( *z ){
747 for(i=0; z[i] && z[i]!='\''; i++){}
748 if( i==0 ){
mistachkinaae280e2015-12-31 19:06:24 +0000749 raw_printf(out,"''");
drh28bd4bc2000-06-15 15:57:22 +0000750 z++;
751 }else if( z[i]=='\'' ){
drhe05461c2015-12-30 13:36:57 +0000752 utf8_printf(out,"%.*s''",i,z);
drh28bd4bc2000-06-15 15:57:22 +0000753 z += i+1;
754 }else{
drhe05461c2015-12-30 13:36:57 +0000755 utf8_printf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000756 break;
757 }
758 }
mistachkinaae280e2015-12-31 19:06:24 +0000759 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000760 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000761 setTextMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000762}
763
764/*
drhfeac5f82004-08-01 00:10:45 +0000765** Output the given string as a quoted according to C or TCL quoting rules.
766*/
767static void output_c_string(FILE *out, const char *z){
768 unsigned int c;
769 fputc('"', out);
770 while( (c = *(z++))!=0 ){
771 if( c=='\\' ){
772 fputc(c, out);
773 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000774 }else if( c=='"' ){
775 fputc('\\', out);
776 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000777 }else if( c=='\t' ){
778 fputc('\\', out);
779 fputc('t', out);
780 }else if( c=='\n' ){
781 fputc('\\', out);
782 fputc('n', out);
783 }else if( c=='\r' ){
784 fputc('\\', out);
785 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000786 }else if( !isprint(c&0xff) ){
mistachkinaae280e2015-12-31 19:06:24 +0000787 raw_printf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000788 }else{
789 fputc(c, out);
790 }
791 }
792 fputc('"', out);
793}
794
795/*
drhc08a4f12000-06-15 16:49:48 +0000796** Output the given string with characters that are special to
797** HTML escaped.
798*/
799static void output_html_string(FILE *out, const char *z){
800 int i;
drhc3d6ba42014-01-13 20:38:35 +0000801 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000802 while( *z ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000803 for(i=0; z[i]
804 && z[i]!='<'
805 && z[i]!='&'
806 && z[i]!='>'
807 && z[i]!='\"'
shane43d9cb22009-10-21 14:11:48 +0000808 && z[i]!='\'';
809 i++){}
drhc08a4f12000-06-15 16:49:48 +0000810 if( i>0 ){
drhe05461c2015-12-30 13:36:57 +0000811 utf8_printf(out,"%.*s",i,z);
drhc08a4f12000-06-15 16:49:48 +0000812 }
813 if( z[i]=='<' ){
mistachkinaae280e2015-12-31 19:06:24 +0000814 raw_printf(out,"&lt;");
drhc08a4f12000-06-15 16:49:48 +0000815 }else if( z[i]=='&' ){
mistachkinaae280e2015-12-31 19:06:24 +0000816 raw_printf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000817 }else if( z[i]=='>' ){
mistachkinaae280e2015-12-31 19:06:24 +0000818 raw_printf(out,"&gt;");
shane43d9cb22009-10-21 14:11:48 +0000819 }else if( z[i]=='\"' ){
mistachkinaae280e2015-12-31 19:06:24 +0000820 raw_printf(out,"&quot;");
shane43d9cb22009-10-21 14:11:48 +0000821 }else if( z[i]=='\'' ){
mistachkinaae280e2015-12-31 19:06:24 +0000822 raw_printf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000823 }else{
824 break;
825 }
826 z += i + 1;
827 }
828}
829
830/*
drhc49f44e2006-10-26 18:15:42 +0000831** If a field contains any character identified by a 1 in the following
832** array, then the string must be quoted for CSV.
833*/
834static const char needCsvQuote[] = {
mistachkin1fe36bb2016-04-04 02:16:44 +0000835 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
836 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
837 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
838 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
839 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
840 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
841 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
842 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
843 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
844 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
845 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
846 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
847 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
848 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
849 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
850 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
drhc49f44e2006-10-26 18:15:42 +0000851};
852
853/*
mistachkindd11f2d2014-12-11 04:49:46 +0000854** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000855** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000856** the null value. Strings are quoted if necessary. The separator
857** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000858*/
drhdcd87a92014-08-18 13:45:42 +0000859static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000860 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000861 if( z==0 ){
drhe05461c2015-12-30 13:36:57 +0000862 utf8_printf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000863 }else{
drhc49f44e2006-10-26 18:15:42 +0000864 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000865 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000866 for(i=0; z[i]; i++){
mistachkin1fe36bb2016-04-04 02:16:44 +0000867 if( needCsvQuote[((unsigned char*)z)[i]]
868 || (z[i]==p->colSeparator[0] &&
mistachkin636bf9f2014-07-19 20:15:16 +0000869 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000870 i = 0;
871 break;
872 }
873 }
874 if( i==0 ){
875 putc('"', out);
876 for(i=0; z[i]; i++){
877 if( z[i]=='"' ) putc('"', out);
878 putc(z[i], out);
879 }
880 putc('"', out);
881 }else{
drhe05461c2015-12-30 13:36:57 +0000882 utf8_printf(out, "%s", z);
drhc49f44e2006-10-26 18:15:42 +0000883 }
drh8e64d1c2004-10-07 00:32:39 +0000884 }
885 if( bSep ){
drhe05461c2015-12-30 13:36:57 +0000886 utf8_printf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000887 }
888}
889
danielk19774af00c62005-01-23 23:43:21 +0000890#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000891/*
drh4c504392000-10-16 22:06:40 +0000892** This routine runs when the user presses Ctrl-C
893*/
894static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000895 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000896 seenInterrupt++;
897 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000898 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000899}
danielk19774af00c62005-01-23 23:43:21 +0000900#endif
drh4c504392000-10-16 22:06:40 +0000901
drha0daa752016-09-16 11:53:10 +0000902#ifndef SQLITE_OMIT_AUTHORIZATION
drh4c504392000-10-16 22:06:40 +0000903/*
drhde613c62016-04-04 17:23:10 +0000904** When the ".auth ON" is set, the following authorizer callback is
905** invoked. It always returns SQLITE_OK.
906*/
907static int shellAuth(
908 void *pClientData,
909 int op,
910 const char *zA1,
911 const char *zA2,
912 const char *zA3,
913 const char *zA4
914){
915 ShellState *p = (ShellState*)pClientData;
916 static const char *azAction[] = { 0,
917 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
918 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
919 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
920 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
921 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
922 "DROP_TRIGGER", "DROP_VIEW", "INSERT",
923 "PRAGMA", "READ", "SELECT",
924 "TRANSACTION", "UPDATE", "ATTACH",
925 "DETACH", "ALTER_TABLE", "REINDEX",
926 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
927 "FUNCTION", "SAVEPOINT", "RECURSIVE"
928 };
929 int i;
930 const char *az[4];
931 az[0] = zA1;
932 az[1] = zA2;
933 az[2] = zA3;
934 az[3] = zA4;
mistachkin8145fc62016-09-16 20:39:21 +0000935 utf8_printf(p->out, "authorizer: %s", azAction[op]);
drhde613c62016-04-04 17:23:10 +0000936 for(i=0; i<4; i++){
937 raw_printf(p->out, " ");
938 if( az[i] ){
939 output_c_string(p->out, az[i]);
940 }else{
941 raw_printf(p->out, "NULL");
942 }
943 }
944 raw_printf(p->out, "\n");
945 return SQLITE_OK;
946}
drha0daa752016-09-16 11:53:10 +0000947#endif
mistachkin8145fc62016-09-16 20:39:21 +0000948
drh79f20e92016-12-13 23:22:39 +0000949/*
950** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
951**
952** This routine converts some CREATE TABLE statements for shadow tables
953** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
954*/
955static void printSchemaLine(FILE *out, const char *z, const char *zTail){
956 if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
957 utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
958 }else{
959 utf8_printf(out, "%s%s", z, zTail);
960 }
961}
962static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
963 char c = z[n];
964 z[n] = 0;
965 printSchemaLine(out, z, zTail);
966 z[n] = c;
967}
drhde613c62016-04-04 17:23:10 +0000968
969/*
shane626a6e42009-10-22 17:30:15 +0000970** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000971** invokes for each row of a query result.
972*/
drh4ace5362014-11-10 14:42:28 +0000973static int shell_callback(
974 void *pArg,
975 int nArg, /* Number of result columns */
976 char **azArg, /* Text of each result column */
977 char **azCol, /* Column names */
978 int *aiType /* Column types */
979){
drh75897232000-05-29 14:26:00 +0000980 int i;
drhdcd87a92014-08-18 13:45:42 +0000981 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000982
drh700c2522016-02-09 18:39:25 +0000983 switch( p->cMode ){
drh75897232000-05-29 14:26:00 +0000984 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000985 int w = 5;
drh6a535342001-10-19 16:44:56 +0000986 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000987 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000988 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000989 if( len>w ) w = len;
990 }
drhe05461c2015-12-30 13:36:57 +0000991 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000992 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000993 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000994 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000995 }
996 break;
997 }
danielk19770d78bae2008-01-03 07:09:48 +0000998 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000999 case MODE_Column: {
drh700c2522016-02-09 18:39:25 +00001000 static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
1001 const int *colWidth;
1002 int showHdr;
1003 char *rowSep;
1004 if( p->cMode==MODE_Column ){
1005 colWidth = p->colWidth;
1006 showHdr = p->showHeader;
1007 rowSep = p->rowSeparator;
1008 }else{
1009 colWidth = aExplainWidths;
1010 showHdr = 1;
mistachkin6d945552016-02-09 20:31:50 +00001011 rowSep = SEP_Row;
drh700c2522016-02-09 18:39:25 +00001012 }
drha0c66f52000-07-29 13:20:21 +00001013 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +00001014 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +00001015 int w, n;
1016 if( i<ArraySize(p->colWidth) ){
drh700c2522016-02-09 18:39:25 +00001017 w = colWidth[i];
drh75897232000-05-29 14:26:00 +00001018 }else{
danielk19770d78bae2008-01-03 07:09:48 +00001019 w = 0;
drh75897232000-05-29 14:26:00 +00001020 }
drh078b1fd2012-09-21 13:40:02 +00001021 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +00001022 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +00001023 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +00001024 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +00001025 if( w<n ) w = n;
1026 }
1027 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001028 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001029 }
drh700c2522016-02-09 18:39:25 +00001030 if( showHdr ){
drh078b1fd2012-09-21 13:40:02 +00001031 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001032 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001033 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001034 }else{
drhe05461c2015-12-30 13:36:57 +00001035 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001036 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001037 }
drha0c66f52000-07-29 13:20:21 +00001038 }
1039 }
drh700c2522016-02-09 18:39:25 +00001040 if( showHdr ){
drha0c66f52000-07-29 13:20:21 +00001041 for(i=0; i<nArg; i++){
1042 int w;
1043 if( i<ArraySize(p->actualWidth) ){
1044 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +00001045 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +00001046 }else{
1047 w = 10;
1048 }
mistachkinaae280e2015-12-31 19:06:24 +00001049 utf8_printf(p->out,"%-*.*s%s",w,w,
drhe05461c2015-12-30 13:36:57 +00001050 "----------------------------------------------------------"
drha0c66f52000-07-29 13:20:21 +00001051 "----------------------------------------------------------",
drh700c2522016-02-09 18:39:25 +00001052 i==nArg-1 ? rowSep : " ");
drha0c66f52000-07-29 13:20:21 +00001053 }
drh75897232000-05-29 14:26:00 +00001054 }
1055 }
drh6a535342001-10-19 16:44:56 +00001056 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001057 for(i=0; i<nArg; i++){
1058 int w;
drha0c66f52000-07-29 13:20:21 +00001059 if( i<ArraySize(p->actualWidth) ){
1060 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001061 }else{
1062 w = 10;
1063 }
drh700c2522016-02-09 18:39:25 +00001064 if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +00001065 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001066 }
dana98bf362013-11-13 18:35:01 +00001067 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +00001068 if( p->iIndent<p->nIndent ){
mistachkinaae280e2015-12-31 19:06:24 +00001069 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +00001070 }
danc4650bb2013-11-18 08:41:06 +00001071 p->iIndent++;
dana98bf362013-11-13 18:35:01 +00001072 }
drh078b1fd2012-09-21 13:40:02 +00001073 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001074 utf8_printf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +00001075 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001076 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001077 }else{
drhe05461c2015-12-30 13:36:57 +00001078 utf8_printf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +00001079 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001080 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001081 }
drh75897232000-05-29 14:26:00 +00001082 }
1083 break;
1084 }
drh4926fec2016-04-13 15:33:42 +00001085 case MODE_Semi: { /* .schema and .fullschema output */
drh79f20e92016-12-13 23:22:39 +00001086 printSchemaLine(p->out, azArg[0], ";\n");
drh4926fec2016-04-13 15:33:42 +00001087 break;
1088 }
1089 case MODE_Pretty: { /* .schema and .fullschema with --indent */
1090 char *z;
drh07d683f2016-04-13 21:00:36 +00001091 int j;
drh4926fec2016-04-13 15:33:42 +00001092 int nParen = 0;
1093 char cEnd = 0;
1094 char c;
1095 int nLine = 0;
1096 assert( nArg==1 );
1097 if( azArg[0]==0 ) break;
1098 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
1099 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
1100 ){
1101 utf8_printf(p->out, "%s;\n", azArg[0]);
1102 break;
1103 }
1104 z = sqlite3_mprintf("%s", azArg[0]);
1105 j = 0;
1106 for(i=0; IsSpace(z[i]); i++){}
1107 for(; (c = z[i])!=0; i++){
1108 if( IsSpace(c) ){
1109 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
1110 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
1111 j--;
1112 }
1113 z[j++] = c;
1114 }
1115 while( j>0 && IsSpace(z[j-1]) ){ j--; }
1116 z[j] = 0;
1117 if( strlen30(z)>=79 ){
drh07d683f2016-04-13 21:00:36 +00001118 for(i=j=0; (c = z[i])!=0; i++){
drh4926fec2016-04-13 15:33:42 +00001119 if( c==cEnd ){
1120 cEnd = 0;
1121 }else if( c=='"' || c=='\'' || c=='`' ){
1122 cEnd = c;
1123 }else if( c=='[' ){
1124 cEnd = ']';
1125 }else if( c=='(' ){
1126 nParen++;
1127 }else if( c==')' ){
1128 nParen--;
1129 if( nLine>0 && nParen==0 && j>0 ){
drh79f20e92016-12-13 23:22:39 +00001130 printSchemaLineN(p->out, z, j, "\n");
drh4926fec2016-04-13 15:33:42 +00001131 j = 0;
1132 }
1133 }
1134 z[j++] = c;
1135 if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
1136 if( c=='\n' ) j--;
drh79f20e92016-12-13 23:22:39 +00001137 printSchemaLineN(p->out, z, j, "\n ");
drh4926fec2016-04-13 15:33:42 +00001138 j = 0;
1139 nLine++;
1140 while( IsSpace(z[i+1]) ){ i++; }
1141 }
1142 }
1143 z[j] = 0;
1144 }
drh79f20e92016-12-13 23:22:39 +00001145 printSchemaLine(p->out, z, ";\n");
drh4926fec2016-04-13 15:33:42 +00001146 sqlite3_free(z);
1147 break;
1148 }
drh75897232000-05-29 14:26:00 +00001149 case MODE_List: {
1150 if( p->cnt++==0 && p->showHeader ){
1151 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001152 utf8_printf(p->out,"%s%s",azCol[i],
mistachkin636bf9f2014-07-19 20:15:16 +00001153 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +00001154 }
1155 }
drh6a535342001-10-19 16:44:56 +00001156 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001157 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001158 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +00001159 if( z==0 ) z = p->nullValue;
drhe05461c2015-12-30 13:36:57 +00001160 utf8_printf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001161 if( i<nArg-1 ){
drhe05461c2015-12-30 13:36:57 +00001162 utf8_printf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +00001163 }else{
drhe05461c2015-12-30 13:36:57 +00001164 utf8_printf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001165 }
drh75897232000-05-29 14:26:00 +00001166 }
1167 break;
1168 }
drh1e5d0e92000-05-31 23:33:17 +00001169 case MODE_Html: {
1170 if( p->cnt++==0 && p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001171 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001172 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001173 raw_printf(p->out,"<TH>");
shane43d9cb22009-10-21 14:11:48 +00001174 output_html_string(p->out, azCol[i]);
mistachkinaae280e2015-12-31 19:06:24 +00001175 raw_printf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001176 }
mistachkinaae280e2015-12-31 19:06:24 +00001177 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001178 }
drh6a535342001-10-19 16:44:56 +00001179 if( azArg==0 ) break;
mistachkinaae280e2015-12-31 19:06:24 +00001180 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001181 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001182 raw_printf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +00001183 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00001184 raw_printf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001185 }
mistachkinaae280e2015-12-31 19:06:24 +00001186 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001187 break;
1188 }
drhfeac5f82004-08-01 00:10:45 +00001189 case MODE_Tcl: {
1190 if( p->cnt++==0 && p->showHeader ){
1191 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001192 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhe05461c2015-12-30 13:36:57 +00001193 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001194 }
drhe05461c2015-12-30 13:36:57 +00001195 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001196 }
1197 if( azArg==0 ) break;
1198 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +00001199 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
drhe05461c2015-12-30 13:36:57 +00001200 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001201 }
drhe05461c2015-12-30 13:36:57 +00001202 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001203 break;
1204 }
drh8e64d1c2004-10-07 00:32:39 +00001205 case MODE_Csv: {
mistachkin1fe36bb2016-04-04 02:16:44 +00001206 setBinaryMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001207 if( p->cnt++==0 && p->showHeader ){
1208 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001209 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001210 }
drhe05461c2015-12-30 13:36:57 +00001211 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001212 }
drh40253262014-10-17 21:35:05 +00001213 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +00001214 for(i=0; i<nArg; i++){
1215 output_csv(p, azArg[i], i<nArg-1);
1216 }
drhe05461c2015-12-30 13:36:57 +00001217 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001218 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001219 setTextMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001220 break;
1221 }
drh41f5f6e2016-10-21 17:39:30 +00001222 case MODE_Quote:
drh28bd4bc2000-06-15 15:57:22 +00001223 case MODE_Insert: {
drh6a535342001-10-19 16:44:56 +00001224 if( azArg==0 ) break;
drh41f5f6e2016-10-21 17:39:30 +00001225 if( p->cMode==MODE_Insert ){
1226 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
1227 if( p->showHeader ){
1228 raw_printf(p->out,"(");
1229 for(i=0; i<nArg; i++){
1230 char *zSep = i>0 ? ",": "";
1231 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
1232 }
1233 raw_printf(p->out,")");
mistachkin151c75a2015-04-07 21:16:40 +00001234 }
drh41f5f6e2016-10-21 17:39:30 +00001235 raw_printf(p->out," VALUES(");
drh59ce2c42016-11-03 13:12:28 +00001236 }else if( p->cnt==0 && p->showHeader ){
1237 for(i=0; i<nArg; i++){
mistachkin2f9a6132016-11-11 05:19:45 +00001238 if( i>0 ) raw_printf(p->out, ",");
drh59ce2c42016-11-03 13:12:28 +00001239 output_quoted_string(p->out, azCol[i]);
1240 }
mistachkin2f9a6132016-11-11 05:19:45 +00001241 raw_printf(p->out,"\n");
mistachkin151c75a2015-04-07 21:16:40 +00001242 }
drh59ce2c42016-11-03 13:12:28 +00001243 p->cnt++;
drh28bd4bc2000-06-15 15:57:22 +00001244 for(i=0; i<nArg; i++){
1245 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001246 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
mistachkinaae280e2015-12-31 19:06:24 +00001247 utf8_printf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001248 }else if( aiType && aiType[i]==SQLITE_TEXT ){
mistachkinaae280e2015-12-31 19:06:24 +00001249 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shanead6b8d02009-10-22 18:12:58 +00001250 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001251 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1252 || aiType[i]==SQLITE_FLOAT) ){
drhe05461c2015-12-30 13:36:57 +00001253 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001254 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1255 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1256 int nBlob = sqlite3_column_bytes(p->pStmt, i);
mistachkinaae280e2015-12-31 19:06:24 +00001257 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shane626a6e42009-10-22 17:30:15 +00001258 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001259 }else if( isNumber(azArg[i], 0) ){
drhe05461c2015-12-30 13:36:57 +00001260 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
drh28bd4bc2000-06-15 15:57:22 +00001261 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001262 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
drh28bd4bc2000-06-15 15:57:22 +00001263 output_quoted_string(p->out, azArg[i]);
1264 }
1265 }
drh41f5f6e2016-10-21 17:39:30 +00001266 raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n");
drh6a535342001-10-19 16:44:56 +00001267 break;
drh28bd4bc2000-06-15 15:57:22 +00001268 }
mistachkin636bf9f2014-07-19 20:15:16 +00001269 case MODE_Ascii: {
1270 if( p->cnt++==0 && p->showHeader ){
1271 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001272 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1273 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +00001274 }
drhe05461c2015-12-30 13:36:57 +00001275 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001276 }
1277 if( azArg==0 ) break;
1278 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001279 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1280 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001281 }
drhe05461c2015-12-30 13:36:57 +00001282 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001283 break;
1284 }
persicom1d0b8722002-04-18 02:53:04 +00001285 }
drh75897232000-05-29 14:26:00 +00001286 return 0;
1287}
1288
1289/*
shane626a6e42009-10-22 17:30:15 +00001290** This is the callback routine that the SQLite library
1291** invokes for each row of a query result.
1292*/
1293static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1294 /* since we don't have type info, call the shell_callback with a NULL value */
1295 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1296}
1297
1298/*
drhdcd87a92014-08-18 13:45:42 +00001299** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001300** the name of the table given. Escape any quote characters in the
1301** table name.
1302*/
drhdcd87a92014-08-18 13:45:42 +00001303static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001304 int i, n;
1305 int needQuote;
1306 char *z;
1307
1308 if( p->zDestTable ){
1309 free(p->zDestTable);
1310 p->zDestTable = 0;
1311 }
1312 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001313 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001314 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001315 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001316 needQuote = 1;
1317 if( zName[i]=='\'' ) n++;
1318 }
1319 }
1320 if( needQuote ) n += 2;
1321 z = p->zDestTable = malloc( n+1 );
1322 if( z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001323 raw_printf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001324 exit(1);
1325 }
1326 n = 0;
1327 if( needQuote ) z[n++] = '\'';
1328 for(i=0; zName[i]; i++){
1329 z[n++] = zName[i];
1330 if( zName[i]=='\'' ) z[n++] = '\'';
1331 }
1332 if( needQuote ) z[n++] = '\'';
1333 z[n] = 0;
1334}
1335
danielk19772a02e332004-06-05 08:04:36 +00001336/* zIn is either a pointer to a NULL-terminated string in memory obtained
1337** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1338** added to zIn, and the result returned in memory obtained from malloc().
1339** zIn, if it was not NULL, is freed.
1340**
mistachkin1fe36bb2016-04-04 02:16:44 +00001341** If the third argument, quote, is not '\0', then it is used as a
danielk19772a02e332004-06-05 08:04:36 +00001342** quote character for zAppend.
1343*/
drhc28490c2006-10-26 14:25:58 +00001344static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001345 int len;
1346 int i;
drh4f21c4a2008-12-10 22:15:00 +00001347 int nAppend = strlen30(zAppend);
1348 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001349
1350 len = nAppend+nIn+1;
1351 if( quote ){
1352 len += 2;
1353 for(i=0; i<nAppend; i++){
1354 if( zAppend[i]==quote ) len++;
1355 }
1356 }
1357
1358 zIn = (char *)realloc(zIn, len);
1359 if( !zIn ){
1360 return 0;
1361 }
1362
1363 if( quote ){
1364 char *zCsr = &zIn[nIn];
1365 *zCsr++ = quote;
1366 for(i=0; i<nAppend; i++){
1367 *zCsr++ = zAppend[i];
1368 if( zAppend[i]==quote ) *zCsr++ = quote;
1369 }
1370 *zCsr++ = quote;
1371 *zCsr++ = '\0';
1372 assert( (zCsr-zIn)==len );
1373 }else{
1374 memcpy(&zIn[nIn], zAppend, nAppend);
1375 zIn[len-1] = '\0';
1376 }
1377
1378 return zIn;
1379}
1380
drhdd3d4592004-08-30 01:54:05 +00001381
1382/*
drhb21a8e42012-01-28 21:08:51 +00001383** Execute a query statement that will generate SQL output. Print
1384** the result columns, comma-separated, on a line and then add a
1385** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001386**
drhb21a8e42012-01-28 21:08:51 +00001387** If the number of columns is 1 and that column contains text "--"
mistachkin1fe36bb2016-04-04 02:16:44 +00001388** then write the semicolon on a separate line. That way, if a
drhb21a8e42012-01-28 21:08:51 +00001389** "--" comment occurs at the end of the statement, the comment
1390** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001391*/
drh157e29a2009-05-21 15:15:00 +00001392static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001393 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001394 const char *zSelect, /* SELECT statement to extract content */
1395 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001396){
drhdd3d4592004-08-30 01:54:05 +00001397 sqlite3_stmt *pSelect;
1398 int rc;
drhb21a8e42012-01-28 21:08:51 +00001399 int nResult;
1400 int i;
1401 const char *z;
drhc7181902014-02-27 15:04:13 +00001402 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001403 if( rc!=SQLITE_OK || !pSelect ){
mistachkinaae280e2015-12-31 19:06:24 +00001404 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1405 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001406 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001407 return rc;
1408 }
1409 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001410 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001411 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001412 if( zFirstRow ){
drhe05461c2015-12-30 13:36:57 +00001413 utf8_printf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001414 zFirstRow = 0;
1415 }
drhb21a8e42012-01-28 21:08:51 +00001416 z = (const char*)sqlite3_column_text(pSelect, 0);
drhe05461c2015-12-30 13:36:57 +00001417 utf8_printf(p->out, "%s", z);
mistachkin1fe36bb2016-04-04 02:16:44 +00001418 for(i=1; i<nResult; i++){
drhe05461c2015-12-30 13:36:57 +00001419 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
drhb21a8e42012-01-28 21:08:51 +00001420 }
1421 if( z==0 ) z = "";
1422 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1423 if( z[0] ){
mistachkinaae280e2015-12-31 19:06:24 +00001424 raw_printf(p->out, "\n;\n");
drhb21a8e42012-01-28 21:08:51 +00001425 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001426 raw_printf(p->out, ";\n");
mistachkin1fe36bb2016-04-04 02:16:44 +00001427 }
drhdd3d4592004-08-30 01:54:05 +00001428 rc = sqlite3_step(pSelect);
1429 }
drh2f464a02011-10-13 00:41:49 +00001430 rc = sqlite3_finalize(pSelect);
1431 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00001432 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1433 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001434 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001435 }
1436 return rc;
drhdd3d4592004-08-30 01:54:05 +00001437}
1438
shane626a6e42009-10-22 17:30:15 +00001439/*
1440** Allocate space and save off current error string.
1441*/
1442static char *save_err_msg(
1443 sqlite3 *db /* Database to query */
1444){
1445 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001446 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001447 if( zErrMsg ){
1448 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1449 }
1450 return zErrMsg;
1451}
1452
drh34784902016-02-27 17:12:36 +00001453#ifdef __linux__
1454/*
1455** Attempt to display I/O stats on Linux using /proc/PID/io
1456*/
1457static void displayLinuxIoStats(FILE *out){
1458 FILE *in;
1459 char z[200];
1460 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
1461 in = fopen(z, "rb");
1462 if( in==0 ) return;
1463 while( fgets(z, sizeof(z), in)!=0 ){
1464 static const struct {
1465 const char *zPattern;
1466 const char *zDesc;
1467 } aTrans[] = {
drhfc1a84c2016-02-27 19:19:22 +00001468 { "rchar: ", "Bytes received by read():" },
1469 { "wchar: ", "Bytes sent to write():" },
1470 { "syscr: ", "Read() system calls:" },
1471 { "syscw: ", "Write() system calls:" },
1472 { "read_bytes: ", "Bytes read from storage:" },
1473 { "write_bytes: ", "Bytes written to storage:" },
1474 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
drh34784902016-02-27 17:12:36 +00001475 };
1476 int i;
1477 for(i=0; i<ArraySize(aTrans); i++){
1478 int n = (int)strlen(aTrans[i].zPattern);
1479 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
mistachkin8145fc62016-09-16 20:39:21 +00001480 utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
drh34784902016-02-27 17:12:36 +00001481 break;
1482 }
1483 }
1484 }
1485 fclose(in);
mistachkin1fe36bb2016-04-04 02:16:44 +00001486}
drh34784902016-02-27 17:12:36 +00001487#endif
1488
1489
shane626a6e42009-10-22 17:30:15 +00001490/*
shaneh642d8b82010-07-28 16:05:34 +00001491** Display memory stats.
1492*/
1493static int display_stats(
1494 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001495 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001496 int bReset /* True to reset the stats */
1497){
1498 int iCur;
1499 int iHiwtr;
1500
1501 if( pArg && pArg->out ){
mistachkin1fe36bb2016-04-04 02:16:44 +00001502
shaneh642d8b82010-07-28 16:05:34 +00001503 iHiwtr = iCur = -1;
1504 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001505 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001506 "Memory Used: %d (max %d) bytes\n",
1507 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001508 iHiwtr = iCur = -1;
1509 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001510 raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001511 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001512 if( pArg->shellFlgs & SHFLG_Pagecache ){
1513 iHiwtr = iCur = -1;
1514 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001515 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001516 "Number of Pcache Pages Used: %d (max %d) pages\n",
1517 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001518 }
shaneh642d8b82010-07-28 16:05:34 +00001519 iHiwtr = iCur = -1;
1520 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001521 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001522 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1523 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001524 if( pArg->shellFlgs & SHFLG_Scratch ){
1525 iHiwtr = iCur = -1;
1526 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001527 raw_printf(pArg->out,
1528 "Number of Scratch Allocations Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001529 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001530 }
shaneh642d8b82010-07-28 16:05:34 +00001531 iHiwtr = iCur = -1;
1532 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001533 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001534 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1535 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001536 iHiwtr = iCur = -1;
1537 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001538 raw_printf(pArg->out, "Largest Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001539 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001540 iHiwtr = iCur = -1;
1541 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001542 raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001543 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001544 iHiwtr = iCur = -1;
1545 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001546 raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001547 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001548#ifdef YYTRACKMAXSTACKDEPTH
1549 iHiwtr = iCur = -1;
1550 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001551 raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001552 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001553#endif
1554 }
1555
1556 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001557 if( pArg->shellFlgs & SHFLG_Lookaside ){
1558 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001559 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1560 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001561 raw_printf(pArg->out,
1562 "Lookaside Slots Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001563 iCur, iHiwtr);
1564 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1565 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001566 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
1567 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001568 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1569 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001570 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
1571 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001572 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1573 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001574 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
1575 iHiwtr);
drh44dec872014-08-30 15:49:25 +00001576 }
shaneh642d8b82010-07-28 16:05:34 +00001577 iHiwtr = iCur = -1;
1578 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001579 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
1580 iCur);
drh4ace5362014-11-10 14:42:28 +00001581 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001582 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001583 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
drhc78e6e42011-09-23 18:58:23 +00001584 iHiwtr = iCur = -1;
1585 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001586 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001587 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001588 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001589 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
drhfbbcd5d2012-03-24 20:09:33 +00001590 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001591 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001592 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001593 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001594 iHiwtr = iCur = -1;
1595 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001596 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001597 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001598 }
1599
1600 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001601 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1602 bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001603 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001604 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001605 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001606 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001607 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001608 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001609 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001610 }
1611
drh34784902016-02-27 17:12:36 +00001612#ifdef __linux__
1613 displayLinuxIoStats(pArg->out);
1614#endif
1615
dan5a790282015-08-07 20:06:14 +00001616 /* Do not remove this machine readable comment: extra-stats-output-here */
1617
shaneh642d8b82010-07-28 16:05:34 +00001618 return 0;
1619}
1620
1621/*
dan8d1edb92014-11-05 09:07:28 +00001622** Display scan stats.
1623*/
1624static void display_scanstats(
1625 sqlite3 *db, /* Database to query */
1626 ShellState *pArg /* Pointer to ShellState */
1627){
drhf5ed7ad2015-06-15 14:43:25 +00001628#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1629 UNUSED_PARAMETER(db);
1630 UNUSED_PARAMETER(pArg);
1631#else
drh15f23c22014-11-06 12:46:16 +00001632 int i, k, n, mx;
mistachkinaae280e2015-12-31 19:06:24 +00001633 raw_printf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001634 mx = 0;
1635 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001636 double rEstLoop = 1.0;
1637 for(i=n=0; 1; i++){
1638 sqlite3_stmt *p = pArg->pStmt;
1639 sqlite3_int64 nLoop, nVisit;
1640 double rEst;
1641 int iSid;
1642 const char *zExplain;
1643 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1644 break;
1645 }
1646 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001647 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001648 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001649 if( n==0 ){
1650 rEstLoop = (double)nLoop;
mistachkinaae280e2015-12-31 19:06:24 +00001651 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001652 }
drh42f30bc2014-11-06 12:08:21 +00001653 n++;
1654 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1655 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1656 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
drhe05461c2015-12-30 13:36:57 +00001657 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
drh42f30bc2014-11-06 12:08:21 +00001658 rEstLoop *= rEst;
mistachkin1fe36bb2016-04-04 02:16:44 +00001659 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001660 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001661 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001662 );
dan8d1edb92014-11-05 09:07:28 +00001663 }
dan8d1edb92014-11-05 09:07:28 +00001664 }
mistachkinaae280e2015-12-31 19:06:24 +00001665 raw_printf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001666#endif
dan8d1edb92014-11-05 09:07:28 +00001667}
1668
1669/*
dana98bf362013-11-13 18:35:01 +00001670** Parameter azArray points to a zero-terminated array of strings. zStr
1671** points to a single nul-terminated string. Return non-zero if zStr
1672** is equal, according to strcmp(), to any of the strings in the array.
1673** Otherwise, return zero.
1674*/
1675static int str_in_array(const char *zStr, const char **azArray){
1676 int i;
1677 for(i=0; azArray[i]; i++){
1678 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1679 }
1680 return 0;
1681}
1682
1683/*
1684** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001685** and populate the ShellState.aiIndent[] array with the number of
mistachkin1fe36bb2016-04-04 02:16:44 +00001686** spaces each opcode should be indented before it is output.
dana98bf362013-11-13 18:35:01 +00001687**
1688** The indenting rules are:
1689**
1690** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1691** all opcodes that occur between the p2 jump destination and the opcode
1692** itself by 2 spaces.
1693**
drh01752bc2013-11-14 23:59:33 +00001694** * For each "Goto", if the jump destination is earlier in the program
1695** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001696** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001697** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001698** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001699** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001700*/
drhdcd87a92014-08-18 13:45:42 +00001701static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001702 const char *zSql; /* The text of the SQL statement */
1703 const char *z; /* Used to check if this is an EXPLAIN */
1704 int *abYield = 0; /* True if op is an OP_Yield */
1705 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001706 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001707
drh8ad0de32014-03-20 18:45:27 +00001708 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1709 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001710 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1711 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001712 const char *azGoto[] = { "Goto", 0 };
1713
1714 /* Try to figure out if this is really an EXPLAIN statement. If this
1715 ** cannot be verified, return early. */
drh87a24aa2016-02-09 20:04:07 +00001716 if( sqlite3_column_count(pSql)!=8 ){
1717 p->cMode = p->mode;
1718 return;
1719 }
dana98bf362013-11-13 18:35:01 +00001720 zSql = sqlite3_sql(pSql);
1721 if( zSql==0 ) return;
1722 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
drh87a24aa2016-02-09 20:04:07 +00001723 if( sqlite3_strnicmp(z, "explain", 7) ){
1724 p->cMode = p->mode;
1725 return;
1726 }
dana98bf362013-11-13 18:35:01 +00001727
1728 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1729 int i;
danc4650bb2013-11-18 08:41:06 +00001730 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001731 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001732
1733 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1734 ** p2 is an instruction address, set variable p2op to the index of that
1735 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1736 ** the current instruction is part of a sub-program generated by an
1737 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001738 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001739 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001740
1741 /* Grow the p->aiIndent array as required */
1742 if( iOp>=nAlloc ){
drh87a24aa2016-02-09 20:04:07 +00001743 if( iOp==0 ){
1744 /* Do further verfication that this is explain output. Abort if
1745 ** it is not */
1746 static const char *explainCols[] = {
1747 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
1748 int jj;
1749 for(jj=0; jj<ArraySize(explainCols); jj++){
1750 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
1751 p->cMode = p->mode;
1752 sqlite3_reset(pSql);
1753 return;
1754 }
1755 }
1756 }
dana98bf362013-11-13 18:35:01 +00001757 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001758 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1759 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001760 }
1761 abYield[iOp] = str_in_array(zOp, azYield);
1762 p->aiIndent[iOp] = 0;
1763 p->nIndent = iOp+1;
1764
1765 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001766 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001767 }
drhfe705102014-03-06 13:38:37 +00001768 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1769 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1770 ){
drheacd29d2016-04-15 15:03:27 +00001771 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001772 }
1773 }
1774
danc4650bb2013-11-18 08:41:06 +00001775 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001776 sqlite3_free(abYield);
1777 sqlite3_reset(pSql);
1778}
1779
1780/*
1781** Free the array allocated by explain_data_prepare().
1782*/
drhdcd87a92014-08-18 13:45:42 +00001783static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001784 sqlite3_free(p->aiIndent);
1785 p->aiIndent = 0;
1786 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001787 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001788}
1789
1790/*
drheacd29d2016-04-15 15:03:27 +00001791** Disable and restore .wheretrace and .selecttrace settings.
1792*/
1793#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1794extern int sqlite3SelectTrace;
1795static int savedSelectTrace;
1796#endif
1797#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1798extern int sqlite3WhereTrace;
1799static int savedWhereTrace;
1800#endif
1801static void disable_debug_trace_modes(void){
1802#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1803 savedSelectTrace = sqlite3SelectTrace;
1804 sqlite3SelectTrace = 0;
1805#endif
1806#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1807 savedWhereTrace = sqlite3WhereTrace;
1808 sqlite3WhereTrace = 0;
1809#endif
1810}
1811static void restore_debug_trace_modes(void){
1812#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1813 sqlite3SelectTrace = savedSelectTrace;
1814#endif
1815#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1816 sqlite3WhereTrace = savedWhereTrace;
1817#endif
1818}
1819
1820/*
1821** Run a prepared statement
1822*/
1823static void exec_prepared_stmt(
1824 ShellState *pArg, /* Pointer to ShellState */
1825 sqlite3_stmt *pStmt, /* Statment to run */
1826 int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
1827){
1828 int rc;
1829
1830 /* perform the first step. this will tell us if we
1831 ** have a result set or not and how wide it is.
1832 */
1833 rc = sqlite3_step(pStmt);
1834 /* if we have a result set... */
1835 if( SQLITE_ROW == rc ){
1836 /* if we have a callback... */
1837 if( xCallback ){
1838 /* allocate space for col name ptr, value ptr, and type */
1839 int nCol = sqlite3_column_count(pStmt);
1840 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
1841 if( !pData ){
1842 rc = SQLITE_NOMEM;
1843 }else{
1844 char **azCols = (char **)pData; /* Names of result columns */
1845 char **azVals = &azCols[nCol]; /* Results */
1846 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1847 int i, x;
1848 assert(sizeof(int) <= sizeof(char *));
1849 /* save off ptrs to column names */
1850 for(i=0; i<nCol; i++){
1851 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1852 }
1853 do{
1854 /* extract the data and data types */
1855 for(i=0; i<nCol; i++){
1856 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1857 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
1858 azVals[i] = "";
1859 }else{
1860 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1861 }
1862 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1863 rc = SQLITE_NOMEM;
1864 break; /* from for */
1865 }
1866 } /* end for */
1867
1868 /* if data and types extracted successfully... */
1869 if( SQLITE_ROW == rc ){
1870 /* call the supplied callback with the result row data */
1871 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1872 rc = SQLITE_ABORT;
1873 }else{
1874 rc = sqlite3_step(pStmt);
1875 }
1876 }
1877 } while( SQLITE_ROW == rc );
1878 sqlite3_free(pData);
1879 }
1880 }else{
1881 do{
1882 rc = sqlite3_step(pStmt);
1883 } while( rc == SQLITE_ROW );
1884 }
1885 }
1886}
1887
1888/*
mistachkin1fe36bb2016-04-04 02:16:44 +00001889** Execute a statement or set of statements. Print
1890** any result rows/columns depending on the current mode
shane626a6e42009-10-22 17:30:15 +00001891** set via the supplied callback.
1892**
mistachkin1fe36bb2016-04-04 02:16:44 +00001893** This is very similar to SQLite's built-in sqlite3_exec()
1894** function except it takes a slightly different callback
shane626a6e42009-10-22 17:30:15 +00001895** and callback data argument.
1896*/
1897static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001898 sqlite3 *db, /* An open database */
1899 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001900 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001901 /* (not the same as sqlite3_exec) */
1902 ShellState *pArg, /* Pointer to ShellState */
1903 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001904){
dan4564ced2010-01-05 04:59:56 +00001905 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1906 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001907 int rc2;
dan4564ced2010-01-05 04:59:56 +00001908 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001909
1910 if( pzErrMsg ){
1911 *pzErrMsg = NULL;
1912 }
1913
shaneb9fc17d2009-10-22 21:23:35 +00001914 while( zSql[0] && (SQLITE_OK == rc) ){
drheacd29d2016-04-15 15:03:27 +00001915 static const char *zStmtSql;
shaneb9fc17d2009-10-22 21:23:35 +00001916 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1917 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001918 if( pzErrMsg ){
1919 *pzErrMsg = save_err_msg(db);
1920 }
1921 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001922 if( !pStmt ){
1923 /* this happens for a comment or white-space */
1924 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001925 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001926 continue;
1927 }
drheacd29d2016-04-15 15:03:27 +00001928 zStmtSql = sqlite3_sql(pStmt);
drh60275612016-11-03 02:25:30 +00001929 if( zStmtSql==0 ) zStmtSql = "";
drheacd29d2016-04-15 15:03:27 +00001930 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
shane626a6e42009-10-22 17:30:15 +00001931
shaneh642d8b82010-07-28 16:05:34 +00001932 /* save off the prepared statment handle and reset row count */
1933 if( pArg ){
1934 pArg->pStmt = pStmt;
1935 pArg->cnt = 0;
1936 }
1937
shanehb7977c52010-01-18 18:17:10 +00001938 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001939 if( pArg && pArg->echoOn ){
drhe05461c2015-12-30 13:36:57 +00001940 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001941 }
shanehb7977c52010-01-18 18:17:10 +00001942
drhefbf3b12014-02-28 20:47:24 +00001943 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
drheacd29d2016-04-15 15:03:27 +00001944 if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
drhefbf3b12014-02-28 20:47:24 +00001945 sqlite3_stmt *pExplain;
drheacd29d2016-04-15 15:03:27 +00001946 char *zEQP;
1947 disable_debug_trace_modes();
1948 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
drhefbf3b12014-02-28 20:47:24 +00001949 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1950 if( rc==SQLITE_OK ){
1951 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001952 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1953 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1954 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001955 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001956 }
1957 }
1958 sqlite3_finalize(pExplain);
1959 sqlite3_free(zEQP);
drheacd29d2016-04-15 15:03:27 +00001960 if( pArg->autoEQP>=2 ){
1961 /* Also do an EXPLAIN for ".eqp full" mode */
1962 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
1963 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1964 if( rc==SQLITE_OK ){
1965 pArg->cMode = MODE_Explain;
1966 explain_data_prepare(pArg, pExplain);
1967 exec_prepared_stmt(pArg, pExplain, xCallback);
1968 explain_data_delete(pArg);
1969 }
1970 sqlite3_finalize(pExplain);
1971 sqlite3_free(zEQP);
1972 }
1973 restore_debug_trace_modes();
drhefbf3b12014-02-28 20:47:24 +00001974 }
1975
drh700c2522016-02-09 18:39:25 +00001976 if( pArg ){
1977 pArg->cMode = pArg->mode;
drh87a24aa2016-02-09 20:04:07 +00001978 if( pArg->autoExplain
1979 && sqlite3_column_count(pStmt)==8
drheacd29d2016-04-15 15:03:27 +00001980 && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
drh700c2522016-02-09 18:39:25 +00001981 ){
1982 pArg->cMode = MODE_Explain;
1983 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001984
drh700c2522016-02-09 18:39:25 +00001985 /* If the shell is currently in ".explain" mode, gather the extra
1986 ** data required to add indents to the output.*/
1987 if( pArg->cMode==MODE_Explain ){
1988 explain_data_prepare(pArg, pStmt);
1989 }
dana98bf362013-11-13 18:35:01 +00001990 }
1991
drheacd29d2016-04-15 15:03:27 +00001992 exec_prepared_stmt(pArg, pStmt, xCallback);
dana98bf362013-11-13 18:35:01 +00001993 explain_data_delete(pArg);
1994
shaneh642d8b82010-07-28 16:05:34 +00001995 /* print usage stats if stats on */
1996 if( pArg && pArg->statsOn ){
1997 display_stats(db, pArg, 0);
1998 }
1999
dan8d1edb92014-11-05 09:07:28 +00002000 /* print loop-counters if required */
2001 if( pArg && pArg->scanstatsOn ){
2002 display_scanstats(db, pArg);
2003 }
2004
mistachkin1fe36bb2016-04-04 02:16:44 +00002005 /* Finalize the statement just executed. If this fails, save a
dan4564ced2010-01-05 04:59:56 +00002006 ** copy of the error message. Otherwise, set zSql to point to the
2007 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00002008 rc2 = sqlite3_finalize(pStmt);
2009 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00002010 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00002011 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00002012 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00002013 }else if( pzErrMsg ){
2014 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00002015 }
shaneh642d8b82010-07-28 16:05:34 +00002016
2017 /* clear saved stmt handle */
2018 if( pArg ){
2019 pArg->pStmt = NULL;
2020 }
shane626a6e42009-10-22 17:30:15 +00002021 }
shaneb9fc17d2009-10-22 21:23:35 +00002022 } /* end while */
shane626a6e42009-10-22 17:30:15 +00002023
2024 return rc;
2025}
2026
drhdd3d4592004-08-30 01:54:05 +00002027
drh33048c02001-10-01 14:29:22 +00002028/*
drh4c653a02000-06-07 01:27:47 +00002029** This is a different callback routine used for dumping the database.
2030** Each row received by this callback consists of a table name,
2031** the table type ("index" or "table") and SQL to create the table.
2032** This routine should print text sufficient to recreate the table.
2033*/
2034static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00002035 int rc;
2036 const char *zTable;
2037 const char *zType;
2038 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00002039 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00002040 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00002041
drh902b9ee2008-12-05 17:17:07 +00002042 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00002043 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00002044 zTable = azArg[0];
2045 zType = azArg[1];
2046 zSql = azArg[2];
mistachkin1fe36bb2016-04-04 02:16:44 +00002047
drh00b950d2005-09-11 02:03:03 +00002048 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00002049 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00002050 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002051 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00002052 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
2053 return 0;
drh45e29d82006-11-20 16:21:10 +00002054 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
2055 char *zIns;
2056 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00002057 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00002058 p->writableSchema = 1;
2059 }
2060 zIns = sqlite3_mprintf(
2061 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
2062 "VALUES('table','%q','%q',0,'%q');",
2063 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00002064 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00002065 sqlite3_free(zIns);
2066 return 0;
drh00b950d2005-09-11 02:03:03 +00002067 }else{
drh79f20e92016-12-13 23:22:39 +00002068 printSchemaLine(p->out, zSql, ";\n");
drhf8eb96a2005-02-03 00:42:34 +00002069 }
danielk19772a02e332004-06-05 08:04:36 +00002070
2071 if( strcmp(zType, "table")==0 ){
2072 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00002073 char *zSelect = 0;
2074 char *zTableInfo = 0;
2075 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00002076 int nRow = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +00002077
danielk19772a02e332004-06-05 08:04:36 +00002078 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
2079 zTableInfo = appendText(zTableInfo, zTable, '"');
2080 zTableInfo = appendText(zTableInfo, ");", 0);
2081
drhc7181902014-02-27 15:04:13 +00002082 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00002083 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00002084 if( rc!=SQLITE_OK || !pTableInfo ){
2085 return 1;
2086 }
2087
2088 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00002089 /* Always quote the table name, even if it appears to be pure ascii,
2090 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
2091 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00002092 if( zTmp ){
2093 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00002094 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00002095 }
2096 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
2097 rc = sqlite3_step(pTableInfo);
2098 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00002099 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00002100 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00002101 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00002102 rc = sqlite3_step(pTableInfo);
2103 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00002104 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00002105 }else{
2106 zSelect = appendText(zSelect, ") ", 0);
2107 }
drh157e29a2009-05-21 15:15:00 +00002108 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00002109 }
2110 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00002111 if( rc!=SQLITE_OK || nRow==0 ){
2112 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00002113 return 1;
2114 }
2115 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
2116 zSelect = appendText(zSelect, zTable, '"');
2117
drh2f464a02011-10-13 00:41:49 +00002118 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00002119 if( rc==SQLITE_CORRUPT ){
2120 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00002121 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00002122 }
drh85e72432012-04-11 11:38:53 +00002123 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00002124 }
drh4c653a02000-06-07 01:27:47 +00002125 return 0;
2126}
2127
2128/*
drh45e29d82006-11-20 16:21:10 +00002129** Run zQuery. Use dump_callback() as the callback routine so that
2130** the contents of the query are output as SQL statements.
2131**
drhdd3d4592004-08-30 01:54:05 +00002132** If we get a SQLITE_CORRUPT error, rerun the query after appending
2133** "ORDER BY rowid DESC" to the end.
2134*/
2135static int run_schema_dump_query(
mistachkin1fe36bb2016-04-04 02:16:44 +00002136 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00002137 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00002138){
2139 int rc;
drh2f464a02011-10-13 00:41:49 +00002140 char *zErr = 0;
2141 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00002142 if( rc==SQLITE_CORRUPT ){
2143 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00002144 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00002145 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00002146 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00002147 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002148 sqlite3_free(zErr);
2149 zErr = 0;
2150 }
drhdd3d4592004-08-30 01:54:05 +00002151 zQ2 = malloc( len+100 );
2152 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00002153 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00002154 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
2155 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002156 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002157 }else{
2158 rc = SQLITE_CORRUPT;
2159 }
2160 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00002161 free(zQ2);
2162 }
2163 return rc;
2164}
2165
2166/*
drh75897232000-05-29 14:26:00 +00002167** Text of a help message
2168*/
persicom1d0b8722002-04-18 02:53:04 +00002169static char zHelp[] =
drha0daa752016-09-16 11:53:10 +00002170#ifndef SQLITE_OMIT_AUTHORIZATION
drhde613c62016-04-04 17:23:10 +00002171 ".auth ON|OFF Show authorizer callbacks\n"
drha0daa752016-09-16 11:53:10 +00002172#endif
drh9ff849f2009-02-04 20:55:57 +00002173 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00002174 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00002175 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00002176 ".changes on|off Show number of rows changed by SQL\n"
drh2db82112016-09-15 21:35:24 +00002177 ".check GLOB Fail if output since .testcase does not match\n"
drh4bbcf102014-02-06 02:46:08 +00002178 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00002179 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00002180 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00002181 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00002182 " If TABLE specified, only dump tables matching\n"
2183 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00002184 ".echo on|off Turn command echo on or off\n"
drheacd29d2016-04-15 15:03:27 +00002185 ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00002186 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00002187 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drh4926fec2016-04-13 15:33:42 +00002188 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00002189 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00002190 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00002191 ".import FILE TABLE Import data from FILE into TABLE\n"
drh16eb5942016-11-03 13:01:38 +00002192#ifndef SQLITE_OMIT_TEST_CONTROL
2193 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n"
2194#endif
drh0e55db12015-02-06 14:51:13 +00002195 ".indexes ?TABLE? Show names of all indexes\n"
2196 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00002197 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00002198#ifdef SQLITE_ENABLE_IOTRACE
2199 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
2200#endif
drh1a513372015-05-02 17:40:23 +00002201 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh3fd9f332016-12-16 18:41:11 +00002202 ".lint OPTIONS Report potential schema issues. Options:\n"
2203 " fkey-indexes Find missing foreign key indexes\n"
drh70df4fe2006-06-13 15:12:21 +00002204#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002205 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00002206#endif
drh127f9d72010-02-23 01:47:00 +00002207 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00002208 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00002209 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00002210 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00002211 " column Left-aligned columns. (See .width)\n"
2212 " html HTML <table> code\n"
2213 " insert SQL insert statements for TABLE\n"
2214 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00002215 " list Values delimited by .separator strings\n"
drh41f5f6e2016-10-21 17:39:30 +00002216 " quote Escape answers as for SQL\n"
drhb860bc92004-08-04 15:16:55 +00002217 " tabs Tab-separated values\n"
2218 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00002219 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00002220 ".once FILENAME Output for the next SQL command only to FILENAME\n"
mistachkin8145fc62016-09-16 20:39:21 +00002221 ".open ?--new? ?FILE? Close existing database and reopen FILE\n"
drhcd0509e2016-09-16 00:26:08 +00002222 " The --new starts with an empty file\n"
drhc2ce0be2014-05-29 12:36:14 +00002223 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00002224 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002225 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002226 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00002227 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00002228 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00002229 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00002230 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh4926fec2016-04-13 15:33:42 +00002231 ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
2232 " Add --indent for pretty-printing\n"
mistachkine0d68852014-12-11 03:12:33 +00002233 ".separator COL ?ROW? Change the column separator and optionally the row\n"
2234 " separator for both the output mode and .import\n"
drhe6229612014-08-18 15:08:26 +00002235#if defined(SQLITE_ENABLE_SESSION)
2236 ".session CMD ... Create or control sessions\n"
2237#endif
drh62cdde52014-05-28 20:22:28 +00002238 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00002239 ".show Show the current values for various settings\n"
drh34784902016-02-27 17:12:36 +00002240 ".stats ?on|off? Show stats or turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00002241 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00002242 ".tables ?TABLE? List names of tables\n"
2243 " If TABLE specified, only list tables matching\n"
2244 " LIKE pattern TABLE.\n"
drh760c8162016-09-16 02:52:22 +00002245 ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
drh2dfbbca2000-07-28 14:32:48 +00002246 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00002247 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00002248 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00002249 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00002250 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00002251 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00002252 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00002253 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00002254;
2255
drhe6229612014-08-18 15:08:26 +00002256#if defined(SQLITE_ENABLE_SESSION)
2257/*
2258** Print help information for the ".sessions" command
2259*/
2260void session_help(ShellState *p){
mistachkin899c5c92016-04-03 20:50:02 +00002261 raw_printf(p->out,
drhe6229612014-08-18 15:08:26 +00002262 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
2263 "If ?NAME? is omitted, the first defined session is used.\n"
2264 "Subcommands:\n"
2265 " attach TABLE Attach TABLE\n"
2266 " changeset FILE Write a changeset into FILE\n"
2267 " close Close one session\n"
2268 " enable ?BOOLEAN? Set or query the enable bit\n"
mistachkin1fe36bb2016-04-04 02:16:44 +00002269 " filter GLOB... Reject tables matching GLOBs\n"
drhe6229612014-08-18 15:08:26 +00002270 " indirect ?BOOLEAN? Mark or query the indirect status\n"
2271 " isempty Query whether the session is empty\n"
2272 " list List currently open session names\n"
2273 " open DB NAME Open a new session on DB\n"
2274 " patchset FILE Write a patchset into FILE\n"
2275 );
2276}
2277#endif
2278
2279
drhdaffd0e2001-04-11 14:28:42 +00002280/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00002281static int process_input(ShellState *p, FILE *in);
drh2db82112016-09-15 21:35:24 +00002282
drh2db82112016-09-15 21:35:24 +00002283/*
dan11da0022016-12-17 08:18:05 +00002284** Read the content of file zName into memory obtained from sqlite3_malloc64()
2285** and return a pointer to the buffer. The caller is responsible for freeing
2286** the memory.
drh2db82112016-09-15 21:35:24 +00002287**
dan11da0022016-12-17 08:18:05 +00002288** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes
2289** read.
2290**
2291** For convenience, a nul-terminator byte is always appended to the data read
2292** from the file before the buffer is returned. This byte is not included in
2293** the final value of (*pnByte), if applicable.
2294**
2295** NULL is returned if any error is encountered. The final value of *pnByte
2296** is undefined in this case.
drh2db82112016-09-15 21:35:24 +00002297*/
dan11da0022016-12-17 08:18:05 +00002298static char *readFile(const char *zName, int *pnByte){
drh2db82112016-09-15 21:35:24 +00002299 FILE *in = fopen(zName, "rb");
2300 long nIn;
drhd1459152016-09-16 19:11:03 +00002301 size_t nRead;
drh2db82112016-09-15 21:35:24 +00002302 char *pBuf;
2303 if( in==0 ) return 0;
2304 fseek(in, 0, SEEK_END);
2305 nIn = ftell(in);
2306 rewind(in);
drhd1459152016-09-16 19:11:03 +00002307 pBuf = sqlite3_malloc64( nIn+1 );
drh2db82112016-09-15 21:35:24 +00002308 if( pBuf==0 ) return 0;
drhd1459152016-09-16 19:11:03 +00002309 nRead = fread(pBuf, nIn, 1, in);
2310 fclose(in);
2311 if( nRead!=1 ){
drh2db82112016-09-15 21:35:24 +00002312 sqlite3_free(pBuf);
2313 return 0;
2314 }
drhd1459152016-09-16 19:11:03 +00002315 pBuf[nIn] = 0;
dan11da0022016-12-17 08:18:05 +00002316 if( pnByte ) *pnByte = nIn;
drh2db82112016-09-15 21:35:24 +00002317 return pBuf;
2318}
2319
drhba5b0932014-07-24 12:39:59 +00002320/*
2321** Implementation of the "readfile(X)" SQL function. The entire content
2322** of the file named X is read and returned as a BLOB. NULL is returned
2323** if the file does not exist or is unreadable.
2324*/
2325static void readfileFunc(
2326 sqlite3_context *context,
2327 int argc,
2328 sqlite3_value **argv
2329){
2330 const char *zName;
drhba5b0932014-07-24 12:39:59 +00002331 void *pBuf;
dan11da0022016-12-17 08:18:05 +00002332 int nBuf;
drhba5b0932014-07-24 12:39:59 +00002333
drhf5ed7ad2015-06-15 14:43:25 +00002334 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002335 zName = (const char*)sqlite3_value_text(argv[0]);
2336 if( zName==0 ) return;
dan11da0022016-12-17 08:18:05 +00002337 pBuf = readFile(zName, &nBuf);
2338 if( pBuf ) sqlite3_result_blob(context, pBuf, nBuf, sqlite3_free);
drhba5b0932014-07-24 12:39:59 +00002339}
2340
2341/*
2342** Implementation of the "writefile(X,Y)" SQL function. The argument Y
2343** is written into file X. The number of bytes written is returned. Or
2344** NULL is returned if something goes wrong, such as being unable to open
2345** file X for writing.
2346*/
2347static void writefileFunc(
2348 sqlite3_context *context,
2349 int argc,
2350 sqlite3_value **argv
2351){
2352 FILE *out;
2353 const char *z;
drhba5b0932014-07-24 12:39:59 +00002354 sqlite3_int64 rc;
2355 const char *zFile;
2356
drhf5ed7ad2015-06-15 14:43:25 +00002357 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002358 zFile = (const char*)sqlite3_value_text(argv[0]);
2359 if( zFile==0 ) return;
2360 out = fopen(zFile, "wb");
2361 if( out==0 ) return;
2362 z = (const char*)sqlite3_value_blob(argv[1]);
2363 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002364 rc = 0;
2365 }else{
drh490fe862014-08-11 14:21:32 +00002366 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002367 }
2368 fclose(out);
2369 sqlite3_result_int64(context, rc);
2370}
drhdaffd0e2001-04-11 14:28:42 +00002371
drhe6229612014-08-18 15:08:26 +00002372#if defined(SQLITE_ENABLE_SESSION)
2373/*
2374** Close a single OpenSession object and release all of its associated
2375** resources.
2376*/
2377static void session_close(OpenSession *pSession){
2378 int i;
2379 sqlite3session_delete(pSession->p);
2380 sqlite3_free(pSession->zName);
2381 for(i=0; i<pSession->nFilter; i++){
2382 sqlite3_free(pSession->azFilter[i]);
2383 }
2384 sqlite3_free(pSession->azFilter);
2385 memset(pSession, 0, sizeof(OpenSession));
2386}
2387#endif
2388
2389/*
drh51b55a32016-04-04 12:38:05 +00002390** Close all OpenSession objects and release all associated resources.
drhe6229612014-08-18 15:08:26 +00002391*/
drhe6229612014-08-18 15:08:26 +00002392#if defined(SQLITE_ENABLE_SESSION)
drh51b55a32016-04-04 12:38:05 +00002393static void session_close_all(ShellState *p){
drhe6229612014-08-18 15:08:26 +00002394 int i;
2395 for(i=0; i<p->nSession; i++){
2396 session_close(&p->aSession[i]);
2397 }
2398 p->nSession = 0;
drhe6229612014-08-18 15:08:26 +00002399}
drh51b55a32016-04-04 12:38:05 +00002400#else
2401# define session_close_all(X)
2402#endif
drhe6229612014-08-18 15:08:26 +00002403
drh75897232000-05-29 14:26:00 +00002404/*
drh03168ca2014-08-18 20:01:31 +00002405** Implementation of the xFilter function for an open session. Omit
2406** any tables named by ".session filter" but let all other table through.
2407*/
2408#if defined(SQLITE_ENABLE_SESSION)
2409static int session_filter(void *pCtx, const char *zTab){
2410 OpenSession *pSession = (OpenSession*)pCtx;
2411 int i;
2412 for(i=0; i<pSession->nFilter; i++){
2413 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
2414 }
2415 return 1;
2416}
2417#endif
2418
2419/*
drh44c2eb12003-04-30 11:38:26 +00002420** Make sure the database is open. If it is not, then open it. If
2421** the database fails to open, print an error message and exit.
2422*/
drhdcd87a92014-08-18 13:45:42 +00002423static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002424 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002425 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002426 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002427 globalDb = p->db;
2428 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2429 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002430 shellstaticFunc, 0, 0);
2431 }
mistachkin8e189222015-04-19 21:43:16 +00002432 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00002433 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002434 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002435 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002436 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002437 }
drhc2e87a32006-06-27 15:16:14 +00002438#ifndef SQLITE_OMIT_LOAD_EXTENSION
2439 sqlite3_enable_load_extension(p->db, 1);
2440#endif
mistachkin8e189222015-04-19 21:43:16 +00002441 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002442 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002443 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002444 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002445 }
2446}
2447
2448/*
drhfeac5f82004-08-01 00:10:45 +00002449** Do C-language style dequoting.
2450**
mistachkinf21979d2015-01-18 05:35:01 +00002451** \a -> alarm
2452** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002453** \t -> tab
2454** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002455** \v -> vertical tab
2456** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002457** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002458** \s -> space
drh4c56b992013-06-27 13:26:55 +00002459** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002460** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002461** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002462** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002463*/
2464static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002465 int i, j;
2466 char c;
drhc2ce0be2014-05-29 12:36:14 +00002467 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002468 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002469 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002470 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002471 if( c=='a' ){
2472 c = '\a';
2473 }else if( c=='b' ){
2474 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002475 }else if( c=='t' ){
2476 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002477 }else if( c=='n' ){
2478 c = '\n';
2479 }else if( c=='v' ){
2480 c = '\v';
2481 }else if( c=='f' ){
2482 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002483 }else if( c=='r' ){
2484 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002485 }else if( c=='"' ){
2486 c = '"';
2487 }else if( c=='\'' ){
2488 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002489 }else if( c=='\\' ){
2490 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002491 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002492 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002493 if( z[i+1]>='0' && z[i+1]<='7' ){
2494 i++;
2495 c = (c<<3) + z[i] - '0';
2496 if( z[i+1]>='0' && z[i+1]<='7' ){
2497 i++;
2498 c = (c<<3) + z[i] - '0';
2499 }
2500 }
2501 }
2502 }
2503 z[j] = c;
2504 }
drhc2ce0be2014-05-29 12:36:14 +00002505 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002506}
2507
2508/*
drh348d19c2013-06-03 12:47:43 +00002509** Return the value of a hexadecimal digit. Return -1 if the input
2510** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002511*/
drh348d19c2013-06-03 12:47:43 +00002512static int hexDigitValue(char c){
2513 if( c>='0' && c<='9' ) return c - '0';
2514 if( c>='a' && c<='f' ) return c - 'a' + 10;
2515 if( c>='A' && c<='F' ) return c - 'A' + 10;
2516 return -1;
drhc28490c2006-10-26 14:25:58 +00002517}
2518
2519/*
drh7d9f3942013-04-03 01:26:54 +00002520** Interpret zArg as an integer value, possibly with suffixes.
2521*/
2522static sqlite3_int64 integerValue(const char *zArg){
2523 sqlite3_int64 v = 0;
2524 static const struct { char *zSuffix; int iMult; } aMult[] = {
2525 { "KiB", 1024 },
2526 { "MiB", 1024*1024 },
2527 { "GiB", 1024*1024*1024 },
2528 { "KB", 1000 },
2529 { "MB", 1000000 },
2530 { "GB", 1000000000 },
2531 { "K", 1000 },
2532 { "M", 1000000 },
2533 { "G", 1000000000 },
2534 };
2535 int i;
2536 int isNeg = 0;
2537 if( zArg[0]=='-' ){
2538 isNeg = 1;
2539 zArg++;
2540 }else if( zArg[0]=='+' ){
2541 zArg++;
2542 }
drh348d19c2013-06-03 12:47:43 +00002543 if( zArg[0]=='0' && zArg[1]=='x' ){
2544 int x;
2545 zArg += 2;
2546 while( (x = hexDigitValue(zArg[0]))>=0 ){
2547 v = (v<<4) + x;
2548 zArg++;
2549 }
2550 }else{
2551 while( IsDigit(zArg[0]) ){
2552 v = v*10 + zArg[0] - '0';
2553 zArg++;
2554 }
drh7d9f3942013-04-03 01:26:54 +00002555 }
drhc2bed0a2013-05-24 11:57:50 +00002556 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002557 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2558 v *= aMult[i].iMult;
2559 break;
2560 }
2561 }
2562 return isNeg? -v : v;
2563}
2564
2565/*
drh348d19c2013-06-03 12:47:43 +00002566** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2567** for TRUE and FALSE. Return the integer value if appropriate.
2568*/
2569static int booleanValue(char *zArg){
2570 int i;
2571 if( zArg[0]=='0' && zArg[1]=='x' ){
2572 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2573 }else{
2574 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2575 }
2576 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2577 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2578 return 1;
2579 }
2580 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2581 return 0;
2582 }
mistachkinaae280e2015-12-31 19:06:24 +00002583 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002584 zArg);
2585 return 0;
2586}
2587
2588/*
drh42f64e52012-04-04 16:56:23 +00002589** Close an output file, assuming it is not stderr or stdout
2590*/
2591static void output_file_close(FILE *f){
2592 if( f && f!=stdout && f!=stderr ) fclose(f);
2593}
2594
2595/*
2596** Try to open an output file. The names "stdout" and "stderr" are
mistachkin1fe36bb2016-04-04 02:16:44 +00002597** recognized and do the right thing. NULL is returned if the output
drh42f64e52012-04-04 16:56:23 +00002598** filename is "off".
2599*/
2600static FILE *output_file_open(const char *zFile){
2601 FILE *f;
2602 if( strcmp(zFile,"stdout")==0 ){
2603 f = stdout;
2604 }else if( strcmp(zFile, "stderr")==0 ){
2605 f = stderr;
2606 }else if( strcmp(zFile, "off")==0 ){
2607 f = 0;
2608 }else{
2609 f = fopen(zFile, "wb");
2610 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002611 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002612 }
2613 }
2614 return f;
2615}
2616
drhd12602a2016-12-07 15:49:02 +00002617#if !defined(SQLITE_UNTESTABLE)
drhc10b9da2016-11-20 17:59:59 +00002618#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00002619/*
2620** A routine for handling output from sqlite3_trace().
2621*/
drh4b363a52016-07-23 20:27:41 +00002622static int sql_trace_callback(
2623 unsigned mType,
2624 void *pArg,
2625 void *pP,
2626 void *pX
2627){
drh42f64e52012-04-04 16:56:23 +00002628 FILE *f = (FILE*)pArg;
drhb0df5402016-08-01 17:06:44 +00002629 UNUSED_PARAMETER(mType);
2630 UNUSED_PARAMETER(pP);
drh4b2590e2014-08-19 19:28:00 +00002631 if( f ){
drh4b363a52016-07-23 20:27:41 +00002632 const char *z = (const char*)pX;
drh4b2590e2014-08-19 19:28:00 +00002633 int i = (int)strlen(z);
2634 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002635 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002636 }
drh4b363a52016-07-23 20:27:41 +00002637 return 0;
drh42f64e52012-04-04 16:56:23 +00002638}
drhc10b9da2016-11-20 17:59:59 +00002639#endif
2640#endif
drh42f64e52012-04-04 16:56:23 +00002641
2642/*
drhd8621b92012-04-17 09:09:33 +00002643** A no-op routine that runs with the ".breakpoint" doc-command. This is
2644** a useful spot to set a debugger breakpoint.
2645*/
2646static void test_breakpoint(void){
2647 static int nCall = 0;
2648 nCall++;
2649}
2650
2651/*
mistachkin636bf9f2014-07-19 20:15:16 +00002652** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002653*/
mistachkin636bf9f2014-07-19 20:15:16 +00002654typedef struct ImportCtx ImportCtx;
2655struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002656 const char *zFile; /* Name of the input file */
2657 FILE *in; /* Read the CSV text from this input stream */
2658 char *z; /* Accumulated text for a field */
2659 int n; /* Number of bytes in z */
2660 int nAlloc; /* Space allocated for z[] */
2661 int nLine; /* Current line number */
2662 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002663 int cColSep; /* The column separator character. (Usually ",") */
2664 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002665};
2666
2667/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002668static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002669 if( p->n+1>=p->nAlloc ){
2670 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002671 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002672 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002673 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002674 exit(1);
2675 }
2676 }
2677 p->z[p->n++] = (char)c;
2678}
2679
2680/* Read a single field of CSV text. Compatible with rfc4180 and extended
2681** with the option of having a separator other than ",".
2682**
2683** + Input comes from p->in.
2684** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002685** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002686** + Use p->cSep as the column separator. The default is ",".
2687** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002688** + Keep track of the line number in p->nLine.
2689** + Store the character that terminates the field in p->cTerm. Store
2690** EOF on end-of-file.
2691** + Report syntax errors on stderr
2692*/
mistachkin44723ce2015-03-21 02:22:37 +00002693static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002694 int c;
2695 int cSep = p->cColSep;
2696 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002697 p->n = 0;
2698 c = fgetc(p->in);
2699 if( c==EOF || seenInterrupt ){
2700 p->cTerm = EOF;
2701 return 0;
2702 }
2703 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002704 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002705 int startLine = p->nLine;
2706 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002707 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002708 while( 1 ){
2709 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002710 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002711 if( c==cQuote ){
2712 if( pc==cQuote ){
2713 pc = 0;
2714 continue;
2715 }
2716 }
2717 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002718 || (c==rSep && pc==cQuote)
2719 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002720 || (c==EOF && pc==cQuote)
2721 ){
2722 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002723 p->cTerm = c;
2724 break;
2725 }
2726 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002727 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002728 p->zFile, p->nLine, cQuote);
2729 }
2730 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002731 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002732 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002733 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002734 break;
2735 }
mistachkin636bf9f2014-07-19 20:15:16 +00002736 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002737 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002738 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002739 }
drhdb95f682013-06-26 22:46:00 +00002740 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002741 while( c!=EOF && c!=cSep && c!=rSep ){
2742 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002743 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002744 }
mistachkin636bf9f2014-07-19 20:15:16 +00002745 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002746 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002747 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002748 }
drhdb95f682013-06-26 22:46:00 +00002749 p->cTerm = c;
2750 }
drh8dd675e2013-07-12 21:09:24 +00002751 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002752 return p->z;
2753}
2754
mistachkin636bf9f2014-07-19 20:15:16 +00002755/* Read a single field of ASCII delimited text.
2756**
2757** + Input comes from p->in.
2758** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002759** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002760** + Use p->cSep as the column separator. The default is "\x1F".
2761** + Use p->rSep as the row separator. The default is "\x1E".
2762** + Keep track of the row number in p->nLine.
2763** + Store the character that terminates the field in p->cTerm. Store
2764** EOF on end-of-file.
2765** + Report syntax errors on stderr
2766*/
mistachkin44723ce2015-03-21 02:22:37 +00002767static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002768 int c;
2769 int cSep = p->cColSep;
2770 int rSep = p->cRowSep;
2771 p->n = 0;
2772 c = fgetc(p->in);
2773 if( c==EOF || seenInterrupt ){
2774 p->cTerm = EOF;
2775 return 0;
2776 }
2777 while( c!=EOF && c!=cSep && c!=rSep ){
2778 import_append_char(p, c);
2779 c = fgetc(p->in);
2780 }
2781 if( c==rSep ){
2782 p->nLine++;
2783 }
2784 p->cTerm = c;
2785 if( p->z ) p->z[p->n] = 0;
2786 return p->z;
2787}
2788
drhdb95f682013-06-26 22:46:00 +00002789/*
drh4bbcf102014-02-06 02:46:08 +00002790** Try to transfer data for table zTable. If an error is seen while
2791** moving forward, try to go backwards. The backwards movement won't
2792** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002793*/
mistachkine31ae902014-02-06 01:15:29 +00002794static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002795 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002796 sqlite3 *newDb,
2797 const char *zTable
2798){
mistachkin1fe36bb2016-04-04 02:16:44 +00002799 sqlite3_stmt *pQuery = 0;
drh3350ce92014-02-06 00:49:12 +00002800 sqlite3_stmt *pInsert = 0;
2801 char *zQuery = 0;
2802 char *zInsert = 0;
2803 int rc;
2804 int i, j, n;
2805 int nTable = (int)strlen(zTable);
2806 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002807 int cnt = 0;
2808 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002809
2810 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2811 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2812 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002813 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002814 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2815 zQuery);
2816 goto end_data_xfer;
2817 }
2818 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002819 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002820 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002821 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002822 goto end_data_xfer;
2823 }
2824 sqlite3_snprintf(200+nTable,zInsert,
2825 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2826 i = (int)strlen(zInsert);
2827 for(j=1; j<n; j++){
2828 memcpy(zInsert+i, ",?", 2);
2829 i += 2;
2830 }
2831 memcpy(zInsert+i, ");", 3);
2832 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2833 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002834 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002835 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2836 zQuery);
2837 goto end_data_xfer;
2838 }
2839 for(k=0; k<2; k++){
2840 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2841 for(i=0; i<n; i++){
2842 switch( sqlite3_column_type(pQuery, i) ){
2843 case SQLITE_NULL: {
2844 sqlite3_bind_null(pInsert, i+1);
2845 break;
2846 }
2847 case SQLITE_INTEGER: {
2848 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2849 break;
2850 }
2851 case SQLITE_FLOAT: {
2852 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2853 break;
2854 }
2855 case SQLITE_TEXT: {
2856 sqlite3_bind_text(pInsert, i+1,
2857 (const char*)sqlite3_column_text(pQuery,i),
2858 -1, SQLITE_STATIC);
2859 break;
2860 }
2861 case SQLITE_BLOB: {
2862 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2863 sqlite3_column_bytes(pQuery,i),
2864 SQLITE_STATIC);
2865 break;
2866 }
2867 }
2868 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002869 rc = sqlite3_step(pInsert);
2870 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002871 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002872 sqlite3_errmsg(newDb));
2873 }
drh3350ce92014-02-06 00:49:12 +00002874 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002875 cnt++;
2876 if( (cnt%spinRate)==0 ){
2877 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2878 fflush(stdout);
2879 }
drh3350ce92014-02-06 00:49:12 +00002880 } /* End while */
2881 if( rc==SQLITE_DONE ) break;
2882 sqlite3_finalize(pQuery);
2883 sqlite3_free(zQuery);
2884 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2885 zTable);
2886 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2887 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002888 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002889 break;
drh3350ce92014-02-06 00:49:12 +00002890 }
2891 } /* End for(k=0...) */
2892
2893end_data_xfer:
2894 sqlite3_finalize(pQuery);
2895 sqlite3_finalize(pInsert);
2896 sqlite3_free(zQuery);
2897 sqlite3_free(zInsert);
2898}
2899
2900
2901/*
2902** Try to transfer all rows of the schema that match zWhere. For
2903** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002904** If an error is encountered while moving forward through the
2905** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002906*/
mistachkine31ae902014-02-06 01:15:29 +00002907static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002908 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002909 sqlite3 *newDb,
2910 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002911 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002912){
2913 sqlite3_stmt *pQuery = 0;
2914 char *zQuery = 0;
2915 int rc;
2916 const unsigned char *zName;
2917 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002918 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002919
2920 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2921 " WHERE %s", zWhere);
2922 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2923 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002924 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002925 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2926 zQuery);
2927 goto end_schema_xfer;
2928 }
2929 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2930 zName = sqlite3_column_text(pQuery, 0);
2931 zSql = sqlite3_column_text(pQuery, 1);
2932 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002933 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2934 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002935 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002936 sqlite3_free(zErrMsg);
2937 zErrMsg = 0;
2938 }
drh3350ce92014-02-06 00:49:12 +00002939 if( xForEach ){
2940 xForEach(p, newDb, (const char*)zName);
2941 }
2942 printf("done\n");
2943 }
2944 if( rc!=SQLITE_DONE ){
2945 sqlite3_finalize(pQuery);
2946 sqlite3_free(zQuery);
2947 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2948 " WHERE %s ORDER BY rowid DESC", zWhere);
2949 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2950 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002951 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002952 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2953 zQuery);
2954 goto end_schema_xfer;
2955 }
2956 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2957 zName = sqlite3_column_text(pQuery, 0);
2958 zSql = sqlite3_column_text(pQuery, 1);
2959 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002960 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2961 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002962 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002963 sqlite3_free(zErrMsg);
2964 zErrMsg = 0;
2965 }
drh3350ce92014-02-06 00:49:12 +00002966 if( xForEach ){
2967 xForEach(p, newDb, (const char*)zName);
2968 }
2969 printf("done\n");
2970 }
2971 }
2972end_schema_xfer:
2973 sqlite3_finalize(pQuery);
2974 sqlite3_free(zQuery);
2975}
2976
2977/*
2978** Open a new database file named "zNewDb". Try to recover as much information
2979** as possible out of the main database (which might be corrupt) and write it
2980** into zNewDb.
2981*/
drhdcd87a92014-08-18 13:45:42 +00002982static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002983 int rc;
2984 sqlite3 *newDb = 0;
2985 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002986 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002987 return;
2988 }
2989 rc = sqlite3_open(zNewDb, &newDb);
2990 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002991 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002992 sqlite3_errmsg(newDb));
2993 }else{
drh54d0d2d2014-04-03 00:32:13 +00002994 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002995 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002996 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2997 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002998 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002999 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00003000 }
3001 sqlite3_close(newDb);
3002}
3003
3004/*
drhc2ce0be2014-05-29 12:36:14 +00003005** Change the output file back to stdout
3006*/
drhdcd87a92014-08-18 13:45:42 +00003007static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00003008 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003009#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00003010 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00003011#endif
drhc2ce0be2014-05-29 12:36:14 +00003012 }else{
3013 output_file_close(p->out);
3014 }
3015 p->outfile[0] = 0;
3016 p->out = stdout;
3017}
3018
3019/*
drhf7502f02015-02-06 14:19:44 +00003020** Run an SQL command and return the single integer result.
3021*/
3022static int db_int(ShellState *p, const char *zSql){
3023 sqlite3_stmt *pStmt;
3024 int res = 0;
3025 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3026 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
3027 res = sqlite3_column_int(pStmt,0);
3028 }
3029 sqlite3_finalize(pStmt);
3030 return res;
3031}
3032
3033/*
3034** Convert a 2-byte or 4-byte big-endian integer into a native integer
3035*/
drha0620ac2016-07-13 13:05:13 +00003036static unsigned int get2byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00003037 return (a[0]<<8) + a[1];
3038}
drha0620ac2016-07-13 13:05:13 +00003039static unsigned int get4byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00003040 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
3041}
3042
3043/*
3044** Implementation of the ".info" command.
3045**
3046** Return 1 on error, 2 to exit, and 0 otherwise.
3047*/
drh0e55db12015-02-06 14:51:13 +00003048static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00003049 static const struct { const char *zName; int ofst; } aField[] = {
3050 { "file change counter:", 24 },
3051 { "database page count:", 28 },
3052 { "freelist page count:", 36 },
3053 { "schema cookie:", 40 },
3054 { "schema format:", 44 },
3055 { "default cache size:", 48 },
3056 { "autovacuum top root:", 52 },
3057 { "incremental vacuum:", 64 },
3058 { "text encoding:", 56 },
3059 { "user version:", 60 },
3060 { "application id:", 68 },
3061 { "software version:", 96 },
3062 };
drh0e55db12015-02-06 14:51:13 +00003063 static const struct { const char *zName; const char *zSql; } aQuery[] = {
3064 { "number of tables:",
3065 "SELECT count(*) FROM %s WHERE type='table'" },
3066 { "number of indexes:",
3067 "SELECT count(*) FROM %s WHERE type='index'" },
3068 { "number of triggers:",
3069 "SELECT count(*) FROM %s WHERE type='trigger'" },
3070 { "number of views:",
3071 "SELECT count(*) FROM %s WHERE type='view'" },
3072 { "schema size:",
3073 "SELECT total(length(sql)) FROM %s" },
3074 };
mistachkinbfe8bd52015-11-17 19:17:14 +00003075 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00003076 int i;
3077 char *zSchemaTab;
3078 char *zDb = nArg>=2 ? azArg[1] : "main";
3079 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00003080 open_db(p, 0);
3081 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00003082 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00003083 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
3084 return 1;
3085 }
3086 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
3087 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003088 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00003089 return 1;
3090 }
3091 i = get2byteInt(aHdr+16);
3092 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00003093 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
3094 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
3095 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
3096 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00003097 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00003098 int ofst = aField[i].ofst;
3099 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00003100 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00003101 switch( ofst ){
3102 case 56: {
mistachkin1fe36bb2016-04-04 02:16:44 +00003103 if( val==1 ) raw_printf(p->out, " (utf8)");
3104 if( val==2 ) raw_printf(p->out, " (utf16le)");
3105 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00003106 }
3107 }
mistachkinaae280e2015-12-31 19:06:24 +00003108 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00003109 }
drh0e55db12015-02-06 14:51:13 +00003110 if( zDb==0 ){
3111 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
3112 }else if( strcmp(zDb,"temp")==0 ){
3113 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
3114 }else{
3115 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
3116 }
drhf5ed7ad2015-06-15 14:43:25 +00003117 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00003118 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
3119 int val = db_int(p, zSql);
3120 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00003121 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00003122 }
3123 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00003124 return 0;
3125}
3126
dand95bb392015-09-30 11:19:05 +00003127/*
3128** Print the current sqlite3_errmsg() value to stderr and return 1.
3129*/
3130static int shellDatabaseError(sqlite3 *db){
3131 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00003132 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00003133 return 1;
3134}
3135
3136/*
3137** Print an out-of-memory message to stderr and return 1.
3138*/
3139static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00003140 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00003141 return 1;
3142}
drhf7502f02015-02-06 14:19:44 +00003143
drh2db82112016-09-15 21:35:24 +00003144/*
3145** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
3146** if they match and FALSE (0) if they do not match.
3147**
3148** Globbing rules:
3149**
3150** '*' Matches any sequence of zero or more characters.
3151**
3152** '?' Matches exactly one character.
3153**
3154** [...] Matches one character from the enclosed list of
3155** characters.
3156**
3157** [^...] Matches one character not in the enclosed list.
3158**
3159** '#' Matches any sequence of one or more digits with an
3160** optional + or - sign in front
3161**
3162** ' ' Any span of whitespace matches any other span of
3163** whitespace.
3164**
3165** Extra whitespace at the end of z[] is ignored.
3166*/
3167static int testcase_glob(const char *zGlob, const char *z){
3168 int c, c2;
3169 int invert;
3170 int seen;
3171
3172 while( (c = (*(zGlob++)))!=0 ){
3173 if( IsSpace(c) ){
3174 if( !IsSpace(*z) ) return 0;
3175 while( IsSpace(*zGlob) ) zGlob++;
3176 while( IsSpace(*z) ) z++;
3177 }else if( c=='*' ){
3178 while( (c=(*(zGlob++))) == '*' || c=='?' ){
3179 if( c=='?' && (*(z++))==0 ) return 0;
3180 }
3181 if( c==0 ){
3182 return 1;
3183 }else if( c=='[' ){
3184 while( *z && testcase_glob(zGlob-1,z)==0 ){
3185 z++;
3186 }
3187 return (*z)!=0;
3188 }
3189 while( (c2 = (*(z++)))!=0 ){
3190 while( c2!=c ){
3191 c2 = *(z++);
3192 if( c2==0 ) return 0;
3193 }
3194 if( testcase_glob(zGlob,z) ) return 1;
3195 }
3196 return 0;
3197 }else if( c=='?' ){
3198 if( (*(z++))==0 ) return 0;
3199 }else if( c=='[' ){
3200 int prior_c = 0;
3201 seen = 0;
3202 invert = 0;
3203 c = *(z++);
3204 if( c==0 ) return 0;
3205 c2 = *(zGlob++);
3206 if( c2=='^' ){
3207 invert = 1;
3208 c2 = *(zGlob++);
3209 }
3210 if( c2==']' ){
3211 if( c==']' ) seen = 1;
3212 c2 = *(zGlob++);
3213 }
3214 while( c2 && c2!=']' ){
3215 if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
3216 c2 = *(zGlob++);
3217 if( c>=prior_c && c<=c2 ) seen = 1;
3218 prior_c = 0;
3219 }else{
3220 if( c==c2 ){
3221 seen = 1;
3222 }
3223 prior_c = c2;
3224 }
3225 c2 = *(zGlob++);
3226 }
3227 if( c2==0 || (seen ^ invert)==0 ) return 0;
3228 }else if( c=='#' ){
3229 if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
3230 if( !IsDigit(z[0]) ) return 0;
3231 z++;
3232 while( IsDigit(z[0]) ){ z++; }
3233 }else{
3234 if( c!=(*(z++)) ) return 0;
3235 }
3236 }
3237 while( IsSpace(*z) ){ z++; }
3238 return *z==0;
3239}
drh2db82112016-09-15 21:35:24 +00003240
3241
drhf7502f02015-02-06 14:19:44 +00003242/*
drh4926fec2016-04-13 15:33:42 +00003243** Compare the string as a command-line option with either one or two
3244** initial "-" characters.
3245*/
3246static int optionMatch(const char *zStr, const char *zOpt){
3247 if( zStr[0]!='-' ) return 0;
3248 zStr++;
3249 if( zStr[0]=='-' ) zStr++;
3250 return strcmp(zStr, zOpt)==0;
3251}
3252
3253/*
drhcd0509e2016-09-16 00:26:08 +00003254** Delete a file.
3255*/
3256int shellDeleteFile(const char *zFilename){
3257 int rc;
3258#ifdef _WIN32
mistachkin8145fc62016-09-16 20:39:21 +00003259 wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
drhcd0509e2016-09-16 00:26:08 +00003260 rc = _wunlink(z);
3261 sqlite3_free(z);
3262#else
3263 rc = unlink(zFilename);
3264#endif
3265 return rc;
3266}
3267
dan35ac58e2016-12-14 19:28:27 +00003268
dan35ac58e2016-12-14 19:28:27 +00003269/*
dandd9e0be2016-12-16 16:44:27 +00003270** The implementation of SQL scalar function fkey_collate_clause(), used
dan3c7ebeb2016-12-16 17:28:56 +00003271** by the ".lint fkey-indexes" command. This scalar function is always
dandd9e0be2016-12-16 16:44:27 +00003272** called with four arguments - the parent table name, the parent column name,
3273** the child table name and the child column name.
dan35ac58e2016-12-14 19:28:27 +00003274**
3275** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col')
3276**
3277** If either of the named tables or columns do not exist, this function
3278** returns an empty string. An empty string is also returned if both tables
3279** and columns exist but have the same default collation sequence. Or,
3280** if both exist but the default collation sequences are different, this
3281** function returns the string " COLLATE <parent-collation>", where
3282** <parent-collation> is the default collation sequence of the parent column.
3283*/
3284static void shellFkeyCollateClause(
3285 sqlite3_context *pCtx,
3286 int nVal,
3287 sqlite3_value **apVal
3288){
3289 sqlite3 *db = sqlite3_context_db_handle(pCtx);
3290 const char *zParent;
3291 const char *zParentCol;
3292 const char *zParentSeq;
3293 const char *zChild;
3294 const char *zChildCol;
drh96ada592016-12-29 19:48:46 +00003295 const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */
dan35ac58e2016-12-14 19:28:27 +00003296 int rc;
3297
3298 assert( nVal==4 );
3299 zParent = (const char*)sqlite3_value_text(apVal[0]);
3300 zParentCol = (const char*)sqlite3_value_text(apVal[1]);
3301 zChild = (const char*)sqlite3_value_text(apVal[2]);
3302 zChildCol = (const char*)sqlite3_value_text(apVal[3]);
3303
3304 sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
3305 rc = sqlite3_table_column_metadata(
3306 db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0
3307 );
3308 if( rc==SQLITE_OK ){
3309 rc = sqlite3_table_column_metadata(
3310 db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0
3311 );
3312 }
3313
3314 if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){
3315 char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq);
3316 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
3317 sqlite3_free(z);
3318 }
3319}
3320
3321
3322/*
dan3c7ebeb2016-12-16 17:28:56 +00003323** The implementation of dot-command ".lint fkey-indexes".
dan35ac58e2016-12-14 19:28:27 +00003324*/
dan3c7ebeb2016-12-16 17:28:56 +00003325static int lintFkeyIndexes(
dan35ac58e2016-12-14 19:28:27 +00003326 ShellState *pState, /* Current shell tool state */
3327 char **azArg, /* Array of arguments passed to dot command */
3328 int nArg /* Number of entries in azArg[] */
3329){
dandd9e0be2016-12-16 16:44:27 +00003330 sqlite3 *db = pState->db; /* Database handle to query "main" db of */
3331 FILE *out = pState->out; /* Stream to write non-error output to */
danf9647b62016-12-15 06:01:40 +00003332 int bVerbose = 0; /* If -verbose is present */
3333 int bGroupByParent = 0; /* If -groupbyparent is present */
dandd9e0be2016-12-16 16:44:27 +00003334 int i; /* To iterate through azArg[] */
3335 const char *zIndent = ""; /* How much to indent CREATE INDEX by */
3336 int rc; /* Return code */
3337 sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */
dan35ac58e2016-12-14 19:28:27 +00003338
dandd9e0be2016-12-16 16:44:27 +00003339 /*
3340 ** This SELECT statement returns one row for each foreign key constraint
3341 ** in the schema of the main database. The column values are:
3342 **
3343 ** 0. The text of an SQL statement similar to:
3344 **
3345 ** "EXPLAIN QUERY PLAN SELECT rowid FROM child_table WHERE child_key=?"
3346 **
3347 ** This is the same SELECT that the foreign keys implementation needs
3348 ** to run internally on child tables. If there is an index that can
3349 ** be used to optimize this query, then it can also be used by the FK
3350 ** implementation to optimize DELETE or UPDATE statements on the parent
3351 ** table.
3352 **
3353 ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by
3354 ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema
3355 ** contains an index that can be used to optimize the query.
3356 **
3357 ** 2. Human readable text that describes the child table and columns. e.g.
3358 **
3359 ** "child_table(child_key1, child_key2)"
3360 **
3361 ** 3. Human readable text that describes the parent table and columns. e.g.
3362 **
3363 ** "parent_table(parent_key1, parent_key2)"
3364 **
3365 ** 4. A full CREATE INDEX statement for an index that could be used to
3366 ** optimize DELETE or UPDATE statements on the parent table. e.g.
3367 **
3368 ** "CREATE INDEX child_table_child_key ON child_table(child_key)"
3369 **
3370 ** 5. The name of the parent table.
3371 **
3372 ** These six values are used by the C logic below to generate the report.
3373 */
dan35ac58e2016-12-14 19:28:27 +00003374 const char *zSql =
dandd9e0be2016-12-16 16:44:27 +00003375 "SELECT "
3376 " 'EXPLAIN QUERY PLAN SELECT rowid FROM ' || quote(s.name) || ' WHERE '"
3377 " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' "
3378 " || fkey_collate_clause(f.[table], f.[to], s.name, f.[from]),' AND ')"
dan35ac58e2016-12-14 19:28:27 +00003379 ", "
dandd9e0be2016-12-16 16:44:27 +00003380 " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('"
dan35ac58e2016-12-14 19:28:27 +00003381 " || group_concat('*=?', ' AND ') || ')'"
3382 ", "
dandd9e0be2016-12-16 16:44:27 +00003383 " s.name || '(' || group_concat(f.[from], ', ') || ')'"
dan35ac58e2016-12-14 19:28:27 +00003384 ", "
dandd9e0be2016-12-16 16:44:27 +00003385 " f.[table] || '(' || group_concat(COALESCE(f.[to], "
3386 " (SELECT name FROM pragma_table_info(f.[table]) WHERE pk=seq+1)"
dan35ac58e2016-12-14 19:28:27 +00003387 " )) || ')'"
3388 ", "
dandd9e0be2016-12-16 16:44:27 +00003389 " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))"
3390 " || ' ON ' || quote(s.name) || '('"
3391 " || group_concat(quote(f.[from]) ||"
3392 " fkey_collate_clause(f.[table], f.[to], s.name, f.[from]), ', ')"
dan35ac58e2016-12-14 19:28:27 +00003393 " || ');'"
danf9647b62016-12-15 06:01:40 +00003394 ", "
dandd9e0be2016-12-16 16:44:27 +00003395 " f.[table] "
dan35ac58e2016-12-14 19:28:27 +00003396
dandd9e0be2016-12-16 16:44:27 +00003397 "FROM sqlite_master AS s, pragma_foreign_key_list(s.name) AS f "
3398 "GROUP BY s.name, f.id "
3399 "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
dan35ac58e2016-12-14 19:28:27 +00003400 ;
3401
dan3c7ebeb2016-12-16 17:28:56 +00003402 for(i=2; i<nArg; i++){
drh344a1bf2016-12-22 14:53:25 +00003403 int n = (int)strlen(azArg[i]);
danf9647b62016-12-15 06:01:40 +00003404 if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
3405 bVerbose = 1;
3406 }
3407 else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
3408 bGroupByParent = 1;
3409 zIndent = " ";
3410 }
3411 else{
dan3c7ebeb2016-12-16 17:28:56 +00003412 raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
3413 azArg[0], azArg[1]
3414 );
danf9647b62016-12-15 06:01:40 +00003415 return SQLITE_ERROR;
3416 }
dan35ac58e2016-12-14 19:28:27 +00003417 }
dan35ac58e2016-12-14 19:28:27 +00003418
3419 /* Register the fkey_collate_clause() SQL function */
dandd9e0be2016-12-16 16:44:27 +00003420 rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8,
3421 0, shellFkeyCollateClause, 0, 0
3422 );
dan35ac58e2016-12-14 19:28:27 +00003423
3424
3425 if( rc==SQLITE_OK ){
3426 rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0);
3427 }
danf9647b62016-12-15 06:01:40 +00003428 if( rc==SQLITE_OK ){
3429 sqlite3_bind_int(pSql, 1, bGroupByParent);
3430 }
dan35ac58e2016-12-14 19:28:27 +00003431
3432 if( rc==SQLITE_OK ){
3433 int rc2;
danf9647b62016-12-15 06:01:40 +00003434 char *zPrev = 0;
dan35ac58e2016-12-14 19:28:27 +00003435 while( SQLITE_ROW==sqlite3_step(pSql) ){
3436 int res = -1;
3437 sqlite3_stmt *pExplain = 0;
3438 const char *zEQP = (const char*)sqlite3_column_text(pSql, 0);
3439 const char *zGlob = (const char*)sqlite3_column_text(pSql, 1);
3440 const char *zFrom = (const char*)sqlite3_column_text(pSql, 2);
3441 const char *zTarget = (const char*)sqlite3_column_text(pSql, 3);
3442 const char *zCI = (const char*)sqlite3_column_text(pSql, 4);
danf9647b62016-12-15 06:01:40 +00003443 const char *zParent = (const char*)sqlite3_column_text(pSql, 5);
dan35ac58e2016-12-14 19:28:27 +00003444
3445 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
3446 if( rc!=SQLITE_OK ) break;
3447 if( SQLITE_ROW==sqlite3_step(pExplain) ){
3448 const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3);
3449 res = (0==sqlite3_strglob(zGlob, zPlan));
3450 }
3451 rc = sqlite3_finalize(pExplain);
3452 if( rc!=SQLITE_OK ) break;
3453
3454 if( res<0 ){
3455 raw_printf(stderr, "Error: internal error");
3456 break;
danf9647b62016-12-15 06:01:40 +00003457 }else{
3458 if( bGroupByParent
3459 && (bVerbose || res==0)
3460 && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
3461 ){
3462 raw_printf(out, "-- Parent table %s\n", zParent);
3463 sqlite3_free(zPrev);
3464 zPrev = sqlite3_mprintf("%s", zParent);
3465 }
3466
3467 if( res==0 ){
3468 raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
3469 }else if( bVerbose ){
3470 raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
3471 zIndent, zFrom, zTarget
3472 );
3473 }
dan35ac58e2016-12-14 19:28:27 +00003474 }
3475 }
danf9647b62016-12-15 06:01:40 +00003476 sqlite3_free(zPrev);
dan35ac58e2016-12-14 19:28:27 +00003477
3478 if( rc!=SQLITE_OK ){
3479 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
3480 }
3481
3482 rc2 = sqlite3_finalize(pSql);
3483 if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
3484 rc = rc2;
3485 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
3486 }
3487 }else{
3488 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
3489 }
3490
3491 return rc;
3492}
dan3c7ebeb2016-12-16 17:28:56 +00003493
dan35ac58e2016-12-14 19:28:27 +00003494/*
dan3c7ebeb2016-12-16 17:28:56 +00003495** Implementation of ".lint" dot command.
3496*/
3497static int lintDotCommand(
3498 ShellState *pState, /* Current shell tool state */
3499 char **azArg, /* Array of arguments passed to dot command */
3500 int nArg /* Number of entries in azArg[] */
3501){
3502 int n;
drh96ada592016-12-29 19:48:46 +00003503 n = (nArg>=2 ? (int)strlen(azArg[1]) : 0);
dan3c7ebeb2016-12-16 17:28:56 +00003504 if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
3505 return lintFkeyIndexes(pState, azArg, nArg);
3506
3507 usage:
3508 raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
3509 raw_printf(stderr, "Where sub-commands are:\n");
3510 raw_printf(stderr, " fkey-indexes\n");
3511 return SQLITE_ERROR;
3512}
3513
dan35ac58e2016-12-14 19:28:27 +00003514
drhcd0509e2016-09-16 00:26:08 +00003515/*
drh75897232000-05-29 14:26:00 +00003516** If an input line begins with "." then invoke this routine to
3517** process that line.
drh67505e72002-04-19 12:34:06 +00003518**
drh47ad6842006-11-08 12:25:42 +00003519** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00003520*/
drhdcd87a92014-08-18 13:45:42 +00003521static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00003522 int h = 1;
drh75897232000-05-29 14:26:00 +00003523 int nArg = 0;
3524 int n, c;
drh67505e72002-04-19 12:34:06 +00003525 int rc = 0;
drh75897232000-05-29 14:26:00 +00003526 char *azArg[50];
3527
3528 /* Parse the input line into tokens.
3529 */
mistachkin8e189222015-04-19 21:43:16 +00003530 while( zLine[h] && nArg<ArraySize(azArg) ){
3531 while( IsSpace(zLine[h]) ){ h++; }
3532 if( zLine[h]==0 ) break;
3533 if( zLine[h]=='\'' || zLine[h]=='"' ){
3534 int delim = zLine[h++];
3535 azArg[nArg++] = &zLine[h];
mistachkin1fe36bb2016-04-04 02:16:44 +00003536 while( zLine[h] && zLine[h]!=delim ){
mistachkin8e189222015-04-19 21:43:16 +00003537 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
mistachkin1fe36bb2016-04-04 02:16:44 +00003538 h++;
drh4c56b992013-06-27 13:26:55 +00003539 }
mistachkin8e189222015-04-19 21:43:16 +00003540 if( zLine[h]==delim ){
3541 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00003542 }
drhfeac5f82004-08-01 00:10:45 +00003543 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003544 }else{
mistachkin8e189222015-04-19 21:43:16 +00003545 azArg[nArg++] = &zLine[h];
3546 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
3547 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00003548 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003549 }
3550 }
3551
3552 /* Process the input line.
3553 */
shane9bd1b442009-10-23 01:27:39 +00003554 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00003555 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00003556 c = azArg[0][0];
drhde613c62016-04-04 17:23:10 +00003557
drha0daa752016-09-16 11:53:10 +00003558#ifndef SQLITE_OMIT_AUTHORIZATION
drhde613c62016-04-04 17:23:10 +00003559 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
3560 if( nArg!=2 ){
3561 raw_printf(stderr, "Usage: .auth ON|OFF\n");
3562 rc = 1;
3563 goto meta_command_exit;
3564 }
3565 open_db(p, 0);
3566 if( booleanValue(azArg[1]) ){
3567 sqlite3_set_authorizer(p->db, shellAuth, p);
3568 }else{
3569 sqlite3_set_authorizer(p->db, 0, 0);
3570 }
3571 }else
drha0daa752016-09-16 11:53:10 +00003572#endif
drhde613c62016-04-04 17:23:10 +00003573
drh5c7976f2014-02-10 19:59:27 +00003574 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
3575 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
3576 ){
drhbc46f022013-01-23 18:53:23 +00003577 const char *zDestFile = 0;
3578 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00003579 sqlite3 *pDest;
3580 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00003581 int j;
3582 for(j=1; j<nArg; j++){
3583 const char *z = azArg[j];
3584 if( z[0]=='-' ){
3585 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00003586 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00003587 {
mistachkinaae280e2015-12-31 19:06:24 +00003588 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00003589 return 1;
3590 }
3591 }else if( zDestFile==0 ){
3592 zDestFile = azArg[j];
3593 }else if( zDb==0 ){
3594 zDb = zDestFile;
3595 zDestFile = azArg[j];
3596 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003597 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00003598 return 1;
3599 }
drh9ff849f2009-02-04 20:55:57 +00003600 }
drhbc46f022013-01-23 18:53:23 +00003601 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003602 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00003603 return 1;
3604 }
3605 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00003606 rc = sqlite3_open(zDestFile, &pDest);
3607 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003608 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00003609 sqlite3_close(pDest);
3610 return 1;
3611 }
drh05782482013-10-24 15:20:20 +00003612 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003613 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
3614 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003615 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00003616 sqlite3_close(pDest);
3617 return 1;
3618 }
3619 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
3620 sqlite3_backup_finish(pBackup);
3621 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003622 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00003623 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003624 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00003625 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003626 }
3627 sqlite3_close(pDest);
3628 }else
3629
drhc2ce0be2014-05-29 12:36:14 +00003630 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
3631 if( nArg==2 ){
3632 bail_on_error = booleanValue(azArg[1]);
3633 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003634 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003635 rc = 1;
3636 }
drhc49f44e2006-10-26 18:15:42 +00003637 }else
3638
mistachkinf21979d2015-01-18 05:35:01 +00003639 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
3640 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00003641 if( booleanValue(azArg[1]) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003642 setBinaryMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003643 }else{
mistachkin1fe36bb2016-04-04 02:16:44 +00003644 setTextMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003645 }
mistachkinf21979d2015-01-18 05:35:01 +00003646 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003647 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00003648 rc = 1;
3649 }
3650 }else
3651
drhd8621b92012-04-17 09:09:33 +00003652 /* The undocumented ".breakpoint" command causes a call to the no-op
3653 ** routine named test_breakpoint().
3654 */
3655 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
3656 test_breakpoint();
3657 }else
3658
drhdf12f1c2015-12-07 21:46:19 +00003659 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
3660 if( nArg==2 ){
3661 p->countChanges = booleanValue(azArg[1]);
3662 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003663 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00003664 rc = 1;
3665 }
3666 }else
3667
drh2db82112016-09-15 21:35:24 +00003668 /* Cancel output redirection, if it is currently set (by .testcase)
3669 ** Then read the content of the testcase-out.txt file and compare against
3670 ** azArg[1]. If there are differences, report an error and exit.
3671 */
3672 if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
3673 char *zRes = 0;
3674 output_reset(p);
3675 if( nArg!=2 ){
3676 raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
drh760c8162016-09-16 02:52:22 +00003677 rc = 2;
dan11da0022016-12-17 08:18:05 +00003678 }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
drh2db82112016-09-15 21:35:24 +00003679 raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
3680 rc = 2;
3681 }else if( testcase_glob(azArg[1],zRes)==0 ){
mistachkin8145fc62016-09-16 20:39:21 +00003682 utf8_printf(stderr,
drh760c8162016-09-16 02:52:22 +00003683 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
3684 p->zTestcase, azArg[1], zRes);
drh2db82112016-09-15 21:35:24 +00003685 rc = 2;
drh760c8162016-09-16 02:52:22 +00003686 }else{
mistachkin8145fc62016-09-16 20:39:21 +00003687 utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
drh760c8162016-09-16 02:52:22 +00003688 p->nCheck++;
drh2db82112016-09-15 21:35:24 +00003689 }
3690 sqlite3_free(zRes);
3691 }else
drh2db82112016-09-15 21:35:24 +00003692
drhc2ce0be2014-05-29 12:36:14 +00003693 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
3694 if( nArg==2 ){
3695 tryToClone(p, azArg[1]);
3696 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003697 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003698 rc = 1;
3699 }
mistachkine31ae902014-02-06 01:15:29 +00003700 }else
3701
drhc2ce0be2014-05-29 12:36:14 +00003702 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003703 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00003704 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003705 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00003706 memcpy(&data, p, sizeof(data));
drhb20a61b2016-12-24 18:18:58 +00003707 data.showHeader = 0;
3708 data.cMode = data.mode = MODE_List;
3709 sqlite3_snprintf(sizeof(data.colSeparator),data.colSeparator,": ");
drh0b2110c2004-10-26 00:08:10 +00003710 data.cnt = 0;
drhb20a61b2016-12-24 18:18:58 +00003711 sqlite3_exec(p->db, "SELECT name, file FROM pragma_database_list",
3712 callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00003713 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003714 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003715 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003716 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00003717 }
3718 }else
3719
drh0e55db12015-02-06 14:51:13 +00003720 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
3721 rc = shell_dbinfo_command(p, nArg, azArg);
3722 }else
3723
drhc2ce0be2014-05-29 12:36:14 +00003724 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00003725 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00003726 /* When playing back a "dump", the content might appear in an order
3727 ** which causes immediate foreign key constraints to be violated.
3728 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00003729 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003730 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003731 rc = 1;
3732 goto meta_command_exit;
3733 }
mistachkinaae280e2015-12-31 19:06:24 +00003734 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
3735 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00003736 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00003737 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00003738 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00003739 if( nArg==1 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003740 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003741 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003742 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00003743 );
mistachkin1fe36bb2016-04-04 02:16:44 +00003744 run_schema_dump_query(p,
drh4f324762009-05-21 14:51:03 +00003745 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003746 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00003747 );
drh2f464a02011-10-13 00:41:49 +00003748 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003749 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00003750 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00003751 );
drh4c653a02000-06-07 01:27:47 +00003752 }else{
3753 int i;
drhdd3d4592004-08-30 01:54:05 +00003754 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00003755 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00003756 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003757 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00003758 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00003759 " AND sql NOT NULL");
3760 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003761 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00003762 "WHERE sql NOT NULL"
3763 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00003764 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00003765 );
danielk1977bc6ada42004-06-30 08:20:16 +00003766 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00003767 }
3768 }
drh45e29d82006-11-20 16:21:10 +00003769 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00003770 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00003771 p->writableSchema = 0;
3772 }
drh56197952011-10-13 16:30:13 +00003773 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
3774 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00003775 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00003776 }else
drh75897232000-05-29 14:26:00 +00003777
drhc2ce0be2014-05-29 12:36:14 +00003778 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
3779 if( nArg==2 ){
3780 p->echoOn = booleanValue(azArg[1]);
3781 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003782 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003783 rc = 1;
3784 }
drhdaffd0e2001-04-11 14:28:42 +00003785 }else
3786
drhc2ce0be2014-05-29 12:36:14 +00003787 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
3788 if( nArg==2 ){
drheacd29d2016-04-15 15:03:27 +00003789 if( strcmp(azArg[1],"full")==0 ){
3790 p->autoEQP = 2;
3791 }else{
3792 p->autoEQP = booleanValue(azArg[1]);
3793 }
drhc2ce0be2014-05-29 12:36:14 +00003794 }else{
drheacd29d2016-04-15 15:03:27 +00003795 raw_printf(stderr, "Usage: .eqp on|off|full\n");
drhc2ce0be2014-05-29 12:36:14 +00003796 rc = 1;
mistachkin1fe36bb2016-04-04 02:16:44 +00003797 }
drhefbf3b12014-02-28 20:47:24 +00003798 }else
3799
drhd3ac7d92013-01-25 18:33:43 +00003800 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00003801 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00003802 rc = 2;
drh75897232000-05-29 14:26:00 +00003803 }else
3804
drhc2ce0be2014-05-29 12:36:14 +00003805 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00003806 int val = 1;
3807 if( nArg>=2 ){
3808 if( strcmp(azArg[1],"auto")==0 ){
3809 val = 99;
3810 }else{
3811 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003812 }
drh700c2522016-02-09 18:39:25 +00003813 }
3814 if( val==1 && p->mode!=MODE_Explain ){
3815 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003816 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003817 p->autoExplain = 0;
3818 }else if( val==0 ){
3819 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3820 p->autoExplain = 0;
3821 }else if( val==99 ){
3822 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3823 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003824 }
drh75897232000-05-29 14:26:00 +00003825 }else
3826
drhc1971542014-06-23 23:28:13 +00003827 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003828 ShellState data;
drhc1971542014-06-23 23:28:13 +00003829 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003830 int doStats = 0;
drh4926fec2016-04-13 15:33:42 +00003831 memcpy(&data, p, sizeof(data));
3832 data.showHeader = 0;
3833 data.cMode = data.mode = MODE_Semi;
3834 if( nArg==2 && optionMatch(azArg[1], "indent") ){
3835 data.cMode = data.mode = MODE_Pretty;
3836 nArg = 1;
3837 }
drhc1971542014-06-23 23:28:13 +00003838 if( nArg!=1 ){
drh4926fec2016-04-13 15:33:42 +00003839 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
drhc1971542014-06-23 23:28:13 +00003840 rc = 1;
3841 goto meta_command_exit;
3842 }
3843 open_db(p, 0);
drhc1971542014-06-23 23:28:13 +00003844 rc = sqlite3_exec(p->db,
3845 "SELECT sql FROM"
3846 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3847 " FROM sqlite_master UNION ALL"
3848 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003849 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003850 "ORDER BY rowid",
3851 callback, &data, &zErrMsg
3852 );
drh56f674c2014-07-18 14:43:29 +00003853 if( rc==SQLITE_OK ){
3854 sqlite3_stmt *pStmt;
3855 rc = sqlite3_prepare_v2(p->db,
3856 "SELECT rowid FROM sqlite_master"
3857 " WHERE name GLOB 'sqlite_stat[134]'",
3858 -1, &pStmt, 0);
3859 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3860 sqlite3_finalize(pStmt);
3861 }
3862 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003863 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003864 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003865 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003866 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3867 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003868 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003869 data.zDestTable = "sqlite_stat1";
3870 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3871 shell_callback, &data,&zErrMsg);
3872 data.zDestTable = "sqlite_stat3";
3873 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3874 shell_callback, &data,&zErrMsg);
3875 data.zDestTable = "sqlite_stat4";
3876 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3877 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003878 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003879 }
drhc1971542014-06-23 23:28:13 +00003880 }else
3881
drhc2ce0be2014-05-29 12:36:14 +00003882 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3883 if( nArg==2 ){
3884 p->showHeader = booleanValue(azArg[1]);
3885 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003886 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003887 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003888 }
drh75897232000-05-29 14:26:00 +00003889 }else
3890
drhc2ce0be2014-05-29 12:36:14 +00003891 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003892 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003893 }else
3894
3895 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003896 char *zTable; /* Insert data into this table */
3897 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003898 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003899 int nCol; /* Number of columns in the table */
3900 int nByte; /* Number of bytes in an SQL string */
3901 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003902 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003903 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003904 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003905 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003906 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3907 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003908
drhc2ce0be2014-05-29 12:36:14 +00003909 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003910 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003911 goto meta_command_exit;
3912 }
drh01f37542014-05-31 15:43:33 +00003913 zFile = azArg[1];
3914 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003915 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003916 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003917 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003918 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003919 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003920 raw_printf(stderr,
3921 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003922 return 1;
drhfeac5f82004-08-01 00:10:45 +00003923 }
drhdb95f682013-06-26 22:46:00 +00003924 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003925 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003926 " for import\n");
3927 return 1;
3928 }
mistachkin636bf9f2014-07-19 20:15:16 +00003929 nSep = strlen30(p->rowSeparator);
3930 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003931 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003932 return 1;
3933 }
mistachkine0d68852014-12-11 03:12:33 +00003934 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3935 /* When importing CSV (only), if the row separator is set to the
3936 ** default output row separator, change it to the default input
3937 ** row separator. This avoids having to maintain different input
3938 ** and output row separators. */
3939 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3940 nSep = strlen30(p->rowSeparator);
3941 }
mistachkin636bf9f2014-07-19 20:15:16 +00003942 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003943 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003944 " for import\n");
3945 return 1;
3946 }
3947 sCtx.zFile = zFile;
3948 sCtx.nLine = 1;
3949 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003950#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003951 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003952 return 1;
3953#else
mistachkin636bf9f2014-07-19 20:15:16 +00003954 sCtx.in = popen(sCtx.zFile+1, "r");
3955 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003956 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003957#endif
drh5bde8162013-06-27 14:07:53 +00003958 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003959 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003960 xCloser = fclose;
3961 }
mistachkin636bf9f2014-07-19 20:15:16 +00003962 if( p->mode==MODE_Ascii ){
3963 xRead = ascii_read_one_field;
3964 }else{
3965 xRead = csv_read_one_field;
3966 }
3967 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003968 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003969 return 1;
3970 }
mistachkin636bf9f2014-07-19 20:15:16 +00003971 sCtx.cColSep = p->colSeparator[0];
3972 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003973 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003974 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003975 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003976 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003977 return 1;
3978 }
drh4f21c4a2008-12-10 22:15:00 +00003979 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003980 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003981 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003982 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003983 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3984 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003985 while( xRead(&sCtx) ){
drhd8c22ac2016-02-25 13:33:02 +00003986 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003987 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003988 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003989 }
drh5bde8162013-06-27 14:07:53 +00003990 if( cSep=='(' ){
3991 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003992 sqlite3_free(sCtx.z);
3993 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003994 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003995 return 1;
3996 }
drhdb95f682013-06-26 22:46:00 +00003997 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3998 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3999 sqlite3_free(zCreate);
4000 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004001 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00004002 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00004003 sqlite3_free(sCtx.z);
4004 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00004005 return 1;
4006 }
drhc7181902014-02-27 15:04:13 +00004007 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00004008 }
drhfeac5f82004-08-01 00:10:45 +00004009 sqlite3_free(zSql);
4010 if( rc ){
shane916f9612009-10-23 00:37:15 +00004011 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00004012 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00004013 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00004014 return 1;
drhfeac5f82004-08-01 00:10:45 +00004015 }
shane916f9612009-10-23 00:37:15 +00004016 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00004017 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00004018 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00004019 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00004020 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00004021 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004022 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00004023 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00004024 return 1;
4025 }
drhdb95f682013-06-26 22:46:00 +00004026 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00004027 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00004028 for(i=1; i<nCol; i++){
4029 zSql[j++] = ',';
4030 zSql[j++] = '?';
4031 }
4032 zSql[j++] = ')';
4033 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00004034 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00004035 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00004036 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004037 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00004038 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00004039 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00004040 return 1;
drhfeac5f82004-08-01 00:10:45 +00004041 }
mistachkin8e189222015-04-19 21:43:16 +00004042 needCommit = sqlite3_get_autocommit(p->db);
4043 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00004044 do{
mistachkin636bf9f2014-07-19 20:15:16 +00004045 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00004046 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00004047 char *z = xRead(&sCtx);
4048 /*
4049 ** Did we reach end-of-file before finding any columns?
4050 ** If so, stop instead of NULL filling the remaining columns.
4051 */
drhdb95f682013-06-26 22:46:00 +00004052 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00004053 /*
4054 ** Did we reach end-of-file OR end-of-line before finding any
4055 ** columns in ASCII mode? If so, stop instead of NULL filling
4056 ** the remaining columns.
4057 */
4058 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00004059 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00004060 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00004061 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00004062 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00004063 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00004064 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00004065 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00004066 }
drhfeac5f82004-08-01 00:10:45 +00004067 }
mistachkin636bf9f2014-07-19 20:15:16 +00004068 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00004069 do{
mistachkin636bf9f2014-07-19 20:15:16 +00004070 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00004071 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00004072 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00004073 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00004074 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00004075 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00004076 }
drhdb95f682013-06-26 22:46:00 +00004077 if( i>=nCol ){
4078 sqlite3_step(pStmt);
4079 rc = sqlite3_reset(pStmt);
4080 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004081 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
4082 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00004083 }
4084 }
mistachkin636bf9f2014-07-19 20:15:16 +00004085 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00004086
mistachkin636bf9f2014-07-19 20:15:16 +00004087 xCloser(sCtx.in);
4088 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00004089 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00004090 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00004091 }else
4092
drhd12602a2016-12-07 15:49:02 +00004093#ifndef SQLITE_UNTESTABLE
drh16eb5942016-11-03 13:01:38 +00004094 if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
4095 char *zSql;
4096 char *zCollist = 0;
4097 sqlite3_stmt *pStmt;
4098 int tnum = 0;
drh59ce2c42016-11-03 13:12:28 +00004099 int i;
drh16eb5942016-11-03 13:01:38 +00004100 if( nArg!=3 ){
4101 utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n");
4102 rc = 1;
4103 goto meta_command_exit;
4104 }
4105 open_db(p, 0);
4106 zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
4107 " WHERE name='%q' AND type='index'", azArg[1]);
4108 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4109 sqlite3_free(zSql);
4110 if( sqlite3_step(pStmt)==SQLITE_ROW ){
4111 tnum = sqlite3_column_int(pStmt, 0);
4112 }
4113 sqlite3_finalize(pStmt);
4114 if( tnum==0 ){
4115 utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
4116 rc = 1;
4117 goto meta_command_exit;
4118 }
4119 zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
4120 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4121 sqlite3_free(zSql);
drh59ce2c42016-11-03 13:12:28 +00004122 i = 0;
drh16eb5942016-11-03 13:01:38 +00004123 while( sqlite3_step(pStmt)==SQLITE_ROW ){
drh59ce2c42016-11-03 13:12:28 +00004124 char zLabel[20];
drh16eb5942016-11-03 13:01:38 +00004125 const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
drh59ce2c42016-11-03 13:12:28 +00004126 i++;
4127 if( zCol==0 ){
4128 if( sqlite3_column_int(pStmt,1)==-1 ){
4129 zCol = "_ROWID_";
4130 }else{
4131 sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i);
4132 zCol = zLabel;
4133 }
4134 }
drh16eb5942016-11-03 13:01:38 +00004135 if( zCollist==0 ){
4136 zCollist = sqlite3_mprintf("\"%w\"", zCol);
4137 }else{
4138 zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
4139 }
4140 }
4141 sqlite3_finalize(pStmt);
4142 zSql = sqlite3_mprintf(
4143 "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID",
4144 azArg[2], zCollist, zCollist);
4145 sqlite3_free(zCollist);
4146 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
4147 if( rc==SQLITE_OK ){
4148 rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
4149 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
4150 if( rc ){
4151 utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
4152 }else{
4153 utf8_printf(stdout, "%s;\n", zSql);
mistachkin2f9a6132016-11-11 05:19:45 +00004154 raw_printf(stdout,
drh16eb5942016-11-03 13:01:38 +00004155 "WARNING: writing to an imposter table will corrupt the index!\n"
4156 );
4157 }
4158 }else{
mistachkin2f9a6132016-11-11 05:19:45 +00004159 raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
drh16eb5942016-11-03 13:01:38 +00004160 rc = 1;
4161 }
4162 sqlite3_free(zSql);
4163 }else
4164#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
4165
drhae5e4452007-05-03 17:18:36 +00004166#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00004167 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00004168 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00004169 if( iotrace && iotrace!=stdout ) fclose(iotrace);
4170 iotrace = 0;
4171 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00004172 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00004173 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00004174 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00004175 iotrace = stdout;
4176 }else{
4177 iotrace = fopen(azArg[1], "w");
4178 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004179 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00004180 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00004181 rc = 1;
drhb0603412007-02-28 04:47:26 +00004182 }else{
mlcreech3a00f902008-03-04 17:45:01 +00004183 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00004184 }
4185 }
4186 }else
drhae5e4452007-05-03 17:18:36 +00004187#endif
drh16eb5942016-11-03 13:01:38 +00004188
drh1a513372015-05-02 17:40:23 +00004189 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
4190 static const struct {
4191 const char *zLimitName; /* Name of a limit */
4192 int limitCode; /* Integer code for that limit */
4193 } aLimit[] = {
4194 { "length", SQLITE_LIMIT_LENGTH },
4195 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
4196 { "column", SQLITE_LIMIT_COLUMN },
4197 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
4198 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
4199 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
4200 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
4201 { "attached", SQLITE_LIMIT_ATTACHED },
4202 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
4203 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
4204 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
4205 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
4206 };
4207 int i, n2;
4208 open_db(p, 0);
4209 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00004210 for(i=0; i<ArraySize(aLimit); i++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004211 printf("%20s %d\n", aLimit[i].zLimitName,
drh1a513372015-05-02 17:40:23 +00004212 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
4213 }
4214 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004215 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00004216 rc = 1;
4217 goto meta_command_exit;
4218 }else{
4219 int iLimit = -1;
4220 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00004221 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00004222 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
4223 if( iLimit<0 ){
4224 iLimit = i;
4225 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004226 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00004227 rc = 1;
4228 goto meta_command_exit;
4229 }
4230 }
4231 }
4232 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004233 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00004234 "enter \".limits\" with no arguments for a list.\n",
4235 azArg[1]);
4236 rc = 1;
4237 goto meta_command_exit;
4238 }
4239 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00004240 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
4241 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00004242 }
4243 printf("%20s %d\n", aLimit[iLimit].zLimitName,
4244 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
4245 }
4246 }else
drhb0603412007-02-28 04:47:26 +00004247
dan3c7ebeb2016-12-16 17:28:56 +00004248 if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
drh3fd9f332016-12-16 18:41:11 +00004249 open_db(p, 0);
dan3c7ebeb2016-12-16 17:28:56 +00004250 lintDotCommand(p, azArg, nArg);
4251 }else
4252
drh70df4fe2006-06-13 15:12:21 +00004253#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00004254 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00004255 const char *zFile, *zProc;
4256 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00004257 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004258 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00004259 rc = 1;
4260 goto meta_command_exit;
4261 }
drh1e397f82006-06-08 15:28:43 +00004262 zFile = azArg[1];
4263 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00004264 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00004265 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
4266 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004267 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00004268 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00004269 rc = 1;
drh1e397f82006-06-08 15:28:43 +00004270 }
4271 }else
drh70df4fe2006-06-13 15:12:21 +00004272#endif
drh1e397f82006-06-08 15:28:43 +00004273
drhc2ce0be2014-05-29 12:36:14 +00004274 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
4275 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004276 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00004277 rc = 1;
4278 }else{
4279 const char *zFile = azArg[1];
4280 output_file_close(p->pLog);
4281 p->pLog = output_file_open(zFile);
4282 }
drh127f9d72010-02-23 01:47:00 +00004283 }else
4284
drhc2ce0be2014-05-29 12:36:14 +00004285 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
4286 const char *zMode = nArg>=2 ? azArg[1] : "";
4287 int n2 = (int)strlen(zMode);
4288 int c2 = zMode[0];
4289 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004290 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00004291 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004292 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00004293 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004294 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00004295 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004296 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00004297 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00004298 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00004299 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00004300 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00004301 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00004302 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00004303 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00004304 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00004305 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004306 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00004307 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00004308 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00004309 set_table_name(p, nArg>=3 ? azArg[2] : "table");
drh41f5f6e2016-10-21 17:39:30 +00004310 }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
4311 p->mode = MODE_Quote;
mistachkin636bf9f2014-07-19 20:15:16 +00004312 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
4313 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00004314 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
4315 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00004316 }else {
mistachkinaae280e2015-12-31 19:06:24 +00004317 raw_printf(stderr, "Error: mode should be one of: "
drh36f49d02016-11-23 23:18:45 +00004318 "ascii column csv html insert line list quote tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00004319 rc = 1;
drh75897232000-05-29 14:26:00 +00004320 }
drh700c2522016-02-09 18:39:25 +00004321 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00004322 }else
4323
drhc2ce0be2014-05-29 12:36:14 +00004324 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
4325 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00004326 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
4327 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00004328 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004329 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00004330 rc = 1;
4331 }
4332 }else
4333
drh05782482013-10-24 15:20:20 +00004334 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
drhcd0509e2016-09-16 00:26:08 +00004335 char *zNewFilename; /* Name of the database file to open */
4336 int iName = 1; /* Index in azArg[] of the filename */
drh760c8162016-09-16 02:52:22 +00004337 int newFlag = 0; /* True to delete file before opening */
drhcd0509e2016-09-16 00:26:08 +00004338 /* Close the existing database */
4339 session_close_all(p);
4340 sqlite3_close(p->db);
drh05782482013-10-24 15:20:20 +00004341 p->db = 0;
drhcd0509e2016-09-16 00:26:08 +00004342 sqlite3_free(p->zFreeOnClose);
4343 p->zFreeOnClose = 0;
drh760c8162016-09-16 02:52:22 +00004344 /* Check for command-line arguments */
4345 for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
4346 const char *z = azArg[iName];
4347 if( optionMatch(z,"new") ){
4348 newFlag = 1;
4349 }else if( z[0]=='-' ){
4350 utf8_printf(stderr, "unknown option: %s\n", z);
4351 rc = 1;
mistachkin8145fc62016-09-16 20:39:21 +00004352 goto meta_command_exit;
drh760c8162016-09-16 02:52:22 +00004353 }
drhcd0509e2016-09-16 00:26:08 +00004354 }
4355 /* If a filename is specified, try to open it first */
4356 zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
4357 if( zNewFilename ){
drh760c8162016-09-16 02:52:22 +00004358 if( newFlag ) shellDeleteFile(zNewFilename);
drhcd0509e2016-09-16 00:26:08 +00004359 p->zDbFilename = zNewFilename;
4360 open_db(p, 1);
4361 if( p->db==0 ){
4362 utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
4363 sqlite3_free(zNewFilename);
4364 }else{
4365 p->zFreeOnClose = zNewFilename;
4366 }
4367 }
4368 if( p->db==0 ){
4369 /* As a fall-back open a TEMP database */
4370 p->zDbFilename = 0;
4371 open_db(p, 0);
drh05782482013-10-24 15:20:20 +00004372 }
4373 }else
4374
drhc2ce0be2014-05-29 12:36:14 +00004375 if( c=='o'
4376 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
4377 ){
4378 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
4379 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004380 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00004381 rc = 1;
4382 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004383 }
drhc2ce0be2014-05-29 12:36:14 +00004384 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
4385 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004386 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004387 rc = 1;
4388 goto meta_command_exit;
4389 }
4390 p->outCount = 2;
4391 }else{
4392 p->outCount = 0;
4393 }
4394 output_reset(p);
4395 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00004396#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00004397 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00004398 rc = 1;
4399 p->out = stdout;
4400#else
drhc2ce0be2014-05-29 12:36:14 +00004401 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00004402 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004403 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00004404 p->out = stdout;
4405 rc = 1;
4406 }else{
drhc2ce0be2014-05-29 12:36:14 +00004407 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00004408 }
drh8cd5b252015-03-02 22:06:43 +00004409#endif
drh75897232000-05-29 14:26:00 +00004410 }else{
drhc2ce0be2014-05-29 12:36:14 +00004411 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00004412 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004413 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004414 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00004415 }
drh75897232000-05-29 14:26:00 +00004416 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00004417 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00004418 } else {
drhc2ce0be2014-05-29 12:36:14 +00004419 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00004420 }
4421 }
4422 }else
4423
drh078b1fd2012-09-21 13:40:02 +00004424 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
4425 int i;
4426 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00004427 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00004428 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00004429 }
mistachkinaae280e2015-12-31 19:06:24 +00004430 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00004431 }else
4432
drhc2ce0be2014-05-29 12:36:14 +00004433 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00004434 if( nArg >= 2) {
4435 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
4436 }
4437 if( nArg >= 3) {
4438 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
4439 }
4440 }else
4441
drhc2ce0be2014-05-29 12:36:14 +00004442 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00004443 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00004444 }else
4445
drhc2ce0be2014-05-29 12:36:14 +00004446 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
4447 FILE *alt;
drh4e8142c2016-11-11 14:54:22 +00004448 if( nArg!=2 ){
4449 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004450 rc = 1;
4451 goto meta_command_exit;
4452 }
drh4e8142c2016-11-11 14:54:22 +00004453 alt = fopen(azArg[1], "rb");
4454 if( alt==0 ){
4455 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
4456 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00004457 }else{
drh4e8142c2016-11-11 14:54:22 +00004458 rc = process_input(p, alt);
4459 fclose(alt);
drhdaffd0e2001-04-11 14:28:42 +00004460 }
4461 }else
4462
drhc2ce0be2014-05-29 12:36:14 +00004463 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00004464 const char *zSrcFile;
4465 const char *zDb;
4466 sqlite3 *pSrc;
4467 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00004468 int nTimeout = 0;
4469
drh9ff849f2009-02-04 20:55:57 +00004470 if( nArg==2 ){
4471 zSrcFile = azArg[1];
4472 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00004473 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00004474 zSrcFile = azArg[2];
4475 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00004476 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004477 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004478 rc = 1;
4479 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00004480 }
4481 rc = sqlite3_open(zSrcFile, &pSrc);
4482 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004483 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00004484 sqlite3_close(pSrc);
4485 return 1;
4486 }
drh05782482013-10-24 15:20:20 +00004487 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00004488 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
4489 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004490 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00004491 sqlite3_close(pSrc);
4492 return 1;
4493 }
drhdc2c4912009-02-04 22:46:47 +00004494 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
4495 || rc==SQLITE_BUSY ){
4496 if( rc==SQLITE_BUSY ){
4497 if( nTimeout++ >= 3 ) break;
4498 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00004499 }
4500 }
4501 sqlite3_backup_finish(pBackup);
4502 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00004503 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00004504 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00004505 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00004506 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004507 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004508 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00004509 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004510 }
4511 sqlite3_close(pSrc);
4512 }else
4513
dan8d1edb92014-11-05 09:07:28 +00004514
4515 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
4516 if( nArg==2 ){
4517 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00004518#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00004519 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00004520#endif
dan8d1edb92014-11-05 09:07:28 +00004521 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004522 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00004523 rc = 1;
4524 }
4525 }else
4526
drhc2ce0be2014-05-29 12:36:14 +00004527 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00004528 ShellState data;
drh75897232000-05-29 14:26:00 +00004529 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00004530 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00004531 memcpy(&data, p, sizeof(data));
4532 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00004533 data.cMode = data.mode = MODE_Semi;
drh4926fec2016-04-13 15:33:42 +00004534 if( nArg>=2 && optionMatch(azArg[1], "indent") ){
4535 data.cMode = data.mode = MODE_Pretty;
4536 nArg--;
4537 if( nArg==2 ) azArg[1] = azArg[2];
4538 }
4539 if( nArg==2 && azArg[1][0]!='-' ){
drhc8d74412004-08-31 23:41:26 +00004540 int i;
drhf0693c82011-10-11 20:41:54 +00004541 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00004542 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00004543 char *new_argv[2], *new_colv[2];
4544 new_argv[0] = "CREATE TABLE sqlite_master (\n"
4545 " type text,\n"
4546 " name text,\n"
4547 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00004548 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00004549 " sql text\n"
4550 ")";
4551 new_argv[1] = 0;
4552 new_colv[0] = "sql";
4553 new_colv[1] = 0;
4554 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004555 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00004556 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00004557 char *new_argv[2], *new_colv[2];
4558 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
4559 " type text,\n"
4560 " name text,\n"
4561 " tbl_name text,\n"
4562 " rootpage integer,\n"
4563 " sql text\n"
4564 ")";
4565 new_argv[1] = 0;
4566 new_colv[0] = "sql";
4567 new_colv[1] = 0;
4568 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004569 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00004570 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00004571 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00004572 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004573 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004574 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004575 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004576 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00004577 "WHERE lower(tbl_name) LIKE shellstatic()"
4578 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00004579 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00004580 callback, &data, &zErrMsg);
4581 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00004582 }
drhc2ce0be2014-05-29 12:36:14 +00004583 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00004584 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004585 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004586 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004587 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004588 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00004589 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00004590 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00004591 callback, &data, &zErrMsg
4592 );
drhc2ce0be2014-05-29 12:36:14 +00004593 }else{
drh4926fec2016-04-13 15:33:42 +00004594 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00004595 rc = 1;
4596 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004597 }
drh75897232000-05-29 14:26:00 +00004598 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00004599 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004600 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00004601 rc = 1;
4602 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004603 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00004604 rc = 1;
4605 }else{
4606 rc = 0;
drh75897232000-05-29 14:26:00 +00004607 }
4608 }else
4609
drhabd4c722014-09-20 18:18:33 +00004610#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
4611 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
drh1d9be4f2015-01-22 11:29:25 +00004612 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00004613 }else
4614#endif
4615
drhe6229612014-08-18 15:08:26 +00004616#if defined(SQLITE_ENABLE_SESSION)
4617 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
4618 OpenSession *pSession = &p->aSession[0];
4619 char **azCmd = &azArg[1];
4620 int iSes = 0;
4621 int nCmd = nArg - 1;
4622 int i;
4623 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00004624 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00004625 if( nArg>=3 ){
4626 for(iSes=0; iSes<p->nSession; iSes++){
4627 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
4628 }
4629 if( iSes<p->nSession ){
4630 pSession = &p->aSession[iSes];
4631 azCmd++;
4632 nCmd--;
4633 }else{
4634 pSession = &p->aSession[0];
4635 iSes = 0;
4636 }
4637 }
4638
drh3a67b042014-08-18 17:56:31 +00004639 /* .session attach TABLE
4640 ** Invoke the sqlite3session_attach() interface to attach a particular
4641 ** table so that it is never filtered.
4642 */
4643 if( strcmp(azCmd[0],"attach")==0 ){
4644 if( nCmd!=2 ) goto session_syntax_error;
4645 if( pSession->p==0 ){
4646 session_not_open:
mistachkin899c5c92016-04-03 20:50:02 +00004647 raw_printf(stderr, "ERROR: No sessions are open\n");
drh3a67b042014-08-18 17:56:31 +00004648 }else{
4649 rc = sqlite3session_attach(pSession->p, azCmd[1]);
4650 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004651 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004652 rc = 0;
4653 }
4654 }
4655 }else
4656
4657 /* .session changeset FILE
4658 ** .session patchset FILE
4659 ** Write a changeset or patchset into a file. The file is overwritten.
4660 */
4661 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
4662 FILE *out = 0;
4663 if( nCmd!=2 ) goto session_syntax_error;
4664 if( pSession->p==0 ) goto session_not_open;
4665 out = fopen(azCmd[1], "wb");
4666 if( out==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004667 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
drh3a67b042014-08-18 17:56:31 +00004668 }else{
4669 int szChng;
4670 void *pChng;
4671 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00004672 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00004673 }else{
drh2967e0c2014-08-19 00:26:17 +00004674 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
4675 }
4676 if( rc ){
4677 printf("Error: error code %d\n", rc);
4678 rc = 0;
drh3a67b042014-08-18 17:56:31 +00004679 }
mistachkin1fe36bb2016-04-04 02:16:44 +00004680 if( pChng
drh3a67b042014-08-18 17:56:31 +00004681 && fwrite(pChng, szChng, 1, out)!=1 ){
mistachkin899c5c92016-04-03 20:50:02 +00004682 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
drh3a67b042014-08-18 17:56:31 +00004683 szChng);
4684 }
4685 sqlite3_free(pChng);
4686 fclose(out);
4687 }
4688 }else
4689
drhe6229612014-08-18 15:08:26 +00004690 /* .session close
4691 ** Close the identified session
4692 */
4693 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00004694 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00004695 if( p->nSession ){
4696 session_close(pSession);
4697 p->aSession[iSes] = p->aSession[--p->nSession];
4698 }
4699 }else
4700
drh03168ca2014-08-18 20:01:31 +00004701 /* .session enable ?BOOLEAN?
4702 ** Query or set the enable flag
4703 */
4704 if( strcmp(azCmd[0], "enable")==0 ){
4705 int ii;
4706 if( nCmd>2 ) goto session_syntax_error;
4707 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4708 if( p->nSession ){
4709 ii = sqlite3session_enable(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004710 utf8_printf(p->out, "session %s enable flag = %d\n",
4711 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004712 }
4713 }else
4714
4715 /* .session filter GLOB ....
4716 ** Set a list of GLOB patterns of table names to be excluded.
4717 */
4718 if( strcmp(azCmd[0], "filter")==0 ){
4719 int ii, nByte;
4720 if( nCmd<2 ) goto session_syntax_error;
4721 if( p->nSession ){
4722 for(ii=0; ii<pSession->nFilter; ii++){
4723 sqlite3_free(pSession->azFilter[ii]);
4724 }
4725 sqlite3_free(pSession->azFilter);
4726 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
4727 pSession->azFilter = sqlite3_malloc( nByte );
4728 if( pSession->azFilter==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004729 raw_printf(stderr, "Error: out or memory\n");
drh03168ca2014-08-18 20:01:31 +00004730 exit(1);
4731 }
4732 for(ii=1; ii<nCmd; ii++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004733 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
drh03168ca2014-08-18 20:01:31 +00004734 }
4735 pSession->nFilter = ii-1;
4736 }
4737 }else
4738
4739 /* .session indirect ?BOOLEAN?
4740 ** Query or set the indirect flag
4741 */
4742 if( strcmp(azCmd[0], "indirect")==0 ){
4743 int ii;
4744 if( nCmd>2 ) goto session_syntax_error;
4745 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4746 if( p->nSession ){
4747 ii = sqlite3session_indirect(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004748 utf8_printf(p->out, "session %s indirect flag = %d\n",
4749 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004750 }
4751 }else
4752
4753 /* .session isempty
4754 ** Determine if the session is empty
4755 */
4756 if( strcmp(azCmd[0], "isempty")==0 ){
4757 int ii;
4758 if( nCmd!=1 ) goto session_syntax_error;
4759 if( p->nSession ){
4760 ii = sqlite3session_isempty(pSession->p);
mistachkin899c5c92016-04-03 20:50:02 +00004761 utf8_printf(p->out, "session %s isempty flag = %d\n",
4762 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004763 }
4764 }else
4765
drhe6229612014-08-18 15:08:26 +00004766 /* .session list
4767 ** List all currently open sessions
4768 */
4769 if( strcmp(azCmd[0],"list")==0 ){
4770 for(i=0; i<p->nSession; i++){
mistachkin899c5c92016-04-03 20:50:02 +00004771 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
drhe6229612014-08-18 15:08:26 +00004772 }
4773 }else
4774
4775 /* .session open DB NAME
4776 ** Open a new session called NAME on the attached database DB.
4777 ** DB is normally "main".
4778 */
4779 if( strcmp(azCmd[0],"open")==0 ){
4780 char *zName;
4781 if( nCmd!=3 ) goto session_syntax_error;
4782 zName = azCmd[2];
4783 if( zName[0]==0 ) goto session_syntax_error;
4784 for(i=0; i<p->nSession; i++){
4785 if( strcmp(p->aSession[i].zName,zName)==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004786 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
drhe6229612014-08-18 15:08:26 +00004787 goto meta_command_exit;
4788 }
4789 }
4790 if( p->nSession>=ArraySize(p->aSession) ){
mistachkin899c5c92016-04-03 20:50:02 +00004791 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
drhe6229612014-08-18 15:08:26 +00004792 goto meta_command_exit;
4793 }
4794 pSession = &p->aSession[p->nSession];
4795 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
4796 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004797 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004798 rc = 0;
drhe6229612014-08-18 15:08:26 +00004799 goto meta_command_exit;
4800 }
drh03168ca2014-08-18 20:01:31 +00004801 pSession->nFilter = 0;
4802 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00004803 p->nSession++;
4804 pSession->zName = sqlite3_mprintf("%s", zName);
4805 }else
4806 /* If no command name matches, show a syntax error */
4807 session_syntax_error:
4808 session_help(p);
4809 }else
4810#endif
4811
drh340f5822013-06-27 13:01:21 +00004812#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00004813 /* Undocumented commands for internal testing. Subject to change
4814 ** without notice. */
4815 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
4816 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
4817 int i, v;
4818 for(i=1; i<nArg; i++){
4819 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00004820 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00004821 }
4822 }
4823 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
4824 int i; sqlite3_int64 v;
4825 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00004826 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00004827 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00004828 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00004829 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00004830 }
4831 }
4832 }else
drh340f5822013-06-27 13:01:21 +00004833#endif
drh348d19c2013-06-03 12:47:43 +00004834
drhc2ce0be2014-05-29 12:36:14 +00004835 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00004836 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004837 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00004838 rc = 1;
4839 }
drh6976c212014-07-24 12:09:47 +00004840 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004841 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00004842 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00004843 }
4844 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00004845 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
4846 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00004847 }
drh75897232000-05-29 14:26:00 +00004848 }else
4849
drh62cdde52014-05-28 20:22:28 +00004850 if( c=='s'
4851 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00004852 ){
4853 char *zCmd;
drh54027102014-08-06 14:36:53 +00004854 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00004855 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004856 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00004857 rc = 1;
4858 goto meta_command_exit;
4859 }
drhdcb3e3d2014-05-29 03:17:29 +00004860 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00004861 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00004862 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
4863 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00004864 }
drh54027102014-08-06 14:36:53 +00004865 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00004866 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00004867 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00004868 }else
4869
drhc2ce0be2014-05-29 12:36:14 +00004870 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drheacd29d2016-04-15 15:03:27 +00004871 static const char *azBool[] = { "off", "on", "full", "unk" };
persicom7e2dfdd2002-04-18 02:46:52 +00004872 int i;
drhc2ce0be2014-05-29 12:36:14 +00004873 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00004874 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00004875 rc = 1;
4876 goto meta_command_exit;
4877 }
drheacd29d2016-04-15 15:03:27 +00004878 utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]);
4879 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
drh700c2522016-02-09 18:39:25 +00004880 utf8_printf(p->out, "%12.12s: %s\n","explain",
4881 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
drheacd29d2016-04-15 15:03:27 +00004882 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004883 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
4884 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00004885 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00004886 raw_printf(p->out, "\n");
4887 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00004888 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00004889 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004890 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004891 raw_printf(p->out, "\n");
4892 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004893 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004894 raw_printf(p->out, "\n");
drheacd29d2016-04-15 15:03:27 +00004895 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004896 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00004897 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00004898 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00004899 }
mistachkinaae280e2015-12-31 19:06:24 +00004900 raw_printf(p->out, "\n");
drhcd0509e2016-09-16 00:26:08 +00004901 utf8_printf(p->out, "%12.12s: %s\n", "filename",
4902 p->zDbFilename ? p->zDbFilename : "");
persicom7e2dfdd2002-04-18 02:46:52 +00004903 }else
4904
drhc2ce0be2014-05-29 12:36:14 +00004905 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
4906 if( nArg==2 ){
4907 p->statsOn = booleanValue(azArg[1]);
drh34784902016-02-27 17:12:36 +00004908 }else if( nArg==1 ){
4909 display_stats(p->db, p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004910 }else{
drh34784902016-02-27 17:12:36 +00004911 raw_printf(stderr, "Usage: .stats ?on|off?\n");
drhc2ce0be2014-05-29 12:36:14 +00004912 rc = 1;
4913 }
shaneh642d8b82010-07-28 16:05:34 +00004914 }else
4915
drh6a5a4202016-12-24 21:32:40 +00004916 if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
4917 || (c=='i' && (strncmp(azArg[0], "indices", n)==0
4918 || strncmp(azArg[0], "indexes", n)==0) )
4919 ){
drh98781232012-04-23 12:38:05 +00004920 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00004921 char **azResult;
drh98781232012-04-23 12:38:05 +00004922 int nRow, nAlloc;
4923 char *zSql = 0;
4924 int ii;
drh05782482013-10-24 15:20:20 +00004925 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00004926 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00004927 if( rc ) return shellDatabaseError(p->db);
4928
4929 /* Create an SQL statement to query for the list of tables in the
4930 ** main and all attached databases where the table name matches the
4931 ** LIKE pattern bound to variable "?1". */
drh6a5a4202016-12-24 21:32:40 +00004932 if( c=='t' ){
4933 zSql = sqlite3_mprintf(
4934 "SELECT name FROM sqlite_master"
4935 " WHERE type IN ('table','view')"
4936 " AND name NOT LIKE 'sqlite_%%'"
4937 " AND name LIKE ?1");
4938 }else if( nArg>2 ){
4939 /* It is an historical accident that the .indexes command shows an error
4940 ** when called with the wrong number of arguments whereas the .tables
4941 ** command does not. */
4942 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
4943 rc = 1;
4944 goto meta_command_exit;
4945 }else{
4946 zSql = sqlite3_mprintf(
4947 "SELECT name FROM sqlite_master"
4948 " WHERE type='index'"
4949 " AND tbl_name LIKE ?1");
4950 }
drha4b81d22016-12-24 18:04:28 +00004951 for(ii=0; zSql && sqlite3_step(pStmt)==SQLITE_ROW; ii++){
drh98781232012-04-23 12:38:05 +00004952 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
drha4b81d22016-12-24 18:04:28 +00004953 if( zDbName==0 || ii==0 ) continue;
drh6a5a4202016-12-24 21:32:40 +00004954 if( c=='t' ){
drh98781232012-04-23 12:38:05 +00004955 zSql = sqlite3_mprintf(
4956 "%z UNION ALL "
4957 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4958 " WHERE type IN ('table','view')"
4959 " AND name NOT LIKE 'sqlite_%%'"
4960 " AND name LIKE ?1", zSql, zDbName, zDbName);
drh6a5a4202016-12-24 21:32:40 +00004961 }else{
4962 zSql = sqlite3_mprintf(
4963 "%z UNION ALL "
4964 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4965 " WHERE type='index'"
4966 " AND tbl_name LIKE ?1", zSql, zDbName, zDbName);
drh98781232012-04-23 12:38:05 +00004967 }
drha50da102000-08-08 20:19:09 +00004968 }
dand95bb392015-09-30 11:19:05 +00004969 rc = sqlite3_finalize(pStmt);
4970 if( zSql && rc==SQLITE_OK ){
4971 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
4972 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4973 }
drh98781232012-04-23 12:38:05 +00004974 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00004975 if( !zSql ) return shellNomemError();
4976 if( rc ) return shellDatabaseError(p->db);
4977
4978 /* Run the SQL statement prepared by the above block. Store the results
4979 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00004980 nRow = nAlloc = 0;
4981 azResult = 0;
4982 if( nArg>1 ){
4983 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00004984 }else{
drh98781232012-04-23 12:38:05 +00004985 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
4986 }
4987 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4988 if( nRow>=nAlloc ){
4989 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00004990 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00004991 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00004992 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00004993 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00004994 break;
4995 }
mistachkin8e189222015-04-19 21:43:16 +00004996 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00004997 azResult = azNew;
4998 }
4999 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00005000 if( 0==azResult[nRow] ){
5001 rc = shellNomemError();
5002 break;
5003 }
5004 nRow++;
drh98781232012-04-23 12:38:05 +00005005 }
dand95bb392015-09-30 11:19:05 +00005006 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
5007 rc = shellDatabaseError(p->db);
5008 }
5009
5010 /* Pretty-print the contents of array azResult[] to the output */
5011 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00005012 int len, maxlen = 0;
5013 int i, j;
5014 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00005015 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00005016 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00005017 if( len>maxlen ) maxlen = len;
5018 }
5019 nPrintCol = 80/(maxlen+2);
5020 if( nPrintCol<1 ) nPrintCol = 1;
5021 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
5022 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00005023 for(j=i; j<nRow; j+=nPrintRow){
5024 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00005025 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
5026 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00005027 }
mistachkinaae280e2015-12-31 19:06:24 +00005028 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00005029 }
5030 }
dand95bb392015-09-30 11:19:05 +00005031
drh98781232012-04-23 12:38:05 +00005032 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
5033 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00005034 }else
5035
drh2db82112016-09-15 21:35:24 +00005036 /* Begin redirecting output to the file "testcase-out.txt" */
5037 if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
5038 output_reset(p);
5039 p->out = output_file_open("testcase-out.txt");
5040 if( p->out==0 ){
mistachkin2f9a6132016-11-11 05:19:45 +00005041 raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
drh2db82112016-09-15 21:35:24 +00005042 }
drh760c8162016-09-16 02:52:22 +00005043 if( nArg>=2 ){
5044 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
5045 }else{
5046 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
5047 }
drh2db82112016-09-15 21:35:24 +00005048 }else
drh2db82112016-09-15 21:35:24 +00005049
drhd12602a2016-12-07 15:49:02 +00005050#ifndef SQLITE_UNTESTABLE
shaneh96887e12011-02-10 21:08:58 +00005051 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00005052 static const struct {
5053 const char *zCtrlName; /* Name of a test-control option */
5054 int ctrlCode; /* Integer code for that option */
5055 } aCtrl[] = {
5056 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
5057 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
5058 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
5059 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
5060 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
5061 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
5062 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
5063 { "assert", SQLITE_TESTCTRL_ASSERT },
5064 { "always", SQLITE_TESTCTRL_ALWAYS },
5065 { "reserve", SQLITE_TESTCTRL_RESERVE },
5066 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
5067 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00005068 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00005069 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00005070 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00005071 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00005072 };
shaneh96887e12011-02-10 21:08:58 +00005073 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00005074 int rc2 = 0;
5075 int i, n2;
drh05782482013-10-24 15:20:20 +00005076 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00005077
drhd416fe72011-03-17 16:45:50 +00005078 /* convert testctrl text option to value. allow any unique prefix
5079 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00005080 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00005081 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00005082 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00005083 if( testctrl<0 ){
5084 testctrl = aCtrl[i].ctrlCode;
5085 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005086 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00005087 testctrl = -1;
5088 break;
5089 }
5090 }
5091 }
drh348d19c2013-06-03 12:47:43 +00005092 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005093 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00005094 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005095 }else{
5096 switch(testctrl){
5097
5098 /* sqlite3_test_control(int, db, int) */
5099 case SQLITE_TESTCTRL_OPTIMIZATIONS:
mistachkin1fe36bb2016-04-04 02:16:44 +00005100 case SQLITE_TESTCTRL_RESERVE:
shaneh96887e12011-02-10 21:08:58 +00005101 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005102 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00005103 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00005104 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00005105 } else {
mistachkinaae280e2015-12-31 19:06:24 +00005106 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00005107 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005108 }
5109 break;
5110
5111 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00005112 case SQLITE_TESTCTRL_PRNG_SAVE:
5113 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00005114 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00005115 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00005116 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00005117 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00005118 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00005119 } else {
mistachkinaae280e2015-12-31 19:06:24 +00005120 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
5121 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005122 }
5123 break;
5124
5125 /* sqlite3_test_control(int, uint) */
mistachkin1fe36bb2016-04-04 02:16:44 +00005126 case SQLITE_TESTCTRL_PENDING_BYTE:
shaneh96887e12011-02-10 21:08:58 +00005127 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00005128 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00005129 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00005130 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00005131 } else {
mistachkinaae280e2015-12-31 19:06:24 +00005132 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00005133 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005134 }
5135 break;
mistachkin1fe36bb2016-04-04 02:16:44 +00005136
shaneh96887e12011-02-10 21:08:58 +00005137 /* sqlite3_test_control(int, int) */
mistachkin1fe36bb2016-04-04 02:16:44 +00005138 case SQLITE_TESTCTRL_ASSERT:
5139 case SQLITE_TESTCTRL_ALWAYS:
5140 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00005141 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005142 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00005143 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00005144 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00005145 } else {
mistachkinaae280e2015-12-31 19:06:24 +00005146 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00005147 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005148 }
5149 break;
5150
5151 /* sqlite3_test_control(int, char *) */
5152#ifdef SQLITE_N_KEYWORD
mistachkin1fe36bb2016-04-04 02:16:44 +00005153 case SQLITE_TESTCTRL_ISKEYWORD:
shaneh96887e12011-02-10 21:08:58 +00005154 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005155 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00005156 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00005157 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00005158 } else {
mistachkinaae280e2015-12-31 19:06:24 +00005159 utf8_printf(stderr,
5160 "Error: testctrl %s takes a single char * option\n",
5161 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005162 }
5163 break;
5164#endif
5165
drh1ffede82015-01-30 20:59:27 +00005166 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00005167 if( nArg==5 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005168 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00005169 azArg[2],
drh8964b342015-01-29 17:54:52 +00005170 integerValue(azArg[3]),
5171 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00005172 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00005173 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005174 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00005175 }
5176 break;
5177
mistachkin1fe36bb2016-04-04 02:16:44 +00005178 case SQLITE_TESTCTRL_BITVEC_TEST:
5179 case SQLITE_TESTCTRL_FAULT_INSTALL:
5180 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
5181 case SQLITE_TESTCTRL_SCRATCHMALLOC:
shaneh96887e12011-02-10 21:08:58 +00005182 default:
mistachkinaae280e2015-12-31 19:06:24 +00005183 utf8_printf(stderr,
5184 "Error: CLI support for testctrl %s not implemented\n",
5185 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00005186 break;
5187 }
5188 }
5189 }else
5190
drhc2ce0be2014-05-29 12:36:14 +00005191 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00005192 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00005193 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00005194 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00005195
drhc2ce0be2014-05-29 12:36:14 +00005196 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
5197 if( nArg==2 ){
5198 enableTimer = booleanValue(azArg[1]);
5199 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00005200 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00005201 enableTimer = 0;
5202 }
5203 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005204 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00005205 rc = 1;
5206 }
shanehe2aa9d72009-11-06 17:20:17 +00005207 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00005208
drhc2ce0be2014-05-29 12:36:14 +00005209 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00005210 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00005211 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00005212 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00005213 rc = 1;
5214 goto meta_command_exit;
5215 }
drh657b4a82015-03-19 13:30:41 +00005216 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00005217 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00005218#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00005219 if( p->traceOut==0 ){
drh4b363a52016-07-23 20:27:41 +00005220 sqlite3_trace_v2(p->db, 0, 0, 0);
drh42f64e52012-04-04 16:56:23 +00005221 }else{
drh4b363a52016-07-23 20:27:41 +00005222 sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
drh42f64e52012-04-04 16:56:23 +00005223 }
5224#endif
5225 }else
drhd12602a2016-12-07 15:49:02 +00005226#endif /* !defined(SQLITE_UNTESTABLE) */
drh42f64e52012-04-04 16:56:23 +00005227
drhf442e332014-09-10 19:01:14 +00005228#if SQLITE_USER_AUTHENTICATION
5229 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
5230 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00005231 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00005232 rc = 1;
5233 goto meta_command_exit;
5234 }
drh7883ecf2014-09-11 16:19:31 +00005235 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00005236 if( strcmp(azArg[1],"login")==0 ){
5237 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00005238 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00005239 rc = 1;
5240 goto meta_command_exit;
5241 }
drhd39c40f2014-09-11 00:27:53 +00005242 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
5243 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00005244 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005245 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00005246 rc = 1;
5247 }
5248 }else if( strcmp(azArg[1],"add")==0 ){
5249 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00005250 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00005251 rc = 1;
5252 goto meta_command_exit;
5253 }
drhd39c40f2014-09-11 00:27:53 +00005254 rc = sqlite3_user_add(p->db, azArg[2],
5255 azArg[3], (int)strlen(azArg[3]),
5256 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00005257 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005258 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00005259 rc = 1;
5260 }
5261 }else if( strcmp(azArg[1],"edit")==0 ){
5262 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00005263 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00005264 rc = 1;
5265 goto meta_command_exit;
5266 }
drhd39c40f2014-09-11 00:27:53 +00005267 rc = sqlite3_user_change(p->db, azArg[2],
5268 azArg[3], (int)strlen(azArg[3]),
5269 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00005270 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005271 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00005272 rc = 1;
5273 }
5274 }else if( strcmp(azArg[1],"delete")==0 ){
5275 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00005276 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00005277 rc = 1;
5278 goto meta_command_exit;
5279 }
5280 rc = sqlite3_user_delete(p->db, azArg[2]);
5281 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005282 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00005283 rc = 1;
5284 }
5285 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005286 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00005287 rc = 1;
5288 goto meta_command_exit;
mistachkin1fe36bb2016-04-04 02:16:44 +00005289 }
drhf442e332014-09-10 19:01:14 +00005290 }else
5291#endif /* SQLITE_USER_AUTHENTICATION */
5292
drh9fd301b2011-06-03 13:28:22 +00005293 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005294 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00005295 sqlite3_libversion(), sqlite3_sourceid());
5296 }else
5297
drh790f2872015-11-28 18:06:36 +00005298 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
5299 const char *zDbName = nArg==2 ? azArg[1] : "main";
5300 sqlite3_vfs *pVfs;
5301 if( p->db ){
5302 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
5303 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00005304 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
5305 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
5306 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
5307 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00005308 }
5309 }
5310 }else
5311
drhb19e7352016-01-12 19:37:20 +00005312 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
5313 sqlite3_vfs *pVfs;
5314 sqlite3_vfs *pCurrent = 0;
5315 if( p->db ){
5316 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
5317 }
5318 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
5319 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
5320 pVfs==pCurrent ? " <--- CURRENT" : "");
5321 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
5322 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
5323 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
5324 if( pVfs->pNext ){
5325 raw_printf(p->out, "-----------------------------------\n");
5326 }
5327 }
5328 }else
5329
drhde60fc22011-12-14 17:53:36 +00005330 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
5331 const char *zDbName = nArg==2 ? azArg[1] : "main";
5332 char *zVfsName = 0;
5333 if( p->db ){
5334 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
5335 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00005336 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00005337 sqlite3_free(zVfsName);
5338 }
5339 }
5340 }else
5341
drhcef4fc82012-09-21 22:50:45 +00005342#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
5343 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
drhc2ce0be2014-05-29 12:36:14 +00005344 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00005345 }else
5346#endif
5347
drhc2ce0be2014-05-29 12:36:14 +00005348 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00005349 int j;
drh43617e92006-03-06 20:55:46 +00005350 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00005351 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00005352 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00005353 }
5354 }else
5355
5356 {
mistachkinaae280e2015-12-31 19:06:24 +00005357 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00005358 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00005359 rc = 1;
drh75897232000-05-29 14:26:00 +00005360 }
drh67505e72002-04-19 12:34:06 +00005361
drhc2ce0be2014-05-29 12:36:14 +00005362meta_command_exit:
5363 if( p->outCount ){
5364 p->outCount--;
5365 if( p->outCount==0 ) output_reset(p);
5366 }
drh67505e72002-04-19 12:34:06 +00005367 return rc;
drh75897232000-05-29 14:26:00 +00005368}
5369
drh67505e72002-04-19 12:34:06 +00005370/*
drh91a66392007-09-07 01:12:32 +00005371** Return TRUE if a semicolon occurs anywhere in the first N characters
5372** of string z[].
drh324ccef2003-02-05 14:06:20 +00005373*/
drh9f099fd2013-08-06 14:01:46 +00005374static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00005375 int i;
5376 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
5377 return 0;
drh324ccef2003-02-05 14:06:20 +00005378}
5379
5380/*
drh70c7a4b2003-04-26 03:03:06 +00005381** Test to see if a line consists entirely of whitespace.
5382*/
5383static int _all_whitespace(const char *z){
5384 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00005385 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00005386 if( *z=='/' && z[1]=='*' ){
5387 z += 2;
5388 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
5389 if( *z==0 ) return 0;
5390 z++;
5391 continue;
5392 }
5393 if( *z=='-' && z[1]=='-' ){
5394 z += 2;
5395 while( *z && *z!='\n' ){ z++; }
5396 if( *z==0 ) return 1;
5397 continue;
5398 }
5399 return 0;
5400 }
5401 return 1;
5402}
5403
5404/*
drha9b17162003-04-29 18:01:28 +00005405** Return TRUE if the line typed in is an SQL command terminator other
5406** than a semi-colon. The SQL Server style "go" command is understood
5407** as is the Oracle "/".
5408*/
drh9f099fd2013-08-06 14:01:46 +00005409static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00005410 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00005411 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
5412 return 1; /* Oracle */
5413 }
drhf0693c82011-10-11 20:41:54 +00005414 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00005415 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00005416 return 1; /* SQL Server */
5417 }
5418 return 0;
5419}
5420
5421/*
drh233a5312008-12-18 22:25:13 +00005422** Return true if zSql is a complete SQL statement. Return false if it
5423** ends in the middle of a string literal or C-style comment.
5424*/
drh9f099fd2013-08-06 14:01:46 +00005425static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00005426 int rc;
5427 if( zSql==0 ) return 1;
5428 zSql[nSql] = ';';
5429 zSql[nSql+1] = 0;
5430 rc = sqlite3_complete(zSql);
5431 zSql[nSql] = 0;
5432 return rc;
5433}
5434
5435/*
drh4e8142c2016-11-11 14:54:22 +00005436** Run a single line of SQL
5437*/
5438static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
5439 int rc;
5440 char *zErrMsg = 0;
5441
5442 open_db(p, 0);
5443 if( p->backslashOn ) resolve_backslashes(zSql);
5444 BEGIN_TIMER;
5445 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
5446 END_TIMER;
5447 if( rc || zErrMsg ){
5448 char zPrefix[100];
5449 if( in!=0 || !stdin_is_interactive ){
5450 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
5451 "Error: near line %d:", startline);
5452 }else{
5453 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
5454 }
5455 if( zErrMsg!=0 ){
5456 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
5457 sqlite3_free(zErrMsg);
5458 zErrMsg = 0;
5459 }else{
5460 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
5461 }
5462 return 1;
5463 }else if( p->countChanges ){
5464 raw_printf(p->out, "changes: %3d total_changes: %d\n",
5465 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
5466 }
5467 return 0;
5468}
5469
5470
5471/*
drh67505e72002-04-19 12:34:06 +00005472** Read input from *in and process it. If *in==0 then input
5473** is interactive - the user is typing it it. Otherwise, input
5474** is coming from a file or device. A prompt is issued and history
5475** is saved only if input is interactive. An interrupt signal will
5476** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00005477**
5478** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00005479*/
drhdcd87a92014-08-18 13:45:42 +00005480static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00005481 char *zLine = 0; /* A single input line */
5482 char *zSql = 0; /* Accumulated SQL text */
5483 int nLine; /* Length of current line */
5484 int nSql = 0; /* Bytes of zSql[] used */
5485 int nAlloc = 0; /* Allocated zSql[] space */
5486 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
drh9f099fd2013-08-06 14:01:46 +00005487 int rc; /* Error code */
5488 int errCnt = 0; /* Number of errors seen */
5489 int lineno = 0; /* Current line number */
5490 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00005491
5492 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
5493 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00005494 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00005495 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00005496 /* End of input */
drhfc8b40f2016-09-07 10:10:18 +00005497 if( in==0 && stdin_is_interactive ) printf("\n");
drh9b8d3572012-04-21 11:33:39 +00005498 break;
drhc49f44e2006-10-26 18:15:42 +00005499 }
drh67505e72002-04-19 12:34:06 +00005500 if( seenInterrupt ){
5501 if( in!=0 ) break;
5502 seenInterrupt = 0;
5503 }
drhc28490c2006-10-26 14:25:58 +00005504 lineno++;
drh849a9d92013-12-21 15:46:06 +00005505 if( nSql==0 && _all_whitespace(zLine) ){
5506 if( p->echoOn ) printf("%s\n", zLine);
5507 continue;
5508 }
drh2af0b2d2002-02-21 02:25:02 +00005509 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00005510 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00005511 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00005512 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00005513 break;
5514 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00005515 errCnt++;
5516 }
drhdaffd0e2001-04-11 14:28:42 +00005517 continue;
5518 }
drh9f099fd2013-08-06 14:01:46 +00005519 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00005520 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00005521 }
drh9f099fd2013-08-06 14:01:46 +00005522 nLine = strlen30(zLine);
5523 if( nSql+nLine+2>=nAlloc ){
5524 nAlloc = nSql+nLine+100;
5525 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00005526 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005527 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00005528 exit(1);
5529 }
drhdaffd0e2001-04-11 14:28:42 +00005530 }
drh9f099fd2013-08-06 14:01:46 +00005531 nSqlPrior = nSql;
5532 if( nSql==0 ){
5533 int i;
5534 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00005535 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00005536 memcpy(zSql, zLine+i, nLine+1-i);
5537 startline = lineno;
5538 nSql = nLine-i;
5539 }else{
5540 zSql[nSql++] = '\n';
5541 memcpy(zSql+nSql, zLine, nLine+1);
5542 nSql += nLine;
5543 }
5544 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00005545 && sqlite3_complete(zSql) ){
drh4e8142c2016-11-11 14:54:22 +00005546 errCnt += runOneSqlLine(p, zSql, in, startline);
drhdaffd0e2001-04-11 14:28:42 +00005547 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00005548 if( p->outCount ){
5549 output_reset(p);
5550 p->outCount = 0;
5551 }
drh9f099fd2013-08-06 14:01:46 +00005552 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00005553 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00005554 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00005555 }
5556 }
drh4e8142c2016-11-11 14:54:22 +00005557 if( nSql && !_all_whitespace(zSql) ){
5558 runOneSqlLine(p, zSql, in, startline);
drhdaffd0e2001-04-11 14:28:42 +00005559 }
drh1f9ca2c2015-08-25 16:57:52 +00005560 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00005561 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00005562 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00005563}
5564
drh67505e72002-04-19 12:34:06 +00005565/*
5566** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00005567** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00005568*/
drhd1459152016-09-16 19:11:03 +00005569static char *find_home_dir(int clearFlag){
drh85e72432012-04-11 11:38:53 +00005570 static char *home_dir = NULL;
drhd1459152016-09-16 19:11:03 +00005571 if( clearFlag ){
5572 free(home_dir);
5573 home_dir = 0;
5574 return 0;
5575 }
drh85e72432012-04-11 11:38:53 +00005576 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00005577
drh4ace5362014-11-10 14:42:28 +00005578#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
5579 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00005580 {
5581 struct passwd *pwent;
5582 uid_t uid = getuid();
5583 if( (pwent=getpwuid(uid)) != NULL) {
5584 home_dir = pwent->pw_dir;
5585 }
drh67505e72002-04-19 12:34:06 +00005586 }
5587#endif
5588
chw65d3c132007-11-12 21:09:10 +00005589#if defined(_WIN32_WCE)
5590 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
5591 */
drh85e72432012-04-11 11:38:53 +00005592 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00005593#else
5594
drh83905c92012-06-21 13:00:37 +00005595#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00005596 if (!home_dir) {
5597 home_dir = getenv("USERPROFILE");
5598 }
5599#endif
5600
drh67505e72002-04-19 12:34:06 +00005601 if (!home_dir) {
5602 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00005603 }
5604
drh83905c92012-06-21 13:00:37 +00005605#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00005606 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00005607 char *zDrive, *zPath;
5608 int n;
5609 zDrive = getenv("HOMEDRIVE");
5610 zPath = getenv("HOMEPATH");
5611 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00005612 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00005613 home_dir = malloc( n );
5614 if( home_dir==0 ) return 0;
5615 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
5616 return home_dir;
5617 }
5618 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00005619 }
5620#endif
5621
chw65d3c132007-11-12 21:09:10 +00005622#endif /* !_WIN32_WCE */
5623
drh67505e72002-04-19 12:34:06 +00005624 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00005625 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00005626 char *z = malloc( n );
5627 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00005628 home_dir = z;
5629 }
drhe98d4fa2002-04-21 19:06:22 +00005630
drh67505e72002-04-19 12:34:06 +00005631 return home_dir;
5632}
5633
5634/*
5635** Read input from the file given by sqliterc_override. Or if that
5636** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00005637**
5638** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00005639*/
drh534f4df2015-02-28 14:03:35 +00005640static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00005641 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00005642 const char *sqliterc_override /* Name of config file. NULL to use default */
5643){
persicom7e2dfdd2002-04-18 02:46:52 +00005644 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00005645 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00005646 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00005647 FILE *in = NULL;
5648
5649 if (sqliterc == NULL) {
drhd1459152016-09-16 19:11:03 +00005650 home_dir = find_home_dir(0);
drhe98d4fa2002-04-21 19:06:22 +00005651 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005652 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00005653 " cannot read ~/.sqliterc\n");
5654 return;
drhe98d4fa2002-04-21 19:06:22 +00005655 }
drh2f3de322012-06-27 16:41:31 +00005656 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00005657 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
5658 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00005659 }
drha1f9b5e2004-02-14 16:31:02 +00005660 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00005661 if( in ){
drhc28490c2006-10-26 14:25:58 +00005662 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00005663 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00005664 }
drh534f4df2015-02-28 14:03:35 +00005665 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00005666 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00005667 }
drh85e72432012-04-11 11:38:53 +00005668 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00005669}
5670
drh67505e72002-04-19 12:34:06 +00005671/*
drhe1e38c42003-05-04 18:30:59 +00005672** Show available command line options
5673*/
mistachkin1fe36bb2016-04-04 02:16:44 +00005674static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00005675 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00005676 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00005677 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005678 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00005679 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00005680 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00005681 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00005682 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00005683 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00005684#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
5685 " -heap SIZE Size of heap for memsys3 or memsys5\n"
5686#endif
drhcc3b4f82012-02-07 14:13:50 +00005687 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00005688 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00005689 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005690 " -line set output mode to 'line'\n"
5691 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00005692 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00005693 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00005694#ifdef SQLITE_ENABLE_MULTIPLEX
5695 " -multiplex enable the multiplexor VFS\n"
5696#endif
mistachkine0d68852014-12-11 03:12:33 +00005697 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00005698 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00005699 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
5700 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00005701 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00005702 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00005703 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00005704 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00005705#ifdef SQLITE_ENABLE_VFSTRACE
5706 " -vfstrace enable tracing of all VFS calls\n"
5707#endif
drhe1e38c42003-05-04 18:30:59 +00005708;
5709static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00005710 utf8_printf(stderr,
mistachkin1fe36bb2016-04-04 02:16:44 +00005711 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
drh80e8be92006-08-29 12:04:19 +00005712 "FILENAME is the name of an SQLite database. A new database is created\n"
5713 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00005714 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00005715 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00005716 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005717 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00005718 }
5719 exit(1);
5720}
5721
5722/*
drh67505e72002-04-19 12:34:06 +00005723** Initialize the state information in data
5724*/
drhdcd87a92014-08-18 13:45:42 +00005725static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00005726 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00005727 data->normalMode = data->cMode = data->mode = MODE_List;
5728 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00005729 memcpy(data->colSeparator,SEP_Column, 2);
5730 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00005731 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00005732 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00005733 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00005734 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00005735 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00005736 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
5737 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00005738}
5739
drh98d312f2012-10-25 15:23:14 +00005740/*
drh5c7976f2014-02-10 19:59:27 +00005741** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00005742*/
5743#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00005744static void printBold(const char *zText){
5745 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
5746 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
5747 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
5748 SetConsoleTextAttribute(out,
5749 FOREGROUND_RED|FOREGROUND_INTENSITY
5750 );
5751 printf("%s", zText);
5752 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00005753}
5754#else
drh5c7976f2014-02-10 19:59:27 +00005755static void printBold(const char *zText){
5756 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00005757}
5758#endif
5759
5760/*
drh98d312f2012-10-25 15:23:14 +00005761** Get the argument to an --option. Throw an error and die if no argument
5762** is available.
5763*/
5764static char *cmdline_option_value(int argc, char **argv, int i){
5765 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00005766 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00005767 argv[0], argv[argc-1]);
5768 exit(1);
5769 }
5770 return argv[i];
5771}
5772
mistachkin1fe36bb2016-04-04 02:16:44 +00005773#ifndef SQLITE_SHELL_IS_UTF8
5774# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
5775# define SQLITE_SHELL_IS_UTF8 (0)
5776# else
5777# define SQLITE_SHELL_IS_UTF8 (1)
5778# endif
5779#endif
5780
5781#if SQLITE_SHELL_IS_UTF8
mistachkin44723ce2015-03-21 02:22:37 +00005782int SQLITE_CDECL main(int argc, char **argv){
mistachkin1fe36bb2016-04-04 02:16:44 +00005783#else
5784int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
mistachkin1810f222016-04-04 02:33:34 +00005785 char **argv;
mistachkin1fe36bb2016-04-04 02:16:44 +00005786#endif
drh75897232000-05-29 14:26:00 +00005787 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00005788 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00005789 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00005790 int i;
drhc28490c2006-10-26 14:25:58 +00005791 int rc = 0;
drhb3735912014-02-10 16:13:42 +00005792 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00005793 int readStdin = 1;
5794 int nCmd = 0;
5795 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00005796
mistachkin1fe36bb2016-04-04 02:16:44 +00005797 setBinaryMode(stdin, 0);
5798 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
mistachkin1810f222016-04-04 02:33:34 +00005799 stdin_is_interactive = isatty(0);
5800 stdout_is_console = isatty(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005801
drh69b30ab2014-02-27 15:11:52 +00005802#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00005803 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005804 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00005805 sqlite3_sourceid(), SQLITE_SOURCE_ID);
5806 exit(1);
5807 }
drhc7181902014-02-27 15:04:13 +00005808#endif
persicom7e2dfdd2002-04-18 02:46:52 +00005809 main_init(&data);
mistachkin1fe36bb2016-04-04 02:16:44 +00005810#if !SQLITE_SHELL_IS_UTF8
5811 sqlite3_initialize();
5812 argv = sqlite3_malloc64(sizeof(argv[0])*argc);
5813 if( argv==0 ){
5814 raw_printf(stderr, "out of memory\n");
5815 exit(1);
5816 }
5817 for(i=0; i<argc; i++){
5818 argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
5819 if( argv[i]==0 ){
5820 raw_printf(stderr, "out of memory\n");
5821 exit(1);
5822 }
5823 }
5824#endif
mistachkin1810f222016-04-04 02:33:34 +00005825 assert( argc>=1 && argv && argv[0] );
mistachkin1fe36bb2016-04-04 02:16:44 +00005826 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00005827
drh44c2eb12003-04-30 11:38:26 +00005828 /* Make sure we have a valid signal handler early, before anything
5829 ** else is done.
5830 */
drh4c504392000-10-16 22:06:40 +00005831#ifdef SIGINT
5832 signal(SIGINT, interrupt_handler);
5833#endif
drh44c2eb12003-04-30 11:38:26 +00005834
drhac5649a2014-11-28 13:35:03 +00005835#ifdef SQLITE_SHELL_DBNAME_PROC
5836 {
5837 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
5838 ** of a C-function that will provide the name of the database file. Use
5839 ** this compile-time option to embed this shell program in larger
5840 ** applications. */
5841 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
5842 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
5843 warnInmemoryDb = 0;
5844 }
5845#endif
5846
drh22fbcb82004-02-01 01:22:50 +00005847 /* Do an initial pass through the command-line argument to locate
5848 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00005849 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00005850 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00005851 */
drh98d312f2012-10-25 15:23:14 +00005852 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00005853 char *z;
drhc28490c2006-10-26 14:25:58 +00005854 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005855 if( z[0]!='-' ){
5856 if( data.zDbFilename==0 ){
5857 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00005858 }else{
5859 /* Excesss arguments are interpreted as SQL (or dot-commands) and
5860 ** mean that nothing is read from stdin */
5861 readStdin = 0;
5862 nCmd++;
5863 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
5864 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005865 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00005866 exit(1);
5867 }
5868 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00005869 }
drh98d312f2012-10-25 15:23:14 +00005870 }
drhcc3b4f82012-02-07 14:13:50 +00005871 if( z[1]=='-' ) z++;
5872 if( strcmp(z,"-separator")==0
5873 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00005874 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00005875 || strcmp(z,"-cmd")==0
5876 ){
drh98d312f2012-10-25 15:23:14 +00005877 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005878 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00005879 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005880 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00005881 /* Need to check for batch mode here to so we can avoid printing
mistachkin1fe36bb2016-04-04 02:16:44 +00005882 ** informational messages (like from process_sqliterc) before
drh98d312f2012-10-25 15:23:14 +00005883 ** we do the actual processing of arguments later in a second pass.
5884 */
shanef69573d2009-10-24 02:06:14 +00005885 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00005886 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00005887#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00005888 const char *zSize;
5889 sqlite3_int64 szHeap;
5890
drh98d312f2012-10-25 15:23:14 +00005891 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00005892 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00005893 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00005894 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
drhc530b9c2016-07-25 11:27:22 +00005895#else
5896 (void)cmdline_option_value(argc, argv, ++i);
drh9c88d682010-12-17 14:03:01 +00005897#endif
drh44dec872014-08-30 15:49:25 +00005898 }else if( strcmp(z,"-scratch")==0 ){
5899 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005900 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005901 if( sz>400000 ) sz = 400000;
5902 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00005903 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005904 if( n>10 ) n = 10;
5905 if( n<1 ) n = 1;
5906 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
5907 data.shellFlgs |= SHFLG_Scratch;
5908 }else if( strcmp(z,"-pagecache")==0 ){
5909 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005910 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005911 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00005912 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005913 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00005914 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
5915 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00005916 data.shellFlgs |= SHFLG_Pagecache;
5917 }else if( strcmp(z,"-lookaside")==0 ){
5918 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005919 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005920 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005921 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005922 if( n<0 ) n = 0;
5923 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
5924 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00005925#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00005926 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00005927 extern int vfstrace_register(
5928 const char *zTraceName,
5929 const char *zOldVfsName,
5930 int (*xOut)(const char*,void*),
5931 void *pOutArg,
5932 int makeDefault
5933 );
drh2b625e22011-03-16 17:05:28 +00005934 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00005935#endif
drh6f25e892011-07-08 17:02:57 +00005936#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00005937 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00005938 extern int sqlite3_multiple_initialize(const char*,int);
5939 sqlite3_multiplex_initialize(0, 1);
5940#endif
drh7d9f3942013-04-03 01:26:54 +00005941 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00005942 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
5943 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00005944 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00005945 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00005946 if( pVfs ){
5947 sqlite3_vfs_register(pVfs, 1);
5948 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005949 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00005950 exit(1);
5951 }
drh44c2eb12003-04-30 11:38:26 +00005952 }
5953 }
drh98d312f2012-10-25 15:23:14 +00005954 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00005955#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00005956 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00005957 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00005958#else
mistachkinaae280e2015-12-31 19:06:24 +00005959 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00005960 return 1;
drh01b41712005-08-29 23:06:23 +00005961#endif
drh98d312f2012-10-25 15:23:14 +00005962 }
5963 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00005964
drh44c2eb12003-04-30 11:38:26 +00005965 /* Go ahead and open the database file if it already exists. If the
5966 ** file does not exist, delay opening it. This prevents empty database
5967 ** files from being created if a user mistypes the database name argument
5968 ** to the sqlite command-line tool.
5969 */
drhc8d74412004-08-31 23:41:26 +00005970 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00005971 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00005972 }
5973
drh22fbcb82004-02-01 01:22:50 +00005974 /* Process the initialization file if there is one. If no -init option
5975 ** is given on the command line, look for a file named ~/.sqliterc and
5976 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00005977 */
drh534f4df2015-02-28 14:03:35 +00005978 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00005979
drh22fbcb82004-02-01 01:22:50 +00005980 /* Make a second pass through the command-line argument and set
5981 ** options. This second pass is delayed until after the initialization
5982 ** file is processed so that the command-line arguments will override
5983 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00005984 */
drh98d312f2012-10-25 15:23:14 +00005985 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00005986 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005987 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00005988 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00005989 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00005990 i++;
5991 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005992 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00005993 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005994 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00005995 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005996 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00005997 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00005998 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00005999 }else if( strcmp(z,"-csv")==0 ){
6000 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00006001 memcpy(data.colSeparator,",",2);
6002 }else if( strcmp(z,"-ascii")==0 ){
6003 data.mode = MODE_Ascii;
6004 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00006005 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00006006 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00006007 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00006008 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00006009 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00006010 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00006011 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00006012 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00006013 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00006014 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00006015 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00006016 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00006017 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00006018 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00006019 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00006020 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00006021 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00006022 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00006023 }else if( strcmp(z,"-eqp")==0 ){
6024 data.autoEQP = 1;
drheacd29d2016-04-15 15:03:27 +00006025 }else if( strcmp(z,"-eqpfull")==0 ){
6026 data.autoEQP = 2;
shaneh642d8b82010-07-28 16:05:34 +00006027 }else if( strcmp(z,"-stats")==0 ){
6028 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00006029 }else if( strcmp(z,"-scanstats")==0 ){
6030 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00006031 }else if( strcmp(z,"-backslash")==0 ){
6032 /* Undocumented command-line option: -backslash
6033 ** Causes C-style backslash escapes to be evaluated in SQL statements
6034 ** prior to sending the SQL into SQLite. Useful for injecting
6035 ** crazy bytes in the middle of SQL statements for testing and debugging.
6036 */
6037 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00006038 }else if( strcmp(z,"-bail")==0 ){
6039 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00006040 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00006041 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00006042 return 0;
drhc28490c2006-10-26 14:25:58 +00006043 }else if( strcmp(z,"-interactive")==0 ){
6044 stdin_is_interactive = 1;
6045 }else if( strcmp(z,"-batch")==0 ){
6046 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00006047 }else if( strcmp(z,"-heap")==0 ){
6048 i++;
drh44dec872014-08-30 15:49:25 +00006049 }else if( strcmp(z,"-scratch")==0 ){
6050 i+=2;
6051 }else if( strcmp(z,"-pagecache")==0 ){
6052 i+=2;
6053 }else if( strcmp(z,"-lookaside")==0 ){
6054 i+=2;
drh7d9f3942013-04-03 01:26:54 +00006055 }else if( strcmp(z,"-mmap")==0 ){
6056 i++;
drha7e61d82011-03-12 17:02:57 +00006057 }else if( strcmp(z,"-vfs")==0 ){
6058 i++;
drh6f25e892011-07-08 17:02:57 +00006059#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00006060 }else if( strcmp(z,"-vfstrace")==0 ){
6061 i++;
drh6f25e892011-07-08 17:02:57 +00006062#endif
6063#ifdef SQLITE_ENABLE_MULTIPLEX
6064 }else if( strcmp(z,"-multiplex")==0 ){
6065 i++;
6066#endif
drhcc3b4f82012-02-07 14:13:50 +00006067 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00006068 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00006069 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00006070 /* Run commands that follow -cmd first and separately from commands
6071 ** that simply appear on the command-line. This seems goofy. It would
6072 ** be better if all commands ran in the order that they appear. But
6073 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00006074 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00006075 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00006076 if( z[0]=='.' ){
6077 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00006078 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00006079 }else{
drh05782482013-10-24 15:20:20 +00006080 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00006081 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
6082 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00006083 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00006084 if( bail_on_error ) return rc!=0 ? rc : 1;
6085 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00006086 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00006087 if( bail_on_error ) return rc;
6088 }
6089 }
drh1e5d0e92000-05-31 23:33:17 +00006090 }else{
mistachkinaae280e2015-12-31 19:06:24 +00006091 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
6092 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00006093 return 1;
6094 }
drh700c2522016-02-09 18:39:25 +00006095 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00006096 }
drh44c2eb12003-04-30 11:38:26 +00006097
drhac5649a2014-11-28 13:35:03 +00006098 if( !readStdin ){
6099 /* Run all arguments that do not begin with '-' as if they were separate
6100 ** command-line inputs, except for the argToSkip argument which contains
6101 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00006102 */
drhac5649a2014-11-28 13:35:03 +00006103 for(i=0; i<nCmd; i++){
6104 if( azCmd[i][0]=='.' ){
6105 rc = do_meta_command(azCmd[i], &data);
6106 if( rc ) return rc==2 ? 0 : rc;
6107 }else{
6108 open_db(&data, 0);
6109 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
6110 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00006111 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00006112 return rc!=0 ? rc : 1;
6113 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00006114 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00006115 return rc;
6116 }
drh6ff13852001-11-25 13:18:23 +00006117 }
drh75897232000-05-29 14:26:00 +00006118 }
drhac5649a2014-11-28 13:35:03 +00006119 free(azCmd);
drh75897232000-05-29 14:26:00 +00006120 }else{
drh44c2eb12003-04-30 11:38:26 +00006121 /* Run commands received from standard input
6122 */
drhc28490c2006-10-26 14:25:58 +00006123 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00006124 char *zHome;
6125 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00006126 int nHistory;
drh75897232000-05-29 14:26:00 +00006127 printf(
drh743e0032011-12-12 16:51:50 +00006128 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00006129 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00006130 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00006131 );
drhb3735912014-02-10 16:13:42 +00006132 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00006133 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00006134 printBold("transient in-memory database");
6135 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00006136 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00006137 }
drhd1459152016-09-16 19:11:03 +00006138 zHome = find_home_dir(0);
drhea678832008-12-10 19:26:22 +00006139 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00006140 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00006141 if( (zHistory = malloc(nHistory))!=0 ){
6142 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
6143 }
drh67505e72002-04-19 12:34:06 +00006144 }
drhf5ed7ad2015-06-15 14:43:25 +00006145 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00006146 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00006147 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00006148 shell_stifle_history(100);
6149 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00006150 free(zHistory);
drh67505e72002-04-19 12:34:06 +00006151 }
drhdaffd0e2001-04-11 14:28:42 +00006152 }else{
drhc28490c2006-10-26 14:25:58 +00006153 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00006154 }
6155 }
drh33048c02001-10-01 14:29:22 +00006156 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00006157 if( data.db ){
drhe6229612014-08-18 15:08:26 +00006158 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00006159 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00006160 }
mistachkin1fe36bb2016-04-04 02:16:44 +00006161 sqlite3_free(data.zFreeOnClose);
drhd1459152016-09-16 19:11:03 +00006162 find_home_dir(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00006163#if !SQLITE_SHELL_IS_UTF8
6164 for(i=0; i<argc; i++) sqlite3_free(argv[i]);
6165 sqlite3_free(argv);
6166#endif
drhc28490c2006-10-26 14:25:58 +00006167 return rc;
drh75897232000-05-29 14:26:00 +00006168}