blob: 374755fcc5477bb47b1ac84587ebc064fbe1f2cf [file] [log] [blame]
drh75897232000-05-29 14:26:00 +00001/*
drhb19a2bc2001-09-16 00:13:26 +00002** 2001 September 15
drh75897232000-05-29 14:26:00 +00003**
drhb19a2bc2001-09-16 00:13:26 +00004** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
drh75897232000-05-29 14:26:00 +00006**
drhb19a2bc2001-09-16 00:13:26 +00007** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
drh75897232000-05-29 14:26:00 +000010**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
drh75897232000-05-29 14:26:00 +000014*/
mistachkina3b2ff52011-09-16 20:16:36 +000015#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
shane18e526c2008-12-10 22:30:24 +000016/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
drh36f7dd32011-10-13 16:02:17 +000020/*
mistachkin2318d332015-01-12 18:02:52 +000021** If requested, include the SQLite compiler options file for MSVC.
22*/
23#if defined(INCLUDE_MSVC_H)
24#include "msvc.h"
25#endif
26
27/*
drh8cd5b252015-03-02 22:06:43 +000028** No support for loadable extensions in VxWorks.
29*/
drhada3f2b2015-03-23 21:32:50 +000030#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
drh8cd5b252015-03-02 22:06:43 +000031# define SQLITE_OMIT_LOAD_EXTENSION 1
32#endif
33
34/*
drh36f7dd32011-10-13 16:02:17 +000035** Enable large-file support for fopen() and friends on unix.
36*/
37#ifndef SQLITE_DISABLE_LFS
38# define _LARGE_FILE 1
39# ifndef _FILE_OFFSET_BITS
40# define _FILE_OFFSET_BITS 64
41# endif
42# define _LARGEFILE_SOURCE 1
43#endif
44
drh75897232000-05-29 14:26:00 +000045#include <stdlib.h>
46#include <string.h>
47#include <stdio.h>
danielk19772a02e332004-06-05 08:04:36 +000048#include <assert.h>
drh1d482dd2004-05-31 18:23:07 +000049#include "sqlite3.h"
drhf442e332014-09-10 19:01:14 +000050#if SQLITE_USER_AUTHENTICATION
51# include "sqlite3userauth.h"
52#endif
drh75897232000-05-29 14:26:00 +000053#include <ctype.h>
drhb0603412007-02-28 04:47:26 +000054#include <stdarg.h>
persicom7e2dfdd2002-04-18 02:46:52 +000055
drh83905c92012-06-21 13:00:37 +000056#if !defined(_WIN32) && !defined(WIN32)
drh4c504392000-10-16 22:06:40 +000057# include <signal.h>
chw97185482008-11-17 08:05:31 +000058# if !defined(__RTP__) && !defined(_WRS_KERNEL)
59# include <pwd.h>
60# endif
drhdd45df82002-04-18 12:39:03 +000061# include <unistd.h>
62# include <sys/types.h>
drh4c504392000-10-16 22:06:40 +000063#endif
drh75897232000-05-29 14:26:00 +000064
drh0ede9eb2015-01-10 16:49:23 +000065#if HAVE_READLINE
drh8e7e7a22000-05-30 18:45:23 +000066# include <readline/readline.h>
67# include <readline/history.h>
drh81d7fd12010-12-08 00:02:26 +000068#endif
danfd34d6d2015-02-25 10:54:53 +000069
drh0ede9eb2015-01-10 16:49:23 +000070#if HAVE_EDITLINE
drhaaa21b42014-02-11 14:37:51 +000071# include <editline/readline.h>
72#endif
danfd34d6d2015-02-25 10:54:53 +000073
74#if HAVE_EDITLINE || HAVE_READLINE
75
76# define shell_add_history(X) add_history(X)
77# define shell_read_history(X) read_history(X)
78# define shell_write_history(X) write_history(X)
79# define shell_stifle_history(X) stifle_history(X)
80# define shell_readline(X) readline(X)
81
82#elif HAVE_LINENOISE
83
84# include "linenoise.h"
85# define shell_add_history(X) linenoiseHistoryAdd(X)
86# define shell_read_history(X) linenoiseHistoryLoad(X)
87# define shell_write_history(X) linenoiseHistorySave(X)
88# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
89# define shell_readline(X) linenoise(X)
90
91#else
92
mistachkin1fe36bb2016-04-04 02:16:44 +000093# define shell_read_history(X)
danfd34d6d2015-02-25 10:54:53 +000094# define shell_write_history(X)
95# define shell_stifle_history(X)
96
97# define SHELL_USE_LOCAL_GETLINE 1
drh75897232000-05-29 14:26:00 +000098#endif
99
danfd34d6d2015-02-25 10:54:53 +0000100
adamd2e8464a2006-09-06 21:39:40 +0000101#if defined(_WIN32) || defined(WIN32)
102# include <io.h>
drh6976c212014-07-24 12:09:47 +0000103# include <fcntl.h>
mistachkin073664d2015-06-17 18:57:37 +0000104# define isatty(h) _isatty(h)
105# ifndef access
106# define access(f,m) _access((f),(m))
107# endif
108# undef popen
109# define popen _popen
110# undef pclose
111# define pclose _pclose
adamd2e8464a2006-09-06 21:39:40 +0000112#else
mistachkin073664d2015-06-17 18:57:37 +0000113 /* Make sure isatty() has a prototype. */
114 extern int isatty(int);
drh4328c8b2003-04-26 02:50:11 +0000115
mistachkin073664d2015-06-17 18:57:37 +0000116# if !defined(__RTP__) && !defined(_WRS_KERNEL)
117 /* popen and pclose are not C89 functions and so are
118 ** sometimes omitted from the <stdio.h> header */
119 extern FILE *popen(const char*,const char*);
120 extern int pclose(FILE*);
121# else
122# define SQLITE_OMIT_POPEN 1
123# endif
mistachkinf6418892013-08-28 01:54:12 +0000124#endif
drh53371f92013-07-25 17:07:03 +0000125
chw65d3c132007-11-12 21:09:10 +0000126#if defined(_WIN32_WCE)
127/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
128 * thus we always assume that we have a console. That can be
129 * overridden with the -batch command line option.
130 */
131#define isatty(x) 1
132#endif
133
drhf0693c82011-10-11 20:41:54 +0000134/* ctype macros that work with signed characters */
135#define IsSpace(X) isspace((unsigned char)X)
136#define IsDigit(X) isdigit((unsigned char)X)
137#define ToLower(X) (char)tolower((unsigned char)X)
138
mistachkin1fe36bb2016-04-04 02:16:44 +0000139#if defined(_WIN32) || defined(WIN32)
140#include <windows.h>
141
142/* string conversion routines only needed on Win32 */
143extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
144extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
145extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
mistachkin8145fc62016-09-16 20:39:21 +0000146extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
mistachkin1fe36bb2016-04-04 02:16:44 +0000147#endif
148
drh047d4532015-01-18 20:30:23 +0000149/* On Windows, we normally run with output mode of TEXT so that \n characters
150** are automatically translated into \r\n. However, this behavior needs
151** to be disabled in some cases (ex: when generating CSV output and when
152** rendering quoted strings that contain \n characters). The following
153** routines take care of that.
154*/
155#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000156static void setBinaryMode(FILE *file, int isOutput){
157 if( isOutput ) fflush(file);
158 _setmode(_fileno(file), _O_BINARY);
drh047d4532015-01-18 20:30:23 +0000159}
mistachkin1fe36bb2016-04-04 02:16:44 +0000160static void setTextMode(FILE *file, int isOutput){
161 if( isOutput ) fflush(file);
162 _setmode(_fileno(file), _O_TEXT);
drh047d4532015-01-18 20:30:23 +0000163}
164#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000165# define setBinaryMode(X,Y)
166# define setTextMode(X,Y)
drh047d4532015-01-18 20:30:23 +0000167#endif
168
drh43408312013-10-30 12:43:36 +0000169
170/* True if the timer is enabled */
171static int enableTimer = 0;
172
173/* Return the current wall-clock time */
174static sqlite3_int64 timeOfDay(void){
175 static sqlite3_vfs *clockVfs = 0;
176 sqlite3_int64 t;
177 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
dan3fd415b2015-11-16 08:54:10 +0000178 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
drh43408312013-10-30 12:43:36 +0000179 clockVfs->xCurrentTimeInt64(clockVfs, &t);
180 }else{
181 double r;
182 clockVfs->xCurrentTime(clockVfs, &r);
183 t = (sqlite3_int64)(r*86400000.0);
184 }
185 return t;
186}
187
drh91eb93c2015-03-03 19:56:20 +0000188#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
drh3b1a9882007-11-02 12:53:03 +0000189#include <sys/time.h>
190#include <sys/resource.h>
191
drh91eb93c2015-03-03 19:56:20 +0000192/* VxWorks does not support getrusage() as far as we can determine */
193#if defined(_WRS_KERNEL) || defined(__RTP__)
194struct rusage {
195 struct timeval ru_utime; /* user CPU time used */
196 struct timeval ru_stime; /* system CPU time used */
197};
198#define getrusage(A,B) memset(B,0,sizeof(*B))
199#endif
200
drhda108222009-02-25 19:07:24 +0000201/* Saved resource information for the beginning of an operation */
drh43408312013-10-30 12:43:36 +0000202static struct rusage sBegin; /* CPU time at start */
203static sqlite3_int64 iBegin; /* Wall-clock time at start */
drhda108222009-02-25 19:07:24 +0000204
drhda108222009-02-25 19:07:24 +0000205/*
206** Begin timing an operation
207*/
208static void beginTimer(void){
209 if( enableTimer ){
210 getrusage(RUSAGE_SELF, &sBegin);
drh43408312013-10-30 12:43:36 +0000211 iBegin = timeOfDay();
drhda108222009-02-25 19:07:24 +0000212 }
213}
214
215/* Return the difference of two time_structs in seconds */
216static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
mistachkin1fe36bb2016-04-04 02:16:44 +0000217 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
drhda108222009-02-25 19:07:24 +0000218 (double)(pEnd->tv_sec - pStart->tv_sec);
219}
220
221/*
222** Print the timing results.
223*/
224static void endTimer(void){
225 if( enableTimer ){
drh43408312013-10-30 12:43:36 +0000226 sqlite3_int64 iEnd = timeOfDay();
drh91eb93c2015-03-03 19:56:20 +0000227 struct rusage sEnd;
drhda108222009-02-25 19:07:24 +0000228 getrusage(RUSAGE_SELF, &sEnd);
drh43408312013-10-30 12:43:36 +0000229 printf("Run Time: real %.3f user %f sys %f\n",
230 (iEnd - iBegin)*0.001,
drhda108222009-02-25 19:07:24 +0000231 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
232 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
233 }
234}
shaneb320ccd2009-10-21 03:42:58 +0000235
drhda108222009-02-25 19:07:24 +0000236#define BEGIN_TIMER beginTimer()
237#define END_TIMER endTimer()
238#define HAS_TIMER 1
shaneb320ccd2009-10-21 03:42:58 +0000239
240#elif (defined(_WIN32) || defined(WIN32))
241
shaneb320ccd2009-10-21 03:42:58 +0000242/* Saved resource information for the beginning of an operation */
243static HANDLE hProcess;
244static FILETIME ftKernelBegin;
245static FILETIME ftUserBegin;
drh43408312013-10-30 12:43:36 +0000246static sqlite3_int64 ftWallBegin;
drh4ace5362014-11-10 14:42:28 +0000247typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
248 LPFILETIME, LPFILETIME);
shaneb320ccd2009-10-21 03:42:58 +0000249static GETPROCTIMES getProcessTimesAddr = NULL;
250
shaneb320ccd2009-10-21 03:42:58 +0000251/*
252** Check to see if we have timer support. Return 1 if necessary
253** support found (or found previously).
254*/
255static int hasTimer(void){
256 if( getProcessTimesAddr ){
257 return 1;
258 } else {
drh4ace5362014-11-10 14:42:28 +0000259 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
260 ** versions. See if the version we are running on has it, and if it
261 ** does, save off a pointer to it and the current process handle.
shaneb320ccd2009-10-21 03:42:58 +0000262 */
263 hProcess = GetCurrentProcess();
264 if( hProcess ){
265 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
266 if( NULL != hinstLib ){
drh4ace5362014-11-10 14:42:28 +0000267 getProcessTimesAddr =
268 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
shaneb320ccd2009-10-21 03:42:58 +0000269 if( NULL != getProcessTimesAddr ){
270 return 1;
271 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000272 FreeLibrary(hinstLib);
shaneb320ccd2009-10-21 03:42:58 +0000273 }
274 }
275 }
276 return 0;
277}
278
279/*
280** Begin timing an operation
281*/
282static void beginTimer(void){
283 if( enableTimer && getProcessTimesAddr ){
284 FILETIME ftCreation, ftExit;
drh4ace5362014-11-10 14:42:28 +0000285 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
286 &ftKernelBegin,&ftUserBegin);
drh43408312013-10-30 12:43:36 +0000287 ftWallBegin = timeOfDay();
shaneb320ccd2009-10-21 03:42:58 +0000288 }
289}
290
291/* Return the difference of two FILETIME structs in seconds */
292static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
293 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
294 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
295 return (double) ((i64End - i64Start) / 10000000.0);
296}
297
298/*
299** Print the timing results.
300*/
301static void endTimer(void){
302 if( enableTimer && getProcessTimesAddr){
303 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
drh43408312013-10-30 12:43:36 +0000304 sqlite3_int64 ftWallEnd = timeOfDay();
drh4ace5362014-11-10 14:42:28 +0000305 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
drh43408312013-10-30 12:43:36 +0000306 printf("Run Time: real %.3f user %f sys %f\n",
307 (ftWallEnd - ftWallBegin)*0.001,
shaneb320ccd2009-10-21 03:42:58 +0000308 timeDiff(&ftUserBegin, &ftUserEnd),
309 timeDiff(&ftKernelBegin, &ftKernelEnd));
310 }
311}
312
313#define BEGIN_TIMER beginTimer()
314#define END_TIMER endTimer()
315#define HAS_TIMER hasTimer()
316
drhda108222009-02-25 19:07:24 +0000317#else
mistachkin1fe36bb2016-04-04 02:16:44 +0000318#define BEGIN_TIMER
drhda108222009-02-25 19:07:24 +0000319#define END_TIMER
320#define HAS_TIMER 0
321#endif
322
shanec0688ea2009-03-05 03:48:06 +0000323/*
324** Used to prevent warnings about unused parameters
325*/
326#define UNUSED_PARAMETER(x) (void)(x)
327
drhe91d16b2008-12-08 18:27:31 +0000328/*
drhc49f44e2006-10-26 18:15:42 +0000329** If the following flag is set, then command execution stops
330** at an error if we are not interactive.
331*/
332static int bail_on_error = 0;
333
334/*
drhc28490c2006-10-26 14:25:58 +0000335** Threat stdin as an interactive input if the following variable
336** is true. Otherwise, assume stdin is connected to a file or pipe.
337*/
338static int stdin_is_interactive = 1;
339
340/*
drhe05461c2015-12-30 13:36:57 +0000341** On Windows systems we have to know if standard output is a console
342** in order to translate UTF-8 into MBCS. The following variable is
343** true if translation is required.
344*/
345static int stdout_is_console = 1;
346
347/*
drh4c504392000-10-16 22:06:40 +0000348** The following is the open SQLite database. We make a pointer
349** to this database a static variable so that it can be accessed
350** by the SIGINT handler to interrupt database processing.
351*/
mistachkin8e189222015-04-19 21:43:16 +0000352static sqlite3 *globalDb = 0;
drh4c504392000-10-16 22:06:40 +0000353
354/*
drh67505e72002-04-19 12:34:06 +0000355** True if an interrupt (Control-C) has been received.
356*/
drh43617e92006-03-06 20:55:46 +0000357static volatile int seenInterrupt = 0;
drh67505e72002-04-19 12:34:06 +0000358
359/*
persicom7e2dfdd2002-04-18 02:46:52 +0000360** This is the name of our program. It is set in main(), used
361** in a number of other places, mostly for error messages.
362*/
363static char *Argv0;
364
365/*
366** Prompt strings. Initialized in main. Settable with
367** .prompt main continue
368*/
369static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
370static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
371
drhb0603412007-02-28 04:47:26 +0000372/*
mistachkin710b33b2016-01-03 18:59:28 +0000373** Render output like fprintf(). Except, if the output is going to the
374** console and if this is running on a Windows machine, translate the
375** output from UTF-8 into MBCS.
376*/
377#if defined(_WIN32) || defined(WIN32)
378void utf8_printf(FILE *out, const char *zFormat, ...){
379 va_list ap;
380 va_start(ap, zFormat);
381 if( stdout_is_console && (out==stdout || out==stderr) ){
mistachkin710b33b2016-01-03 18:59:28 +0000382 char *z1 = sqlite3_vmprintf(zFormat, ap);
mistachkin1fe36bb2016-04-04 02:16:44 +0000383 char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
mistachkin710b33b2016-01-03 18:59:28 +0000384 sqlite3_free(z1);
385 fputs(z2, out);
386 sqlite3_free(z2);
387 }else{
388 vfprintf(out, zFormat, ap);
389 }
390 va_end(ap);
391}
392#elif !defined(utf8_printf)
393# define utf8_printf fprintf
394#endif
395
396/*
397** Render output like fprintf(). This should not be used on anything that
398** includes string formatting (e.g. "%s").
399*/
400#if !defined(raw_printf)
401# define raw_printf fprintf
402#endif
403
404/*
drhb0603412007-02-28 04:47:26 +0000405** Write I/O traces to the following stream.
406*/
rsebe0a9092007-07-30 18:24:38 +0000407#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +0000408static FILE *iotrace = 0;
rsebe0a9092007-07-30 18:24:38 +0000409#endif
drhb0603412007-02-28 04:47:26 +0000410
411/*
412** This routine works like printf in that its first argument is a
413** format string and subsequent arguments are values to be substituted
414** in place of % fields. The result of formatting this string
415** is written to iotrace.
416*/
rsebe0a9092007-07-30 18:24:38 +0000417#ifdef SQLITE_ENABLE_IOTRACE
mistachkin9871a932015-03-27 00:21:52 +0000418static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
drhb0603412007-02-28 04:47:26 +0000419 va_list ap;
drhf075cd02007-02-28 06:14:25 +0000420 char *z;
drhb0603412007-02-28 04:47:26 +0000421 if( iotrace==0 ) return;
422 va_start(ap, zFormat);
drhf075cd02007-02-28 06:14:25 +0000423 z = sqlite3_vmprintf(zFormat, ap);
drhb0603412007-02-28 04:47:26 +0000424 va_end(ap);
mistachkin710b33b2016-01-03 18:59:28 +0000425 utf8_printf(iotrace, "%s", z);
drhf075cd02007-02-28 06:14:25 +0000426 sqlite3_free(z);
drhb0603412007-02-28 04:47:26 +0000427}
rsebe0a9092007-07-30 18:24:38 +0000428#endif
drhb0603412007-02-28 04:47:26 +0000429
drh44c2eb12003-04-30 11:38:26 +0000430
persicom7e2dfdd2002-04-18 02:46:52 +0000431/*
drh83965662003-04-17 02:54:13 +0000432** Determines if a string is a number of not.
433*/
danielk19772e588c72005-12-09 14:25:08 +0000434static int isNumber(const char *z, int *realnum){
drhc8d74412004-08-31 23:41:26 +0000435 if( *z=='-' || *z=='+' ) z++;
drhf0693c82011-10-11 20:41:54 +0000436 if( !IsDigit(*z) ){
drhc8d74412004-08-31 23:41:26 +0000437 return 0;
438 }
439 z++;
440 if( realnum ) *realnum = 0;
drhf0693c82011-10-11 20:41:54 +0000441 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000442 if( *z=='.' ){
443 z++;
drhf0693c82011-10-11 20:41:54 +0000444 if( !IsDigit(*z) ) return 0;
445 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000446 if( realnum ) *realnum = 1;
447 }
448 if( *z=='e' || *z=='E' ){
449 z++;
450 if( *z=='+' || *z=='-' ) z++;
drhf0693c82011-10-11 20:41:54 +0000451 if( !IsDigit(*z) ) return 0;
452 while( IsDigit(*z) ){ z++; }
drhc8d74412004-08-31 23:41:26 +0000453 if( realnum ) *realnum = 1;
454 }
455 return *z==0;
456}
drh83965662003-04-17 02:54:13 +0000457
458/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000459** A global char* and an SQL function to access its current value
460** from within an SQL statement. This program used to use the
danielk1977bc6ada42004-06-30 08:20:16 +0000461** sqlite_exec_printf() API to substitue a string into an SQL statement.
462** The correct way to do this with sqlite3 is to use the bind API, but
463** since the shell is built around the callback paradigm it would be a lot
464** of work. Instead just use this hack, which is quite harmless.
465*/
466static const char *zShellStatic = 0;
467static void shellstaticFunc(
468 sqlite3_context *context,
469 int argc,
470 sqlite3_value **argv
471){
472 assert( 0==argc );
473 assert( zShellStatic );
shaned87897d2009-01-30 05:40:27 +0000474 UNUSED_PARAMETER(argc);
drh902b9ee2008-12-05 17:17:07 +0000475 UNUSED_PARAMETER(argv);
danielk1977bc6ada42004-06-30 08:20:16 +0000476 sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
477}
478
479
480/*
drhe05461c2015-12-30 13:36:57 +0000481** Compute a string length that is limited to what can be stored in
482** lower 30 bits of a 32-bit signed integer.
483*/
484static int strlen30(const char *z){
485 const char *z2 = z;
486 while( *z2 ){ z2++; }
487 return 0x3fffffff & (int)(z2 - z);
488}
489
490/*
drhfeac5f82004-08-01 00:10:45 +0000491** This routine reads a line of text from FILE in, stores
drh8e7e7a22000-05-30 18:45:23 +0000492** the text in memory obtained from malloc() and returns a pointer
493** to the text. NULL is returned at end of file, or if malloc()
494** fails.
495**
drh9f099fd2013-08-06 14:01:46 +0000496** If zLine is not NULL then it is a malloced buffer returned from
497** a previous call to this routine that may be reused.
drh8e7e7a22000-05-30 18:45:23 +0000498*/
drh9f099fd2013-08-06 14:01:46 +0000499static char *local_getline(char *zLine, FILE *in){
500 int nLine = zLine==0 ? 0 : 100;
501 int n = 0;
drh8e7e7a22000-05-30 18:45:23 +0000502
drhb07028f2011-10-14 21:49:18 +0000503 while( 1 ){
drh8e7e7a22000-05-30 18:45:23 +0000504 if( n+100>nLine ){
505 nLine = nLine*2 + 100;
506 zLine = realloc(zLine, nLine);
507 if( zLine==0 ) return 0;
508 }
drhdaffd0e2001-04-11 14:28:42 +0000509 if( fgets(&zLine[n], nLine - n, in)==0 ){
drh8e7e7a22000-05-30 18:45:23 +0000510 if( n==0 ){
511 free(zLine);
512 return 0;
513 }
514 zLine[n] = 0;
drh8e7e7a22000-05-30 18:45:23 +0000515 break;
516 }
drh9f099fd2013-08-06 14:01:46 +0000517 while( zLine[n] ) n++;
518 if( n>0 && zLine[n-1]=='\n' ){
drh8e7e7a22000-05-30 18:45:23 +0000519 n--;
shaneh13b36022009-12-17 21:07:15 +0000520 if( n>0 && zLine[n-1]=='\r' ) n--;
drh8e7e7a22000-05-30 18:45:23 +0000521 zLine[n] = 0;
drhb07028f2011-10-14 21:49:18 +0000522 break;
drh8e7e7a22000-05-30 18:45:23 +0000523 }
524 }
drhe05461c2015-12-30 13:36:57 +0000525#if defined(_WIN32) || defined(WIN32)
mistachkin1fe36bb2016-04-04 02:16:44 +0000526 /* For interactive input on Windows systems, translate the
drhe05461c2015-12-30 13:36:57 +0000527 ** multi-byte characterset characters into UTF-8. */
drhfc8b40f2016-09-07 10:10:18 +0000528 if( stdin_is_interactive && in==stdin ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000529 char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
drhe05461c2015-12-30 13:36:57 +0000530 if( zTrans ){
531 int nTrans = strlen30(zTrans)+1;
532 if( nTrans>nLine ){
533 zLine = realloc(zLine, nTrans);
534 if( zLine==0 ){
535 sqlite3_free(zTrans);
536 return 0;
537 }
538 }
539 memcpy(zLine, zTrans, nTrans);
540 sqlite3_free(zTrans);
541 }
542 }
543#endif /* defined(_WIN32) || defined(WIN32) */
drh8e7e7a22000-05-30 18:45:23 +0000544 return zLine;
545}
546
547/*
drhc28490c2006-10-26 14:25:58 +0000548** Retrieve a single line of input text.
drh8e7e7a22000-05-30 18:45:23 +0000549**
drh9f099fd2013-08-06 14:01:46 +0000550** If in==0 then read from standard input and prompt before each line.
551** If isContinuation is true, then a continuation prompt is appropriate.
552** If isContinuation is zero, then the main prompt should be used.
553**
554** If zPrior is not NULL then it is a buffer from a prior call to this
555** routine that can be reused.
556**
557** The result is stored in space obtained from malloc() and must either
558** be freed by the caller or else passed back into this routine via the
559** zPrior argument for reuse.
drh8e7e7a22000-05-30 18:45:23 +0000560*/
drh9f099fd2013-08-06 14:01:46 +0000561static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
drh8e7e7a22000-05-30 18:45:23 +0000562 char *zPrompt;
563 char *zResult;
drhdaffd0e2001-04-11 14:28:42 +0000564 if( in!=0 ){
drh9f099fd2013-08-06 14:01:46 +0000565 zResult = local_getline(zPrior, in);
drh8e7e7a22000-05-30 18:45:23 +0000566 }else{
drh9f099fd2013-08-06 14:01:46 +0000567 zPrompt = isContinuation ? continuePrompt : mainPrompt;
danfd34d6d2015-02-25 10:54:53 +0000568#if SHELL_USE_LOCAL_GETLINE
drh9f099fd2013-08-06 14:01:46 +0000569 printf("%s", zPrompt);
570 fflush(stdout);
571 zResult = local_getline(zPrior, stdin);
danfd34d6d2015-02-25 10:54:53 +0000572#else
573 free(zPrior);
574 zResult = shell_readline(zPrompt);
575 if( zResult && *zResult ) shell_add_history(zResult);
danielk19774af00c62005-01-23 23:43:21 +0000576#endif
drh9f099fd2013-08-06 14:01:46 +0000577 }
drh8e7e7a22000-05-30 18:45:23 +0000578 return zResult;
579}
580
drhe6229612014-08-18 15:08:26 +0000581#if defined(SQLITE_ENABLE_SESSION)
582/*
583** State information for a single open session
584*/
585typedef struct OpenSession OpenSession;
586struct OpenSession {
587 char *zName; /* Symbolic name for this session */
588 int nFilter; /* Number of xFilter rejection GLOB patterns */
589 char **azFilter; /* Array of xFilter rejection GLOB patterns */
590 sqlite3_session *p; /* The open session */
591};
592#endif
593
drhdcd87a92014-08-18 13:45:42 +0000594/*
mistachkin1fe36bb2016-04-04 02:16:44 +0000595** Shell output mode information from before ".explain on",
drhdcd87a92014-08-18 13:45:42 +0000596** saved so that it can be restored by ".explain off"
597*/
598typedef struct SavedModeInfo SavedModeInfo;
599struct SavedModeInfo {
600 int valid; /* Is there legit data in here? */
601 int mode; /* Mode prior to ".explain on" */
602 int showHeader; /* The ".header" setting prior to ".explain on" */
603 int colWidth[100]; /* Column widths prior to ".explain on" */
persicom7e2dfdd2002-04-18 02:46:52 +0000604};
drh45e29d82006-11-20 16:21:10 +0000605
drh8e7e7a22000-05-30 18:45:23 +0000606/*
drhdcd87a92014-08-18 13:45:42 +0000607** State information about the database connection is contained in an
608** instance of the following structure.
drh75897232000-05-29 14:26:00 +0000609*/
drhdcd87a92014-08-18 13:45:42 +0000610typedef struct ShellState ShellState;
611struct ShellState {
shane626a6e42009-10-22 17:30:15 +0000612 sqlite3 *db; /* The database */
drhdaffd0e2001-04-11 14:28:42 +0000613 int echoOn; /* True to echo input commands */
drh700c2522016-02-09 18:39:25 +0000614 int autoExplain; /* Automatically turn on .explain mode */
drhc2ce0be2014-05-29 12:36:14 +0000615 int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
shaneh642d8b82010-07-28 16:05:34 +0000616 int statsOn; /* True to display memory stats before each finalize */
dan8d1edb92014-11-05 09:07:28 +0000617 int scanstatsOn; /* True to display scan stats before each finalize */
drhdf12f1c2015-12-07 21:46:19 +0000618 int countChanges; /* True to display change counts */
drh9569f602015-04-16 15:05:04 +0000619 int backslashOn; /* Resolve C-style \x escapes in SQL input text */
drhc2ce0be2014-05-29 12:36:14 +0000620 int outCount; /* Revert to stdout when reaching zero */
drh28bd4bc2000-06-15 15:57:22 +0000621 int cnt; /* Number of records displayed so far */
622 FILE *out; /* Write results here */
drh42f64e52012-04-04 16:56:23 +0000623 FILE *traceOut; /* Output for sqlite3_trace() */
drh2f464a02011-10-13 00:41:49 +0000624 int nErr; /* Number of errors seen */
drh28bd4bc2000-06-15 15:57:22 +0000625 int mode; /* An output mode setting */
drh700c2522016-02-09 18:39:25 +0000626 int cMode; /* temporary output mode for the current query */
627 int normalMode; /* Output mode before ".explain on" */
drh45e29d82006-11-20 16:21:10 +0000628 int writableSchema; /* True if PRAGMA writable_schema=ON */
drh28bd4bc2000-06-15 15:57:22 +0000629 int showHeader; /* True to show column names in List or Column mode */
drh760c8162016-09-16 02:52:22 +0000630 int nCheck; /* Number of ".check" commands run */
drh44dec872014-08-30 15:49:25 +0000631 unsigned shellFlgs; /* Various flags */
drh33048c02001-10-01 14:29:22 +0000632 char *zDestTable; /* Name of destination table when MODE_Insert */
drh760c8162016-09-16 02:52:22 +0000633 char zTestcase[30]; /* Name of current test case */
mistachkin636bf9f2014-07-19 20:15:16 +0000634 char colSeparator[20]; /* Column separator character for several modes */
635 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drha0c66f52000-07-29 13:20:21 +0000636 int colWidth[100]; /* Requested width of each column when in column mode*/
637 int actualWidth[100]; /* Actual width of each column */
mistachkin44b99f72014-12-11 03:29:14 +0000638 char nullValue[20]; /* The text to print when a NULL comes back from
drh83965662003-04-17 02:54:13 +0000639 ** the database */
drh44c2eb12003-04-30 11:38:26 +0000640 char outfile[FILENAME_MAX]; /* Filename for *out */
641 const char *zDbFilename; /* name of the database file */
drh05782482013-10-24 15:20:20 +0000642 char *zFreeOnClose; /* Filename to free when closing */
drha7e61d82011-03-12 17:02:57 +0000643 const char *zVfs; /* Name of VFS to use */
shane626a6e42009-10-22 17:30:15 +0000644 sqlite3_stmt *pStmt; /* Current statement if any. */
drh127f9d72010-02-23 01:47:00 +0000645 FILE *pLog; /* Write log output here */
dana98bf362013-11-13 18:35:01 +0000646 int *aiIndent; /* Array of indents used in MODE_Explain */
647 int nIndent; /* Size of array aiIndent[] */
danc4650bb2013-11-18 08:41:06 +0000648 int iIndent; /* Index of current op in aiIndent[] */
drhe6229612014-08-18 15:08:26 +0000649#if defined(SQLITE_ENABLE_SESSION)
650 int nSession; /* Number of active sessions */
651 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
652#endif
drh75897232000-05-29 14:26:00 +0000653};
654
655/*
drh44dec872014-08-30 15:49:25 +0000656** These are the allowed shellFlgs values
657*/
658#define SHFLG_Scratch 0x00001 /* The --scratch option is used */
659#define SHFLG_Pagecache 0x00002 /* The --pagecache option is used */
660#define SHFLG_Lookaside 0x00004 /* Lookaside memory is used */
661
662/*
drh75897232000-05-29 14:26:00 +0000663** These are the allowed modes.
664*/
drh967e8b72000-06-21 13:59:10 +0000665#define MODE_Line 0 /* One column per line. Blank line between records */
drh75897232000-05-29 14:26:00 +0000666#define MODE_Column 1 /* One record per line in neat columns */
667#define MODE_List 2 /* One record per line with a separator */
drhe3710332000-09-29 13:30:53 +0000668#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
669#define MODE_Html 4 /* Generate an XHTML table */
670#define MODE_Insert 5 /* Generate SQL "insert" statements */
drh41f5f6e2016-10-21 17:39:30 +0000671#define MODE_Quote 6 /* Quote values as for SQL */
672#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
673#define MODE_Csv 8 /* Quote strings, numbers are plain */
674#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
675#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
676#define MODE_Pretty 11 /* Pretty-print schemas */
persicom7e2dfdd2002-04-18 02:46:52 +0000677
drh66ce4d02008-02-15 17:38:06 +0000678static const char *modeDescr[] = {
persicom7e2dfdd2002-04-18 02:46:52 +0000679 "line",
680 "column",
681 "list",
682 "semi",
683 "html",
drhfeac5f82004-08-01 00:10:45 +0000684 "insert",
drh41f5f6e2016-10-21 17:39:30 +0000685 "quote",
drhfeac5f82004-08-01 00:10:45 +0000686 "tcl",
drh8e64d1c2004-10-07 00:32:39 +0000687 "csv",
drh66ce4d02008-02-15 17:38:06 +0000688 "explain",
mistachkin636bf9f2014-07-19 20:15:16 +0000689 "ascii",
drh4926fec2016-04-13 15:33:42 +0000690 "prettyprint",
persicom7e2dfdd2002-04-18 02:46:52 +0000691};
drh75897232000-05-29 14:26:00 +0000692
693/*
mistachkinfad42082014-07-24 22:13:12 +0000694** These are the column/row/line separators used by the various
695** import/export modes.
mistachkin636bf9f2014-07-19 20:15:16 +0000696*/
mistachkinfad42082014-07-24 22:13:12 +0000697#define SEP_Column "|"
698#define SEP_Row "\n"
699#define SEP_Tab "\t"
700#define SEP_Space " "
701#define SEP_Comma ","
702#define SEP_CrLf "\r\n"
703#define SEP_Unit "\x1F"
704#define SEP_Record "\x1E"
mistachkin636bf9f2014-07-19 20:15:16 +0000705
706/*
drh75897232000-05-29 14:26:00 +0000707** Number of elements in an array
708*/
drh902b9ee2008-12-05 17:17:07 +0000709#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
drh75897232000-05-29 14:26:00 +0000710
711/*
drh127f9d72010-02-23 01:47:00 +0000712** A callback for the sqlite3_log() interface.
713*/
714static void shellLog(void *pArg, int iErrCode, const char *zMsg){
drhdcd87a92014-08-18 13:45:42 +0000715 ShellState *p = (ShellState*)pArg;
drh127f9d72010-02-23 01:47:00 +0000716 if( p->pLog==0 ) return;
mistachkinaae280e2015-12-31 19:06:24 +0000717 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
drh127f9d72010-02-23 01:47:00 +0000718 fflush(p->pLog);
719}
720
721/*
shane626a6e42009-10-22 17:30:15 +0000722** Output the given string as a hex-encoded blob (eg. X'1234' )
723*/
724static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
725 int i;
726 char *zBlob = (char *)pBlob;
mistachkinaae280e2015-12-31 19:06:24 +0000727 raw_printf(out,"X'");
728 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
729 raw_printf(out,"'");
shane626a6e42009-10-22 17:30:15 +0000730}
731
732/*
drh28bd4bc2000-06-15 15:57:22 +0000733** Output the given string as a quoted string using SQL quoting conventions.
734*/
735static void output_quoted_string(FILE *out, const char *z){
736 int i;
737 int nSingle = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +0000738 setBinaryMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000739 for(i=0; z[i]; i++){
740 if( z[i]=='\'' ) nSingle++;
drh28bd4bc2000-06-15 15:57:22 +0000741 }
742 if( nSingle==0 ){
drhe05461c2015-12-30 13:36:57 +0000743 utf8_printf(out,"'%s'",z);
drh28bd4bc2000-06-15 15:57:22 +0000744 }else{
mistachkinaae280e2015-12-31 19:06:24 +0000745 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000746 while( *z ){
747 for(i=0; z[i] && z[i]!='\''; i++){}
748 if( i==0 ){
mistachkinaae280e2015-12-31 19:06:24 +0000749 raw_printf(out,"''");
drh28bd4bc2000-06-15 15:57:22 +0000750 z++;
751 }else if( z[i]=='\'' ){
drhe05461c2015-12-30 13:36:57 +0000752 utf8_printf(out,"%.*s''",i,z);
drh28bd4bc2000-06-15 15:57:22 +0000753 z += i+1;
754 }else{
drhe05461c2015-12-30 13:36:57 +0000755 utf8_printf(out,"%s",z);
drh28bd4bc2000-06-15 15:57:22 +0000756 break;
757 }
758 }
mistachkinaae280e2015-12-31 19:06:24 +0000759 raw_printf(out,"'");
drh28bd4bc2000-06-15 15:57:22 +0000760 }
mistachkin1fe36bb2016-04-04 02:16:44 +0000761 setTextMode(out, 1);
drh28bd4bc2000-06-15 15:57:22 +0000762}
763
764/*
drhfeac5f82004-08-01 00:10:45 +0000765** Output the given string as a quoted according to C or TCL quoting rules.
766*/
767static void output_c_string(FILE *out, const char *z){
768 unsigned int c;
769 fputc('"', out);
770 while( (c = *(z++))!=0 ){
771 if( c=='\\' ){
772 fputc(c, out);
773 fputc(c, out);
mistachkin585dcb22012-12-04 00:23:43 +0000774 }else if( c=='"' ){
775 fputc('\\', out);
776 fputc('"', out);
drhfeac5f82004-08-01 00:10:45 +0000777 }else if( c=='\t' ){
778 fputc('\\', out);
779 fputc('t', out);
780 }else if( c=='\n' ){
781 fputc('\\', out);
782 fputc('n', out);
783 }else if( c=='\r' ){
784 fputc('\\', out);
785 fputc('r', out);
mistachkinf6418892013-08-28 01:54:12 +0000786 }else if( !isprint(c&0xff) ){
mistachkinaae280e2015-12-31 19:06:24 +0000787 raw_printf(out, "\\%03o", c&0xff);
drhfeac5f82004-08-01 00:10:45 +0000788 }else{
789 fputc(c, out);
790 }
791 }
792 fputc('"', out);
793}
794
795/*
drhc08a4f12000-06-15 16:49:48 +0000796** Output the given string with characters that are special to
797** HTML escaped.
798*/
799static void output_html_string(FILE *out, const char *z){
800 int i;
drhc3d6ba42014-01-13 20:38:35 +0000801 if( z==0 ) z = "";
drhc08a4f12000-06-15 16:49:48 +0000802 while( *z ){
mistachkin1fe36bb2016-04-04 02:16:44 +0000803 for(i=0; z[i]
804 && z[i]!='<'
805 && z[i]!='&'
806 && z[i]!='>'
807 && z[i]!='\"'
shane43d9cb22009-10-21 14:11:48 +0000808 && z[i]!='\'';
809 i++){}
drhc08a4f12000-06-15 16:49:48 +0000810 if( i>0 ){
drhe05461c2015-12-30 13:36:57 +0000811 utf8_printf(out,"%.*s",i,z);
drhc08a4f12000-06-15 16:49:48 +0000812 }
813 if( z[i]=='<' ){
mistachkinaae280e2015-12-31 19:06:24 +0000814 raw_printf(out,"&lt;");
drhc08a4f12000-06-15 16:49:48 +0000815 }else if( z[i]=='&' ){
mistachkinaae280e2015-12-31 19:06:24 +0000816 raw_printf(out,"&amp;");
shane43d9cb22009-10-21 14:11:48 +0000817 }else if( z[i]=='>' ){
mistachkinaae280e2015-12-31 19:06:24 +0000818 raw_printf(out,"&gt;");
shane43d9cb22009-10-21 14:11:48 +0000819 }else if( z[i]=='\"' ){
mistachkinaae280e2015-12-31 19:06:24 +0000820 raw_printf(out,"&quot;");
shane43d9cb22009-10-21 14:11:48 +0000821 }else if( z[i]=='\'' ){
mistachkinaae280e2015-12-31 19:06:24 +0000822 raw_printf(out,"&#39;");
drhc08a4f12000-06-15 16:49:48 +0000823 }else{
824 break;
825 }
826 z += i + 1;
827 }
828}
829
830/*
drhc49f44e2006-10-26 18:15:42 +0000831** If a field contains any character identified by a 1 in the following
832** array, then the string must be quoted for CSV.
833*/
834static const char needCsvQuote[] = {
mistachkin1fe36bb2016-04-04 02:16:44 +0000835 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
836 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
837 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
838 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
839 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
840 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
841 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
842 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
843 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
844 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
845 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
846 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
847 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
848 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
849 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
850 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
drhc49f44e2006-10-26 18:15:42 +0000851};
852
853/*
mistachkindd11f2d2014-12-11 04:49:46 +0000854** Output a single term of CSV. Actually, p->colSeparator is used for
mistachkin44b99f72014-12-11 03:29:14 +0000855** the separator, which may or may not be a comma. p->nullValue is
drh6976c212014-07-24 12:09:47 +0000856** the null value. Strings are quoted if necessary. The separator
857** is only issued if bSep is true.
drh8e64d1c2004-10-07 00:32:39 +0000858*/
drhdcd87a92014-08-18 13:45:42 +0000859static void output_csv(ShellState *p, const char *z, int bSep){
drhc49f44e2006-10-26 18:15:42 +0000860 FILE *out = p->out;
drh8e64d1c2004-10-07 00:32:39 +0000861 if( z==0 ){
drhe05461c2015-12-30 13:36:57 +0000862 utf8_printf(out,"%s",p->nullValue);
drh8e64d1c2004-10-07 00:32:39 +0000863 }else{
drhc49f44e2006-10-26 18:15:42 +0000864 int i;
mistachkin636bf9f2014-07-19 20:15:16 +0000865 int nSep = strlen30(p->colSeparator);
drhc49f44e2006-10-26 18:15:42 +0000866 for(i=0; z[i]; i++){
mistachkin1fe36bb2016-04-04 02:16:44 +0000867 if( needCsvQuote[((unsigned char*)z)[i]]
868 || (z[i]==p->colSeparator[0] &&
mistachkin636bf9f2014-07-19 20:15:16 +0000869 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
drhc49f44e2006-10-26 18:15:42 +0000870 i = 0;
871 break;
872 }
873 }
874 if( i==0 ){
875 putc('"', out);
876 for(i=0; z[i]; i++){
877 if( z[i]=='"' ) putc('"', out);
878 putc(z[i], out);
879 }
880 putc('"', out);
881 }else{
drhe05461c2015-12-30 13:36:57 +0000882 utf8_printf(out, "%s", z);
drhc49f44e2006-10-26 18:15:42 +0000883 }
drh8e64d1c2004-10-07 00:32:39 +0000884 }
885 if( bSep ){
drhe05461c2015-12-30 13:36:57 +0000886 utf8_printf(p->out, "%s", p->colSeparator);
drh8e64d1c2004-10-07 00:32:39 +0000887 }
888}
889
danielk19774af00c62005-01-23 23:43:21 +0000890#ifdef SIGINT
drh8e64d1c2004-10-07 00:32:39 +0000891/*
drh4c504392000-10-16 22:06:40 +0000892** This routine runs when the user presses Ctrl-C
893*/
894static void interrupt_handler(int NotUsed){
drh902b9ee2008-12-05 17:17:07 +0000895 UNUSED_PARAMETER(NotUsed);
drh43ae8f62014-05-23 12:03:47 +0000896 seenInterrupt++;
897 if( seenInterrupt>2 ) exit(1);
mistachkin8e189222015-04-19 21:43:16 +0000898 if( globalDb ) sqlite3_interrupt(globalDb);
drh4c504392000-10-16 22:06:40 +0000899}
danielk19774af00c62005-01-23 23:43:21 +0000900#endif
drh4c504392000-10-16 22:06:40 +0000901
drha0daa752016-09-16 11:53:10 +0000902#ifndef SQLITE_OMIT_AUTHORIZATION
drh4c504392000-10-16 22:06:40 +0000903/*
drhde613c62016-04-04 17:23:10 +0000904** When the ".auth ON" is set, the following authorizer callback is
905** invoked. It always returns SQLITE_OK.
906*/
907static int shellAuth(
908 void *pClientData,
909 int op,
910 const char *zA1,
911 const char *zA2,
912 const char *zA3,
913 const char *zA4
914){
915 ShellState *p = (ShellState*)pClientData;
916 static const char *azAction[] = { 0,
917 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
918 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
919 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
920 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
921 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
922 "DROP_TRIGGER", "DROP_VIEW", "INSERT",
923 "PRAGMA", "READ", "SELECT",
924 "TRANSACTION", "UPDATE", "ATTACH",
925 "DETACH", "ALTER_TABLE", "REINDEX",
926 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
927 "FUNCTION", "SAVEPOINT", "RECURSIVE"
928 };
929 int i;
930 const char *az[4];
931 az[0] = zA1;
932 az[1] = zA2;
933 az[2] = zA3;
934 az[3] = zA4;
mistachkin8145fc62016-09-16 20:39:21 +0000935 utf8_printf(p->out, "authorizer: %s", azAction[op]);
drhde613c62016-04-04 17:23:10 +0000936 for(i=0; i<4; i++){
937 raw_printf(p->out, " ");
938 if( az[i] ){
939 output_c_string(p->out, az[i]);
940 }else{
941 raw_printf(p->out, "NULL");
942 }
943 }
944 raw_printf(p->out, "\n");
945 return SQLITE_OK;
946}
drha0daa752016-09-16 11:53:10 +0000947#endif
mistachkin8145fc62016-09-16 20:39:21 +0000948
drhde613c62016-04-04 17:23:10 +0000949
950/*
shane626a6e42009-10-22 17:30:15 +0000951** This is the callback routine that the shell
drh75897232000-05-29 14:26:00 +0000952** invokes for each row of a query result.
953*/
drh4ace5362014-11-10 14:42:28 +0000954static int shell_callback(
955 void *pArg,
956 int nArg, /* Number of result columns */
957 char **azArg, /* Text of each result column */
958 char **azCol, /* Column names */
959 int *aiType /* Column types */
960){
drh75897232000-05-29 14:26:00 +0000961 int i;
drhdcd87a92014-08-18 13:45:42 +0000962 ShellState *p = (ShellState*)pArg;
shaneb9fc17d2009-10-22 21:23:35 +0000963
drh700c2522016-02-09 18:39:25 +0000964 switch( p->cMode ){
drh75897232000-05-29 14:26:00 +0000965 case MODE_Line: {
drhe3710332000-09-29 13:30:53 +0000966 int w = 5;
drh6a535342001-10-19 16:44:56 +0000967 if( azArg==0 ) break;
drhe3710332000-09-29 13:30:53 +0000968 for(i=0; i<nArg; i++){
drh4f21c4a2008-12-10 22:15:00 +0000969 int len = strlen30(azCol[i] ? azCol[i] : "");
drhe3710332000-09-29 13:30:53 +0000970 if( len>w ) w = len;
971 }
drhe05461c2015-12-30 13:36:57 +0000972 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000973 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +0000974 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
mistachkin44b99f72014-12-11 03:29:14 +0000975 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
drh75897232000-05-29 14:26:00 +0000976 }
977 break;
978 }
danielk19770d78bae2008-01-03 07:09:48 +0000979 case MODE_Explain:
drh75897232000-05-29 14:26:00 +0000980 case MODE_Column: {
drh700c2522016-02-09 18:39:25 +0000981 static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
982 const int *colWidth;
983 int showHdr;
984 char *rowSep;
985 if( p->cMode==MODE_Column ){
986 colWidth = p->colWidth;
987 showHdr = p->showHeader;
988 rowSep = p->rowSeparator;
989 }else{
990 colWidth = aExplainWidths;
991 showHdr = 1;
mistachkin6d945552016-02-09 20:31:50 +0000992 rowSep = SEP_Row;
drh700c2522016-02-09 18:39:25 +0000993 }
drha0c66f52000-07-29 13:20:21 +0000994 if( p->cnt++==0 ){
drh75897232000-05-29 14:26:00 +0000995 for(i=0; i<nArg; i++){
drha0c66f52000-07-29 13:20:21 +0000996 int w, n;
997 if( i<ArraySize(p->colWidth) ){
drh700c2522016-02-09 18:39:25 +0000998 w = colWidth[i];
drh75897232000-05-29 14:26:00 +0000999 }else{
danielk19770d78bae2008-01-03 07:09:48 +00001000 w = 0;
drh75897232000-05-29 14:26:00 +00001001 }
drh078b1fd2012-09-21 13:40:02 +00001002 if( w==0 ){
drh4f21c4a2008-12-10 22:15:00 +00001003 w = strlen30(azCol[i] ? azCol[i] : "");
drha0c66f52000-07-29 13:20:21 +00001004 if( w<10 ) w = 10;
mistachkin44b99f72014-12-11 03:29:14 +00001005 n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
drha0c66f52000-07-29 13:20:21 +00001006 if( w<n ) w = n;
1007 }
1008 if( i<ArraySize(p->actualWidth) ){
persicom1d0b8722002-04-18 02:53:04 +00001009 p->actualWidth[i] = w;
drha0c66f52000-07-29 13:20:21 +00001010 }
drh700c2522016-02-09 18:39:25 +00001011 if( showHdr ){
drh078b1fd2012-09-21 13:40:02 +00001012 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001013 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001014 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001015 }else{
drhe05461c2015-12-30 13:36:57 +00001016 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
drh700c2522016-02-09 18:39:25 +00001017 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001018 }
drha0c66f52000-07-29 13:20:21 +00001019 }
1020 }
drh700c2522016-02-09 18:39:25 +00001021 if( showHdr ){
drha0c66f52000-07-29 13:20:21 +00001022 for(i=0; i<nArg; i++){
1023 int w;
1024 if( i<ArraySize(p->actualWidth) ){
1025 w = p->actualWidth[i];
drh078b1fd2012-09-21 13:40:02 +00001026 if( w<0 ) w = -w;
drha0c66f52000-07-29 13:20:21 +00001027 }else{
1028 w = 10;
1029 }
mistachkinaae280e2015-12-31 19:06:24 +00001030 utf8_printf(p->out,"%-*.*s%s",w,w,
drhe05461c2015-12-30 13:36:57 +00001031 "----------------------------------------------------------"
drha0c66f52000-07-29 13:20:21 +00001032 "----------------------------------------------------------",
drh700c2522016-02-09 18:39:25 +00001033 i==nArg-1 ? rowSep : " ");
drha0c66f52000-07-29 13:20:21 +00001034 }
drh75897232000-05-29 14:26:00 +00001035 }
1036 }
drh6a535342001-10-19 16:44:56 +00001037 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001038 for(i=0; i<nArg; i++){
1039 int w;
drha0c66f52000-07-29 13:20:21 +00001040 if( i<ArraySize(p->actualWidth) ){
1041 w = p->actualWidth[i];
drh75897232000-05-29 14:26:00 +00001042 }else{
1043 w = 10;
1044 }
drh700c2522016-02-09 18:39:25 +00001045 if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
drh4f21c4a2008-12-10 22:15:00 +00001046 w = strlen30(azArg[i]);
danielk19770d78bae2008-01-03 07:09:48 +00001047 }
dana98bf362013-11-13 18:35:01 +00001048 if( i==1 && p->aiIndent && p->pStmt ){
danc4650bb2013-11-18 08:41:06 +00001049 if( p->iIndent<p->nIndent ){
mistachkinaae280e2015-12-31 19:06:24 +00001050 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
dana98bf362013-11-13 18:35:01 +00001051 }
danc4650bb2013-11-18 08:41:06 +00001052 p->iIndent++;
dana98bf362013-11-13 18:35:01 +00001053 }
drh078b1fd2012-09-21 13:40:02 +00001054 if( w<0 ){
drhe05461c2015-12-30 13:36:57 +00001055 utf8_printf(p->out,"%*.*s%s",-w,-w,
mistachkin44b99f72014-12-11 03:29:14 +00001056 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001057 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001058 }else{
drhe05461c2015-12-30 13:36:57 +00001059 utf8_printf(p->out,"%-*.*s%s",w,w,
mistachkin44b99f72014-12-11 03:29:14 +00001060 azArg[i] ? azArg[i] : p->nullValue,
drh700c2522016-02-09 18:39:25 +00001061 i==nArg-1 ? rowSep : " ");
drh078b1fd2012-09-21 13:40:02 +00001062 }
drh75897232000-05-29 14:26:00 +00001063 }
1064 break;
1065 }
drh4926fec2016-04-13 15:33:42 +00001066 case MODE_Semi: { /* .schema and .fullschema output */
1067 utf8_printf(p->out, "%s;\n", azArg[0]);
1068 break;
1069 }
1070 case MODE_Pretty: { /* .schema and .fullschema with --indent */
1071 char *z;
drh07d683f2016-04-13 21:00:36 +00001072 int j;
drh4926fec2016-04-13 15:33:42 +00001073 int nParen = 0;
1074 char cEnd = 0;
1075 char c;
1076 int nLine = 0;
1077 assert( nArg==1 );
1078 if( azArg[0]==0 ) break;
1079 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
1080 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
1081 ){
1082 utf8_printf(p->out, "%s;\n", azArg[0]);
1083 break;
1084 }
1085 z = sqlite3_mprintf("%s", azArg[0]);
1086 j = 0;
1087 for(i=0; IsSpace(z[i]); i++){}
1088 for(; (c = z[i])!=0; i++){
1089 if( IsSpace(c) ){
1090 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
1091 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
1092 j--;
1093 }
1094 z[j++] = c;
1095 }
1096 while( j>0 && IsSpace(z[j-1]) ){ j--; }
1097 z[j] = 0;
1098 if( strlen30(z)>=79 ){
drh07d683f2016-04-13 21:00:36 +00001099 for(i=j=0; (c = z[i])!=0; i++){
drh4926fec2016-04-13 15:33:42 +00001100 if( c==cEnd ){
1101 cEnd = 0;
1102 }else if( c=='"' || c=='\'' || c=='`' ){
1103 cEnd = c;
1104 }else if( c=='[' ){
1105 cEnd = ']';
1106 }else if( c=='(' ){
1107 nParen++;
1108 }else if( c==')' ){
1109 nParen--;
1110 if( nLine>0 && nParen==0 && j>0 ){
1111 utf8_printf(p->out, "%.*s\n", j, z);
1112 j = 0;
1113 }
1114 }
1115 z[j++] = c;
1116 if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
1117 if( c=='\n' ) j--;
1118 utf8_printf(p->out, "%.*s\n ", j, z);
1119 j = 0;
1120 nLine++;
1121 while( IsSpace(z[i+1]) ){ i++; }
1122 }
1123 }
1124 z[j] = 0;
1125 }
1126 utf8_printf(p->out, "%s;\n", z);
1127 sqlite3_free(z);
1128 break;
1129 }
drh75897232000-05-29 14:26:00 +00001130 case MODE_List: {
1131 if( p->cnt++==0 && p->showHeader ){
1132 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001133 utf8_printf(p->out,"%s%s",azCol[i],
mistachkin636bf9f2014-07-19 20:15:16 +00001134 i==nArg-1 ? p->rowSeparator : p->colSeparator);
drh75897232000-05-29 14:26:00 +00001135 }
1136 }
drh6a535342001-10-19 16:44:56 +00001137 if( azArg==0 ) break;
drh75897232000-05-29 14:26:00 +00001138 for(i=0; i<nArg; i++){
drh4c653a02000-06-07 01:27:47 +00001139 char *z = azArg[i];
mistachkin44b99f72014-12-11 03:29:14 +00001140 if( z==0 ) z = p->nullValue;
drhe05461c2015-12-30 13:36:57 +00001141 utf8_printf(p->out, "%s", z);
drhe3710332000-09-29 13:30:53 +00001142 if( i<nArg-1 ){
drhe05461c2015-12-30 13:36:57 +00001143 utf8_printf(p->out, "%s", p->colSeparator);
drhe3710332000-09-29 13:30:53 +00001144 }else{
drhe05461c2015-12-30 13:36:57 +00001145 utf8_printf(p->out, "%s", p->rowSeparator);
drhe3710332000-09-29 13:30:53 +00001146 }
drh75897232000-05-29 14:26:00 +00001147 }
1148 break;
1149 }
drh1e5d0e92000-05-31 23:33:17 +00001150 case MODE_Html: {
1151 if( p->cnt++==0 && p->showHeader ){
mistachkinaae280e2015-12-31 19:06:24 +00001152 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001153 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001154 raw_printf(p->out,"<TH>");
shane43d9cb22009-10-21 14:11:48 +00001155 output_html_string(p->out, azCol[i]);
mistachkinaae280e2015-12-31 19:06:24 +00001156 raw_printf(p->out,"</TH>\n");
drh1e5d0e92000-05-31 23:33:17 +00001157 }
mistachkinaae280e2015-12-31 19:06:24 +00001158 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001159 }
drh6a535342001-10-19 16:44:56 +00001160 if( azArg==0 ) break;
mistachkinaae280e2015-12-31 19:06:24 +00001161 raw_printf(p->out,"<TR>");
drh1e5d0e92000-05-31 23:33:17 +00001162 for(i=0; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00001163 raw_printf(p->out,"<TD>");
mistachkin44b99f72014-12-11 03:29:14 +00001164 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00001165 raw_printf(p->out,"</TD>\n");
drh1e5d0e92000-05-31 23:33:17 +00001166 }
mistachkinaae280e2015-12-31 19:06:24 +00001167 raw_printf(p->out,"</TR>\n");
drh1e5d0e92000-05-31 23:33:17 +00001168 break;
1169 }
drhfeac5f82004-08-01 00:10:45 +00001170 case MODE_Tcl: {
1171 if( p->cnt++==0 && p->showHeader ){
1172 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001173 output_c_string(p->out,azCol[i] ? azCol[i] : "");
drhe05461c2015-12-30 13:36:57 +00001174 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001175 }
drhe05461c2015-12-30 13:36:57 +00001176 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001177 }
1178 if( azArg==0 ) break;
1179 for(i=0; i<nArg; i++){
mistachkin44b99f72014-12-11 03:29:14 +00001180 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
drhe05461c2015-12-30 13:36:57 +00001181 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00001182 }
drhe05461c2015-12-30 13:36:57 +00001183 utf8_printf(p->out, "%s", p->rowSeparator);
drhfeac5f82004-08-01 00:10:45 +00001184 break;
1185 }
drh8e64d1c2004-10-07 00:32:39 +00001186 case MODE_Csv: {
mistachkin1fe36bb2016-04-04 02:16:44 +00001187 setBinaryMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001188 if( p->cnt++==0 && p->showHeader ){
1189 for(i=0; i<nArg; i++){
drh2cc55692006-06-27 20:39:04 +00001190 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
drh8e64d1c2004-10-07 00:32:39 +00001191 }
drhe05461c2015-12-30 13:36:57 +00001192 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001193 }
drh40253262014-10-17 21:35:05 +00001194 if( nArg>0 ){
drh6976c212014-07-24 12:09:47 +00001195 for(i=0; i<nArg; i++){
1196 output_csv(p, azArg[i], i<nArg-1);
1197 }
drhe05461c2015-12-30 13:36:57 +00001198 utf8_printf(p->out, "%s", p->rowSeparator);
drh8e64d1c2004-10-07 00:32:39 +00001199 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001200 setTextMode(p->out, 1);
drh8e64d1c2004-10-07 00:32:39 +00001201 break;
1202 }
drh41f5f6e2016-10-21 17:39:30 +00001203 case MODE_Quote:
drh28bd4bc2000-06-15 15:57:22 +00001204 case MODE_Insert: {
shaneb9fc17d2009-10-22 21:23:35 +00001205 p->cnt++;
drh6a535342001-10-19 16:44:56 +00001206 if( azArg==0 ) break;
drh41f5f6e2016-10-21 17:39:30 +00001207 if( p->cMode==MODE_Insert ){
1208 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
1209 if( p->showHeader ){
1210 raw_printf(p->out,"(");
1211 for(i=0; i<nArg; i++){
1212 char *zSep = i>0 ? ",": "";
1213 utf8_printf(p->out, "%s%s", zSep, azCol[i]);
1214 }
1215 raw_printf(p->out,")");
mistachkin151c75a2015-04-07 21:16:40 +00001216 }
drh41f5f6e2016-10-21 17:39:30 +00001217 raw_printf(p->out," VALUES(");
mistachkin151c75a2015-04-07 21:16:40 +00001218 }
drh28bd4bc2000-06-15 15:57:22 +00001219 for(i=0; i<nArg; i++){
1220 char *zSep = i>0 ? ",": "";
shanead6b8d02009-10-22 18:12:58 +00001221 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
mistachkinaae280e2015-12-31 19:06:24 +00001222 utf8_printf(p->out,"%sNULL",zSep);
shanead6b8d02009-10-22 18:12:58 +00001223 }else if( aiType && aiType[i]==SQLITE_TEXT ){
mistachkinaae280e2015-12-31 19:06:24 +00001224 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shanead6b8d02009-10-22 18:12:58 +00001225 output_quoted_string(p->out, azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00001226 }else if( aiType && (aiType[i]==SQLITE_INTEGER
1227 || aiType[i]==SQLITE_FLOAT) ){
drhe05461c2015-12-30 13:36:57 +00001228 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
shane626a6e42009-10-22 17:30:15 +00001229 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
1230 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
1231 int nBlob = sqlite3_column_bytes(p->pStmt, i);
mistachkinaae280e2015-12-31 19:06:24 +00001232 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
shane626a6e42009-10-22 17:30:15 +00001233 output_hex_blob(p->out, pBlob, nBlob);
drhc8d74412004-08-31 23:41:26 +00001234 }else if( isNumber(azArg[i], 0) ){
drhe05461c2015-12-30 13:36:57 +00001235 utf8_printf(p->out,"%s%s",zSep, azArg[i]);
drh28bd4bc2000-06-15 15:57:22 +00001236 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001237 if( zSep[0] ) utf8_printf(p->out,"%s",zSep);
drh28bd4bc2000-06-15 15:57:22 +00001238 output_quoted_string(p->out, azArg[i]);
1239 }
1240 }
drh41f5f6e2016-10-21 17:39:30 +00001241 raw_printf(p->out,p->cMode==MODE_Quote?"\n":");\n");
drh6a535342001-10-19 16:44:56 +00001242 break;
drh28bd4bc2000-06-15 15:57:22 +00001243 }
mistachkin636bf9f2014-07-19 20:15:16 +00001244 case MODE_Ascii: {
1245 if( p->cnt++==0 && p->showHeader ){
1246 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001247 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1248 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
mistachkin636bf9f2014-07-19 20:15:16 +00001249 }
drhe05461c2015-12-30 13:36:57 +00001250 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001251 }
1252 if( azArg==0 ) break;
1253 for(i=0; i<nArg; i++){
drhe05461c2015-12-30 13:36:57 +00001254 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
1255 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
mistachkin636bf9f2014-07-19 20:15:16 +00001256 }
drhe05461c2015-12-30 13:36:57 +00001257 utf8_printf(p->out, "%s", p->rowSeparator);
mistachkin636bf9f2014-07-19 20:15:16 +00001258 break;
1259 }
persicom1d0b8722002-04-18 02:53:04 +00001260 }
drh75897232000-05-29 14:26:00 +00001261 return 0;
1262}
1263
1264/*
shane626a6e42009-10-22 17:30:15 +00001265** This is the callback routine that the SQLite library
1266** invokes for each row of a query result.
1267*/
1268static int callback(void *pArg, int nArg, char **azArg, char **azCol){
1269 /* since we don't have type info, call the shell_callback with a NULL value */
1270 return shell_callback(pArg, nArg, azArg, azCol, NULL);
1271}
1272
1273/*
drhdcd87a92014-08-18 13:45:42 +00001274** Set the destination table field of the ShellState structure to
drh33048c02001-10-01 14:29:22 +00001275** the name of the table given. Escape any quote characters in the
1276** table name.
1277*/
drhdcd87a92014-08-18 13:45:42 +00001278static void set_table_name(ShellState *p, const char *zName){
drh33048c02001-10-01 14:29:22 +00001279 int i, n;
1280 int needQuote;
1281 char *z;
1282
1283 if( p->zDestTable ){
1284 free(p->zDestTable);
1285 p->zDestTable = 0;
1286 }
1287 if( zName==0 ) return;
drh4c755c02004-08-08 20:22:17 +00001288 needQuote = !isalpha((unsigned char)*zName) && *zName!='_';
drh33048c02001-10-01 14:29:22 +00001289 for(i=n=0; zName[i]; i++, n++){
drh4c755c02004-08-08 20:22:17 +00001290 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ){
drh33048c02001-10-01 14:29:22 +00001291 needQuote = 1;
1292 if( zName[i]=='\'' ) n++;
1293 }
1294 }
1295 if( needQuote ) n += 2;
1296 z = p->zDestTable = malloc( n+1 );
1297 if( z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00001298 raw_printf(stderr,"Error: out of memory\n");
drh33048c02001-10-01 14:29:22 +00001299 exit(1);
1300 }
1301 n = 0;
1302 if( needQuote ) z[n++] = '\'';
1303 for(i=0; zName[i]; i++){
1304 z[n++] = zName[i];
1305 if( zName[i]=='\'' ) z[n++] = '\'';
1306 }
1307 if( needQuote ) z[n++] = '\'';
1308 z[n] = 0;
1309}
1310
danielk19772a02e332004-06-05 08:04:36 +00001311/* zIn is either a pointer to a NULL-terminated string in memory obtained
1312** from malloc(), or a NULL pointer. The string pointed to by zAppend is
1313** added to zIn, and the result returned in memory obtained from malloc().
1314** zIn, if it was not NULL, is freed.
1315**
mistachkin1fe36bb2016-04-04 02:16:44 +00001316** If the third argument, quote, is not '\0', then it is used as a
danielk19772a02e332004-06-05 08:04:36 +00001317** quote character for zAppend.
1318*/
drhc28490c2006-10-26 14:25:58 +00001319static char *appendText(char *zIn, char const *zAppend, char quote){
danielk19772a02e332004-06-05 08:04:36 +00001320 int len;
1321 int i;
drh4f21c4a2008-12-10 22:15:00 +00001322 int nAppend = strlen30(zAppend);
1323 int nIn = (zIn?strlen30(zIn):0);
danielk19772a02e332004-06-05 08:04:36 +00001324
1325 len = nAppend+nIn+1;
1326 if( quote ){
1327 len += 2;
1328 for(i=0; i<nAppend; i++){
1329 if( zAppend[i]==quote ) len++;
1330 }
1331 }
1332
1333 zIn = (char *)realloc(zIn, len);
1334 if( !zIn ){
1335 return 0;
1336 }
1337
1338 if( quote ){
1339 char *zCsr = &zIn[nIn];
1340 *zCsr++ = quote;
1341 for(i=0; i<nAppend; i++){
1342 *zCsr++ = zAppend[i];
1343 if( zAppend[i]==quote ) *zCsr++ = quote;
1344 }
1345 *zCsr++ = quote;
1346 *zCsr++ = '\0';
1347 assert( (zCsr-zIn)==len );
1348 }else{
1349 memcpy(&zIn[nIn], zAppend, nAppend);
1350 zIn[len-1] = '\0';
1351 }
1352
1353 return zIn;
1354}
1355
drhdd3d4592004-08-30 01:54:05 +00001356
1357/*
drhb21a8e42012-01-28 21:08:51 +00001358** Execute a query statement that will generate SQL output. Print
1359** the result columns, comma-separated, on a line and then add a
1360** semicolon terminator to the end of that line.
drh45e29d82006-11-20 16:21:10 +00001361**
drhb21a8e42012-01-28 21:08:51 +00001362** If the number of columns is 1 and that column contains text "--"
mistachkin1fe36bb2016-04-04 02:16:44 +00001363** then write the semicolon on a separate line. That way, if a
drhb21a8e42012-01-28 21:08:51 +00001364** "--" comment occurs at the end of the statement, the comment
1365** won't consume the semicolon terminator.
drhdd3d4592004-08-30 01:54:05 +00001366*/
drh157e29a2009-05-21 15:15:00 +00001367static int run_table_dump_query(
drhdcd87a92014-08-18 13:45:42 +00001368 ShellState *p, /* Query context */
drh2f464a02011-10-13 00:41:49 +00001369 const char *zSelect, /* SELECT statement to extract content */
1370 const char *zFirstRow /* Print before first row, if not NULL */
drh157e29a2009-05-21 15:15:00 +00001371){
drhdd3d4592004-08-30 01:54:05 +00001372 sqlite3_stmt *pSelect;
1373 int rc;
drhb21a8e42012-01-28 21:08:51 +00001374 int nResult;
1375 int i;
1376 const char *z;
drhc7181902014-02-27 15:04:13 +00001377 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00001378 if( rc!=SQLITE_OK || !pSelect ){
mistachkinaae280e2015-12-31 19:06:24 +00001379 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1380 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001381 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drhdd3d4592004-08-30 01:54:05 +00001382 return rc;
1383 }
1384 rc = sqlite3_step(pSelect);
drhb21a8e42012-01-28 21:08:51 +00001385 nResult = sqlite3_column_count(pSelect);
drhdd3d4592004-08-30 01:54:05 +00001386 while( rc==SQLITE_ROW ){
drh157e29a2009-05-21 15:15:00 +00001387 if( zFirstRow ){
drhe05461c2015-12-30 13:36:57 +00001388 utf8_printf(p->out, "%s", zFirstRow);
drh157e29a2009-05-21 15:15:00 +00001389 zFirstRow = 0;
1390 }
drhb21a8e42012-01-28 21:08:51 +00001391 z = (const char*)sqlite3_column_text(pSelect, 0);
drhe05461c2015-12-30 13:36:57 +00001392 utf8_printf(p->out, "%s", z);
mistachkin1fe36bb2016-04-04 02:16:44 +00001393 for(i=1; i<nResult; i++){
drhe05461c2015-12-30 13:36:57 +00001394 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
drhb21a8e42012-01-28 21:08:51 +00001395 }
1396 if( z==0 ) z = "";
1397 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
1398 if( z[0] ){
mistachkinaae280e2015-12-31 19:06:24 +00001399 raw_printf(p->out, "\n;\n");
drhb21a8e42012-01-28 21:08:51 +00001400 }else{
mistachkinaae280e2015-12-31 19:06:24 +00001401 raw_printf(p->out, ";\n");
mistachkin1fe36bb2016-04-04 02:16:44 +00001402 }
drhdd3d4592004-08-30 01:54:05 +00001403 rc = sqlite3_step(pSelect);
1404 }
drh2f464a02011-10-13 00:41:49 +00001405 rc = sqlite3_finalize(pSelect);
1406 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00001407 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
1408 sqlite3_errmsg(p->db));
drh4384e982013-10-01 15:30:05 +00001409 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
drh2f464a02011-10-13 00:41:49 +00001410 }
1411 return rc;
drhdd3d4592004-08-30 01:54:05 +00001412}
1413
shane626a6e42009-10-22 17:30:15 +00001414/*
1415** Allocate space and save off current error string.
1416*/
1417static char *save_err_msg(
1418 sqlite3 *db /* Database to query */
1419){
1420 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
drhf3cdcdc2015-04-29 16:50:28 +00001421 char *zErrMsg = sqlite3_malloc64(nErrMsg);
shane626a6e42009-10-22 17:30:15 +00001422 if( zErrMsg ){
1423 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
1424 }
1425 return zErrMsg;
1426}
1427
drh34784902016-02-27 17:12:36 +00001428#ifdef __linux__
1429/*
1430** Attempt to display I/O stats on Linux using /proc/PID/io
1431*/
1432static void displayLinuxIoStats(FILE *out){
1433 FILE *in;
1434 char z[200];
1435 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
1436 in = fopen(z, "rb");
1437 if( in==0 ) return;
1438 while( fgets(z, sizeof(z), in)!=0 ){
1439 static const struct {
1440 const char *zPattern;
1441 const char *zDesc;
1442 } aTrans[] = {
drhfc1a84c2016-02-27 19:19:22 +00001443 { "rchar: ", "Bytes received by read():" },
1444 { "wchar: ", "Bytes sent to write():" },
1445 { "syscr: ", "Read() system calls:" },
1446 { "syscw: ", "Write() system calls:" },
1447 { "read_bytes: ", "Bytes read from storage:" },
1448 { "write_bytes: ", "Bytes written to storage:" },
1449 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
drh34784902016-02-27 17:12:36 +00001450 };
1451 int i;
1452 for(i=0; i<ArraySize(aTrans); i++){
1453 int n = (int)strlen(aTrans[i].zPattern);
1454 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
mistachkin8145fc62016-09-16 20:39:21 +00001455 utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
drh34784902016-02-27 17:12:36 +00001456 break;
1457 }
1458 }
1459 }
1460 fclose(in);
mistachkin1fe36bb2016-04-04 02:16:44 +00001461}
drh34784902016-02-27 17:12:36 +00001462#endif
1463
1464
shane626a6e42009-10-22 17:30:15 +00001465/*
shaneh642d8b82010-07-28 16:05:34 +00001466** Display memory stats.
1467*/
1468static int display_stats(
1469 sqlite3 *db, /* Database to query */
drhdcd87a92014-08-18 13:45:42 +00001470 ShellState *pArg, /* Pointer to ShellState */
shaneh642d8b82010-07-28 16:05:34 +00001471 int bReset /* True to reset the stats */
1472){
1473 int iCur;
1474 int iHiwtr;
1475
1476 if( pArg && pArg->out ){
mistachkin1fe36bb2016-04-04 02:16:44 +00001477
shaneh642d8b82010-07-28 16:05:34 +00001478 iHiwtr = iCur = -1;
1479 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001480 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001481 "Memory Used: %d (max %d) bytes\n",
1482 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001483 iHiwtr = iCur = -1;
1484 sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001485 raw_printf(pArg->out, "Number of Outstanding Allocations: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001486 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001487 if( pArg->shellFlgs & SHFLG_Pagecache ){
1488 iHiwtr = iCur = -1;
1489 sqlite3_status(SQLITE_STATUS_PAGECACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001490 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001491 "Number of Pcache Pages Used: %d (max %d) pages\n",
1492 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001493 }
shaneh642d8b82010-07-28 16:05:34 +00001494 iHiwtr = iCur = -1;
1495 sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001496 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001497 "Number of Pcache Overflow Bytes: %d (max %d) bytes\n",
1498 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001499 if( pArg->shellFlgs & SHFLG_Scratch ){
1500 iHiwtr = iCur = -1;
1501 sqlite3_status(SQLITE_STATUS_SCRATCH_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001502 raw_printf(pArg->out,
1503 "Number of Scratch Allocations Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001504 iCur, iHiwtr);
drh44dec872014-08-30 15:49:25 +00001505 }
shaneh642d8b82010-07-28 16:05:34 +00001506 iHiwtr = iCur = -1;
1507 sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001508 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001509 "Number of Scratch Overflow Bytes: %d (max %d) bytes\n",
1510 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001511 iHiwtr = iCur = -1;
1512 sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001513 raw_printf(pArg->out, "Largest Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001514 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001515 iHiwtr = iCur = -1;
1516 sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001517 raw_printf(pArg->out, "Largest Pcache Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001518 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001519 iHiwtr = iCur = -1;
1520 sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001521 raw_printf(pArg->out, "Largest Scratch Allocation: %d bytes\n",
drh4ace5362014-11-10 14:42:28 +00001522 iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001523#ifdef YYTRACKMAXSTACKDEPTH
1524 iHiwtr = iCur = -1;
1525 sqlite3_status(SQLITE_STATUS_PARSER_STACK, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001526 raw_printf(pArg->out, "Deepest Parser Stack: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001527 iCur, iHiwtr);
shaneh642d8b82010-07-28 16:05:34 +00001528#endif
1529 }
1530
1531 if( pArg && pArg->out && db ){
drh44dec872014-08-30 15:49:25 +00001532 if( pArg->shellFlgs & SHFLG_Lookaside ){
1533 iHiwtr = iCur = -1;
drh4ace5362014-11-10 14:42:28 +00001534 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
1535 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001536 raw_printf(pArg->out,
1537 "Lookaside Slots Used: %d (max %d)\n",
drh4ace5362014-11-10 14:42:28 +00001538 iCur, iHiwtr);
1539 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
1540 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001541 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
1542 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001543 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
1544 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001545 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
1546 iHiwtr);
drh4ace5362014-11-10 14:42:28 +00001547 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
1548 &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001549 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
1550 iHiwtr);
drh44dec872014-08-30 15:49:25 +00001551 }
shaneh642d8b82010-07-28 16:05:34 +00001552 iHiwtr = iCur = -1;
1553 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001554 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
1555 iCur);
drh4ace5362014-11-10 14:42:28 +00001556 iHiwtr = iCur = -1;
drhc78e6e42011-09-23 18:58:23 +00001557 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
mistachkinaae280e2015-12-31 19:06:24 +00001558 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
drhc78e6e42011-09-23 18:58:23 +00001559 iHiwtr = iCur = -1;
1560 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001561 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001562 iHiwtr = iCur = -1;
drhfbbcd5d2012-03-24 20:09:33 +00001563 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
mistachkin1fe36bb2016-04-04 02:16:44 +00001564 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
drhfbbcd5d2012-03-24 20:09:33 +00001565 iHiwtr = iCur = -1;
shaneh642d8b82010-07-28 16:05:34 +00001566 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001567 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001568 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001569 iHiwtr = iCur = -1;
1570 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001571 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
mistachkin1fe36bb2016-04-04 02:16:44 +00001572 iCur);
shaneh642d8b82010-07-28 16:05:34 +00001573 }
1574
1575 if( pArg && pArg->out && db && pArg->pStmt ){
drh4ace5362014-11-10 14:42:28 +00001576 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1577 bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001578 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001579 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001580 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
drh4ace5362014-11-10 14:42:28 +00001581 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001582 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
drhbf159fa2013-06-25 22:01:22 +00001583 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
mistachkinaae280e2015-12-31 19:06:24 +00001584 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
shaneh642d8b82010-07-28 16:05:34 +00001585 }
1586
drh34784902016-02-27 17:12:36 +00001587#ifdef __linux__
1588 displayLinuxIoStats(pArg->out);
1589#endif
1590
dan5a790282015-08-07 20:06:14 +00001591 /* Do not remove this machine readable comment: extra-stats-output-here */
1592
shaneh642d8b82010-07-28 16:05:34 +00001593 return 0;
1594}
1595
1596/*
dan8d1edb92014-11-05 09:07:28 +00001597** Display scan stats.
1598*/
1599static void display_scanstats(
1600 sqlite3 *db, /* Database to query */
1601 ShellState *pArg /* Pointer to ShellState */
1602){
drhf5ed7ad2015-06-15 14:43:25 +00001603#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
1604 UNUSED_PARAMETER(db);
1605 UNUSED_PARAMETER(pArg);
1606#else
drh15f23c22014-11-06 12:46:16 +00001607 int i, k, n, mx;
mistachkinaae280e2015-12-31 19:06:24 +00001608 raw_printf(pArg->out, "-------- scanstats --------\n");
drh15f23c22014-11-06 12:46:16 +00001609 mx = 0;
1610 for(k=0; k<=mx; k++){
drh42f30bc2014-11-06 12:08:21 +00001611 double rEstLoop = 1.0;
1612 for(i=n=0; 1; i++){
1613 sqlite3_stmt *p = pArg->pStmt;
1614 sqlite3_int64 nLoop, nVisit;
1615 double rEst;
1616 int iSid;
1617 const char *zExplain;
1618 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
1619 break;
1620 }
1621 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
drh15f23c22014-11-06 12:46:16 +00001622 if( iSid>mx ) mx = iSid;
drh42f30bc2014-11-06 12:08:21 +00001623 if( iSid!=k ) continue;
drh179bac32014-11-06 12:17:24 +00001624 if( n==0 ){
1625 rEstLoop = (double)nLoop;
mistachkinaae280e2015-12-31 19:06:24 +00001626 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
drh179bac32014-11-06 12:17:24 +00001627 }
drh42f30bc2014-11-06 12:08:21 +00001628 n++;
1629 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
1630 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
1631 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
drhe05461c2015-12-30 13:36:57 +00001632 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
drh42f30bc2014-11-06 12:08:21 +00001633 rEstLoop *= rEst;
mistachkin1fe36bb2016-04-04 02:16:44 +00001634 raw_printf(pArg->out,
drh4ace5362014-11-10 14:42:28 +00001635 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
drh9a06d302014-11-07 13:52:44 +00001636 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
drh42f30bc2014-11-06 12:08:21 +00001637 );
dan8d1edb92014-11-05 09:07:28 +00001638 }
dan8d1edb92014-11-05 09:07:28 +00001639 }
mistachkinaae280e2015-12-31 19:06:24 +00001640 raw_printf(pArg->out, "---------------------------\n");
drh15f23c22014-11-06 12:46:16 +00001641#endif
dan8d1edb92014-11-05 09:07:28 +00001642}
1643
1644/*
dana98bf362013-11-13 18:35:01 +00001645** Parameter azArray points to a zero-terminated array of strings. zStr
1646** points to a single nul-terminated string. Return non-zero if zStr
1647** is equal, according to strcmp(), to any of the strings in the array.
1648** Otherwise, return zero.
1649*/
1650static int str_in_array(const char *zStr, const char **azArray){
1651 int i;
1652 for(i=0; azArray[i]; i++){
1653 if( 0==strcmp(zStr, azArray[i]) ) return 1;
1654 }
1655 return 0;
1656}
1657
1658/*
1659** If compiled statement pSql appears to be an EXPLAIN statement, allocate
drhdcd87a92014-08-18 13:45:42 +00001660** and populate the ShellState.aiIndent[] array with the number of
mistachkin1fe36bb2016-04-04 02:16:44 +00001661** spaces each opcode should be indented before it is output.
dana98bf362013-11-13 18:35:01 +00001662**
1663** The indenting rules are:
1664**
1665** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
1666** all opcodes that occur between the p2 jump destination and the opcode
1667** itself by 2 spaces.
1668**
drh01752bc2013-11-14 23:59:33 +00001669** * For each "Goto", if the jump destination is earlier in the program
1670** and ends on one of:
drhe73f0592014-01-21 22:25:45 +00001671** Yield SeekGt SeekLt RowSetRead Rewind
drhfe705102014-03-06 13:38:37 +00001672** or if the P1 parameter is one instead of zero,
drh01752bc2013-11-14 23:59:33 +00001673** then indent all opcodes between the earlier instruction
drhd2447442013-11-13 19:01:41 +00001674** and "Goto" by 2 spaces.
dana98bf362013-11-13 18:35:01 +00001675*/
drhdcd87a92014-08-18 13:45:42 +00001676static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
dana98bf362013-11-13 18:35:01 +00001677 const char *zSql; /* The text of the SQL statement */
1678 const char *z; /* Used to check if this is an EXPLAIN */
1679 int *abYield = 0; /* True if op is an OP_Yield */
1680 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
danc4650bb2013-11-18 08:41:06 +00001681 int iOp; /* Index of operation in p->aiIndent[] */
dana98bf362013-11-13 18:35:01 +00001682
drh8ad0de32014-03-20 18:45:27 +00001683 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext",
1684 "NextIfOpen", "PrevIfOpen", 0 };
drh4ace5362014-11-10 14:42:28 +00001685 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
1686 "Rewind", 0 };
dana98bf362013-11-13 18:35:01 +00001687 const char *azGoto[] = { "Goto", 0 };
1688
1689 /* Try to figure out if this is really an EXPLAIN statement. If this
1690 ** cannot be verified, return early. */
drh87a24aa2016-02-09 20:04:07 +00001691 if( sqlite3_column_count(pSql)!=8 ){
1692 p->cMode = p->mode;
1693 return;
1694 }
dana98bf362013-11-13 18:35:01 +00001695 zSql = sqlite3_sql(pSql);
1696 if( zSql==0 ) return;
1697 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
drh87a24aa2016-02-09 20:04:07 +00001698 if( sqlite3_strnicmp(z, "explain", 7) ){
1699 p->cMode = p->mode;
1700 return;
1701 }
dana98bf362013-11-13 18:35:01 +00001702
1703 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
1704 int i;
danc4650bb2013-11-18 08:41:06 +00001705 int iAddr = sqlite3_column_int(pSql, 0);
dana98bf362013-11-13 18:35:01 +00001706 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
danc4650bb2013-11-18 08:41:06 +00001707
1708 /* Set p2 to the P2 field of the current opcode. Then, assuming that
1709 ** p2 is an instruction address, set variable p2op to the index of that
1710 ** instruction in the aiIndent[] array. p2 and p2op may be different if
1711 ** the current instruction is part of a sub-program generated by an
1712 ** SQL trigger or foreign key. */
dana98bf362013-11-13 18:35:01 +00001713 int p2 = sqlite3_column_int(pSql, 3);
danc4650bb2013-11-18 08:41:06 +00001714 int p2op = (p2 + (iOp-iAddr));
dana98bf362013-11-13 18:35:01 +00001715
1716 /* Grow the p->aiIndent array as required */
1717 if( iOp>=nAlloc ){
drh87a24aa2016-02-09 20:04:07 +00001718 if( iOp==0 ){
1719 /* Do further verfication that this is explain output. Abort if
1720 ** it is not */
1721 static const char *explainCols[] = {
1722 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
1723 int jj;
1724 for(jj=0; jj<ArraySize(explainCols); jj++){
1725 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
1726 p->cMode = p->mode;
1727 sqlite3_reset(pSql);
1728 return;
1729 }
1730 }
1731 }
dana98bf362013-11-13 18:35:01 +00001732 nAlloc += 100;
drhf3cdcdc2015-04-29 16:50:28 +00001733 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
1734 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
dana98bf362013-11-13 18:35:01 +00001735 }
1736 abYield[iOp] = str_in_array(zOp, azYield);
1737 p->aiIndent[iOp] = 0;
1738 p->nIndent = iOp+1;
1739
1740 if( str_in_array(zOp, azNext) ){
danc4650bb2013-11-18 08:41:06 +00001741 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001742 }
drhfe705102014-03-06 13:38:37 +00001743 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
1744 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
1745 ){
drheacd29d2016-04-15 15:03:27 +00001746 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
dana98bf362013-11-13 18:35:01 +00001747 }
1748 }
1749
danc4650bb2013-11-18 08:41:06 +00001750 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001751 sqlite3_free(abYield);
1752 sqlite3_reset(pSql);
1753}
1754
1755/*
1756** Free the array allocated by explain_data_prepare().
1757*/
drhdcd87a92014-08-18 13:45:42 +00001758static void explain_data_delete(ShellState *p){
dana98bf362013-11-13 18:35:01 +00001759 sqlite3_free(p->aiIndent);
1760 p->aiIndent = 0;
1761 p->nIndent = 0;
danc4650bb2013-11-18 08:41:06 +00001762 p->iIndent = 0;
dana98bf362013-11-13 18:35:01 +00001763}
1764
1765/*
drheacd29d2016-04-15 15:03:27 +00001766** Disable and restore .wheretrace and .selecttrace settings.
1767*/
1768#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1769extern int sqlite3SelectTrace;
1770static int savedSelectTrace;
1771#endif
1772#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1773extern int sqlite3WhereTrace;
1774static int savedWhereTrace;
1775#endif
1776static void disable_debug_trace_modes(void){
1777#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1778 savedSelectTrace = sqlite3SelectTrace;
1779 sqlite3SelectTrace = 0;
1780#endif
1781#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1782 savedWhereTrace = sqlite3WhereTrace;
1783 sqlite3WhereTrace = 0;
1784#endif
1785}
1786static void restore_debug_trace_modes(void){
1787#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
1788 sqlite3SelectTrace = savedSelectTrace;
1789#endif
1790#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
1791 sqlite3WhereTrace = savedWhereTrace;
1792#endif
1793}
1794
1795/*
1796** Run a prepared statement
1797*/
1798static void exec_prepared_stmt(
1799 ShellState *pArg, /* Pointer to ShellState */
1800 sqlite3_stmt *pStmt, /* Statment to run */
1801 int (*xCallback)(void*,int,char**,char**,int*) /* Callback function */
1802){
1803 int rc;
1804
1805 /* perform the first step. this will tell us if we
1806 ** have a result set or not and how wide it is.
1807 */
1808 rc = sqlite3_step(pStmt);
1809 /* if we have a result set... */
1810 if( SQLITE_ROW == rc ){
1811 /* if we have a callback... */
1812 if( xCallback ){
1813 /* allocate space for col name ptr, value ptr, and type */
1814 int nCol = sqlite3_column_count(pStmt);
1815 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
1816 if( !pData ){
1817 rc = SQLITE_NOMEM;
1818 }else{
1819 char **azCols = (char **)pData; /* Names of result columns */
1820 char **azVals = &azCols[nCol]; /* Results */
1821 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
1822 int i, x;
1823 assert(sizeof(int) <= sizeof(char *));
1824 /* save off ptrs to column names */
1825 for(i=0; i<nCol; i++){
1826 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1827 }
1828 do{
1829 /* extract the data and data types */
1830 for(i=0; i<nCol; i++){
1831 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1832 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
1833 azVals[i] = "";
1834 }else{
1835 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
1836 }
1837 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
1838 rc = SQLITE_NOMEM;
1839 break; /* from for */
1840 }
1841 } /* end for */
1842
1843 /* if data and types extracted successfully... */
1844 if( SQLITE_ROW == rc ){
1845 /* call the supplied callback with the result row data */
1846 if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
1847 rc = SQLITE_ABORT;
1848 }else{
1849 rc = sqlite3_step(pStmt);
1850 }
1851 }
1852 } while( SQLITE_ROW == rc );
1853 sqlite3_free(pData);
1854 }
1855 }else{
1856 do{
1857 rc = sqlite3_step(pStmt);
1858 } while( rc == SQLITE_ROW );
1859 }
1860 }
1861}
1862
1863/*
mistachkin1fe36bb2016-04-04 02:16:44 +00001864** Execute a statement or set of statements. Print
1865** any result rows/columns depending on the current mode
shane626a6e42009-10-22 17:30:15 +00001866** set via the supplied callback.
1867**
mistachkin1fe36bb2016-04-04 02:16:44 +00001868** This is very similar to SQLite's built-in sqlite3_exec()
1869** function except it takes a slightly different callback
shane626a6e42009-10-22 17:30:15 +00001870** and callback data argument.
1871*/
1872static int shell_exec(
drhdcd87a92014-08-18 13:45:42 +00001873 sqlite3 *db, /* An open database */
1874 const char *zSql, /* SQL to be evaluated */
shane626a6e42009-10-22 17:30:15 +00001875 int (*xCallback)(void*,int,char**,char**,int*), /* Callback function */
drhdcd87a92014-08-18 13:45:42 +00001876 /* (not the same as sqlite3_exec) */
1877 ShellState *pArg, /* Pointer to ShellState */
1878 char **pzErrMsg /* Error msg written here */
shane626a6e42009-10-22 17:30:15 +00001879){
dan4564ced2010-01-05 04:59:56 +00001880 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1881 int rc = SQLITE_OK; /* Return Code */
drhb07028f2011-10-14 21:49:18 +00001882 int rc2;
dan4564ced2010-01-05 04:59:56 +00001883 const char *zLeftover; /* Tail of unprocessed SQL */
shane626a6e42009-10-22 17:30:15 +00001884
1885 if( pzErrMsg ){
1886 *pzErrMsg = NULL;
1887 }
1888
shaneb9fc17d2009-10-22 21:23:35 +00001889 while( zSql[0] && (SQLITE_OK == rc) ){
drheacd29d2016-04-15 15:03:27 +00001890 static const char *zStmtSql;
shaneb9fc17d2009-10-22 21:23:35 +00001891 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1892 if( SQLITE_OK != rc ){
shane626a6e42009-10-22 17:30:15 +00001893 if( pzErrMsg ){
1894 *pzErrMsg = save_err_msg(db);
1895 }
1896 }else{
shaneb9fc17d2009-10-22 21:23:35 +00001897 if( !pStmt ){
1898 /* this happens for a comment or white-space */
1899 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001900 while( IsSpace(zSql[0]) ) zSql++;
shaneb9fc17d2009-10-22 21:23:35 +00001901 continue;
1902 }
drheacd29d2016-04-15 15:03:27 +00001903 zStmtSql = sqlite3_sql(pStmt);
drh60275612016-11-03 02:25:30 +00001904 if( zStmtSql==0 ) zStmtSql = "";
drheacd29d2016-04-15 15:03:27 +00001905 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
shane626a6e42009-10-22 17:30:15 +00001906
shaneh642d8b82010-07-28 16:05:34 +00001907 /* save off the prepared statment handle and reset row count */
1908 if( pArg ){
1909 pArg->pStmt = pStmt;
1910 pArg->cnt = 0;
1911 }
1912
shanehb7977c52010-01-18 18:17:10 +00001913 /* echo the sql statement if echo on */
shaneh642d8b82010-07-28 16:05:34 +00001914 if( pArg && pArg->echoOn ){
drhe05461c2015-12-30 13:36:57 +00001915 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
drha8c62df2010-02-15 15:47:18 +00001916 }
shanehb7977c52010-01-18 18:17:10 +00001917
drhefbf3b12014-02-28 20:47:24 +00001918 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
drheacd29d2016-04-15 15:03:27 +00001919 if( pArg && pArg->autoEQP && sqlite3_strlike("EXPLAIN%",zStmtSql,0)!=0 ){
drhefbf3b12014-02-28 20:47:24 +00001920 sqlite3_stmt *pExplain;
drheacd29d2016-04-15 15:03:27 +00001921 char *zEQP;
1922 disable_debug_trace_modes();
1923 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
drhefbf3b12014-02-28 20:47:24 +00001924 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1925 if( rc==SQLITE_OK ){
1926 while( sqlite3_step(pExplain)==SQLITE_ROW ){
mistachkinaae280e2015-12-31 19:06:24 +00001927 raw_printf(pArg->out,"--EQP-- %d,",sqlite3_column_int(pExplain, 0));
1928 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
1929 raw_printf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
drhe05461c2015-12-30 13:36:57 +00001930 utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
drhefbf3b12014-02-28 20:47:24 +00001931 }
1932 }
1933 sqlite3_finalize(pExplain);
1934 sqlite3_free(zEQP);
drheacd29d2016-04-15 15:03:27 +00001935 if( pArg->autoEQP>=2 ){
1936 /* Also do an EXPLAIN for ".eqp full" mode */
1937 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
1938 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
1939 if( rc==SQLITE_OK ){
1940 pArg->cMode = MODE_Explain;
1941 explain_data_prepare(pArg, pExplain);
1942 exec_prepared_stmt(pArg, pExplain, xCallback);
1943 explain_data_delete(pArg);
1944 }
1945 sqlite3_finalize(pExplain);
1946 sqlite3_free(zEQP);
1947 }
1948 restore_debug_trace_modes();
drhefbf3b12014-02-28 20:47:24 +00001949 }
1950
drh700c2522016-02-09 18:39:25 +00001951 if( pArg ){
1952 pArg->cMode = pArg->mode;
drh87a24aa2016-02-09 20:04:07 +00001953 if( pArg->autoExplain
1954 && sqlite3_column_count(pStmt)==8
drheacd29d2016-04-15 15:03:27 +00001955 && sqlite3_strlike("EXPLAIN%", zStmtSql,0)==0
drh700c2522016-02-09 18:39:25 +00001956 ){
1957 pArg->cMode = MODE_Explain;
1958 }
mistachkin1fe36bb2016-04-04 02:16:44 +00001959
drh700c2522016-02-09 18:39:25 +00001960 /* If the shell is currently in ".explain" mode, gather the extra
1961 ** data required to add indents to the output.*/
1962 if( pArg->cMode==MODE_Explain ){
1963 explain_data_prepare(pArg, pStmt);
1964 }
dana98bf362013-11-13 18:35:01 +00001965 }
1966
drheacd29d2016-04-15 15:03:27 +00001967 exec_prepared_stmt(pArg, pStmt, xCallback);
dana98bf362013-11-13 18:35:01 +00001968 explain_data_delete(pArg);
1969
shaneh642d8b82010-07-28 16:05:34 +00001970 /* print usage stats if stats on */
1971 if( pArg && pArg->statsOn ){
1972 display_stats(db, pArg, 0);
1973 }
1974
dan8d1edb92014-11-05 09:07:28 +00001975 /* print loop-counters if required */
1976 if( pArg && pArg->scanstatsOn ){
1977 display_scanstats(db, pArg);
1978 }
1979
mistachkin1fe36bb2016-04-04 02:16:44 +00001980 /* Finalize the statement just executed. If this fails, save a
dan4564ced2010-01-05 04:59:56 +00001981 ** copy of the error message. Otherwise, set zSql to point to the
1982 ** next statement to execute. */
drhb07028f2011-10-14 21:49:18 +00001983 rc2 = sqlite3_finalize(pStmt);
1984 if( rc!=SQLITE_NOMEM ) rc = rc2;
dan4564ced2010-01-05 04:59:56 +00001985 if( rc==SQLITE_OK ){
shaneb9fc17d2009-10-22 21:23:35 +00001986 zSql = zLeftover;
drhf0693c82011-10-11 20:41:54 +00001987 while( IsSpace(zSql[0]) ) zSql++;
dan4564ced2010-01-05 04:59:56 +00001988 }else if( pzErrMsg ){
1989 *pzErrMsg = save_err_msg(db);
shane626a6e42009-10-22 17:30:15 +00001990 }
shaneh642d8b82010-07-28 16:05:34 +00001991
1992 /* clear saved stmt handle */
1993 if( pArg ){
1994 pArg->pStmt = NULL;
1995 }
shane626a6e42009-10-22 17:30:15 +00001996 }
shaneb9fc17d2009-10-22 21:23:35 +00001997 } /* end while */
shane626a6e42009-10-22 17:30:15 +00001998
1999 return rc;
2000}
2001
drhdd3d4592004-08-30 01:54:05 +00002002
drh33048c02001-10-01 14:29:22 +00002003/*
drh4c653a02000-06-07 01:27:47 +00002004** This is a different callback routine used for dumping the database.
2005** Each row received by this callback consists of a table name,
2006** the table type ("index" or "table") and SQL to create the table.
2007** This routine should print text sufficient to recreate the table.
2008*/
2009static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
danielk19772a02e332004-06-05 08:04:36 +00002010 int rc;
2011 const char *zTable;
2012 const char *zType;
2013 const char *zSql;
drh157e29a2009-05-21 15:15:00 +00002014 const char *zPrepStmt = 0;
drhdcd87a92014-08-18 13:45:42 +00002015 ShellState *p = (ShellState *)pArg;
danielk19772a02e332004-06-05 08:04:36 +00002016
drh902b9ee2008-12-05 17:17:07 +00002017 UNUSED_PARAMETER(azCol);
drh4c653a02000-06-07 01:27:47 +00002018 if( nArg!=3 ) return 1;
danielk19772a02e332004-06-05 08:04:36 +00002019 zTable = azArg[0];
2020 zType = azArg[1];
2021 zSql = azArg[2];
mistachkin1fe36bb2016-04-04 02:16:44 +00002022
drh00b950d2005-09-11 02:03:03 +00002023 if( strcmp(zTable, "sqlite_sequence")==0 ){
drh157e29a2009-05-21 15:15:00 +00002024 zPrepStmt = "DELETE FROM sqlite_sequence;\n";
drh7ed10322013-08-07 16:04:27 +00002025 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002026 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh00b950d2005-09-11 02:03:03 +00002027 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
2028 return 0;
drh45e29d82006-11-20 16:21:10 +00002029 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
2030 char *zIns;
2031 if( !p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00002032 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
drh45e29d82006-11-20 16:21:10 +00002033 p->writableSchema = 1;
2034 }
2035 zIns = sqlite3_mprintf(
2036 "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
2037 "VALUES('table','%q','%q',0,'%q');",
2038 zTable, zTable, zSql);
drhe05461c2015-12-30 13:36:57 +00002039 utf8_printf(p->out, "%s\n", zIns);
drh45e29d82006-11-20 16:21:10 +00002040 sqlite3_free(zIns);
2041 return 0;
drh00b950d2005-09-11 02:03:03 +00002042 }else{
drhe05461c2015-12-30 13:36:57 +00002043 utf8_printf(p->out, "%s;\n", zSql);
drhf8eb96a2005-02-03 00:42:34 +00002044 }
danielk19772a02e332004-06-05 08:04:36 +00002045
2046 if( strcmp(zType, "table")==0 ){
2047 sqlite3_stmt *pTableInfo = 0;
danielk19772a02e332004-06-05 08:04:36 +00002048 char *zSelect = 0;
2049 char *zTableInfo = 0;
2050 char *zTmp = 0;
drh157e29a2009-05-21 15:15:00 +00002051 int nRow = 0;
mistachkin1fe36bb2016-04-04 02:16:44 +00002052
danielk19772a02e332004-06-05 08:04:36 +00002053 zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
2054 zTableInfo = appendText(zTableInfo, zTable, '"');
2055 zTableInfo = appendText(zTableInfo, ");", 0);
2056
drhc7181902014-02-27 15:04:13 +00002057 rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
drh157e29a2009-05-21 15:15:00 +00002058 free(zTableInfo);
danielk19772a02e332004-06-05 08:04:36 +00002059 if( rc!=SQLITE_OK || !pTableInfo ){
2060 return 1;
2061 }
2062
2063 zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
drhbf92ec02012-03-22 12:50:34 +00002064 /* Always quote the table name, even if it appears to be pure ascii,
2065 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
2066 zTmp = appendText(zTmp, zTable, '"');
danielk19772a02e332004-06-05 08:04:36 +00002067 if( zTmp ){
2068 zSelect = appendText(zSelect, zTmp, '\'');
drh85e72432012-04-11 11:38:53 +00002069 free(zTmp);
danielk19772a02e332004-06-05 08:04:36 +00002070 }
2071 zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
2072 rc = sqlite3_step(pTableInfo);
2073 while( rc==SQLITE_ROW ){
danielk19772e588c72005-12-09 14:25:08 +00002074 const char *zText = (const char *)sqlite3_column_text(pTableInfo, 1);
danielk19773f41e972004-06-08 00:39:01 +00002075 zSelect = appendText(zSelect, "quote(", 0);
danielk19772e588c72005-12-09 14:25:08 +00002076 zSelect = appendText(zSelect, zText, '"');
danielk19772a02e332004-06-05 08:04:36 +00002077 rc = sqlite3_step(pTableInfo);
2078 if( rc==SQLITE_ROW ){
drhb21a8e42012-01-28 21:08:51 +00002079 zSelect = appendText(zSelect, "), ", 0);
danielk19772a02e332004-06-05 08:04:36 +00002080 }else{
2081 zSelect = appendText(zSelect, ") ", 0);
2082 }
drh157e29a2009-05-21 15:15:00 +00002083 nRow++;
danielk19772a02e332004-06-05 08:04:36 +00002084 }
2085 rc = sqlite3_finalize(pTableInfo);
drh157e29a2009-05-21 15:15:00 +00002086 if( rc!=SQLITE_OK || nRow==0 ){
2087 free(zSelect);
danielk19772a02e332004-06-05 08:04:36 +00002088 return 1;
2089 }
2090 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
2091 zSelect = appendText(zSelect, zTable, '"');
2092
drh2f464a02011-10-13 00:41:49 +00002093 rc = run_table_dump_query(p, zSelect, zPrepStmt);
drhdd3d4592004-08-30 01:54:05 +00002094 if( rc==SQLITE_CORRUPT ){
2095 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
drh2f464a02011-10-13 00:41:49 +00002096 run_table_dump_query(p, zSelect, 0);
drhdd3d4592004-08-30 01:54:05 +00002097 }
drh85e72432012-04-11 11:38:53 +00002098 free(zSelect);
drh4c653a02000-06-07 01:27:47 +00002099 }
drh4c653a02000-06-07 01:27:47 +00002100 return 0;
2101}
2102
2103/*
drh45e29d82006-11-20 16:21:10 +00002104** Run zQuery. Use dump_callback() as the callback routine so that
2105** the contents of the query are output as SQL statements.
2106**
drhdd3d4592004-08-30 01:54:05 +00002107** If we get a SQLITE_CORRUPT error, rerun the query after appending
2108** "ORDER BY rowid DESC" to the end.
2109*/
2110static int run_schema_dump_query(
mistachkin1fe36bb2016-04-04 02:16:44 +00002111 ShellState *p,
drh2f464a02011-10-13 00:41:49 +00002112 const char *zQuery
drhdd3d4592004-08-30 01:54:05 +00002113){
2114 int rc;
drh2f464a02011-10-13 00:41:49 +00002115 char *zErr = 0;
2116 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
drhdd3d4592004-08-30 01:54:05 +00002117 if( rc==SQLITE_CORRUPT ){
2118 char *zQ2;
drh4f21c4a2008-12-10 22:15:00 +00002119 int len = strlen30(zQuery);
mistachkinaae280e2015-12-31 19:06:24 +00002120 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
drh2f464a02011-10-13 00:41:49 +00002121 if( zErr ){
mistachkinaae280e2015-12-31 19:06:24 +00002122 utf8_printf(p->out, "/****** %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002123 sqlite3_free(zErr);
2124 zErr = 0;
2125 }
drhdd3d4592004-08-30 01:54:05 +00002126 zQ2 = malloc( len+100 );
2127 if( zQ2==0 ) return rc;
drh8c5058b2012-04-16 17:22:30 +00002128 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
drh2f464a02011-10-13 00:41:49 +00002129 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
2130 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002131 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
drh2f464a02011-10-13 00:41:49 +00002132 }else{
2133 rc = SQLITE_CORRUPT;
2134 }
2135 sqlite3_free(zErr);
drhdd3d4592004-08-30 01:54:05 +00002136 free(zQ2);
2137 }
2138 return rc;
2139}
2140
2141/*
drh75897232000-05-29 14:26:00 +00002142** Text of a help message
2143*/
persicom1d0b8722002-04-18 02:53:04 +00002144static char zHelp[] =
drha0daa752016-09-16 11:53:10 +00002145#ifndef SQLITE_OMIT_AUTHORIZATION
drhde613c62016-04-04 17:23:10 +00002146 ".auth ON|OFF Show authorizer callbacks\n"
drha0daa752016-09-16 11:53:10 +00002147#endif
drh9ff849f2009-02-04 20:55:57 +00002148 ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
drhc2ce0be2014-05-29 12:36:14 +00002149 ".bail on|off Stop after hitting an error. Default OFF\n"
mistachkinf21979d2015-01-18 05:35:01 +00002150 ".binary on|off Turn binary output on or off. Default OFF\n"
drhdf12f1c2015-12-07 21:46:19 +00002151 ".changes on|off Show number of rows changed by SQL\n"
drh2db82112016-09-15 21:35:24 +00002152 ".check GLOB Fail if output since .testcase does not match\n"
drh4bbcf102014-02-06 02:46:08 +00002153 ".clone NEWDB Clone data into NEWDB from the existing database\n"
jplyon6a65bb32003-05-04 07:25:57 +00002154 ".databases List names and files of attached databases\n"
drh0e55db12015-02-06 14:51:13 +00002155 ".dbinfo ?DB? Show status information about the database\n"
drhb860bc92004-08-04 15:16:55 +00002156 ".dump ?TABLE? ... Dump the database in an SQL text format\n"
shane86f5bdb2009-10-24 02:00:07 +00002157 " If TABLE specified, only dump tables matching\n"
2158 " LIKE pattern TABLE.\n"
drhc2ce0be2014-05-29 12:36:14 +00002159 ".echo on|off Turn command echo on or off\n"
drheacd29d2016-04-15 15:03:27 +00002160 ".eqp on|off|full Enable or disable automatic EXPLAIN QUERY PLAN\n"
drh75897232000-05-29 14:26:00 +00002161 ".exit Exit this program\n"
drh700c2522016-02-09 18:39:25 +00002162 ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
drh4926fec2016-04-13 15:33:42 +00002163 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
drhc2ce0be2014-05-29 12:36:14 +00002164 ".headers on|off Turn display of headers on or off\n"
drh75897232000-05-29 14:26:00 +00002165 ".help Show this message\n"
drhb860bc92004-08-04 15:16:55 +00002166 ".import FILE TABLE Import data from FILE into TABLE\n"
drh16eb5942016-11-03 13:01:38 +00002167#ifndef SQLITE_OMIT_TEST_CONTROL
2168 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX\n"
2169#endif
drh0e55db12015-02-06 14:51:13 +00002170 ".indexes ?TABLE? Show names of all indexes\n"
2171 " If TABLE specified, only show indexes for tables\n"
shane86f5bdb2009-10-24 02:00:07 +00002172 " matching LIKE pattern TABLE.\n"
drhae5e4452007-05-03 17:18:36 +00002173#ifdef SQLITE_ENABLE_IOTRACE
2174 ".iotrace FILE Enable I/O diagnostic logging to FILE\n"
2175#endif
drh1a513372015-05-02 17:40:23 +00002176 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT\n"
drh70df4fe2006-06-13 15:12:21 +00002177#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh1e397f82006-06-08 15:28:43 +00002178 ".load FILE ?ENTRY? Load an extension library\n"
drh70df4fe2006-06-13 15:12:21 +00002179#endif
drh127f9d72010-02-23 01:47:00 +00002180 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout\n"
danielk19776b77a362005-01-13 11:10:25 +00002181 ".mode MODE ?TABLE? Set output mode where MODE is one of:\n"
mistachkine0d68852014-12-11 03:12:33 +00002182 " ascii Columns/rows delimited by 0x1F and 0x1E\n"
drh3b584fa2004-09-24 12:50:03 +00002183 " csv Comma-separated values\n"
drhb860bc92004-08-04 15:16:55 +00002184 " column Left-aligned columns. (See .width)\n"
2185 " html HTML <table> code\n"
2186 " insert SQL insert statements for TABLE\n"
2187 " line One value per line\n"
mistachkine0d68852014-12-11 03:12:33 +00002188 " list Values delimited by .separator strings\n"
drh41f5f6e2016-10-21 17:39:30 +00002189 " quote Escape answers as for SQL\n"
drhb860bc92004-08-04 15:16:55 +00002190 " tabs Tab-separated values\n"
2191 " tcl TCL list elements\n"
drh078b1fd2012-09-21 13:40:02 +00002192 ".nullvalue STRING Use STRING in place of NULL values\n"
drhc2ce0be2014-05-29 12:36:14 +00002193 ".once FILENAME Output for the next SQL command only to FILENAME\n"
mistachkin8145fc62016-09-16 20:39:21 +00002194 ".open ?--new? ?FILE? Close existing database and reopen FILE\n"
drhcd0509e2016-09-16 00:26:08 +00002195 " The --new starts with an empty file\n"
drhc2ce0be2014-05-29 12:36:14 +00002196 ".output ?FILENAME? Send output to FILENAME or stdout\n"
drh078b1fd2012-09-21 13:40:02 +00002197 ".print STRING... Print literal STRING\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002198 ".prompt MAIN CONTINUE Replace the standard prompts\n"
persicom7e2dfdd2002-04-18 02:46:52 +00002199 ".quit Exit this program\n"
drhdaffd0e2001-04-11 14:28:42 +00002200 ".read FILENAME Execute SQL in FILENAME\n"
drh9ff849f2009-02-04 20:55:57 +00002201 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
drh5c7976f2014-02-10 19:59:27 +00002202 ".save FILE Write in-memory database into FILE\n"
drh15f23c22014-11-06 12:46:16 +00002203 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off\n"
drh4926fec2016-04-13 15:33:42 +00002204 ".schema ?PATTERN? Show the CREATE statements matching PATTERN\n"
2205 " Add --indent for pretty-printing\n"
mistachkine0d68852014-12-11 03:12:33 +00002206 ".separator COL ?ROW? Change the column separator and optionally the row\n"
2207 " separator for both the output mode and .import\n"
drhe6229612014-08-18 15:08:26 +00002208#if defined(SQLITE_ENABLE_SESSION)
2209 ".session CMD ... Create or control sessions\n"
2210#endif
drh62cdde52014-05-28 20:22:28 +00002211 ".shell CMD ARGS... Run CMD ARGS... in a system shell\n"
drhdd45df82002-04-18 12:39:03 +00002212 ".show Show the current values for various settings\n"
drh34784902016-02-27 17:12:36 +00002213 ".stats ?on|off? Show stats or turn stats on or off\n"
drh62cdde52014-05-28 20:22:28 +00002214 ".system CMD ARGS... Run CMD ARGS... in a system shell\n"
shane86f5bdb2009-10-24 02:00:07 +00002215 ".tables ?TABLE? List names of tables\n"
2216 " If TABLE specified, only list tables matching\n"
2217 " LIKE pattern TABLE.\n"
drh760c8162016-09-16 02:52:22 +00002218 ".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
drh2dfbbca2000-07-28 14:32:48 +00002219 ".timeout MS Try opening locked tables for MS milliseconds\n"
drhc2ce0be2014-05-29 12:36:14 +00002220 ".timer on|off Turn SQL timer on or off\n"
drh42f64e52012-04-04 16:56:23 +00002221 ".trace FILE|off Output each SQL statement as it is run\n"
drh790f2872015-11-28 18:06:36 +00002222 ".vfsinfo ?AUX? Information about the top-level VFS\n"
drhb19e7352016-01-12 19:37:20 +00002223 ".vfslist List all available VFSes\n"
drhde60fc22011-12-14 17:53:36 +00002224 ".vfsname ?AUX? Print the name of the VFS stack\n"
shanehe2aa9d72009-11-06 17:20:17 +00002225 ".width NUM1 NUM2 ... Set column widths for \"column\" mode\n"
drh62cdde52014-05-28 20:22:28 +00002226 " Negative values right-justify\n"
drh75897232000-05-29 14:26:00 +00002227;
2228
drhe6229612014-08-18 15:08:26 +00002229#if defined(SQLITE_ENABLE_SESSION)
2230/*
2231** Print help information for the ".sessions" command
2232*/
2233void session_help(ShellState *p){
mistachkin899c5c92016-04-03 20:50:02 +00002234 raw_printf(p->out,
drhe6229612014-08-18 15:08:26 +00002235 ".session ?NAME? SUBCOMMAND ?ARGS...?\n"
2236 "If ?NAME? is omitted, the first defined session is used.\n"
2237 "Subcommands:\n"
2238 " attach TABLE Attach TABLE\n"
2239 " changeset FILE Write a changeset into FILE\n"
2240 " close Close one session\n"
2241 " enable ?BOOLEAN? Set or query the enable bit\n"
mistachkin1fe36bb2016-04-04 02:16:44 +00002242 " filter GLOB... Reject tables matching GLOBs\n"
drhe6229612014-08-18 15:08:26 +00002243 " indirect ?BOOLEAN? Mark or query the indirect status\n"
2244 " isempty Query whether the session is empty\n"
2245 " list List currently open session names\n"
2246 " open DB NAME Open a new session on DB\n"
2247 " patchset FILE Write a patchset into FILE\n"
2248 );
2249}
2250#endif
2251
2252
drhdaffd0e2001-04-11 14:28:42 +00002253/* Forward reference */
drhdcd87a92014-08-18 13:45:42 +00002254static int process_input(ShellState *p, FILE *in);
drh2db82112016-09-15 21:35:24 +00002255
2256
2257/*
2258** Read the content of a file into memory obtained from sqlite3_malloc64().
2259** The caller is responsible for freeing the memory.
2260**
2261** NULL is returned if any error is encountered.
2262*/
2263static char *readFile(const char *zName){
2264 FILE *in = fopen(zName, "rb");
2265 long nIn;
drhd1459152016-09-16 19:11:03 +00002266 size_t nRead;
drh2db82112016-09-15 21:35:24 +00002267 char *pBuf;
2268 if( in==0 ) return 0;
2269 fseek(in, 0, SEEK_END);
2270 nIn = ftell(in);
2271 rewind(in);
drhd1459152016-09-16 19:11:03 +00002272 pBuf = sqlite3_malloc64( nIn+1 );
drh2db82112016-09-15 21:35:24 +00002273 if( pBuf==0 ) return 0;
drhd1459152016-09-16 19:11:03 +00002274 nRead = fread(pBuf, nIn, 1, in);
2275 fclose(in);
2276 if( nRead!=1 ){
drh2db82112016-09-15 21:35:24 +00002277 sqlite3_free(pBuf);
2278 return 0;
2279 }
drhd1459152016-09-16 19:11:03 +00002280 pBuf[nIn] = 0;
drh2db82112016-09-15 21:35:24 +00002281 return pBuf;
2282}
2283
drhba5b0932014-07-24 12:39:59 +00002284/*
2285** Implementation of the "readfile(X)" SQL function. The entire content
2286** of the file named X is read and returned as a BLOB. NULL is returned
2287** if the file does not exist or is unreadable.
2288*/
2289static void readfileFunc(
2290 sqlite3_context *context,
2291 int argc,
2292 sqlite3_value **argv
2293){
2294 const char *zName;
drhba5b0932014-07-24 12:39:59 +00002295 void *pBuf;
2296
drhf5ed7ad2015-06-15 14:43:25 +00002297 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002298 zName = (const char*)sqlite3_value_text(argv[0]);
2299 if( zName==0 ) return;
drh2db82112016-09-15 21:35:24 +00002300 pBuf = readFile(zName);
2301 if( pBuf ) sqlite3_result_blob(context, pBuf, -1, sqlite3_free);
drhba5b0932014-07-24 12:39:59 +00002302}
2303
2304/*
2305** Implementation of the "writefile(X,Y)" SQL function. The argument Y
2306** is written into file X. The number of bytes written is returned. Or
2307** NULL is returned if something goes wrong, such as being unable to open
2308** file X for writing.
2309*/
2310static void writefileFunc(
2311 sqlite3_context *context,
2312 int argc,
2313 sqlite3_value **argv
2314){
2315 FILE *out;
2316 const char *z;
drhba5b0932014-07-24 12:39:59 +00002317 sqlite3_int64 rc;
2318 const char *zFile;
2319
drhf5ed7ad2015-06-15 14:43:25 +00002320 UNUSED_PARAMETER(argc);
drhba5b0932014-07-24 12:39:59 +00002321 zFile = (const char*)sqlite3_value_text(argv[0]);
2322 if( zFile==0 ) return;
2323 out = fopen(zFile, "wb");
2324 if( out==0 ) return;
2325 z = (const char*)sqlite3_value_blob(argv[1]);
2326 if( z==0 ){
drhba5b0932014-07-24 12:39:59 +00002327 rc = 0;
2328 }else{
drh490fe862014-08-11 14:21:32 +00002329 rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
drhba5b0932014-07-24 12:39:59 +00002330 }
2331 fclose(out);
2332 sqlite3_result_int64(context, rc);
2333}
drhdaffd0e2001-04-11 14:28:42 +00002334
drhe6229612014-08-18 15:08:26 +00002335#if defined(SQLITE_ENABLE_SESSION)
2336/*
2337** Close a single OpenSession object and release all of its associated
2338** resources.
2339*/
2340static void session_close(OpenSession *pSession){
2341 int i;
2342 sqlite3session_delete(pSession->p);
2343 sqlite3_free(pSession->zName);
2344 for(i=0; i<pSession->nFilter; i++){
2345 sqlite3_free(pSession->azFilter[i]);
2346 }
2347 sqlite3_free(pSession->azFilter);
2348 memset(pSession, 0, sizeof(OpenSession));
2349}
2350#endif
2351
2352/*
drh51b55a32016-04-04 12:38:05 +00002353** Close all OpenSession objects and release all associated resources.
drhe6229612014-08-18 15:08:26 +00002354*/
drhe6229612014-08-18 15:08:26 +00002355#if defined(SQLITE_ENABLE_SESSION)
drh51b55a32016-04-04 12:38:05 +00002356static void session_close_all(ShellState *p){
drhe6229612014-08-18 15:08:26 +00002357 int i;
2358 for(i=0; i<p->nSession; i++){
2359 session_close(&p->aSession[i]);
2360 }
2361 p->nSession = 0;
drhe6229612014-08-18 15:08:26 +00002362}
drh51b55a32016-04-04 12:38:05 +00002363#else
2364# define session_close_all(X)
2365#endif
drhe6229612014-08-18 15:08:26 +00002366
drh75897232000-05-29 14:26:00 +00002367/*
drh03168ca2014-08-18 20:01:31 +00002368** Implementation of the xFilter function for an open session. Omit
2369** any tables named by ".session filter" but let all other table through.
2370*/
2371#if defined(SQLITE_ENABLE_SESSION)
2372static int session_filter(void *pCtx, const char *zTab){
2373 OpenSession *pSession = (OpenSession*)pCtx;
2374 int i;
2375 for(i=0; i<pSession->nFilter; i++){
2376 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
2377 }
2378 return 1;
2379}
2380#endif
2381
2382/*
drh44c2eb12003-04-30 11:38:26 +00002383** Make sure the database is open. If it is not, then open it. If
2384** the database fails to open, print an error message and exit.
2385*/
drhdcd87a92014-08-18 13:45:42 +00002386static void open_db(ShellState *p, int keepAlive){
drh44c2eb12003-04-30 11:38:26 +00002387 if( p->db==0 ){
drhbbb0be82012-06-27 16:12:27 +00002388 sqlite3_initialize();
danielk19774f057f92004-06-08 00:02:33 +00002389 sqlite3_open(p->zDbFilename, &p->db);
mistachkin8e189222015-04-19 21:43:16 +00002390 globalDb = p->db;
2391 if( p->db && sqlite3_errcode(p->db)==SQLITE_OK ){
2392 sqlite3_create_function(p->db, "shellstatic", 0, SQLITE_UTF8, 0,
drh4cea5ba2008-05-05 16:27:24 +00002393 shellstaticFunc, 0, 0);
2394 }
mistachkin8e189222015-04-19 21:43:16 +00002395 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00002396 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
mistachkin8e189222015-04-19 21:43:16 +00002397 p->zDbFilename, sqlite3_errmsg(p->db));
drh05782482013-10-24 15:20:20 +00002398 if( keepAlive ) return;
drh22fbcb82004-02-01 01:22:50 +00002399 exit(1);
drh44c2eb12003-04-30 11:38:26 +00002400 }
drhc2e87a32006-06-27 15:16:14 +00002401#ifndef SQLITE_OMIT_LOAD_EXTENSION
2402 sqlite3_enable_load_extension(p->db, 1);
2403#endif
mistachkin8e189222015-04-19 21:43:16 +00002404 sqlite3_create_function(p->db, "readfile", 1, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002405 readfileFunc, 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00002406 sqlite3_create_function(p->db, "writefile", 2, SQLITE_UTF8, 0,
drhba5b0932014-07-24 12:39:59 +00002407 writefileFunc, 0, 0);
drh44c2eb12003-04-30 11:38:26 +00002408 }
2409}
2410
2411/*
drhfeac5f82004-08-01 00:10:45 +00002412** Do C-language style dequoting.
2413**
mistachkinf21979d2015-01-18 05:35:01 +00002414** \a -> alarm
2415** \b -> backspace
drhfeac5f82004-08-01 00:10:45 +00002416** \t -> tab
2417** \n -> newline
mistachkinf21979d2015-01-18 05:35:01 +00002418** \v -> vertical tab
2419** \f -> form feed
drhfeac5f82004-08-01 00:10:45 +00002420** \r -> carriage return
mistachkinf21979d2015-01-18 05:35:01 +00002421** \s -> space
drh4c56b992013-06-27 13:26:55 +00002422** \" -> "
mistachkinf21979d2015-01-18 05:35:01 +00002423** \' -> '
drhfeac5f82004-08-01 00:10:45 +00002424** \\ -> backslash
mistachkinf21979d2015-01-18 05:35:01 +00002425** \NNN -> ascii character NNN in octal
drhfeac5f82004-08-01 00:10:45 +00002426*/
2427static void resolve_backslashes(char *z){
shane7d3846a2008-12-11 02:58:26 +00002428 int i, j;
2429 char c;
drhc2ce0be2014-05-29 12:36:14 +00002430 while( *z && *z!='\\' ) z++;
drhfeac5f82004-08-01 00:10:45 +00002431 for(i=j=0; (c = z[i])!=0; i++, j++){
drh4b608032015-04-15 19:25:25 +00002432 if( c=='\\' && z[i+1]!=0 ){
drhfeac5f82004-08-01 00:10:45 +00002433 c = z[++i];
mistachkinf21979d2015-01-18 05:35:01 +00002434 if( c=='a' ){
2435 c = '\a';
2436 }else if( c=='b' ){
2437 c = '\b';
drhfeac5f82004-08-01 00:10:45 +00002438 }else if( c=='t' ){
2439 c = '\t';
mistachkinf21979d2015-01-18 05:35:01 +00002440 }else if( c=='n' ){
2441 c = '\n';
2442 }else if( c=='v' ){
2443 c = '\v';
2444 }else if( c=='f' ){
2445 c = '\f';
drhfeac5f82004-08-01 00:10:45 +00002446 }else if( c=='r' ){
2447 c = '\r';
mistachkinf21979d2015-01-18 05:35:01 +00002448 }else if( c=='"' ){
2449 c = '"';
2450 }else if( c=='\'' ){
2451 c = '\'';
drh4c56b992013-06-27 13:26:55 +00002452 }else if( c=='\\' ){
2453 c = '\\';
drhfeac5f82004-08-01 00:10:45 +00002454 }else if( c>='0' && c<='7' ){
drhaa816082005-12-29 12:53:09 +00002455 c -= '0';
drhfeac5f82004-08-01 00:10:45 +00002456 if( z[i+1]>='0' && z[i+1]<='7' ){
2457 i++;
2458 c = (c<<3) + z[i] - '0';
2459 if( z[i+1]>='0' && z[i+1]<='7' ){
2460 i++;
2461 c = (c<<3) + z[i] - '0';
2462 }
2463 }
2464 }
2465 }
2466 z[j] = c;
2467 }
drhc2ce0be2014-05-29 12:36:14 +00002468 if( j<i ) z[j] = 0;
drhfeac5f82004-08-01 00:10:45 +00002469}
2470
2471/*
drh348d19c2013-06-03 12:47:43 +00002472** Return the value of a hexadecimal digit. Return -1 if the input
2473** is not a hex digit.
drhc28490c2006-10-26 14:25:58 +00002474*/
drh348d19c2013-06-03 12:47:43 +00002475static int hexDigitValue(char c){
2476 if( c>='0' && c<='9' ) return c - '0';
2477 if( c>='a' && c<='f' ) return c - 'a' + 10;
2478 if( c>='A' && c<='F' ) return c - 'A' + 10;
2479 return -1;
drhc28490c2006-10-26 14:25:58 +00002480}
2481
2482/*
drh7d9f3942013-04-03 01:26:54 +00002483** Interpret zArg as an integer value, possibly with suffixes.
2484*/
2485static sqlite3_int64 integerValue(const char *zArg){
2486 sqlite3_int64 v = 0;
2487 static const struct { char *zSuffix; int iMult; } aMult[] = {
2488 { "KiB", 1024 },
2489 { "MiB", 1024*1024 },
2490 { "GiB", 1024*1024*1024 },
2491 { "KB", 1000 },
2492 { "MB", 1000000 },
2493 { "GB", 1000000000 },
2494 { "K", 1000 },
2495 { "M", 1000000 },
2496 { "G", 1000000000 },
2497 };
2498 int i;
2499 int isNeg = 0;
2500 if( zArg[0]=='-' ){
2501 isNeg = 1;
2502 zArg++;
2503 }else if( zArg[0]=='+' ){
2504 zArg++;
2505 }
drh348d19c2013-06-03 12:47:43 +00002506 if( zArg[0]=='0' && zArg[1]=='x' ){
2507 int x;
2508 zArg += 2;
2509 while( (x = hexDigitValue(zArg[0]))>=0 ){
2510 v = (v<<4) + x;
2511 zArg++;
2512 }
2513 }else{
2514 while( IsDigit(zArg[0]) ){
2515 v = v*10 + zArg[0] - '0';
2516 zArg++;
2517 }
drh7d9f3942013-04-03 01:26:54 +00002518 }
drhc2bed0a2013-05-24 11:57:50 +00002519 for(i=0; i<ArraySize(aMult); i++){
drh7d9f3942013-04-03 01:26:54 +00002520 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
2521 v *= aMult[i].iMult;
2522 break;
2523 }
2524 }
2525 return isNeg? -v : v;
2526}
2527
2528/*
drh348d19c2013-06-03 12:47:43 +00002529** Interpret zArg as either an integer or a boolean value. Return 1 or 0
2530** for TRUE and FALSE. Return the integer value if appropriate.
2531*/
2532static int booleanValue(char *zArg){
2533 int i;
2534 if( zArg[0]=='0' && zArg[1]=='x' ){
2535 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
2536 }else{
2537 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
2538 }
2539 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
2540 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
2541 return 1;
2542 }
2543 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
2544 return 0;
2545 }
mistachkinaae280e2015-12-31 19:06:24 +00002546 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
drh348d19c2013-06-03 12:47:43 +00002547 zArg);
2548 return 0;
2549}
2550
2551/*
drh42f64e52012-04-04 16:56:23 +00002552** Close an output file, assuming it is not stderr or stdout
2553*/
2554static void output_file_close(FILE *f){
2555 if( f && f!=stdout && f!=stderr ) fclose(f);
2556}
2557
2558/*
2559** Try to open an output file. The names "stdout" and "stderr" are
mistachkin1fe36bb2016-04-04 02:16:44 +00002560** recognized and do the right thing. NULL is returned if the output
drh42f64e52012-04-04 16:56:23 +00002561** filename is "off".
2562*/
2563static FILE *output_file_open(const char *zFile){
2564 FILE *f;
2565 if( strcmp(zFile,"stdout")==0 ){
2566 f = stdout;
2567 }else if( strcmp(zFile, "stderr")==0 ){
2568 f = stderr;
2569 }else if( strcmp(zFile, "off")==0 ){
2570 f = 0;
2571 }else{
2572 f = fopen(zFile, "wb");
2573 if( f==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002574 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00002575 }
2576 }
2577 return f;
2578}
2579
2580/*
2581** A routine for handling output from sqlite3_trace().
2582*/
drh4b363a52016-07-23 20:27:41 +00002583static int sql_trace_callback(
2584 unsigned mType,
2585 void *pArg,
2586 void *pP,
2587 void *pX
2588){
drh42f64e52012-04-04 16:56:23 +00002589 FILE *f = (FILE*)pArg;
drhb0df5402016-08-01 17:06:44 +00002590 UNUSED_PARAMETER(mType);
2591 UNUSED_PARAMETER(pP);
drh4b2590e2014-08-19 19:28:00 +00002592 if( f ){
drh4b363a52016-07-23 20:27:41 +00002593 const char *z = (const char*)pX;
drh4b2590e2014-08-19 19:28:00 +00002594 int i = (int)strlen(z);
2595 while( i>0 && z[i-1]==';' ){ i--; }
drhe05461c2015-12-30 13:36:57 +00002596 utf8_printf(f, "%.*s;\n", i, z);
drh4b2590e2014-08-19 19:28:00 +00002597 }
drh4b363a52016-07-23 20:27:41 +00002598 return 0;
drh42f64e52012-04-04 16:56:23 +00002599}
2600
2601/*
drhd8621b92012-04-17 09:09:33 +00002602** A no-op routine that runs with the ".breakpoint" doc-command. This is
2603** a useful spot to set a debugger breakpoint.
2604*/
2605static void test_breakpoint(void){
2606 static int nCall = 0;
2607 nCall++;
2608}
2609
2610/*
mistachkin636bf9f2014-07-19 20:15:16 +00002611** An object used to read a CSV and other files for import.
drhdb95f682013-06-26 22:46:00 +00002612*/
mistachkin636bf9f2014-07-19 20:15:16 +00002613typedef struct ImportCtx ImportCtx;
2614struct ImportCtx {
drhdb95f682013-06-26 22:46:00 +00002615 const char *zFile; /* Name of the input file */
2616 FILE *in; /* Read the CSV text from this input stream */
2617 char *z; /* Accumulated text for a field */
2618 int n; /* Number of bytes in z */
2619 int nAlloc; /* Space allocated for z[] */
2620 int nLine; /* Current line number */
2621 int cTerm; /* Character that terminated the most recent field */
mistachkin636bf9f2014-07-19 20:15:16 +00002622 int cColSep; /* The column separator character. (Usually ",") */
2623 int cRowSep; /* The row separator character. (Usually "\n") */
drhdb95f682013-06-26 22:46:00 +00002624};
2625
2626/* Append a single byte to z[] */
mistachkin636bf9f2014-07-19 20:15:16 +00002627static void import_append_char(ImportCtx *p, int c){
drhdb95f682013-06-26 22:46:00 +00002628 if( p->n+1>=p->nAlloc ){
2629 p->nAlloc += p->nAlloc + 100;
drhf3cdcdc2015-04-29 16:50:28 +00002630 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drhdb95f682013-06-26 22:46:00 +00002631 if( p->z==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002632 raw_printf(stderr, "out of memory\n");
drhdb95f682013-06-26 22:46:00 +00002633 exit(1);
2634 }
2635 }
2636 p->z[p->n++] = (char)c;
2637}
2638
2639/* Read a single field of CSV text. Compatible with rfc4180 and extended
2640** with the option of having a separator other than ",".
2641**
2642** + Input comes from p->in.
2643** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002644** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002645** + Use p->cSep as the column separator. The default is ",".
2646** + Use p->rSep as the row separator. The default is "\n".
drhdb95f682013-06-26 22:46:00 +00002647** + Keep track of the line number in p->nLine.
2648** + Store the character that terminates the field in p->cTerm. Store
2649** EOF on end-of-file.
2650** + Report syntax errors on stderr
2651*/
mistachkin44723ce2015-03-21 02:22:37 +00002652static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002653 int c;
2654 int cSep = p->cColSep;
2655 int rSep = p->cRowSep;
drhdb95f682013-06-26 22:46:00 +00002656 p->n = 0;
2657 c = fgetc(p->in);
2658 if( c==EOF || seenInterrupt ){
2659 p->cTerm = EOF;
2660 return 0;
2661 }
2662 if( c=='"' ){
mistachkin636bf9f2014-07-19 20:15:16 +00002663 int pc, ppc;
drhdb95f682013-06-26 22:46:00 +00002664 int startLine = p->nLine;
2665 int cQuote = c;
drha81ad172013-12-11 14:00:04 +00002666 pc = ppc = 0;
drhdb95f682013-06-26 22:46:00 +00002667 while( 1 ){
2668 c = fgetc(p->in);
mistachkin636bf9f2014-07-19 20:15:16 +00002669 if( c==rSep ) p->nLine++;
drhdb95f682013-06-26 22:46:00 +00002670 if( c==cQuote ){
2671 if( pc==cQuote ){
2672 pc = 0;
2673 continue;
2674 }
2675 }
2676 if( (c==cSep && pc==cQuote)
mistachkin636bf9f2014-07-19 20:15:16 +00002677 || (c==rSep && pc==cQuote)
2678 || (c==rSep && pc=='\r' && ppc==cQuote)
drhdb95f682013-06-26 22:46:00 +00002679 || (c==EOF && pc==cQuote)
2680 ){
2681 do{ p->n--; }while( p->z[p->n]!=cQuote );
drhdb95f682013-06-26 22:46:00 +00002682 p->cTerm = c;
2683 break;
2684 }
2685 if( pc==cQuote && c!='\r' ){
mistachkinaae280e2015-12-31 19:06:24 +00002686 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
drhdb95f682013-06-26 22:46:00 +00002687 p->zFile, p->nLine, cQuote);
2688 }
2689 if( c==EOF ){
mistachkinaae280e2015-12-31 19:06:24 +00002690 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
drhdb95f682013-06-26 22:46:00 +00002691 p->zFile, startLine, cQuote);
mistachkin636bf9f2014-07-19 20:15:16 +00002692 p->cTerm = c;
drhdb95f682013-06-26 22:46:00 +00002693 break;
2694 }
mistachkin636bf9f2014-07-19 20:15:16 +00002695 import_append_char(p, c);
drha81ad172013-12-11 14:00:04 +00002696 ppc = pc;
drhdb95f682013-06-26 22:46:00 +00002697 pc = c;
drhd0a64dc2013-06-30 20:24:26 +00002698 }
drhdb95f682013-06-26 22:46:00 +00002699 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00002700 while( c!=EOF && c!=cSep && c!=rSep ){
2701 import_append_char(p, c);
drhd0a64dc2013-06-30 20:24:26 +00002702 c = fgetc(p->in);
drhdb95f682013-06-26 22:46:00 +00002703 }
mistachkin636bf9f2014-07-19 20:15:16 +00002704 if( c==rSep ){
drhdb95f682013-06-26 22:46:00 +00002705 p->nLine++;
drh3852b682014-02-26 13:53:34 +00002706 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
drhdb95f682013-06-26 22:46:00 +00002707 }
drhdb95f682013-06-26 22:46:00 +00002708 p->cTerm = c;
2709 }
drh8dd675e2013-07-12 21:09:24 +00002710 if( p->z ) p->z[p->n] = 0;
drhdb95f682013-06-26 22:46:00 +00002711 return p->z;
2712}
2713
mistachkin636bf9f2014-07-19 20:15:16 +00002714/* Read a single field of ASCII delimited text.
2715**
2716** + Input comes from p->in.
2717** + Store results in p->z of length p->n. Space to hold p->z comes
drhf3cdcdc2015-04-29 16:50:28 +00002718** from sqlite3_malloc64().
mistachkin636bf9f2014-07-19 20:15:16 +00002719** + Use p->cSep as the column separator. The default is "\x1F".
2720** + Use p->rSep as the row separator. The default is "\x1E".
2721** + Keep track of the row number in p->nLine.
2722** + Store the character that terminates the field in p->cTerm. Store
2723** EOF on end-of-file.
2724** + Report syntax errors on stderr
2725*/
mistachkin44723ce2015-03-21 02:22:37 +00002726static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
mistachkin636bf9f2014-07-19 20:15:16 +00002727 int c;
2728 int cSep = p->cColSep;
2729 int rSep = p->cRowSep;
2730 p->n = 0;
2731 c = fgetc(p->in);
2732 if( c==EOF || seenInterrupt ){
2733 p->cTerm = EOF;
2734 return 0;
2735 }
2736 while( c!=EOF && c!=cSep && c!=rSep ){
2737 import_append_char(p, c);
2738 c = fgetc(p->in);
2739 }
2740 if( c==rSep ){
2741 p->nLine++;
2742 }
2743 p->cTerm = c;
2744 if( p->z ) p->z[p->n] = 0;
2745 return p->z;
2746}
2747
drhdb95f682013-06-26 22:46:00 +00002748/*
drh4bbcf102014-02-06 02:46:08 +00002749** Try to transfer data for table zTable. If an error is seen while
2750** moving forward, try to go backwards. The backwards movement won't
2751** work for WITHOUT ROWID tables.
drh3350ce92014-02-06 00:49:12 +00002752*/
mistachkine31ae902014-02-06 01:15:29 +00002753static void tryToCloneData(
drhdcd87a92014-08-18 13:45:42 +00002754 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002755 sqlite3 *newDb,
2756 const char *zTable
2757){
mistachkin1fe36bb2016-04-04 02:16:44 +00002758 sqlite3_stmt *pQuery = 0;
drh3350ce92014-02-06 00:49:12 +00002759 sqlite3_stmt *pInsert = 0;
2760 char *zQuery = 0;
2761 char *zInsert = 0;
2762 int rc;
2763 int i, j, n;
2764 int nTable = (int)strlen(zTable);
2765 int k = 0;
drh4bbcf102014-02-06 02:46:08 +00002766 int cnt = 0;
2767 const int spinRate = 10000;
drh3350ce92014-02-06 00:49:12 +00002768
2769 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
2770 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2771 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002772 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002773 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2774 zQuery);
2775 goto end_data_xfer;
2776 }
2777 n = sqlite3_column_count(pQuery);
drhf3cdcdc2015-04-29 16:50:28 +00002778 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh3350ce92014-02-06 00:49:12 +00002779 if( zInsert==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002780 raw_printf(stderr, "out of memory\n");
drh3350ce92014-02-06 00:49:12 +00002781 goto end_data_xfer;
2782 }
2783 sqlite3_snprintf(200+nTable,zInsert,
2784 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
2785 i = (int)strlen(zInsert);
2786 for(j=1; j<n; j++){
2787 memcpy(zInsert+i, ",?", 2);
2788 i += 2;
2789 }
2790 memcpy(zInsert+i, ");", 3);
2791 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
2792 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002793 utf8_printf(stderr, "Error %d: %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002794 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
2795 zQuery);
2796 goto end_data_xfer;
2797 }
2798 for(k=0; k<2; k++){
2799 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2800 for(i=0; i<n; i++){
2801 switch( sqlite3_column_type(pQuery, i) ){
2802 case SQLITE_NULL: {
2803 sqlite3_bind_null(pInsert, i+1);
2804 break;
2805 }
2806 case SQLITE_INTEGER: {
2807 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
2808 break;
2809 }
2810 case SQLITE_FLOAT: {
2811 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
2812 break;
2813 }
2814 case SQLITE_TEXT: {
2815 sqlite3_bind_text(pInsert, i+1,
2816 (const char*)sqlite3_column_text(pQuery,i),
2817 -1, SQLITE_STATIC);
2818 break;
2819 }
2820 case SQLITE_BLOB: {
2821 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
2822 sqlite3_column_bytes(pQuery,i),
2823 SQLITE_STATIC);
2824 break;
2825 }
2826 }
2827 } /* End for */
drh4bbcf102014-02-06 02:46:08 +00002828 rc = sqlite3_step(pInsert);
2829 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
mistachkinaae280e2015-12-31 19:06:24 +00002830 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
drh4bbcf102014-02-06 02:46:08 +00002831 sqlite3_errmsg(newDb));
2832 }
drh3350ce92014-02-06 00:49:12 +00002833 sqlite3_reset(pInsert);
drh4bbcf102014-02-06 02:46:08 +00002834 cnt++;
2835 if( (cnt%spinRate)==0 ){
2836 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
2837 fflush(stdout);
2838 }
drh3350ce92014-02-06 00:49:12 +00002839 } /* End while */
2840 if( rc==SQLITE_DONE ) break;
2841 sqlite3_finalize(pQuery);
2842 sqlite3_free(zQuery);
2843 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
2844 zTable);
2845 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2846 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002847 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
drh4bbcf102014-02-06 02:46:08 +00002848 break;
drh3350ce92014-02-06 00:49:12 +00002849 }
2850 } /* End for(k=0...) */
2851
2852end_data_xfer:
2853 sqlite3_finalize(pQuery);
2854 sqlite3_finalize(pInsert);
2855 sqlite3_free(zQuery);
2856 sqlite3_free(zInsert);
2857}
2858
2859
2860/*
2861** Try to transfer all rows of the schema that match zWhere. For
2862** each row, invoke xForEach() on the object defined by that row.
drh4bbcf102014-02-06 02:46:08 +00002863** If an error is encountered while moving forward through the
2864** sqlite_master table, try again moving backwards.
drh3350ce92014-02-06 00:49:12 +00002865*/
mistachkine31ae902014-02-06 01:15:29 +00002866static void tryToCloneSchema(
drhdcd87a92014-08-18 13:45:42 +00002867 ShellState *p,
drh3350ce92014-02-06 00:49:12 +00002868 sqlite3 *newDb,
2869 const char *zWhere,
drhdcd87a92014-08-18 13:45:42 +00002870 void (*xForEach)(ShellState*,sqlite3*,const char*)
drh3350ce92014-02-06 00:49:12 +00002871){
2872 sqlite3_stmt *pQuery = 0;
2873 char *zQuery = 0;
2874 int rc;
2875 const unsigned char *zName;
2876 const unsigned char *zSql;
drh4bbcf102014-02-06 02:46:08 +00002877 char *zErrMsg = 0;
drh3350ce92014-02-06 00:49:12 +00002878
2879 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2880 " WHERE %s", zWhere);
2881 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2882 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002883 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002884 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2885 zQuery);
2886 goto end_schema_xfer;
2887 }
2888 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2889 zName = sqlite3_column_text(pQuery, 0);
2890 zSql = sqlite3_column_text(pQuery, 1);
2891 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002892 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2893 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002894 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002895 sqlite3_free(zErrMsg);
2896 zErrMsg = 0;
2897 }
drh3350ce92014-02-06 00:49:12 +00002898 if( xForEach ){
2899 xForEach(p, newDb, (const char*)zName);
2900 }
2901 printf("done\n");
2902 }
2903 if( rc!=SQLITE_DONE ){
2904 sqlite3_finalize(pQuery);
2905 sqlite3_free(zQuery);
2906 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
2907 " WHERE %s ORDER BY rowid DESC", zWhere);
2908 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
2909 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002910 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
drh3350ce92014-02-06 00:49:12 +00002911 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
2912 zQuery);
2913 goto end_schema_xfer;
2914 }
2915 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
2916 zName = sqlite3_column_text(pQuery, 0);
2917 zSql = sqlite3_column_text(pQuery, 1);
2918 printf("%s... ", zName); fflush(stdout);
drh4bbcf102014-02-06 02:46:08 +00002919 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
2920 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00002921 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
drh4bbcf102014-02-06 02:46:08 +00002922 sqlite3_free(zErrMsg);
2923 zErrMsg = 0;
2924 }
drh3350ce92014-02-06 00:49:12 +00002925 if( xForEach ){
2926 xForEach(p, newDb, (const char*)zName);
2927 }
2928 printf("done\n");
2929 }
2930 }
2931end_schema_xfer:
2932 sqlite3_finalize(pQuery);
2933 sqlite3_free(zQuery);
2934}
2935
2936/*
2937** Open a new database file named "zNewDb". Try to recover as much information
2938** as possible out of the main database (which might be corrupt) and write it
2939** into zNewDb.
2940*/
drhdcd87a92014-08-18 13:45:42 +00002941static void tryToClone(ShellState *p, const char *zNewDb){
drh3350ce92014-02-06 00:49:12 +00002942 int rc;
2943 sqlite3 *newDb = 0;
2944 if( access(zNewDb,0)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00002945 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
drh3350ce92014-02-06 00:49:12 +00002946 return;
2947 }
2948 rc = sqlite3_open(zNewDb, &newDb);
2949 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00002950 utf8_printf(stderr, "Cannot create output database: %s\n",
drh3350ce92014-02-06 00:49:12 +00002951 sqlite3_errmsg(newDb));
2952 }else{
drh54d0d2d2014-04-03 00:32:13 +00002953 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002954 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
mistachkine31ae902014-02-06 01:15:29 +00002955 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
2956 tryToCloneSchema(p, newDb, "type!='table'", 0);
drh3350ce92014-02-06 00:49:12 +00002957 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
drh54d0d2d2014-04-03 00:32:13 +00002958 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
drh3350ce92014-02-06 00:49:12 +00002959 }
2960 sqlite3_close(newDb);
2961}
2962
2963/*
drhc2ce0be2014-05-29 12:36:14 +00002964** Change the output file back to stdout
2965*/
drhdcd87a92014-08-18 13:45:42 +00002966static void output_reset(ShellState *p){
drhc2ce0be2014-05-29 12:36:14 +00002967 if( p->outfile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00002968#ifndef SQLITE_OMIT_POPEN
drhc2ce0be2014-05-29 12:36:14 +00002969 pclose(p->out);
drh8cd5b252015-03-02 22:06:43 +00002970#endif
drhc2ce0be2014-05-29 12:36:14 +00002971 }else{
2972 output_file_close(p->out);
2973 }
2974 p->outfile[0] = 0;
2975 p->out = stdout;
2976}
2977
2978/*
drhf7502f02015-02-06 14:19:44 +00002979** Run an SQL command and return the single integer result.
2980*/
2981static int db_int(ShellState *p, const char *zSql){
2982 sqlite3_stmt *pStmt;
2983 int res = 0;
2984 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
2985 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
2986 res = sqlite3_column_int(pStmt,0);
2987 }
2988 sqlite3_finalize(pStmt);
2989 return res;
2990}
2991
2992/*
2993** Convert a 2-byte or 4-byte big-endian integer into a native integer
2994*/
drha0620ac2016-07-13 13:05:13 +00002995static unsigned int get2byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00002996 return (a[0]<<8) + a[1];
2997}
drha0620ac2016-07-13 13:05:13 +00002998static unsigned int get4byteInt(unsigned char *a){
drhf7502f02015-02-06 14:19:44 +00002999 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
3000}
3001
3002/*
3003** Implementation of the ".info" command.
3004**
3005** Return 1 on error, 2 to exit, and 0 otherwise.
3006*/
drh0e55db12015-02-06 14:51:13 +00003007static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
drhf7502f02015-02-06 14:19:44 +00003008 static const struct { const char *zName; int ofst; } aField[] = {
3009 { "file change counter:", 24 },
3010 { "database page count:", 28 },
3011 { "freelist page count:", 36 },
3012 { "schema cookie:", 40 },
3013 { "schema format:", 44 },
3014 { "default cache size:", 48 },
3015 { "autovacuum top root:", 52 },
3016 { "incremental vacuum:", 64 },
3017 { "text encoding:", 56 },
3018 { "user version:", 60 },
3019 { "application id:", 68 },
3020 { "software version:", 96 },
3021 };
drh0e55db12015-02-06 14:51:13 +00003022 static const struct { const char *zName; const char *zSql; } aQuery[] = {
3023 { "number of tables:",
3024 "SELECT count(*) FROM %s WHERE type='table'" },
3025 { "number of indexes:",
3026 "SELECT count(*) FROM %s WHERE type='index'" },
3027 { "number of triggers:",
3028 "SELECT count(*) FROM %s WHERE type='trigger'" },
3029 { "number of views:",
3030 "SELECT count(*) FROM %s WHERE type='view'" },
3031 { "schema size:",
3032 "SELECT total(length(sql)) FROM %s" },
3033 };
mistachkinbfe8bd52015-11-17 19:17:14 +00003034 sqlite3_file *pFile = 0;
drh0e55db12015-02-06 14:51:13 +00003035 int i;
3036 char *zSchemaTab;
3037 char *zDb = nArg>=2 ? azArg[1] : "main";
3038 unsigned char aHdr[100];
drhf7502f02015-02-06 14:19:44 +00003039 open_db(p, 0);
3040 if( p->db==0 ) return 1;
drh0e55db12015-02-06 14:51:13 +00003041 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
drhf7502f02015-02-06 14:19:44 +00003042 if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
3043 return 1;
3044 }
3045 i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
3046 if( i!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003047 raw_printf(stderr, "unable to read database header\n");
drhf7502f02015-02-06 14:19:44 +00003048 return 1;
3049 }
3050 i = get2byteInt(aHdr+16);
3051 if( i==1 ) i = 65536;
mistachkinaae280e2015-12-31 19:06:24 +00003052 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
3053 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
3054 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
3055 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
drhf5ed7ad2015-06-15 14:43:25 +00003056 for(i=0; i<ArraySize(aField); i++){
drhf7502f02015-02-06 14:19:44 +00003057 int ofst = aField[i].ofst;
3058 unsigned int val = get4byteInt(aHdr + ofst);
mistachkinaae280e2015-12-31 19:06:24 +00003059 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
drhf7502f02015-02-06 14:19:44 +00003060 switch( ofst ){
3061 case 56: {
mistachkin1fe36bb2016-04-04 02:16:44 +00003062 if( val==1 ) raw_printf(p->out, " (utf8)");
3063 if( val==2 ) raw_printf(p->out, " (utf16le)");
3064 if( val==3 ) raw_printf(p->out, " (utf16be)");
drhf7502f02015-02-06 14:19:44 +00003065 }
3066 }
mistachkinaae280e2015-12-31 19:06:24 +00003067 raw_printf(p->out, "\n");
drhf7502f02015-02-06 14:19:44 +00003068 }
drh0e55db12015-02-06 14:51:13 +00003069 if( zDb==0 ){
3070 zSchemaTab = sqlite3_mprintf("main.sqlite_master");
3071 }else if( strcmp(zDb,"temp")==0 ){
3072 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_master");
3073 }else{
3074 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
3075 }
drhf5ed7ad2015-06-15 14:43:25 +00003076 for(i=0; i<ArraySize(aQuery); i++){
drh0e55db12015-02-06 14:51:13 +00003077 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
3078 int val = db_int(p, zSql);
3079 sqlite3_free(zSql);
drhe05461c2015-12-30 13:36:57 +00003080 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
drh0e55db12015-02-06 14:51:13 +00003081 }
3082 sqlite3_free(zSchemaTab);
drhf7502f02015-02-06 14:19:44 +00003083 return 0;
3084}
3085
dand95bb392015-09-30 11:19:05 +00003086/*
3087** Print the current sqlite3_errmsg() value to stderr and return 1.
3088*/
3089static int shellDatabaseError(sqlite3 *db){
3090 const char *zErr = sqlite3_errmsg(db);
mistachkinaae280e2015-12-31 19:06:24 +00003091 utf8_printf(stderr, "Error: %s\n", zErr);
dand95bb392015-09-30 11:19:05 +00003092 return 1;
3093}
3094
3095/*
3096** Print an out-of-memory message to stderr and return 1.
3097*/
3098static int shellNomemError(void){
mistachkinaae280e2015-12-31 19:06:24 +00003099 raw_printf(stderr, "Error: out of memory\n");
dand95bb392015-09-30 11:19:05 +00003100 return 1;
3101}
drhf7502f02015-02-06 14:19:44 +00003102
drh2db82112016-09-15 21:35:24 +00003103/*
3104** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
3105** if they match and FALSE (0) if they do not match.
3106**
3107** Globbing rules:
3108**
3109** '*' Matches any sequence of zero or more characters.
3110**
3111** '?' Matches exactly one character.
3112**
3113** [...] Matches one character from the enclosed list of
3114** characters.
3115**
3116** [^...] Matches one character not in the enclosed list.
3117**
3118** '#' Matches any sequence of one or more digits with an
3119** optional + or - sign in front
3120**
3121** ' ' Any span of whitespace matches any other span of
3122** whitespace.
3123**
3124** Extra whitespace at the end of z[] is ignored.
3125*/
3126static int testcase_glob(const char *zGlob, const char *z){
3127 int c, c2;
3128 int invert;
3129 int seen;
3130
3131 while( (c = (*(zGlob++)))!=0 ){
3132 if( IsSpace(c) ){
3133 if( !IsSpace(*z) ) return 0;
3134 while( IsSpace(*zGlob) ) zGlob++;
3135 while( IsSpace(*z) ) z++;
3136 }else if( c=='*' ){
3137 while( (c=(*(zGlob++))) == '*' || c=='?' ){
3138 if( c=='?' && (*(z++))==0 ) return 0;
3139 }
3140 if( c==0 ){
3141 return 1;
3142 }else if( c=='[' ){
3143 while( *z && testcase_glob(zGlob-1,z)==0 ){
3144 z++;
3145 }
3146 return (*z)!=0;
3147 }
3148 while( (c2 = (*(z++)))!=0 ){
3149 while( c2!=c ){
3150 c2 = *(z++);
3151 if( c2==0 ) return 0;
3152 }
3153 if( testcase_glob(zGlob,z) ) return 1;
3154 }
3155 return 0;
3156 }else if( c=='?' ){
3157 if( (*(z++))==0 ) return 0;
3158 }else if( c=='[' ){
3159 int prior_c = 0;
3160 seen = 0;
3161 invert = 0;
3162 c = *(z++);
3163 if( c==0 ) return 0;
3164 c2 = *(zGlob++);
3165 if( c2=='^' ){
3166 invert = 1;
3167 c2 = *(zGlob++);
3168 }
3169 if( c2==']' ){
3170 if( c==']' ) seen = 1;
3171 c2 = *(zGlob++);
3172 }
3173 while( c2 && c2!=']' ){
3174 if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
3175 c2 = *(zGlob++);
3176 if( c>=prior_c && c<=c2 ) seen = 1;
3177 prior_c = 0;
3178 }else{
3179 if( c==c2 ){
3180 seen = 1;
3181 }
3182 prior_c = c2;
3183 }
3184 c2 = *(zGlob++);
3185 }
3186 if( c2==0 || (seen ^ invert)==0 ) return 0;
3187 }else if( c=='#' ){
3188 if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
3189 if( !IsDigit(z[0]) ) return 0;
3190 z++;
3191 while( IsDigit(z[0]) ){ z++; }
3192 }else{
3193 if( c!=(*(z++)) ) return 0;
3194 }
3195 }
3196 while( IsSpace(*z) ){ z++; }
3197 return *z==0;
3198}
drh2db82112016-09-15 21:35:24 +00003199
3200
drhf7502f02015-02-06 14:19:44 +00003201/*
drh4926fec2016-04-13 15:33:42 +00003202** Compare the string as a command-line option with either one or two
3203** initial "-" characters.
3204*/
3205static int optionMatch(const char *zStr, const char *zOpt){
3206 if( zStr[0]!='-' ) return 0;
3207 zStr++;
3208 if( zStr[0]=='-' ) zStr++;
3209 return strcmp(zStr, zOpt)==0;
3210}
3211
3212/*
drhcd0509e2016-09-16 00:26:08 +00003213** Delete a file.
3214*/
3215int shellDeleteFile(const char *zFilename){
3216 int rc;
3217#ifdef _WIN32
mistachkin8145fc62016-09-16 20:39:21 +00003218 wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
drhcd0509e2016-09-16 00:26:08 +00003219 rc = _wunlink(z);
3220 sqlite3_free(z);
3221#else
3222 rc = unlink(zFilename);
3223#endif
3224 return rc;
3225}
3226
3227/*
drh75897232000-05-29 14:26:00 +00003228** If an input line begins with "." then invoke this routine to
3229** process that line.
drh67505e72002-04-19 12:34:06 +00003230**
drh47ad6842006-11-08 12:25:42 +00003231** Return 1 on error, 2 to exit, and 0 otherwise.
drh75897232000-05-29 14:26:00 +00003232*/
drhdcd87a92014-08-18 13:45:42 +00003233static int do_meta_command(char *zLine, ShellState *p){
mistachkin8e189222015-04-19 21:43:16 +00003234 int h = 1;
drh75897232000-05-29 14:26:00 +00003235 int nArg = 0;
3236 int n, c;
drh67505e72002-04-19 12:34:06 +00003237 int rc = 0;
drh75897232000-05-29 14:26:00 +00003238 char *azArg[50];
3239
3240 /* Parse the input line into tokens.
3241 */
mistachkin8e189222015-04-19 21:43:16 +00003242 while( zLine[h] && nArg<ArraySize(azArg) ){
3243 while( IsSpace(zLine[h]) ){ h++; }
3244 if( zLine[h]==0 ) break;
3245 if( zLine[h]=='\'' || zLine[h]=='"' ){
3246 int delim = zLine[h++];
3247 azArg[nArg++] = &zLine[h];
mistachkin1fe36bb2016-04-04 02:16:44 +00003248 while( zLine[h] && zLine[h]!=delim ){
mistachkin8e189222015-04-19 21:43:16 +00003249 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
mistachkin1fe36bb2016-04-04 02:16:44 +00003250 h++;
drh4c56b992013-06-27 13:26:55 +00003251 }
mistachkin8e189222015-04-19 21:43:16 +00003252 if( zLine[h]==delim ){
3253 zLine[h++] = 0;
drh75897232000-05-29 14:26:00 +00003254 }
drhfeac5f82004-08-01 00:10:45 +00003255 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003256 }else{
mistachkin8e189222015-04-19 21:43:16 +00003257 azArg[nArg++] = &zLine[h];
3258 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
3259 if( zLine[h] ) zLine[h++] = 0;
drhfeac5f82004-08-01 00:10:45 +00003260 resolve_backslashes(azArg[nArg-1]);
drh75897232000-05-29 14:26:00 +00003261 }
3262 }
3263
3264 /* Process the input line.
3265 */
shane9bd1b442009-10-23 01:27:39 +00003266 if( nArg==0 ) return 0; /* no tokens, no error */
drh4f21c4a2008-12-10 22:15:00 +00003267 n = strlen30(azArg[0]);
drh75897232000-05-29 14:26:00 +00003268 c = azArg[0][0];
drhde613c62016-04-04 17:23:10 +00003269
drha0daa752016-09-16 11:53:10 +00003270#ifndef SQLITE_OMIT_AUTHORIZATION
drhde613c62016-04-04 17:23:10 +00003271 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
3272 if( nArg!=2 ){
3273 raw_printf(stderr, "Usage: .auth ON|OFF\n");
3274 rc = 1;
3275 goto meta_command_exit;
3276 }
3277 open_db(p, 0);
3278 if( booleanValue(azArg[1]) ){
3279 sqlite3_set_authorizer(p->db, shellAuth, p);
3280 }else{
3281 sqlite3_set_authorizer(p->db, 0, 0);
3282 }
3283 }else
drha0daa752016-09-16 11:53:10 +00003284#endif
drhde613c62016-04-04 17:23:10 +00003285
drh5c7976f2014-02-10 19:59:27 +00003286 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
3287 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
3288 ){
drhbc46f022013-01-23 18:53:23 +00003289 const char *zDestFile = 0;
3290 const char *zDb = 0;
drh9ff849f2009-02-04 20:55:57 +00003291 sqlite3 *pDest;
3292 sqlite3_backup *pBackup;
drhbc46f022013-01-23 18:53:23 +00003293 int j;
3294 for(j=1; j<nArg; j++){
3295 const char *z = azArg[j];
3296 if( z[0]=='-' ){
3297 while( z[0]=='-' ) z++;
drhaf664332013-07-18 20:28:29 +00003298 /* No options to process at this time */
drhbc46f022013-01-23 18:53:23 +00003299 {
mistachkinaae280e2015-12-31 19:06:24 +00003300 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
drhbc46f022013-01-23 18:53:23 +00003301 return 1;
3302 }
3303 }else if( zDestFile==0 ){
3304 zDestFile = azArg[j];
3305 }else if( zDb==0 ){
3306 zDb = zDestFile;
3307 zDestFile = azArg[j];
3308 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003309 raw_printf(stderr, "too many arguments to .backup\n");
drhbc46f022013-01-23 18:53:23 +00003310 return 1;
3311 }
drh9ff849f2009-02-04 20:55:57 +00003312 }
drhbc46f022013-01-23 18:53:23 +00003313 if( zDestFile==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003314 raw_printf(stderr, "missing FILENAME argument on .backup\n");
drhbc46f022013-01-23 18:53:23 +00003315 return 1;
3316 }
3317 if( zDb==0 ) zDb = "main";
drh9ff849f2009-02-04 20:55:57 +00003318 rc = sqlite3_open(zDestFile, &pDest);
3319 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003320 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9ff849f2009-02-04 20:55:57 +00003321 sqlite3_close(pDest);
3322 return 1;
3323 }
drh05782482013-10-24 15:20:20 +00003324 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00003325 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
3326 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003327 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9ff849f2009-02-04 20:55:57 +00003328 sqlite3_close(pDest);
3329 return 1;
3330 }
3331 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
3332 sqlite3_backup_finish(pBackup);
3333 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00003334 rc = 0;
drh9ff849f2009-02-04 20:55:57 +00003335 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003336 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
shane9bd1b442009-10-23 01:27:39 +00003337 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00003338 }
3339 sqlite3_close(pDest);
3340 }else
3341
drhc2ce0be2014-05-29 12:36:14 +00003342 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
3343 if( nArg==2 ){
3344 bail_on_error = booleanValue(azArg[1]);
3345 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003346 raw_printf(stderr, "Usage: .bail on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003347 rc = 1;
3348 }
drhc49f44e2006-10-26 18:15:42 +00003349 }else
3350
mistachkinf21979d2015-01-18 05:35:01 +00003351 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
3352 if( nArg==2 ){
mistachkinbdffff92015-01-19 20:22:33 +00003353 if( booleanValue(azArg[1]) ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003354 setBinaryMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003355 }else{
mistachkin1fe36bb2016-04-04 02:16:44 +00003356 setTextMode(p->out, 1);
mistachkinbdffff92015-01-19 20:22:33 +00003357 }
mistachkinf21979d2015-01-18 05:35:01 +00003358 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003359 raw_printf(stderr, "Usage: .binary on|off\n");
mistachkinf21979d2015-01-18 05:35:01 +00003360 rc = 1;
3361 }
3362 }else
3363
drhd8621b92012-04-17 09:09:33 +00003364 /* The undocumented ".breakpoint" command causes a call to the no-op
3365 ** routine named test_breakpoint().
3366 */
3367 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
3368 test_breakpoint();
3369 }else
3370
drhdf12f1c2015-12-07 21:46:19 +00003371 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
3372 if( nArg==2 ){
3373 p->countChanges = booleanValue(azArg[1]);
3374 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003375 raw_printf(stderr, "Usage: .changes on|off\n");
drhdf12f1c2015-12-07 21:46:19 +00003376 rc = 1;
3377 }
3378 }else
3379
drh2db82112016-09-15 21:35:24 +00003380 /* Cancel output redirection, if it is currently set (by .testcase)
3381 ** Then read the content of the testcase-out.txt file and compare against
3382 ** azArg[1]. If there are differences, report an error and exit.
3383 */
3384 if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
3385 char *zRes = 0;
3386 output_reset(p);
3387 if( nArg!=2 ){
3388 raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
drh760c8162016-09-16 02:52:22 +00003389 rc = 2;
drh2db82112016-09-15 21:35:24 +00003390 }else if( (zRes = readFile("testcase-out.txt"))==0 ){
3391 raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
3392 rc = 2;
3393 }else if( testcase_glob(azArg[1],zRes)==0 ){
mistachkin8145fc62016-09-16 20:39:21 +00003394 utf8_printf(stderr,
drh760c8162016-09-16 02:52:22 +00003395 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
3396 p->zTestcase, azArg[1], zRes);
drh2db82112016-09-15 21:35:24 +00003397 rc = 2;
drh760c8162016-09-16 02:52:22 +00003398 }else{
mistachkin8145fc62016-09-16 20:39:21 +00003399 utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
drh760c8162016-09-16 02:52:22 +00003400 p->nCheck++;
drh2db82112016-09-15 21:35:24 +00003401 }
3402 sqlite3_free(zRes);
3403 }else
drh2db82112016-09-15 21:35:24 +00003404
drhc2ce0be2014-05-29 12:36:14 +00003405 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
3406 if( nArg==2 ){
3407 tryToClone(p, azArg[1]);
3408 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003409 raw_printf(stderr, "Usage: .clone FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00003410 rc = 1;
3411 }
mistachkine31ae902014-02-06 01:15:29 +00003412 }else
3413
drhc2ce0be2014-05-29 12:36:14 +00003414 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003415 ShellState data;
jplyon672a1ed2003-05-11 20:07:05 +00003416 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003417 open_db(p, 0);
jplyon672a1ed2003-05-11 20:07:05 +00003418 memcpy(&data, p, sizeof(data));
drhd8885442004-03-17 23:42:12 +00003419 data.showHeader = 1;
drh700c2522016-02-09 18:39:25 +00003420 data.cMode = data.mode = MODE_Column;
drhd8885442004-03-17 23:42:12 +00003421 data.colWidth[0] = 3;
3422 data.colWidth[1] = 15;
3423 data.colWidth[2] = 58;
drh0b2110c2004-10-26 00:08:10 +00003424 data.cnt = 0;
danielk19776f8a5032004-05-10 10:34:51 +00003425 sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
jplyon672a1ed2003-05-11 20:07:05 +00003426 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003427 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003428 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003429 rc = 1;
jplyon6a65bb32003-05-04 07:25:57 +00003430 }
3431 }else
3432
drh0e55db12015-02-06 14:51:13 +00003433 if( c=='d' && strncmp(azArg[0], "dbinfo", n)==0 ){
3434 rc = shell_dbinfo_command(p, nArg, azArg);
3435 }else
3436
drhc2ce0be2014-05-29 12:36:14 +00003437 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh05782482013-10-24 15:20:20 +00003438 open_db(p, 0);
drhf1dfc4f2009-09-23 15:51:35 +00003439 /* When playing back a "dump", the content might appear in an order
3440 ** which causes immediate foreign key constraints to be violated.
3441 ** So disable foreign-key constraint enforcement to prevent problems. */
drhc2ce0be2014-05-29 12:36:14 +00003442 if( nArg!=1 && nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00003443 raw_printf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003444 rc = 1;
3445 goto meta_command_exit;
3446 }
mistachkinaae280e2015-12-31 19:06:24 +00003447 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
3448 raw_printf(p->out, "BEGIN TRANSACTION;\n");
drh45e29d82006-11-20 16:21:10 +00003449 p->writableSchema = 0;
drh56197952011-10-13 16:30:13 +00003450 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
drh2f464a02011-10-13 00:41:49 +00003451 p->nErr = 0;
drh4c653a02000-06-07 01:27:47 +00003452 if( nArg==1 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00003453 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003454 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003455 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
drh4f324762009-05-21 14:51:03 +00003456 );
mistachkin1fe36bb2016-04-04 02:16:44 +00003457 run_schema_dump_query(p,
drh4f324762009-05-21 14:51:03 +00003458 "SELECT name, type, sql FROM sqlite_master "
drh2f464a02011-10-13 00:41:49 +00003459 "WHERE name=='sqlite_sequence'"
drh0b9a5942006-09-13 20:22:02 +00003460 );
drh2f464a02011-10-13 00:41:49 +00003461 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003462 "SELECT sql FROM sqlite_master "
drh157e29a2009-05-21 15:15:00 +00003463 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
drha18c5682000-10-08 22:20:57 +00003464 );
drh4c653a02000-06-07 01:27:47 +00003465 }else{
3466 int i;
drhdd3d4592004-08-30 01:54:05 +00003467 for(i=1; i<nArg; i++){
danielk1977bc6ada42004-06-30 08:20:16 +00003468 zShellStatic = azArg[i];
drhdd3d4592004-08-30 01:54:05 +00003469 run_schema_dump_query(p,
drha18c5682000-10-08 22:20:57 +00003470 "SELECT name, type, sql FROM sqlite_master "
drhdd3d4592004-08-30 01:54:05 +00003471 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
drh2f464a02011-10-13 00:41:49 +00003472 " AND sql NOT NULL");
3473 run_table_dump_query(p,
drh0b9a5942006-09-13 20:22:02 +00003474 "SELECT sql FROM sqlite_master "
drh45e29d82006-11-20 16:21:10 +00003475 "WHERE sql NOT NULL"
3476 " AND type IN ('index','trigger','view')"
drh157e29a2009-05-21 15:15:00 +00003477 " AND tbl_name LIKE shellstatic()", 0
drh0b9a5942006-09-13 20:22:02 +00003478 );
danielk1977bc6ada42004-06-30 08:20:16 +00003479 zShellStatic = 0;
drh4c653a02000-06-07 01:27:47 +00003480 }
3481 }
drh45e29d82006-11-20 16:21:10 +00003482 if( p->writableSchema ){
mistachkinaae280e2015-12-31 19:06:24 +00003483 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
drh45e29d82006-11-20 16:21:10 +00003484 p->writableSchema = 0;
3485 }
drh56197952011-10-13 16:30:13 +00003486 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
3487 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
mistachkinaae280e2015-12-31 19:06:24 +00003488 raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
drh4c653a02000-06-07 01:27:47 +00003489 }else
drh75897232000-05-29 14:26:00 +00003490
drhc2ce0be2014-05-29 12:36:14 +00003491 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
3492 if( nArg==2 ){
3493 p->echoOn = booleanValue(azArg[1]);
3494 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003495 raw_printf(stderr, "Usage: .echo on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003496 rc = 1;
3497 }
drhdaffd0e2001-04-11 14:28:42 +00003498 }else
3499
drhc2ce0be2014-05-29 12:36:14 +00003500 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
3501 if( nArg==2 ){
drheacd29d2016-04-15 15:03:27 +00003502 if( strcmp(azArg[1],"full")==0 ){
3503 p->autoEQP = 2;
3504 }else{
3505 p->autoEQP = booleanValue(azArg[1]);
3506 }
drhc2ce0be2014-05-29 12:36:14 +00003507 }else{
drheacd29d2016-04-15 15:03:27 +00003508 raw_printf(stderr, "Usage: .eqp on|off|full\n");
drhc2ce0be2014-05-29 12:36:14 +00003509 rc = 1;
mistachkin1fe36bb2016-04-04 02:16:44 +00003510 }
drhefbf3b12014-02-28 20:47:24 +00003511 }else
3512
drhd3ac7d92013-01-25 18:33:43 +00003513 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
drh348d19c2013-06-03 12:47:43 +00003514 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
drh47ad6842006-11-08 12:25:42 +00003515 rc = 2;
drh75897232000-05-29 14:26:00 +00003516 }else
3517
drhc2ce0be2014-05-29 12:36:14 +00003518 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
drh700c2522016-02-09 18:39:25 +00003519 int val = 1;
3520 if( nArg>=2 ){
3521 if( strcmp(azArg[1],"auto")==0 ){
3522 val = 99;
3523 }else{
3524 val = booleanValue(azArg[1]);
persicom7e2dfdd2002-04-18 02:46:52 +00003525 }
drh700c2522016-02-09 18:39:25 +00003526 }
3527 if( val==1 && p->mode!=MODE_Explain ){
3528 p->normalMode = p->mode;
danielk19770d78bae2008-01-03 07:09:48 +00003529 p->mode = MODE_Explain;
drh700c2522016-02-09 18:39:25 +00003530 p->autoExplain = 0;
3531 }else if( val==0 ){
3532 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3533 p->autoExplain = 0;
3534 }else if( val==99 ){
3535 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
3536 p->autoExplain = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00003537 }
drh75897232000-05-29 14:26:00 +00003538 }else
3539
drhc1971542014-06-23 23:28:13 +00003540 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00003541 ShellState data;
drhc1971542014-06-23 23:28:13 +00003542 char *zErrMsg = 0;
drh56f674c2014-07-18 14:43:29 +00003543 int doStats = 0;
drh4926fec2016-04-13 15:33:42 +00003544 memcpy(&data, p, sizeof(data));
3545 data.showHeader = 0;
3546 data.cMode = data.mode = MODE_Semi;
3547 if( nArg==2 && optionMatch(azArg[1], "indent") ){
3548 data.cMode = data.mode = MODE_Pretty;
3549 nArg = 1;
3550 }
drhc1971542014-06-23 23:28:13 +00003551 if( nArg!=1 ){
drh4926fec2016-04-13 15:33:42 +00003552 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
drhc1971542014-06-23 23:28:13 +00003553 rc = 1;
3554 goto meta_command_exit;
3555 }
3556 open_db(p, 0);
drhc1971542014-06-23 23:28:13 +00003557 rc = sqlite3_exec(p->db,
3558 "SELECT sql FROM"
3559 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
3560 " FROM sqlite_master UNION ALL"
3561 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00003562 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drhc1971542014-06-23 23:28:13 +00003563 "ORDER BY rowid",
3564 callback, &data, &zErrMsg
3565 );
drh56f674c2014-07-18 14:43:29 +00003566 if( rc==SQLITE_OK ){
3567 sqlite3_stmt *pStmt;
3568 rc = sqlite3_prepare_v2(p->db,
3569 "SELECT rowid FROM sqlite_master"
3570 " WHERE name GLOB 'sqlite_stat[134]'",
3571 -1, &pStmt, 0);
3572 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
3573 sqlite3_finalize(pStmt);
3574 }
3575 if( doStats==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003576 raw_printf(p->out, "/* No STAT tables available */\n");
drh56f674c2014-07-18 14:43:29 +00003577 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003578 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003579 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
3580 callback, &data, &zErrMsg);
drh700c2522016-02-09 18:39:25 +00003581 data.cMode = data.mode = MODE_Insert;
drh56f674c2014-07-18 14:43:29 +00003582 data.zDestTable = "sqlite_stat1";
3583 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
3584 shell_callback, &data,&zErrMsg);
3585 data.zDestTable = "sqlite_stat3";
3586 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
3587 shell_callback, &data,&zErrMsg);
3588 data.zDestTable = "sqlite_stat4";
3589 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
3590 shell_callback, &data, &zErrMsg);
mistachkinaae280e2015-12-31 19:06:24 +00003591 raw_printf(p->out, "ANALYZE sqlite_master;\n");
drh56f674c2014-07-18 14:43:29 +00003592 }
drhc1971542014-06-23 23:28:13 +00003593 }else
3594
drhc2ce0be2014-05-29 12:36:14 +00003595 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
3596 if( nArg==2 ){
3597 p->showHeader = booleanValue(azArg[1]);
3598 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003599 raw_printf(stderr, "Usage: .headers on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00003600 rc = 1;
shaneb320ccd2009-10-21 03:42:58 +00003601 }
drh75897232000-05-29 14:26:00 +00003602 }else
3603
drhc2ce0be2014-05-29 12:36:14 +00003604 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003605 utf8_printf(p->out, "%s", zHelp);
drhc2ce0be2014-05-29 12:36:14 +00003606 }else
3607
3608 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drh01f37542014-05-31 15:43:33 +00003609 char *zTable; /* Insert data into this table */
3610 char *zFile; /* Name of file to extra content from */
shane916f9612009-10-23 00:37:15 +00003611 sqlite3_stmt *pStmt = NULL; /* A statement */
drhfeac5f82004-08-01 00:10:45 +00003612 int nCol; /* Number of columns in the table */
3613 int nByte; /* Number of bytes in an SQL string */
3614 int i, j; /* Loop counters */
drh2d463112013-08-06 14:36:36 +00003615 int needCommit; /* True to COMMIT or ROLLBACK at end */
mistachkin636bf9f2014-07-19 20:15:16 +00003616 int nSep; /* Number of bytes in p->colSeparator[] */
drhfeac5f82004-08-01 00:10:45 +00003617 char *zSql; /* An SQL statement */
mistachkin636bf9f2014-07-19 20:15:16 +00003618 ImportCtx sCtx; /* Reader context */
mistachkin44723ce2015-03-21 02:22:37 +00003619 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
3620 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close file */
drhfeac5f82004-08-01 00:10:45 +00003621
drhc2ce0be2014-05-29 12:36:14 +00003622 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003623 raw_printf(stderr, "Usage: .import FILE TABLE\n");
drhc2ce0be2014-05-29 12:36:14 +00003624 goto meta_command_exit;
3625 }
drh01f37542014-05-31 15:43:33 +00003626 zFile = azArg[1];
3627 zTable = azArg[2];
drhdb95f682013-06-26 22:46:00 +00003628 seenInterrupt = 0;
mistachkin636bf9f2014-07-19 20:15:16 +00003629 memset(&sCtx, 0, sizeof(sCtx));
drh05782482013-10-24 15:20:20 +00003630 open_db(p, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003631 nSep = strlen30(p->colSeparator);
drhfeac5f82004-08-01 00:10:45 +00003632 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003633 raw_printf(stderr,
3634 "Error: non-null column separator required for import\n");
shane916f9612009-10-23 00:37:15 +00003635 return 1;
drhfeac5f82004-08-01 00:10:45 +00003636 }
drhdb95f682013-06-26 22:46:00 +00003637 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003638 raw_printf(stderr, "Error: multi-character column separators not allowed"
drhdb95f682013-06-26 22:46:00 +00003639 " for import\n");
3640 return 1;
3641 }
mistachkin636bf9f2014-07-19 20:15:16 +00003642 nSep = strlen30(p->rowSeparator);
3643 if( nSep==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003644 raw_printf(stderr, "Error: non-null row separator required for import\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003645 return 1;
3646 }
mistachkine0d68852014-12-11 03:12:33 +00003647 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator, SEP_CrLf)==0 ){
3648 /* When importing CSV (only), if the row separator is set to the
3649 ** default output row separator, change it to the default input
3650 ** row separator. This avoids having to maintain different input
3651 ** and output row separators. */
3652 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
3653 nSep = strlen30(p->rowSeparator);
3654 }
mistachkin636bf9f2014-07-19 20:15:16 +00003655 if( nSep>1 ){
mistachkinaae280e2015-12-31 19:06:24 +00003656 raw_printf(stderr, "Error: multi-character row separators not allowed"
mistachkin636bf9f2014-07-19 20:15:16 +00003657 " for import\n");
3658 return 1;
3659 }
3660 sCtx.zFile = zFile;
3661 sCtx.nLine = 1;
3662 if( sCtx.zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00003663#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00003664 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00003665 return 1;
3666#else
mistachkin636bf9f2014-07-19 20:15:16 +00003667 sCtx.in = popen(sCtx.zFile+1, "r");
3668 sCtx.zFile = "<pipe>";
drh5bde8162013-06-27 14:07:53 +00003669 xCloser = pclose;
drh8cd5b252015-03-02 22:06:43 +00003670#endif
drh5bde8162013-06-27 14:07:53 +00003671 }else{
mistachkin636bf9f2014-07-19 20:15:16 +00003672 sCtx.in = fopen(sCtx.zFile, "rb");
drh5bde8162013-06-27 14:07:53 +00003673 xCloser = fclose;
3674 }
mistachkin636bf9f2014-07-19 20:15:16 +00003675 if( p->mode==MODE_Ascii ){
3676 xRead = ascii_read_one_field;
3677 }else{
3678 xRead = csv_read_one_field;
3679 }
3680 if( sCtx.in==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003681 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhdb95f682013-06-26 22:46:00 +00003682 return 1;
3683 }
mistachkin636bf9f2014-07-19 20:15:16 +00003684 sCtx.cColSep = p->colSeparator[0];
3685 sCtx.cRowSep = p->rowSeparator[0];
drh7b075e32011-09-28 01:10:00 +00003686 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
shane916f9612009-10-23 00:37:15 +00003687 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003688 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003689 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003690 return 1;
3691 }
drh4f21c4a2008-12-10 22:15:00 +00003692 nByte = strlen30(zSql);
drhc7181902014-02-27 15:04:13 +00003693 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
mistachkin636bf9f2014-07-19 20:15:16 +00003694 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
mistachkin8e189222015-04-19 21:43:16 +00003695 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhdb95f682013-06-26 22:46:00 +00003696 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
3697 char cSep = '(';
mistachkin636bf9f2014-07-19 20:15:16 +00003698 while( xRead(&sCtx) ){
drhd8c22ac2016-02-25 13:33:02 +00003699 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
drhdb95f682013-06-26 22:46:00 +00003700 cSep = ',';
mistachkin636bf9f2014-07-19 20:15:16 +00003701 if( sCtx.cTerm!=sCtx.cColSep ) break;
drhdb95f682013-06-26 22:46:00 +00003702 }
drh5bde8162013-06-27 14:07:53 +00003703 if( cSep=='(' ){
3704 sqlite3_free(zCreate);
mistachkin636bf9f2014-07-19 20:15:16 +00003705 sqlite3_free(sCtx.z);
3706 xCloser(sCtx.in);
mistachkinaae280e2015-12-31 19:06:24 +00003707 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drh5bde8162013-06-27 14:07:53 +00003708 return 1;
3709 }
drhdb95f682013-06-26 22:46:00 +00003710 zCreate = sqlite3_mprintf("%z\n)", zCreate);
3711 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
3712 sqlite3_free(zCreate);
3713 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003714 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
mistachkin8e189222015-04-19 21:43:16 +00003715 sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003716 sqlite3_free(sCtx.z);
3717 xCloser(sCtx.in);
drhdb95f682013-06-26 22:46:00 +00003718 return 1;
3719 }
drhc7181902014-02-27 15:04:13 +00003720 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003721 }
drhfeac5f82004-08-01 00:10:45 +00003722 sqlite3_free(zSql);
3723 if( rc ){
shane916f9612009-10-23 00:37:15 +00003724 if (pStmt) sqlite3_finalize(pStmt);
mistachkinaae280e2015-12-31 19:06:24 +00003725 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
mistachkin636bf9f2014-07-19 20:15:16 +00003726 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003727 return 1;
drhfeac5f82004-08-01 00:10:45 +00003728 }
shane916f9612009-10-23 00:37:15 +00003729 nCol = sqlite3_column_count(pStmt);
drhfeac5f82004-08-01 00:10:45 +00003730 sqlite3_finalize(pStmt);
shane916f9612009-10-23 00:37:15 +00003731 pStmt = 0;
shane9bd1b442009-10-23 01:27:39 +00003732 if( nCol==0 ) return 0; /* no columns, no error */
drhf3cdcdc2015-04-29 16:50:28 +00003733 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
shane916f9612009-10-23 00:37:15 +00003734 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003735 raw_printf(stderr, "Error: out of memory\n");
mistachkin636bf9f2014-07-19 20:15:16 +00003736 xCloser(sCtx.in);
shane916f9612009-10-23 00:37:15 +00003737 return 1;
3738 }
drhdb95f682013-06-26 22:46:00 +00003739 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
drh4f21c4a2008-12-10 22:15:00 +00003740 j = strlen30(zSql);
drhfeac5f82004-08-01 00:10:45 +00003741 for(i=1; i<nCol; i++){
3742 zSql[j++] = ',';
3743 zSql[j++] = '?';
3744 }
3745 zSql[j++] = ')';
3746 zSql[j] = 0;
drhc7181902014-02-27 15:04:13 +00003747 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
drhdb95f682013-06-26 22:46:00 +00003748 sqlite3_free(zSql);
drhfeac5f82004-08-01 00:10:45 +00003749 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00003750 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane916f9612009-10-23 00:37:15 +00003751 if (pStmt) sqlite3_finalize(pStmt);
mistachkin636bf9f2014-07-19 20:15:16 +00003752 xCloser(sCtx.in);
drh47ad6842006-11-08 12:25:42 +00003753 return 1;
drhfeac5f82004-08-01 00:10:45 +00003754 }
mistachkin8e189222015-04-19 21:43:16 +00003755 needCommit = sqlite3_get_autocommit(p->db);
3756 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
drhdb95f682013-06-26 22:46:00 +00003757 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003758 int startLine = sCtx.nLine;
drhfeac5f82004-08-01 00:10:45 +00003759 for(i=0; i<nCol; i++){
mistachkin636bf9f2014-07-19 20:15:16 +00003760 char *z = xRead(&sCtx);
3761 /*
3762 ** Did we reach end-of-file before finding any columns?
3763 ** If so, stop instead of NULL filling the remaining columns.
3764 */
drhdb95f682013-06-26 22:46:00 +00003765 if( z==0 && i==0 ) break;
mistachkin636bf9f2014-07-19 20:15:16 +00003766 /*
3767 ** Did we reach end-of-file OR end-of-line before finding any
3768 ** columns in ASCII mode? If so, stop instead of NULL filling
3769 ** the remaining columns.
3770 */
3771 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
drhdb95f682013-06-26 22:46:00 +00003772 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
mistachkin636bf9f2014-07-19 20:15:16 +00003773 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
mistachkinaae280e2015-12-31 19:06:24 +00003774 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003775 "filling the rest with NULL\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003776 sCtx.zFile, startLine, nCol, i+1);
mistachkina0efb1a2015-02-12 22:45:25 +00003777 i += 2;
mistachkin6fe03382014-06-16 22:45:28 +00003778 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
drh18f52e02012-01-16 16:56:31 +00003779 }
drhfeac5f82004-08-01 00:10:45 +00003780 }
mistachkin636bf9f2014-07-19 20:15:16 +00003781 if( sCtx.cTerm==sCtx.cColSep ){
drhdb95f682013-06-26 22:46:00 +00003782 do{
mistachkin636bf9f2014-07-19 20:15:16 +00003783 xRead(&sCtx);
drhdb95f682013-06-26 22:46:00 +00003784 i++;
mistachkin636bf9f2014-07-19 20:15:16 +00003785 }while( sCtx.cTerm==sCtx.cColSep );
mistachkinaae280e2015-12-31 19:06:24 +00003786 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
drhdb95f682013-06-26 22:46:00 +00003787 "extras ignored\n",
mistachkin636bf9f2014-07-19 20:15:16 +00003788 sCtx.zFile, startLine, nCol, i);
drhfeac5f82004-08-01 00:10:45 +00003789 }
drhdb95f682013-06-26 22:46:00 +00003790 if( i>=nCol ){
3791 sqlite3_step(pStmt);
3792 rc = sqlite3_reset(pStmt);
3793 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003794 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
3795 startLine, sqlite3_errmsg(p->db));
drhdb95f682013-06-26 22:46:00 +00003796 }
3797 }
mistachkin636bf9f2014-07-19 20:15:16 +00003798 }while( sCtx.cTerm!=EOF );
drhdb95f682013-06-26 22:46:00 +00003799
mistachkin636bf9f2014-07-19 20:15:16 +00003800 xCloser(sCtx.in);
3801 sqlite3_free(sCtx.z);
drhfeac5f82004-08-01 00:10:45 +00003802 sqlite3_finalize(pStmt);
mistachkin8e189222015-04-19 21:43:16 +00003803 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhfeac5f82004-08-01 00:10:45 +00003804 }else
3805
drh0e55db12015-02-06 14:51:13 +00003806 if( c=='i' && (strncmp(azArg[0], "indices", n)==0
3807 || strncmp(azArg[0], "indexes", n)==0) ){
drhdcd87a92014-08-18 13:45:42 +00003808 ShellState data;
drh75897232000-05-29 14:26:00 +00003809 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00003810 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00003811 memcpy(&data, p, sizeof(data));
3812 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00003813 data.cMode = data.mode = MODE_List;
shane86f5bdb2009-10-24 02:00:07 +00003814 if( nArg==1 ){
3815 rc = sqlite3_exec(p->db,
3816 "SELECT name FROM sqlite_master "
3817 "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
3818 "UNION ALL "
3819 "SELECT name FROM sqlite_temp_master "
3820 "WHERE type='index' "
3821 "ORDER BY 1",
3822 callback, &data, &zErrMsg
3823 );
drhc2ce0be2014-05-29 12:36:14 +00003824 }else if( nArg==2 ){
shane86f5bdb2009-10-24 02:00:07 +00003825 zShellStatic = azArg[1];
3826 rc = sqlite3_exec(p->db,
3827 "SELECT name FROM sqlite_master "
3828 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3829 "UNION ALL "
3830 "SELECT name FROM sqlite_temp_master "
3831 "WHERE type='index' AND tbl_name LIKE shellstatic() "
3832 "ORDER BY 1",
3833 callback, &data, &zErrMsg
3834 );
3835 zShellStatic = 0;
drhc2ce0be2014-05-29 12:36:14 +00003836 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003837 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00003838 rc = 1;
3839 goto meta_command_exit;
shane86f5bdb2009-10-24 02:00:07 +00003840 }
drh75897232000-05-29 14:26:00 +00003841 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00003842 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00003843 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00003844 rc = 1;
shane86f5bdb2009-10-24 02:00:07 +00003845 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00003846 raw_printf(stderr,
3847 "Error: querying sqlite_master and sqlite_temp_master\n");
shane86f5bdb2009-10-24 02:00:07 +00003848 rc = 1;
drh75897232000-05-29 14:26:00 +00003849 }
3850 }else
3851
drh16eb5942016-11-03 13:01:38 +00003852#ifndef SQLITE_OMIT_BUILTIN_TEST
3853 if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
3854 char *zSql;
3855 char *zCollist = 0;
3856 sqlite3_stmt *pStmt;
3857 int tnum = 0;
3858 if( nArg!=3 ){
3859 utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n");
3860 rc = 1;
3861 goto meta_command_exit;
3862 }
3863 open_db(p, 0);
3864 zSql = sqlite3_mprintf("SELECT rootpage FROM sqlite_master"
3865 " WHERE name='%q' AND type='index'", azArg[1]);
3866 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3867 sqlite3_free(zSql);
3868 if( sqlite3_step(pStmt)==SQLITE_ROW ){
3869 tnum = sqlite3_column_int(pStmt, 0);
3870 }
3871 sqlite3_finalize(pStmt);
3872 if( tnum==0 ){
3873 utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
3874 rc = 1;
3875 goto meta_command_exit;
3876 }
3877 zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
3878 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3879 sqlite3_free(zSql);
3880 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3881 const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
3882 if( zCol==0 ) zCol = "_ROWID_";
3883 if( zCollist==0 ){
3884 zCollist = sqlite3_mprintf("\"%w\"", zCol);
3885 }else{
3886 zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
3887 }
3888 }
3889 sqlite3_finalize(pStmt);
3890 zSql = sqlite3_mprintf(
3891 "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%s))WITHOUT ROWID",
3892 azArg[2], zCollist, zCollist);
3893 sqlite3_free(zCollist);
3894 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
3895 if( rc==SQLITE_OK ){
3896 rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
3897 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
3898 if( rc ){
3899 utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
3900 }else{
3901 utf8_printf(stdout, "%s;\n", zSql);
3902 utf8_printf(stdout,
3903 "WARNING: writing to an imposter table will corrupt the index!\n"
3904 );
3905 }
3906 }else{
3907 utf8_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
3908 rc = 1;
3909 }
3910 sqlite3_free(zSql);
3911 }else
3912#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
3913
drhae5e4452007-05-03 17:18:36 +00003914#ifdef SQLITE_ENABLE_IOTRACE
drhb0603412007-02-28 04:47:26 +00003915 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
mistachkin9871a932015-03-27 00:21:52 +00003916 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
drhb0603412007-02-28 04:47:26 +00003917 if( iotrace && iotrace!=stdout ) fclose(iotrace);
3918 iotrace = 0;
3919 if( nArg<2 ){
mlcreech3a00f902008-03-04 17:45:01 +00003920 sqlite3IoTrace = 0;
drhb0603412007-02-28 04:47:26 +00003921 }else if( strcmp(azArg[1], "-")==0 ){
mlcreech3a00f902008-03-04 17:45:01 +00003922 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003923 iotrace = stdout;
3924 }else{
3925 iotrace = fopen(azArg[1], "w");
3926 if( iotrace==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003927 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
mlcreech3a00f902008-03-04 17:45:01 +00003928 sqlite3IoTrace = 0;
shane9bd1b442009-10-23 01:27:39 +00003929 rc = 1;
drhb0603412007-02-28 04:47:26 +00003930 }else{
mlcreech3a00f902008-03-04 17:45:01 +00003931 sqlite3IoTrace = iotracePrintf;
drhb0603412007-02-28 04:47:26 +00003932 }
3933 }
3934 }else
drhae5e4452007-05-03 17:18:36 +00003935#endif
drh16eb5942016-11-03 13:01:38 +00003936
drh1a513372015-05-02 17:40:23 +00003937 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
3938 static const struct {
3939 const char *zLimitName; /* Name of a limit */
3940 int limitCode; /* Integer code for that limit */
3941 } aLimit[] = {
3942 { "length", SQLITE_LIMIT_LENGTH },
3943 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
3944 { "column", SQLITE_LIMIT_COLUMN },
3945 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
3946 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
3947 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
3948 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
3949 { "attached", SQLITE_LIMIT_ATTACHED },
3950 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
3951 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
3952 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
3953 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
3954 };
3955 int i, n2;
3956 open_db(p, 0);
3957 if( nArg==1 ){
drhf5ed7ad2015-06-15 14:43:25 +00003958 for(i=0; i<ArraySize(aLimit); i++){
mistachkin1fe36bb2016-04-04 02:16:44 +00003959 printf("%20s %d\n", aLimit[i].zLimitName,
drh1a513372015-05-02 17:40:23 +00003960 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
3961 }
3962 }else if( nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00003963 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
drh1a513372015-05-02 17:40:23 +00003964 rc = 1;
3965 goto meta_command_exit;
3966 }else{
3967 int iLimit = -1;
3968 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00003969 for(i=0; i<ArraySize(aLimit); i++){
drh1a513372015-05-02 17:40:23 +00003970 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
3971 if( iLimit<0 ){
3972 iLimit = i;
3973 }else{
mistachkinaae280e2015-12-31 19:06:24 +00003974 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
drh1a513372015-05-02 17:40:23 +00003975 rc = 1;
3976 goto meta_command_exit;
3977 }
3978 }
3979 }
3980 if( iLimit<0 ){
mistachkinaae280e2015-12-31 19:06:24 +00003981 utf8_printf(stderr, "unknown limit: \"%s\"\n"
drh1a513372015-05-02 17:40:23 +00003982 "enter \".limits\" with no arguments for a list.\n",
3983 azArg[1]);
3984 rc = 1;
3985 goto meta_command_exit;
3986 }
3987 if( nArg==3 ){
mistachkin2c1820c2015-05-08 01:04:39 +00003988 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3989 (int)integerValue(azArg[2]));
drh1a513372015-05-02 17:40:23 +00003990 }
3991 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3992 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3993 }
3994 }else
drhb0603412007-02-28 04:47:26 +00003995
drh70df4fe2006-06-13 15:12:21 +00003996#ifndef SQLITE_OMIT_LOAD_EXTENSION
drhc2ce0be2014-05-29 12:36:14 +00003997 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
drh1e397f82006-06-08 15:28:43 +00003998 const char *zFile, *zProc;
3999 char *zErrMsg = 0;
drhc2ce0be2014-05-29 12:36:14 +00004000 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004001 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
drhc2ce0be2014-05-29 12:36:14 +00004002 rc = 1;
4003 goto meta_command_exit;
4004 }
drh1e397f82006-06-08 15:28:43 +00004005 zFile = azArg[1];
4006 zProc = nArg>=3 ? azArg[2] : 0;
drh05782482013-10-24 15:20:20 +00004007 open_db(p, 0);
drh1e397f82006-06-08 15:28:43 +00004008 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
4009 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004010 utf8_printf(stderr, "Error: %s\n", zErrMsg);
drh1e397f82006-06-08 15:28:43 +00004011 sqlite3_free(zErrMsg);
drh47ad6842006-11-08 12:25:42 +00004012 rc = 1;
drh1e397f82006-06-08 15:28:43 +00004013 }
4014 }else
drh70df4fe2006-06-13 15:12:21 +00004015#endif
drh1e397f82006-06-08 15:28:43 +00004016
drhc2ce0be2014-05-29 12:36:14 +00004017 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
4018 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004019 raw_printf(stderr, "Usage: .log FILENAME\n");
drhc2ce0be2014-05-29 12:36:14 +00004020 rc = 1;
4021 }else{
4022 const char *zFile = azArg[1];
4023 output_file_close(p->pLog);
4024 p->pLog = output_file_open(zFile);
4025 }
drh127f9d72010-02-23 01:47:00 +00004026 }else
4027
drhc2ce0be2014-05-29 12:36:14 +00004028 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
4029 const char *zMode = nArg>=2 ? azArg[1] : "";
4030 int n2 = (int)strlen(zMode);
4031 int c2 = zMode[0];
4032 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004033 p->mode = MODE_Line;
drhc2ce0be2014-05-29 12:36:14 +00004034 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004035 p->mode = MODE_Column;
drhc2ce0be2014-05-29 12:36:14 +00004036 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
drh75897232000-05-29 14:26:00 +00004037 p->mode = MODE_List;
drhc2ce0be2014-05-29 12:36:14 +00004038 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
drh1e5d0e92000-05-31 23:33:17 +00004039 p->mode = MODE_Html;
drhc2ce0be2014-05-29 12:36:14 +00004040 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00004041 p->mode = MODE_Tcl;
mistachkinfad42082014-07-24 22:13:12 +00004042 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
drhc2ce0be2014-05-29 12:36:14 +00004043 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
drh8e64d1c2004-10-07 00:32:39 +00004044 p->mode = MODE_Csv;
mistachkinfad42082014-07-24 22:13:12 +00004045 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
mistachkine0d68852014-12-11 03:12:33 +00004046 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
drhc2ce0be2014-05-29 12:36:14 +00004047 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
drhfeac5f82004-08-01 00:10:45 +00004048 p->mode = MODE_List;
mistachkinfad42082014-07-24 22:13:12 +00004049 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
drhc2ce0be2014-05-29 12:36:14 +00004050 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
drh28bd4bc2000-06-15 15:57:22 +00004051 p->mode = MODE_Insert;
drhc2ce0be2014-05-29 12:36:14 +00004052 set_table_name(p, nArg>=3 ? azArg[2] : "table");
drh41f5f6e2016-10-21 17:39:30 +00004053 }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
4054 p->mode = MODE_Quote;
mistachkin636bf9f2014-07-19 20:15:16 +00004055 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
4056 p->mode = MODE_Ascii;
mistachkinfad42082014-07-24 22:13:12 +00004057 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
4058 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drhdaffd0e2001-04-11 14:28:42 +00004059 }else {
mistachkinaae280e2015-12-31 19:06:24 +00004060 raw_printf(stderr, "Error: mode should be one of: "
mistachkin636bf9f2014-07-19 20:15:16 +00004061 "ascii column csv html insert line list tabs tcl\n");
shane9bd1b442009-10-23 01:27:39 +00004062 rc = 1;
drh75897232000-05-29 14:26:00 +00004063 }
drh700c2522016-02-09 18:39:25 +00004064 p->cMode = p->mode;
drh75897232000-05-29 14:26:00 +00004065 }else
4066
drhc2ce0be2014-05-29 12:36:14 +00004067 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
4068 if( nArg==2 ){
mistachkin44b99f72014-12-11 03:29:14 +00004069 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
4070 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
drhc2ce0be2014-05-29 12:36:14 +00004071 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004072 raw_printf(stderr, "Usage: .nullvalue STRING\n");
shanehe2aa9d72009-11-06 17:20:17 +00004073 rc = 1;
4074 }
4075 }else
4076
drh05782482013-10-24 15:20:20 +00004077 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
drhcd0509e2016-09-16 00:26:08 +00004078 char *zNewFilename; /* Name of the database file to open */
4079 int iName = 1; /* Index in azArg[] of the filename */
drh760c8162016-09-16 02:52:22 +00004080 int newFlag = 0; /* True to delete file before opening */
drhcd0509e2016-09-16 00:26:08 +00004081 /* Close the existing database */
4082 session_close_all(p);
4083 sqlite3_close(p->db);
drh05782482013-10-24 15:20:20 +00004084 p->db = 0;
drhcd0509e2016-09-16 00:26:08 +00004085 sqlite3_free(p->zFreeOnClose);
4086 p->zFreeOnClose = 0;
drh760c8162016-09-16 02:52:22 +00004087 /* Check for command-line arguments */
4088 for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
4089 const char *z = azArg[iName];
4090 if( optionMatch(z,"new") ){
4091 newFlag = 1;
4092 }else if( z[0]=='-' ){
4093 utf8_printf(stderr, "unknown option: %s\n", z);
4094 rc = 1;
mistachkin8145fc62016-09-16 20:39:21 +00004095 goto meta_command_exit;
drh760c8162016-09-16 02:52:22 +00004096 }
drhcd0509e2016-09-16 00:26:08 +00004097 }
4098 /* If a filename is specified, try to open it first */
4099 zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
4100 if( zNewFilename ){
drh760c8162016-09-16 02:52:22 +00004101 if( newFlag ) shellDeleteFile(zNewFilename);
drhcd0509e2016-09-16 00:26:08 +00004102 p->zDbFilename = zNewFilename;
4103 open_db(p, 1);
4104 if( p->db==0 ){
4105 utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
4106 sqlite3_free(zNewFilename);
4107 }else{
4108 p->zFreeOnClose = zNewFilename;
4109 }
4110 }
4111 if( p->db==0 ){
4112 /* As a fall-back open a TEMP database */
4113 p->zDbFilename = 0;
4114 open_db(p, 0);
drh05782482013-10-24 15:20:20 +00004115 }
4116 }else
4117
drhc2ce0be2014-05-29 12:36:14 +00004118 if( c=='o'
4119 && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
4120 ){
4121 const char *zFile = nArg>=2 ? azArg[1] : "stdout";
4122 if( nArg>2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004123 utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
drhc2ce0be2014-05-29 12:36:14 +00004124 rc = 1;
4125 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004126 }
drhc2ce0be2014-05-29 12:36:14 +00004127 if( n>1 && strncmp(azArg[0], "once", n)==0 ){
4128 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004129 raw_printf(stderr, "Usage: .once FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004130 rc = 1;
4131 goto meta_command_exit;
4132 }
4133 p->outCount = 2;
4134 }else{
4135 p->outCount = 0;
4136 }
4137 output_reset(p);
4138 if( zFile[0]=='|' ){
drh8cd5b252015-03-02 22:06:43 +00004139#ifdef SQLITE_OMIT_POPEN
mistachkinaae280e2015-12-31 19:06:24 +00004140 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drh8cd5b252015-03-02 22:06:43 +00004141 rc = 1;
4142 p->out = stdout;
4143#else
drhc2ce0be2014-05-29 12:36:14 +00004144 p->out = popen(zFile + 1, "w");
drhe1da8fa2012-03-30 00:05:57 +00004145 if( p->out==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004146 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
drhe1da8fa2012-03-30 00:05:57 +00004147 p->out = stdout;
4148 rc = 1;
4149 }else{
drhc2ce0be2014-05-29 12:36:14 +00004150 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drhe1da8fa2012-03-30 00:05:57 +00004151 }
drh8cd5b252015-03-02 22:06:43 +00004152#endif
drh75897232000-05-29 14:26:00 +00004153 }else{
drhc2ce0be2014-05-29 12:36:14 +00004154 p->out = output_file_open(zFile);
drh75897232000-05-29 14:26:00 +00004155 if( p->out==0 ){
drhc2ce0be2014-05-29 12:36:14 +00004156 if( strcmp(zFile,"off")!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004157 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
drh42f64e52012-04-04 16:56:23 +00004158 }
drh75897232000-05-29 14:26:00 +00004159 p->out = stdout;
shane9bd1b442009-10-23 01:27:39 +00004160 rc = 1;
persicom7e2dfdd2002-04-18 02:46:52 +00004161 } else {
drhc2ce0be2014-05-29 12:36:14 +00004162 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
drh75897232000-05-29 14:26:00 +00004163 }
4164 }
4165 }else
4166
drh078b1fd2012-09-21 13:40:02 +00004167 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
4168 int i;
4169 for(i=1; i<nArg; i++){
mistachkinaae280e2015-12-31 19:06:24 +00004170 if( i>1 ) raw_printf(p->out, " ");
drhe05461c2015-12-30 13:36:57 +00004171 utf8_printf(p->out, "%s", azArg[i]);
drh078b1fd2012-09-21 13:40:02 +00004172 }
mistachkinaae280e2015-12-31 19:06:24 +00004173 raw_printf(p->out, "\n");
drh078b1fd2012-09-21 13:40:02 +00004174 }else
4175
drhc2ce0be2014-05-29 12:36:14 +00004176 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
persicom7e2dfdd2002-04-18 02:46:52 +00004177 if( nArg >= 2) {
4178 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
4179 }
4180 if( nArg >= 3) {
4181 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
4182 }
4183 }else
4184
drhc2ce0be2014-05-29 12:36:14 +00004185 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
drh47ad6842006-11-08 12:25:42 +00004186 rc = 2;
persicom7e2dfdd2002-04-18 02:46:52 +00004187 }else
4188
drhc2ce0be2014-05-29 12:36:14 +00004189 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
4190 FILE *alt;
4191 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004192 raw_printf(stderr, "Usage: .read FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004193 rc = 1;
4194 goto meta_command_exit;
4195 }
4196 alt = fopen(azArg[1], "rb");
drhdaffd0e2001-04-11 14:28:42 +00004197 if( alt==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004198 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
shane9bd1b442009-10-23 01:27:39 +00004199 rc = 1;
drhdaffd0e2001-04-11 14:28:42 +00004200 }else{
shane9bd1b442009-10-23 01:27:39 +00004201 rc = process_input(p, alt);
drhdaffd0e2001-04-11 14:28:42 +00004202 fclose(alt);
4203 }
4204 }else
4205
drhc2ce0be2014-05-29 12:36:14 +00004206 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
drh9ff849f2009-02-04 20:55:57 +00004207 const char *zSrcFile;
4208 const char *zDb;
4209 sqlite3 *pSrc;
4210 sqlite3_backup *pBackup;
drhdc2c4912009-02-04 22:46:47 +00004211 int nTimeout = 0;
4212
drh9ff849f2009-02-04 20:55:57 +00004213 if( nArg==2 ){
4214 zSrcFile = azArg[1];
4215 zDb = "main";
drhc2ce0be2014-05-29 12:36:14 +00004216 }else if( nArg==3 ){
drh9ff849f2009-02-04 20:55:57 +00004217 zSrcFile = azArg[2];
4218 zDb = azArg[1];
drhc2ce0be2014-05-29 12:36:14 +00004219 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004220 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
drhc2ce0be2014-05-29 12:36:14 +00004221 rc = 1;
4222 goto meta_command_exit;
drh9ff849f2009-02-04 20:55:57 +00004223 }
4224 rc = sqlite3_open(zSrcFile, &pSrc);
4225 if( rc!=SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004226 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9ff849f2009-02-04 20:55:57 +00004227 sqlite3_close(pSrc);
4228 return 1;
4229 }
drh05782482013-10-24 15:20:20 +00004230 open_db(p, 0);
drh9ff849f2009-02-04 20:55:57 +00004231 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
4232 if( pBackup==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00004233 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9ff849f2009-02-04 20:55:57 +00004234 sqlite3_close(pSrc);
4235 return 1;
4236 }
drhdc2c4912009-02-04 22:46:47 +00004237 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
4238 || rc==SQLITE_BUSY ){
4239 if( rc==SQLITE_BUSY ){
4240 if( nTimeout++ >= 3 ) break;
4241 sqlite3_sleep(100);
drh9ff849f2009-02-04 20:55:57 +00004242 }
4243 }
4244 sqlite3_backup_finish(pBackup);
4245 if( rc==SQLITE_DONE ){
shane9bd1b442009-10-23 01:27:39 +00004246 rc = 0;
drhdc2c4912009-02-04 22:46:47 +00004247 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
mistachkinaae280e2015-12-31 19:06:24 +00004248 raw_printf(stderr, "Error: source database is busy\n");
shane9bd1b442009-10-23 01:27:39 +00004249 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004250 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004251 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
shane9bd1b442009-10-23 01:27:39 +00004252 rc = 1;
drh9ff849f2009-02-04 20:55:57 +00004253 }
4254 sqlite3_close(pSrc);
4255 }else
4256
dan8d1edb92014-11-05 09:07:28 +00004257
4258 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
4259 if( nArg==2 ){
4260 p->scanstatsOn = booleanValue(azArg[1]);
drh15f23c22014-11-06 12:46:16 +00004261#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
mistachkinaae280e2015-12-31 19:06:24 +00004262 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
drh15f23c22014-11-06 12:46:16 +00004263#endif
dan8d1edb92014-11-05 09:07:28 +00004264 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004265 raw_printf(stderr, "Usage: .scanstats on|off\n");
dan8d1edb92014-11-05 09:07:28 +00004266 rc = 1;
4267 }
4268 }else
4269
drhc2ce0be2014-05-29 12:36:14 +00004270 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
drhdcd87a92014-08-18 13:45:42 +00004271 ShellState data;
drh75897232000-05-29 14:26:00 +00004272 char *zErrMsg = 0;
drh05782482013-10-24 15:20:20 +00004273 open_db(p, 0);
drh75897232000-05-29 14:26:00 +00004274 memcpy(&data, p, sizeof(data));
4275 data.showHeader = 0;
drh700c2522016-02-09 18:39:25 +00004276 data.cMode = data.mode = MODE_Semi;
drh4926fec2016-04-13 15:33:42 +00004277 if( nArg>=2 && optionMatch(azArg[1], "indent") ){
4278 data.cMode = data.mode = MODE_Pretty;
4279 nArg--;
4280 if( nArg==2 ) azArg[1] = azArg[2];
4281 }
4282 if( nArg==2 && azArg[1][0]!='-' ){
drhc8d74412004-08-31 23:41:26 +00004283 int i;
drhf0693c82011-10-11 20:41:54 +00004284 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
drhc8d74412004-08-31 23:41:26 +00004285 if( strcmp(azArg[1],"sqlite_master")==0 ){
drha18c5682000-10-08 22:20:57 +00004286 char *new_argv[2], *new_colv[2];
4287 new_argv[0] = "CREATE TABLE sqlite_master (\n"
4288 " type text,\n"
4289 " name text,\n"
4290 " tbl_name text,\n"
drhadbca9c2001-09-27 15:11:53 +00004291 " rootpage integer,\n"
drha18c5682000-10-08 22:20:57 +00004292 " sql text\n"
4293 ")";
4294 new_argv[1] = 0;
4295 new_colv[0] = "sql";
4296 new_colv[1] = 0;
4297 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004298 rc = SQLITE_OK;
drhc8d74412004-08-31 23:41:26 +00004299 }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
drhe0bc4042002-06-25 01:09:11 +00004300 char *new_argv[2], *new_colv[2];
4301 new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
4302 " type text,\n"
4303 " name text,\n"
4304 " tbl_name text,\n"
4305 " rootpage integer,\n"
4306 " sql text\n"
4307 ")";
4308 new_argv[1] = 0;
4309 new_colv[0] = "sql";
4310 new_colv[1] = 0;
4311 callback(&data, 1, new_argv, new_colv);
shane9bd1b442009-10-23 01:27:39 +00004312 rc = SQLITE_OK;
drha18c5682000-10-08 22:20:57 +00004313 }else{
danielk1977bc6ada42004-06-30 08:20:16 +00004314 zShellStatic = azArg[1];
shane9bd1b442009-10-23 01:27:39 +00004315 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004316 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004317 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004318 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004319 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh6ac7a582011-11-04 00:35:56 +00004320 "WHERE lower(tbl_name) LIKE shellstatic()"
4321 " AND type!='meta' AND sql NOTNULL "
drh1ba00292013-05-06 21:01:06 +00004322 "ORDER BY rowid",
danielk1977bc6ada42004-06-30 08:20:16 +00004323 callback, &data, &zErrMsg);
4324 zShellStatic = 0;
drha18c5682000-10-08 22:20:57 +00004325 }
drhc2ce0be2014-05-29 12:36:14 +00004326 }else if( nArg==1 ){
shane9bd1b442009-10-23 01:27:39 +00004327 rc = sqlite3_exec(p->db,
drhe0bc4042002-06-25 01:09:11 +00004328 "SELECT sql FROM "
drhac43e982012-05-21 03:15:06 +00004329 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh8f800a72009-01-14 23:17:55 +00004330 " FROM sqlite_master UNION ALL"
drhac43e982012-05-21 03:15:06 +00004331 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
drh4b2590e2014-08-19 19:28:00 +00004332 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
drh1ba00292013-05-06 21:01:06 +00004333 "ORDER BY rowid",
drha18c5682000-10-08 22:20:57 +00004334 callback, &data, &zErrMsg
4335 );
drhc2ce0be2014-05-29 12:36:14 +00004336 }else{
drh4926fec2016-04-13 15:33:42 +00004337 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
drhc2ce0be2014-05-29 12:36:14 +00004338 rc = 1;
4339 goto meta_command_exit;
drh75897232000-05-29 14:26:00 +00004340 }
drh75897232000-05-29 14:26:00 +00004341 if( zErrMsg ){
mistachkinaae280e2015-12-31 19:06:24 +00004342 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00004343 sqlite3_free(zErrMsg);
shane9bd1b442009-10-23 01:27:39 +00004344 rc = 1;
4345 }else if( rc != SQLITE_OK ){
mistachkinaae280e2015-12-31 19:06:24 +00004346 raw_printf(stderr,"Error: querying schema information\n");
shane9bd1b442009-10-23 01:27:39 +00004347 rc = 1;
4348 }else{
4349 rc = 0;
drh75897232000-05-29 14:26:00 +00004350 }
4351 }else
4352
drhabd4c722014-09-20 18:18:33 +00004353#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
4354 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
drh1d9be4f2015-01-22 11:29:25 +00004355 sqlite3SelectTrace = integerValue(azArg[1]);
drhabd4c722014-09-20 18:18:33 +00004356 }else
4357#endif
4358
drhe6229612014-08-18 15:08:26 +00004359#if defined(SQLITE_ENABLE_SESSION)
4360 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
4361 OpenSession *pSession = &p->aSession[0];
4362 char **azCmd = &azArg[1];
4363 int iSes = 0;
4364 int nCmd = nArg - 1;
4365 int i;
4366 if( nArg<=1 ) goto session_syntax_error;
drh3a67b042014-08-18 17:56:31 +00004367 open_db(p, 0);
drhe6229612014-08-18 15:08:26 +00004368 if( nArg>=3 ){
4369 for(iSes=0; iSes<p->nSession; iSes++){
4370 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
4371 }
4372 if( iSes<p->nSession ){
4373 pSession = &p->aSession[iSes];
4374 azCmd++;
4375 nCmd--;
4376 }else{
4377 pSession = &p->aSession[0];
4378 iSes = 0;
4379 }
4380 }
4381
drh3a67b042014-08-18 17:56:31 +00004382 /* .session attach TABLE
4383 ** Invoke the sqlite3session_attach() interface to attach a particular
4384 ** table so that it is never filtered.
4385 */
4386 if( strcmp(azCmd[0],"attach")==0 ){
4387 if( nCmd!=2 ) goto session_syntax_error;
4388 if( pSession->p==0 ){
4389 session_not_open:
mistachkin899c5c92016-04-03 20:50:02 +00004390 raw_printf(stderr, "ERROR: No sessions are open\n");
drh3a67b042014-08-18 17:56:31 +00004391 }else{
4392 rc = sqlite3session_attach(pSession->p, azCmd[1]);
4393 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004394 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004395 rc = 0;
4396 }
4397 }
4398 }else
4399
4400 /* .session changeset FILE
4401 ** .session patchset FILE
4402 ** Write a changeset or patchset into a file. The file is overwritten.
4403 */
4404 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
4405 FILE *out = 0;
4406 if( nCmd!=2 ) goto session_syntax_error;
4407 if( pSession->p==0 ) goto session_not_open;
4408 out = fopen(azCmd[1], "wb");
4409 if( out==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004410 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]);
drh3a67b042014-08-18 17:56:31 +00004411 }else{
4412 int szChng;
4413 void *pChng;
4414 if( azCmd[0][0]=='c' ){
drh2967e0c2014-08-19 00:26:17 +00004415 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
drh3a67b042014-08-18 17:56:31 +00004416 }else{
drh2967e0c2014-08-19 00:26:17 +00004417 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
4418 }
4419 if( rc ){
4420 printf("Error: error code %d\n", rc);
4421 rc = 0;
drh3a67b042014-08-18 17:56:31 +00004422 }
mistachkin1fe36bb2016-04-04 02:16:44 +00004423 if( pChng
drh3a67b042014-08-18 17:56:31 +00004424 && fwrite(pChng, szChng, 1, out)!=1 ){
mistachkin899c5c92016-04-03 20:50:02 +00004425 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
drh3a67b042014-08-18 17:56:31 +00004426 szChng);
4427 }
4428 sqlite3_free(pChng);
4429 fclose(out);
4430 }
4431 }else
4432
drhe6229612014-08-18 15:08:26 +00004433 /* .session close
4434 ** Close the identified session
4435 */
4436 if( strcmp(azCmd[0], "close")==0 ){
drh03168ca2014-08-18 20:01:31 +00004437 if( nCmd!=1 ) goto session_syntax_error;
drhe6229612014-08-18 15:08:26 +00004438 if( p->nSession ){
4439 session_close(pSession);
4440 p->aSession[iSes] = p->aSession[--p->nSession];
4441 }
4442 }else
4443
drh03168ca2014-08-18 20:01:31 +00004444 /* .session enable ?BOOLEAN?
4445 ** Query or set the enable flag
4446 */
4447 if( strcmp(azCmd[0], "enable")==0 ){
4448 int ii;
4449 if( nCmd>2 ) goto session_syntax_error;
4450 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4451 if( p->nSession ){
4452 ii = sqlite3session_enable(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004453 utf8_printf(p->out, "session %s enable flag = %d\n",
4454 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004455 }
4456 }else
4457
4458 /* .session filter GLOB ....
4459 ** Set a list of GLOB patterns of table names to be excluded.
4460 */
4461 if( strcmp(azCmd[0], "filter")==0 ){
4462 int ii, nByte;
4463 if( nCmd<2 ) goto session_syntax_error;
4464 if( p->nSession ){
4465 for(ii=0; ii<pSession->nFilter; ii++){
4466 sqlite3_free(pSession->azFilter[ii]);
4467 }
4468 sqlite3_free(pSession->azFilter);
4469 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
4470 pSession->azFilter = sqlite3_malloc( nByte );
4471 if( pSession->azFilter==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004472 raw_printf(stderr, "Error: out or memory\n");
drh03168ca2014-08-18 20:01:31 +00004473 exit(1);
4474 }
4475 for(ii=1; ii<nCmd; ii++){
mistachkin1fe36bb2016-04-04 02:16:44 +00004476 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
drh03168ca2014-08-18 20:01:31 +00004477 }
4478 pSession->nFilter = ii-1;
4479 }
4480 }else
4481
4482 /* .session indirect ?BOOLEAN?
4483 ** Query or set the indirect flag
4484 */
4485 if( strcmp(azCmd[0], "indirect")==0 ){
4486 int ii;
4487 if( nCmd>2 ) goto session_syntax_error;
4488 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
4489 if( p->nSession ){
4490 ii = sqlite3session_indirect(pSession->p, ii);
mistachkin899c5c92016-04-03 20:50:02 +00004491 utf8_printf(p->out, "session %s indirect flag = %d\n",
4492 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004493 }
4494 }else
4495
4496 /* .session isempty
4497 ** Determine if the session is empty
4498 */
4499 if( strcmp(azCmd[0], "isempty")==0 ){
4500 int ii;
4501 if( nCmd!=1 ) goto session_syntax_error;
4502 if( p->nSession ){
4503 ii = sqlite3session_isempty(pSession->p);
mistachkin899c5c92016-04-03 20:50:02 +00004504 utf8_printf(p->out, "session %s isempty flag = %d\n",
4505 pSession->zName, ii);
drh03168ca2014-08-18 20:01:31 +00004506 }
4507 }else
4508
drhe6229612014-08-18 15:08:26 +00004509 /* .session list
4510 ** List all currently open sessions
4511 */
4512 if( strcmp(azCmd[0],"list")==0 ){
4513 for(i=0; i<p->nSession; i++){
mistachkin899c5c92016-04-03 20:50:02 +00004514 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
drhe6229612014-08-18 15:08:26 +00004515 }
4516 }else
4517
4518 /* .session open DB NAME
4519 ** Open a new session called NAME on the attached database DB.
4520 ** DB is normally "main".
4521 */
4522 if( strcmp(azCmd[0],"open")==0 ){
4523 char *zName;
4524 if( nCmd!=3 ) goto session_syntax_error;
4525 zName = azCmd[2];
4526 if( zName[0]==0 ) goto session_syntax_error;
4527 for(i=0; i<p->nSession; i++){
4528 if( strcmp(p->aSession[i].zName,zName)==0 ){
mistachkin899c5c92016-04-03 20:50:02 +00004529 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
drhe6229612014-08-18 15:08:26 +00004530 goto meta_command_exit;
4531 }
4532 }
4533 if( p->nSession>=ArraySize(p->aSession) ){
mistachkin899c5c92016-04-03 20:50:02 +00004534 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
drhe6229612014-08-18 15:08:26 +00004535 goto meta_command_exit;
4536 }
4537 pSession = &p->aSession[p->nSession];
4538 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
4539 if( rc ){
mistachkin899c5c92016-04-03 20:50:02 +00004540 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
drh3a67b042014-08-18 17:56:31 +00004541 rc = 0;
drhe6229612014-08-18 15:08:26 +00004542 goto meta_command_exit;
4543 }
drh03168ca2014-08-18 20:01:31 +00004544 pSession->nFilter = 0;
4545 sqlite3session_table_filter(pSession->p, session_filter, pSession);
drhe6229612014-08-18 15:08:26 +00004546 p->nSession++;
4547 pSession->zName = sqlite3_mprintf("%s", zName);
4548 }else
4549 /* If no command name matches, show a syntax error */
4550 session_syntax_error:
4551 session_help(p);
4552 }else
4553#endif
4554
drh340f5822013-06-27 13:01:21 +00004555#ifdef SQLITE_DEBUG
drh348d19c2013-06-03 12:47:43 +00004556 /* Undocumented commands for internal testing. Subject to change
4557 ** without notice. */
4558 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
4559 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
4560 int i, v;
4561 for(i=1; i<nArg; i++){
4562 v = booleanValue(azArg[i]);
drhe05461c2015-12-30 13:36:57 +00004563 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
drh348d19c2013-06-03 12:47:43 +00004564 }
4565 }
4566 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
4567 int i; sqlite3_int64 v;
4568 for(i=1; i<nArg; i++){
drh340f5822013-06-27 13:01:21 +00004569 char zBuf[200];
drh348d19c2013-06-03 12:47:43 +00004570 v = integerValue(azArg[i]);
drhc2ce0be2014-05-29 12:36:14 +00004571 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
drhe05461c2015-12-30 13:36:57 +00004572 utf8_printf(p->out, "%s", zBuf);
drh348d19c2013-06-03 12:47:43 +00004573 }
4574 }
4575 }else
drh340f5822013-06-27 13:01:21 +00004576#endif
drh348d19c2013-06-03 12:47:43 +00004577
drhc2ce0be2014-05-29 12:36:14 +00004578 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
drh6976c212014-07-24 12:09:47 +00004579 if( nArg<2 || nArg>3 ){
mistachkinaae280e2015-12-31 19:06:24 +00004580 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
drhc2ce0be2014-05-29 12:36:14 +00004581 rc = 1;
4582 }
drh6976c212014-07-24 12:09:47 +00004583 if( nArg>=2 ){
mistachkin636bf9f2014-07-19 20:15:16 +00004584 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
mistachkin22c96382014-07-24 22:51:18 +00004585 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
drh6976c212014-07-24 12:09:47 +00004586 }
4587 if( nArg>=3 ){
mistachkine0d68852014-12-11 03:12:33 +00004588 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
4589 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
drh6976c212014-07-24 12:09:47 +00004590 }
drh75897232000-05-29 14:26:00 +00004591 }else
4592
drh62cdde52014-05-28 20:22:28 +00004593 if( c=='s'
4594 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
drh62cdde52014-05-28 20:22:28 +00004595 ){
4596 char *zCmd;
drh54027102014-08-06 14:36:53 +00004597 int i, x;
drhc2ce0be2014-05-29 12:36:14 +00004598 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004599 raw_printf(stderr, "Usage: .system COMMAND\n");
drhc2ce0be2014-05-29 12:36:14 +00004600 rc = 1;
4601 goto meta_command_exit;
4602 }
drhdcb3e3d2014-05-29 03:17:29 +00004603 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
drh62cdde52014-05-28 20:22:28 +00004604 for(i=2; i<nArg; i++){
drhdcb3e3d2014-05-29 03:17:29 +00004605 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
4606 zCmd, azArg[i]);
drh62cdde52014-05-28 20:22:28 +00004607 }
drh54027102014-08-06 14:36:53 +00004608 x = system(zCmd);
drh62cdde52014-05-28 20:22:28 +00004609 sqlite3_free(zCmd);
mistachkinaae280e2015-12-31 19:06:24 +00004610 if( x ) raw_printf(stderr, "System command returns %d\n", x);
drh62cdde52014-05-28 20:22:28 +00004611 }else
4612
drhc2ce0be2014-05-29 12:36:14 +00004613 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drheacd29d2016-04-15 15:03:27 +00004614 static const char *azBool[] = { "off", "on", "full", "unk" };
persicom7e2dfdd2002-04-18 02:46:52 +00004615 int i;
drhc2ce0be2014-05-29 12:36:14 +00004616 if( nArg!=1 ){
mistachkinaae280e2015-12-31 19:06:24 +00004617 raw_printf(stderr, "Usage: .show\n");
drhc2ce0be2014-05-29 12:36:14 +00004618 rc = 1;
4619 goto meta_command_exit;
4620 }
drheacd29d2016-04-15 15:03:27 +00004621 utf8_printf(p->out, "%12.12s: %s\n","echo", azBool[p->echoOn!=0]);
4622 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
drh700c2522016-02-09 18:39:25 +00004623 utf8_printf(p->out, "%12.12s: %s\n","explain",
4624 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
drheacd29d2016-04-15 15:03:27 +00004625 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004626 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
4627 utf8_printf(p->out, "%12.12s: ", "nullvalue");
mistachkin44b99f72014-12-11 03:29:14 +00004628 output_c_string(p->out, p->nullValue);
mistachkinaae280e2015-12-31 19:06:24 +00004629 raw_printf(p->out, "\n");
4630 utf8_printf(p->out,"%12.12s: %s\n","output",
drh4f21c4a2008-12-10 22:15:00 +00004631 strlen30(p->outfile) ? p->outfile : "stdout");
mistachkinaae280e2015-12-31 19:06:24 +00004632 utf8_printf(p->out,"%12.12s: ", "colseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004633 output_c_string(p->out, p->colSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004634 raw_printf(p->out, "\n");
4635 utf8_printf(p->out,"%12.12s: ", "rowseparator");
mistachkin636bf9f2014-07-19 20:15:16 +00004636 output_c_string(p->out, p->rowSeparator);
mistachkinaae280e2015-12-31 19:06:24 +00004637 raw_printf(p->out, "\n");
drheacd29d2016-04-15 15:03:27 +00004638 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
mistachkinaae280e2015-12-31 19:06:24 +00004639 utf8_printf(p->out, "%12.12s: ", "width");
persicom7e2dfdd2002-04-18 02:46:52 +00004640 for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
mistachkinaae280e2015-12-31 19:06:24 +00004641 raw_printf(p->out, "%d ", p->colWidth[i]);
persicom7e2dfdd2002-04-18 02:46:52 +00004642 }
mistachkinaae280e2015-12-31 19:06:24 +00004643 raw_printf(p->out, "\n");
drhcd0509e2016-09-16 00:26:08 +00004644 utf8_printf(p->out, "%12.12s: %s\n", "filename",
4645 p->zDbFilename ? p->zDbFilename : "");
persicom7e2dfdd2002-04-18 02:46:52 +00004646 }else
4647
drhc2ce0be2014-05-29 12:36:14 +00004648 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
4649 if( nArg==2 ){
4650 p->statsOn = booleanValue(azArg[1]);
drh34784902016-02-27 17:12:36 +00004651 }else if( nArg==1 ){
4652 display_stats(p->db, p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004653 }else{
drh34784902016-02-27 17:12:36 +00004654 raw_printf(stderr, "Usage: .stats ?on|off?\n");
drhc2ce0be2014-05-29 12:36:14 +00004655 rc = 1;
4656 }
shaneh642d8b82010-07-28 16:05:34 +00004657 }else
4658
drhc2ce0be2014-05-29 12:36:14 +00004659 if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
drh98781232012-04-23 12:38:05 +00004660 sqlite3_stmt *pStmt;
drhe3710332000-09-29 13:30:53 +00004661 char **azResult;
drh98781232012-04-23 12:38:05 +00004662 int nRow, nAlloc;
4663 char *zSql = 0;
4664 int ii;
drh05782482013-10-24 15:20:20 +00004665 open_db(p, 0);
drh98781232012-04-23 12:38:05 +00004666 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
dand95bb392015-09-30 11:19:05 +00004667 if( rc ) return shellDatabaseError(p->db);
4668
4669 /* Create an SQL statement to query for the list of tables in the
4670 ** main and all attached databases where the table name matches the
4671 ** LIKE pattern bound to variable "?1". */
drh98781232012-04-23 12:38:05 +00004672 zSql = sqlite3_mprintf(
4673 "SELECT name FROM sqlite_master"
4674 " WHERE type IN ('table','view')"
4675 " AND name NOT LIKE 'sqlite_%%'"
4676 " AND name LIKE ?1");
dand95bb392015-09-30 11:19:05 +00004677 while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
drh98781232012-04-23 12:38:05 +00004678 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
4679 if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
4680 if( strcmp(zDbName,"temp")==0 ){
4681 zSql = sqlite3_mprintf(
4682 "%z UNION ALL "
4683 "SELECT 'temp.' || name FROM sqlite_temp_master"
4684 " WHERE type IN ('table','view')"
4685 " AND name NOT LIKE 'sqlite_%%'"
4686 " AND name LIKE ?1", zSql);
4687 }else{
4688 zSql = sqlite3_mprintf(
4689 "%z UNION ALL "
4690 "SELECT '%q.' || name FROM \"%w\".sqlite_master"
4691 " WHERE type IN ('table','view')"
4692 " AND name NOT LIKE 'sqlite_%%'"
4693 " AND name LIKE ?1", zSql, zDbName, zDbName);
4694 }
drha50da102000-08-08 20:19:09 +00004695 }
dand95bb392015-09-30 11:19:05 +00004696 rc = sqlite3_finalize(pStmt);
4697 if( zSql && rc==SQLITE_OK ){
4698 zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
4699 if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
4700 }
drh98781232012-04-23 12:38:05 +00004701 sqlite3_free(zSql);
dand95bb392015-09-30 11:19:05 +00004702 if( !zSql ) return shellNomemError();
4703 if( rc ) return shellDatabaseError(p->db);
4704
4705 /* Run the SQL statement prepared by the above block. Store the results
4706 ** as an array of nul-terminated strings in azResult[]. */
drh98781232012-04-23 12:38:05 +00004707 nRow = nAlloc = 0;
4708 azResult = 0;
4709 if( nArg>1 ){
4710 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
shane9bd1b442009-10-23 01:27:39 +00004711 }else{
drh98781232012-04-23 12:38:05 +00004712 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
4713 }
4714 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4715 if( nRow>=nAlloc ){
4716 char **azNew;
mistachkin8e189222015-04-19 21:43:16 +00004717 int n2 = nAlloc*2 + 10;
drhf3cdcdc2015-04-29 16:50:28 +00004718 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh98781232012-04-23 12:38:05 +00004719 if( azNew==0 ){
dand95bb392015-09-30 11:19:05 +00004720 rc = shellNomemError();
drh98781232012-04-23 12:38:05 +00004721 break;
4722 }
mistachkin8e189222015-04-19 21:43:16 +00004723 nAlloc = n2;
drh98781232012-04-23 12:38:05 +00004724 azResult = azNew;
4725 }
4726 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
dand95bb392015-09-30 11:19:05 +00004727 if( 0==azResult[nRow] ){
4728 rc = shellNomemError();
4729 break;
4730 }
4731 nRow++;
drh98781232012-04-23 12:38:05 +00004732 }
dand95bb392015-09-30 11:19:05 +00004733 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
4734 rc = shellDatabaseError(p->db);
4735 }
4736
4737 /* Pretty-print the contents of array azResult[] to the output */
4738 if( rc==0 && nRow>0 ){
drhe3710332000-09-29 13:30:53 +00004739 int len, maxlen = 0;
4740 int i, j;
4741 int nPrintCol, nPrintRow;
drh98781232012-04-23 12:38:05 +00004742 for(i=0; i<nRow; i++){
drh4f21c4a2008-12-10 22:15:00 +00004743 len = strlen30(azResult[i]);
drhe3710332000-09-29 13:30:53 +00004744 if( len>maxlen ) maxlen = len;
4745 }
4746 nPrintCol = 80/(maxlen+2);
4747 if( nPrintCol<1 ) nPrintCol = 1;
4748 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
4749 for(i=0; i<nPrintRow; i++){
drh98781232012-04-23 12:38:05 +00004750 for(j=i; j<nRow; j+=nPrintRow){
4751 char *zSp = j<nPrintRow ? "" : " ";
drhe05461c2015-12-30 13:36:57 +00004752 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
4753 azResult[j] ? azResult[j]:"");
drhe3710332000-09-29 13:30:53 +00004754 }
mistachkinaae280e2015-12-31 19:06:24 +00004755 raw_printf(p->out, "\n");
drhe3710332000-09-29 13:30:53 +00004756 }
4757 }
dand95bb392015-09-30 11:19:05 +00004758
drh98781232012-04-23 12:38:05 +00004759 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
4760 sqlite3_free(azResult);
drh75897232000-05-29 14:26:00 +00004761 }else
4762
drh2db82112016-09-15 21:35:24 +00004763 /* Begin redirecting output to the file "testcase-out.txt" */
4764 if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
4765 output_reset(p);
4766 p->out = output_file_open("testcase-out.txt");
4767 if( p->out==0 ){
4768 utf8_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
4769 }
drh760c8162016-09-16 02:52:22 +00004770 if( nArg>=2 ){
4771 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
4772 }else{
4773 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
4774 }
drh2db82112016-09-15 21:35:24 +00004775 }else
drh2db82112016-09-15 21:35:24 +00004776
drh16eb5942016-11-03 13:01:38 +00004777#ifndef SQLITE_OMIT_BUILTIN_TEST
shaneh96887e12011-02-10 21:08:58 +00004778 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
drhd416fe72011-03-17 16:45:50 +00004779 static const struct {
4780 const char *zCtrlName; /* Name of a test-control option */
4781 int ctrlCode; /* Integer code for that option */
4782 } aCtrl[] = {
4783 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE },
4784 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE },
4785 { "prng_reset", SQLITE_TESTCTRL_PRNG_RESET },
4786 { "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST },
4787 { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL },
4788 { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS },
4789 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE },
4790 { "assert", SQLITE_TESTCTRL_ASSERT },
4791 { "always", SQLITE_TESTCTRL_ALWAYS },
4792 { "reserve", SQLITE_TESTCTRL_RESERVE },
4793 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS },
4794 { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD },
drhd416fe72011-03-17 16:45:50 +00004795 { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC },
drh2cf4acb2014-04-18 00:06:02 +00004796 { "byteorder", SQLITE_TESTCTRL_BYTEORDER },
drhe4bb23a2015-01-19 15:05:54 +00004797 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT },
drh1ffede82015-01-30 20:59:27 +00004798 { "imposter", SQLITE_TESTCTRL_IMPOSTER },
drhd416fe72011-03-17 16:45:50 +00004799 };
shaneh96887e12011-02-10 21:08:58 +00004800 int testctrl = -1;
mistachkin8e189222015-04-19 21:43:16 +00004801 int rc2 = 0;
4802 int i, n2;
drh05782482013-10-24 15:20:20 +00004803 open_db(p, 0);
shaneh96887e12011-02-10 21:08:58 +00004804
drhd416fe72011-03-17 16:45:50 +00004805 /* convert testctrl text option to value. allow any unique prefix
4806 ** of the option name, or a numerical value. */
mistachkin8e189222015-04-19 21:43:16 +00004807 n2 = strlen30(azArg[1]);
drhf5ed7ad2015-06-15 14:43:25 +00004808 for(i=0; i<ArraySize(aCtrl); i++){
mistachkin8e189222015-04-19 21:43:16 +00004809 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n2)==0 ){
drhd416fe72011-03-17 16:45:50 +00004810 if( testctrl<0 ){
4811 testctrl = aCtrl[i].ctrlCode;
4812 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004813 utf8_printf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
drhd416fe72011-03-17 16:45:50 +00004814 testctrl = -1;
4815 break;
4816 }
4817 }
4818 }
drh348d19c2013-06-03 12:47:43 +00004819 if( testctrl<0 ) testctrl = (int)integerValue(azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004820 if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
mistachkinaae280e2015-12-31 19:06:24 +00004821 utf8_printf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004822 }else{
4823 switch(testctrl){
4824
4825 /* sqlite3_test_control(int, db, int) */
4826 case SQLITE_TESTCTRL_OPTIMIZATIONS:
mistachkin1fe36bb2016-04-04 02:16:44 +00004827 case SQLITE_TESTCTRL_RESERVE:
shaneh96887e12011-02-10 21:08:58 +00004828 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004829 int opt = (int)strtol(azArg[2], 0, 0);
mistachkin8e189222015-04-19 21:43:16 +00004830 rc2 = sqlite3_test_control(testctrl, p->db, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004831 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004832 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004833 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004834 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004835 }
4836 break;
4837
4838 /* sqlite3_test_control(int) */
drh2cf4acb2014-04-18 00:06:02 +00004839 case SQLITE_TESTCTRL_PRNG_SAVE:
4840 case SQLITE_TESTCTRL_PRNG_RESTORE:
shaneh96887e12011-02-10 21:08:58 +00004841 case SQLITE_TESTCTRL_PRNG_RESET:
drh2cf4acb2014-04-18 00:06:02 +00004842 case SQLITE_TESTCTRL_BYTEORDER:
shaneh96887e12011-02-10 21:08:58 +00004843 if( nArg==2 ){
mistachkin8e189222015-04-19 21:43:16 +00004844 rc2 = sqlite3_test_control(testctrl);
mistachkinaae280e2015-12-31 19:06:24 +00004845 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004846 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004847 utf8_printf(stderr,"Error: testctrl %s takes no options\n",
4848 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004849 }
4850 break;
4851
4852 /* sqlite3_test_control(int, uint) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004853 case SQLITE_TESTCTRL_PENDING_BYTE:
shaneh96887e12011-02-10 21:08:58 +00004854 if( nArg==3 ){
drhaf664332013-07-18 20:28:29 +00004855 unsigned int opt = (unsigned int)integerValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004856 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004857 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004858 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004859 utf8_printf(stderr,"Error: testctrl %s takes a single unsigned"
drhd416fe72011-03-17 16:45:50 +00004860 " int option\n", azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004861 }
4862 break;
mistachkin1fe36bb2016-04-04 02:16:44 +00004863
shaneh96887e12011-02-10 21:08:58 +00004864 /* sqlite3_test_control(int, int) */
mistachkin1fe36bb2016-04-04 02:16:44 +00004865 case SQLITE_TESTCTRL_ASSERT:
4866 case SQLITE_TESTCTRL_ALWAYS:
4867 case SQLITE_TESTCTRL_NEVER_CORRUPT:
shaneh96887e12011-02-10 21:08:58 +00004868 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004869 int opt = booleanValue(azArg[2]);
mistachkin8e189222015-04-19 21:43:16 +00004870 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004871 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004872 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004873 utf8_printf(stderr,"Error: testctrl %s takes a single int option\n",
drhd416fe72011-03-17 16:45:50 +00004874 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004875 }
4876 break;
4877
4878 /* sqlite3_test_control(int, char *) */
4879#ifdef SQLITE_N_KEYWORD
mistachkin1fe36bb2016-04-04 02:16:44 +00004880 case SQLITE_TESTCTRL_ISKEYWORD:
shaneh96887e12011-02-10 21:08:58 +00004881 if( nArg==3 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004882 const char *opt = azArg[2];
mistachkin8e189222015-04-19 21:43:16 +00004883 rc2 = sqlite3_test_control(testctrl, opt);
mistachkinaae280e2015-12-31 19:06:24 +00004884 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
shaneh96887e12011-02-10 21:08:58 +00004885 } else {
mistachkinaae280e2015-12-31 19:06:24 +00004886 utf8_printf(stderr,
4887 "Error: testctrl %s takes a single char * option\n",
4888 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004889 }
4890 break;
4891#endif
4892
drh1ffede82015-01-30 20:59:27 +00004893 case SQLITE_TESTCTRL_IMPOSTER:
drh8964b342015-01-29 17:54:52 +00004894 if( nArg==5 ){
mistachkin1fe36bb2016-04-04 02:16:44 +00004895 rc2 = sqlite3_test_control(testctrl, p->db,
drh1ffede82015-01-30 20:59:27 +00004896 azArg[2],
drh8964b342015-01-29 17:54:52 +00004897 integerValue(azArg[3]),
4898 integerValue(azArg[4]));
mistachkinaae280e2015-12-31 19:06:24 +00004899 raw_printf(p->out, "%d (0x%08x)\n", rc2, rc2);
drh8964b342015-01-29 17:54:52 +00004900 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004901 raw_printf(stderr,"Usage: .testctrl imposter dbName onoff tnum\n");
drh8964b342015-01-29 17:54:52 +00004902 }
4903 break;
4904
mistachkin1fe36bb2016-04-04 02:16:44 +00004905 case SQLITE_TESTCTRL_BITVEC_TEST:
4906 case SQLITE_TESTCTRL_FAULT_INSTALL:
4907 case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS:
4908 case SQLITE_TESTCTRL_SCRATCHMALLOC:
shaneh96887e12011-02-10 21:08:58 +00004909 default:
mistachkinaae280e2015-12-31 19:06:24 +00004910 utf8_printf(stderr,
4911 "Error: CLI support for testctrl %s not implemented\n",
4912 azArg[1]);
shaneh96887e12011-02-10 21:08:58 +00004913 break;
4914 }
4915 }
4916 }else
4917
drhc2ce0be2014-05-29 12:36:14 +00004918 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
drh05782482013-10-24 15:20:20 +00004919 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004920 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
shanehe2aa9d72009-11-06 17:20:17 +00004921 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004922
drhc2ce0be2014-05-29 12:36:14 +00004923 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
4924 if( nArg==2 ){
4925 enableTimer = booleanValue(azArg[1]);
4926 if( enableTimer && !HAS_TIMER ){
mistachkinaae280e2015-12-31 19:06:24 +00004927 raw_printf(stderr, "Error: timer not available on this system.\n");
drhc2ce0be2014-05-29 12:36:14 +00004928 enableTimer = 0;
4929 }
4930 }else{
mistachkinaae280e2015-12-31 19:06:24 +00004931 raw_printf(stderr, "Usage: .timer on|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004932 rc = 1;
4933 }
shanehe2aa9d72009-11-06 17:20:17 +00004934 }else
mistachkin1fe36bb2016-04-04 02:16:44 +00004935
drhc2ce0be2014-05-29 12:36:14 +00004936 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh05782482013-10-24 15:20:20 +00004937 open_db(p, 0);
drhc2ce0be2014-05-29 12:36:14 +00004938 if( nArg!=2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004939 raw_printf(stderr, "Usage: .trace FILE|off\n");
drhc2ce0be2014-05-29 12:36:14 +00004940 rc = 1;
4941 goto meta_command_exit;
4942 }
drh657b4a82015-03-19 13:30:41 +00004943 output_file_close(p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004944 p->traceOut = output_file_open(azArg[1]);
drhbbb0be82012-06-27 16:12:27 +00004945#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
drh42f64e52012-04-04 16:56:23 +00004946 if( p->traceOut==0 ){
drh4b363a52016-07-23 20:27:41 +00004947 sqlite3_trace_v2(p->db, 0, 0, 0);
drh42f64e52012-04-04 16:56:23 +00004948 }else{
drh4b363a52016-07-23 20:27:41 +00004949 sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
drh42f64e52012-04-04 16:56:23 +00004950 }
4951#endif
4952 }else
drh16eb5942016-11-03 13:01:38 +00004953#endif /* !defined(SQLITE_OMIT_BUILTIN_TEST) */
drh42f64e52012-04-04 16:56:23 +00004954
drhf442e332014-09-10 19:01:14 +00004955#if SQLITE_USER_AUTHENTICATION
4956 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
4957 if( nArg<2 ){
mistachkinaae280e2015-12-31 19:06:24 +00004958 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
drhf442e332014-09-10 19:01:14 +00004959 rc = 1;
4960 goto meta_command_exit;
4961 }
drh7883ecf2014-09-11 16:19:31 +00004962 open_db(p, 0);
drhf442e332014-09-10 19:01:14 +00004963 if( strcmp(azArg[1],"login")==0 ){
4964 if( nArg!=4 ){
mistachkinaae280e2015-12-31 19:06:24 +00004965 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
drhf442e332014-09-10 19:01:14 +00004966 rc = 1;
4967 goto meta_command_exit;
4968 }
drhd39c40f2014-09-11 00:27:53 +00004969 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
4970 (int)strlen(azArg[3]));
drhf442e332014-09-10 19:01:14 +00004971 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004972 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
drhf442e332014-09-10 19:01:14 +00004973 rc = 1;
4974 }
4975 }else if( strcmp(azArg[1],"add")==0 ){
4976 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004977 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004978 rc = 1;
4979 goto meta_command_exit;
4980 }
drhd39c40f2014-09-11 00:27:53 +00004981 rc = sqlite3_user_add(p->db, azArg[2],
4982 azArg[3], (int)strlen(azArg[3]),
4983 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004984 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004985 raw_printf(stderr, "User-Add failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004986 rc = 1;
4987 }
4988 }else if( strcmp(azArg[1],"edit")==0 ){
4989 if( nArg!=5 ){
mistachkinaae280e2015-12-31 19:06:24 +00004990 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
drhf442e332014-09-10 19:01:14 +00004991 rc = 1;
4992 goto meta_command_exit;
4993 }
drhd39c40f2014-09-11 00:27:53 +00004994 rc = sqlite3_user_change(p->db, azArg[2],
4995 azArg[3], (int)strlen(azArg[3]),
4996 booleanValue(azArg[4]));
drhf442e332014-09-10 19:01:14 +00004997 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00004998 raw_printf(stderr, "User-Edit failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00004999 rc = 1;
5000 }
5001 }else if( strcmp(azArg[1],"delete")==0 ){
5002 if( nArg!=3 ){
mistachkinaae280e2015-12-31 19:06:24 +00005003 raw_printf(stderr, "Usage: .user delete USER\n");
drhf442e332014-09-10 19:01:14 +00005004 rc = 1;
5005 goto meta_command_exit;
5006 }
5007 rc = sqlite3_user_delete(p->db, azArg[2]);
5008 if( rc ){
mistachkinaae280e2015-12-31 19:06:24 +00005009 raw_printf(stderr, "User-Delete failed: %d\n", rc);
drhf442e332014-09-10 19:01:14 +00005010 rc = 1;
5011 }
5012 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005013 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
drhf442e332014-09-10 19:01:14 +00005014 rc = 1;
5015 goto meta_command_exit;
mistachkin1fe36bb2016-04-04 02:16:44 +00005016 }
drhf442e332014-09-10 19:01:14 +00005017 }else
5018#endif /* SQLITE_USER_AUTHENTICATION */
5019
drh9fd301b2011-06-03 13:28:22 +00005020 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005021 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
drh9fd301b2011-06-03 13:28:22 +00005022 sqlite3_libversion(), sqlite3_sourceid());
5023 }else
5024
drh790f2872015-11-28 18:06:36 +00005025 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
5026 const char *zDbName = nArg==2 ? azArg[1] : "main";
5027 sqlite3_vfs *pVfs;
5028 if( p->db ){
5029 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
5030 if( pVfs ){
mistachkinaae280e2015-12-31 19:06:24 +00005031 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
5032 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
5033 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
5034 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
drh790f2872015-11-28 18:06:36 +00005035 }
5036 }
5037 }else
5038
drhb19e7352016-01-12 19:37:20 +00005039 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
5040 sqlite3_vfs *pVfs;
5041 sqlite3_vfs *pCurrent = 0;
5042 if( p->db ){
5043 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
5044 }
5045 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
5046 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
5047 pVfs==pCurrent ? " <--- CURRENT" : "");
5048 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
5049 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
5050 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
5051 if( pVfs->pNext ){
5052 raw_printf(p->out, "-----------------------------------\n");
5053 }
5054 }
5055 }else
5056
drhde60fc22011-12-14 17:53:36 +00005057 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
5058 const char *zDbName = nArg==2 ? azArg[1] : "main";
5059 char *zVfsName = 0;
5060 if( p->db ){
5061 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
5062 if( zVfsName ){
mistachkinaae280e2015-12-31 19:06:24 +00005063 utf8_printf(p->out, "%s\n", zVfsName);
drhde60fc22011-12-14 17:53:36 +00005064 sqlite3_free(zVfsName);
5065 }
5066 }
5067 }else
5068
drhcef4fc82012-09-21 22:50:45 +00005069#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
5070 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
drhc2ce0be2014-05-29 12:36:14 +00005071 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
drhcef4fc82012-09-21 22:50:45 +00005072 }else
5073#endif
5074
drhc2ce0be2014-05-29 12:36:14 +00005075 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
drh75897232000-05-29 14:26:00 +00005076 int j;
drh43617e92006-03-06 20:55:46 +00005077 assert( nArg<=ArraySize(azArg) );
drh75897232000-05-29 14:26:00 +00005078 for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
drh348d19c2013-06-03 12:47:43 +00005079 p->colWidth[j-1] = (int)integerValue(azArg[j]);
drh75897232000-05-29 14:26:00 +00005080 }
5081 }else
5082
5083 {
mistachkinaae280e2015-12-31 19:06:24 +00005084 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
drh67505e72002-04-19 12:34:06 +00005085 " \"%s\". Enter \".help\" for help\n", azArg[0]);
shane9bd1b442009-10-23 01:27:39 +00005086 rc = 1;
drh75897232000-05-29 14:26:00 +00005087 }
drh67505e72002-04-19 12:34:06 +00005088
drhc2ce0be2014-05-29 12:36:14 +00005089meta_command_exit:
5090 if( p->outCount ){
5091 p->outCount--;
5092 if( p->outCount==0 ) output_reset(p);
5093 }
drh67505e72002-04-19 12:34:06 +00005094 return rc;
drh75897232000-05-29 14:26:00 +00005095}
5096
drh67505e72002-04-19 12:34:06 +00005097/*
drh91a66392007-09-07 01:12:32 +00005098** Return TRUE if a semicolon occurs anywhere in the first N characters
5099** of string z[].
drh324ccef2003-02-05 14:06:20 +00005100*/
drh9f099fd2013-08-06 14:01:46 +00005101static int line_contains_semicolon(const char *z, int N){
drh91a66392007-09-07 01:12:32 +00005102 int i;
5103 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
5104 return 0;
drh324ccef2003-02-05 14:06:20 +00005105}
5106
5107/*
drh70c7a4b2003-04-26 03:03:06 +00005108** Test to see if a line consists entirely of whitespace.
5109*/
5110static int _all_whitespace(const char *z){
5111 for(; *z; z++){
drhf0693c82011-10-11 20:41:54 +00005112 if( IsSpace(z[0]) ) continue;
drh70c7a4b2003-04-26 03:03:06 +00005113 if( *z=='/' && z[1]=='*' ){
5114 z += 2;
5115 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
5116 if( *z==0 ) return 0;
5117 z++;
5118 continue;
5119 }
5120 if( *z=='-' && z[1]=='-' ){
5121 z += 2;
5122 while( *z && *z!='\n' ){ z++; }
5123 if( *z==0 ) return 1;
5124 continue;
5125 }
5126 return 0;
5127 }
5128 return 1;
5129}
5130
5131/*
drha9b17162003-04-29 18:01:28 +00005132** Return TRUE if the line typed in is an SQL command terminator other
5133** than a semi-colon. The SQL Server style "go" command is understood
5134** as is the Oracle "/".
5135*/
drh9f099fd2013-08-06 14:01:46 +00005136static int line_is_command_terminator(const char *zLine){
drhf0693c82011-10-11 20:41:54 +00005137 while( IsSpace(zLine[0]) ){ zLine++; };
drh233a5312008-12-18 22:25:13 +00005138 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
5139 return 1; /* Oracle */
5140 }
drhf0693c82011-10-11 20:41:54 +00005141 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
drhc8d74412004-08-31 23:41:26 +00005142 && _all_whitespace(&zLine[2]) ){
drha9b17162003-04-29 18:01:28 +00005143 return 1; /* SQL Server */
5144 }
5145 return 0;
5146}
5147
5148/*
drh233a5312008-12-18 22:25:13 +00005149** Return true if zSql is a complete SQL statement. Return false if it
5150** ends in the middle of a string literal or C-style comment.
5151*/
drh9f099fd2013-08-06 14:01:46 +00005152static int line_is_complete(char *zSql, int nSql){
drh233a5312008-12-18 22:25:13 +00005153 int rc;
5154 if( zSql==0 ) return 1;
5155 zSql[nSql] = ';';
5156 zSql[nSql+1] = 0;
5157 rc = sqlite3_complete(zSql);
5158 zSql[nSql] = 0;
5159 return rc;
5160}
5161
5162/*
drh67505e72002-04-19 12:34:06 +00005163** Read input from *in and process it. If *in==0 then input
5164** is interactive - the user is typing it it. Otherwise, input
5165** is coming from a file or device. A prompt is issued and history
5166** is saved only if input is interactive. An interrupt signal will
5167** cause this routine to exit immediately, unless input is interactive.
drhc28490c2006-10-26 14:25:58 +00005168**
5169** Return the number of errors.
drh67505e72002-04-19 12:34:06 +00005170*/
drhdcd87a92014-08-18 13:45:42 +00005171static int process_input(ShellState *p, FILE *in){
drh9f099fd2013-08-06 14:01:46 +00005172 char *zLine = 0; /* A single input line */
5173 char *zSql = 0; /* Accumulated SQL text */
5174 int nLine; /* Length of current line */
5175 int nSql = 0; /* Bytes of zSql[] used */
5176 int nAlloc = 0; /* Allocated zSql[] space */
5177 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
5178 char *zErrMsg; /* Error message returned */
5179 int rc; /* Error code */
5180 int errCnt = 0; /* Number of errors seen */
5181 int lineno = 0; /* Current line number */
5182 int startline = 0; /* Line number for start of current input */
drhc49f44e2006-10-26 18:15:42 +00005183
5184 while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
5185 fflush(p->out);
drh9f099fd2013-08-06 14:01:46 +00005186 zLine = one_input_line(in, zLine, nSql>0);
drhc49f44e2006-10-26 18:15:42 +00005187 if( zLine==0 ){
drh9b8d3572012-04-21 11:33:39 +00005188 /* End of input */
drhfc8b40f2016-09-07 10:10:18 +00005189 if( in==0 && stdin_is_interactive ) printf("\n");
drh9b8d3572012-04-21 11:33:39 +00005190 break;
drhc49f44e2006-10-26 18:15:42 +00005191 }
drh67505e72002-04-19 12:34:06 +00005192 if( seenInterrupt ){
5193 if( in!=0 ) break;
5194 seenInterrupt = 0;
5195 }
drhc28490c2006-10-26 14:25:58 +00005196 lineno++;
drh849a9d92013-12-21 15:46:06 +00005197 if( nSql==0 && _all_whitespace(zLine) ){
5198 if( p->echoOn ) printf("%s\n", zLine);
5199 continue;
5200 }
drh2af0b2d2002-02-21 02:25:02 +00005201 if( zLine && zLine[0]=='.' && nSql==0 ){
shaneb9fc17d2009-10-22 21:23:35 +00005202 if( p->echoOn ) printf("%s\n", zLine);
drhc49f44e2006-10-26 18:15:42 +00005203 rc = do_meta_command(zLine, p);
shane916f9612009-10-23 00:37:15 +00005204 if( rc==2 ){ /* exit requested */
drh47ad6842006-11-08 12:25:42 +00005205 break;
5206 }else if( rc ){
drhc49f44e2006-10-26 18:15:42 +00005207 errCnt++;
5208 }
drhdaffd0e2001-04-11 14:28:42 +00005209 continue;
5210 }
drh9f099fd2013-08-06 14:01:46 +00005211 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
drh5bb3eb92007-05-04 13:15:55 +00005212 memcpy(zLine,";",2);
drha9b17162003-04-29 18:01:28 +00005213 }
drh9f099fd2013-08-06 14:01:46 +00005214 nLine = strlen30(zLine);
5215 if( nSql+nLine+2>=nAlloc ){
5216 nAlloc = nSql+nLine+100;
5217 zSql = realloc(zSql, nAlloc);
drhdaffd0e2001-04-11 14:28:42 +00005218 if( zSql==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005219 raw_printf(stderr, "Error: out of memory\n");
drhdaffd0e2001-04-11 14:28:42 +00005220 exit(1);
5221 }
drhdaffd0e2001-04-11 14:28:42 +00005222 }
drh9f099fd2013-08-06 14:01:46 +00005223 nSqlPrior = nSql;
5224 if( nSql==0 ){
5225 int i;
5226 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
drh77dfd5b2013-08-19 11:15:48 +00005227 assert( nAlloc>0 && zSql!=0 );
drh9f099fd2013-08-06 14:01:46 +00005228 memcpy(zSql, zLine+i, nLine+1-i);
5229 startline = lineno;
5230 nSql = nLine-i;
5231 }else{
5232 zSql[nSql++] = '\n';
5233 memcpy(zSql+nSql, zLine, nLine+1);
5234 nSql += nLine;
5235 }
5236 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
drh91a66392007-09-07 01:12:32 +00005237 && sqlite3_complete(zSql) ){
drhdaffd0e2001-04-11 14:28:42 +00005238 p->cnt = 0;
drh05782482013-10-24 15:20:20 +00005239 open_db(p, 0);
drh9569f602015-04-16 15:05:04 +00005240 if( p->backslashOn ) resolve_backslashes(zSql);
drh3b1a9882007-11-02 12:53:03 +00005241 BEGIN_TIMER;
shane626a6e42009-10-22 17:30:15 +00005242 rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
drh3b1a9882007-11-02 12:53:03 +00005243 END_TIMER;
drh7f953e22002-07-13 17:33:45 +00005244 if( rc || zErrMsg ){
drhc28490c2006-10-26 14:25:58 +00005245 char zPrefix[100];
5246 if( in!=0 || !stdin_is_interactive ){
mistachkin1fe36bb2016-04-04 02:16:44 +00005247 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
shane9bd1b442009-10-23 01:27:39 +00005248 "Error: near line %d:", startline);
drhc28490c2006-10-26 14:25:58 +00005249 }else{
shane9bd1b442009-10-23 01:27:39 +00005250 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
drhc28490c2006-10-26 14:25:58 +00005251 }
drh7f953e22002-07-13 17:33:45 +00005252 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005253 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
drh3f4fedb2004-05-31 19:34:33 +00005254 sqlite3_free(zErrMsg);
drh7f953e22002-07-13 17:33:45 +00005255 zErrMsg = 0;
5256 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005257 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
drh7f953e22002-07-13 17:33:45 +00005258 }
drhc49f44e2006-10-26 18:15:42 +00005259 errCnt++;
drhdf12f1c2015-12-07 21:46:19 +00005260 }else if( p->countChanges ){
mistachkinaae280e2015-12-31 19:06:24 +00005261 raw_printf(p->out, "changes: %3d total_changes: %d\n",
drhdf12f1c2015-12-07 21:46:19 +00005262 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
drhdaffd0e2001-04-11 14:28:42 +00005263 }
drhdaffd0e2001-04-11 14:28:42 +00005264 nSql = 0;
drhc2ce0be2014-05-29 12:36:14 +00005265 if( p->outCount ){
5266 output_reset(p);
5267 p->outCount = 0;
5268 }
drh9f099fd2013-08-06 14:01:46 +00005269 }else if( nSql && _all_whitespace(zSql) ){
drh849a9d92013-12-21 15:46:06 +00005270 if( p->echoOn ) printf("%s\n", zSql);
drh7a411f42013-04-17 17:33:17 +00005271 nSql = 0;
drhdaffd0e2001-04-11 14:28:42 +00005272 }
5273 }
drh9f099fd2013-08-06 14:01:46 +00005274 if( nSql ){
drhd416fe72011-03-17 16:45:50 +00005275 if( !_all_whitespace(zSql) ){
mistachkinaae280e2015-12-31 19:06:24 +00005276 utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
drhbf59bf92014-10-10 13:08:33 +00005277 errCnt++;
drhd416fe72011-03-17 16:45:50 +00005278 }
drhdaffd0e2001-04-11 14:28:42 +00005279 }
drh1f9ca2c2015-08-25 16:57:52 +00005280 free(zSql);
danielk19772ac27622007-07-03 05:31:16 +00005281 free(zLine);
drh4d15a0d2012-12-01 20:21:22 +00005282 return errCnt>0;
drhdaffd0e2001-04-11 14:28:42 +00005283}
5284
drh67505e72002-04-19 12:34:06 +00005285/*
5286** Return a pathname which is the user's home directory. A
drh85e72432012-04-11 11:38:53 +00005287** 0 return indicates an error of some kind.
drh67505e72002-04-19 12:34:06 +00005288*/
drhd1459152016-09-16 19:11:03 +00005289static char *find_home_dir(int clearFlag){
drh85e72432012-04-11 11:38:53 +00005290 static char *home_dir = NULL;
drhd1459152016-09-16 19:11:03 +00005291 if( clearFlag ){
5292 free(home_dir);
5293 home_dir = 0;
5294 return 0;
5295 }
drh85e72432012-04-11 11:38:53 +00005296 if( home_dir ) return home_dir;
persicom7e2dfdd2002-04-18 02:46:52 +00005297
drh4ace5362014-11-10 14:42:28 +00005298#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
5299 && !defined(__RTP__) && !defined(_WRS_KERNEL)
mistachkinc8bde372012-06-18 08:00:56 +00005300 {
5301 struct passwd *pwent;
5302 uid_t uid = getuid();
5303 if( (pwent=getpwuid(uid)) != NULL) {
5304 home_dir = pwent->pw_dir;
5305 }
drh67505e72002-04-19 12:34:06 +00005306 }
5307#endif
5308
chw65d3c132007-11-12 21:09:10 +00005309#if defined(_WIN32_WCE)
5310 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
5311 */
drh85e72432012-04-11 11:38:53 +00005312 home_dir = "/";
chw65d3c132007-11-12 21:09:10 +00005313#else
5314
drh83905c92012-06-21 13:00:37 +00005315#if defined(_WIN32) || defined(WIN32)
drh164a1b62006-08-19 11:15:20 +00005316 if (!home_dir) {
5317 home_dir = getenv("USERPROFILE");
5318 }
5319#endif
5320
drh67505e72002-04-19 12:34:06 +00005321 if (!home_dir) {
5322 home_dir = getenv("HOME");
drh67505e72002-04-19 12:34:06 +00005323 }
5324
drh83905c92012-06-21 13:00:37 +00005325#if defined(_WIN32) || defined(WIN32)
drhe98d4fa2002-04-21 19:06:22 +00005326 if (!home_dir) {
drh164a1b62006-08-19 11:15:20 +00005327 char *zDrive, *zPath;
5328 int n;
5329 zDrive = getenv("HOMEDRIVE");
5330 zPath = getenv("HOMEPATH");
5331 if( zDrive && zPath ){
drh4f21c4a2008-12-10 22:15:00 +00005332 n = strlen30(zDrive) + strlen30(zPath) + 1;
drh164a1b62006-08-19 11:15:20 +00005333 home_dir = malloc( n );
5334 if( home_dir==0 ) return 0;
5335 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
5336 return home_dir;
5337 }
5338 home_dir = "c:\\";
drhe98d4fa2002-04-21 19:06:22 +00005339 }
5340#endif
5341
chw65d3c132007-11-12 21:09:10 +00005342#endif /* !_WIN32_WCE */
5343
drh67505e72002-04-19 12:34:06 +00005344 if( home_dir ){
drh4f21c4a2008-12-10 22:15:00 +00005345 int n = strlen30(home_dir) + 1;
drh5bb3eb92007-05-04 13:15:55 +00005346 char *z = malloc( n );
5347 if( z ) memcpy(z, home_dir, n);
drh67505e72002-04-19 12:34:06 +00005348 home_dir = z;
5349 }
drhe98d4fa2002-04-21 19:06:22 +00005350
drh67505e72002-04-19 12:34:06 +00005351 return home_dir;
5352}
5353
5354/*
5355** Read input from the file given by sqliterc_override. Or if that
5356** parameter is NULL, take input from ~/.sqliterc
shane9bd1b442009-10-23 01:27:39 +00005357**
5358** Returns the number of errors.
drh67505e72002-04-19 12:34:06 +00005359*/
drh534f4df2015-02-28 14:03:35 +00005360static void process_sqliterc(
drhdcd87a92014-08-18 13:45:42 +00005361 ShellState *p, /* Configuration data */
drh22fbcb82004-02-01 01:22:50 +00005362 const char *sqliterc_override /* Name of config file. NULL to use default */
5363){
persicom7e2dfdd2002-04-18 02:46:52 +00005364 char *home_dir = NULL;
drh22fbcb82004-02-01 01:22:50 +00005365 const char *sqliterc = sqliterc_override;
drh43617e92006-03-06 20:55:46 +00005366 char *zBuf = 0;
persicom7e2dfdd2002-04-18 02:46:52 +00005367 FILE *in = NULL;
5368
5369 if (sqliterc == NULL) {
drhd1459152016-09-16 19:11:03 +00005370 home_dir = find_home_dir(0);
drhe98d4fa2002-04-21 19:06:22 +00005371 if( home_dir==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005372 raw_printf(stderr, "-- warning: cannot find home directory;"
drh534f4df2015-02-28 14:03:35 +00005373 " cannot read ~/.sqliterc\n");
5374 return;
drhe98d4fa2002-04-21 19:06:22 +00005375 }
drh2f3de322012-06-27 16:41:31 +00005376 sqlite3_initialize();
drh85e72432012-04-11 11:38:53 +00005377 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
5378 sqliterc = zBuf;
persicom7e2dfdd2002-04-18 02:46:52 +00005379 }
drha1f9b5e2004-02-14 16:31:02 +00005380 in = fopen(sqliterc,"rb");
drh22fbcb82004-02-01 01:22:50 +00005381 if( in ){
drhc28490c2006-10-26 14:25:58 +00005382 if( stdin_is_interactive ){
mistachkinaae280e2015-12-31 19:06:24 +00005383 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
drh22fbcb82004-02-01 01:22:50 +00005384 }
drh534f4df2015-02-28 14:03:35 +00005385 process_input(p,in);
drhdd45df82002-04-18 12:39:03 +00005386 fclose(in);
persicom7e2dfdd2002-04-18 02:46:52 +00005387 }
drh85e72432012-04-11 11:38:53 +00005388 sqlite3_free(zBuf);
persicom7e2dfdd2002-04-18 02:46:52 +00005389}
5390
drh67505e72002-04-19 12:34:06 +00005391/*
drhe1e38c42003-05-04 18:30:59 +00005392** Show available command line options
5393*/
mistachkin1fe36bb2016-04-04 02:16:44 +00005394static const char zOptions[] =
mistachkin636bf9f2014-07-19 20:15:16 +00005395 " -ascii set output mode to 'ascii'\n"
drhc49f44e2006-10-26 18:15:42 +00005396 " -bail stop after hitting an error\n"
drhc49f44e2006-10-26 18:15:42 +00005397 " -batch force batch I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005398 " -column set output mode to 'column'\n"
mistachkin6d81d752012-10-25 15:43:28 +00005399 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
drhc49f44e2006-10-26 18:15:42 +00005400 " -csv set output mode to 'csv'\n"
drhcc3b4f82012-02-07 14:13:50 +00005401 " -echo print commands before execution\n"
mistachkin6d81d752012-10-25 15:43:28 +00005402 " -init FILENAME read/process named file\n"
drhcc3b4f82012-02-07 14:13:50 +00005403 " -[no]header turn headers on or off\n"
drh98d312f2012-10-25 15:23:14 +00005404#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
5405 " -heap SIZE Size of heap for memsys3 or memsys5\n"
5406#endif
drhcc3b4f82012-02-07 14:13:50 +00005407 " -help show this message\n"
drhe1e38c42003-05-04 18:30:59 +00005408 " -html set output mode to HTML\n"
drhcc3b4f82012-02-07 14:13:50 +00005409 " -interactive force interactive I/O\n"
drhe1e38c42003-05-04 18:30:59 +00005410 " -line set output mode to 'line'\n"
5411 " -list set output mode to 'list'\n"
drh44dec872014-08-30 15:49:25 +00005412 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh7d9f3942013-04-03 01:26:54 +00005413 " -mmap N default mmap size set to N\n"
drhcc3b4f82012-02-07 14:13:50 +00005414#ifdef SQLITE_ENABLE_MULTIPLEX
5415 " -multiplex enable the multiplexor VFS\n"
5416#endif
mistachkine0d68852014-12-11 03:12:33 +00005417 " -newline SEP set output row separator. Default: '\\n'\n"
drh98d312f2012-10-25 15:23:14 +00005418 " -nullvalue TEXT set text string for NULL values. Default ''\n"
drh44dec872014-08-30 15:49:25 +00005419 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
5420 " -scratch SIZE N use N slots of SZ bytes each for scratch memory\n"
mistachkine0d68852014-12-11 03:12:33 +00005421 " -separator SEP set output column separator. Default: '|'\n"
shaneh642d8b82010-07-28 16:05:34 +00005422 " -stats print memory stats before each finalize\n"
drhe1e38c42003-05-04 18:30:59 +00005423 " -version show SQLite version\n"
drha7e61d82011-03-12 17:02:57 +00005424 " -vfs NAME use NAME as the default VFS\n"
drh2b625e22011-03-16 17:05:28 +00005425#ifdef SQLITE_ENABLE_VFSTRACE
5426 " -vfstrace enable tracing of all VFS calls\n"
5427#endif
drhe1e38c42003-05-04 18:30:59 +00005428;
5429static void usage(int showDetail){
mistachkinaae280e2015-12-31 19:06:24 +00005430 utf8_printf(stderr,
mistachkin1fe36bb2016-04-04 02:16:44 +00005431 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
drh80e8be92006-08-29 12:04:19 +00005432 "FILENAME is the name of an SQLite database. A new database is created\n"
5433 "if the file does not previously exist.\n", Argv0);
drhe1e38c42003-05-04 18:30:59 +00005434 if( showDetail ){
mistachkinaae280e2015-12-31 19:06:24 +00005435 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
drhe1e38c42003-05-04 18:30:59 +00005436 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005437 raw_printf(stderr, "Use the -help option for additional information\n");
drhe1e38c42003-05-04 18:30:59 +00005438 }
5439 exit(1);
5440}
5441
5442/*
drh67505e72002-04-19 12:34:06 +00005443** Initialize the state information in data
5444*/
drhdcd87a92014-08-18 13:45:42 +00005445static void main_init(ShellState *data) {
persicom7e2dfdd2002-04-18 02:46:52 +00005446 memset(data, 0, sizeof(*data));
drh700c2522016-02-09 18:39:25 +00005447 data->normalMode = data->cMode = data->mode = MODE_List;
5448 data->autoExplain = 1;
mistachkinfad42082014-07-24 22:13:12 +00005449 memcpy(data->colSeparator,SEP_Column, 2);
5450 memcpy(data->rowSeparator,SEP_Row, 2);
persicom7e2dfdd2002-04-18 02:46:52 +00005451 data->showHeader = 0;
drh44dec872014-08-30 15:49:25 +00005452 data->shellFlgs = SHFLG_Lookaside;
drh52784bd2011-05-18 17:15:06 +00005453 sqlite3_config(SQLITE_CONFIG_URI, 1);
drh127f9d72010-02-23 01:47:00 +00005454 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
drh44dec872014-08-30 15:49:25 +00005455 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
drh5bb3eb92007-05-04 13:15:55 +00005456 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
5457 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
persicom7e2dfdd2002-04-18 02:46:52 +00005458}
5459
drh98d312f2012-10-25 15:23:14 +00005460/*
drh5c7976f2014-02-10 19:59:27 +00005461** Output text to the console in a font that attracts extra attention.
drh1247aa42014-02-10 19:27:05 +00005462*/
5463#ifdef _WIN32
drh5c7976f2014-02-10 19:59:27 +00005464static void printBold(const char *zText){
5465 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
5466 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
5467 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
5468 SetConsoleTextAttribute(out,
5469 FOREGROUND_RED|FOREGROUND_INTENSITY
5470 );
5471 printf("%s", zText);
5472 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
drh1247aa42014-02-10 19:27:05 +00005473}
5474#else
drh5c7976f2014-02-10 19:59:27 +00005475static void printBold(const char *zText){
5476 printf("\033[1m%s\033[0m", zText);
drh1247aa42014-02-10 19:27:05 +00005477}
5478#endif
5479
5480/*
drh98d312f2012-10-25 15:23:14 +00005481** Get the argument to an --option. Throw an error and die if no argument
5482** is available.
5483*/
5484static char *cmdline_option_value(int argc, char **argv, int i){
5485 if( i==argc ){
mistachkinaae280e2015-12-31 19:06:24 +00005486 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
drh98d312f2012-10-25 15:23:14 +00005487 argv[0], argv[argc-1]);
5488 exit(1);
5489 }
5490 return argv[i];
5491}
5492
mistachkin1fe36bb2016-04-04 02:16:44 +00005493#ifndef SQLITE_SHELL_IS_UTF8
5494# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
5495# define SQLITE_SHELL_IS_UTF8 (0)
5496# else
5497# define SQLITE_SHELL_IS_UTF8 (1)
5498# endif
5499#endif
5500
5501#if SQLITE_SHELL_IS_UTF8
mistachkin44723ce2015-03-21 02:22:37 +00005502int SQLITE_CDECL main(int argc, char **argv){
mistachkin1fe36bb2016-04-04 02:16:44 +00005503#else
5504int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
mistachkin1810f222016-04-04 02:33:34 +00005505 char **argv;
mistachkin1fe36bb2016-04-04 02:16:44 +00005506#endif
drh75897232000-05-29 14:26:00 +00005507 char *zErrMsg = 0;
drhdcd87a92014-08-18 13:45:42 +00005508 ShellState data;
drh22fbcb82004-02-01 01:22:50 +00005509 const char *zInitFile = 0;
drh44c2eb12003-04-30 11:38:26 +00005510 int i;
drhc28490c2006-10-26 14:25:58 +00005511 int rc = 0;
drhb3735912014-02-10 16:13:42 +00005512 int warnInmemoryDb = 0;
drhac5649a2014-11-28 13:35:03 +00005513 int readStdin = 1;
5514 int nCmd = 0;
5515 char **azCmd = 0;
drh75897232000-05-29 14:26:00 +00005516
mistachkin1fe36bb2016-04-04 02:16:44 +00005517 setBinaryMode(stdin, 0);
5518 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
mistachkin1810f222016-04-04 02:33:34 +00005519 stdin_is_interactive = isatty(0);
5520 stdout_is_console = isatty(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005521
drh69b30ab2014-02-27 15:11:52 +00005522#if USE_SYSTEM_SQLITE+0!=1
drh52784bd2011-05-18 17:15:06 +00005523 if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005524 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
drh52784bd2011-05-18 17:15:06 +00005525 sqlite3_sourceid(), SQLITE_SOURCE_ID);
5526 exit(1);
5527 }
drhc7181902014-02-27 15:04:13 +00005528#endif
persicom7e2dfdd2002-04-18 02:46:52 +00005529 main_init(&data);
mistachkin1fe36bb2016-04-04 02:16:44 +00005530#if !SQLITE_SHELL_IS_UTF8
5531 sqlite3_initialize();
5532 argv = sqlite3_malloc64(sizeof(argv[0])*argc);
5533 if( argv==0 ){
5534 raw_printf(stderr, "out of memory\n");
5535 exit(1);
5536 }
5537 for(i=0; i<argc; i++){
5538 argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);
5539 if( argv[i]==0 ){
5540 raw_printf(stderr, "out of memory\n");
5541 exit(1);
5542 }
5543 }
5544#endif
mistachkin1810f222016-04-04 02:33:34 +00005545 assert( argc>=1 && argv && argv[0] );
mistachkin1fe36bb2016-04-04 02:16:44 +00005546 Argv0 = argv[0];
persicom7e2dfdd2002-04-18 02:46:52 +00005547
drh44c2eb12003-04-30 11:38:26 +00005548 /* Make sure we have a valid signal handler early, before anything
5549 ** else is done.
5550 */
drh4c504392000-10-16 22:06:40 +00005551#ifdef SIGINT
5552 signal(SIGINT, interrupt_handler);
5553#endif
drh44c2eb12003-04-30 11:38:26 +00005554
drhac5649a2014-11-28 13:35:03 +00005555#ifdef SQLITE_SHELL_DBNAME_PROC
5556 {
5557 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
5558 ** of a C-function that will provide the name of the database file. Use
5559 ** this compile-time option to embed this shell program in larger
5560 ** applications. */
5561 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
5562 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
5563 warnInmemoryDb = 0;
5564 }
5565#endif
5566
drh22fbcb82004-02-01 01:22:50 +00005567 /* Do an initial pass through the command-line argument to locate
5568 ** the name of the database file, the name of the initialization file,
drh9c88d682010-12-17 14:03:01 +00005569 ** the size of the alternative malloc heap,
drh22fbcb82004-02-01 01:22:50 +00005570 ** and the first command to execute.
drh44c2eb12003-04-30 11:38:26 +00005571 */
drh98d312f2012-10-25 15:23:14 +00005572 for(i=1; i<argc; i++){
drhc28490c2006-10-26 14:25:58 +00005573 char *z;
drhc28490c2006-10-26 14:25:58 +00005574 z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005575 if( z[0]!='-' ){
5576 if( data.zDbFilename==0 ){
5577 data.zDbFilename = z;
drhac5649a2014-11-28 13:35:03 +00005578 }else{
5579 /* Excesss arguments are interpreted as SQL (or dot-commands) and
5580 ** mean that nothing is read from stdin */
5581 readStdin = 0;
5582 nCmd++;
5583 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
5584 if( azCmd==0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005585 raw_printf(stderr, "out of memory\n");
drhac5649a2014-11-28 13:35:03 +00005586 exit(1);
5587 }
5588 azCmd[nCmd-1] = z;
drh98d312f2012-10-25 15:23:14 +00005589 }
drh98d312f2012-10-25 15:23:14 +00005590 }
drhcc3b4f82012-02-07 14:13:50 +00005591 if( z[1]=='-' ) z++;
5592 if( strcmp(z,"-separator")==0
5593 || strcmp(z,"-nullvalue")==0
drh6976c212014-07-24 12:09:47 +00005594 || strcmp(z,"-newline")==0
drhcc3b4f82012-02-07 14:13:50 +00005595 || strcmp(z,"-cmd")==0
5596 ){
drh98d312f2012-10-25 15:23:14 +00005597 (void)cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005598 }else if( strcmp(z,"-init")==0 ){
drh98d312f2012-10-25 15:23:14 +00005599 zInitFile = cmdline_option_value(argc, argv, ++i);
drhcc3b4f82012-02-07 14:13:50 +00005600 }else if( strcmp(z,"-batch")==0 ){
drh98d312f2012-10-25 15:23:14 +00005601 /* Need to check for batch mode here to so we can avoid printing
mistachkin1fe36bb2016-04-04 02:16:44 +00005602 ** informational messages (like from process_sqliterc) before
drh98d312f2012-10-25 15:23:14 +00005603 ** we do the actual processing of arguments later in a second pass.
5604 */
shanef69573d2009-10-24 02:06:14 +00005605 stdin_is_interactive = 0;
drhcc3b4f82012-02-07 14:13:50 +00005606 }else if( strcmp(z,"-heap")==0 ){
drhb07028f2011-10-14 21:49:18 +00005607#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
drh9c88d682010-12-17 14:03:01 +00005608 const char *zSize;
5609 sqlite3_int64 szHeap;
5610
drh98d312f2012-10-25 15:23:14 +00005611 zSize = cmdline_option_value(argc, argv, ++i);
drh7d9f3942013-04-03 01:26:54 +00005612 szHeap = integerValue(zSize);
drh9c88d682010-12-17 14:03:01 +00005613 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
drh9c88d682010-12-17 14:03:01 +00005614 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
drhc530b9c2016-07-25 11:27:22 +00005615#else
5616 (void)cmdline_option_value(argc, argv, ++i);
drh9c88d682010-12-17 14:03:01 +00005617#endif
drh44dec872014-08-30 15:49:25 +00005618 }else if( strcmp(z,"-scratch")==0 ){
5619 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005620 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005621 if( sz>400000 ) sz = 400000;
5622 if( sz<2500 ) sz = 2500;
mistachkin31970cc2014-09-01 01:16:49 +00005623 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005624 if( n>10 ) n = 10;
5625 if( n<1 ) n = 1;
5626 sqlite3_config(SQLITE_CONFIG_SCRATCH, malloc(n*sz+1), sz, n);
5627 data.shellFlgs |= SHFLG_Scratch;
5628 }else if( strcmp(z,"-pagecache")==0 ){
5629 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005630 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005631 if( sz>70000 ) sz = 70000;
drh3d38cec2015-11-11 15:28:52 +00005632 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005633 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh3d38cec2015-11-11 15:28:52 +00005634 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
5635 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
drh44dec872014-08-30 15:49:25 +00005636 data.shellFlgs |= SHFLG_Pagecache;
5637 }else if( strcmp(z,"-lookaside")==0 ){
5638 int n, sz;
mistachkin31970cc2014-09-01 01:16:49 +00005639 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005640 if( sz<0 ) sz = 0;
mistachkin31970cc2014-09-01 01:16:49 +00005641 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
drh44dec872014-08-30 15:49:25 +00005642 if( n<0 ) n = 0;
5643 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
5644 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
drh97ae8ff2011-03-16 16:56:29 +00005645#ifdef SQLITE_ENABLE_VFSTRACE
drhcc3b4f82012-02-07 14:13:50 +00005646 }else if( strcmp(z,"-vfstrace")==0 ){
drh97ae8ff2011-03-16 16:56:29 +00005647 extern int vfstrace_register(
5648 const char *zTraceName,
5649 const char *zOldVfsName,
5650 int (*xOut)(const char*,void*),
5651 void *pOutArg,
5652 int makeDefault
5653 );
drh2b625e22011-03-16 17:05:28 +00005654 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
drh97ae8ff2011-03-16 16:56:29 +00005655#endif
drh6f25e892011-07-08 17:02:57 +00005656#ifdef SQLITE_ENABLE_MULTIPLEX
drhcc3b4f82012-02-07 14:13:50 +00005657 }else if( strcmp(z,"-multiplex")==0 ){
drh6f25e892011-07-08 17:02:57 +00005658 extern int sqlite3_multiple_initialize(const char*,int);
5659 sqlite3_multiplex_initialize(0, 1);
5660#endif
drh7d9f3942013-04-03 01:26:54 +00005661 }else if( strcmp(z,"-mmap")==0 ){
drh9b4c59f2013-04-15 17:03:42 +00005662 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
5663 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drhcc3b4f82012-02-07 14:13:50 +00005664 }else if( strcmp(z,"-vfs")==0 ){
drh98d312f2012-10-25 15:23:14 +00005665 sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
drha7e61d82011-03-12 17:02:57 +00005666 if( pVfs ){
5667 sqlite3_vfs_register(pVfs, 1);
5668 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005669 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
drha7e61d82011-03-12 17:02:57 +00005670 exit(1);
5671 }
drh44c2eb12003-04-30 11:38:26 +00005672 }
5673 }
drh98d312f2012-10-25 15:23:14 +00005674 if( data.zDbFilename==0 ){
danielk197703aded42004-11-22 05:26:27 +00005675#ifndef SQLITE_OMIT_MEMORYDB
drh22fbcb82004-02-01 01:22:50 +00005676 data.zDbFilename = ":memory:";
drh1247aa42014-02-10 19:27:05 +00005677 warnInmemoryDb = argc==1;
danielk197703aded42004-11-22 05:26:27 +00005678#else
mistachkinaae280e2015-12-31 19:06:24 +00005679 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
shane86f5bdb2009-10-24 02:00:07 +00005680 return 1;
drh01b41712005-08-29 23:06:23 +00005681#endif
drh98d312f2012-10-25 15:23:14 +00005682 }
5683 data.out = stdout;
drh01b41712005-08-29 23:06:23 +00005684
drh44c2eb12003-04-30 11:38:26 +00005685 /* Go ahead and open the database file if it already exists. If the
5686 ** file does not exist, delay opening it. This prevents empty database
5687 ** files from being created if a user mistypes the database name argument
5688 ** to the sqlite command-line tool.
5689 */
drhc8d74412004-08-31 23:41:26 +00005690 if( access(data.zDbFilename, 0)==0 ){
drh05782482013-10-24 15:20:20 +00005691 open_db(&data, 0);
drh44c2eb12003-04-30 11:38:26 +00005692 }
5693
drh22fbcb82004-02-01 01:22:50 +00005694 /* Process the initialization file if there is one. If no -init option
5695 ** is given on the command line, look for a file named ~/.sqliterc and
5696 ** try to process it.
drh44c2eb12003-04-30 11:38:26 +00005697 */
drh534f4df2015-02-28 14:03:35 +00005698 process_sqliterc(&data,zInitFile);
drh44c2eb12003-04-30 11:38:26 +00005699
drh22fbcb82004-02-01 01:22:50 +00005700 /* Make a second pass through the command-line argument and set
5701 ** options. This second pass is delayed until after the initialization
5702 ** file is processed so that the command-line arguments will override
5703 ** settings in the initialization file.
drh44c2eb12003-04-30 11:38:26 +00005704 */
drh98d312f2012-10-25 15:23:14 +00005705 for(i=1; i<argc; i++){
drh22fbcb82004-02-01 01:22:50 +00005706 char *z = argv[i];
drh98d312f2012-10-25 15:23:14 +00005707 if( z[0]!='-' ) continue;
drhc28490c2006-10-26 14:25:58 +00005708 if( z[1]=='-' ){ z++; }
drh2e584cd2006-09-25 13:09:22 +00005709 if( strcmp(z,"-init")==0 ){
drh22fbcb82004-02-01 01:22:50 +00005710 i++;
5711 }else if( strcmp(z,"-html")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005712 data.mode = MODE_Html;
drh22fbcb82004-02-01 01:22:50 +00005713 }else if( strcmp(z,"-list")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005714 data.mode = MODE_List;
drh22fbcb82004-02-01 01:22:50 +00005715 }else if( strcmp(z,"-line")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005716 data.mode = MODE_Line;
drh22fbcb82004-02-01 01:22:50 +00005717 }else if( strcmp(z,"-column")==0 ){
drh8b32e172002-04-08 02:42:57 +00005718 data.mode = MODE_Column;
drhc49f44e2006-10-26 18:15:42 +00005719 }else if( strcmp(z,"-csv")==0 ){
5720 data.mode = MODE_Csv;
mistachkin636bf9f2014-07-19 20:15:16 +00005721 memcpy(data.colSeparator,",",2);
5722 }else if( strcmp(z,"-ascii")==0 ){
5723 data.mode = MODE_Ascii;
5724 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005725 SEP_Unit);
mistachkin636bf9f2014-07-19 20:15:16 +00005726 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
mistachkinfad42082014-07-24 22:13:12 +00005727 SEP_Record);
drh22fbcb82004-02-01 01:22:50 +00005728 }else if( strcmp(z,"-separator")==0 ){
mistachkin636bf9f2014-07-19 20:15:16 +00005729 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
drh98d312f2012-10-25 15:23:14 +00005730 "%s",cmdline_option_value(argc,argv,++i));
drh6976c212014-07-24 12:09:47 +00005731 }else if( strcmp(z,"-newline")==0 ){
mistachkine0d68852014-12-11 03:12:33 +00005732 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
drh6976c212014-07-24 12:09:47 +00005733 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005734 }else if( strcmp(z,"-nullvalue")==0 ){
mistachkin44b99f72014-12-11 03:29:14 +00005735 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
drh98d312f2012-10-25 15:23:14 +00005736 "%s",cmdline_option_value(argc,argv,++i));
drh22fbcb82004-02-01 01:22:50 +00005737 }else if( strcmp(z,"-header")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005738 data.showHeader = 1;
drh22fbcb82004-02-01 01:22:50 +00005739 }else if( strcmp(z,"-noheader")==0 ){
drh1e5d0e92000-05-31 23:33:17 +00005740 data.showHeader = 0;
drh22fbcb82004-02-01 01:22:50 +00005741 }else if( strcmp(z,"-echo")==0 ){
drhdaffd0e2001-04-11 14:28:42 +00005742 data.echoOn = 1;
drhefbf3b12014-02-28 20:47:24 +00005743 }else if( strcmp(z,"-eqp")==0 ){
5744 data.autoEQP = 1;
drheacd29d2016-04-15 15:03:27 +00005745 }else if( strcmp(z,"-eqpfull")==0 ){
5746 data.autoEQP = 2;
shaneh642d8b82010-07-28 16:05:34 +00005747 }else if( strcmp(z,"-stats")==0 ){
5748 data.statsOn = 1;
dan8d1edb92014-11-05 09:07:28 +00005749 }else if( strcmp(z,"-scanstats")==0 ){
5750 data.scanstatsOn = 1;
drh9569f602015-04-16 15:05:04 +00005751 }else if( strcmp(z,"-backslash")==0 ){
5752 /* Undocumented command-line option: -backslash
5753 ** Causes C-style backslash escapes to be evaluated in SQL statements
5754 ** prior to sending the SQL into SQLite. Useful for injecting
5755 ** crazy bytes in the middle of SQL statements for testing and debugging.
5756 */
5757 data.backslashOn = 1;
drhc49f44e2006-10-26 18:15:42 +00005758 }else if( strcmp(z,"-bail")==0 ){
5759 bail_on_error = 1;
drh22fbcb82004-02-01 01:22:50 +00005760 }else if( strcmp(z,"-version")==0 ){
drh9fd301b2011-06-03 13:28:22 +00005761 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
drh151e3e12006-06-06 12:32:21 +00005762 return 0;
drhc28490c2006-10-26 14:25:58 +00005763 }else if( strcmp(z,"-interactive")==0 ){
5764 stdin_is_interactive = 1;
5765 }else if( strcmp(z,"-batch")==0 ){
5766 stdin_is_interactive = 0;
drh9c88d682010-12-17 14:03:01 +00005767 }else if( strcmp(z,"-heap")==0 ){
5768 i++;
drh44dec872014-08-30 15:49:25 +00005769 }else if( strcmp(z,"-scratch")==0 ){
5770 i+=2;
5771 }else if( strcmp(z,"-pagecache")==0 ){
5772 i+=2;
5773 }else if( strcmp(z,"-lookaside")==0 ){
5774 i+=2;
drh7d9f3942013-04-03 01:26:54 +00005775 }else if( strcmp(z,"-mmap")==0 ){
5776 i++;
drha7e61d82011-03-12 17:02:57 +00005777 }else if( strcmp(z,"-vfs")==0 ){
5778 i++;
drh6f25e892011-07-08 17:02:57 +00005779#ifdef SQLITE_ENABLE_VFSTRACE
drh97ae8ff2011-03-16 16:56:29 +00005780 }else if( strcmp(z,"-vfstrace")==0 ){
5781 i++;
drh6f25e892011-07-08 17:02:57 +00005782#endif
5783#ifdef SQLITE_ENABLE_MULTIPLEX
5784 }else if( strcmp(z,"-multiplex")==0 ){
5785 i++;
5786#endif
drhcc3b4f82012-02-07 14:13:50 +00005787 }else if( strcmp(z,"-help")==0 ){
drhe1e38c42003-05-04 18:30:59 +00005788 usage(1);
drhcc3b4f82012-02-07 14:13:50 +00005789 }else if( strcmp(z,"-cmd")==0 ){
drhac5649a2014-11-28 13:35:03 +00005790 /* Run commands that follow -cmd first and separately from commands
5791 ** that simply appear on the command-line. This seems goofy. It would
5792 ** be better if all commands ran in the order that they appear. But
5793 ** we retain the goofy behavior for historical compatibility. */
drhcc3b4f82012-02-07 14:13:50 +00005794 if( i==argc-1 ) break;
drh98d312f2012-10-25 15:23:14 +00005795 z = cmdline_option_value(argc,argv,++i);
drhcc3b4f82012-02-07 14:13:50 +00005796 if( z[0]=='.' ){
5797 rc = do_meta_command(z, &data);
drh99b39082013-04-17 12:19:48 +00005798 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
drhcc3b4f82012-02-07 14:13:50 +00005799 }else{
drh05782482013-10-24 15:20:20 +00005800 open_db(&data, 0);
drhcc3b4f82012-02-07 14:13:50 +00005801 rc = shell_exec(data.db, z, shell_callback, &data, &zErrMsg);
5802 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005803 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhcc3b4f82012-02-07 14:13:50 +00005804 if( bail_on_error ) return rc!=0 ? rc : 1;
5805 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005806 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
drhcc3b4f82012-02-07 14:13:50 +00005807 if( bail_on_error ) return rc;
5808 }
5809 }
drh1e5d0e92000-05-31 23:33:17 +00005810 }else{
mistachkinaae280e2015-12-31 19:06:24 +00005811 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
5812 raw_printf(stderr,"Use -help for a list of options.\n");
drh1e5d0e92000-05-31 23:33:17 +00005813 return 1;
5814 }
drh700c2522016-02-09 18:39:25 +00005815 data.cMode = data.mode;
drh1e5d0e92000-05-31 23:33:17 +00005816 }
drh44c2eb12003-04-30 11:38:26 +00005817
drhac5649a2014-11-28 13:35:03 +00005818 if( !readStdin ){
5819 /* Run all arguments that do not begin with '-' as if they were separate
5820 ** command-line inputs, except for the argToSkip argument which contains
5821 ** the database filename.
drh44c2eb12003-04-30 11:38:26 +00005822 */
drhac5649a2014-11-28 13:35:03 +00005823 for(i=0; i<nCmd; i++){
5824 if( azCmd[i][0]=='.' ){
5825 rc = do_meta_command(azCmd[i], &data);
5826 if( rc ) return rc==2 ? 0 : rc;
5827 }else{
5828 open_db(&data, 0);
5829 rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
5830 if( zErrMsg!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005831 utf8_printf(stderr,"Error: %s\n", zErrMsg);
drhac5649a2014-11-28 13:35:03 +00005832 return rc!=0 ? rc : 1;
5833 }else if( rc!=0 ){
mistachkinaae280e2015-12-31 19:06:24 +00005834 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
drhac5649a2014-11-28 13:35:03 +00005835 return rc;
5836 }
drh6ff13852001-11-25 13:18:23 +00005837 }
drh75897232000-05-29 14:26:00 +00005838 }
drhac5649a2014-11-28 13:35:03 +00005839 free(azCmd);
drh75897232000-05-29 14:26:00 +00005840 }else{
drh44c2eb12003-04-30 11:38:26 +00005841 /* Run commands received from standard input
5842 */
drhc28490c2006-10-26 14:25:58 +00005843 if( stdin_is_interactive ){
drh67505e72002-04-19 12:34:06 +00005844 char *zHome;
5845 char *zHistory = 0;
drh5bb3eb92007-05-04 13:15:55 +00005846 int nHistory;
drh75897232000-05-29 14:26:00 +00005847 printf(
drh743e0032011-12-12 16:51:50 +00005848 "SQLite version %s %.19s\n" /*extra-version-info*/
drh1247aa42014-02-10 19:27:05 +00005849 "Enter \".help\" for usage hints.\n",
drh9fd301b2011-06-03 13:28:22 +00005850 sqlite3_libversion(), sqlite3_sourceid()
drh75897232000-05-29 14:26:00 +00005851 );
drhb3735912014-02-10 16:13:42 +00005852 if( warnInmemoryDb ){
drh1247aa42014-02-10 19:27:05 +00005853 printf("Connected to a ");
mistachkin378d01a2014-03-06 02:15:42 +00005854 printBold("transient in-memory database");
5855 printf(".\nUse \".open FILENAME\" to reopen on a "
drh1247aa42014-02-10 19:27:05 +00005856 "persistent database.\n");
drhb3735912014-02-10 16:13:42 +00005857 }
drhd1459152016-09-16 19:11:03 +00005858 zHome = find_home_dir(0);
drhea678832008-12-10 19:26:22 +00005859 if( zHome ){
drh4f21c4a2008-12-10 22:15:00 +00005860 nHistory = strlen30(zHome) + 20;
drhea678832008-12-10 19:26:22 +00005861 if( (zHistory = malloc(nHistory))!=0 ){
5862 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
5863 }
drh67505e72002-04-19 12:34:06 +00005864 }
drhf5ed7ad2015-06-15 14:43:25 +00005865 if( zHistory ){ shell_read_history(zHistory); }
drhc28490c2006-10-26 14:25:58 +00005866 rc = process_input(&data, 0);
drh67505e72002-04-19 12:34:06 +00005867 if( zHistory ){
danfd34d6d2015-02-25 10:54:53 +00005868 shell_stifle_history(100);
5869 shell_write_history(zHistory);
adamd0a3daa32006-07-28 20:16:14 +00005870 free(zHistory);
drh67505e72002-04-19 12:34:06 +00005871 }
drhdaffd0e2001-04-11 14:28:42 +00005872 }else{
drhc28490c2006-10-26 14:25:58 +00005873 rc = process_input(&data, stdin);
drh75897232000-05-29 14:26:00 +00005874 }
5875 }
drh33048c02001-10-01 14:29:22 +00005876 set_table_name(&data, 0);
drh72af0772010-05-06 20:19:55 +00005877 if( data.db ){
drhe6229612014-08-18 15:08:26 +00005878 session_close_all(&data);
drhe14cd932010-12-08 03:28:17 +00005879 sqlite3_close(data.db);
adamd0a3daa32006-07-28 20:16:14 +00005880 }
mistachkin1fe36bb2016-04-04 02:16:44 +00005881 sqlite3_free(data.zFreeOnClose);
drhd1459152016-09-16 19:11:03 +00005882 find_home_dir(1);
mistachkin1fe36bb2016-04-04 02:16:44 +00005883#if !SQLITE_SHELL_IS_UTF8
5884 for(i=0; i<argc; i++) sqlite3_free(argv[i]);
5885 sqlite3_free(argv);
5886#endif
drhc28490c2006-10-26 14:25:58 +00005887 return rc;
drh75897232000-05-29 14:26:00 +00005888}