blob: 826523870de320ad7438a39eefebd8a8b69e85d5 [file] [log] [blame]
drh2ce15c32017-07-11 13:34:40 +00001/*
2** 2001 September 15
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** 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.
10**
11*************************************************************************
12** This file contains code to implement the "sqlite" command line
13** utility for accessing SQLite databases.
14*/
15#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
16/* This needs to come before any includes for MSVC compiler */
17#define _CRT_SECURE_NO_WARNINGS
18#endif
19
20/*
mistachkin43e86272020-04-09 15:31:22 +000021** Determine if we are dealing with WinRT, which provides only a subset of
22** the full Win32 API.
23*/
24#if !defined(SQLITE_OS_WINRT)
25# define SQLITE_OS_WINRT 0
26#endif
27
28/*
drh2ce15c32017-07-11 13:34:40 +000029** Warning pragmas copied from msvc.h in the core.
30*/
31#if defined(_MSC_VER)
32#pragma warning(disable : 4054)
33#pragma warning(disable : 4055)
34#pragma warning(disable : 4100)
35#pragma warning(disable : 4127)
36#pragma warning(disable : 4130)
37#pragma warning(disable : 4152)
38#pragma warning(disable : 4189)
39#pragma warning(disable : 4206)
40#pragma warning(disable : 4210)
41#pragma warning(disable : 4232)
42#pragma warning(disable : 4244)
43#pragma warning(disable : 4305)
44#pragma warning(disable : 4306)
45#pragma warning(disable : 4702)
46#pragma warning(disable : 4706)
47#endif /* defined(_MSC_VER) */
48
49/*
50** No support for loadable extensions in VxWorks.
51*/
52#if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION
53# define SQLITE_OMIT_LOAD_EXTENSION 1
54#endif
55
56/*
57** Enable large-file support for fopen() and friends on unix.
58*/
59#ifndef SQLITE_DISABLE_LFS
60# define _LARGE_FILE 1
61# ifndef _FILE_OFFSET_BITS
62# define _FILE_OFFSET_BITS 64
63# endif
64# define _LARGEFILE_SOURCE 1
65#endif
66
67#include <stdlib.h>
68#include <string.h>
69#include <stdio.h>
70#include <assert.h>
71#include "sqlite3.h"
drh1e506b52018-01-05 21:01:37 +000072typedef sqlite3_int64 i64;
73typedef sqlite3_uint64 u64;
drh1fa6d9f2018-01-06 21:46:01 +000074typedef unsigned char u8;
drh2ce15c32017-07-11 13:34:40 +000075#if SQLITE_USER_AUTHENTICATION
76# include "sqlite3userauth.h"
77#endif
78#include <ctype.h>
79#include <stdarg.h>
80
81#if !defined(_WIN32) && !defined(WIN32)
82# include <signal.h>
83# if !defined(__RTP__) && !defined(_WRS_KERNEL)
84# include <pwd.h>
85# endif
mistachkinacae8c32018-01-05 20:08:46 +000086#endif
mistachkin562f0c82018-01-09 00:28:24 +000087#if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__)
drh2ce15c32017-07-11 13:34:40 +000088# include <unistd.h>
mistachkinacae8c32018-01-05 20:08:46 +000089# include <dirent.h>
mistachkin1e8487d2018-07-22 06:25:35 +000090# define GETPID getpid
mistachkin562f0c82018-01-09 00:28:24 +000091# if defined(__MINGW32__)
mistachkinacae8c32018-01-05 20:08:46 +000092# define DIRENT dirent
mistachkin2f74b3c2018-01-05 20:26:06 +000093# ifndef S_ISLNK
94# define S_ISLNK(mode) (0)
95# endif
mistachkinacae8c32018-01-05 20:08:46 +000096# endif
mistachkin1e8487d2018-07-22 06:25:35 +000097#else
98# define GETPID (int)GetCurrentProcessId
drh2ce15c32017-07-11 13:34:40 +000099#endif
mistachkindfdfd8c2018-01-04 22:46:08 +0000100#include <sys/types.h>
101#include <sys/stat.h>
drh2ce15c32017-07-11 13:34:40 +0000102
103#if HAVE_READLINE
104# include <readline/readline.h>
105# include <readline/history.h>
106#endif
107
108#if HAVE_EDITLINE
109# include <editline/readline.h>
110#endif
111
112#if HAVE_EDITLINE || HAVE_READLINE
113
114# define shell_add_history(X) add_history(X)
115# define shell_read_history(X) read_history(X)
116# define shell_write_history(X) write_history(X)
117# define shell_stifle_history(X) stifle_history(X)
118# define shell_readline(X) readline(X)
119
120#elif HAVE_LINENOISE
121
122# include "linenoise.h"
123# define shell_add_history(X) linenoiseHistoryAdd(X)
124# define shell_read_history(X) linenoiseHistoryLoad(X)
125# define shell_write_history(X) linenoiseHistorySave(X)
126# define shell_stifle_history(X) linenoiseHistorySetMaxLen(X)
127# define shell_readline(X) linenoise(X)
128
129#else
130
131# define shell_read_history(X)
132# define shell_write_history(X)
133# define shell_stifle_history(X)
134
135# define SHELL_USE_LOCAL_GETLINE 1
136#endif
137
138
139#if defined(_WIN32) || defined(WIN32)
mistachkin43e86272020-04-09 15:31:22 +0000140# if SQLITE_OS_WINRT
141# define SQLITE_OMIT_POPEN 1
142# else
143# include <io.h>
144# include <fcntl.h>
145# define isatty(h) _isatty(h)
146# ifndef access
147# define access(f,m) _access((f),(m))
148# endif
149# ifndef unlink
150# define unlink _unlink
151# endif
152# ifndef strdup
153# define strdup _strdup
154# endif
155# undef popen
156# define popen _popen
157# undef pclose
158# define pclose _pclose
drh2ce15c32017-07-11 13:34:40 +0000159# endif
drh2ce15c32017-07-11 13:34:40 +0000160#else
161 /* Make sure isatty() has a prototype. */
162 extern int isatty(int);
163
164# if !defined(__RTP__) && !defined(_WRS_KERNEL)
165 /* popen and pclose are not C89 functions and so are
166 ** sometimes omitted from the <stdio.h> header */
167 extern FILE *popen(const char*,const char*);
168 extern int pclose(FILE*);
169# else
170# define SQLITE_OMIT_POPEN 1
171# endif
172#endif
173
174#if defined(_WIN32_WCE)
175/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
176 * thus we always assume that we have a console. That can be
177 * overridden with the -batch command line option.
178 */
179#define isatty(x) 1
180#endif
181
182/* ctype macros that work with signed characters */
183#define IsSpace(X) isspace((unsigned char)X)
184#define IsDigit(X) isdigit((unsigned char)X)
185#define ToLower(X) (char)tolower((unsigned char)X)
186
187#if defined(_WIN32) || defined(WIN32)
mistachkin43e86272020-04-09 15:31:22 +0000188#if SQLITE_OS_WINRT
189#include <intrin.h>
190#endif
drh2ce15c32017-07-11 13:34:40 +0000191#include <windows.h>
192
193/* string conversion routines only needed on Win32 */
194extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
195extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
196extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
197extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
198#endif
199
200/* On Windows, we normally run with output mode of TEXT so that \n characters
201** are automatically translated into \r\n. However, this behavior needs
202** to be disabled in some cases (ex: when generating CSV output and when
203** rendering quoted strings that contain \n characters). The following
204** routines take care of that.
205*/
mistachkin43e86272020-04-09 15:31:22 +0000206#if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT
drh2ce15c32017-07-11 13:34:40 +0000207static void setBinaryMode(FILE *file, int isOutput){
208 if( isOutput ) fflush(file);
209 _setmode(_fileno(file), _O_BINARY);
210}
211static void setTextMode(FILE *file, int isOutput){
212 if( isOutput ) fflush(file);
213 _setmode(_fileno(file), _O_TEXT);
214}
215#else
216# define setBinaryMode(X,Y)
217# define setTextMode(X,Y)
218#endif
219
220
221/* True if the timer is enabled */
222static int enableTimer = 0;
223
224/* Return the current wall-clock time */
225static sqlite3_int64 timeOfDay(void){
226 static sqlite3_vfs *clockVfs = 0;
227 sqlite3_int64 t;
228 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0);
229 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){
230 clockVfs->xCurrentTimeInt64(clockVfs, &t);
231 }else{
232 double r;
233 clockVfs->xCurrentTime(clockVfs, &r);
234 t = (sqlite3_int64)(r*86400000.0);
235 }
236 return t;
237}
238
239#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux)
240#include <sys/time.h>
241#include <sys/resource.h>
242
243/* VxWorks does not support getrusage() as far as we can determine */
244#if defined(_WRS_KERNEL) || defined(__RTP__)
245struct rusage {
246 struct timeval ru_utime; /* user CPU time used */
247 struct timeval ru_stime; /* system CPU time used */
248};
249#define getrusage(A,B) memset(B,0,sizeof(*B))
250#endif
251
252/* Saved resource information for the beginning of an operation */
253static struct rusage sBegin; /* CPU time at start */
254static sqlite3_int64 iBegin; /* Wall-clock time at start */
255
256/*
257** Begin timing an operation
258*/
259static void beginTimer(void){
260 if( enableTimer ){
261 getrusage(RUSAGE_SELF, &sBegin);
262 iBegin = timeOfDay();
263 }
264}
265
266/* Return the difference of two time_structs in seconds */
267static double timeDiff(struct timeval *pStart, struct timeval *pEnd){
268 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 +
269 (double)(pEnd->tv_sec - pStart->tv_sec);
270}
271
272/*
273** Print the timing results.
274*/
275static void endTimer(void){
276 if( enableTimer ){
277 sqlite3_int64 iEnd = timeOfDay();
278 struct rusage sEnd;
279 getrusage(RUSAGE_SELF, &sEnd);
280 printf("Run Time: real %.3f user %f sys %f\n",
281 (iEnd - iBegin)*0.001,
282 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
283 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
284 }
285}
286
287#define BEGIN_TIMER beginTimer()
288#define END_TIMER endTimer()
289#define HAS_TIMER 1
290
291#elif (defined(_WIN32) || defined(WIN32))
292
293/* Saved resource information for the beginning of an operation */
294static HANDLE hProcess;
295static FILETIME ftKernelBegin;
296static FILETIME ftUserBegin;
297static sqlite3_int64 ftWallBegin;
298typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME,
299 LPFILETIME, LPFILETIME);
300static GETPROCTIMES getProcessTimesAddr = NULL;
301
302/*
303** Check to see if we have timer support. Return 1 if necessary
304** support found (or found previously).
305*/
306static int hasTimer(void){
307 if( getProcessTimesAddr ){
308 return 1;
309 } else {
mistachkin43e86272020-04-09 15:31:22 +0000310#if !SQLITE_OS_WINRT
drh2ce15c32017-07-11 13:34:40 +0000311 /* GetProcessTimes() isn't supported in WIN95 and some other Windows
312 ** versions. See if the version we are running on has it, and if it
313 ** does, save off a pointer to it and the current process handle.
314 */
315 hProcess = GetCurrentProcess();
316 if( hProcess ){
317 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll"));
318 if( NULL != hinstLib ){
319 getProcessTimesAddr =
320 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes");
321 if( NULL != getProcessTimesAddr ){
322 return 1;
323 }
324 FreeLibrary(hinstLib);
325 }
326 }
mistachkin43e86272020-04-09 15:31:22 +0000327#endif
drh2ce15c32017-07-11 13:34:40 +0000328 }
329 return 0;
330}
331
332/*
333** Begin timing an operation
334*/
335static void beginTimer(void){
336 if( enableTimer && getProcessTimesAddr ){
337 FILETIME ftCreation, ftExit;
338 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,
339 &ftKernelBegin,&ftUserBegin);
340 ftWallBegin = timeOfDay();
341 }
342}
343
344/* Return the difference of two FILETIME structs in seconds */
345static double timeDiff(FILETIME *pStart, FILETIME *pEnd){
346 sqlite_int64 i64Start = *((sqlite_int64 *) pStart);
347 sqlite_int64 i64End = *((sqlite_int64 *) pEnd);
348 return (double) ((i64End - i64Start) / 10000000.0);
349}
350
351/*
352** Print the timing results.
353*/
354static void endTimer(void){
355 if( enableTimer && getProcessTimesAddr){
356 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
357 sqlite3_int64 ftWallEnd = timeOfDay();
358 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
359 printf("Run Time: real %.3f user %f sys %f\n",
360 (ftWallEnd - ftWallBegin)*0.001,
361 timeDiff(&ftUserBegin, &ftUserEnd),
362 timeDiff(&ftKernelBegin, &ftKernelEnd));
363 }
364}
365
366#define BEGIN_TIMER beginTimer()
367#define END_TIMER endTimer()
368#define HAS_TIMER hasTimer()
369
370#else
371#define BEGIN_TIMER
372#define END_TIMER
373#define HAS_TIMER 0
374#endif
375
376/*
377** Used to prevent warnings about unused parameters
378*/
379#define UNUSED_PARAMETER(x) (void)(x)
380
381/*
drh5af06982018-01-10 00:53:55 +0000382** Number of elements in an array
383*/
384#define ArraySize(X) (int)(sizeof(X)/sizeof(X[0]))
385
386/*
drh2ce15c32017-07-11 13:34:40 +0000387** If the following flag is set, then command execution stops
388** at an error if we are not interactive.
389*/
390static int bail_on_error = 0;
391
392/*
393** Threat stdin as an interactive input if the following variable
394** is true. Otherwise, assume stdin is connected to a file or pipe.
395*/
396static int stdin_is_interactive = 1;
397
398/*
399** On Windows systems we have to know if standard output is a console
400** in order to translate UTF-8 into MBCS. The following variable is
401** true if translation is required.
402*/
403static int stdout_is_console = 1;
404
405/*
406** The following is the open SQLite database. We make a pointer
407** to this database a static variable so that it can be accessed
408** by the SIGINT handler to interrupt database processing.
409*/
410static sqlite3 *globalDb = 0;
411
412/*
413** True if an interrupt (Control-C) has been received.
414*/
415static volatile int seenInterrupt = 0;
416
drh4a3a3eb2020-02-29 15:53:48 +0000417#ifdef SQLITE_DEBUG
418/*
419** Out-of-memory simulator variables
420*/
421static unsigned int oomCounter = 0; /* Simulate OOM when equals 1 */
422static unsigned int oomRepeat = 0; /* Number of OOMs in a row */
423static void*(*defaultMalloc)(int) = 0; /* The low-level malloc routine */
424#endif /* SQLITE_DEBUG */
425
drh2ce15c32017-07-11 13:34:40 +0000426/*
427** This is the name of our program. It is set in main(), used
428** in a number of other places, mostly for error messages.
429*/
430static char *Argv0;
431
432/*
433** Prompt strings. Initialized in main. Settable with
434** .prompt main continue
435*/
436static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
437static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
438
439/*
440** Render output like fprintf(). Except, if the output is going to the
441** console and if this is running on a Windows machine, translate the
442** output from UTF-8 into MBCS.
443*/
444#if defined(_WIN32) || defined(WIN32)
445void utf8_printf(FILE *out, const char *zFormat, ...){
446 va_list ap;
447 va_start(ap, zFormat);
448 if( stdout_is_console && (out==stdout || out==stderr) ){
449 char *z1 = sqlite3_vmprintf(zFormat, ap);
450 char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
451 sqlite3_free(z1);
452 fputs(z2, out);
453 sqlite3_free(z2);
454 }else{
455 vfprintf(out, zFormat, ap);
456 }
457 va_end(ap);
458}
459#elif !defined(utf8_printf)
460# define utf8_printf fprintf
461#endif
462
463/*
464** Render output like fprintf(). This should not be used on anything that
465** includes string formatting (e.g. "%s").
466*/
467#if !defined(raw_printf)
468# define raw_printf fprintf
469#endif
470
drh4b5345c2018-04-24 13:07:40 +0000471/* Indicate out-of-memory and exit. */
472static void shell_out_of_memory(void){
473 raw_printf(stderr,"Error: out of memory\n");
474 exit(1);
475}
476
drh4a3a3eb2020-02-29 15:53:48 +0000477#ifdef SQLITE_DEBUG
478/* This routine is called when a simulated OOM occurs. It is broken
479** out as a separate routine to make it easy to set a breakpoint on
480** the OOM
481*/
482void shellOomFault(void){
483 if( oomRepeat>0 ){
484 oomRepeat--;
485 }else{
486 oomCounter--;
487 }
488}
489#endif /* SQLITE_DEBUG */
490
491#ifdef SQLITE_DEBUG
492/* This routine is a replacement malloc() that is used to simulate
493** Out-Of-Memory (OOM) errors for testing purposes.
494*/
495static void *oomMalloc(int nByte){
496 if( oomCounter ){
497 if( oomCounter==1 ){
498 shellOomFault();
499 return 0;
500 }else{
501 oomCounter--;
502 }
503 }
504 return defaultMalloc(nByte);
505}
506#endif /* SQLITE_DEBUG */
507
508#ifdef SQLITE_DEBUG
509/* Register the OOM simulator. This must occur before any memory
510** allocations */
511static void registerOomSimulator(void){
512 sqlite3_mem_methods mem;
513 sqlite3_config(SQLITE_CONFIG_GETMALLOC, &mem);
514 defaultMalloc = mem.xMalloc;
515 mem.xMalloc = oomMalloc;
516 sqlite3_config(SQLITE_CONFIG_MALLOC, &mem);
517}
518#endif
519
drh2ce15c32017-07-11 13:34:40 +0000520/*
521** Write I/O traces to the following stream.
522*/
523#ifdef SQLITE_ENABLE_IOTRACE
524static FILE *iotrace = 0;
525#endif
526
527/*
528** This routine works like printf in that its first argument is a
529** format string and subsequent arguments are values to be substituted
530** in place of % fields. The result of formatting this string
531** is written to iotrace.
532*/
533#ifdef SQLITE_ENABLE_IOTRACE
534static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
535 va_list ap;
536 char *z;
537 if( iotrace==0 ) return;
538 va_start(ap, zFormat);
539 z = sqlite3_vmprintf(zFormat, ap);
540 va_end(ap);
541 utf8_printf(iotrace, "%s", z);
542 sqlite3_free(z);
543}
544#endif
545
546/*
547** Output string zUtf to stream pOut as w characters. If w is negative,
548** then right-justify the text. W is the width in UTF-8 characters, not
549** in bytes. This is different from the %*.*s specification in printf
550** since with %*.*s the width is measured in bytes, not characters.
551*/
552static void utf8_width_print(FILE *pOut, int w, const char *zUtf){
553 int i;
554 int n;
555 int aw = w<0 ? -w : w;
drh2ce15c32017-07-11 13:34:40 +0000556 for(i=n=0; zUtf[i]; i++){
557 if( (zUtf[i]&0xc0)!=0x80 ){
558 n++;
559 if( n==aw ){
560 do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
561 break;
562 }
563 }
564 }
565 if( n>=aw ){
566 utf8_printf(pOut, "%.*s", i, zUtf);
567 }else if( w<0 ){
568 utf8_printf(pOut, "%*s%s", aw-n, "", zUtf);
569 }else{
570 utf8_printf(pOut, "%s%*s", zUtf, aw-n, "");
571 }
572}
573
574
575/*
576** Determines if a string is a number of not.
577*/
578static int isNumber(const char *z, int *realnum){
579 if( *z=='-' || *z=='+' ) z++;
580 if( !IsDigit(*z) ){
581 return 0;
582 }
583 z++;
584 if( realnum ) *realnum = 0;
585 while( IsDigit(*z) ){ z++; }
586 if( *z=='.' ){
587 z++;
588 if( !IsDigit(*z) ) return 0;
589 while( IsDigit(*z) ){ z++; }
590 if( realnum ) *realnum = 1;
591 }
592 if( *z=='e' || *z=='E' ){
593 z++;
594 if( *z=='+' || *z=='-' ) z++;
595 if( !IsDigit(*z) ) return 0;
596 while( IsDigit(*z) ){ z++; }
597 if( realnum ) *realnum = 1;
598 }
599 return *z==0;
600}
601
602/*
603** Compute a string length that is limited to what can be stored in
604** lower 30 bits of a 32-bit signed integer.
605*/
606static int strlen30(const char *z){
607 const char *z2 = z;
608 while( *z2 ){ z2++; }
609 return 0x3fffffff & (int)(z2 - z);
610}
611
612/*
613** Return the length of a string in characters. Multibyte UTF8 characters
614** count as a single character.
615*/
616static int strlenChar(const char *z){
617 int n = 0;
618 while( *z ){
619 if( (0xc0&*(z++))!=0x80 ) n++;
620 }
621 return n;
622}
623
624/*
drhbbd620e2020-07-20 23:33:11 +0000625** Return true if zFile does not exist or if it is not an ordinary file.
626*/
627#ifdef _WIN32
628# define notNormalFile(X) 0
629#else
630static int notNormalFile(const char *zFile){
631 struct stat x;
632 int rc;
633 memset(&x, 0, sizeof(x));
634 rc = stat(zFile, &x);
635 return rc || !S_ISREG(x.st_mode);
636}
637#endif
638
639/*
drh2ce15c32017-07-11 13:34:40 +0000640** This routine reads a line of text from FILE in, stores
641** the text in memory obtained from malloc() and returns a pointer
642** to the text. NULL is returned at end of file, or if malloc()
643** fails.
644**
645** If zLine is not NULL then it is a malloced buffer returned from
646** a previous call to this routine that may be reused.
647*/
648static char *local_getline(char *zLine, FILE *in){
649 int nLine = zLine==0 ? 0 : 100;
650 int n = 0;
651
652 while( 1 ){
653 if( n+100>nLine ){
654 nLine = nLine*2 + 100;
655 zLine = realloc(zLine, nLine);
drh884406b2018-07-29 18:56:35 +0000656 if( zLine==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +0000657 }
658 if( fgets(&zLine[n], nLine - n, in)==0 ){
659 if( n==0 ){
660 free(zLine);
661 return 0;
662 }
663 zLine[n] = 0;
664 break;
665 }
666 while( zLine[n] ) n++;
667 if( n>0 && zLine[n-1]=='\n' ){
668 n--;
669 if( n>0 && zLine[n-1]=='\r' ) n--;
670 zLine[n] = 0;
671 break;
672 }
673 }
674#if defined(_WIN32) || defined(WIN32)
675 /* For interactive input on Windows systems, translate the
676 ** multi-byte characterset characters into UTF-8. */
677 if( stdin_is_interactive && in==stdin ){
678 char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
679 if( zTrans ){
680 int nTrans = strlen30(zTrans)+1;
681 if( nTrans>nLine ){
682 zLine = realloc(zLine, nTrans);
drh884406b2018-07-29 18:56:35 +0000683 if( zLine==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +0000684 }
685 memcpy(zLine, zTrans, nTrans);
686 sqlite3_free(zTrans);
687 }
688 }
689#endif /* defined(_WIN32) || defined(WIN32) */
690 return zLine;
691}
692
693/*
694** Retrieve a single line of input text.
695**
696** If in==0 then read from standard input and prompt before each line.
697** If isContinuation is true, then a continuation prompt is appropriate.
698** If isContinuation is zero, then the main prompt should be used.
699**
700** If zPrior is not NULL then it is a buffer from a prior call to this
701** routine that can be reused.
702**
703** The result is stored in space obtained from malloc() and must either
704** be freed by the caller or else passed back into this routine via the
705** zPrior argument for reuse.
706*/
707static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
708 char *zPrompt;
709 char *zResult;
710 if( in!=0 ){
711 zResult = local_getline(zPrior, in);
712 }else{
713 zPrompt = isContinuation ? continuePrompt : mainPrompt;
714#if SHELL_USE_LOCAL_GETLINE
715 printf("%s", zPrompt);
716 fflush(stdout);
717 zResult = local_getline(zPrior, stdin);
718#else
719 free(zPrior);
720 zResult = shell_readline(zPrompt);
721 if( zResult && *zResult ) shell_add_history(zResult);
722#endif
723 }
724 return zResult;
725}
drh5af06982018-01-10 00:53:55 +0000726
727
728/*
729** Return the value of a hexadecimal digit. Return -1 if the input
730** is not a hex digit.
731*/
732static int hexDigitValue(char c){
733 if( c>='0' && c<='9' ) return c - '0';
734 if( c>='a' && c<='f' ) return c - 'a' + 10;
735 if( c>='A' && c<='F' ) return c - 'A' + 10;
736 return -1;
737}
738
739/*
740** Interpret zArg as an integer value, possibly with suffixes.
741*/
742static sqlite3_int64 integerValue(const char *zArg){
743 sqlite3_int64 v = 0;
744 static const struct { char *zSuffix; int iMult; } aMult[] = {
745 { "KiB", 1024 },
746 { "MiB", 1024*1024 },
747 { "GiB", 1024*1024*1024 },
748 { "KB", 1000 },
749 { "MB", 1000000 },
750 { "GB", 1000000000 },
751 { "K", 1000 },
752 { "M", 1000000 },
753 { "G", 1000000000 },
754 };
755 int i;
756 int isNeg = 0;
757 if( zArg[0]=='-' ){
758 isNeg = 1;
759 zArg++;
760 }else if( zArg[0]=='+' ){
761 zArg++;
762 }
763 if( zArg[0]=='0' && zArg[1]=='x' ){
764 int x;
765 zArg += 2;
766 while( (x = hexDigitValue(zArg[0]))>=0 ){
767 v = (v<<4) + x;
768 zArg++;
769 }
770 }else{
771 while( IsDigit(zArg[0]) ){
772 v = v*10 + zArg[0] - '0';
773 zArg++;
774 }
775 }
776 for(i=0; i<ArraySize(aMult); i++){
777 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
778 v *= aMult[i].iMult;
779 break;
780 }
781 }
782 return isNeg? -v : v;
783}
784
drh2ce15c32017-07-11 13:34:40 +0000785/*
786** A variable length string to which one can append text.
787*/
788typedef struct ShellText ShellText;
789struct ShellText {
790 char *z;
791 int n;
792 int nAlloc;
793};
794
795/*
796** Initialize and destroy a ShellText object
797*/
798static void initText(ShellText *p){
799 memset(p, 0, sizeof(*p));
800}
801static void freeText(ShellText *p){
802 free(p->z);
803 initText(p);
804}
805
806/* zIn is either a pointer to a NULL-terminated string in memory obtained
807** from malloc(), or a NULL pointer. The string pointed to by zAppend is
808** added to zIn, and the result returned in memory obtained from malloc().
809** zIn, if it was not NULL, is freed.
810**
811** If the third argument, quote, is not '\0', then it is used as a
812** quote character for zAppend.
813*/
814static void appendText(ShellText *p, char const *zAppend, char quote){
815 int len;
816 int i;
817 int nAppend = strlen30(zAppend);
818
819 len = nAppend+p->n+1;
820 if( quote ){
821 len += 2;
822 for(i=0; i<nAppend; i++){
823 if( zAppend[i]==quote ) len++;
824 }
825 }
826
827 if( p->n+len>=p->nAlloc ){
828 p->nAlloc = p->nAlloc*2 + len + 20;
829 p->z = realloc(p->z, p->nAlloc);
drh884406b2018-07-29 18:56:35 +0000830 if( p->z==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +0000831 }
832
833 if( quote ){
834 char *zCsr = p->z+p->n;
835 *zCsr++ = quote;
836 for(i=0; i<nAppend; i++){
837 *zCsr++ = zAppend[i];
838 if( zAppend[i]==quote ) *zCsr++ = quote;
839 }
840 *zCsr++ = quote;
841 p->n = (int)(zCsr - p->z);
842 *zCsr = '\0';
843 }else{
844 memcpy(p->z+p->n, zAppend, nAppend);
845 p->n += nAppend;
846 p->z[p->n] = '\0';
847 }
848}
849
850/*
851** Attempt to determine if identifier zName needs to be quoted, either
852** because it contains non-alphanumeric characters, or because it is an
853** SQLite keyword. Be conservative in this estimate: When in doubt assume
854** that quoting is required.
855**
856** Return '"' if quoting is required. Return 0 if no quoting is required.
857*/
858static char quoteChar(const char *zName){
drhfc0ec3e2018-04-25 19:02:48 +0000859 int i;
drh2ce15c32017-07-11 13:34:40 +0000860 if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
861 for(i=0; zName[i]; i++){
862 if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
863 }
drhfc0ec3e2018-04-25 19:02:48 +0000864 return sqlite3_keyword_check(zName, i) ? '"' : 0;
drh2ce15c32017-07-11 13:34:40 +0000865}
866
867/*
drh667a2a22018-01-02 00:04:37 +0000868** Construct a fake object name and column list to describe the structure
869** of the view, virtual table, or table valued function zSchema.zName.
drhceba7922018-01-01 21:28:25 +0000870*/
drh667a2a22018-01-02 00:04:37 +0000871static char *shellFakeSchema(
drhceba7922018-01-01 21:28:25 +0000872 sqlite3 *db, /* The database connection containing the vtab */
873 const char *zSchema, /* Schema of the database holding the vtab */
874 const char *zName /* The name of the virtual table */
875){
876 sqlite3_stmt *pStmt = 0;
877 char *zSql;
drh1d315cf2018-01-01 21:49:43 +0000878 ShellText s;
879 char cQuote;
880 char *zDiv = "(";
drh667a2a22018-01-02 00:04:37 +0000881 int nRow = 0;
drhceba7922018-01-01 21:28:25 +0000882
drh1d315cf2018-01-01 21:49:43 +0000883 zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;",
884 zSchema ? zSchema : "main", zName);
drhceba7922018-01-01 21:28:25 +0000885 sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
886 sqlite3_free(zSql);
drh1d315cf2018-01-01 21:49:43 +0000887 initText(&s);
888 if( zSchema ){
889 cQuote = quoteChar(zSchema);
890 if( cQuote && sqlite3_stricmp(zSchema,"temp")==0 ) cQuote = 0;
891 appendText(&s, zSchema, cQuote);
892 appendText(&s, ".", 0);
drhceba7922018-01-01 21:28:25 +0000893 }
drh1d315cf2018-01-01 21:49:43 +0000894 cQuote = quoteChar(zName);
895 appendText(&s, zName, cQuote);
896 while( sqlite3_step(pStmt)==SQLITE_ROW ){
897 const char *zCol = (const char*)sqlite3_column_text(pStmt, 1);
drh667a2a22018-01-02 00:04:37 +0000898 nRow++;
drh1d315cf2018-01-01 21:49:43 +0000899 appendText(&s, zDiv, 0);
900 zDiv = ",";
901 cQuote = quoteChar(zCol);
902 appendText(&s, zCol, cQuote);
903 }
904 appendText(&s, ")", 0);
drhceba7922018-01-01 21:28:25 +0000905 sqlite3_finalize(pStmt);
drh667a2a22018-01-02 00:04:37 +0000906 if( nRow==0 ){
907 freeText(&s);
908 s.z = 0;
909 }
drh1d315cf2018-01-01 21:49:43 +0000910 return s.z;
drhceba7922018-01-01 21:28:25 +0000911}
912
913/*
drh667a2a22018-01-02 00:04:37 +0000914** SQL function: shell_module_schema(X)
915**
916** Return a fake schema for the table-valued function or eponymous virtual
917** table X.
918*/
919static void shellModuleSchema(
920 sqlite3_context *pCtx,
921 int nVal,
922 sqlite3_value **apVal
923){
924 const char *zName = (const char*)sqlite3_value_text(apVal[0]);
925 char *zFake = shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName);
drhb9685182018-01-17 13:15:23 +0000926 UNUSED_PARAMETER(nVal);
drh667a2a22018-01-02 00:04:37 +0000927 if( zFake ){
dandcfbff92018-01-08 17:05:32 +0000928 sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
drh667a2a22018-01-02 00:04:37 +0000929 -1, sqlite3_free);
dandcfbff92018-01-08 17:05:32 +0000930 free(zFake);
drh667a2a22018-01-02 00:04:37 +0000931 }
932}
933
934/*
drh2ce15c32017-07-11 13:34:40 +0000935** SQL function: shell_add_schema(S,X)
936**
937** Add the schema name X to the CREATE statement in S and return the result.
938** Examples:
939**
940** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x);
941**
942** Also works on
943**
944** CREATE INDEX
945** CREATE UNIQUE INDEX
946** CREATE VIEW
947** CREATE TRIGGER
948** CREATE VIRTUAL TABLE
949**
950** This UDF is used by the .schema command to insert the schema name of
drh067b92b2020-06-19 15:24:12 +0000951** attached databases into the middle of the sqlite_schema.sql field.
drh2ce15c32017-07-11 13:34:40 +0000952*/
953static void shellAddSchemaName(
954 sqlite3_context *pCtx,
955 int nVal,
956 sqlite3_value **apVal
957){
958 static const char *aPrefix[] = {
959 "TABLE",
960 "INDEX",
961 "UNIQUE INDEX",
962 "VIEW",
963 "TRIGGER",
964 "VIRTUAL TABLE"
965 };
966 int i = 0;
967 const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
968 const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
drh667a2a22018-01-02 00:04:37 +0000969 const char *zName = (const char*)sqlite3_value_text(apVal[2]);
drhceba7922018-01-01 21:28:25 +0000970 sqlite3 *db = sqlite3_context_db_handle(pCtx);
drhb9685182018-01-17 13:15:23 +0000971 UNUSED_PARAMETER(nVal);
drh2ce15c32017-07-11 13:34:40 +0000972 if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
drh89997982017-07-11 18:11:33 +0000973 for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){
drh2ce15c32017-07-11 13:34:40 +0000974 int n = strlen30(aPrefix[i]);
975 if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
drhceba7922018-01-01 21:28:25 +0000976 char *z = 0;
drh667a2a22018-01-02 00:04:37 +0000977 char *zFake = 0;
drhceba7922018-01-01 21:28:25 +0000978 if( zSchema ){
979 char cQuote = quoteChar(zSchema);
980 if( cQuote && sqlite3_stricmp(zSchema,"temp")!=0 ){
981 z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8);
982 }else{
983 z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8);
984 }
drh2ce15c32017-07-11 13:34:40 +0000985 }
drh667a2a22018-01-02 00:04:37 +0000986 if( zName
987 && aPrefix[i][0]=='V'
988 && (zFake = shellFakeSchema(db, zSchema, zName))!=0
989 ){
990 if( z==0 ){
dandcfbff92018-01-08 17:05:32 +0000991 z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
drh667a2a22018-01-02 00:04:37 +0000992 }else{
dandcfbff92018-01-08 17:05:32 +0000993 z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
drh667a2a22018-01-02 00:04:37 +0000994 }
dandcfbff92018-01-08 17:05:32 +0000995 free(zFake);
drhceba7922018-01-01 21:28:25 +0000996 }
997 if( z ){
998 sqlite3_result_text(pCtx, z, -1, sqlite3_free);
999 return;
1000 }
drh2ce15c32017-07-11 13:34:40 +00001001 }
1002 }
1003 }
1004 sqlite3_result_value(pCtx, apVal[0]);
1005}
1006
1007/*
1008** The source code for several run-time loadable extensions is inserted
1009** below by the ../tool/mkshellc.tcl script. Before processing that included
1010** code, we need to override some macros to make the included program code
1011** work here in the middle of this regular program.
1012*/
1013#define SQLITE_EXTENSION_INIT1
drh89997982017-07-11 18:11:33 +00001014#define SQLITE_EXTENSION_INIT2(X) (void)(X)
drh2ce15c32017-07-11 13:34:40 +00001015
mistachkinacae8c32018-01-05 20:08:46 +00001016#if defined(_WIN32) && defined(_MSC_VER)
drh03491a12018-01-07 21:58:17 +00001017INCLUDE test_windirent.h
mistachkindfdfd8c2018-01-04 22:46:08 +00001018INCLUDE test_windirent.c
1019#define dirent DIRENT
mistachkindfdfd8c2018-01-04 22:46:08 +00001020#endif
drh2ce15c32017-07-11 13:34:40 +00001021INCLUDE ../ext/misc/shathree.c
1022INCLUDE ../ext/misc/fileio.c
drh56eb09b2017-07-11 13:59:07 +00001023INCLUDE ../ext/misc/completion.c
drh8682e122018-01-07 20:38:10 +00001024INCLUDE ../ext/misc/appendvfs.c
drh50b910a2019-01-21 14:55:03 +00001025INCLUDE ../ext/misc/memtrace.c
drhf05dd032020-04-14 15:53:58 +00001026INCLUDE ../ext/misc/uint.c
drhbeb9def2020-06-22 19:12:23 +00001027INCLUDE ../ext/misc/decimal.c
drh8cda77d2020-06-24 15:06:29 +00001028INCLUDE ../ext/misc/ieee754.c
mistachkin72c38d82020-08-28 18:47:39 +00001029INCLUDE ../ext/misc/series.c
dan72afc3c2017-12-05 18:32:40 +00001030#ifdef SQLITE_HAVE_ZLIB
dan9ebfaad2017-12-26 20:39:58 +00001031INCLUDE ../ext/misc/zipfile.c
dand1b51d42017-12-16 19:11:26 +00001032INCLUDE ../ext/misc/sqlar.c
dan72afc3c2017-12-05 18:32:40 +00001033#endif
dan43efc182017-12-19 17:42:13 +00001034INCLUDE ../ext/expert/sqlite3expert.h
1035INCLUDE ../ext/expert/sqlite3expert.c
drh2ce15c32017-07-11 13:34:40 +00001036
dan1b162162019-04-27 20:15:15 +00001037#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
dan68cb86e2019-04-20 20:57:28 +00001038INCLUDE ../ext/misc/dbdata.c
dan1b162162019-04-27 20:15:15 +00001039#endif
dan68cb86e2019-04-20 20:57:28 +00001040
drh2ce15c32017-07-11 13:34:40 +00001041#if defined(SQLITE_ENABLE_SESSION)
1042/*
1043** State information for a single open session
1044*/
1045typedef struct OpenSession OpenSession;
1046struct OpenSession {
1047 char *zName; /* Symbolic name for this session */
1048 int nFilter; /* Number of xFilter rejection GLOB patterns */
1049 char **azFilter; /* Array of xFilter rejection GLOB patterns */
1050 sqlite3_session *p; /* The open session */
1051};
1052#endif
1053
dan43efc182017-12-19 17:42:13 +00001054typedef struct ExpertInfo ExpertInfo;
1055struct ExpertInfo {
1056 sqlite3expert *pExpert;
1057 int bVerbose;
1058};
1059
drh4b5345c2018-04-24 13:07:40 +00001060/* A single line in the EQP output */
1061typedef struct EQPGraphRow EQPGraphRow;
1062struct EQPGraphRow {
drhe2ca99c2018-05-02 00:33:43 +00001063 int iEqpId; /* ID for this row */
1064 int iParentId; /* ID of the parent row */
drh4b5345c2018-04-24 13:07:40 +00001065 EQPGraphRow *pNext; /* Next row in sequence */
1066 char zText[1]; /* Text to display for this row */
1067};
1068
1069/* All EQP output is collected into an instance of the following */
1070typedef struct EQPGraph EQPGraph;
1071struct EQPGraph {
1072 EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */
1073 EQPGraphRow *pLast; /* Last element of the pRow list */
1074 char zPrefix[100]; /* Graph prefix */
1075};
1076
drh2ce15c32017-07-11 13:34:40 +00001077/*
1078** State information about the database connection is contained in an
1079** instance of the following structure.
1080*/
1081typedef struct ShellState ShellState;
1082struct ShellState {
1083 sqlite3 *db; /* The database */
drh1fa6d9f2018-01-06 21:46:01 +00001084 u8 autoExplain; /* Automatically turn on .explain mode */
1085 u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
drhe2ca99c2018-05-02 00:33:43 +00001086 u8 autoEQPtest; /* autoEQP is in test mode */
drhb4e50392019-01-26 15:40:04 +00001087 u8 autoEQPtrace; /* autoEQP is in trace mode */
drh1fa6d9f2018-01-06 21:46:01 +00001088 u8 statsOn; /* True to display memory stats before each finalize */
1089 u8 scanstatsOn; /* True to display scan stats before each finalize */
1090 u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
drh13c20932018-01-10 21:41:55 +00001091 u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */
drh4b5345c2018-04-24 13:07:40 +00001092 u8 nEqpLevel; /* Depth of the EQP output graph */
drh707821f2018-12-05 13:39:06 +00001093 u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
drh4b5345c2018-04-24 13:07:40 +00001094 unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */
drh2ce15c32017-07-11 13:34:40 +00001095 int outCount; /* Revert to stdout when reaching zero */
1096 int cnt; /* Number of records displayed so far */
drh2c8ee022018-12-13 18:59:30 +00001097 int lineno; /* Line number of last line read from in */
drh0933aad2019-11-18 17:46:38 +00001098 int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */
drh60379d42018-12-13 18:30:01 +00001099 FILE *in; /* Read commands from this stream */
drh2ce15c32017-07-11 13:34:40 +00001100 FILE *out; /* Write results here */
1101 FILE *traceOut; /* Output for sqlite3_trace() */
1102 int nErr; /* Number of errors seen */
1103 int mode; /* An output mode setting */
drh3c484e82018-01-10 22:27:21 +00001104 int modePrior; /* Saved mode */
drh2ce15c32017-07-11 13:34:40 +00001105 int cMode; /* temporary output mode for the current query */
1106 int normalMode; /* Output mode before ".explain on" */
1107 int writableSchema; /* True if PRAGMA writable_schema=ON */
1108 int showHeader; /* True to show column names in List or Column mode */
1109 int nCheck; /* Number of ".check" commands run */
drh3f83f592019-02-04 14:53:18 +00001110 unsigned nProgress; /* Number of progress callbacks encountered */
1111 unsigned mxProgress; /* Maximum progress callbacks before failing */
1112 unsigned flgProgress; /* Flags for the progress callback */
drh2ce15c32017-07-11 13:34:40 +00001113 unsigned shellFlgs; /* Various flags */
drh7a431002020-04-18 14:12:00 +00001114 unsigned priorShFlgs; /* Saved copy of flags */
drh6ca64482019-01-22 16:06:20 +00001115 sqlite3_int64 szMax; /* --maxsize argument to .open */
drh2ce15c32017-07-11 13:34:40 +00001116 char *zDestTable; /* Name of destination table when MODE_Insert */
drh13c20932018-01-10 21:41:55 +00001117 char *zTempFile; /* Temporary file that might need deleting */
drh2ce15c32017-07-11 13:34:40 +00001118 char zTestcase[30]; /* Name of current test case */
1119 char colSeparator[20]; /* Column separator character for several modes */
1120 char rowSeparator[20]; /* Row separator character for MODE_Ascii */
drh3c484e82018-01-10 22:27:21 +00001121 char colSepPrior[20]; /* Saved column separator */
1122 char rowSepPrior[20]; /* Saved row separator */
drh0285d982020-05-29 14:38:43 +00001123 int *colWidth; /* Requested width of each column in columnar modes */
1124 int *actualWidth; /* Actual width of each column */
1125 int nWidth; /* Number of slots in colWidth[] and actualWidth[] */
drh2ce15c32017-07-11 13:34:40 +00001126 char nullValue[20]; /* The text to print when a NULL comes back from
1127 ** the database */
1128 char outfile[FILENAME_MAX]; /* Filename for *out */
1129 const char *zDbFilename; /* name of the database file */
1130 char *zFreeOnClose; /* Filename to free when closing */
1131 const char *zVfs; /* Name of VFS to use */
1132 sqlite3_stmt *pStmt; /* Current statement if any. */
1133 FILE *pLog; /* Write log output here */
1134 int *aiIndent; /* Array of indents used in MODE_Explain */
1135 int nIndent; /* Size of array aiIndent[] */
1136 int iIndent; /* Index of current op in aiIndent[] */
drh4b5345c2018-04-24 13:07:40 +00001137 EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */
drh2ce15c32017-07-11 13:34:40 +00001138#if defined(SQLITE_ENABLE_SESSION)
1139 int nSession; /* Number of active sessions */
1140 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */
1141#endif
dan43efc182017-12-19 17:42:13 +00001142 ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */
drh2ce15c32017-07-11 13:34:40 +00001143};
1144
drh1fa6d9f2018-01-06 21:46:01 +00001145
drhada70452017-12-21 21:02:27 +00001146/* Allowed values for ShellState.autoEQP
1147*/
drhe2ca99c2018-05-02 00:33:43 +00001148#define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */
1149#define AUTOEQP_on 1 /* Automatic EQP is on */
1150#define AUTOEQP_trigger 2 /* On and also show plans for triggers */
1151#define AUTOEQP_full 3 /* Show full EXPLAIN */
drhada70452017-12-21 21:02:27 +00001152
drh1fa6d9f2018-01-06 21:46:01 +00001153/* Allowed values for ShellState.openMode
1154*/
drh60f34ae2018-10-30 13:19:49 +00001155#define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */
1156#define SHELL_OPEN_NORMAL 1 /* Normal database file */
1157#define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */
1158#define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */
1159#define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */
1160#define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */
drh33746482018-12-13 15:06:26 +00001161#define SHELL_OPEN_HEXDB 6 /* Use "dbtotxt" output as data source */
drh1fa6d9f2018-01-06 21:46:01 +00001162
drh707821f2018-12-05 13:39:06 +00001163/* Allowed values for ShellState.eTraceType
1164*/
1165#define SHELL_TRACE_PLAIN 0 /* Show input SQL text */
1166#define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */
1167#define SHELL_TRACE_NORMALIZED 2 /* Show normalized SQL text */
1168
drh3f83f592019-02-04 14:53:18 +00001169/* Bits in the ShellState.flgProgress variable */
drhfc4eeef2019-02-05 19:48:46 +00001170#define SHELL_PROGRESS_QUIET 0x01 /* Omit announcing every progress callback */
1171#define SHELL_PROGRESS_RESET 0x02 /* Reset the count when the progres
1172 ** callback limit is reached, and for each
1173 ** top-level SQL statement */
1174#define SHELL_PROGRESS_ONCE 0x04 /* Cancel the --limit after firing once */
drh3f83f592019-02-04 14:53:18 +00001175
drh2ce15c32017-07-11 13:34:40 +00001176/*
1177** These are the allowed shellFlgs values
1178*/
drhb2a0f752017-08-28 15:51:35 +00001179#define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */
1180#define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */
1181#define SHFLG_Backslash 0x00000004 /* The --backslash option is used */
1182#define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */
1183#define SHFLG_Newlines 0x00000010 /* .dump --newline flag */
1184#define SHFLG_CountChanges 0x00000020 /* .changes setting */
1185#define SHFLG_Echo 0x00000040 /* .echo or --echo setting */
drhc0605082020-06-05 00:54:27 +00001186#define SHFLG_HeaderSet 0x00000080 /* .header has been used */
drhc1962192020-10-12 16:54:28 +00001187#define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */
1188#define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */
drh2ce15c32017-07-11 13:34:40 +00001189
1190/*
1191** Macros for testing and setting shellFlgs
1192*/
1193#define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0)
1194#define ShellSetFlag(P,X) ((P)->shellFlgs|=(X))
1195#define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X)))
1196
1197/*
1198** These are the allowed modes.
1199*/
1200#define MODE_Line 0 /* One column per line. Blank line between records */
1201#define MODE_Column 1 /* One record per line in neat columns */
1202#define MODE_List 2 /* One record per line with a separator */
1203#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
1204#define MODE_Html 4 /* Generate an XHTML table */
1205#define MODE_Insert 5 /* Generate SQL "insert" statements */
1206#define MODE_Quote 6 /* Quote values as for SQL */
1207#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
1208#define MODE_Csv 8 /* Quote strings, numbers are plain */
1209#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
1210#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
1211#define MODE_Pretty 11 /* Pretty-print schemas */
drh4b5345c2018-04-24 13:07:40 +00001212#define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
drh30c54a02020-05-28 23:49:50 +00001213#define MODE_Json 13 /* Output JSON */
1214#define MODE_Markdown 14 /* Markdown formatting */
1215#define MODE_Table 15 /* MySQL-style table formatting */
drh0908e382020-06-04 18:05:39 +00001216#define MODE_Box 16 /* Unicode box-drawing characters */
drh2ce15c32017-07-11 13:34:40 +00001217
1218static const char *modeDescr[] = {
1219 "line",
1220 "column",
1221 "list",
1222 "semi",
1223 "html",
1224 "insert",
1225 "quote",
1226 "tcl",
1227 "csv",
1228 "explain",
1229 "ascii",
1230 "prettyprint",
drh30c54a02020-05-28 23:49:50 +00001231 "eqp",
1232 "json",
1233 "markdown",
drh0908e382020-06-04 18:05:39 +00001234 "table",
1235 "box"
drh2ce15c32017-07-11 13:34:40 +00001236};
1237
1238/*
1239** These are the column/row/line separators used by the various
1240** import/export modes.
1241*/
1242#define SEP_Column "|"
1243#define SEP_Row "\n"
1244#define SEP_Tab "\t"
1245#define SEP_Space " "
1246#define SEP_Comma ","
1247#define SEP_CrLf "\r\n"
1248#define SEP_Unit "\x1F"
1249#define SEP_Record "\x1E"
1250
1251/*
drh2ce15c32017-07-11 13:34:40 +00001252** A callback for the sqlite3_log() interface.
1253*/
1254static void shellLog(void *pArg, int iErrCode, const char *zMsg){
1255 ShellState *p = (ShellState*)pArg;
1256 if( p->pLog==0 ) return;
1257 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
1258 fflush(p->pLog);
1259}
1260
1261/*
drh634c70f2018-01-10 16:50:18 +00001262** SQL function: shell_putsnl(X)
1263**
1264** Write the text X to the screen (or whatever output is being directed)
1265** adding a newline at the end, and then return X.
1266*/
1267static void shellPutsFunc(
1268 sqlite3_context *pCtx,
1269 int nVal,
1270 sqlite3_value **apVal
1271){
1272 ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
drhb9685182018-01-17 13:15:23 +00001273 (void)nVal;
drh634c70f2018-01-10 16:50:18 +00001274 utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
1275 sqlite3_result_value(pCtx, apVal[0]);
1276}
1277
1278/*
drh97913132018-01-11 00:04:00 +00001279** SQL function: edit(VALUE)
1280** edit(VALUE,EDITOR)
1281**
1282** These steps:
1283**
1284** (1) Write VALUE into a temporary file.
1285** (2) Run program EDITOR on that temporary file.
1286** (3) Read the temporary file back and return its content as the result.
1287** (4) Delete the temporary file
1288**
1289** If the EDITOR argument is omitted, use the value in the VISUAL
1290** environment variable. If still there is no EDITOR, through an error.
1291**
1292** Also throw an error if the EDITOR program returns a non-zero exit code.
1293*/
drh04a28c32018-01-31 01:38:44 +00001294#ifndef SQLITE_NOHAVE_SYSTEM
drh97913132018-01-11 00:04:00 +00001295static void editFunc(
1296 sqlite3_context *context,
1297 int argc,
1298 sqlite3_value **argv
1299){
1300 const char *zEditor;
1301 char *zTempFile = 0;
1302 sqlite3 *db;
1303 char *zCmd = 0;
1304 int bBin;
1305 int rc;
drhf018fd52018-08-06 02:08:53 +00001306 int hasCRNL = 0;
drh97913132018-01-11 00:04:00 +00001307 FILE *f = 0;
1308 sqlite3_int64 sz;
1309 sqlite3_int64 x;
1310 unsigned char *p = 0;
1311
1312 if( argc==2 ){
1313 zEditor = (const char*)sqlite3_value_text(argv[1]);
1314 }else{
1315 zEditor = getenv("VISUAL");
1316 }
1317 if( zEditor==0 ){
1318 sqlite3_result_error(context, "no editor for edit()", -1);
1319 return;
1320 }
1321 if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
1322 sqlite3_result_error(context, "NULL input to edit()", -1);
1323 return;
1324 }
1325 db = sqlite3_context_db_handle(context);
1326 zTempFile = 0;
1327 sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile);
1328 if( zTempFile==0 ){
1329 sqlite3_uint64 r = 0;
1330 sqlite3_randomness(sizeof(r), &r);
1331 zTempFile = sqlite3_mprintf("temp%llx", r);
1332 if( zTempFile==0 ){
1333 sqlite3_result_error_nomem(context);
1334 return;
1335 }
1336 }
1337 bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB;
drhf018fd52018-08-06 02:08:53 +00001338 /* When writing the file to be edited, do \n to \r\n conversions on systems
1339 ** that want \r\n line endings */
drh97913132018-01-11 00:04:00 +00001340 f = fopen(zTempFile, bBin ? "wb" : "w");
1341 if( f==0 ){
1342 sqlite3_result_error(context, "edit() cannot open temp file", -1);
1343 goto edit_func_end;
1344 }
1345 sz = sqlite3_value_bytes(argv[0]);
1346 if( bBin ){
dan4d02b5f2019-07-17 07:23:06 +00001347 x = fwrite(sqlite3_value_blob(argv[0]), 1, (size_t)sz, f);
drh97913132018-01-11 00:04:00 +00001348 }else{
drhf018fd52018-08-06 02:08:53 +00001349 const char *z = (const char*)sqlite3_value_text(argv[0]);
1350 /* Remember whether or not the value originally contained \r\n */
1351 if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
dan4d02b5f2019-07-17 07:23:06 +00001352 x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f);
drh97913132018-01-11 00:04:00 +00001353 }
1354 fclose(f);
1355 f = 0;
1356 if( x!=sz ){
1357 sqlite3_result_error(context, "edit() could not write the whole file", -1);
1358 goto edit_func_end;
1359 }
1360 zCmd = sqlite3_mprintf("%s \"%s\"", zEditor, zTempFile);
1361 if( zCmd==0 ){
1362 sqlite3_result_error_nomem(context);
1363 goto edit_func_end;
1364 }
1365 rc = system(zCmd);
1366 sqlite3_free(zCmd);
1367 if( rc ){
1368 sqlite3_result_error(context, "EDITOR returned non-zero", -1);
1369 goto edit_func_end;
1370 }
drhf018fd52018-08-06 02:08:53 +00001371 f = fopen(zTempFile, "rb");
drh97913132018-01-11 00:04:00 +00001372 if( f==0 ){
1373 sqlite3_result_error(context,
1374 "edit() cannot reopen temp file after edit", -1);
1375 goto edit_func_end;
1376 }
1377 fseek(f, 0, SEEK_END);
1378 sz = ftell(f);
1379 rewind(f);
drhee37f8b2019-08-23 23:05:32 +00001380 p = sqlite3_malloc64( sz+1 );
drh97913132018-01-11 00:04:00 +00001381 if( p==0 ){
1382 sqlite3_result_error_nomem(context);
1383 goto edit_func_end;
1384 }
dan4d02b5f2019-07-17 07:23:06 +00001385 x = fread(p, 1, (size_t)sz, f);
drh97913132018-01-11 00:04:00 +00001386 fclose(f);
1387 f = 0;
1388 if( x!=sz ){
1389 sqlite3_result_error(context, "could not read back the whole file", -1);
1390 goto edit_func_end;
1391 }
1392 if( bBin ){
mistachkinb71aa092018-01-23 00:05:18 +00001393 sqlite3_result_blob64(context, p, sz, sqlite3_free);
drh97913132018-01-11 00:04:00 +00001394 }else{
dan60bdcf52018-10-03 11:13:30 +00001395 sqlite3_int64 i, j;
drhf018fd52018-08-06 02:08:53 +00001396 if( hasCRNL ){
1397 /* If the original contains \r\n then do no conversions back to \n */
1398 j = sz;
1399 }else{
1400 /* If the file did not originally contain \r\n then convert any new
1401 ** \r\n back into \n */
1402 for(i=j=0; i<sz; i++){
1403 if( p[i]=='\r' && p[i+1]=='\n' ) i++;
1404 p[j++] = p[i];
1405 }
1406 sz = j;
1407 p[sz] = 0;
1408 }
mistachkinb71aa092018-01-23 00:05:18 +00001409 sqlite3_result_text64(context, (const char*)p, sz,
1410 sqlite3_free, SQLITE_UTF8);
drh97913132018-01-11 00:04:00 +00001411 }
1412 p = 0;
1413
1414edit_func_end:
1415 if( f ) fclose(f);
1416 unlink(zTempFile);
1417 sqlite3_free(zTempFile);
1418 sqlite3_free(p);
1419}
drh04a28c32018-01-31 01:38:44 +00001420#endif /* SQLITE_NOHAVE_SYSTEM */
drh97913132018-01-11 00:04:00 +00001421
1422/*
drh3c484e82018-01-10 22:27:21 +00001423** Save or restore the current output mode
1424*/
1425static void outputModePush(ShellState *p){
1426 p->modePrior = p->mode;
drh7a431002020-04-18 14:12:00 +00001427 p->priorShFlgs = p->shellFlgs;
drh3c484e82018-01-10 22:27:21 +00001428 memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
1429 memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
1430}
1431static void outputModePop(ShellState *p){
1432 p->mode = p->modePrior;
drh7a431002020-04-18 14:12:00 +00001433 p->shellFlgs = p->priorShFlgs;
drh3c484e82018-01-10 22:27:21 +00001434 memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
1435 memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
1436}
1437
1438/*
drh2ce15c32017-07-11 13:34:40 +00001439** Output the given string as a hex-encoded blob (eg. X'1234' )
1440*/
1441static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
1442 int i;
1443 char *zBlob = (char *)pBlob;
1444 raw_printf(out,"X'");
1445 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
1446 raw_printf(out,"'");
1447}
1448
1449/*
1450** Find a string that is not found anywhere in z[]. Return a pointer
1451** to that string.
1452**
1453** Try to use zA and zB first. If both of those are already found in z[]
1454** then make up some string and store it in the buffer zBuf.
1455*/
1456static const char *unused_string(
1457 const char *z, /* Result must not appear anywhere in z */
1458 const char *zA, const char *zB, /* Try these first */
1459 char *zBuf /* Space to store a generated string */
1460){
1461 unsigned i = 0;
1462 if( strstr(z, zA)==0 ) return zA;
1463 if( strstr(z, zB)==0 ) return zB;
1464 do{
1465 sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
1466 }while( strstr(z,zBuf)!=0 );
1467 return zBuf;
1468}
1469
1470/*
1471** Output the given string as a quoted string using SQL quoting conventions.
1472**
1473** See also: output_quoted_escaped_string()
1474*/
1475static void output_quoted_string(FILE *out, const char *z){
1476 int i;
1477 char c;
1478 setBinaryMode(out, 1);
1479 for(i=0; (c = z[i])!=0 && c!='\''; i++){}
1480 if( c==0 ){
1481 utf8_printf(out,"'%s'",z);
1482 }else{
1483 raw_printf(out, "'");
1484 while( *z ){
1485 for(i=0; (c = z[i])!=0 && c!='\''; i++){}
1486 if( c=='\'' ) i++;
1487 if( i ){
1488 utf8_printf(out, "%.*s", i, z);
1489 z += i;
1490 }
1491 if( c=='\'' ){
1492 raw_printf(out, "'");
1493 continue;
1494 }
1495 if( c==0 ){
1496 break;
1497 }
1498 z++;
1499 }
1500 raw_printf(out, "'");
1501 }
1502 setTextMode(out, 1);
1503}
1504
1505/*
1506** Output the given string as a quoted string using SQL quoting conventions.
1507** Additionallly , escape the "\n" and "\r" characters so that they do not
1508** get corrupted by end-of-line translation facilities in some operating
1509** systems.
1510**
1511** This is like output_quoted_string() but with the addition of the \r\n
1512** escape mechanism.
1513*/
1514static void output_quoted_escaped_string(FILE *out, const char *z){
1515 int i;
1516 char c;
1517 setBinaryMode(out, 1);
1518 for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
1519 if( c==0 ){
1520 utf8_printf(out,"'%s'",z);
1521 }else{
1522 const char *zNL = 0;
1523 const char *zCR = 0;
1524 int nNL = 0;
1525 int nCR = 0;
1526 char zBuf1[20], zBuf2[20];
1527 for(i=0; z[i]; i++){
1528 if( z[i]=='\n' ) nNL++;
1529 if( z[i]=='\r' ) nCR++;
1530 }
1531 if( nNL ){
1532 raw_printf(out, "replace(");
1533 zNL = unused_string(z, "\\n", "\\012", zBuf1);
1534 }
1535 if( nCR ){
1536 raw_printf(out, "replace(");
1537 zCR = unused_string(z, "\\r", "\\015", zBuf2);
1538 }
1539 raw_printf(out, "'");
1540 while( *z ){
1541 for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
1542 if( c=='\'' ) i++;
1543 if( i ){
1544 utf8_printf(out, "%.*s", i, z);
1545 z += i;
1546 }
1547 if( c=='\'' ){
1548 raw_printf(out, "'");
1549 continue;
1550 }
1551 if( c==0 ){
1552 break;
1553 }
1554 z++;
1555 if( c=='\n' ){
1556 raw_printf(out, "%s", zNL);
1557 continue;
1558 }
1559 raw_printf(out, "%s", zCR);
1560 }
1561 raw_printf(out, "'");
1562 if( nCR ){
1563 raw_printf(out, ",'%s',char(13))", zCR);
1564 }
1565 if( nNL ){
1566 raw_printf(out, ",'%s',char(10))", zNL);
1567 }
1568 }
1569 setTextMode(out, 1);
1570}
1571
1572/*
1573** Output the given string as a quoted according to C or TCL quoting rules.
1574*/
1575static void output_c_string(FILE *out, const char *z){
1576 unsigned int c;
1577 fputc('"', out);
1578 while( (c = *(z++))!=0 ){
1579 if( c=='\\' ){
1580 fputc(c, out);
1581 fputc(c, out);
1582 }else if( c=='"' ){
1583 fputc('\\', out);
1584 fputc('"', out);
1585 }else if( c=='\t' ){
1586 fputc('\\', out);
1587 fputc('t', out);
1588 }else if( c=='\n' ){
1589 fputc('\\', out);
1590 fputc('n', out);
1591 }else if( c=='\r' ){
1592 fputc('\\', out);
1593 fputc('r', out);
1594 }else if( !isprint(c&0xff) ){
1595 raw_printf(out, "\\%03o", c&0xff);
1596 }else{
1597 fputc(c, out);
1598 }
1599 }
1600 fputc('"', out);
1601}
1602
1603/*
drh69c093d2020-05-29 00:21:43 +00001604** Output the given string as a quoted according to JSON quoting rules.
1605*/
1606static void output_json_string(FILE *out, const char *z, int n){
1607 unsigned int c;
1608 if( n<0 ) n = (int)strlen(z);
1609 fputc('"', out);
1610 while( n-- ){
1611 c = *(z++);
1612 if( c=='\\' || c=='"' ){
1613 fputc('\\', out);
1614 fputc(c, out);
1615 }else if( c<=0x1f ){
1616 fputc('\\', out);
1617 if( c=='\b' ){
1618 fputc('b', out);
1619 }else if( c=='\f' ){
1620 fputc('f', out);
1621 }else if( c=='\n' ){
1622 fputc('n', out);
1623 }else if( c=='\r' ){
1624 fputc('r', out);
1625 }else if( c=='\t' ){
1626 fputc('t', out);
1627 }else{
1628 raw_printf(out, "u%04x",c);
1629 }
1630 }else{
1631 fputc(c, out);
1632 }
1633 }
1634 fputc('"', out);
1635}
1636
1637/*
drh2ce15c32017-07-11 13:34:40 +00001638** Output the given string with characters that are special to
1639** HTML escaped.
1640*/
1641static void output_html_string(FILE *out, const char *z){
1642 int i;
1643 if( z==0 ) z = "";
1644 while( *z ){
1645 for(i=0; z[i]
1646 && z[i]!='<'
1647 && z[i]!='&'
1648 && z[i]!='>'
1649 && z[i]!='\"'
1650 && z[i]!='\'';
1651 i++){}
1652 if( i>0 ){
1653 utf8_printf(out,"%.*s",i,z);
1654 }
1655 if( z[i]=='<' ){
1656 raw_printf(out,"&lt;");
1657 }else if( z[i]=='&' ){
1658 raw_printf(out,"&amp;");
1659 }else if( z[i]=='>' ){
1660 raw_printf(out,"&gt;");
1661 }else if( z[i]=='\"' ){
1662 raw_printf(out,"&quot;");
1663 }else if( z[i]=='\'' ){
1664 raw_printf(out,"&#39;");
1665 }else{
1666 break;
1667 }
1668 z += i + 1;
1669 }
1670}
1671
1672/*
1673** If a field contains any character identified by a 1 in the following
1674** array, then the string must be quoted for CSV.
1675*/
1676static const char needCsvQuote[] = {
1677 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1678 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1679 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1680 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1681 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1682 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1683 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1684 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1685 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1686 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1687 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1688 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1689 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1690 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1691 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1692 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1693};
1694
1695/*
1696** Output a single term of CSV. Actually, p->colSeparator is used for
1697** the separator, which may or may not be a comma. p->nullValue is
1698** the null value. Strings are quoted if necessary. The separator
1699** is only issued if bSep is true.
1700*/
1701static void output_csv(ShellState *p, const char *z, int bSep){
1702 FILE *out = p->out;
1703 if( z==0 ){
1704 utf8_printf(out,"%s",p->nullValue);
1705 }else{
1706 int i;
1707 int nSep = strlen30(p->colSeparator);
1708 for(i=0; z[i]; i++){
1709 if( needCsvQuote[((unsigned char*)z)[i]]
1710 || (z[i]==p->colSeparator[0] &&
1711 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
1712 i = 0;
1713 break;
1714 }
1715 }
1716 if( i==0 ){
drh9b7affc2017-11-26 02:14:18 +00001717 char *zQuoted = sqlite3_mprintf("\"%w\"", z);
1718 utf8_printf(out, "%s", zQuoted);
1719 sqlite3_free(zQuoted);
drh2ce15c32017-07-11 13:34:40 +00001720 }else{
1721 utf8_printf(out, "%s", z);
1722 }
1723 }
1724 if( bSep ){
1725 utf8_printf(p->out, "%s", p->colSeparator);
1726 }
1727}
1728
drh2ce15c32017-07-11 13:34:40 +00001729/*
1730** This routine runs when the user presses Ctrl-C
1731*/
1732static void interrupt_handler(int NotUsed){
1733 UNUSED_PARAMETER(NotUsed);
1734 seenInterrupt++;
1735 if( seenInterrupt>2 ) exit(1);
1736 if( globalDb ) sqlite3_interrupt(globalDb);
1737}
mistachkinb4bab902017-10-27 17:09:44 +00001738
1739#if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
1740/*
1741** This routine runs for console events (e.g. Ctrl-C) on Win32
1742*/
1743static BOOL WINAPI ConsoleCtrlHandler(
1744 DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */
1745){
1746 if( dwCtrlType==CTRL_C_EVENT ){
1747 interrupt_handler(0);
1748 return TRUE;
1749 }
1750 return FALSE;
1751}
drh2ce15c32017-07-11 13:34:40 +00001752#endif
1753
1754#ifndef SQLITE_OMIT_AUTHORIZATION
1755/*
1756** When the ".auth ON" is set, the following authorizer callback is
1757** invoked. It always returns SQLITE_OK.
1758*/
1759static int shellAuth(
1760 void *pClientData,
1761 int op,
1762 const char *zA1,
1763 const char *zA2,
1764 const char *zA3,
1765 const char *zA4
1766){
1767 ShellState *p = (ShellState*)pClientData;
1768 static const char *azAction[] = { 0,
1769 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
1770 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
1771 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
1772 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
1773 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
1774 "DROP_TRIGGER", "DROP_VIEW", "INSERT",
1775 "PRAGMA", "READ", "SELECT",
1776 "TRANSACTION", "UPDATE", "ATTACH",
1777 "DETACH", "ALTER_TABLE", "REINDEX",
1778 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
1779 "FUNCTION", "SAVEPOINT", "RECURSIVE"
1780 };
1781 int i;
1782 const char *az[4];
1783 az[0] = zA1;
1784 az[1] = zA2;
1785 az[2] = zA3;
1786 az[3] = zA4;
1787 utf8_printf(p->out, "authorizer: %s", azAction[op]);
1788 for(i=0; i<4; i++){
1789 raw_printf(p->out, " ");
1790 if( az[i] ){
1791 output_c_string(p->out, az[i]);
1792 }else{
1793 raw_printf(p->out, "NULL");
1794 }
1795 }
1796 raw_printf(p->out, "\n");
1797 return SQLITE_OK;
1798}
1799#endif
1800
1801/*
1802** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
1803**
1804** This routine converts some CREATE TABLE statements for shadow tables
1805** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
1806*/
1807static void printSchemaLine(FILE *out, const char *z, const char *zTail){
drh0a0536a2019-05-09 18:13:30 +00001808 if( z==0 ) return;
1809 if( zTail==0 ) return;
drh2ce15c32017-07-11 13:34:40 +00001810 if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
1811 utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
1812 }else{
1813 utf8_printf(out, "%s%s", z, zTail);
1814 }
1815}
1816static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
1817 char c = z[n];
1818 z[n] = 0;
1819 printSchemaLine(out, z, zTail);
1820 z[n] = c;
1821}
1822
1823/*
drh11be81d2018-01-06 15:46:20 +00001824** Return true if string z[] has nothing but whitespace and comments to the
1825** end of the first line.
1826*/
1827static int wsToEol(const char *z){
1828 int i;
1829 for(i=0; z[i]; i++){
1830 if( z[i]=='\n' ) return 1;
1831 if( IsSpace(z[i]) ) continue;
1832 if( z[i]=='-' && z[i+1]=='-' ) return 1;
1833 return 0;
1834 }
1835 return 1;
1836}
drh4b5345c2018-04-24 13:07:40 +00001837
1838/*
1839** Add a new entry to the EXPLAIN QUERY PLAN data
1840*/
drhe2ca99c2018-05-02 00:33:43 +00001841static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
drh4b5345c2018-04-24 13:07:40 +00001842 EQPGraphRow *pNew;
1843 int nText = strlen30(zText);
drhe2ca99c2018-05-02 00:33:43 +00001844 if( p->autoEQPtest ){
1845 utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText);
1846 }
drh4b5345c2018-04-24 13:07:40 +00001847 pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
1848 if( pNew==0 ) shell_out_of_memory();
drhe2ca99c2018-05-02 00:33:43 +00001849 pNew->iEqpId = iEqpId;
1850 pNew->iParentId = p2;
drh4b5345c2018-04-24 13:07:40 +00001851 memcpy(pNew->zText, zText, nText+1);
1852 pNew->pNext = 0;
1853 if( p->sGraph.pLast ){
1854 p->sGraph.pLast->pNext = pNew;
1855 }else{
1856 p->sGraph.pRow = pNew;
1857 }
1858 p->sGraph.pLast = pNew;
1859}
1860
1861/*
1862** Free and reset the EXPLAIN QUERY PLAN data that has been collected
1863** in p->sGraph.
1864*/
1865static void eqp_reset(ShellState *p){
1866 EQPGraphRow *pRow, *pNext;
1867 for(pRow = p->sGraph.pRow; pRow; pRow = pNext){
1868 pNext = pRow->pNext;
1869 sqlite3_free(pRow);
1870 }
1871 memset(&p->sGraph, 0, sizeof(p->sGraph));
1872}
1873
drhe2ca99c2018-05-02 00:33:43 +00001874/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
drh4b5345c2018-04-24 13:07:40 +00001875** pOld, or return the first such line if pOld is NULL
1876*/
drhe2ca99c2018-05-02 00:33:43 +00001877static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){
drh4b5345c2018-04-24 13:07:40 +00001878 EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
drhe2ca99c2018-05-02 00:33:43 +00001879 while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
drh4b5345c2018-04-24 13:07:40 +00001880 return pRow;
1881}
1882
drhe2ca99c2018-05-02 00:33:43 +00001883/* Render a single level of the graph that has iEqpId as its parent. Called
drh4b5345c2018-04-24 13:07:40 +00001884** recursively to render sublevels.
1885*/
drhe2ca99c2018-05-02 00:33:43 +00001886static void eqp_render_level(ShellState *p, int iEqpId){
drh4b5345c2018-04-24 13:07:40 +00001887 EQPGraphRow *pRow, *pNext;
drh4b5345c2018-04-24 13:07:40 +00001888 int n = strlen30(p->sGraph.zPrefix);
1889 char *z;
drhe2ca99c2018-05-02 00:33:43 +00001890 for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
1891 pNext = eqp_next_row(p, iEqpId, pRow);
drh4b5345c2018-04-24 13:07:40 +00001892 z = pRow->zText;
drhe2754c12019-08-26 12:50:01 +00001893 utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix,
1894 pNext ? "|--" : "`--", z);
drhe2188f02018-05-07 11:37:34 +00001895 if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){
drh4b5345c2018-04-24 13:07:40 +00001896 memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4);
drhe2ca99c2018-05-02 00:33:43 +00001897 eqp_render_level(p, pRow->iEqpId);
drh4b5345c2018-04-24 13:07:40 +00001898 p->sGraph.zPrefix[n] = 0;
1899 }
1900 }
1901}
1902
1903/*
1904** Display and reset the EXPLAIN QUERY PLAN data
1905*/
1906static void eqp_render(ShellState *p){
1907 EQPGraphRow *pRow = p->sGraph.pRow;
1908 if( pRow ){
1909 if( pRow->zText[0]=='-' ){
1910 if( pRow->pNext==0 ){
1911 eqp_reset(p);
1912 return;
1913 }
1914 utf8_printf(p->out, "%s\n", pRow->zText+3);
1915 p->sGraph.pRow = pRow->pNext;
1916 sqlite3_free(pRow);
1917 }else{
1918 utf8_printf(p->out, "QUERY PLAN\n");
1919 }
1920 p->sGraph.zPrefix[0] = 0;
1921 eqp_render_level(p, 0);
1922 eqp_reset(p);
1923 }
1924}
drh11be81d2018-01-06 15:46:20 +00001925
drh569b1d92019-02-05 20:51:41 +00001926#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
drh11be81d2018-01-06 15:46:20 +00001927/*
drh3f83f592019-02-04 14:53:18 +00001928** Progress handler callback.
1929*/
1930static int progress_handler(void *pClientData) {
1931 ShellState *p = (ShellState*)pClientData;
1932 p->nProgress++;
1933 if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
1934 raw_printf(p->out, "Progress limit reached (%u)\n", p->nProgress);
drhfc4eeef2019-02-05 19:48:46 +00001935 if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
1936 if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0;
drh3f83f592019-02-04 14:53:18 +00001937 return 1;
1938 }
drhfc4eeef2019-02-05 19:48:46 +00001939 if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
drh3f83f592019-02-04 14:53:18 +00001940 raw_printf(p->out, "Progress %u\n", p->nProgress);
1941 }
1942 return 0;
1943}
drh569b1d92019-02-05 20:51:41 +00001944#endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
drh3f83f592019-02-04 14:53:18 +00001945
1946/*
drh30c54a02020-05-28 23:49:50 +00001947** Print N dashes
1948*/
1949static void print_dashes(FILE *out, int N){
1950 const char zDash[] = "--------------------------------------------------";
1951 const int nDash = sizeof(zDash) - 1;
1952 while( N>nDash ){
1953 fputs(zDash, out);
1954 N -= nDash;
1955 }
1956 raw_printf(out, "%.*s", N, zDash);
1957}
1958
1959/*
drh0908e382020-06-04 18:05:39 +00001960** Print a markdown or table-style row separator using ascii-art
drh30c54a02020-05-28 23:49:50 +00001961*/
1962static void print_row_separator(
1963 ShellState *p,
1964 int nArg,
1965 const char *zSep
1966){
1967 int i;
drh0908e382020-06-04 18:05:39 +00001968 if( nArg>0 ){
drh30c54a02020-05-28 23:49:50 +00001969 fputs(zSep, p->out);
drh0908e382020-06-04 18:05:39 +00001970 print_dashes(p->out, p->actualWidth[0]+2);
1971 for(i=1; i<nArg; i++){
1972 fputs(zSep, p->out);
1973 print_dashes(p->out, p->actualWidth[i]+2);
1974 }
1975 fputs(zSep, p->out);
drh30c54a02020-05-28 23:49:50 +00001976 }
drh30c54a02020-05-28 23:49:50 +00001977 fputs("\n", p->out);
1978}
1979
1980/*
drh2ce15c32017-07-11 13:34:40 +00001981** This is the callback routine that the shell
1982** invokes for each row of a query result.
1983*/
1984static int shell_callback(
1985 void *pArg,
1986 int nArg, /* Number of result columns */
1987 char **azArg, /* Text of each result column */
1988 char **azCol, /* Column names */
drhd6f25242020-05-29 12:31:53 +00001989 int *aiType /* Column types. Might be NULL */
drh2ce15c32017-07-11 13:34:40 +00001990){
1991 int i;
1992 ShellState *p = (ShellState*)pArg;
1993
drhb3c45232017-08-28 14:33:27 +00001994 if( azArg==0 ) return 0;
drh2ce15c32017-07-11 13:34:40 +00001995 switch( p->cMode ){
1996 case MODE_Line: {
1997 int w = 5;
1998 if( azArg==0 ) break;
1999 for(i=0; i<nArg; i++){
2000 int len = strlen30(azCol[i] ? azCol[i] : "");
2001 if( len>w ) w = len;
2002 }
2003 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
2004 for(i=0; i<nArg; i++){
2005 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
2006 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
2007 }
2008 break;
2009 }
drh8c748632020-05-29 16:15:58 +00002010 case MODE_Explain: {
2011 static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
2012 if( nArg>ArraySize(aExplainWidth) ){
2013 nArg = ArraySize(aExplainWidth);
drh2ce15c32017-07-11 13:34:40 +00002014 }
2015 if( p->cnt++==0 ){
2016 for(i=0; i<nArg; i++){
drh8c748632020-05-29 16:15:58 +00002017 int w = aExplainWidth[i];
2018 utf8_width_print(p->out, w, azCol[i]);
2019 fputs(i==nArg-1 ? "\n" : " ", p->out);
drh2ce15c32017-07-11 13:34:40 +00002020 }
drhe566ceb2020-05-30 15:34:49 +00002021 for(i=0; i<nArg; i++){
2022 int w = aExplainWidth[i];
2023 print_dashes(p->out, w);
2024 fputs(i==nArg-1 ? "\n" : " ", p->out);
2025 }
drh2ce15c32017-07-11 13:34:40 +00002026 }
2027 if( azArg==0 ) break;
2028 for(i=0; i<nArg; i++){
drh8c748632020-05-29 16:15:58 +00002029 int w = aExplainWidth[i];
2030 if( azArg[i] && strlenChar(azArg[i])>w ){
2031 w = strlenChar(azArg[i]);
drh2ce15c32017-07-11 13:34:40 +00002032 }
drh8c748632020-05-29 16:15:58 +00002033 if( i==1 && p->aiIndent && p->pStmt ){
2034 if( p->iIndent<p->nIndent ){
2035 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
drh2ce15c32017-07-11 13:34:40 +00002036 }
drh8c748632020-05-29 16:15:58 +00002037 p->iIndent++;
drh2ce15c32017-07-11 13:34:40 +00002038 }
2039 utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
drh8c748632020-05-29 16:15:58 +00002040 fputs(i==nArg-1 ? "\n" : " ", p->out);
drh2ce15c32017-07-11 13:34:40 +00002041 }
2042 break;
2043 }
2044 case MODE_Semi: { /* .schema and .fullschema output */
2045 printSchemaLine(p->out, azArg[0], ";\n");
2046 break;
2047 }
2048 case MODE_Pretty: { /* .schema and .fullschema with --indent */
2049 char *z;
2050 int j;
2051 int nParen = 0;
2052 char cEnd = 0;
2053 char c;
2054 int nLine = 0;
2055 assert( nArg==1 );
2056 if( azArg[0]==0 ) break;
2057 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
2058 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
2059 ){
2060 utf8_printf(p->out, "%s;\n", azArg[0]);
2061 break;
2062 }
2063 z = sqlite3_mprintf("%s", azArg[0]);
2064 j = 0;
2065 for(i=0; IsSpace(z[i]); i++){}
2066 for(; (c = z[i])!=0; i++){
2067 if( IsSpace(c) ){
drhc3cbd672017-10-05 19:12:10 +00002068 if( z[j-1]=='\r' ) z[j-1] = '\n';
drh2ce15c32017-07-11 13:34:40 +00002069 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
2070 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
2071 j--;
2072 }
2073 z[j++] = c;
2074 }
2075 while( j>0 && IsSpace(z[j-1]) ){ j--; }
2076 z[j] = 0;
2077 if( strlen30(z)>=79 ){
drhe2754c12019-08-26 12:50:01 +00002078 for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
drh2ce15c32017-07-11 13:34:40 +00002079 if( c==cEnd ){
2080 cEnd = 0;
2081 }else if( c=='"' || c=='\'' || c=='`' ){
2082 cEnd = c;
2083 }else if( c=='[' ){
2084 cEnd = ']';
drh11be81d2018-01-06 15:46:20 +00002085 }else if( c=='-' && z[i+1]=='-' ){
2086 cEnd = '\n';
drh2ce15c32017-07-11 13:34:40 +00002087 }else if( c=='(' ){
2088 nParen++;
2089 }else if( c==')' ){
2090 nParen--;
2091 if( nLine>0 && nParen==0 && j>0 ){
2092 printSchemaLineN(p->out, z, j, "\n");
2093 j = 0;
2094 }
2095 }
2096 z[j++] = c;
drh11be81d2018-01-06 15:46:20 +00002097 if( nParen==1 && cEnd==0
2098 && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
2099 ){
drh2ce15c32017-07-11 13:34:40 +00002100 if( c=='\n' ) j--;
2101 printSchemaLineN(p->out, z, j, "\n ");
2102 j = 0;
2103 nLine++;
2104 while( IsSpace(z[i+1]) ){ i++; }
2105 }
2106 }
2107 z[j] = 0;
2108 }
2109 printSchemaLine(p->out, z, ";\n");
2110 sqlite3_free(z);
2111 break;
2112 }
2113 case MODE_List: {
2114 if( p->cnt++==0 && p->showHeader ){
2115 for(i=0; i<nArg; i++){
2116 utf8_printf(p->out,"%s%s",azCol[i],
2117 i==nArg-1 ? p->rowSeparator : p->colSeparator);
2118 }
2119 }
2120 if( azArg==0 ) break;
2121 for(i=0; i<nArg; i++){
2122 char *z = azArg[i];
2123 if( z==0 ) z = p->nullValue;
2124 utf8_printf(p->out, "%s", z);
2125 if( i<nArg-1 ){
2126 utf8_printf(p->out, "%s", p->colSeparator);
2127 }else{
2128 utf8_printf(p->out, "%s", p->rowSeparator);
2129 }
2130 }
2131 break;
2132 }
2133 case MODE_Html: {
2134 if( p->cnt++==0 && p->showHeader ){
2135 raw_printf(p->out,"<TR>");
2136 for(i=0; i<nArg; i++){
2137 raw_printf(p->out,"<TH>");
2138 output_html_string(p->out, azCol[i]);
2139 raw_printf(p->out,"</TH>\n");
2140 }
2141 raw_printf(p->out,"</TR>\n");
2142 }
2143 if( azArg==0 ) break;
2144 raw_printf(p->out,"<TR>");
2145 for(i=0; i<nArg; i++){
2146 raw_printf(p->out,"<TD>");
2147 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
2148 raw_printf(p->out,"</TD>\n");
2149 }
2150 raw_printf(p->out,"</TR>\n");
2151 break;
2152 }
2153 case MODE_Tcl: {
2154 if( p->cnt++==0 && p->showHeader ){
2155 for(i=0; i<nArg; i++){
2156 output_c_string(p->out,azCol[i] ? azCol[i] : "");
2157 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
2158 }
2159 utf8_printf(p->out, "%s", p->rowSeparator);
2160 }
2161 if( azArg==0 ) break;
2162 for(i=0; i<nArg; i++){
2163 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
2164 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
2165 }
2166 utf8_printf(p->out, "%s", p->rowSeparator);
2167 break;
2168 }
2169 case MODE_Csv: {
2170 setBinaryMode(p->out, 1);
2171 if( p->cnt++==0 && p->showHeader ){
2172 for(i=0; i<nArg; i++){
2173 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
2174 }
2175 utf8_printf(p->out, "%s", p->rowSeparator);
2176 }
2177 if( nArg>0 ){
2178 for(i=0; i<nArg; i++){
2179 output_csv(p, azArg[i], i<nArg-1);
2180 }
2181 utf8_printf(p->out, "%s", p->rowSeparator);
2182 }
2183 setTextMode(p->out, 1);
2184 break;
2185 }
2186 case MODE_Insert: {
2187 if( azArg==0 ) break;
2188 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
2189 if( p->showHeader ){
2190 raw_printf(p->out,"(");
2191 for(i=0; i<nArg; i++){
2192 if( i>0 ) raw_printf(p->out, ",");
2193 if( quoteChar(azCol[i]) ){
2194 char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
2195 utf8_printf(p->out, "%s", z);
2196 sqlite3_free(z);
2197 }else{
2198 raw_printf(p->out, "%s", azCol[i]);
2199 }
2200 }
2201 raw_printf(p->out,")");
2202 }
2203 p->cnt++;
2204 for(i=0; i<nArg; i++){
2205 raw_printf(p->out, i>0 ? "," : " VALUES(");
2206 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
2207 utf8_printf(p->out,"NULL");
2208 }else if( aiType && aiType[i]==SQLITE_TEXT ){
2209 if( ShellHasFlag(p, SHFLG_Newlines) ){
2210 output_quoted_string(p->out, azArg[i]);
2211 }else{
2212 output_quoted_escaped_string(p->out, azArg[i]);
2213 }
2214 }else if( aiType && aiType[i]==SQLITE_INTEGER ){
2215 utf8_printf(p->out,"%s", azArg[i]);
2216 }else if( aiType && aiType[i]==SQLITE_FLOAT ){
2217 char z[50];
2218 double r = sqlite3_column_double(p->pStmt, i);
drh2f1f8802018-06-13 17:19:20 +00002219 sqlite3_uint64 ur;
2220 memcpy(&ur,&r,sizeof(r));
2221 if( ur==0x7ff0000000000000LL ){
2222 raw_printf(p->out, "1e999");
2223 }else if( ur==0xfff0000000000000LL ){
2224 raw_printf(p->out, "-1e999");
2225 }else{
2226 sqlite3_snprintf(50,z,"%!.20g", r);
2227 raw_printf(p->out, "%s", z);
2228 }
drh2ce15c32017-07-11 13:34:40 +00002229 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
2230 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
2231 int nBlob = sqlite3_column_bytes(p->pStmt, i);
2232 output_hex_blob(p->out, pBlob, nBlob);
2233 }else if( isNumber(azArg[i], 0) ){
2234 utf8_printf(p->out,"%s", azArg[i]);
2235 }else if( ShellHasFlag(p, SHFLG_Newlines) ){
2236 output_quoted_string(p->out, azArg[i]);
2237 }else{
2238 output_quoted_escaped_string(p->out, azArg[i]);
2239 }
2240 }
2241 raw_printf(p->out,");\n");
2242 break;
2243 }
drh30c54a02020-05-28 23:49:50 +00002244 case MODE_Json: {
2245 if( azArg==0 ) break;
2246 if( p->cnt==0 ){
2247 fputs("[{", p->out);
2248 }else{
2249 fputs(",\n{", p->out);
2250 }
2251 p->cnt++;
2252 for(i=0; i<nArg; i++){
drh69c093d2020-05-29 00:21:43 +00002253 output_json_string(p->out, azCol[i], -1);
drh30c54a02020-05-28 23:49:50 +00002254 putc(':', p->out);
2255 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
2256 fputs("null",p->out);
2257 }else if( aiType && aiType[i]==SQLITE_FLOAT ){
2258 char z[50];
2259 double r = sqlite3_column_double(p->pStmt, i);
2260 sqlite3_uint64 ur;
2261 memcpy(&ur,&r,sizeof(r));
2262 if( ur==0x7ff0000000000000LL ){
2263 raw_printf(p->out, "1e999");
2264 }else if( ur==0xfff0000000000000LL ){
2265 raw_printf(p->out, "-1e999");
2266 }else{
2267 sqlite3_snprintf(50,z,"%!.20g", r);
2268 raw_printf(p->out, "%s", z);
2269 }
2270 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
2271 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
2272 int nBlob = sqlite3_column_bytes(p->pStmt, i);
drh69c093d2020-05-29 00:21:43 +00002273 output_json_string(p->out, pBlob, nBlob);
drh30c54a02020-05-28 23:49:50 +00002274 }else if( aiType && aiType[i]==SQLITE_TEXT ){
drh69c093d2020-05-29 00:21:43 +00002275 output_json_string(p->out, azArg[i], -1);
drh30c54a02020-05-28 23:49:50 +00002276 }else{
2277 utf8_printf(p->out,"%s", azArg[i]);
2278 }
2279 if( i<nArg-1 ){
2280 putc(',', p->out);
2281 }
2282 }
2283 putc('}', p->out);
2284 break;
2285 }
drh2ce15c32017-07-11 13:34:40 +00002286 case MODE_Quote: {
2287 if( azArg==0 ) break;
2288 if( p->cnt==0 && p->showHeader ){
2289 for(i=0; i<nArg; i++){
drhc6835732020-05-28 20:37:17 +00002290 if( i>0 ) fputs(p->colSeparator, p->out);
drh2ce15c32017-07-11 13:34:40 +00002291 output_quoted_string(p->out, azCol[i]);
2292 }
drhc6835732020-05-28 20:37:17 +00002293 fputs(p->rowSeparator, p->out);
drh2ce15c32017-07-11 13:34:40 +00002294 }
2295 p->cnt++;
2296 for(i=0; i<nArg; i++){
drhc6835732020-05-28 20:37:17 +00002297 if( i>0 ) fputs(p->colSeparator, p->out);
drh2ce15c32017-07-11 13:34:40 +00002298 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
2299 utf8_printf(p->out,"NULL");
2300 }else if( aiType && aiType[i]==SQLITE_TEXT ){
2301 output_quoted_string(p->out, azArg[i]);
2302 }else if( aiType && aiType[i]==SQLITE_INTEGER ){
2303 utf8_printf(p->out,"%s", azArg[i]);
2304 }else if( aiType && aiType[i]==SQLITE_FLOAT ){
2305 char z[50];
2306 double r = sqlite3_column_double(p->pStmt, i);
2307 sqlite3_snprintf(50,z,"%!.20g", r);
2308 raw_printf(p->out, "%s", z);
2309 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
2310 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
2311 int nBlob = sqlite3_column_bytes(p->pStmt, i);
2312 output_hex_blob(p->out, pBlob, nBlob);
2313 }else if( isNumber(azArg[i], 0) ){
2314 utf8_printf(p->out,"%s", azArg[i]);
2315 }else{
2316 output_quoted_string(p->out, azArg[i]);
2317 }
2318 }
drhc6835732020-05-28 20:37:17 +00002319 fputs(p->rowSeparator, p->out);
drh2ce15c32017-07-11 13:34:40 +00002320 break;
2321 }
2322 case MODE_Ascii: {
2323 if( p->cnt++==0 && p->showHeader ){
2324 for(i=0; i<nArg; i++){
2325 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
2326 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
2327 }
2328 utf8_printf(p->out, "%s", p->rowSeparator);
2329 }
2330 if( azArg==0 ) break;
2331 for(i=0; i<nArg; i++){
2332 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
2333 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
2334 }
2335 utf8_printf(p->out, "%s", p->rowSeparator);
2336 break;
2337 }
drh4b5345c2018-04-24 13:07:40 +00002338 case MODE_EQP: {
drhe2ca99c2018-05-02 00:33:43 +00002339 eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
drh4b5345c2018-04-24 13:07:40 +00002340 break;
2341 }
drh2ce15c32017-07-11 13:34:40 +00002342 }
2343 return 0;
2344}
2345
2346/*
2347** This is the callback routine that the SQLite library
2348** invokes for each row of a query result.
2349*/
2350static int callback(void *pArg, int nArg, char **azArg, char **azCol){
2351 /* since we don't have type info, call the shell_callback with a NULL value */
2352 return shell_callback(pArg, nArg, azArg, azCol, NULL);
2353}
2354
2355/*
2356** This is the callback routine from sqlite3_exec() that appends all
2357** output onto the end of a ShellText object.
2358*/
2359static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){
2360 ShellText *p = (ShellText*)pArg;
2361 int i;
2362 UNUSED_PARAMETER(az);
drhb3c45232017-08-28 14:33:27 +00002363 if( azArg==0 ) return 0;
drh2ce15c32017-07-11 13:34:40 +00002364 if( p->n ) appendText(p, "|", 0);
2365 for(i=0; i<nArg; i++){
2366 if( i ) appendText(p, ",", 0);
2367 if( azArg[i] ) appendText(p, azArg[i], 0);
2368 }
2369 return 0;
2370}
2371
2372/*
2373** Generate an appropriate SELFTEST table in the main database.
2374*/
2375static void createSelftestTable(ShellState *p){
2376 char *zErrMsg = 0;
2377 sqlite3_exec(p->db,
2378 "SAVEPOINT selftest_init;\n"
2379 "CREATE TABLE IF NOT EXISTS selftest(\n"
2380 " tno INTEGER PRIMARY KEY,\n" /* Test number */
2381 " op TEXT,\n" /* Operator: memo run */
2382 " cmd TEXT,\n" /* Command text */
2383 " ans TEXT\n" /* Desired answer */
2384 ");"
2385 "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n"
2386 "INSERT INTO [_shell$self](rowid,op,cmd)\n"
2387 " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n"
2388 " 'memo','Tests generated by --init');\n"
2389 "INSERT INTO [_shell$self]\n"
2390 " SELECT 'run',\n"
2391 " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql "
drh067b92b2020-06-19 15:24:12 +00002392 "FROM sqlite_schema ORDER BY 2'',224))',\n"
drh2ce15c32017-07-11 13:34:40 +00002393 " hex(sha3_query('SELECT type,name,tbl_name,sql "
drh067b92b2020-06-19 15:24:12 +00002394 "FROM sqlite_schema ORDER BY 2',224));\n"
drh2ce15c32017-07-11 13:34:40 +00002395 "INSERT INTO [_shell$self]\n"
2396 " SELECT 'run',"
2397 " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||"
2398 " printf('%w',name) || '\" NOT INDEXED'',224))',\n"
2399 " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n"
2400 " FROM (\n"
drh067b92b2020-06-19 15:24:12 +00002401 " SELECT name FROM sqlite_schema\n"
drh2ce15c32017-07-11 13:34:40 +00002402 " WHERE type='table'\n"
2403 " AND name<>'selftest'\n"
2404 " AND coalesce(rootpage,0)>0\n"
2405 " )\n"
2406 " ORDER BY name;\n"
2407 "INSERT INTO [_shell$self]\n"
2408 " VALUES('run','PRAGMA integrity_check','ok');\n"
2409 "INSERT INTO selftest(tno,op,cmd,ans)"
2410 " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
2411 "DROP TABLE [_shell$self];"
2412 ,0,0,&zErrMsg);
2413 if( zErrMsg ){
2414 utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
2415 sqlite3_free(zErrMsg);
2416 }
2417 sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
2418}
2419
2420
2421/*
2422** Set the destination table field of the ShellState structure to
2423** the name of the table given. Escape any quote characters in the
2424** table name.
2425*/
2426static void set_table_name(ShellState *p, const char *zName){
2427 int i, n;
mistachkin2158a0c2017-09-09 00:51:36 +00002428 char cQuote;
drh2ce15c32017-07-11 13:34:40 +00002429 char *z;
2430
2431 if( p->zDestTable ){
2432 free(p->zDestTable);
2433 p->zDestTable = 0;
2434 }
2435 if( zName==0 ) return;
2436 cQuote = quoteChar(zName);
2437 n = strlen30(zName);
2438 if( cQuote ) n += n+2;
2439 z = p->zDestTable = malloc( n+1 );
drh4b5345c2018-04-24 13:07:40 +00002440 if( z==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00002441 n = 0;
2442 if( cQuote ) z[n++] = cQuote;
2443 for(i=0; zName[i]; i++){
2444 z[n++] = zName[i];
2445 if( zName[i]==cQuote ) z[n++] = cQuote;
2446 }
2447 if( cQuote ) z[n++] = cQuote;
2448 z[n] = 0;
2449}
2450
2451
2452/*
2453** Execute a query statement that will generate SQL output. Print
2454** the result columns, comma-separated, on a line and then add a
2455** semicolon terminator to the end of that line.
2456**
2457** If the number of columns is 1 and that column contains text "--"
2458** then write the semicolon on a separate line. That way, if a
2459** "--" comment occurs at the end of the statement, the comment
2460** won't consume the semicolon terminator.
2461*/
2462static int run_table_dump_query(
2463 ShellState *p, /* Query context */
drh8e9297f2020-03-25 12:50:13 +00002464 const char *zSelect /* SELECT statement to extract content */
drh2ce15c32017-07-11 13:34:40 +00002465){
2466 sqlite3_stmt *pSelect;
2467 int rc;
2468 int nResult;
2469 int i;
2470 const char *z;
2471 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
2472 if( rc!=SQLITE_OK || !pSelect ){
2473 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
2474 sqlite3_errmsg(p->db));
2475 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
2476 return rc;
2477 }
2478 rc = sqlite3_step(pSelect);
2479 nResult = sqlite3_column_count(pSelect);
2480 while( rc==SQLITE_ROW ){
drh2ce15c32017-07-11 13:34:40 +00002481 z = (const char*)sqlite3_column_text(pSelect, 0);
2482 utf8_printf(p->out, "%s", z);
2483 for(i=1; i<nResult; i++){
2484 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
2485 }
2486 if( z==0 ) z = "";
2487 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
2488 if( z[0] ){
2489 raw_printf(p->out, "\n;\n");
2490 }else{
2491 raw_printf(p->out, ";\n");
2492 }
2493 rc = sqlite3_step(pSelect);
2494 }
2495 rc = sqlite3_finalize(pSelect);
2496 if( rc!=SQLITE_OK ){
2497 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
2498 sqlite3_errmsg(p->db));
2499 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
2500 }
2501 return rc;
2502}
2503
2504/*
2505** Allocate space and save off current error string.
2506*/
2507static char *save_err_msg(
2508 sqlite3 *db /* Database to query */
2509){
2510 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
2511 char *zErrMsg = sqlite3_malloc64(nErrMsg);
2512 if( zErrMsg ){
2513 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
2514 }
2515 return zErrMsg;
2516}
2517
2518#ifdef __linux__
2519/*
2520** Attempt to display I/O stats on Linux using /proc/PID/io
2521*/
2522static void displayLinuxIoStats(FILE *out){
2523 FILE *in;
2524 char z[200];
2525 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
2526 in = fopen(z, "rb");
2527 if( in==0 ) return;
2528 while( fgets(z, sizeof(z), in)!=0 ){
2529 static const struct {
2530 const char *zPattern;
2531 const char *zDesc;
2532 } aTrans[] = {
2533 { "rchar: ", "Bytes received by read():" },
2534 { "wchar: ", "Bytes sent to write():" },
2535 { "syscr: ", "Read() system calls:" },
2536 { "syscw: ", "Write() system calls:" },
2537 { "read_bytes: ", "Bytes read from storage:" },
2538 { "write_bytes: ", "Bytes written to storage:" },
2539 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
2540 };
2541 int i;
2542 for(i=0; i<ArraySize(aTrans); i++){
drhaf2770f2018-01-05 14:55:43 +00002543 int n = strlen30(aTrans[i].zPattern);
drh2ce15c32017-07-11 13:34:40 +00002544 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
2545 utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
2546 break;
2547 }
2548 }
2549 }
2550 fclose(in);
2551}
2552#endif
2553
2554/*
2555** Display a single line of status using 64-bit values.
2556*/
2557static void displayStatLine(
2558 ShellState *p, /* The shell context */
2559 char *zLabel, /* Label for this one line */
2560 char *zFormat, /* Format for the result */
2561 int iStatusCtrl, /* Which status to display */
2562 int bReset /* True to reset the stats */
2563){
2564 sqlite3_int64 iCur = -1;
2565 sqlite3_int64 iHiwtr = -1;
2566 int i, nPercent;
2567 char zLine[200];
2568 sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset);
2569 for(i=0, nPercent=0; zFormat[i]; i++){
2570 if( zFormat[i]=='%' ) nPercent++;
2571 }
2572 if( nPercent>1 ){
2573 sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
2574 }else{
2575 sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
2576 }
2577 raw_printf(p->out, "%-36s %s\n", zLabel, zLine);
2578}
2579
2580/*
2581** Display memory stats.
2582*/
2583static int display_stats(
2584 sqlite3 *db, /* Database to query */
2585 ShellState *pArg, /* Pointer to ShellState */
2586 int bReset /* True to reset the stats */
2587){
2588 int iCur;
2589 int iHiwtr;
drh393344f2018-03-09 16:37:05 +00002590 FILE *out;
2591 if( pArg==0 || pArg->out==0 ) return 0;
2592 out = pArg->out;
drh2ce15c32017-07-11 13:34:40 +00002593
drh393344f2018-03-09 16:37:05 +00002594 if( pArg->pStmt && (pArg->statsOn & 2) ){
2595 int nCol, i, x;
2596 sqlite3_stmt *pStmt = pArg->pStmt;
2597 char z[100];
2598 nCol = sqlite3_column_count(pStmt);
2599 raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
2600 for(i=0; i<nCol; i++){
2601 sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
2602 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
drh929cce82018-03-17 16:26:36 +00002603#ifndef SQLITE_OMIT_DECLTYPE
drh393344f2018-03-09 16:37:05 +00002604 sqlite3_snprintf(30, z+x, "declared type:");
2605 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
drh929cce82018-03-17 16:26:36 +00002606#endif
2607#ifdef SQLITE_ENABLE_COLUMN_METADATA
drh393344f2018-03-09 16:37:05 +00002608 sqlite3_snprintf(30, z+x, "database name:");
2609 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_database_name(pStmt,i));
2610 sqlite3_snprintf(30, z+x, "table name:");
2611 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
2612 sqlite3_snprintf(30, z+x, "origin name:");
2613 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
drh929cce82018-03-17 16:26:36 +00002614#endif
drh2ce15c32017-07-11 13:34:40 +00002615 }
drh929cce82018-03-17 16:26:36 +00002616 }
drh2ce15c32017-07-11 13:34:40 +00002617
drh393344f2018-03-09 16:37:05 +00002618 displayStatLine(pArg, "Memory Used:",
2619 "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
2620 displayStatLine(pArg, "Number of Outstanding Allocations:",
2621 "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
2622 if( pArg->shellFlgs & SHFLG_Pagecache ){
2623 displayStatLine(pArg, "Number of Pcache Pages Used:",
2624 "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
2625 }
2626 displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
2627 "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
2628 displayStatLine(pArg, "Largest Allocation:",
2629 "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
2630 displayStatLine(pArg, "Largest Pcache Allocation:",
2631 "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
2632#ifdef YYTRACKMAXSTACKDEPTH
2633 displayStatLine(pArg, "Deepest Parser Stack:",
2634 "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
2635#endif
2636
2637 if( db ){
drh2ce15c32017-07-11 13:34:40 +00002638 if( pArg->shellFlgs & SHFLG_Lookaside ){
2639 iHiwtr = iCur = -1;
2640 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
2641 &iCur, &iHiwtr, bReset);
2642 raw_printf(pArg->out,
2643 "Lookaside Slots Used: %d (max %d)\n",
2644 iCur, iHiwtr);
2645 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
2646 &iCur, &iHiwtr, bReset);
2647 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
2648 iHiwtr);
2649 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
2650 &iCur, &iHiwtr, bReset);
2651 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
2652 iHiwtr);
2653 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
2654 &iCur, &iHiwtr, bReset);
2655 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
2656 iHiwtr);
2657 }
2658 iHiwtr = iCur = -1;
2659 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
2660 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
2661 iCur);
2662 iHiwtr = iCur = -1;
2663 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
2664 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
2665 iHiwtr = iCur = -1;
2666 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
2667 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
2668 iHiwtr = iCur = -1;
2669 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
2670 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
2671 iHiwtr = iCur = -1;
drhffc78a42018-03-14 14:53:50 +00002672 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
2673 raw_printf(pArg->out, "Page cache spills: %d\n", iCur);
2674 iHiwtr = iCur = -1;
drh2ce15c32017-07-11 13:34:40 +00002675 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
2676 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
2677 iCur);
2678 iHiwtr = iCur = -1;
2679 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
2680 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
2681 iCur);
2682 }
2683
drh393344f2018-03-09 16:37:05 +00002684 if( pArg->pStmt ){
drh2ce15c32017-07-11 13:34:40 +00002685 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
2686 bReset);
2687 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
2688 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
2689 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
2690 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
2691 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
2692 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
2693 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
drhe2754c12019-08-26 12:50:01 +00002694 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
drh393344f2018-03-09 16:37:05 +00002695 raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
2696 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
2697 raw_printf(pArg->out, "Number of times run: %d\n", iCur);
2698 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
2699 raw_printf(pArg->out, "Memory used by prepared stmt: %d\n", iCur);
drh2ce15c32017-07-11 13:34:40 +00002700 }
2701
2702#ifdef __linux__
2703 displayLinuxIoStats(pArg->out);
2704#endif
2705
2706 /* Do not remove this machine readable comment: extra-stats-output-here */
2707
2708 return 0;
2709}
2710
2711/*
2712** Display scan stats.
2713*/
2714static void display_scanstats(
2715 sqlite3 *db, /* Database to query */
2716 ShellState *pArg /* Pointer to ShellState */
2717){
2718#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
2719 UNUSED_PARAMETER(db);
2720 UNUSED_PARAMETER(pArg);
2721#else
2722 int i, k, n, mx;
2723 raw_printf(pArg->out, "-------- scanstats --------\n");
2724 mx = 0;
2725 for(k=0; k<=mx; k++){
2726 double rEstLoop = 1.0;
2727 for(i=n=0; 1; i++){
2728 sqlite3_stmt *p = pArg->pStmt;
2729 sqlite3_int64 nLoop, nVisit;
2730 double rEst;
2731 int iSid;
2732 const char *zExplain;
2733 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
2734 break;
2735 }
2736 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
2737 if( iSid>mx ) mx = iSid;
2738 if( iSid!=k ) continue;
2739 if( n==0 ){
2740 rEstLoop = (double)nLoop;
2741 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
2742 }
2743 n++;
2744 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
2745 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
2746 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
2747 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
2748 rEstLoop *= rEst;
2749 raw_printf(pArg->out,
2750 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
2751 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
2752 );
2753 }
2754 }
2755 raw_printf(pArg->out, "---------------------------\n");
2756#endif
2757}
2758
2759/*
2760** Parameter azArray points to a zero-terminated array of strings. zStr
2761** points to a single nul-terminated string. Return non-zero if zStr
2762** is equal, according to strcmp(), to any of the strings in the array.
2763** Otherwise, return zero.
2764*/
2765static int str_in_array(const char *zStr, const char **azArray){
2766 int i;
2767 for(i=0; azArray[i]; i++){
2768 if( 0==strcmp(zStr, azArray[i]) ) return 1;
2769 }
2770 return 0;
2771}
2772
2773/*
2774** If compiled statement pSql appears to be an EXPLAIN statement, allocate
2775** and populate the ShellState.aiIndent[] array with the number of
2776** spaces each opcode should be indented before it is output.
2777**
2778** The indenting rules are:
2779**
2780** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
2781** all opcodes that occur between the p2 jump destination and the opcode
2782** itself by 2 spaces.
2783**
2784** * For each "Goto", if the jump destination is earlier in the program
2785** and ends on one of:
2786** Yield SeekGt SeekLt RowSetRead Rewind
2787** or if the P1 parameter is one instead of zero,
2788** then indent all opcodes between the earlier instruction
2789** and "Goto" by 2 spaces.
2790*/
2791static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
2792 const char *zSql; /* The text of the SQL statement */
2793 const char *z; /* Used to check if this is an EXPLAIN */
2794 int *abYield = 0; /* True if op is an OP_Yield */
2795 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
2796 int iOp; /* Index of operation in p->aiIndent[] */
2797
drhf1949b62018-06-07 17:32:59 +00002798 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
drh2ce15c32017-07-11 13:34:40 +00002799 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
2800 "Rewind", 0 };
2801 const char *azGoto[] = { "Goto", 0 };
2802
2803 /* Try to figure out if this is really an EXPLAIN statement. If this
2804 ** cannot be verified, return early. */
2805 if( sqlite3_column_count(pSql)!=8 ){
2806 p->cMode = p->mode;
2807 return;
2808 }
2809 zSql = sqlite3_sql(pSql);
2810 if( zSql==0 ) return;
2811 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
2812 if( sqlite3_strnicmp(z, "explain", 7) ){
2813 p->cMode = p->mode;
2814 return;
2815 }
2816
2817 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
2818 int i;
2819 int iAddr = sqlite3_column_int(pSql, 0);
2820 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
2821
2822 /* Set p2 to the P2 field of the current opcode. Then, assuming that
2823 ** p2 is an instruction address, set variable p2op to the index of that
2824 ** instruction in the aiIndent[] array. p2 and p2op may be different if
2825 ** the current instruction is part of a sub-program generated by an
2826 ** SQL trigger or foreign key. */
2827 int p2 = sqlite3_column_int(pSql, 3);
2828 int p2op = (p2 + (iOp-iAddr));
2829
2830 /* Grow the p->aiIndent array as required */
2831 if( iOp>=nAlloc ){
2832 if( iOp==0 ){
2833 /* Do further verfication that this is explain output. Abort if
2834 ** it is not */
2835 static const char *explainCols[] = {
2836 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
2837 int jj;
2838 for(jj=0; jj<ArraySize(explainCols); jj++){
2839 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
2840 p->cMode = p->mode;
2841 sqlite3_reset(pSql);
2842 return;
2843 }
2844 }
2845 }
2846 nAlloc += 100;
2847 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
drh884406b2018-07-29 18:56:35 +00002848 if( p->aiIndent==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00002849 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
drh884406b2018-07-29 18:56:35 +00002850 if( abYield==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00002851 }
2852 abYield[iOp] = str_in_array(zOp, azYield);
2853 p->aiIndent[iOp] = 0;
2854 p->nIndent = iOp+1;
2855
2856 if( str_in_array(zOp, azNext) ){
2857 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
2858 }
2859 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
2860 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
2861 ){
2862 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
2863 }
2864 }
2865
2866 p->iIndent = 0;
2867 sqlite3_free(abYield);
2868 sqlite3_reset(pSql);
2869}
2870
2871/*
2872** Free the array allocated by explain_data_prepare().
2873*/
2874static void explain_data_delete(ShellState *p){
2875 sqlite3_free(p->aiIndent);
2876 p->aiIndent = 0;
2877 p->nIndent = 0;
2878 p->iIndent = 0;
2879}
2880
2881/*
2882** Disable and restore .wheretrace and .selecttrace settings.
2883*/
drhc0622a42020-12-04 01:17:57 +00002884static unsigned int savedSelectTrace;
2885static unsigned int savedWhereTrace;
drh2ce15c32017-07-11 13:34:40 +00002886static void disable_debug_trace_modes(void){
drhc0622a42020-12-04 01:17:57 +00002887 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &savedSelectTrace);
2888 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, 0);
2889 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &savedWhereTrace);
2890 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, 0);
drh2ce15c32017-07-11 13:34:40 +00002891}
2892static void restore_debug_trace_modes(void){
drhc0622a42020-12-04 01:17:57 +00002893 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace);
2894 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &savedWhereTrace);
drh2ce15c32017-07-11 13:34:40 +00002895}
2896
drh9cb02642019-02-28 20:10:52 +00002897/* Create the TEMP table used to store parameter bindings */
2898static void bind_table_init(ShellState *p){
drh346f4e22019-03-25 21:35:41 +00002899 int wrSchema = 0;
drh4b86e202020-01-19 20:37:26 +00002900 int defensiveMode = 0;
2901 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &defensiveMode);
2902 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0);
drh346f4e22019-03-25 21:35:41 +00002903 sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema);
2904 sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0);
drh9cb02642019-02-28 20:10:52 +00002905 sqlite3_exec(p->db,
drh65c29fd2019-03-25 21:56:26 +00002906 "CREATE TABLE IF NOT EXISTS temp.sqlite_parameters(\n"
drh9cb02642019-02-28 20:10:52 +00002907 " key TEXT PRIMARY KEY,\n"
2908 " value ANY\n"
2909 ") WITHOUT ROWID;",
2910 0, 0, 0);
drh346f4e22019-03-25 21:35:41 +00002911 sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0);
drh4b86e202020-01-19 20:37:26 +00002912 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, defensiveMode, 0);
drh9cb02642019-02-28 20:10:52 +00002913}
2914
drh8b738d02019-02-25 18:43:54 +00002915/*
2916** Bind parameters on a prepared statement.
2917**
2918** Parameter bindings are taken from a TEMP table of the form:
2919**
drh1cb02632019-03-25 22:05:22 +00002920** CREATE TEMP TABLE sqlite_parameters(key TEXT PRIMARY KEY, value)
drh8b738d02019-02-25 18:43:54 +00002921** WITHOUT ROWID;
2922**
drh91654b22020-04-02 13:21:10 +00002923** No bindings occur if this table does not exist. The name of the table
2924** begins with "sqlite_" so that it will not collide with ordinary application
2925** tables. The table must be in the TEMP schema.
drh8b738d02019-02-25 18:43:54 +00002926*/
2927static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
2928 int nVar;
2929 int i;
2930 int rc;
2931 sqlite3_stmt *pQ = 0;
2932
2933 nVar = sqlite3_bind_parameter_count(pStmt);
2934 if( nVar==0 ) return; /* Nothing to do */
drh65c29fd2019-03-25 21:56:26 +00002935 if( sqlite3_table_column_metadata(pArg->db, "TEMP", "sqlite_parameters",
drh8b738d02019-02-25 18:43:54 +00002936 "key", 0, 0, 0, 0, 0)!=SQLITE_OK ){
2937 return; /* Parameter table does not exist */
2938 }
2939 rc = sqlite3_prepare_v2(pArg->db,
drh65c29fd2019-03-25 21:56:26 +00002940 "SELECT value FROM temp.sqlite_parameters"
drh8b738d02019-02-25 18:43:54 +00002941 " WHERE key=?1", -1, &pQ, 0);
2942 if( rc || pQ==0 ) return;
2943 for(i=1; i<=nVar; i++){
2944 char zNum[30];
2945 const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
2946 if( zVar==0 ){
2947 sqlite3_snprintf(sizeof(zNum),zNum,"?%d",i);
2948 zVar = zNum;
2949 }
2950 sqlite3_bind_text(pQ, 1, zVar, -1, SQLITE_STATIC);
2951 if( sqlite3_step(pQ)==SQLITE_ROW ){
2952 sqlite3_bind_value(pStmt, i, sqlite3_column_value(pQ, 0));
2953 }else{
2954 sqlite3_bind_null(pStmt, i);
2955 }
2956 sqlite3_reset(pQ);
2957 }
2958 sqlite3_finalize(pQ);
2959}
2960
drh30c54a02020-05-28 23:49:50 +00002961/*
drh0908e382020-06-04 18:05:39 +00002962** UTF8 box-drawing characters. Imagine box lines like this:
2963**
2964** 1
2965** |
2966** 4 --+-- 2
2967** |
2968** 3
2969**
2970** Each box characters has between 2 and 4 of the lines leading from
2971** the center. The characters are here identified by the numbers of
2972** their corresponding lines.
2973*/
2974#define BOX_24 "\342\224\200" /* U+2500 --- */
2975#define BOX_13 "\342\224\202" /* U+2502 | */
2976#define BOX_23 "\342\224\214" /* U+250c ,- */
2977#define BOX_34 "\342\224\220" /* U+2510 -, */
2978#define BOX_12 "\342\224\224" /* U+2514 '- */
2979#define BOX_14 "\342\224\230" /* U+2518 -' */
2980#define BOX_123 "\342\224\234" /* U+251c |- */
2981#define BOX_134 "\342\224\244" /* U+2524 -| */
2982#define BOX_234 "\342\224\254" /* U+252c -,- */
2983#define BOX_124 "\342\224\264" /* U+2534 -'- */
2984#define BOX_1234 "\342\224\274" /* U+253c -|- */
2985
2986/* Draw horizontal line N characters long using unicode box
2987** characters
2988*/
2989static void print_box_line(FILE *out, int N){
2990 const char zDash[] =
2991 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
2992 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
2993 const int nDash = sizeof(zDash) - 1;
2994 N *= 3;
2995 while( N>nDash ){
2996 utf8_printf(out, zDash);
2997 N -= nDash;
2998 }
2999 utf8_printf(out, "%.*s", N, zDash);
3000}
3001
3002/*
3003** Draw a horizontal separator for a MODE_Box table.
3004*/
3005static void print_box_row_separator(
3006 ShellState *p,
3007 int nArg,
3008 const char *zSep1,
3009 const char *zSep2,
3010 const char *zSep3
3011){
3012 int i;
3013 if( nArg>0 ){
3014 utf8_printf(p->out, "%s", zSep1);
3015 print_box_line(p->out, p->actualWidth[0]+2);
3016 for(i=1; i<nArg; i++){
3017 utf8_printf(p->out, "%s", zSep2);
3018 print_box_line(p->out, p->actualWidth[i]+2);
3019 }
3020 utf8_printf(p->out, "%s", zSep3);
3021 }
3022 fputs("\n", p->out);
3023}
3024
3025
3026
3027/*
drh30c54a02020-05-28 23:49:50 +00003028** Run a prepared statement and output the result in one of the
drh0908e382020-06-04 18:05:39 +00003029** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
3030** or MODE_Box.
drh30c54a02020-05-28 23:49:50 +00003031**
3032** This is different from ordinary exec_prepared_stmt() in that
3033** it has to run the entire query and gather the results into memory
3034** first, in order to determine column widths, before providing
3035** any output.
3036*/
drh8c748632020-05-29 16:15:58 +00003037static void exec_prepared_stmt_columnar(
3038 ShellState *p, /* Pointer to ShellState */
3039 sqlite3_stmt *pStmt /* Statment to run */
drh30c54a02020-05-28 23:49:50 +00003040){
drhf82ce382020-08-06 16:45:22 +00003041 sqlite3_int64 nRow = 0;
drh8c748632020-05-29 16:15:58 +00003042 int nColumn = 0;
3043 char **azData = 0;
drhf82ce382020-08-06 16:45:22 +00003044 sqlite3_int64 nAlloc = 0;
drh8c748632020-05-29 16:15:58 +00003045 const char *z;
3046 int rc;
drhf82ce382020-08-06 16:45:22 +00003047 sqlite3_int64 i, nData;
3048 int j, nTotal, w, n;
drh0908e382020-06-04 18:05:39 +00003049 const char *colSep = 0;
3050 const char *rowSep = 0;
drh30c54a02020-05-28 23:49:50 +00003051
drhf82ce382020-08-06 16:45:22 +00003052 rc = sqlite3_step(pStmt);
3053 if( rc!=SQLITE_ROW ) return;
3054 nColumn = sqlite3_column_count(pStmt);
3055 nAlloc = nColumn*4;
3056 azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
3057 if( azData==0 ) shell_out_of_memory();
3058 for(i=0; i<nColumn; i++){
3059 azData[i] = strdup(sqlite3_column_name(pStmt,i));
drh8c748632020-05-29 16:15:58 +00003060 }
drhf82ce382020-08-06 16:45:22 +00003061 do{
3062 if( (nRow+2)*nColumn >= nAlloc ){
3063 nAlloc *= 2;
3064 azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
3065 if( azData==0 ) shell_out_of_memory();
3066 }
3067 nRow++;
3068 for(i=0; i<nColumn; i++){
3069 z = (const char*)sqlite3_column_text(pStmt,i);
3070 azData[nRow*nColumn + i] = z ? strdup(z) : 0;
3071 }
3072 }while( (rc = sqlite3_step(pStmt))==SQLITE_ROW );
drh8c748632020-05-29 16:15:58 +00003073 if( nColumn>p->nWidth ){
3074 p->colWidth = realloc(p->colWidth, nColumn*2*sizeof(int));
3075 if( p->colWidth==0 ) shell_out_of_memory();
3076 for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
3077 p->nWidth = nColumn;
3078 p->actualWidth = &p->colWidth[nColumn];
3079 }
3080 memset(p->actualWidth, 0, nColumn*sizeof(int));
3081 for(i=0; i<nColumn; i++){
3082 w = p->colWidth[i];
3083 if( w<0 ) w = -w;
3084 p->actualWidth[i] = w;
3085 }
3086 nTotal = nColumn*(nRow+1);
3087 for(i=0; i<nTotal; i++){
3088 z = azData[i];
3089 if( z==0 ) z = p->nullValue;
3090 n = strlenChar(z);
3091 j = i%nColumn;
3092 if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
3093 }
drh99942982020-06-15 20:05:37 +00003094 if( seenInterrupt ) goto columnar_end;
drh0908e382020-06-04 18:05:39 +00003095 switch( p->cMode ){
3096 case MODE_Column: {
3097 colSep = " ";
3098 rowSep = "\n";
3099 if( p->showHeader ){
3100 for(i=0; i<nColumn; i++){
3101 w = p->actualWidth[i];
3102 if( p->colWidth[i]<0 ) w = -w;
3103 utf8_width_print(p->out, w, azData[i]);
3104 fputs(i==nColumn-1?"\n":" ", p->out);
3105 }
3106 for(i=0; i<nColumn; i++){
3107 print_dashes(p->out, p->actualWidth[i]);
3108 fputs(i==nColumn-1?"\n":" ", p->out);
3109 }
3110 }
3111 break;
3112 }
3113 case MODE_Table: {
3114 colSep = " | ";
3115 rowSep = " |\n";
3116 print_row_separator(p, nColumn, "+");
3117 fputs("| ", p->out);
drh8c748632020-05-29 16:15:58 +00003118 for(i=0; i<nColumn; i++){
3119 w = p->actualWidth[i];
drh0908e382020-06-04 18:05:39 +00003120 n = strlenChar(azData[i]);
3121 utf8_printf(p->out, "%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
3122 fputs(i==nColumn-1?" |\n":" | ", p->out);
drh8c748632020-05-29 16:15:58 +00003123 }
drh0908e382020-06-04 18:05:39 +00003124 print_row_separator(p, nColumn, "+");
3125 break;
3126 }
3127 case MODE_Markdown: {
3128 colSep = " | ";
3129 rowSep = " |\n";
3130 fputs("| ", p->out);
drh8c748632020-05-29 16:15:58 +00003131 for(i=0; i<nColumn; i++){
drh0908e382020-06-04 18:05:39 +00003132 w = p->actualWidth[i];
3133 n = strlenChar(azData[i]);
3134 utf8_printf(p->out, "%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
3135 fputs(i==nColumn-1?" |\n":" | ", p->out);
drh8c748632020-05-29 16:15:58 +00003136 }
drh0908e382020-06-04 18:05:39 +00003137 print_row_separator(p, nColumn, "|");
3138 break;
drh8c748632020-05-29 16:15:58 +00003139 }
drh0908e382020-06-04 18:05:39 +00003140 case MODE_Box: {
3141 colSep = " " BOX_13 " ";
3142 rowSep = " " BOX_13 "\n";
3143 print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34);
3144 utf8_printf(p->out, BOX_13 " ");
3145 for(i=0; i<nColumn; i++){
3146 w = p->actualWidth[i];
3147 n = strlenChar(azData[i]);
3148 utf8_printf(p->out, "%*s%s%*s%s",
3149 (w-n)/2, "", azData[i], (w-n+1)/2, "",
3150 i==nColumn-1?" "BOX_13"\n":" "BOX_13" ");
3151 }
3152 print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
3153 break;
drh8c748632020-05-29 16:15:58 +00003154 }
drh8c748632020-05-29 16:15:58 +00003155 }
3156 for(i=nColumn, j=0; i<nTotal; i++, j++){
drh0908e382020-06-04 18:05:39 +00003157 if( j==0 && p->cMode!=MODE_Column ){
3158 utf8_printf(p->out, "%s", p->cMode==MODE_Box?BOX_13" ":"| ");
3159 }
drh8c748632020-05-29 16:15:58 +00003160 z = azData[i];
3161 if( z==0 ) z = p->nullValue;
3162 w = p->actualWidth[j];
3163 if( p->colWidth[j]<0 ) w = -w;
3164 utf8_width_print(p->out, w, z);
3165 if( j==nColumn-1 ){
drh0908e382020-06-04 18:05:39 +00003166 utf8_printf(p->out, "%s", rowSep);
drh8c748632020-05-29 16:15:58 +00003167 j = -1;
drhdd853c32020-06-16 17:34:40 +00003168 if( seenInterrupt ) goto columnar_end;
drh8c748632020-05-29 16:15:58 +00003169 }else{
drh0908e382020-06-04 18:05:39 +00003170 utf8_printf(p->out, "%s", colSep);
drh8c748632020-05-29 16:15:58 +00003171 }
3172 }
3173 if( p->cMode==MODE_Table ){
3174 print_row_separator(p, nColumn, "+");
drh0908e382020-06-04 18:05:39 +00003175 }else if( p->cMode==MODE_Box ){
3176 print_box_row_separator(p, nColumn, BOX_12, BOX_124, BOX_14);
drh8c748632020-05-29 16:15:58 +00003177 }
drh99942982020-06-15 20:05:37 +00003178columnar_end:
drhdd853c32020-06-16 17:34:40 +00003179 if( seenInterrupt ){
3180 utf8_printf(p->out, "Interrupt\n");
3181 }
drhf82ce382020-08-06 16:45:22 +00003182 nData = (nRow+1)*nColumn;
3183 for(i=0; i<nData; i++) free(azData[i]);
3184 sqlite3_free(azData);
drh30c54a02020-05-28 23:49:50 +00003185}
drh30c54a02020-05-28 23:49:50 +00003186
drh2ce15c32017-07-11 13:34:40 +00003187/*
3188** Run a prepared statement
3189*/
3190static void exec_prepared_stmt(
3191 ShellState *pArg, /* Pointer to ShellState */
drha10b9992018-03-09 15:24:33 +00003192 sqlite3_stmt *pStmt /* Statment to run */
drh2ce15c32017-07-11 13:34:40 +00003193){
3194 int rc;
3195
drh8c748632020-05-29 16:15:58 +00003196 if( pArg->cMode==MODE_Column
3197 || pArg->cMode==MODE_Table
drh0908e382020-06-04 18:05:39 +00003198 || pArg->cMode==MODE_Box
drh8c748632020-05-29 16:15:58 +00003199 || pArg->cMode==MODE_Markdown
3200 ){
3201 exec_prepared_stmt_columnar(pArg, pStmt);
3202 return;
3203 }
3204
drh2ce15c32017-07-11 13:34:40 +00003205 /* perform the first step. this will tell us if we
3206 ** have a result set or not and how wide it is.
3207 */
3208 rc = sqlite3_step(pStmt);
3209 /* if we have a result set... */
3210 if( SQLITE_ROW == rc ){
drha10b9992018-03-09 15:24:33 +00003211 /* allocate space for col name ptr, value ptr, and type */
3212 int nCol = sqlite3_column_count(pStmt);
3213 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
3214 if( !pData ){
3215 rc = SQLITE_NOMEM;
drh2ce15c32017-07-11 13:34:40 +00003216 }else{
drha10b9992018-03-09 15:24:33 +00003217 char **azCols = (char **)pData; /* Names of result columns */
3218 char **azVals = &azCols[nCol]; /* Results */
3219 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
3220 int i, x;
3221 assert(sizeof(int) <= sizeof(char *));
3222 /* save off ptrs to column names */
3223 for(i=0; i<nCol; i++){
3224 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
3225 }
drh2ce15c32017-07-11 13:34:40 +00003226 do{
drha10b9992018-03-09 15:24:33 +00003227 /* extract the data and data types */
3228 for(i=0; i<nCol; i++){
3229 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
3230 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
3231 azVals[i] = "";
3232 }else{
3233 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
3234 }
3235 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
3236 rc = SQLITE_NOMEM;
3237 break; /* from for */
3238 }
3239 } /* end for */
3240
3241 /* if data and types extracted successfully... */
3242 if( SQLITE_ROW == rc ){
3243 /* call the supplied callback with the result row data */
3244 if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){
3245 rc = SQLITE_ABORT;
3246 }else{
3247 rc = sqlite3_step(pStmt);
3248 }
3249 }
3250 } while( SQLITE_ROW == rc );
3251 sqlite3_free(pData);
drh0908e382020-06-04 18:05:39 +00003252 if( pArg->cMode==MODE_Json ){
drh30c54a02020-05-28 23:49:50 +00003253 fputs("]\n", pArg->out);
3254 }
drh2ce15c32017-07-11 13:34:40 +00003255 }
3256 }
3257}
3258
dan6b046be2018-01-09 15:25:55 +00003259#ifndef SQLITE_OMIT_VIRTUALTABLE
drh2ce15c32017-07-11 13:34:40 +00003260/*
dan43efc182017-12-19 17:42:13 +00003261** This function is called to process SQL if the previous shell command
3262** was ".expert". It passes the SQL in the second argument directly to
3263** the sqlite3expert object.
3264**
3265** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
3266** code. In this case, (*pzErr) may be set to point to a buffer containing
3267** an English language error message. It is the responsibility of the
3268** caller to eventually free this buffer using sqlite3_free().
3269*/
3270static int expertHandleSQL(
3271 ShellState *pState,
3272 const char *zSql,
3273 char **pzErr
3274){
3275 assert( pState->expert.pExpert );
3276 assert( pzErr==0 || *pzErr==0 );
3277 return sqlite3_expert_sql(pState->expert.pExpert, zSql, pzErr);
3278}
3279
3280/*
3281** This function is called either to silently clean up the object
3282** created by the ".expert" command (if bCancel==1), or to generate a
3283** report from it and then clean it up (if bCancel==0).
3284**
3285** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
3286** code. In this case, (*pzErr) may be set to point to a buffer containing
3287** an English language error message. It is the responsibility of the
3288** caller to eventually free this buffer using sqlite3_free().
3289*/
3290static int expertFinish(
3291 ShellState *pState,
3292 int bCancel,
3293 char **pzErr
3294){
3295 int rc = SQLITE_OK;
3296 sqlite3expert *p = pState->expert.pExpert;
3297 assert( p );
3298 assert( bCancel || pzErr==0 || *pzErr==0 );
3299 if( bCancel==0 ){
3300 FILE *out = pState->out;
3301 int bVerbose = pState->expert.bVerbose;
3302
3303 rc = sqlite3_expert_analyze(p, pzErr);
3304 if( rc==SQLITE_OK ){
3305 int nQuery = sqlite3_expert_count(p);
3306 int i;
3307
3308 if( bVerbose ){
3309 const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
3310 raw_printf(out, "-- Candidates -----------------------------\n");
3311 raw_printf(out, "%s\n", zCand);
3312 }
3313 for(i=0; i<nQuery; i++){
3314 const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
3315 const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES);
3316 const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
3317 if( zIdx==0 ) zIdx = "(no new indexes)\n";
3318 if( bVerbose ){
3319 raw_printf(out, "-- Query %d --------------------------------\n",i+1);
3320 raw_printf(out, "%s\n\n", zSql);
3321 }
3322 raw_printf(out, "%s\n", zIdx);
3323 raw_printf(out, "%s\n", zEQP);
3324 }
3325 }
3326 }
3327 sqlite3_expert_destroy(p);
3328 pState->expert.pExpert = 0;
3329 return rc;
3330}
3331
dan6b046be2018-01-09 15:25:55 +00003332/*
3333** Implementation of ".expert" dot command.
3334*/
3335static int expertDotCommand(
3336 ShellState *pState, /* Current shell tool state */
3337 char **azArg, /* Array of arguments passed to dot command */
3338 int nArg /* Number of entries in azArg[] */
3339){
3340 int rc = SQLITE_OK;
3341 char *zErr = 0;
3342 int i;
3343 int iSample = 0;
3344
3345 assert( pState->expert.pExpert==0 );
3346 memset(&pState->expert, 0, sizeof(ExpertInfo));
3347
3348 for(i=1; rc==SQLITE_OK && i<nArg; i++){
3349 char *z = azArg[i];
3350 int n;
3351 if( z[0]=='-' && z[1]=='-' ) z++;
3352 n = strlen30(z);
3353 if( n>=2 && 0==strncmp(z, "-verbose", n) ){
3354 pState->expert.bVerbose = 1;
3355 }
3356 else if( n>=2 && 0==strncmp(z, "-sample", n) ){
3357 if( i==(nArg-1) ){
3358 raw_printf(stderr, "option requires an argument: %s\n", z);
3359 rc = SQLITE_ERROR;
3360 }else{
3361 iSample = (int)integerValue(azArg[++i]);
3362 if( iSample<0 || iSample>100 ){
3363 raw_printf(stderr, "value out of range: %s\n", azArg[i]);
3364 rc = SQLITE_ERROR;
3365 }
3366 }
3367 }
3368 else{
3369 raw_printf(stderr, "unknown option: %s\n", z);
3370 rc = SQLITE_ERROR;
3371 }
3372 }
3373
3374 if( rc==SQLITE_OK ){
3375 pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
3376 if( pState->expert.pExpert==0 ){
3377 raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr);
3378 rc = SQLITE_ERROR;
3379 }else{
3380 sqlite3_expert_config(
3381 pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
3382 );
3383 }
3384 }
3385
3386 return rc;
3387}
3388#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
dan43efc182017-12-19 17:42:13 +00003389
3390/*
drh2ce15c32017-07-11 13:34:40 +00003391** Execute a statement or set of statements. Print
3392** any result rows/columns depending on the current mode
3393** set via the supplied callback.
3394**
3395** This is very similar to SQLite's built-in sqlite3_exec()
3396** function except it takes a slightly different callback
3397** and callback data argument.
3398*/
3399static int shell_exec(
drh2ce15c32017-07-11 13:34:40 +00003400 ShellState *pArg, /* Pointer to ShellState */
drha10b9992018-03-09 15:24:33 +00003401 const char *zSql, /* SQL to be evaluated */
drh2ce15c32017-07-11 13:34:40 +00003402 char **pzErrMsg /* Error msg written here */
3403){
3404 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
3405 int rc = SQLITE_OK; /* Return Code */
3406 int rc2;
3407 const char *zLeftover; /* Tail of unprocessed SQL */
drha10b9992018-03-09 15:24:33 +00003408 sqlite3 *db = pArg->db;
drh2ce15c32017-07-11 13:34:40 +00003409
3410 if( pzErrMsg ){
3411 *pzErrMsg = NULL;
3412 }
3413
dan6b046be2018-01-09 15:25:55 +00003414#ifndef SQLITE_OMIT_VIRTUALTABLE
dan43efc182017-12-19 17:42:13 +00003415 if( pArg->expert.pExpert ){
3416 rc = expertHandleSQL(pArg, zSql, pzErrMsg);
3417 return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg);
3418 }
dan6b046be2018-01-09 15:25:55 +00003419#endif
dan43efc182017-12-19 17:42:13 +00003420
drh2ce15c32017-07-11 13:34:40 +00003421 while( zSql[0] && (SQLITE_OK == rc) ){
3422 static const char *zStmtSql;
3423 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
3424 if( SQLITE_OK != rc ){
3425 if( pzErrMsg ){
3426 *pzErrMsg = save_err_msg(db);
3427 }
3428 }else{
3429 if( !pStmt ){
3430 /* this happens for a comment or white-space */
3431 zSql = zLeftover;
3432 while( IsSpace(zSql[0]) ) zSql++;
3433 continue;
3434 }
3435 zStmtSql = sqlite3_sql(pStmt);
3436 if( zStmtSql==0 ) zStmtSql = "";
3437 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
3438
3439 /* save off the prepared statment handle and reset row count */
3440 if( pArg ){
3441 pArg->pStmt = pStmt;
3442 pArg->cnt = 0;
3443 }
3444
3445 /* echo the sql statement if echo on */
3446 if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){
3447 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
3448 }
3449
3450 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
drh39c5c4a2019-03-06 14:53:27 +00003451 if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
drh2ce15c32017-07-11 13:34:40 +00003452 sqlite3_stmt *pExplain;
3453 char *zEQP;
drhada70452017-12-21 21:02:27 +00003454 int triggerEQP = 0;
drh2ce15c32017-07-11 13:34:40 +00003455 disable_debug_trace_modes();
drhada70452017-12-21 21:02:27 +00003456 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
3457 if( pArg->autoEQP>=AUTOEQP_trigger ){
3458 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
3459 }
drh2ce15c32017-07-11 13:34:40 +00003460 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
3461 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
3462 if( rc==SQLITE_OK ){
3463 while( sqlite3_step(pExplain)==SQLITE_ROW ){
drh4b5345c2018-04-24 13:07:40 +00003464 const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
drhe2ca99c2018-05-02 00:33:43 +00003465 int iEqpId = sqlite3_column_int(pExplain, 0);
3466 int iParentId = sqlite3_column_int(pExplain, 1);
drh7e088a62020-05-02 00:01:39 +00003467 if( zEQPLine==0 ) zEQPLine = "";
drh4b5345c2018-04-24 13:07:40 +00003468 if( zEQPLine[0]=='-' ) eqp_render(pArg);
drhe2ca99c2018-05-02 00:33:43 +00003469 eqp_append(pArg, iEqpId, iParentId, zEQPLine);
drh2ce15c32017-07-11 13:34:40 +00003470 }
drh4b5345c2018-04-24 13:07:40 +00003471 eqp_render(pArg);
drh2ce15c32017-07-11 13:34:40 +00003472 }
3473 sqlite3_finalize(pExplain);
3474 sqlite3_free(zEQP);
drhada70452017-12-21 21:02:27 +00003475 if( pArg->autoEQP>=AUTOEQP_full ){
drh2ce15c32017-07-11 13:34:40 +00003476 /* Also do an EXPLAIN for ".eqp full" mode */
3477 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
3478 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
3479 if( rc==SQLITE_OK ){
3480 pArg->cMode = MODE_Explain;
3481 explain_data_prepare(pArg, pExplain);
drha10b9992018-03-09 15:24:33 +00003482 exec_prepared_stmt(pArg, pExplain);
drh2ce15c32017-07-11 13:34:40 +00003483 explain_data_delete(pArg);
3484 }
3485 sqlite3_finalize(pExplain);
3486 sqlite3_free(zEQP);
3487 }
drh51efe092018-03-20 12:04:38 +00003488 if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
3489 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
3490 /* Reprepare pStmt before reactiving trace modes */
3491 sqlite3_finalize(pStmt);
3492 sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
drh3c49eaf2018-06-07 15:23:43 +00003493 if( pArg ) pArg->pStmt = pStmt;
drh51efe092018-03-20 12:04:38 +00003494 }
drh2ce15c32017-07-11 13:34:40 +00003495 restore_debug_trace_modes();
3496 }
3497
3498 if( pArg ){
3499 pArg->cMode = pArg->mode;
drh4b5345c2018-04-24 13:07:40 +00003500 if( pArg->autoExplain ){
drh39c5c4a2019-03-06 14:53:27 +00003501 if( sqlite3_stmt_isexplain(pStmt)==1 ){
drh4b5345c2018-04-24 13:07:40 +00003502 pArg->cMode = MODE_Explain;
3503 }
drh39c5c4a2019-03-06 14:53:27 +00003504 if( sqlite3_stmt_isexplain(pStmt)==2 ){
drh4b5345c2018-04-24 13:07:40 +00003505 pArg->cMode = MODE_EQP;
3506 }
drh2ce15c32017-07-11 13:34:40 +00003507 }
3508
3509 /* If the shell is currently in ".explain" mode, gather the extra
3510 ** data required to add indents to the output.*/
3511 if( pArg->cMode==MODE_Explain ){
3512 explain_data_prepare(pArg, pStmt);
3513 }
3514 }
3515
drh8b738d02019-02-25 18:43:54 +00003516 bind_prepared_stmt(pArg, pStmt);
drha10b9992018-03-09 15:24:33 +00003517 exec_prepared_stmt(pArg, pStmt);
drh2ce15c32017-07-11 13:34:40 +00003518 explain_data_delete(pArg);
drh4b5345c2018-04-24 13:07:40 +00003519 eqp_render(pArg);
drh2ce15c32017-07-11 13:34:40 +00003520
3521 /* print usage stats if stats on */
3522 if( pArg && pArg->statsOn ){
3523 display_stats(db, pArg, 0);
3524 }
3525
3526 /* print loop-counters if required */
3527 if( pArg && pArg->scanstatsOn ){
3528 display_scanstats(db, pArg);
3529 }
3530
3531 /* Finalize the statement just executed. If this fails, save a
3532 ** copy of the error message. Otherwise, set zSql to point to the
3533 ** next statement to execute. */
3534 rc2 = sqlite3_finalize(pStmt);
3535 if( rc!=SQLITE_NOMEM ) rc = rc2;
3536 if( rc==SQLITE_OK ){
3537 zSql = zLeftover;
3538 while( IsSpace(zSql[0]) ) zSql++;
3539 }else if( pzErrMsg ){
3540 *pzErrMsg = save_err_msg(db);
3541 }
3542
3543 /* clear saved stmt handle */
3544 if( pArg ){
3545 pArg->pStmt = NULL;
3546 }
3547 }
3548 } /* end while */
3549
3550 return rc;
3551}
3552
3553/*
3554** Release memory previously allocated by tableColumnList().
3555*/
3556static void freeColumnList(char **azCol){
3557 int i;
3558 for(i=1; azCol[i]; i++){
3559 sqlite3_free(azCol[i]);
3560 }
3561 /* azCol[0] is a static string */
3562 sqlite3_free(azCol);
3563}
3564
3565/*
3566** Return a list of pointers to strings which are the names of all
3567** columns in table zTab. The memory to hold the names is dynamically
3568** allocated and must be released by the caller using a subsequent call
3569** to freeColumnList().
3570**
3571** The azCol[0] entry is usually NULL. However, if zTab contains a rowid
3572** value that needs to be preserved, then azCol[0] is filled in with the
3573** name of the rowid column.
3574**
3575** The first regular column in the table is azCol[1]. The list is terminated
3576** by an entry with azCol[i]==0.
3577*/
3578static char **tableColumnList(ShellState *p, const char *zTab){
3579 char **azCol = 0;
3580 sqlite3_stmt *pStmt;
3581 char *zSql;
3582 int nCol = 0;
3583 int nAlloc = 0;
3584 int nPK = 0; /* Number of PRIMARY KEY columns seen */
3585 int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */
3586 int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid);
3587 int rc;
3588
3589 zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab);
3590 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3591 sqlite3_free(zSql);
3592 if( rc ) return 0;
3593 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3594 if( nCol>=nAlloc-2 ){
3595 nAlloc = nAlloc*2 + nCol + 10;
3596 azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
drh4b5345c2018-04-24 13:07:40 +00003597 if( azCol==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00003598 }
3599 azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
3600 if( sqlite3_column_int(pStmt, 5) ){
3601 nPK++;
3602 if( nPK==1
3603 && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2),
3604 "INTEGER")==0
3605 ){
3606 isIPK = 1;
3607 }else{
3608 isIPK = 0;
3609 }
3610 }
3611 }
3612 sqlite3_finalize(pStmt);
drh4c6cddc2017-10-12 10:28:30 +00003613 if( azCol==0 ) return 0;
drh2ce15c32017-07-11 13:34:40 +00003614 azCol[0] = 0;
3615 azCol[nCol+1] = 0;
3616
3617 /* The decision of whether or not a rowid really needs to be preserved
3618 ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table
3619 ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve
3620 ** rowids on tables where the rowid is inaccessible because there are other
3621 ** columns in the table named "rowid", "_rowid_", and "oid".
3622 */
3623 if( preserveRowid && isIPK ){
3624 /* If a single PRIMARY KEY column with type INTEGER was seen, then it
3625 ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID
3626 ** table or a INTEGER PRIMARY KEY DESC column, neither of which are
3627 ** ROWID aliases. To distinguish these cases, check to see if
3628 ** there is a "pk" entry in "PRAGMA index_list". There will be
3629 ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID.
3630 */
3631 zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)"
3632 " WHERE origin='pk'", zTab);
3633 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3634 sqlite3_free(zSql);
3635 if( rc ){
3636 freeColumnList(azCol);
3637 return 0;
3638 }
3639 rc = sqlite3_step(pStmt);
3640 sqlite3_finalize(pStmt);
3641 preserveRowid = rc==SQLITE_ROW;
3642 }
3643 if( preserveRowid ){
3644 /* Only preserve the rowid if we can find a name to use for the
3645 ** rowid */
3646 static char *azRowid[] = { "rowid", "_rowid_", "oid" };
3647 int i, j;
3648 for(j=0; j<3; j++){
3649 for(i=1; i<=nCol; i++){
3650 if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break;
3651 }
3652 if( i>nCol ){
3653 /* At this point, we know that azRowid[j] is not the name of any
3654 ** ordinary column in the table. Verify that azRowid[j] is a valid
3655 ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID
3656 ** tables will fail this last check */
3657 rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0);
3658 if( rc==SQLITE_OK ) azCol[0] = azRowid[j];
3659 break;
3660 }
3661 }
3662 }
3663 return azCol;
3664}
3665
3666/*
3667** Toggle the reverse_unordered_selects setting.
3668*/
3669static void toggleSelectOrder(sqlite3 *db){
3670 sqlite3_stmt *pStmt = 0;
3671 int iSetting = 0;
3672 char zStmt[100];
3673 sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0);
3674 if( sqlite3_step(pStmt)==SQLITE_ROW ){
3675 iSetting = sqlite3_column_int(pStmt, 0);
3676 }
3677 sqlite3_finalize(pStmt);
3678 sqlite3_snprintf(sizeof(zStmt), zStmt,
3679 "PRAGMA reverse_unordered_selects(%d)", !iSetting);
3680 sqlite3_exec(db, zStmt, 0, 0, 0);
3681}
3682
3683/*
3684** This is a different callback routine used for dumping the database.
3685** Each row received by this callback consists of a table name,
3686** the table type ("index" or "table") and SQL to create the table.
3687** This routine should print text sufficient to recreate the table.
3688*/
3689static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
3690 int rc;
3691 const char *zTable;
3692 const char *zType;
3693 const char *zSql;
3694 ShellState *p = (ShellState *)pArg;
mistachkina00a0162020-10-18 18:35:34 +00003695 int dataOnly;
3696 int noSys;
drh2ce15c32017-07-11 13:34:40 +00003697
3698 UNUSED_PARAMETER(azNotUsed);
drhb3c45232017-08-28 14:33:27 +00003699 if( nArg!=3 || azArg==0 ) return 0;
drh2ce15c32017-07-11 13:34:40 +00003700 zTable = azArg[0];
3701 zType = azArg[1];
3702 zSql = azArg[2];
mistachkina00a0162020-10-18 18:35:34 +00003703 dataOnly = (p->shellFlgs & SHFLG_DumpDataOnly)!=0;
3704 noSys = (p->shellFlgs & SHFLG_DumpNoSys)!=0;
drh2ce15c32017-07-11 13:34:40 +00003705
drhc1962192020-10-12 16:54:28 +00003706 if( strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
3707 if( !dataOnly ) raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
3708 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
3709 if( !dataOnly ) raw_printf(p->out, "ANALYZE sqlite_schema;\n");
drh2ce15c32017-07-11 13:34:40 +00003710 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
3711 return 0;
drhc1962192020-10-12 16:54:28 +00003712 }else if( dataOnly ){
3713 /* no-op */
drh2ce15c32017-07-11 13:34:40 +00003714 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
3715 char *zIns;
3716 if( !p->writableSchema ){
3717 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
3718 p->writableSchema = 1;
3719 }
3720 zIns = sqlite3_mprintf(
drh067b92b2020-06-19 15:24:12 +00003721 "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)"
drh2ce15c32017-07-11 13:34:40 +00003722 "VALUES('table','%q','%q',0,'%q');",
3723 zTable, zTable, zSql);
3724 utf8_printf(p->out, "%s\n", zIns);
3725 sqlite3_free(zIns);
3726 return 0;
3727 }else{
3728 printSchemaLine(p->out, zSql, ";\n");
3729 }
3730
3731 if( strcmp(zType, "table")==0 ){
3732 ShellText sSelect;
3733 ShellText sTable;
3734 char **azCol;
3735 int i;
3736 char *savedDestTable;
3737 int savedMode;
3738
3739 azCol = tableColumnList(p, zTable);
3740 if( azCol==0 ){
3741 p->nErr++;
3742 return 0;
3743 }
3744
3745 /* Always quote the table name, even if it appears to be pure ascii,
3746 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
3747 initText(&sTable);
3748 appendText(&sTable, zTable, quoteChar(zTable));
3749 /* If preserving the rowid, add a column list after the table name.
3750 ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)"
3751 ** instead of the usual "INSERT INTO tab VALUES(...)".
3752 */
3753 if( azCol[0] ){
3754 appendText(&sTable, "(", 0);
3755 appendText(&sTable, azCol[0], 0);
3756 for(i=1; azCol[i]; i++){
3757 appendText(&sTable, ",", 0);
3758 appendText(&sTable, azCol[i], quoteChar(azCol[i]));
3759 }
3760 appendText(&sTable, ")", 0);
3761 }
3762
3763 /* Build an appropriate SELECT statement */
3764 initText(&sSelect);
3765 appendText(&sSelect, "SELECT ", 0);
3766 if( azCol[0] ){
3767 appendText(&sSelect, azCol[0], 0);
3768 appendText(&sSelect, ",", 0);
3769 }
3770 for(i=1; azCol[i]; i++){
3771 appendText(&sSelect, azCol[i], quoteChar(azCol[i]));
3772 if( azCol[i+1] ){
3773 appendText(&sSelect, ",", 0);
3774 }
3775 }
3776 freeColumnList(azCol);
3777 appendText(&sSelect, " FROM ", 0);
3778 appendText(&sSelect, zTable, quoteChar(zTable));
3779
3780 savedDestTable = p->zDestTable;
3781 savedMode = p->mode;
3782 p->zDestTable = sTable.z;
3783 p->mode = p->cMode = MODE_Insert;
drha10b9992018-03-09 15:24:33 +00003784 rc = shell_exec(p, sSelect.z, 0);
drh2ce15c32017-07-11 13:34:40 +00003785 if( (rc&0xff)==SQLITE_CORRUPT ){
3786 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
3787 toggleSelectOrder(p->db);
drha10b9992018-03-09 15:24:33 +00003788 shell_exec(p, sSelect.z, 0);
drh2ce15c32017-07-11 13:34:40 +00003789 toggleSelectOrder(p->db);
3790 }
3791 p->zDestTable = savedDestTable;
3792 p->mode = savedMode;
3793 freeText(&sTable);
3794 freeText(&sSelect);
3795 if( rc ) p->nErr++;
3796 }
3797 return 0;
3798}
3799
3800/*
3801** Run zQuery. Use dump_callback() as the callback routine so that
3802** the contents of the query are output as SQL statements.
3803**
3804** If we get a SQLITE_CORRUPT error, rerun the query after appending
3805** "ORDER BY rowid DESC" to the end.
3806*/
3807static int run_schema_dump_query(
3808 ShellState *p,
3809 const char *zQuery
3810){
3811 int rc;
3812 char *zErr = 0;
3813 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
3814 if( rc==SQLITE_CORRUPT ){
3815 char *zQ2;
3816 int len = strlen30(zQuery);
3817 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
3818 if( zErr ){
3819 utf8_printf(p->out, "/****** %s ******/\n", zErr);
3820 sqlite3_free(zErr);
3821 zErr = 0;
3822 }
3823 zQ2 = malloc( len+100 );
3824 if( zQ2==0 ) return rc;
3825 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
3826 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
3827 if( rc ){
3828 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
3829 }else{
3830 rc = SQLITE_CORRUPT;
3831 }
3832 sqlite3_free(zErr);
3833 free(zQ2);
3834 }
3835 return rc;
3836}
3837
3838/*
drh98aa2ab2018-09-26 16:53:51 +00003839** Text of help messages.
3840**
3841** The help text for each individual command begins with a line that starts
3842** with ".". Subsequent lines are supplimental information.
3843**
3844** There must be two or more spaces between the end of the command and the
3845** start of the description of what that command does.
drh2ce15c32017-07-11 13:34:40 +00003846*/
drh98aa2ab2018-09-26 16:53:51 +00003847static const char *(azHelp[]) = {
drhe37c0e12018-01-06 19:19:50 +00003848#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
drh98aa2ab2018-09-26 16:53:51 +00003849 ".archive ... Manage SQL archives",
3850 " Each command must have exactly one of the following options:",
3851 " -c, --create Create a new archive",
drhe2754c12019-08-26 12:50:01 +00003852 " -u, --update Add or update files with changed mtime",
3853 " -i, --insert Like -u but always add even if unchanged",
drh98aa2ab2018-09-26 16:53:51 +00003854 " -t, --list List contents of archive",
3855 " -x, --extract Extract files from archive",
3856 " Optional arguments:",
3857 " -v, --verbose Print each filename as it is processed",
drhe2754c12019-08-26 12:50:01 +00003858 " -f FILE, --file FILE Use archive FILE (default is current db)",
3859 " -a FILE, --append FILE Open FILE using the apndvfs VFS",
3860 " -C DIR, --directory DIR Read/extract files from directory DIR",
drh98aa2ab2018-09-26 16:53:51 +00003861 " -n, --dryrun Show the SQL that would have occurred",
3862 " Examples:",
drhe2754c12019-08-26 12:50:01 +00003863 " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
3864 " .ar -tf ARCHIVE # List members of ARCHIVE",
3865 " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
drh98aa2ab2018-09-26 16:53:51 +00003866 " See also:",
3867 " http://sqlite.org/cli.html#sqlar_archive_support",
drhe37c0e12018-01-06 19:19:50 +00003868#endif
drh2ce15c32017-07-11 13:34:40 +00003869#ifndef SQLITE_OMIT_AUTHORIZATION
drh98aa2ab2018-09-26 16:53:51 +00003870 ".auth ON|OFF Show authorizer callbacks",
drh2ce15c32017-07-11 13:34:40 +00003871#endif
drh98aa2ab2018-09-26 16:53:51 +00003872 ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
3873 " --append Use the appendvfs",
drhe2754c12019-08-26 12:50:01 +00003874 " --async Write to FILE without journal and fsync()",
drh98aa2ab2018-09-26 16:53:51 +00003875 ".bail on|off Stop after hitting an error. Default OFF",
3876 ".binary on|off Turn binary output on or off. Default OFF",
3877 ".cd DIRECTORY Change the working directory to DIRECTORY",
3878 ".changes on|off Show number of rows changed by SQL",
3879 ".check GLOB Fail if output since .testcase does not match",
3880 ".clone NEWDB Clone data into NEWDB from the existing database",
3881 ".databases List names and files of attached databases",
3882 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
3883 ".dbinfo ?DB? Show status information about the database",
drh8e9297f2020-03-25 12:50:13 +00003884 ".dump ?TABLE? Render database content as SQL",
drheb7f2a02018-09-26 18:02:32 +00003885 " Options:",
drhc1962192020-10-12 16:54:28 +00003886 " --data-only Output only INSERT statements",
drheb7f2a02018-09-26 18:02:32 +00003887 " --newlines Allow unescaped newline characters in output",
drhc1962192020-10-12 16:54:28 +00003888 " --nosys Omit system tables (ex: \"sqlite_stat1\")",
3889 " --preserve-rowids Include ROWID values in the output",
drhe551b512019-04-17 13:58:07 +00003890 " TABLE is a LIKE pattern for the tables to dump",
drh8e9297f2020-03-25 12:50:13 +00003891 " Additional LIKE patterns can be given in subsequent arguments",
drh98aa2ab2018-09-26 16:53:51 +00003892 ".echo on|off Turn command echo on or off",
drhb4e50392019-01-26 15:40:04 +00003893 ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN",
3894 " Other Modes:",
3895#ifdef SQLITE_DEBUG
3896 " test Show raw EXPLAIN QUERY PLAN output",
drhe2754c12019-08-26 12:50:01 +00003897 " trace Like \"full\" but enable \"PRAGMA vdbe_trace\"",
drhb4e50392019-01-26 15:40:04 +00003898#endif
3899 " trigger Like \"full\" but also show trigger bytecode",
drhe2754c12019-08-26 12:50:01 +00003900 ".excel Display the output of next command in spreadsheet",
drh7a431002020-04-18 14:12:00 +00003901 " --bom Put a UTF8 byte-order mark on intermediate file",
drheb7f2a02018-09-26 18:02:32 +00003902 ".exit ?CODE? Exit this program with return-code CODE",
drhe2754c12019-08-26 12:50:01 +00003903 ".expert EXPERIMENTAL. Suggest indexes for queries",
drh978256f2019-11-02 00:00:14 +00003904 ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
drhd985f722019-06-05 14:29:53 +00003905 ".filectrl CMD ... Run various sqlite3_file_control() operations",
drh541ef2c2020-04-20 16:21:30 +00003906 " --schema SCHEMA Use SCHEMA instead of \"main\"",
3907 " --help Show CMD details",
drh98aa2ab2018-09-26 16:53:51 +00003908 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
3909 ".headers on|off Turn display of headers on or off",
3910 ".help ?-all? ?PATTERN? Show help text for PATTERN",
3911 ".import FILE TABLE Import data from FILE into TABLE",
drhccb37812020-03-09 15:39:39 +00003912 " Options:",
3913 " --ascii Use \\037 and \\036 as column and row separators",
3914 " --csv Use , and \\n as column and row separators",
3915 " --skip N Skip the first N rows of input",
3916 " -v \"Verbose\" - increase auxiliary output",
3917 " Notes:",
3918 " * If TABLE does not exist, it is created. The first row of input",
3919 " determines the column names.",
3920 " * If neither --csv or --ascii are used, the input mode is derived",
3921 " from the \".mode\" output mode",
3922 " * If FILE begins with \"|\" then it is a command that generates the",
3923 " input text.",
drh2ce15c32017-07-11 13:34:40 +00003924#ifndef SQLITE_OMIT_TEST_CONTROL
drh98aa2ab2018-09-26 16:53:51 +00003925 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
drh2ce15c32017-07-11 13:34:40 +00003926#endif
drh98aa2ab2018-09-26 16:53:51 +00003927 ".indexes ?TABLE? Show names of indexes",
3928 " If TABLE is specified, only show indexes for",
3929 " tables matching TABLE using the LIKE operator.",
drh2ce15c32017-07-11 13:34:40 +00003930#ifdef SQLITE_ENABLE_IOTRACE
drh98aa2ab2018-09-26 16:53:51 +00003931 ".iotrace FILE Enable I/O diagnostic logging to FILE",
drh2ce15c32017-07-11 13:34:40 +00003932#endif
drh98aa2ab2018-09-26 16:53:51 +00003933 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
3934 ".lint OPTIONS Report potential schema issues.",
3935 " Options:",
3936 " fkey-indexes Find missing foreign key indexes",
drh2ce15c32017-07-11 13:34:40 +00003937#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh98aa2ab2018-09-26 16:53:51 +00003938 ".load FILE ?ENTRY? Load an extension library",
drh2ce15c32017-07-11 13:34:40 +00003939#endif
drh98aa2ab2018-09-26 16:53:51 +00003940 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
3941 ".mode MODE ?TABLE? Set output mode",
3942 " MODE is one of:",
drh7da29a32020-05-29 19:17:20 +00003943 " ascii Columns/rows delimited by 0x1F and 0x1E",
drh0908e382020-06-04 18:05:39 +00003944 " box Tables using unicode box-drawing characters",
drh7da29a32020-05-29 19:17:20 +00003945 " csv Comma-separated values",
3946 " column Output in columns. (See .width)",
3947 " html HTML <table> code",
3948 " insert SQL insert statements for TABLE",
3949 " json Results in a JSON array",
3950 " line One value per line",
3951 " list Values delimited by \"|\"",
3952 " markdown Markdown table format",
3953 " quote Escape answers as for SQL",
3954 " table ASCII-art table",
3955 " tabs Tab-separated values",
3956 " tcl TCL list elements",
drh98aa2ab2018-09-26 16:53:51 +00003957 ".nullvalue STRING Use STRING in place of NULL values",
drh7a431002020-04-18 14:12:00 +00003958 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
drh98aa2ab2018-09-26 16:53:51 +00003959 " If FILE begins with '|' then open as a pipe",
drh7a431002020-04-18 14:12:00 +00003960 " --bom Put a UTF8 byte-order mark at the beginning",
3961 " -e Send output to the system text editor",
3962 " -x Send output as CSV to a spreadsheet (same as \".excel\")",
drh4a3a3eb2020-02-29 15:53:48 +00003963#ifdef SQLITE_DEBUG
drhc0605082020-06-05 00:54:27 +00003964 ".oom ?--repeat M? ?N? Simulate an OOM error on the N-th allocation",
drh4a3a3eb2020-02-29 15:53:48 +00003965#endif
drh98aa2ab2018-09-26 16:53:51 +00003966 ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
3967 " Options:",
drh60f34ae2018-10-30 13:19:49 +00003968 " --append Use appendvfs to append database to the end of FILE",
drha751f392018-10-30 15:31:22 +00003969#ifdef SQLITE_ENABLE_DESERIALIZE
drh60f34ae2018-10-30 13:19:49 +00003970 " --deserialize Load into memory useing sqlite3_deserialize()",
drhe2754c12019-08-26 12:50:01 +00003971 " --hexdb Load the output of \"dbtotxt\" as an in-memory db",
drh6ca64482019-01-22 16:06:20 +00003972 " --maxsize N Maximum size for --hexdb or --deserialized database",
drha751f392018-10-30 15:31:22 +00003973#endif
drh60f34ae2018-10-30 13:19:49 +00003974 " --new Initialize FILE to an empty database",
drh0933aad2019-11-18 17:46:38 +00003975 " --nofollow Do not follow symbolic links",
drh60f34ae2018-10-30 13:19:49 +00003976 " --readonly Open FILE readonly",
3977 " --zip FILE is a ZIP archive",
drh98aa2ab2018-09-26 16:53:51 +00003978 ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
drh7a431002020-04-18 14:12:00 +00003979 " If FILE begins with '|' then open it as a pipe.",
3980 " Options:",
3981 " --bom Prefix output with a UTF8 byte-order mark",
3982 " -e Send output to the system text editor",
3983 " -x Send output as CSV to a spreadsheet",
drh9cb02642019-02-28 20:10:52 +00003984 ".parameter CMD ... Manage SQL parameter bindings",
3985 " clear Erase all bindings",
3986 " init Initialize the TEMP table that holds bindings",
3987 " list List the current parameter bindings",
3988 " set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE",
drhe2754c12019-08-26 12:50:01 +00003989 " PARAMETER should start with one of: $ : @ ?",
drh9cb02642019-02-28 20:10:52 +00003990 " unset PARAMETER Remove PARAMETER from the binding table",
drh98aa2ab2018-09-26 16:53:51 +00003991 ".print STRING... Print literal STRING",
drh569b1d92019-02-05 20:51:41 +00003992#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
drh3f83f592019-02-04 14:53:18 +00003993 ".progress N Invoke progress handler after every N opcodes",
3994 " --limit N Interrupt after N progress callbacks",
3995 " --once Do no more than one progress interrupt",
3996 " --quiet|-q No output except at interrupts",
3997 " --reset Reset the count for each input and interrupt",
drh569b1d92019-02-05 20:51:41 +00003998#endif
drh98aa2ab2018-09-26 16:53:51 +00003999 ".prompt MAIN CONTINUE Replace the standard prompts",
4000 ".quit Exit this program",
4001 ".read FILE Read input from FILE",
dan1b162162019-04-27 20:15:15 +00004002#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
dan42ebb012019-04-27 18:47:03 +00004003 ".recover Recover as much data as possible from corrupt db.",
drhe2754c12019-08-26 12:50:01 +00004004 " --freelist-corrupt Assume the freelist is corrupt",
4005 " --recovery-db NAME Store recovery metadata in database file NAME",
4006 " --lost-and-found TABLE Alternative name for the lost-and-found table",
dan8cce6b82019-09-14 16:44:51 +00004007 " --no-rowids Do not attempt to recover rowid values",
4008 " that are not also INTEGER PRIMARY KEYs",
dan1b162162019-04-27 20:15:15 +00004009#endif
drh98aa2ab2018-09-26 16:53:51 +00004010 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
4011 ".save FILE Write in-memory database into FILE",
4012 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
4013 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
drhbbb29ec2020-10-12 14:56:47 +00004014 " Options:",
4015 " --indent Try to pretty-print the schema",
4016 " --nosys Omit objects whose names start with \"sqlite_\"",
drheb7f2a02018-09-26 18:02:32 +00004017 ".selftest ?OPTIONS? Run tests defined in the SELFTEST table",
4018 " Options:",
4019 " --init Create a new SELFTEST table",
4020 " -v Verbose output",
drh98aa2ab2018-09-26 16:53:51 +00004021 ".separator COL ?ROW? Change the column and row separators",
drh2ce15c32017-07-11 13:34:40 +00004022#if defined(SQLITE_ENABLE_SESSION)
drheb7f2a02018-09-26 18:02:32 +00004023 ".session ?NAME? CMD ... Create or control sessions",
4024 " Subcommands:",
4025 " attach TABLE Attach TABLE",
4026 " changeset FILE Write a changeset into FILE",
4027 " close Close one session",
4028 " enable ?BOOLEAN? Set or query the enable bit",
4029 " filter GLOB... Reject tables matching GLOBs",
4030 " indirect ?BOOLEAN? Mark or query the indirect status",
4031 " isempty Query whether the session is empty",
4032 " list List currently open session names",
4033 " open DB NAME Open a new session on DB",
4034 " patchset FILE Write a patchset into FILE",
4035 " If ?NAME? is omitted, the first defined session is used.",
drh2ce15c32017-07-11 13:34:40 +00004036#endif
drheb7f2a02018-09-26 18:02:32 +00004037 ".sha3sum ... Compute a SHA3 hash of database content",
4038 " Options:",
drh067b92b2020-06-19 15:24:12 +00004039 " --schema Also hash the sqlite_schema table",
drheb7f2a02018-09-26 18:02:32 +00004040 " --sha3-224 Use the sha3-224 algorithm",
drhe2754c12019-08-26 12:50:01 +00004041 " --sha3-256 Use the sha3-256 algorithm (default)",
drheb7f2a02018-09-26 18:02:32 +00004042 " --sha3-384 Use the sha3-384 algorithm",
4043 " --sha3-512 Use the sha3-512 algorithm",
4044 " Any other argument is a LIKE pattern for tables to hash",
drh04a28c32018-01-31 01:38:44 +00004045#ifndef SQLITE_NOHAVE_SYSTEM
drh98aa2ab2018-09-26 16:53:51 +00004046 ".shell CMD ARGS... Run CMD ARGS... in a system shell",
drh04a28c32018-01-31 01:38:44 +00004047#endif
drh98aa2ab2018-09-26 16:53:51 +00004048 ".show Show the current values for various settings",
4049 ".stats ?on|off? Show stats or turn stats on or off",
drh04a28c32018-01-31 01:38:44 +00004050#ifndef SQLITE_NOHAVE_SYSTEM
drh98aa2ab2018-09-26 16:53:51 +00004051 ".system CMD ARGS... Run CMD ARGS... in a system shell",
drh04a28c32018-01-31 01:38:44 +00004052#endif
drh98aa2ab2018-09-26 16:53:51 +00004053 ".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
4054 ".testcase NAME Begin redirecting output to 'testcase-out.txt'",
drhd985f722019-06-05 14:29:53 +00004055 ".testctrl CMD ... Run various sqlite3_test_control() operations",
4056 " Run \".testctrl\" with no arguments for details",
drh98aa2ab2018-09-26 16:53:51 +00004057 ".timeout MS Try opening locked tables for MS milliseconds",
4058 ".timer on|off Turn SQL timer on or off",
drh707821f2018-12-05 13:39:06 +00004059#ifndef SQLITE_OMIT_TRACE
4060 ".trace ?OPTIONS? Output each SQL statement as it is run",
4061 " FILE Send output to FILE",
4062 " stdout Send output to stdout",
4063 " stderr Send output to stderr",
4064 " off Disable tracing",
4065 " --expanded Expand query parameters",
4066#ifdef SQLITE_ENABLE_NORMALIZE
4067 " --normalized Normal the SQL statements",
4068#endif
4069 " --plain Show SQL as it is input",
4070 " --stmt Trace statement execution (SQLITE_TRACE_STMT)",
4071 " --profile Profile statements (SQLITE_TRACE_PROFILE)",
4072 " --row Trace each row (SQLITE_TRACE_ROW)",
4073 " --close Trace connection close (SQLITE_TRACE_CLOSE)",
4074#endif /* SQLITE_OMIT_TRACE */
drhcc5979d2019-08-16 22:58:29 +00004075#ifdef SQLITE_DEBUG
4076 ".unmodule NAME ... Unregister virtual table modules",
drh5df84282019-08-17 19:45:25 +00004077 " --allexcept Unregister everything except those named",
drhcc5979d2019-08-16 22:58:29 +00004078#endif
drh98aa2ab2018-09-26 16:53:51 +00004079 ".vfsinfo ?AUX? Information about the top-level VFS",
4080 ".vfslist List all available VFSes",
4081 ".vfsname ?AUX? Print the name of the VFS stack",
drh7da29a32020-05-29 19:17:20 +00004082 ".width NUM1 NUM2 ... Set minimum column widths for columnar output",
drh98aa2ab2018-09-26 16:53:51 +00004083 " Negative values right-justify",
4084};
4085
4086/*
4087** Output help text.
4088**
4089** zPattern describes the set of commands for which help text is provided.
4090** If zPattern is NULL, then show all commands, but only give a one-line
4091** description of each.
4092**
4093** Return the number of matches.
4094*/
4095static int showHelp(FILE *out, const char *zPattern){
drhe93f8262018-10-11 16:53:37 +00004096 int i = 0;
4097 int j = 0;
drh98aa2ab2018-09-26 16:53:51 +00004098 int n = 0;
4099 char *zPat;
drh488cddf2018-10-06 14:38:17 +00004100 if( zPattern==0
4101 || zPattern[0]=='0'
4102 || strcmp(zPattern,"-a")==0
4103 || strcmp(zPattern,"-all")==0
drh7a431002020-04-18 14:12:00 +00004104 || strcmp(zPattern,"--all")==0
drh488cddf2018-10-06 14:38:17 +00004105 ){
drh98aa2ab2018-09-26 16:53:51 +00004106 /* Show all commands, but only one line per command */
drh488cddf2018-10-06 14:38:17 +00004107 if( zPattern==0 ) zPattern = "";
drh98aa2ab2018-09-26 16:53:51 +00004108 for(i=0; i<ArraySize(azHelp); i++){
drh488cddf2018-10-06 14:38:17 +00004109 if( azHelp[i][0]=='.' || zPattern[0] ){
drh98aa2ab2018-09-26 16:53:51 +00004110 utf8_printf(out, "%s\n", azHelp[i]);
4111 n++;
4112 }
4113 }
4114 }else{
4115 /* Look for commands that for which zPattern is an exact prefix */
4116 zPat = sqlite3_mprintf(".%s*", zPattern);
4117 for(i=0; i<ArraySize(azHelp); i++){
4118 if( sqlite3_strglob(zPat, azHelp[i])==0 ){
4119 utf8_printf(out, "%s\n", azHelp[i]);
drheb7f2a02018-09-26 18:02:32 +00004120 j = i+1;
drh98aa2ab2018-09-26 16:53:51 +00004121 n++;
4122 }
4123 }
4124 sqlite3_free(zPat);
drheb7f2a02018-09-26 18:02:32 +00004125 if( n ){
4126 if( n==1 ){
4127 /* when zPattern is a prefix of exactly one command, then include the
4128 ** details of that command, which should begin at offset j */
4129 while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
4130 utf8_printf(out, "%s\n", azHelp[j]);
4131 j++;
4132 }
4133 }
4134 return n;
4135 }
4136 /* Look for commands that contain zPattern anywhere. Show the complete
4137 ** text of all commands that match. */
drh98aa2ab2018-09-26 16:53:51 +00004138 zPat = sqlite3_mprintf("%%%s%%", zPattern);
4139 for(i=0; i<ArraySize(azHelp); i++){
4140 if( azHelp[i][0]=='.' ) j = i;
4141 if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
4142 utf8_printf(out, "%s\n", azHelp[j]);
4143 while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
4144 j++;
4145 utf8_printf(out, "%s\n", azHelp[j]);
4146 }
4147 i = j;
4148 n++;
4149 }
4150 }
4151 sqlite3_free(zPat);
4152 }
4153 return n;
4154}
drh2ce15c32017-07-11 13:34:40 +00004155
drh2ce15c32017-07-11 13:34:40 +00004156/* Forward reference */
drh60379d42018-12-13 18:30:01 +00004157static int process_input(ShellState *p);
drh2ce15c32017-07-11 13:34:40 +00004158
4159/*
4160** Read the content of file zName into memory obtained from sqlite3_malloc64()
4161** and return a pointer to the buffer. The caller is responsible for freeing
4162** the memory.
4163**
4164** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes
4165** read.
4166**
4167** For convenience, a nul-terminator byte is always appended to the data read
4168** from the file before the buffer is returned. This byte is not included in
4169** the final value of (*pnByte), if applicable.
4170**
4171** NULL is returned if any error is encountered. The final value of *pnByte
4172** is undefined in this case.
4173*/
4174static char *readFile(const char *zName, int *pnByte){
4175 FILE *in = fopen(zName, "rb");
4176 long nIn;
4177 size_t nRead;
4178 char *pBuf;
4179 if( in==0 ) return 0;
4180 fseek(in, 0, SEEK_END);
4181 nIn = ftell(in);
4182 rewind(in);
4183 pBuf = sqlite3_malloc64( nIn+1 );
drh1dbb1472018-10-11 10:37:24 +00004184 if( pBuf==0 ){ fclose(in); return 0; }
drh2ce15c32017-07-11 13:34:40 +00004185 nRead = fread(pBuf, nIn, 1, in);
4186 fclose(in);
4187 if( nRead!=1 ){
4188 sqlite3_free(pBuf);
4189 return 0;
4190 }
4191 pBuf[nIn] = 0;
4192 if( pnByte ) *pnByte = nIn;
4193 return pBuf;
4194}
4195
4196#if defined(SQLITE_ENABLE_SESSION)
4197/*
4198** Close a single OpenSession object and release all of its associated
4199** resources.
4200*/
4201static void session_close(OpenSession *pSession){
4202 int i;
4203 sqlite3session_delete(pSession->p);
4204 sqlite3_free(pSession->zName);
4205 for(i=0; i<pSession->nFilter; i++){
4206 sqlite3_free(pSession->azFilter[i]);
4207 }
4208 sqlite3_free(pSession->azFilter);
4209 memset(pSession, 0, sizeof(OpenSession));
4210}
4211#endif
4212
4213/*
4214** Close all OpenSession objects and release all associated resources.
4215*/
4216#if defined(SQLITE_ENABLE_SESSION)
4217static void session_close_all(ShellState *p){
4218 int i;
4219 for(i=0; i<p->nSession; i++){
4220 session_close(&p->aSession[i]);
4221 }
4222 p->nSession = 0;
4223}
4224#else
4225# define session_close_all(X)
4226#endif
4227
4228/*
4229** Implementation of the xFilter function for an open session. Omit
4230** any tables named by ".session filter" but let all other table through.
4231*/
4232#if defined(SQLITE_ENABLE_SESSION)
4233static int session_filter(void *pCtx, const char *zTab){
4234 OpenSession *pSession = (OpenSession*)pCtx;
4235 int i;
4236 for(i=0; i<pSession->nFilter; i++){
4237 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
4238 }
4239 return 1;
4240}
4241#endif
4242
4243/*
drh1fa6d9f2018-01-06 21:46:01 +00004244** Try to deduce the type of file for zName based on its content. Return
4245** one of the SHELL_OPEN_* constants.
drh1bf208c2018-03-09 21:54:01 +00004246**
4247** If the file does not exist or is empty but its name looks like a ZIP
4248** archive and the dfltZip flag is true, then assume it is a ZIP archive.
4249** Otherwise, assume an ordinary database regardless of the filename if
4250** the type cannot be determined from content.
drh1fa6d9f2018-01-06 21:46:01 +00004251*/
drhfc97c1c2018-05-14 00:41:12 +00004252int deduceDatabaseType(const char *zName, int dfltZip){
drh1fa6d9f2018-01-06 21:46:01 +00004253 FILE *f = fopen(zName, "rb");
4254 size_t n;
4255 int rc = SHELL_OPEN_UNSPEC;
4256 char zBuf[100];
drh1bf208c2018-03-09 21:54:01 +00004257 if( f==0 ){
drhbe4ccb22018-05-17 20:04:24 +00004258 if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
4259 return SHELL_OPEN_ZIPFILE;
4260 }else{
4261 return SHELL_OPEN_NORMAL;
4262 }
drh1bf208c2018-03-09 21:54:01 +00004263 }
drh2b3c4af2018-10-30 14:36:21 +00004264 n = fread(zBuf, 16, 1, f);
4265 if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
4266 fclose(f);
4267 return SHELL_OPEN_NORMAL;
4268 }
drh1fa6d9f2018-01-06 21:46:01 +00004269 fseek(f, -25, SEEK_END);
4270 n = fread(zBuf, 25, 1, f);
4271 if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
4272 rc = SHELL_OPEN_APPENDVFS;
4273 }else{
4274 fseek(f, -22, SEEK_END);
4275 n = fread(zBuf, 22, 1, f);
4276 if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05
4277 && zBuf[3]==0x06 ){
4278 rc = SHELL_OPEN_ZIPFILE;
drh1bf208c2018-03-09 21:54:01 +00004279 }else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
mistachkina3926f42018-05-14 12:23:04 +00004280 rc = SHELL_OPEN_ZIPFILE;
drh1fa6d9f2018-01-06 21:46:01 +00004281 }
4282 }
4283 fclose(f);
4284 return rc;
4285}
4286
drh33746482018-12-13 15:06:26 +00004287#ifdef SQLITE_ENABLE_DESERIALIZE
4288/*
4289** Reconstruct an in-memory database using the output from the "dbtotxt"
4290** program. Read content from the file in p->zDbFilename. If p->zDbFilename
4291** is 0, then read from standard input.
4292*/
4293static unsigned char *readHexDb(ShellState *p, int *pnData){
4294 unsigned char *a = 0;
drh2c8ee022018-12-13 18:59:30 +00004295 int nLine;
drh33746482018-12-13 15:06:26 +00004296 int n = 0;
4297 int pgsz = 0;
4298 int iOffset = 0;
4299 int j, k;
4300 int rc;
4301 FILE *in;
drh3ea557e2019-04-23 15:30:58 +00004302 unsigned int x[16];
drh2c8ee022018-12-13 18:59:30 +00004303 char zLine[1000];
drh33746482018-12-13 15:06:26 +00004304 if( p->zDbFilename ){
4305 in = fopen(p->zDbFilename, "r");
4306 if( in==0 ){
4307 utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename);
4308 return 0;
4309 }
drh2c8ee022018-12-13 18:59:30 +00004310 nLine = 0;
drh33746482018-12-13 15:06:26 +00004311 }else{
drh60379d42018-12-13 18:30:01 +00004312 in = p->in;
drh2c8ee022018-12-13 18:59:30 +00004313 nLine = p->lineno;
drh5bf46442019-05-03 02:41:36 +00004314 if( in==0 ) in = stdin;
drh33746482018-12-13 15:06:26 +00004315 }
4316 *pnData = 0;
drh2c8ee022018-12-13 18:59:30 +00004317 nLine++;
drh33746482018-12-13 15:06:26 +00004318 if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
4319 rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
4320 if( rc!=2 ) goto readHexDb_error;
drh68feae52019-05-09 11:18:41 +00004321 if( n<0 ) goto readHexDb_error;
drh09ea1252019-07-17 15:05:16 +00004322 if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error;
4323 n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */
drh68feae52019-05-09 11:18:41 +00004324 a = sqlite3_malloc( n ? n : 1 );
drh33746482018-12-13 15:06:26 +00004325 if( a==0 ){
4326 utf8_printf(stderr, "Out of memory!\n");
4327 goto readHexDb_error;
4328 }
4329 memset(a, 0, n);
4330 if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
4331 utf8_printf(stderr, "invalid pagesize\n");
4332 goto readHexDb_error;
4333 }
drh2c8ee022018-12-13 18:59:30 +00004334 for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){
drh33746482018-12-13 15:06:26 +00004335 rc = sscanf(zLine, "| page %d offset %d", &j, &k);
4336 if( rc==2 ){
4337 iOffset = k;
4338 continue;
4339 }
4340 if( strncmp(zLine, "| end ", 6)==0 ){
4341 break;
4342 }
drh3ea557e2019-04-23 15:30:58 +00004343 rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
drh33746482018-12-13 15:06:26 +00004344 &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
4345 &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
4346 if( rc==17 ){
4347 k = iOffset+j;
drhf354e772018-12-13 22:58:52 +00004348 if( k+16<=n ){
drh3ea557e2019-04-23 15:30:58 +00004349 int ii;
4350 for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
drh33746482018-12-13 15:06:26 +00004351 }
drh33746482018-12-13 15:06:26 +00004352 }
4353 }
4354 *pnData = n;
drh2c8ee022018-12-13 18:59:30 +00004355 if( in!=p->in ){
4356 fclose(in);
4357 }else{
4358 p->lineno = nLine;
4359 }
drh33746482018-12-13 15:06:26 +00004360 return a;
4361
4362readHexDb_error:
drh68feae52019-05-09 11:18:41 +00004363 if( in!=p->in ){
drh33746482018-12-13 15:06:26 +00004364 fclose(in);
4365 }else{
drh60379d42018-12-13 18:30:01 +00004366 while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
drh2c8ee022018-12-13 18:59:30 +00004367 nLine++;
drh33746482018-12-13 15:06:26 +00004368 if(strncmp(zLine, "| end ", 6)==0 ) break;
4369 }
drh2c8ee022018-12-13 18:59:30 +00004370 p->lineno = nLine;
drh33746482018-12-13 15:06:26 +00004371 }
4372 sqlite3_free(a);
4373 utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine);
4374 return 0;
4375}
4376#endif /* SQLITE_ENABLE_DESERIALIZE */
4377
danb1825882019-04-23 20:48:32 +00004378/*
dan9c014f82019-04-25 19:23:15 +00004379** Scalar function "shell_int32". The first argument to this function
4380** must be a blob. The second a non-negative integer. This function
4381** reads and returns a 32-bit big-endian integer from byte
4382** offset (4*<arg2>) of the blob.
4383*/
4384static void shellInt32(
4385 sqlite3_context *context,
4386 int argc,
4387 sqlite3_value **argv
4388){
4389 const unsigned char *pBlob;
4390 int nBlob;
4391 int iInt;
drh9546c762019-05-10 17:50:33 +00004392
4393 UNUSED_PARAMETER(argc);
dan9c014f82019-04-25 19:23:15 +00004394 nBlob = sqlite3_value_bytes(argv[0]);
4395 pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
4396 iInt = sqlite3_value_int(argv[1]);
4397
4398 if( iInt>=0 && (iInt+1)*4<=nBlob ){
4399 const unsigned char *a = &pBlob[iInt*4];
4400 sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24)
4401 + ((sqlite3_int64)a[1]<<16)
4402 + ((sqlite3_int64)a[2]<< 8)
4403 + ((sqlite3_int64)a[3]<< 0);
4404 sqlite3_result_int64(context, iVal);
4405 }
4406}
4407
4408/*
drha2de66c2019-08-06 20:26:17 +00004409** Scalar function "shell_idquote(X)" returns string X quoted as an identifier,
4410** using "..." with internal double-quote characters doubled.
4411*/
4412static void shellIdQuote(
4413 sqlite3_context *context,
4414 int argc,
4415 sqlite3_value **argv
4416){
4417 const char *zName = (const char*)sqlite3_value_text(argv[0]);
drh51755a72019-08-08 19:40:29 +00004418 UNUSED_PARAMETER(argc);
drha2de66c2019-08-06 20:26:17 +00004419 if( zName ){
4420 char *z = sqlite3_mprintf("\"%w\"", zName);
4421 sqlite3_result_text(context, z, -1, sqlite3_free);
4422 }
4423}
4424
4425/*
drhddcfe922020-09-15 12:29:35 +00004426** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X.
4427*/
4428static void shellUSleepFunc(
4429 sqlite3_context *context,
drhd36f5882020-11-25 16:28:04 +00004430 int argcUnused,
drhddcfe922020-09-15 12:29:35 +00004431 sqlite3_value **argv
4432){
4433 int sleep = sqlite3_value_int(argv[0]);
drhd36f5882020-11-25 16:28:04 +00004434 (void)argcUnused;
drhddcfe922020-09-15 12:29:35 +00004435 sqlite3_sleep(sleep/1000);
4436 sqlite3_result_int(context, sleep);
4437}
4438
4439/*
danb1825882019-04-23 20:48:32 +00004440** Scalar function "shell_escape_crnl" used by the .recover command.
4441** The argument passed to this function is the output of built-in
4442** function quote(). If the first character of the input is "'",
4443** indicating that the value passed to quote() was a text value,
4444** then this function searches the input for "\n" and "\r" characters
4445** and adds a wrapper similar to the following:
4446**
4447** replace(replace(<input>, '\n', char(10), '\r', char(13));
4448**
4449** Or, if the first character of the input is not "'", then a copy
4450** of the input is returned.
4451*/
4452static void shellEscapeCrnl(
4453 sqlite3_context *context,
4454 int argc,
4455 sqlite3_value **argv
4456){
4457 const char *zText = (const char*)sqlite3_value_text(argv[0]);
drh9546c762019-05-10 17:50:33 +00004458 UNUSED_PARAMETER(argc);
danb1825882019-04-23 20:48:32 +00004459 if( zText[0]=='\'' ){
4460 int nText = sqlite3_value_bytes(argv[0]);
4461 int i;
4462 char zBuf1[20];
4463 char zBuf2[20];
4464 const char *zNL = 0;
4465 const char *zCR = 0;
4466 int nCR = 0;
4467 int nNL = 0;
4468
4469 for(i=0; zText[i]; i++){
4470 if( zNL==0 && zText[i]=='\n' ){
4471 zNL = unused_string(zText, "\\n", "\\012", zBuf1);
4472 nNL = (int)strlen(zNL);
4473 }
4474 if( zCR==0 && zText[i]=='\r' ){
4475 zCR = unused_string(zText, "\\r", "\\015", zBuf2);
4476 nCR = (int)strlen(zCR);
4477 }
4478 }
4479
4480 if( zNL || zCR ){
4481 int iOut = 0;
4482 i64 nMax = (nNL > nCR) ? nNL : nCR;
dan51f5ffa2019-04-29 11:41:46 +00004483 i64 nAlloc = nMax * nText + (nMax+64)*2;
danb1825882019-04-23 20:48:32 +00004484 char *zOut = (char*)sqlite3_malloc64(nAlloc);
4485 if( zOut==0 ){
4486 sqlite3_result_error_nomem(context);
4487 return;
4488 }
4489
4490 if( zNL && zCR ){
4491 memcpy(&zOut[iOut], "replace(replace(", 16);
4492 iOut += 16;
4493 }else{
4494 memcpy(&zOut[iOut], "replace(", 8);
4495 iOut += 8;
4496 }
4497 for(i=0; zText[i]; i++){
4498 if( zText[i]=='\n' ){
4499 memcpy(&zOut[iOut], zNL, nNL);
4500 iOut += nNL;
4501 }else if( zText[i]=='\r' ){
4502 memcpy(&zOut[iOut], zCR, nCR);
4503 iOut += nCR;
4504 }else{
4505 zOut[iOut] = zText[i];
4506 iOut++;
4507 }
4508 }
4509
4510 if( zNL ){
4511 memcpy(&zOut[iOut], ",'", 2); iOut += 2;
4512 memcpy(&zOut[iOut], zNL, nNL); iOut += nNL;
4513 memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12;
4514 }
4515 if( zCR ){
4516 memcpy(&zOut[iOut], ",'", 2); iOut += 2;
4517 memcpy(&zOut[iOut], zCR, nCR); iOut += nCR;
4518 memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12;
4519 }
4520
4521 sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT);
4522 sqlite3_free(zOut);
4523 return;
4524 }
4525 }
4526
4527 sqlite3_result_value(context, argv[0]);
4528}
4529
drhbe4ccb22018-05-17 20:04:24 +00004530/* Flags for open_db().
4531**
4532** The default behavior of open_db() is to exit(1) if the database fails to
4533** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
4534** but still returns without calling exit.
4535**
4536** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a
4537** ZIP archive if the file does not exist or is empty and its name matches
4538** the *.zip pattern.
4539*/
4540#define OPEN_DB_KEEPALIVE 0x001 /* Return after error if true */
4541#define OPEN_DB_ZIPFILE 0x002 /* Open as ZIP if name matches *.zip */
4542
drh1fa6d9f2018-01-06 21:46:01 +00004543/*
drh2ce15c32017-07-11 13:34:40 +00004544** Make sure the database is open. If it is not, then open it. If
4545** the database fails to open, print an error message and exit.
4546*/
drhbe4ccb22018-05-17 20:04:24 +00004547static void open_db(ShellState *p, int openFlags){
drh2ce15c32017-07-11 13:34:40 +00004548 if( p->db==0 ){
drhf2072d12018-05-11 15:10:11 +00004549 if( p->openMode==SHELL_OPEN_UNSPEC ){
4550 if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){
4551 p->openMode = SHELL_OPEN_NORMAL;
drhbe4ccb22018-05-17 20:04:24 +00004552 }else{
4553 p->openMode = (u8)deduceDatabaseType(p->zDbFilename,
4554 (openFlags & OPEN_DB_ZIPFILE)!=0);
drhf2072d12018-05-11 15:10:11 +00004555 }
drh1fa6d9f2018-01-06 21:46:01 +00004556 }
4557 switch( p->openMode ){
4558 case SHELL_OPEN_APPENDVFS: {
4559 sqlite3_open_v2(p->zDbFilename, &p->db,
drh0933aad2019-11-18 17:46:38 +00004560 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs");
drh1fa6d9f2018-01-06 21:46:01 +00004561 break;
4562 }
drh33746482018-12-13 15:06:26 +00004563 case SHELL_OPEN_HEXDB:
drh60f34ae2018-10-30 13:19:49 +00004564 case SHELL_OPEN_DESERIALIZE: {
4565 sqlite3_open(0, &p->db);
4566 break;
4567 }
drh1fa6d9f2018-01-06 21:46:01 +00004568 case SHELL_OPEN_ZIPFILE: {
4569 sqlite3_open(":memory:", &p->db);
4570 break;
4571 }
drhee269a62018-02-14 23:27:43 +00004572 case SHELL_OPEN_READONLY: {
drh0933aad2019-11-18 17:46:38 +00004573 sqlite3_open_v2(p->zDbFilename, &p->db,
4574 SQLITE_OPEN_READONLY|p->openFlags, 0);
drhee269a62018-02-14 23:27:43 +00004575 break;
4576 }
drh1fa6d9f2018-01-06 21:46:01 +00004577 case SHELL_OPEN_UNSPEC:
4578 case SHELL_OPEN_NORMAL: {
drh0933aad2019-11-18 17:46:38 +00004579 sqlite3_open_v2(p->zDbFilename, &p->db,
4580 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
drh1fa6d9f2018-01-06 21:46:01 +00004581 break;
4582 }
4583 }
drh2ce15c32017-07-11 13:34:40 +00004584 globalDb = p->db;
4585 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
4586 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
4587 p->zDbFilename, sqlite3_errmsg(p->db));
drhf25cc4f2019-01-04 14:29:21 +00004588 if( openFlags & OPEN_DB_KEEPALIVE ){
4589 sqlite3_open(":memory:", &p->db);
4590 return;
4591 }
drh2ce15c32017-07-11 13:34:40 +00004592 exit(1);
4593 }
4594#ifndef SQLITE_OMIT_LOAD_EXTENSION
4595 sqlite3_enable_load_extension(p->db, 1);
4596#endif
4597 sqlite3_fileio_init(p->db, 0, 0);
4598 sqlite3_shathree_init(p->db, 0, 0);
drh56eb09b2017-07-11 13:59:07 +00004599 sqlite3_completion_init(p->db, 0, 0);
drhf05dd032020-04-14 15:53:58 +00004600 sqlite3_uint_init(p->db, 0, 0);
drhbeb9def2020-06-22 19:12:23 +00004601 sqlite3_decimal_init(p->db, 0, 0);
drh8cda77d2020-06-24 15:06:29 +00004602 sqlite3_ieee_init(p->db, 0, 0);
mistachkin72c38d82020-08-28 18:47:39 +00004603 sqlite3_series_init(p->db, 0, 0);
dan1b162162019-04-27 20:15:15 +00004604#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
dan68cb86e2019-04-20 20:57:28 +00004605 sqlite3_dbdata_init(p->db, 0, 0);
dan1b162162019-04-27 20:15:15 +00004606#endif
dan72afc3c2017-12-05 18:32:40 +00004607#ifdef SQLITE_HAVE_ZLIB
dan9ebfaad2017-12-26 20:39:58 +00004608 sqlite3_zipfile_init(p->db, 0, 0);
dand1b51d42017-12-16 19:11:26 +00004609 sqlite3_sqlar_init(p->db, 0, 0);
dan72afc3c2017-12-05 18:32:40 +00004610#endif
drhceba7922018-01-01 21:28:25 +00004611 sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
drh2ce15c32017-07-11 13:34:40 +00004612 shellAddSchemaName, 0, 0);
drh667a2a22018-01-02 00:04:37 +00004613 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
4614 shellModuleSchema, 0, 0);
drh634c70f2018-01-10 16:50:18 +00004615 sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
4616 shellPutsFunc, 0, 0);
danb1825882019-04-23 20:48:32 +00004617 sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0,
4618 shellEscapeCrnl, 0, 0);
dan9c014f82019-04-25 19:23:15 +00004619 sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0,
4620 shellInt32, 0, 0);
drha2de66c2019-08-06 20:26:17 +00004621 sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,
4622 shellIdQuote, 0, 0);
drhddcfe922020-09-15 12:29:35 +00004623 sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
4624 shellUSleepFunc, 0, 0);
drh04a28c32018-01-31 01:38:44 +00004625#ifndef SQLITE_NOHAVE_SYSTEM
drh97913132018-01-11 00:04:00 +00004626 sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
4627 editFunc, 0, 0);
4628 sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
4629 editFunc, 0, 0);
drh04a28c32018-01-31 01:38:44 +00004630#endif
drh1fa6d9f2018-01-06 21:46:01 +00004631 if( p->openMode==SHELL_OPEN_ZIPFILE ){
4632 char *zSql = sqlite3_mprintf(
4633 "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
4634 sqlite3_exec(p->db, zSql, 0, 0, 0);
4635 sqlite3_free(zSql);
drha751f392018-10-30 15:31:22 +00004636 }
4637#ifdef SQLITE_ENABLE_DESERIALIZE
drh33746482018-12-13 15:06:26 +00004638 else
4639 if( p->openMode==SHELL_OPEN_DESERIALIZE || p->openMode==SHELL_OPEN_HEXDB ){
mistachkin99490932018-12-17 22:19:57 +00004640 int rc;
drh60f34ae2018-10-30 13:19:49 +00004641 int nData = 0;
drh33746482018-12-13 15:06:26 +00004642 unsigned char *aData;
4643 if( p->openMode==SHELL_OPEN_DESERIALIZE ){
4644 aData = (unsigned char*)readFile(p->zDbFilename, &nData);
4645 }else{
4646 aData = readHexDb(p, &nData);
4647 if( aData==0 ){
drh33746482018-12-13 15:06:26 +00004648 return;
4649 }
4650 }
mistachkin99490932018-12-17 22:19:57 +00004651 rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
drh60f34ae2018-10-30 13:19:49 +00004652 SQLITE_DESERIALIZE_RESIZEABLE |
4653 SQLITE_DESERIALIZE_FREEONCLOSE);
4654 if( rc ){
4655 utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
4656 }
drh6ca64482019-01-22 16:06:20 +00004657 if( p->szMax>0 ){
4658 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax);
4659 }
drh1fa6d9f2018-01-06 21:46:01 +00004660 }
drha751f392018-10-30 15:31:22 +00004661#endif
drh2ce15c32017-07-11 13:34:40 +00004662 }
4663}
4664
drh9e804032018-05-18 17:11:50 +00004665/*
4666** Attempt to close the databaes connection. Report errors.
4667*/
4668void close_db(sqlite3 *db){
4669 int rc = sqlite3_close(db);
4670 if( rc ){
4671 utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n",
4672 rc, sqlite3_errmsg(db));
4673 }
4674}
4675
drh56eb09b2017-07-11 13:59:07 +00004676#if HAVE_READLINE || HAVE_EDITLINE
4677/*
4678** Readline completion callbacks
4679*/
4680static char *readline_completion_generator(const char *text, int state){
4681 static sqlite3_stmt *pStmt = 0;
4682 char *zRet;
4683 if( state==0 ){
4684 char *zSql;
drh56eb09b2017-07-11 13:59:07 +00004685 sqlite3_finalize(pStmt);
4686 zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
4687 " FROM completion(%Q) ORDER BY 1", text);
4688 sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
4689 sqlite3_free(zSql);
4690 }
4691 if( sqlite3_step(pStmt)==SQLITE_ROW ){
drh968d8712017-07-14 00:28:28 +00004692 zRet = strdup((const char*)sqlite3_column_text(pStmt, 0));
drh56eb09b2017-07-11 13:59:07 +00004693 }else{
4694 sqlite3_finalize(pStmt);
4695 pStmt = 0;
4696 zRet = 0;
4697 }
4698 return zRet;
4699}
4700static char **readline_completion(const char *zText, int iStart, int iEnd){
4701 rl_attempted_completion_over = 1;
4702 return rl_completion_matches(zText, readline_completion_generator);
4703}
4704
4705#elif HAVE_LINENOISE
4706/*
4707** Linenoise completion callback
4708*/
4709static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
drhaf2770f2018-01-05 14:55:43 +00004710 int nLine = strlen30(zLine);
drh56eb09b2017-07-11 13:59:07 +00004711 int i, iStart;
4712 sqlite3_stmt *pStmt = 0;
4713 char *zSql;
4714 char zBuf[1000];
4715
4716 if( nLine>sizeof(zBuf)-30 ) return;
drh1615c372018-05-12 23:56:22 +00004717 if( zLine[0]=='.' || zLine[0]=='#') return;
drh56eb09b2017-07-11 13:59:07 +00004718 for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
4719 if( i==nLine-1 ) return;
4720 iStart = i+1;
4721 memcpy(zBuf, zLine, iStart);
4722 zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
4723 " FROM completion(%Q,%Q) ORDER BY 1",
4724 &zLine[iStart], zLine);
4725 sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
4726 sqlite3_free(zSql);
4727 sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */
4728 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4729 const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0);
4730 int nCompletion = sqlite3_column_bytes(pStmt, 0);
4731 if( iStart+nCompletion < sizeof(zBuf)-1 ){
4732 memcpy(zBuf+iStart, zCompletion, nCompletion+1);
4733 linenoiseAddCompletion(lc, zBuf);
4734 }
4735 }
4736 sqlite3_finalize(pStmt);
4737}
4738#endif
4739
drh2ce15c32017-07-11 13:34:40 +00004740/*
4741** Do C-language style dequoting.
4742**
4743** \a -> alarm
4744** \b -> backspace
4745** \t -> tab
4746** \n -> newline
4747** \v -> vertical tab
4748** \f -> form feed
4749** \r -> carriage return
4750** \s -> space
4751** \" -> "
4752** \' -> '
4753** \\ -> backslash
4754** \NNN -> ascii character NNN in octal
4755*/
4756static void resolve_backslashes(char *z){
4757 int i, j;
4758 char c;
4759 while( *z && *z!='\\' ) z++;
4760 for(i=j=0; (c = z[i])!=0; i++, j++){
4761 if( c=='\\' && z[i+1]!=0 ){
4762 c = z[++i];
4763 if( c=='a' ){
4764 c = '\a';
4765 }else if( c=='b' ){
4766 c = '\b';
4767 }else if( c=='t' ){
4768 c = '\t';
4769 }else if( c=='n' ){
4770 c = '\n';
4771 }else if( c=='v' ){
4772 c = '\v';
4773 }else if( c=='f' ){
4774 c = '\f';
4775 }else if( c=='r' ){
4776 c = '\r';
4777 }else if( c=='"' ){
4778 c = '"';
4779 }else if( c=='\'' ){
4780 c = '\'';
4781 }else if( c=='\\' ){
4782 c = '\\';
4783 }else if( c>='0' && c<='7' ){
4784 c -= '0';
4785 if( z[i+1]>='0' && z[i+1]<='7' ){
4786 i++;
4787 c = (c<<3) + z[i] - '0';
4788 if( z[i+1]>='0' && z[i+1]<='7' ){
4789 i++;
4790 c = (c<<3) + z[i] - '0';
4791 }
4792 }
4793 }
4794 }
4795 z[j] = c;
4796 }
4797 if( j<i ) z[j] = 0;
4798}
4799
4800/*
drh2ce15c32017-07-11 13:34:40 +00004801** Interpret zArg as either an integer or a boolean value. Return 1 or 0
4802** for TRUE and FALSE. Return the integer value if appropriate.
4803*/
4804static int booleanValue(const char *zArg){
4805 int i;
4806 if( zArg[0]=='0' && zArg[1]=='x' ){
4807 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
4808 }else{
4809 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
4810 }
4811 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
4812 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
4813 return 1;
4814 }
4815 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
4816 return 0;
4817 }
4818 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
4819 zArg);
4820 return 0;
4821}
4822
4823/*
4824** Set or clear a shell flag according to a boolean value.
4825*/
4826static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){
4827 if( booleanValue(zArg) ){
4828 ShellSetFlag(p, mFlag);
4829 }else{
4830 ShellClearFlag(p, mFlag);
4831 }
4832}
4833
4834/*
4835** Close an output file, assuming it is not stderr or stdout
4836*/
4837static void output_file_close(FILE *f){
4838 if( f && f!=stdout && f!=stderr ) fclose(f);
4839}
4840
4841/*
4842** Try to open an output file. The names "stdout" and "stderr" are
4843** recognized and do the right thing. NULL is returned if the output
4844** filename is "off".
4845*/
drha92a01a2018-01-10 22:15:37 +00004846static FILE *output_file_open(const char *zFile, int bTextMode){
drh2ce15c32017-07-11 13:34:40 +00004847 FILE *f;
4848 if( strcmp(zFile,"stdout")==0 ){
4849 f = stdout;
4850 }else if( strcmp(zFile, "stderr")==0 ){
4851 f = stderr;
4852 }else if( strcmp(zFile, "off")==0 ){
4853 f = 0;
4854 }else{
drha92a01a2018-01-10 22:15:37 +00004855 f = fopen(zFile, bTextMode ? "w" : "wb");
drh2ce15c32017-07-11 13:34:40 +00004856 if( f==0 ){
4857 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
4858 }
4859 }
4860 return f;
4861}
4862
drh707821f2018-12-05 13:39:06 +00004863#ifndef SQLITE_OMIT_TRACE
drh2ce15c32017-07-11 13:34:40 +00004864/*
4865** A routine for handling output from sqlite3_trace().
4866*/
4867static int sql_trace_callback(
drh707821f2018-12-05 13:39:06 +00004868 unsigned mType, /* The trace type */
4869 void *pArg, /* The ShellState pointer */
4870 void *pP, /* Usually a pointer to sqlite_stmt */
4871 void *pX /* Auxiliary output */
drh2ce15c32017-07-11 13:34:40 +00004872){
drh707821f2018-12-05 13:39:06 +00004873 ShellState *p = (ShellState*)pArg;
4874 sqlite3_stmt *pStmt;
4875 const char *zSql;
4876 int nSql;
4877 if( p->traceOut==0 ) return 0;
4878 if( mType==SQLITE_TRACE_CLOSE ){
4879 utf8_printf(p->traceOut, "-- closing database connection\n");
4880 return 0;
4881 }
4882 if( mType!=SQLITE_TRACE_ROW && ((const char*)pX)[0]=='-' ){
4883 zSql = (const char*)pX;
4884 }else{
4885 pStmt = (sqlite3_stmt*)pP;
4886 switch( p->eTraceType ){
4887 case SHELL_TRACE_EXPANDED: {
4888 zSql = sqlite3_expanded_sql(pStmt);
4889 break;
4890 }
4891#ifdef SQLITE_ENABLE_NORMALIZE
4892 case SHELL_TRACE_NORMALIZED: {
4893 zSql = sqlite3_normalized_sql(pStmt);
4894 break;
4895 }
4896#endif
4897 default: {
4898 zSql = sqlite3_sql(pStmt);
4899 break;
4900 }
4901 }
4902 }
4903 if( zSql==0 ) return 0;
4904 nSql = strlen30(zSql);
4905 while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; }
4906 switch( mType ){
4907 case SQLITE_TRACE_ROW:
4908 case SQLITE_TRACE_STMT: {
4909 utf8_printf(p->traceOut, "%.*s;\n", nSql, zSql);
4910 break;
4911 }
4912 case SQLITE_TRACE_PROFILE: {
4913 sqlite3_int64 nNanosec = *(sqlite3_int64*)pX;
4914 utf8_printf(p->traceOut, "%.*s; -- %lld ns\n", nSql, zSql, nNanosec);
4915 break;
4916 }
drh2ce15c32017-07-11 13:34:40 +00004917 }
4918 return 0;
4919}
4920#endif
drh2ce15c32017-07-11 13:34:40 +00004921
4922/*
4923** A no-op routine that runs with the ".breakpoint" doc-command. This is
4924** a useful spot to set a debugger breakpoint.
4925*/
4926static void test_breakpoint(void){
4927 static int nCall = 0;
4928 nCall++;
4929}
4930
4931/*
4932** An object used to read a CSV and other files for import.
4933*/
4934typedef struct ImportCtx ImportCtx;
4935struct ImportCtx {
4936 const char *zFile; /* Name of the input file */
4937 FILE *in; /* Read the CSV text from this input stream */
drh97767842020-05-29 19:39:35 +00004938 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close in */
drh2ce15c32017-07-11 13:34:40 +00004939 char *z; /* Accumulated text for a field */
4940 int n; /* Number of bytes in z */
4941 int nAlloc; /* Space allocated for z[] */
4942 int nLine; /* Current line number */
drhccb37812020-03-09 15:39:39 +00004943 int nRow; /* Number of rows imported */
4944 int nErr; /* Number of errors encountered */
drh2ce15c32017-07-11 13:34:40 +00004945 int bNotFirst; /* True if one or more bytes already read */
4946 int cTerm; /* Character that terminated the most recent field */
4947 int cColSep; /* The column separator character. (Usually ",") */
4948 int cRowSep; /* The row separator character. (Usually "\n") */
4949};
4950
drh97767842020-05-29 19:39:35 +00004951/* Clean up resourced used by an ImportCtx */
4952static void import_cleanup(ImportCtx *p){
drh42c2a042020-05-29 20:16:19 +00004953 if( p->in!=0 && p->xCloser!=0 ){
drh97767842020-05-29 19:39:35 +00004954 p->xCloser(p->in);
4955 p->in = 0;
4956 }
4957 sqlite3_free(p->z);
4958 p->z = 0;
4959}
4960
drh2ce15c32017-07-11 13:34:40 +00004961/* Append a single byte to z[] */
4962static void import_append_char(ImportCtx *p, int c){
4963 if( p->n+1>=p->nAlloc ){
4964 p->nAlloc += p->nAlloc + 100;
4965 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drh4b5345c2018-04-24 13:07:40 +00004966 if( p->z==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00004967 }
4968 p->z[p->n++] = (char)c;
4969}
4970
4971/* Read a single field of CSV text. Compatible with rfc4180 and extended
4972** with the option of having a separator other than ",".
4973**
4974** + Input comes from p->in.
4975** + Store results in p->z of length p->n. Space to hold p->z comes
4976** from sqlite3_malloc64().
4977** + Use p->cSep as the column separator. The default is ",".
4978** + Use p->rSep as the row separator. The default is "\n".
4979** + Keep track of the line number in p->nLine.
4980** + Store the character that terminates the field in p->cTerm. Store
4981** EOF on end-of-file.
4982** + Report syntax errors on stderr
4983*/
4984static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
4985 int c;
4986 int cSep = p->cColSep;
4987 int rSep = p->cRowSep;
4988 p->n = 0;
4989 c = fgetc(p->in);
4990 if( c==EOF || seenInterrupt ){
4991 p->cTerm = EOF;
4992 return 0;
4993 }
4994 if( c=='"' ){
4995 int pc, ppc;
4996 int startLine = p->nLine;
4997 int cQuote = c;
4998 pc = ppc = 0;
4999 while( 1 ){
5000 c = fgetc(p->in);
5001 if( c==rSep ) p->nLine++;
5002 if( c==cQuote ){
5003 if( pc==cQuote ){
5004 pc = 0;
5005 continue;
5006 }
5007 }
5008 if( (c==cSep && pc==cQuote)
5009 || (c==rSep && pc==cQuote)
5010 || (c==rSep && pc=='\r' && ppc==cQuote)
5011 || (c==EOF && pc==cQuote)
5012 ){
5013 do{ p->n--; }while( p->z[p->n]!=cQuote );
5014 p->cTerm = c;
5015 break;
5016 }
5017 if( pc==cQuote && c!='\r' ){
5018 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
5019 p->zFile, p->nLine, cQuote);
5020 }
5021 if( c==EOF ){
5022 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
5023 p->zFile, startLine, cQuote);
5024 p->cTerm = c;
5025 break;
5026 }
5027 import_append_char(p, c);
5028 ppc = pc;
5029 pc = c;
5030 }
5031 }else{
5032 /* If this is the first field being parsed and it begins with the
5033 ** UTF-8 BOM (0xEF BB BF) then skip the BOM */
5034 if( (c&0xff)==0xef && p->bNotFirst==0 ){
5035 import_append_char(p, c);
5036 c = fgetc(p->in);
5037 if( (c&0xff)==0xbb ){
5038 import_append_char(p, c);
5039 c = fgetc(p->in);
5040 if( (c&0xff)==0xbf ){
5041 p->bNotFirst = 1;
5042 p->n = 0;
5043 return csv_read_one_field(p);
5044 }
5045 }
5046 }
5047 while( c!=EOF && c!=cSep && c!=rSep ){
5048 import_append_char(p, c);
5049 c = fgetc(p->in);
5050 }
5051 if( c==rSep ){
5052 p->nLine++;
5053 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
5054 }
5055 p->cTerm = c;
5056 }
5057 if( p->z ) p->z[p->n] = 0;
5058 p->bNotFirst = 1;
5059 return p->z;
5060}
5061
5062/* Read a single field of ASCII delimited text.
5063**
5064** + Input comes from p->in.
5065** + Store results in p->z of length p->n. Space to hold p->z comes
5066** from sqlite3_malloc64().
5067** + Use p->cSep as the column separator. The default is "\x1F".
5068** + Use p->rSep as the row separator. The default is "\x1E".
5069** + Keep track of the row number in p->nLine.
5070** + Store the character that terminates the field in p->cTerm. Store
5071** EOF on end-of-file.
5072** + Report syntax errors on stderr
5073*/
5074static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
5075 int c;
5076 int cSep = p->cColSep;
5077 int rSep = p->cRowSep;
5078 p->n = 0;
5079 c = fgetc(p->in);
5080 if( c==EOF || seenInterrupt ){
5081 p->cTerm = EOF;
5082 return 0;
5083 }
5084 while( c!=EOF && c!=cSep && c!=rSep ){
5085 import_append_char(p, c);
5086 c = fgetc(p->in);
5087 }
5088 if( c==rSep ){
5089 p->nLine++;
5090 }
5091 p->cTerm = c;
5092 if( p->z ) p->z[p->n] = 0;
5093 return p->z;
5094}
5095
5096/*
5097** Try to transfer data for table zTable. If an error is seen while
5098** moving forward, try to go backwards. The backwards movement won't
5099** work for WITHOUT ROWID tables.
5100*/
5101static void tryToCloneData(
5102 ShellState *p,
5103 sqlite3 *newDb,
5104 const char *zTable
5105){
5106 sqlite3_stmt *pQuery = 0;
5107 sqlite3_stmt *pInsert = 0;
5108 char *zQuery = 0;
5109 char *zInsert = 0;
5110 int rc;
5111 int i, j, n;
drhaf2770f2018-01-05 14:55:43 +00005112 int nTable = strlen30(zTable);
drh2ce15c32017-07-11 13:34:40 +00005113 int k = 0;
5114 int cnt = 0;
5115 const int spinRate = 10000;
5116
5117 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
5118 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
5119 if( rc ){
5120 utf8_printf(stderr, "Error %d: %s on [%s]\n",
5121 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
5122 zQuery);
5123 goto end_data_xfer;
5124 }
5125 n = sqlite3_column_count(pQuery);
5126 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh4b5345c2018-04-24 13:07:40 +00005127 if( zInsert==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00005128 sqlite3_snprintf(200+nTable,zInsert,
5129 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
drhaf2770f2018-01-05 14:55:43 +00005130 i = strlen30(zInsert);
drh2ce15c32017-07-11 13:34:40 +00005131 for(j=1; j<n; j++){
5132 memcpy(zInsert+i, ",?", 2);
5133 i += 2;
5134 }
5135 memcpy(zInsert+i, ");", 3);
5136 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
5137 if( rc ){
5138 utf8_printf(stderr, "Error %d: %s on [%s]\n",
5139 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
5140 zQuery);
5141 goto end_data_xfer;
5142 }
5143 for(k=0; k<2; k++){
5144 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
5145 for(i=0; i<n; i++){
5146 switch( sqlite3_column_type(pQuery, i) ){
5147 case SQLITE_NULL: {
5148 sqlite3_bind_null(pInsert, i+1);
5149 break;
5150 }
5151 case SQLITE_INTEGER: {
5152 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
5153 break;
5154 }
5155 case SQLITE_FLOAT: {
5156 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
5157 break;
5158 }
5159 case SQLITE_TEXT: {
5160 sqlite3_bind_text(pInsert, i+1,
5161 (const char*)sqlite3_column_text(pQuery,i),
5162 -1, SQLITE_STATIC);
5163 break;
5164 }
5165 case SQLITE_BLOB: {
5166 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
5167 sqlite3_column_bytes(pQuery,i),
5168 SQLITE_STATIC);
5169 break;
5170 }
5171 }
5172 } /* End for */
5173 rc = sqlite3_step(pInsert);
5174 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
5175 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
5176 sqlite3_errmsg(newDb));
5177 }
5178 sqlite3_reset(pInsert);
5179 cnt++;
5180 if( (cnt%spinRate)==0 ){
5181 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
5182 fflush(stdout);
5183 }
5184 } /* End while */
5185 if( rc==SQLITE_DONE ) break;
5186 sqlite3_finalize(pQuery);
5187 sqlite3_free(zQuery);
5188 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
5189 zTable);
5190 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
5191 if( rc ){
5192 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
5193 break;
5194 }
5195 } /* End for(k=0...) */
5196
5197end_data_xfer:
5198 sqlite3_finalize(pQuery);
5199 sqlite3_finalize(pInsert);
5200 sqlite3_free(zQuery);
5201 sqlite3_free(zInsert);
5202}
5203
5204
5205/*
5206** Try to transfer all rows of the schema that match zWhere. For
5207** each row, invoke xForEach() on the object defined by that row.
5208** If an error is encountered while moving forward through the
drh067b92b2020-06-19 15:24:12 +00005209** sqlite_schema table, try again moving backwards.
drh2ce15c32017-07-11 13:34:40 +00005210*/
5211static void tryToCloneSchema(
5212 ShellState *p,
5213 sqlite3 *newDb,
5214 const char *zWhere,
5215 void (*xForEach)(ShellState*,sqlite3*,const char*)
5216){
5217 sqlite3_stmt *pQuery = 0;
5218 char *zQuery = 0;
5219 int rc;
5220 const unsigned char *zName;
5221 const unsigned char *zSql;
5222 char *zErrMsg = 0;
5223
drh067b92b2020-06-19 15:24:12 +00005224 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00005225 " WHERE %s", zWhere);
5226 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
5227 if( rc ){
5228 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
5229 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
5230 zQuery);
5231 goto end_schema_xfer;
5232 }
5233 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
5234 zName = sqlite3_column_text(pQuery, 0);
5235 zSql = sqlite3_column_text(pQuery, 1);
5236 printf("%s... ", zName); fflush(stdout);
5237 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
5238 if( zErrMsg ){
5239 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
5240 sqlite3_free(zErrMsg);
5241 zErrMsg = 0;
5242 }
5243 if( xForEach ){
5244 xForEach(p, newDb, (const char*)zName);
5245 }
5246 printf("done\n");
5247 }
5248 if( rc!=SQLITE_DONE ){
5249 sqlite3_finalize(pQuery);
5250 sqlite3_free(zQuery);
drh067b92b2020-06-19 15:24:12 +00005251 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00005252 " WHERE %s ORDER BY rowid DESC", zWhere);
5253 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
5254 if( rc ){
5255 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
5256 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
5257 zQuery);
5258 goto end_schema_xfer;
5259 }
5260 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
5261 zName = sqlite3_column_text(pQuery, 0);
5262 zSql = sqlite3_column_text(pQuery, 1);
5263 printf("%s... ", zName); fflush(stdout);
5264 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
5265 if( zErrMsg ){
5266 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
5267 sqlite3_free(zErrMsg);
5268 zErrMsg = 0;
5269 }
5270 if( xForEach ){
5271 xForEach(p, newDb, (const char*)zName);
5272 }
5273 printf("done\n");
5274 }
5275 }
5276end_schema_xfer:
5277 sqlite3_finalize(pQuery);
5278 sqlite3_free(zQuery);
5279}
5280
5281/*
5282** Open a new database file named "zNewDb". Try to recover as much information
5283** as possible out of the main database (which might be corrupt) and write it
5284** into zNewDb.
5285*/
5286static void tryToClone(ShellState *p, const char *zNewDb){
5287 int rc;
5288 sqlite3 *newDb = 0;
5289 if( access(zNewDb,0)==0 ){
5290 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
5291 return;
5292 }
5293 rc = sqlite3_open(zNewDb, &newDb);
5294 if( rc ){
5295 utf8_printf(stderr, "Cannot create output database: %s\n",
5296 sqlite3_errmsg(newDb));
5297 }else{
5298 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
5299 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
5300 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
5301 tryToCloneSchema(p, newDb, "type!='table'", 0);
5302 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
5303 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
5304 }
drh9e804032018-05-18 17:11:50 +00005305 close_db(newDb);
drh2ce15c32017-07-11 13:34:40 +00005306}
5307
5308/*
drh13c20932018-01-10 21:41:55 +00005309** Change the output file back to stdout.
5310**
5311** If the p->doXdgOpen flag is set, that means the output was being
5312** redirected to a temporary file named by p->zTempFile. In that case,
5313** launch start/open/xdg-open on that temporary file.
drh2ce15c32017-07-11 13:34:40 +00005314*/
5315static void output_reset(ShellState *p){
5316 if( p->outfile[0]=='|' ){
5317#ifndef SQLITE_OMIT_POPEN
5318 pclose(p->out);
5319#endif
5320 }else{
5321 output_file_close(p->out);
drh04a28c32018-01-31 01:38:44 +00005322#ifndef SQLITE_NOHAVE_SYSTEM
drh13c20932018-01-10 21:41:55 +00005323 if( p->doXdgOpen ){
5324 const char *zXdgOpenCmd =
5325#if defined(_WIN32)
5326 "start";
5327#elif defined(__APPLE__)
5328 "open";
5329#else
5330 "xdg-open";
5331#endif
5332 char *zCmd;
5333 zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
drha92a01a2018-01-10 22:15:37 +00005334 if( system(zCmd) ){
5335 utf8_printf(stderr, "Failed: [%s]\n", zCmd);
drh1d9ea272020-04-17 23:46:54 +00005336 }else{
5337 /* Give the start/open/xdg-open command some time to get
5338 ** going before we continue, and potential delete the
5339 ** p->zTempFile data file out from under it */
5340 sqlite3_sleep(2000);
drha92a01a2018-01-10 22:15:37 +00005341 }
drh13c20932018-01-10 21:41:55 +00005342 sqlite3_free(zCmd);
drh3c484e82018-01-10 22:27:21 +00005343 outputModePop(p);
drh13c20932018-01-10 21:41:55 +00005344 p->doXdgOpen = 0;
5345 }
drh04a28c32018-01-31 01:38:44 +00005346#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
drh2ce15c32017-07-11 13:34:40 +00005347 }
5348 p->outfile[0] = 0;
5349 p->out = stdout;
5350}
5351
5352/*
5353** Run an SQL command and return the single integer result.
5354*/
5355static int db_int(ShellState *p, const char *zSql){
5356 sqlite3_stmt *pStmt;
5357 int res = 0;
5358 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
5359 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
5360 res = sqlite3_column_int(pStmt,0);
5361 }
5362 sqlite3_finalize(pStmt);
5363 return res;
5364}
5365
5366/*
5367** Convert a 2-byte or 4-byte big-endian integer into a native integer
5368*/
5369static unsigned int get2byteInt(unsigned char *a){
5370 return (a[0]<<8) + a[1];
5371}
5372static unsigned int get4byteInt(unsigned char *a){
5373 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
5374}
5375
5376/*
drh76c12062020-01-14 13:13:19 +00005377** Implementation of the ".dbinfo" command.
drh2ce15c32017-07-11 13:34:40 +00005378**
5379** Return 1 on error, 2 to exit, and 0 otherwise.
5380*/
5381static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
5382 static const struct { const char *zName; int ofst; } aField[] = {
5383 { "file change counter:", 24 },
5384 { "database page count:", 28 },
5385 { "freelist page count:", 36 },
5386 { "schema cookie:", 40 },
5387 { "schema format:", 44 },
5388 { "default cache size:", 48 },
5389 { "autovacuum top root:", 52 },
5390 { "incremental vacuum:", 64 },
5391 { "text encoding:", 56 },
5392 { "user version:", 60 },
5393 { "application id:", 68 },
5394 { "software version:", 96 },
5395 };
5396 static const struct { const char *zName; const char *zSql; } aQuery[] = {
5397 { "number of tables:",
5398 "SELECT count(*) FROM %s WHERE type='table'" },
5399 { "number of indexes:",
5400 "SELECT count(*) FROM %s WHERE type='index'" },
5401 { "number of triggers:",
5402 "SELECT count(*) FROM %s WHERE type='trigger'" },
5403 { "number of views:",
5404 "SELECT count(*) FROM %s WHERE type='view'" },
5405 { "schema size:",
5406 "SELECT total(length(sql)) FROM %s" },
5407 };
drh87c889c2019-03-20 18:22:51 +00005408 int i, rc;
drhea99a312018-07-18 19:09:07 +00005409 unsigned iDataVersion;
drh2ce15c32017-07-11 13:34:40 +00005410 char *zSchemaTab;
5411 char *zDb = nArg>=2 ? azArg[1] : "main";
drh512e6c32017-10-11 17:51:08 +00005412 sqlite3_stmt *pStmt = 0;
drh2ce15c32017-07-11 13:34:40 +00005413 unsigned char aHdr[100];
5414 open_db(p, 0);
5415 if( p->db==0 ) return 1;
drh87c889c2019-03-20 18:22:51 +00005416 rc = sqlite3_prepare_v2(p->db,
5417 "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
5418 -1, &pStmt, 0);
5419 if( rc ){
drh451f89a2020-04-28 23:09:56 +00005420 utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
drh87c889c2019-03-20 18:22:51 +00005421 sqlite3_finalize(pStmt);
5422 return 1;
5423 }
drh512e6c32017-10-11 17:51:08 +00005424 sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
5425 if( sqlite3_step(pStmt)==SQLITE_ROW
5426 && sqlite3_column_bytes(pStmt,0)>100
5427 ){
5428 memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100);
5429 sqlite3_finalize(pStmt);
5430 }else{
drh2ce15c32017-07-11 13:34:40 +00005431 raw_printf(stderr, "unable to read database header\n");
drh512e6c32017-10-11 17:51:08 +00005432 sqlite3_finalize(pStmt);
drh2ce15c32017-07-11 13:34:40 +00005433 return 1;
5434 }
5435 i = get2byteInt(aHdr+16);
5436 if( i==1 ) i = 65536;
5437 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
5438 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
5439 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
5440 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
5441 for(i=0; i<ArraySize(aField); i++){
5442 int ofst = aField[i].ofst;
5443 unsigned int val = get4byteInt(aHdr + ofst);
5444 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
5445 switch( ofst ){
5446 case 56: {
5447 if( val==1 ) raw_printf(p->out, " (utf8)");
5448 if( val==2 ) raw_printf(p->out, " (utf16le)");
5449 if( val==3 ) raw_printf(p->out, " (utf16be)");
5450 }
5451 }
5452 raw_printf(p->out, "\n");
5453 }
5454 if( zDb==0 ){
drh067b92b2020-06-19 15:24:12 +00005455 zSchemaTab = sqlite3_mprintf("main.sqlite_schema");
drh2ce15c32017-07-11 13:34:40 +00005456 }else if( strcmp(zDb,"temp")==0 ){
drh067b92b2020-06-19 15:24:12 +00005457 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
drh2ce15c32017-07-11 13:34:40 +00005458 }else{
drh067b92b2020-06-19 15:24:12 +00005459 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
drh2ce15c32017-07-11 13:34:40 +00005460 }
5461 for(i=0; i<ArraySize(aQuery); i++){
5462 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
5463 int val = db_int(p, zSql);
5464 sqlite3_free(zSql);
5465 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
5466 }
5467 sqlite3_free(zSchemaTab);
drhea99a312018-07-18 19:09:07 +00005468 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
5469 utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
drh2ce15c32017-07-11 13:34:40 +00005470 return 0;
5471}
5472
5473/*
5474** Print the current sqlite3_errmsg() value to stderr and return 1.
5475*/
5476static int shellDatabaseError(sqlite3 *db){
5477 const char *zErr = sqlite3_errmsg(db);
5478 utf8_printf(stderr, "Error: %s\n", zErr);
5479 return 1;
5480}
5481
5482/*
drh2ce15c32017-07-11 13:34:40 +00005483** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
5484** if they match and FALSE (0) if they do not match.
5485**
5486** Globbing rules:
5487**
5488** '*' Matches any sequence of zero or more characters.
5489**
5490** '?' Matches exactly one character.
5491**
5492** [...] Matches one character from the enclosed list of
5493** characters.
5494**
5495** [^...] Matches one character not in the enclosed list.
5496**
5497** '#' Matches any sequence of one or more digits with an
5498** optional + or - sign in front
5499**
5500** ' ' Any span of whitespace matches any other span of
5501** whitespace.
5502**
5503** Extra whitespace at the end of z[] is ignored.
5504*/
5505static int testcase_glob(const char *zGlob, const char *z){
5506 int c, c2;
5507 int invert;
5508 int seen;
5509
5510 while( (c = (*(zGlob++)))!=0 ){
5511 if( IsSpace(c) ){
5512 if( !IsSpace(*z) ) return 0;
5513 while( IsSpace(*zGlob) ) zGlob++;
5514 while( IsSpace(*z) ) z++;
5515 }else if( c=='*' ){
5516 while( (c=(*(zGlob++))) == '*' || c=='?' ){
5517 if( c=='?' && (*(z++))==0 ) return 0;
5518 }
5519 if( c==0 ){
5520 return 1;
5521 }else if( c=='[' ){
5522 while( *z && testcase_glob(zGlob-1,z)==0 ){
5523 z++;
5524 }
5525 return (*z)!=0;
5526 }
5527 while( (c2 = (*(z++)))!=0 ){
5528 while( c2!=c ){
5529 c2 = *(z++);
5530 if( c2==0 ) return 0;
5531 }
5532 if( testcase_glob(zGlob,z) ) return 1;
5533 }
5534 return 0;
5535 }else if( c=='?' ){
5536 if( (*(z++))==0 ) return 0;
5537 }else if( c=='[' ){
5538 int prior_c = 0;
5539 seen = 0;
5540 invert = 0;
5541 c = *(z++);
5542 if( c==0 ) return 0;
5543 c2 = *(zGlob++);
5544 if( c2=='^' ){
5545 invert = 1;
5546 c2 = *(zGlob++);
5547 }
5548 if( c2==']' ){
5549 if( c==']' ) seen = 1;
5550 c2 = *(zGlob++);
5551 }
5552 while( c2 && c2!=']' ){
5553 if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
5554 c2 = *(zGlob++);
5555 if( c>=prior_c && c<=c2 ) seen = 1;
5556 prior_c = 0;
5557 }else{
5558 if( c==c2 ){
5559 seen = 1;
5560 }
5561 prior_c = c2;
5562 }
5563 c2 = *(zGlob++);
5564 }
5565 if( c2==0 || (seen ^ invert)==0 ) return 0;
5566 }else if( c=='#' ){
5567 if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
5568 if( !IsDigit(z[0]) ) return 0;
5569 z++;
5570 while( IsDigit(z[0]) ){ z++; }
5571 }else{
5572 if( c!=(*(z++)) ) return 0;
5573 }
5574 }
5575 while( IsSpace(*z) ){ z++; }
5576 return *z==0;
5577}
5578
5579
5580/*
5581** Compare the string as a command-line option with either one or two
5582** initial "-" characters.
5583*/
5584static int optionMatch(const char *zStr, const char *zOpt){
5585 if( zStr[0]!='-' ) return 0;
5586 zStr++;
5587 if( zStr[0]=='-' ) zStr++;
5588 return strcmp(zStr, zOpt)==0;
5589}
5590
5591/*
5592** Delete a file.
5593*/
5594int shellDeleteFile(const char *zFilename){
5595 int rc;
5596#ifdef _WIN32
5597 wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
5598 rc = _wunlink(z);
5599 sqlite3_free(z);
5600#else
5601 rc = unlink(zFilename);
5602#endif
5603 return rc;
5604}
5605
drh13c20932018-01-10 21:41:55 +00005606/*
5607** Try to delete the temporary file (if there is one) and free the
5608** memory used to hold the name of the temp file.
5609*/
5610static void clearTempFile(ShellState *p){
5611 if( p->zTempFile==0 ) return;
drh536c3452018-01-11 00:38:39 +00005612 if( p->doXdgOpen ) return;
drh13c20932018-01-10 21:41:55 +00005613 if( shellDeleteFile(p->zTempFile) ) return;
5614 sqlite3_free(p->zTempFile);
5615 p->zTempFile = 0;
5616}
5617
5618/*
5619** Create a new temp file name with the given suffix.
5620*/
5621static void newTempFile(ShellState *p, const char *zSuffix){
5622 clearTempFile(p);
5623 sqlite3_free(p->zTempFile);
5624 p->zTempFile = 0;
drh7f3bf8a2018-01-10 21:50:08 +00005625 if( p->db ){
5626 sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
5627 }
drh13c20932018-01-10 21:41:55 +00005628 if( p->zTempFile==0 ){
drh1d9ea272020-04-17 23:46:54 +00005629 /* If p->db is an in-memory database then the TEMPFILENAME file-control
5630 ** will not work and we will need to fallback to guessing */
5631 char *zTemp;
drh13c20932018-01-10 21:41:55 +00005632 sqlite3_uint64 r;
5633 sqlite3_randomness(sizeof(r), &r);
drh1d9ea272020-04-17 23:46:54 +00005634 zTemp = getenv("TEMP");
5635 if( zTemp==0 ) zTemp = getenv("TMP");
5636 if( zTemp==0 ){
5637#ifdef _WIN32
5638 zTemp = "\\tmp";
5639#else
5640 zTemp = "/tmp";
5641#endif
5642 }
5643 p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
drh13c20932018-01-10 21:41:55 +00005644 }else{
5645 p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
5646 }
5647 if( p->zTempFile==0 ){
5648 raw_printf(stderr, "out of memory\n");
5649 exit(1);
5650 }
5651}
5652
drh2ce15c32017-07-11 13:34:40 +00005653
5654/*
5655** The implementation of SQL scalar function fkey_collate_clause(), used
5656** by the ".lint fkey-indexes" command. This scalar function is always
5657** called with four arguments - the parent table name, the parent column name,
5658** the child table name and the child column name.
5659**
5660** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col')
5661**
5662** If either of the named tables or columns do not exist, this function
5663** returns an empty string. An empty string is also returned if both tables
5664** and columns exist but have the same default collation sequence. Or,
5665** if both exist but the default collation sequences are different, this
5666** function returns the string " COLLATE <parent-collation>", where
5667** <parent-collation> is the default collation sequence of the parent column.
5668*/
5669static void shellFkeyCollateClause(
5670 sqlite3_context *pCtx,
5671 int nVal,
5672 sqlite3_value **apVal
5673){
5674 sqlite3 *db = sqlite3_context_db_handle(pCtx);
5675 const char *zParent;
5676 const char *zParentCol;
5677 const char *zParentSeq;
5678 const char *zChild;
5679 const char *zChildCol;
5680 const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */
5681 int rc;
5682
5683 assert( nVal==4 );
5684 zParent = (const char*)sqlite3_value_text(apVal[0]);
5685 zParentCol = (const char*)sqlite3_value_text(apVal[1]);
5686 zChild = (const char*)sqlite3_value_text(apVal[2]);
5687 zChildCol = (const char*)sqlite3_value_text(apVal[3]);
5688
5689 sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
5690 rc = sqlite3_table_column_metadata(
5691 db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0
5692 );
5693 if( rc==SQLITE_OK ){
5694 rc = sqlite3_table_column_metadata(
5695 db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0
5696 );
5697 }
5698
5699 if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){
5700 char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq);
5701 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
5702 sqlite3_free(z);
5703 }
5704}
5705
5706
5707/*
5708** The implementation of dot-command ".lint fkey-indexes".
5709*/
5710static int lintFkeyIndexes(
5711 ShellState *pState, /* Current shell tool state */
5712 char **azArg, /* Array of arguments passed to dot command */
5713 int nArg /* Number of entries in azArg[] */
5714){
5715 sqlite3 *db = pState->db; /* Database handle to query "main" db of */
5716 FILE *out = pState->out; /* Stream to write non-error output to */
5717 int bVerbose = 0; /* If -verbose is present */
5718 int bGroupByParent = 0; /* If -groupbyparent is present */
5719 int i; /* To iterate through azArg[] */
5720 const char *zIndent = ""; /* How much to indent CREATE INDEX by */
5721 int rc; /* Return code */
5722 sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */
5723
5724 /*
5725 ** This SELECT statement returns one row for each foreign key constraint
5726 ** in the schema of the main database. The column values are:
5727 **
5728 ** 0. The text of an SQL statement similar to:
5729 **
danf9679312017-12-01 18:40:18 +00005730 ** "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?"
drh2ce15c32017-07-11 13:34:40 +00005731 **
danf9679312017-12-01 18:40:18 +00005732 ** This SELECT is similar to the one that the foreign keys implementation
5733 ** needs to run internally on child tables. If there is an index that can
drh2ce15c32017-07-11 13:34:40 +00005734 ** be used to optimize this query, then it can also be used by the FK
5735 ** implementation to optimize DELETE or UPDATE statements on the parent
5736 ** table.
5737 **
5738 ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by
5739 ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema
5740 ** contains an index that can be used to optimize the query.
5741 **
5742 ** 2. Human readable text that describes the child table and columns. e.g.
5743 **
5744 ** "child_table(child_key1, child_key2)"
5745 **
5746 ** 3. Human readable text that describes the parent table and columns. e.g.
5747 **
5748 ** "parent_table(parent_key1, parent_key2)"
5749 **
5750 ** 4. A full CREATE INDEX statement for an index that could be used to
5751 ** optimize DELETE or UPDATE statements on the parent table. e.g.
5752 **
5753 ** "CREATE INDEX child_table_child_key ON child_table(child_key)"
5754 **
5755 ** 5. The name of the parent table.
5756 **
5757 ** These six values are used by the C logic below to generate the report.
5758 */
5759 const char *zSql =
5760 "SELECT "
danf9679312017-12-01 18:40:18 +00005761 " 'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '"
drh2ce15c32017-07-11 13:34:40 +00005762 " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' "
5763 " || fkey_collate_clause("
5764 " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')"
5765 ", "
5766 " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('"
5767 " || group_concat('*=?', ' AND ') || ')'"
5768 ", "
5769 " s.name || '(' || group_concat(f.[from], ', ') || ')'"
5770 ", "
5771 " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'"
5772 ", "
5773 " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))"
5774 " || ' ON ' || quote(s.name) || '('"
5775 " || group_concat(quote(f.[from]) ||"
5776 " fkey_collate_clause("
5777 " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')"
5778 " || ');'"
5779 ", "
5780 " f.[table] "
drh067b92b2020-06-19 15:24:12 +00005781 "FROM sqlite_schema AS s, pragma_foreign_key_list(s.name) AS f "
drh2ce15c32017-07-11 13:34:40 +00005782 "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) "
5783 "GROUP BY s.name, f.id "
5784 "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
5785 ;
5786 const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)";
5787
5788 for(i=2; i<nArg; i++){
drhaf2770f2018-01-05 14:55:43 +00005789 int n = strlen30(azArg[i]);
drh2ce15c32017-07-11 13:34:40 +00005790 if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
5791 bVerbose = 1;
5792 }
5793 else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
5794 bGroupByParent = 1;
5795 zIndent = " ";
5796 }
5797 else{
5798 raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
5799 azArg[0], azArg[1]
5800 );
5801 return SQLITE_ERROR;
5802 }
5803 }
5804
5805 /* Register the fkey_collate_clause() SQL function */
5806 rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8,
5807 0, shellFkeyCollateClause, 0, 0
5808 );
5809
5810
5811 if( rc==SQLITE_OK ){
5812 rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0);
5813 }
5814 if( rc==SQLITE_OK ){
5815 sqlite3_bind_int(pSql, 1, bGroupByParent);
5816 }
5817
5818 if( rc==SQLITE_OK ){
5819 int rc2;
5820 char *zPrev = 0;
5821 while( SQLITE_ROW==sqlite3_step(pSql) ){
5822 int res = -1;
5823 sqlite3_stmt *pExplain = 0;
5824 const char *zEQP = (const char*)sqlite3_column_text(pSql, 0);
5825 const char *zGlob = (const char*)sqlite3_column_text(pSql, 1);
5826 const char *zFrom = (const char*)sqlite3_column_text(pSql, 2);
5827 const char *zTarget = (const char*)sqlite3_column_text(pSql, 3);
5828 const char *zCI = (const char*)sqlite3_column_text(pSql, 4);
5829 const char *zParent = (const char*)sqlite3_column_text(pSql, 5);
5830
5831 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
5832 if( rc!=SQLITE_OK ) break;
5833 if( SQLITE_ROW==sqlite3_step(pExplain) ){
5834 const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3);
5835 res = (
5836 0==sqlite3_strglob(zGlob, zPlan)
5837 || 0==sqlite3_strglob(zGlobIPK, zPlan)
5838 );
5839 }
5840 rc = sqlite3_finalize(pExplain);
5841 if( rc!=SQLITE_OK ) break;
5842
5843 if( res<0 ){
5844 raw_printf(stderr, "Error: internal error");
5845 break;
5846 }else{
5847 if( bGroupByParent
5848 && (bVerbose || res==0)
5849 && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
5850 ){
5851 raw_printf(out, "-- Parent table %s\n", zParent);
5852 sqlite3_free(zPrev);
5853 zPrev = sqlite3_mprintf("%s", zParent);
5854 }
5855
5856 if( res==0 ){
5857 raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
5858 }else if( bVerbose ){
5859 raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
5860 zIndent, zFrom, zTarget
5861 );
5862 }
5863 }
5864 }
5865 sqlite3_free(zPrev);
5866
5867 if( rc!=SQLITE_OK ){
5868 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
5869 }
5870
5871 rc2 = sqlite3_finalize(pSql);
5872 if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
5873 rc = rc2;
5874 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
5875 }
5876 }else{
5877 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
5878 }
5879
5880 return rc;
5881}
5882
5883/*
5884** Implementation of ".lint" dot command.
5885*/
5886static int lintDotCommand(
5887 ShellState *pState, /* Current shell tool state */
5888 char **azArg, /* Array of arguments passed to dot command */
5889 int nArg /* Number of entries in azArg[] */
5890){
5891 int n;
drhaf2770f2018-01-05 14:55:43 +00005892 n = (nArg>=2 ? strlen30(azArg[1]) : 0);
drh2ce15c32017-07-11 13:34:40 +00005893 if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
5894 return lintFkeyIndexes(pState, azArg, nArg);
5895
5896 usage:
5897 raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
5898 raw_printf(stderr, "Where sub-commands are:\n");
5899 raw_printf(stderr, " fkey-indexes\n");
5900 return SQLITE_ERROR;
5901}
5902
dan1b162162019-04-27 20:15:15 +00005903#if !defined SQLITE_OMIT_VIRTUALTABLE
danfd0245d2017-12-07 15:44:29 +00005904static void shellPrepare(
dand4b56e52017-12-12 20:04:59 +00005905 sqlite3 *db,
danfd0245d2017-12-07 15:44:29 +00005906 int *pRc,
5907 const char *zSql,
5908 sqlite3_stmt **ppStmt
5909){
5910 *ppStmt = 0;
5911 if( *pRc==SQLITE_OK ){
dand4b56e52017-12-12 20:04:59 +00005912 int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
danfd0245d2017-12-07 15:44:29 +00005913 if( rc!=SQLITE_OK ){
5914 raw_printf(stderr, "sql error: %s (%d)\n",
dand4b56e52017-12-12 20:04:59 +00005915 sqlite3_errmsg(db), sqlite3_errcode(db)
danfd0245d2017-12-07 15:44:29 +00005916 );
5917 *pRc = rc;
5918 }
5919 }
5920}
5921
drh9546c762019-05-10 17:50:33 +00005922/*
5923** Create a prepared statement using printf-style arguments for the SQL.
5924**
5925** This routine is could be marked "static". But it is not always used,
5926** depending on compile-time options. By omitting the "static", we avoid
5927** nuisance compiler warnings about "defined but not used".
5928*/
5929void shellPreparePrintf(
dan3f67ddf2017-12-13 20:04:53 +00005930 sqlite3 *db,
5931 int *pRc,
danac15e2d2017-12-14 19:15:07 +00005932 sqlite3_stmt **ppStmt,
5933 const char *zFmt,
5934 ...
dan3f67ddf2017-12-13 20:04:53 +00005935){
danac15e2d2017-12-14 19:15:07 +00005936 *ppStmt = 0;
5937 if( *pRc==SQLITE_OK ){
5938 va_list ap;
5939 char *z;
5940 va_start(ap, zFmt);
5941 z = sqlite3_vmprintf(zFmt, ap);
drh1dbb1472018-10-11 10:37:24 +00005942 va_end(ap);
dan3f67ddf2017-12-13 20:04:53 +00005943 if( z==0 ){
5944 *pRc = SQLITE_NOMEM;
5945 }else{
5946 shellPrepare(db, pRc, z, ppStmt);
5947 sqlite3_free(z);
5948 }
dan3f67ddf2017-12-13 20:04:53 +00005949 }
5950}
5951
drh9546c762019-05-10 17:50:33 +00005952/* Finalize the prepared statement created using shellPreparePrintf().
5953**
5954** This routine is could be marked "static". But it is not always used,
5955** depending on compile-time options. By omitting the "static", we avoid
5956** nuisance compiler warnings about "defined but not used".
5957*/
5958void shellFinalize(
danfd0245d2017-12-07 15:44:29 +00005959 int *pRc,
5960 sqlite3_stmt *pStmt
5961){
dan25c12182017-12-07 21:03:33 +00005962 if( pStmt ){
5963 sqlite3 *db = sqlite3_db_handle(pStmt);
5964 int rc = sqlite3_finalize(pStmt);
5965 if( *pRc==SQLITE_OK ){
5966 if( rc!=SQLITE_OK ){
5967 raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
5968 }
5969 *pRc = rc;
5970 }
5971 }
danfd0245d2017-12-07 15:44:29 +00005972}
5973
drh9546c762019-05-10 17:50:33 +00005974/* Reset the prepared statement created using shellPreparePrintf().
5975**
5976** This routine is could be marked "static". But it is not always used,
5977** depending on compile-time options. By omitting the "static", we avoid
5978** nuisance compiler warnings about "defined but not used".
5979*/
5980void shellReset(
danfd0245d2017-12-07 15:44:29 +00005981 int *pRc,
5982 sqlite3_stmt *pStmt
5983){
5984 int rc = sqlite3_reset(pStmt);
dan5a78b812017-12-27 18:54:11 +00005985 if( *pRc==SQLITE_OK ){
5986 if( rc!=SQLITE_OK ){
5987 sqlite3 *db = sqlite3_db_handle(pStmt);
5988 raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
5989 }
5990 *pRc = rc;
5991 }
danfd0245d2017-12-07 15:44:29 +00005992}
dan1b162162019-04-27 20:15:15 +00005993#endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
5994
5995#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
drhe2754c12019-08-26 12:50:01 +00005996/******************************************************************************
dan1b162162019-04-27 20:15:15 +00005997** The ".archive" or ".ar" command.
5998*/
drhe37c0e12018-01-06 19:19:50 +00005999/*
dan88be0202017-12-09 17:58:02 +00006000** Structure representing a single ".ar" command.
6001*/
6002typedef struct ArCommand ArCommand;
6003struct ArCommand {
drhb376b3d2018-01-10 13:11:51 +00006004 u8 eCmd; /* An AR_CMD_* value */
6005 u8 bVerbose; /* True if --verbose */
drha5676c42018-01-10 15:17:34 +00006006 u8 bZip; /* True if the archive is a ZIP */
drhb376b3d2018-01-10 13:11:51 +00006007 u8 bDryRun; /* True if --dry-run */
drha5676c42018-01-10 15:17:34 +00006008 u8 bAppend; /* True if --append */
drhd0f9cdc2018-05-17 14:09:06 +00006009 u8 fromCmdLine; /* Run from -A instead of .archive */
drhb376b3d2018-01-10 13:11:51 +00006010 int nArg; /* Number of command arguments */
drha5676c42018-01-10 15:17:34 +00006011 char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
dan88be0202017-12-09 17:58:02 +00006012 const char *zFile; /* --file argument, or NULL */
6013 const char *zDir; /* --directory argument, or NULL */
dan88be0202017-12-09 17:58:02 +00006014 char **azArg; /* Array of command arguments */
drhb376b3d2018-01-10 13:11:51 +00006015 ShellState *p; /* Shell state */
6016 sqlite3 *db; /* Database containing the archive */
dan88be0202017-12-09 17:58:02 +00006017};
6018
6019/*
6020** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
6021*/
dan0d0547f2017-12-14 15:40:42 +00006022static int arUsage(FILE *f){
drh98aa2ab2018-09-26 16:53:51 +00006023 showHelp(f,"archive");
dan0d0547f2017-12-14 15:40:42 +00006024 return SQLITE_ERROR;
6025}
6026
6027/*
6028** Print an error message for the .ar command to stderr and return
6029** SQLITE_ERROR.
6030*/
drhd0f9cdc2018-05-17 14:09:06 +00006031static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
dan0d0547f2017-12-14 15:40:42 +00006032 va_list ap;
6033 char *z;
6034 va_start(ap, zFmt);
6035 z = sqlite3_vmprintf(zFmt, ap);
6036 va_end(ap);
drhd0f9cdc2018-05-17 14:09:06 +00006037 utf8_printf(stderr, "Error: %s\n", z);
6038 if( pAr->fromCmdLine ){
6039 utf8_printf(stderr, "Use \"-A\" for more help\n");
6040 }else{
6041 utf8_printf(stderr, "Use \".archive --help\" for more help\n");
6042 }
dan0d0547f2017-12-14 15:40:42 +00006043 sqlite3_free(z);
dan88be0202017-12-09 17:58:02 +00006044 return SQLITE_ERROR;
6045}
6046
6047/*
6048** Values for ArCommand.eCmd.
6049*/
dand4b56e52017-12-12 20:04:59 +00006050#define AR_CMD_CREATE 1
drhb17ea912019-03-25 14:24:19 +00006051#define AR_CMD_UPDATE 2
6052#define AR_CMD_INSERT 3
6053#define AR_CMD_EXTRACT 4
6054#define AR_CMD_LIST 5
6055#define AR_CMD_HELP 6
dand4b56e52017-12-12 20:04:59 +00006056
6057/*
6058** Other (non-command) switches.
6059*/
drhb17ea912019-03-25 14:24:19 +00006060#define AR_SWITCH_VERBOSE 7
6061#define AR_SWITCH_FILE 8
6062#define AR_SWITCH_DIRECTORY 9
6063#define AR_SWITCH_APPEND 10
6064#define AR_SWITCH_DRYRUN 11
dand4b56e52017-12-12 20:04:59 +00006065
6066static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
6067 switch( eSwitch ){
6068 case AR_CMD_CREATE:
6069 case AR_CMD_EXTRACT:
6070 case AR_CMD_LIST:
6071 case AR_CMD_UPDATE:
drhb17ea912019-03-25 14:24:19 +00006072 case AR_CMD_INSERT:
dan0d0547f2017-12-14 15:40:42 +00006073 case AR_CMD_HELP:
6074 if( pAr->eCmd ){
drhd0f9cdc2018-05-17 14:09:06 +00006075 return arErrorMsg(pAr, "multiple command options");
dan0d0547f2017-12-14 15:40:42 +00006076 }
dand4b56e52017-12-12 20:04:59 +00006077 pAr->eCmd = eSwitch;
6078 break;
6079
drhb376b3d2018-01-10 13:11:51 +00006080 case AR_SWITCH_DRYRUN:
6081 pAr->bDryRun = 1;
6082 break;
dand4b56e52017-12-12 20:04:59 +00006083 case AR_SWITCH_VERBOSE:
6084 pAr->bVerbose = 1;
6085 break;
drha5676c42018-01-10 15:17:34 +00006086 case AR_SWITCH_APPEND:
6087 pAr->bAppend = 1;
drhca7733b2018-01-10 18:09:20 +00006088 /* Fall thru into --file */
dand4b56e52017-12-12 20:04:59 +00006089 case AR_SWITCH_FILE:
6090 pAr->zFile = zArg;
6091 break;
6092 case AR_SWITCH_DIRECTORY:
6093 pAr->zDir = zArg;
6094 break;
6095 }
6096
6097 return SQLITE_OK;
6098}
dan88be0202017-12-09 17:58:02 +00006099
6100/*
6101** Parse the command line for an ".ar" command. The results are written into
6102** structure (*pAr). SQLITE_OK is returned if the command line is parsed
6103** successfully, otherwise an error message is written to stderr and
6104** SQLITE_ERROR returned.
6105*/
6106static int arParseCommand(
6107 char **azArg, /* Array of arguments passed to dot command */
6108 int nArg, /* Number of entries in azArg[] */
6109 ArCommand *pAr /* Populate this object */
6110){
dand4b56e52017-12-12 20:04:59 +00006111 struct ArSwitch {
dand4b56e52017-12-12 20:04:59 +00006112 const char *zLong;
drhb376b3d2018-01-10 13:11:51 +00006113 char cShort;
6114 u8 eSwitch;
6115 u8 bArg;
dand4b56e52017-12-12 20:04:59 +00006116 } aSwitch[] = {
drhb376b3d2018-01-10 13:11:51 +00006117 { "create", 'c', AR_CMD_CREATE, 0 },
6118 { "extract", 'x', AR_CMD_EXTRACT, 0 },
drhb17ea912019-03-25 14:24:19 +00006119 { "insert", 'i', AR_CMD_INSERT, 0 },
drhb376b3d2018-01-10 13:11:51 +00006120 { "list", 't', AR_CMD_LIST, 0 },
6121 { "update", 'u', AR_CMD_UPDATE, 0 },
6122 { "help", 'h', AR_CMD_HELP, 0 },
6123 { "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
6124 { "file", 'f', AR_SWITCH_FILE, 1 },
drhca7733b2018-01-10 18:09:20 +00006125 { "append", 'a', AR_SWITCH_APPEND, 1 },
drhb376b3d2018-01-10 13:11:51 +00006126 { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
drhb376b3d2018-01-10 13:11:51 +00006127 { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
dand4b56e52017-12-12 20:04:59 +00006128 };
6129 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
6130 struct ArSwitch *pEnd = &aSwitch[nSwitch];
6131
dan88be0202017-12-09 17:58:02 +00006132 if( nArg<=1 ){
drh98aa2ab2018-09-26 16:53:51 +00006133 utf8_printf(stderr, "Wrong number of arguments. Usage:\n");
dan0d0547f2017-12-14 15:40:42 +00006134 return arUsage(stderr);
dan88be0202017-12-09 17:58:02 +00006135 }else{
6136 char *z = azArg[1];
dan88be0202017-12-09 17:58:02 +00006137 if( z[0]!='-' ){
6138 /* Traditional style [tar] invocation */
6139 int i;
6140 int iArg = 2;
6141 for(i=0; z[i]; i++){
dand4b56e52017-12-12 20:04:59 +00006142 const char *zArg = 0;
6143 struct ArSwitch *pOpt;
6144 for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
6145 if( z[i]==pOpt->cShort ) break;
dan88be0202017-12-09 17:58:02 +00006146 }
dan0d0547f2017-12-14 15:40:42 +00006147 if( pOpt==pEnd ){
drhd0f9cdc2018-05-17 14:09:06 +00006148 return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
dan0d0547f2017-12-14 15:40:42 +00006149 }
dand4b56e52017-12-12 20:04:59 +00006150 if( pOpt->bArg ){
dan0d0547f2017-12-14 15:40:42 +00006151 if( iArg>=nArg ){
drhd0f9cdc2018-05-17 14:09:06 +00006152 return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
dan0d0547f2017-12-14 15:40:42 +00006153 }
dand4b56e52017-12-12 20:04:59 +00006154 zArg = azArg[iArg++];
6155 }
6156 if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
dan88be0202017-12-09 17:58:02 +00006157 }
dan88be0202017-12-09 17:58:02 +00006158 pAr->nArg = nArg-iArg;
6159 if( pAr->nArg>0 ){
6160 pAr->azArg = &azArg[iArg];
6161 }
dand4b56e52017-12-12 20:04:59 +00006162 }else{
6163 /* Non-traditional invocation */
6164 int iArg;
6165 for(iArg=1; iArg<nArg; iArg++){
6166 int n;
6167 z = azArg[iArg];
6168 if( z[0]!='-' ){
6169 /* All remaining command line words are command arguments. */
6170 pAr->azArg = &azArg[iArg];
6171 pAr->nArg = nArg-iArg;
6172 break;
6173 }
drhaf2770f2018-01-05 14:55:43 +00006174 n = strlen30(z);
dand4b56e52017-12-12 20:04:59 +00006175
6176 if( z[1]!='-' ){
6177 int i;
6178 /* One or more short options */
6179 for(i=1; i<n; i++){
6180 const char *zArg = 0;
6181 struct ArSwitch *pOpt;
6182 for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
6183 if( z[i]==pOpt->cShort ) break;
6184 }
dan0d0547f2017-12-14 15:40:42 +00006185 if( pOpt==pEnd ){
drhd0f9cdc2018-05-17 14:09:06 +00006186 return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
dan0d0547f2017-12-14 15:40:42 +00006187 }
dand4b56e52017-12-12 20:04:59 +00006188 if( pOpt->bArg ){
6189 if( i<(n-1) ){
6190 zArg = &z[i+1];
6191 i = n;
6192 }else{
dan0d0547f2017-12-14 15:40:42 +00006193 if( iArg>=(nArg-1) ){
drhe2754c12019-08-26 12:50:01 +00006194 return arErrorMsg(pAr, "option requires an argument: %c",
6195 z[i]);
dan0d0547f2017-12-14 15:40:42 +00006196 }
dand4b56e52017-12-12 20:04:59 +00006197 zArg = azArg[++iArg];
6198 }
6199 }
6200 if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
6201 }
6202 }else if( z[2]=='\0' ){
6203 /* A -- option, indicating that all remaining command line words
6204 ** are command arguments. */
6205 pAr->azArg = &azArg[iArg+1];
6206 pAr->nArg = nArg-iArg-1;
6207 break;
6208 }else{
6209 /* A long option */
6210 const char *zArg = 0; /* Argument for option, if any */
6211 struct ArSwitch *pMatch = 0; /* Matching option */
6212 struct ArSwitch *pOpt; /* Iterator */
6213 for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
6214 const char *zLong = pOpt->zLong;
drhaf2770f2018-01-05 14:55:43 +00006215 if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){
dand4b56e52017-12-12 20:04:59 +00006216 if( pMatch ){
drhd0f9cdc2018-05-17 14:09:06 +00006217 return arErrorMsg(pAr, "ambiguous option: %s",z);
dand4b56e52017-12-12 20:04:59 +00006218 }else{
6219 pMatch = pOpt;
6220 }
6221 }
6222 }
6223
6224 if( pMatch==0 ){
drhd0f9cdc2018-05-17 14:09:06 +00006225 return arErrorMsg(pAr, "unrecognized option: %s", z);
dand4b56e52017-12-12 20:04:59 +00006226 }
6227 if( pMatch->bArg ){
dan0d0547f2017-12-14 15:40:42 +00006228 if( iArg>=(nArg-1) ){
drhd0f9cdc2018-05-17 14:09:06 +00006229 return arErrorMsg(pAr, "option requires an argument: %s", z);
dan0d0547f2017-12-14 15:40:42 +00006230 }
dand4b56e52017-12-12 20:04:59 +00006231 zArg = azArg[++iArg];
6232 }
6233 if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR;
6234 }
6235 }
dan88be0202017-12-09 17:58:02 +00006236 }
6237 }
6238
6239 return SQLITE_OK;
6240}
6241
6242/*
dan3f67ddf2017-12-13 20:04:53 +00006243** This function assumes that all arguments within the ArCommand.azArg[]
6244** array refer to archive members, as for the --extract or --list commands.
6245** It checks that each of them are present. If any specified file is not
6246** present in the archive, an error is printed to stderr and an error
6247** code returned. Otherwise, if all specified arguments are present in
6248** the archive, SQLITE_OK is returned.
6249**
6250** This function strips any trailing '/' characters from each argument.
6251** This is consistent with the way the [tar] command seems to work on
6252** Linux.
6253*/
drhb376b3d2018-01-10 13:11:51 +00006254static int arCheckEntries(ArCommand *pAr){
dan3f67ddf2017-12-13 20:04:53 +00006255 int rc = SQLITE_OK;
6256 if( pAr->nArg ){
drhb376b3d2018-01-10 13:11:51 +00006257 int i, j;
dan3f67ddf2017-12-13 20:04:53 +00006258 sqlite3_stmt *pTest = 0;
6259
drhb376b3d2018-01-10 13:11:51 +00006260 shellPreparePrintf(pAr->db, &rc, &pTest,
6261 "SELECT name FROM %s WHERE name=$name",
6262 pAr->zSrcTable
dan5a78b812017-12-27 18:54:11 +00006263 );
drhb376b3d2018-01-10 13:11:51 +00006264 j = sqlite3_bind_parameter_index(pTest, "$name");
dan3f67ddf2017-12-13 20:04:53 +00006265 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
6266 char *z = pAr->azArg[i];
drhaf2770f2018-01-05 14:55:43 +00006267 int n = strlen30(z);
dan3f67ddf2017-12-13 20:04:53 +00006268 int bOk = 0;
6269 while( n>0 && z[n-1]=='/' ) n--;
6270 z[n] = '\0';
drhb376b3d2018-01-10 13:11:51 +00006271 sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC);
dan3f67ddf2017-12-13 20:04:53 +00006272 if( SQLITE_ROW==sqlite3_step(pTest) ){
6273 bOk = 1;
6274 }
6275 shellReset(&rc, pTest);
6276 if( rc==SQLITE_OK && bOk==0 ){
drhb376b3d2018-01-10 13:11:51 +00006277 utf8_printf(stderr, "not found in archive: %s\n", z);
dan3f67ddf2017-12-13 20:04:53 +00006278 rc = SQLITE_ERROR;
6279 }
6280 }
6281 shellFinalize(&rc, pTest);
6282 }
dan3f67ddf2017-12-13 20:04:53 +00006283 return rc;
6284}
6285
6286/*
6287** Format a WHERE clause that can be used against the "sqlar" table to
6288** identify all archive members that match the command arguments held
6289** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
6290** The caller is responsible for eventually calling sqlite3_free() on
6291** any non-NULL (*pzWhere) value.
6292*/
6293static void arWhereClause(
6294 int *pRc,
6295 ArCommand *pAr,
danac15e2d2017-12-14 19:15:07 +00006296 char **pzWhere /* OUT: New WHERE clause */
dan3f67ddf2017-12-13 20:04:53 +00006297){
6298 char *zWhere = 0;
6299 if( *pRc==SQLITE_OK ){
danac15e2d2017-12-14 19:15:07 +00006300 if( pAr->nArg==0 ){
6301 zWhere = sqlite3_mprintf("1");
6302 }else{
6303 int i;
6304 const char *zSep = "";
6305 for(i=0; i<pAr->nArg; i++){
6306 const char *z = pAr->azArg[i];
6307 zWhere = sqlite3_mprintf(
drhb376b3d2018-01-10 13:11:51 +00006308 "%z%s name = '%q' OR substr(name,1,%d) = '%q/'",
6309 zWhere, zSep, z, strlen30(z)+1, z
6310 );
danac15e2d2017-12-14 19:15:07 +00006311 if( zWhere==0 ){
6312 *pRc = SQLITE_NOMEM;
6313 break;
6314 }
6315 zSep = " OR ";
dan3f67ddf2017-12-13 20:04:53 +00006316 }
dan3f67ddf2017-12-13 20:04:53 +00006317 }
6318 }
6319 *pzWhere = zWhere;
6320}
6321
6322/*
dan88be0202017-12-09 17:58:02 +00006323** Implementation of .ar "lisT" command.
6324*/
drhb376b3d2018-01-10 13:11:51 +00006325static int arListCommand(ArCommand *pAr){
danb5090e42017-12-27 21:13:21 +00006326 const char *zSql = "SELECT %s FROM %s WHERE %s";
danb5090e42017-12-27 21:13:21 +00006327 const char *azCols[] = {
6328 "name",
drh410cad92018-01-10 17:19:16 +00006329 "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name"
danb5090e42017-12-27 21:13:21 +00006330 };
dan5a78b812017-12-27 18:54:11 +00006331
dan3f67ddf2017-12-13 20:04:53 +00006332 char *zWhere = 0;
6333 sqlite3_stmt *pSql = 0;
6334 int rc;
6335
drhb376b3d2018-01-10 13:11:51 +00006336 rc = arCheckEntries(pAr);
dan3f67ddf2017-12-13 20:04:53 +00006337 arWhereClause(&rc, pAr, &zWhere);
6338
drhb376b3d2018-01-10 13:11:51 +00006339 shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
6340 pAr->zSrcTable, zWhere);
drhb376b3d2018-01-10 13:11:51 +00006341 if( pAr->bDryRun ){
6342 utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
6343 }else{
6344 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
6345 if( pAr->bVerbose ){
drh410cad92018-01-10 17:19:16 +00006346 utf8_printf(pAr->p->out, "%s % 10d %s %s\n",
6347 sqlite3_column_text(pSql, 0),
drhb376b3d2018-01-10 13:11:51 +00006348 sqlite3_column_int(pSql, 1),
6349 sqlite3_column_text(pSql, 2),
6350 sqlite3_column_text(pSql, 3)
6351 );
6352 }else{
6353 utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
6354 }
danb5090e42017-12-27 21:13:21 +00006355 }
dan3f67ddf2017-12-13 20:04:53 +00006356 }
dan5a78b812017-12-27 18:54:11 +00006357 shellFinalize(&rc, pSql);
drhd0f9cdc2018-05-17 14:09:06 +00006358 sqlite3_free(zWhere);
dan3f67ddf2017-12-13 20:04:53 +00006359 return rc;
dan88be0202017-12-09 17:58:02 +00006360}
6361
6362
danfd0245d2017-12-07 15:44:29 +00006363/*
6364** Implementation of .ar "eXtract" command.
6365*/
drhb376b3d2018-01-10 13:11:51 +00006366static int arExtractCommand(ArCommand *pAr){
dan25c12182017-12-07 21:03:33 +00006367 const char *zSql1 =
dand1b51d42017-12-16 19:11:26 +00006368 "SELECT "
drhb376b3d2018-01-10 13:11:51 +00006369 " ($dir || name),"
6370 " writefile(($dir || name), %s, mode, mtime) "
drh0cfd46a2018-06-06 01:18:01 +00006371 "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)"
6372 " AND name NOT GLOB '*..[/\\]*'";
dan5a78b812017-12-27 18:54:11 +00006373
6374 const char *azExtraArg[] = {
6375 "sqlar_uncompress(data, sz)",
dan7c15ac12018-01-08 19:59:59 +00006376 "data"
dan5a78b812017-12-27 18:54:11 +00006377 };
dan5a78b812017-12-27 18:54:11 +00006378
danfd0245d2017-12-07 15:44:29 +00006379 sqlite3_stmt *pSql = 0;
6380 int rc = SQLITE_OK;
dan2ad09492017-12-09 18:28:22 +00006381 char *zDir = 0;
dan3f67ddf2017-12-13 20:04:53 +00006382 char *zWhere = 0;
drhb376b3d2018-01-10 13:11:51 +00006383 int i, j;
dan2ad09492017-12-09 18:28:22 +00006384
dan3f67ddf2017-12-13 20:04:53 +00006385 /* If arguments are specified, check that they actually exist within
6386 ** the archive before proceeding. And formulate a WHERE clause to
6387 ** match them. */
drhb376b3d2018-01-10 13:11:51 +00006388 rc = arCheckEntries(pAr);
dan3f67ddf2017-12-13 20:04:53 +00006389 arWhereClause(&rc, pAr, &zWhere);
6390
6391 if( rc==SQLITE_OK ){
6392 if( pAr->zDir ){
6393 zDir = sqlite3_mprintf("%s/", pAr->zDir);
6394 }else{
6395 zDir = sqlite3_mprintf("");
6396 }
6397 if( zDir==0 ) rc = SQLITE_NOMEM;
dan2ad09492017-12-09 18:28:22 +00006398 }
danfd0245d2017-12-07 15:44:29 +00006399
drhb376b3d2018-01-10 13:11:51 +00006400 shellPreparePrintf(pAr->db, &rc, &pSql, zSql1,
6401 azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere
dan5a78b812017-12-27 18:54:11 +00006402 );
6403
dan2ad09492017-12-09 18:28:22 +00006404 if( rc==SQLITE_OK ){
drhb376b3d2018-01-10 13:11:51 +00006405 j = sqlite3_bind_parameter_index(pSql, "$dir");
6406 sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC);
dan25c12182017-12-07 21:03:33 +00006407
danac15e2d2017-12-14 19:15:07 +00006408 /* Run the SELECT statement twice. The first time, writefile() is called
6409 ** for all archive members that should be extracted. The second time,
6410 ** only for the directories. This is because the timestamps for
6411 ** extracted directories must be reset after they are populated (as
6412 ** populating them changes the timestamp). */
6413 for(i=0; i<2; i++){
drhb376b3d2018-01-10 13:11:51 +00006414 j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
6415 sqlite3_bind_int(pSql, j, i);
6416 if( pAr->bDryRun ){
6417 utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
6418 }else{
6419 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
6420 if( i==0 && pAr->bVerbose ){
6421 utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
6422 }
danac15e2d2017-12-14 19:15:07 +00006423 }
6424 }
6425 shellReset(&rc, pSql);
dan25c12182017-12-07 21:03:33 +00006426 }
danac15e2d2017-12-14 19:15:07 +00006427 shellFinalize(&rc, pSql);
dan25c12182017-12-07 21:03:33 +00006428 }
dan25c12182017-12-07 21:03:33 +00006429
dan2ad09492017-12-09 18:28:22 +00006430 sqlite3_free(zDir);
dan3f67ddf2017-12-13 20:04:53 +00006431 sqlite3_free(zWhere);
danfd0245d2017-12-07 15:44:29 +00006432 return rc;
6433}
6434
drhb376b3d2018-01-10 13:11:51 +00006435/*
6436** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out.
6437*/
6438static int arExecSql(ArCommand *pAr, const char *zSql){
6439 int rc;
6440 if( pAr->bDryRun ){
6441 utf8_printf(pAr->p->out, "%s\n", zSql);
6442 rc = SQLITE_OK;
6443 }else{
drh410cad92018-01-10 17:19:16 +00006444 char *zErr = 0;
6445 rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
6446 if( zErr ){
6447 utf8_printf(stdout, "ERROR: %s\n", zErr);
6448 sqlite3_free(zErr);
6449 }
drhb376b3d2018-01-10 13:11:51 +00006450 }
6451 return rc;
6452}
6453
dan1ad3f612017-12-11 20:22:02 +00006454
danfd0245d2017-12-07 15:44:29 +00006455/*
drhb17ea912019-03-25 14:24:19 +00006456** Implementation of .ar "create", "insert", and "update" commands.
6457**
6458** create -> Create a new SQL archive
6459** insert -> Insert or reinsert all files listed
6460** update -> Insert files that have changed or that were not
6461** previously in the archive
danfd0245d2017-12-07 15:44:29 +00006462**
6463** Create the "sqlar" table in the database if it does not already exist.
6464** Then add each file in the azFile[] array to the archive. Directories
6465** are added recursively. If argument bVerbose is non-zero, a message is
6466** printed on stdout for each file archived.
dan06741a32017-12-13 20:17:18 +00006467**
6468** The create command is the same as update, except that it drops
drhb17ea912019-03-25 14:24:19 +00006469** any existing "sqlar" table before beginning. The "insert" command
6470** always overwrites every file named on the command-line, where as
6471** "update" only overwrites if the size or mtime or mode has changed.
danfd0245d2017-12-07 15:44:29 +00006472*/
drhb376b3d2018-01-10 13:11:51 +00006473static int arCreateOrUpdateCommand(
dan06741a32017-12-13 20:17:18 +00006474 ArCommand *pAr, /* Command arguments and options */
drhb17ea912019-03-25 14:24:19 +00006475 int bUpdate, /* true for a --create. */
6476 int bOnlyIfChanged /* Only update if file has changed */
danfd0245d2017-12-07 15:44:29 +00006477){
dand4b56e52017-12-12 20:04:59 +00006478 const char *zCreate =
drhafba1802018-01-06 15:49:57 +00006479 "CREATE TABLE IF NOT EXISTS sqlar(\n"
6480 " name TEXT PRIMARY KEY, -- name of the file\n"
6481 " mode INT, -- access permissions\n"
6482 " mtime INT, -- last modification time\n"
6483 " sz INT, -- original file size\n"
6484 " data BLOB -- compressed content\n"
6485 ")";
dand4b56e52017-12-12 20:04:59 +00006486 const char *zDrop = "DROP TABLE IF EXISTS sqlar";
drh1bf208c2018-03-09 21:54:01 +00006487 const char *zInsertFmt[2] = {
6488 "REPLACE INTO %s(name,mode,mtime,sz,data)\n"
drh634c70f2018-01-10 16:50:18 +00006489 " SELECT\n"
6490 " %s,\n"
6491 " mode,\n"
6492 " mtime,\n"
drh410cad92018-01-10 17:19:16 +00006493 " CASE substr(lsmode(mode),1,1)\n"
6494 " WHEN '-' THEN length(data)\n"
6495 " WHEN 'd' THEN 0\n"
drh634c70f2018-01-10 16:50:18 +00006496 " ELSE -1 END,\n"
drh69d2d352018-03-09 22:18:53 +00006497 " sqlar_compress(data)\n"
drhb17ea912019-03-25 14:24:19 +00006498 " FROM fsdir(%Q,%Q) AS disk\n"
6499 " WHERE lsmode(mode) NOT LIKE '?%%'%s;"
6500 ,
drh1bf208c2018-03-09 21:54:01 +00006501 "REPLACE INTO %s(name,mode,mtime,data)\n"
6502 " SELECT\n"
6503 " %s,\n"
6504 " mode,\n"
6505 " mtime,\n"
6506 " data\n"
drhb17ea912019-03-25 14:24:19 +00006507 " FROM fsdir(%Q,%Q) AS disk\n"
6508 " WHERE lsmode(mode) NOT LIKE '?%%'%s;"
drh1bf208c2018-03-09 21:54:01 +00006509 };
danfd0245d2017-12-07 15:44:29 +00006510 int i; /* For iterating through azFile[] */
6511 int rc; /* Return code */
drh1bf208c2018-03-09 21:54:01 +00006512 const char *zTab = 0; /* SQL table into which to insert */
6513 char *zSql;
6514 char zTemp[50];
drhb17ea912019-03-25 14:24:19 +00006515 char *zExists = 0;
danfd0245d2017-12-07 15:44:29 +00006516
drh1bf208c2018-03-09 21:54:01 +00006517 arExecSql(pAr, "PRAGMA page_size=512");
drhb376b3d2018-01-10 13:11:51 +00006518 rc = arExecSql(pAr, "SAVEPOINT ar;");
danfd0245d2017-12-07 15:44:29 +00006519 if( rc!=SQLITE_OK ) return rc;
drh1bf208c2018-03-09 21:54:01 +00006520 zTemp[0] = 0;
6521 if( pAr->bZip ){
6522 /* Initialize the zipfile virtual table, if necessary */
6523 if( pAr->zFile ){
6524 sqlite3_uint64 r;
6525 sqlite3_randomness(sizeof(r),&r);
6526 sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r);
6527 zTab = zTemp;
6528 zSql = sqlite3_mprintf(
6529 "CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)",
6530 zTab, pAr->zFile
6531 );
6532 rc = arExecSql(pAr, zSql);
6533 sqlite3_free(zSql);
6534 }else{
6535 zTab = "zip";
6536 }
6537 }else{
6538 /* Initialize the table for an SQLAR */
6539 zTab = "sqlar";
6540 if( bUpdate==0 ){
6541 rc = arExecSql(pAr, zDrop);
6542 if( rc!=SQLITE_OK ) goto end_ar_transaction;
6543 }
6544 rc = arExecSql(pAr, zCreate);
dan06741a32017-12-13 20:17:18 +00006545 }
drhb17ea912019-03-25 14:24:19 +00006546 if( bOnlyIfChanged ){
6547 zExists = sqlite3_mprintf(
6548 " AND NOT EXISTS("
6549 "SELECT 1 FROM %s AS mem"
6550 " WHERE mem.name=disk.name"
6551 " AND mem.mtime=disk.mtime"
6552 " AND mem.mode=disk.mode)", zTab);
6553 }else{
6554 zExists = sqlite3_mprintf("");
6555 }
6556 if( zExists==0 ) rc = SQLITE_NOMEM;
dan88be0202017-12-09 17:58:02 +00006557 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
mistachkince2052b2018-03-23 00:31:53 +00006558 char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab,
drh634c70f2018-01-10 16:50:18 +00006559 pAr->bVerbose ? "shell_putsnl(name)" : "name",
drhb17ea912019-03-25 14:24:19 +00006560 pAr->azArg[i], pAr->zDir, zExists);
mistachkince2052b2018-03-23 00:31:53 +00006561 rc = arExecSql(pAr, zSql2);
6562 sqlite3_free(zSql2);
danfd0245d2017-12-07 15:44:29 +00006563 }
drh1bf208c2018-03-09 21:54:01 +00006564end_ar_transaction:
danfd0245d2017-12-07 15:44:29 +00006565 if( rc!=SQLITE_OK ){
drh2bd207f2019-01-11 17:19:59 +00006566 sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0);
danfd0245d2017-12-07 15:44:29 +00006567 }else{
drhb376b3d2018-01-10 13:11:51 +00006568 rc = arExecSql(pAr, "RELEASE ar;");
drh1bf208c2018-03-09 21:54:01 +00006569 if( pAr->bZip && pAr->zFile ){
6570 zSql = sqlite3_mprintf("DROP TABLE %s", zTemp);
6571 arExecSql(pAr, zSql);
6572 sqlite3_free(zSql);
6573 }
danfd0245d2017-12-07 15:44:29 +00006574 }
drhb17ea912019-03-25 14:24:19 +00006575 sqlite3_free(zExists);
danfd0245d2017-12-07 15:44:29 +00006576 return rc;
6577}
6578
6579/*
6580** Implementation of ".ar" dot command.
6581*/
6582static int arDotCommand(
drhe2754c12019-08-26 12:50:01 +00006583 ShellState *pState, /* Current shell tool state */
6584 int fromCmdLine, /* True if -A command-line option, not .ar cmd */
6585 char **azArg, /* Array of arguments passed to dot command */
6586 int nArg /* Number of entries in azArg[] */
danfd0245d2017-12-07 15:44:29 +00006587){
dan88be0202017-12-09 17:58:02 +00006588 ArCommand cmd;
6589 int rc;
drh34660642018-01-10 17:39:54 +00006590 memset(&cmd, 0, sizeof(cmd));
drhd0f9cdc2018-05-17 14:09:06 +00006591 cmd.fromCmdLine = fromCmdLine;
dan88be0202017-12-09 17:58:02 +00006592 rc = arParseCommand(azArg, nArg, &cmd);
6593 if( rc==SQLITE_OK ){
drha5676c42018-01-10 15:17:34 +00006594 int eDbType = SHELL_OPEN_UNSPEC;
drhb376b3d2018-01-10 13:11:51 +00006595 cmd.p = pState;
6596 cmd.db = pState->db;
drha5676c42018-01-10 15:17:34 +00006597 if( cmd.zFile ){
drh1bf208c2018-03-09 21:54:01 +00006598 eDbType = deduceDatabaseType(cmd.zFile, 1);
drha5676c42018-01-10 15:17:34 +00006599 }else{
6600 eDbType = pState->openMode;
6601 }
6602 if( eDbType==SHELL_OPEN_ZIPFILE ){
drh1bf208c2018-03-09 21:54:01 +00006603 if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){
6604 if( cmd.zFile==0 ){
6605 cmd.zSrcTable = sqlite3_mprintf("zip");
6606 }else{
6607 cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile);
6608 }
dan5a78b812017-12-27 18:54:11 +00006609 }
drha5676c42018-01-10 15:17:34 +00006610 cmd.bZip = 1;
dan5a78b812017-12-27 18:54:11 +00006611 }else if( cmd.zFile ){
dand4b56e52017-12-12 20:04:59 +00006612 int flags;
drha5676c42018-01-10 15:17:34 +00006613 if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
drhb17ea912019-03-25 14:24:19 +00006614 if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
6615 || cmd.eCmd==AR_CMD_UPDATE ){
dand4b56e52017-12-12 20:04:59 +00006616 flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
6617 }else{
6618 flags = SQLITE_OPEN_READONLY;
6619 }
drha82c95b2018-01-10 14:00:00 +00006620 cmd.db = 0;
drha5676c42018-01-10 15:17:34 +00006621 if( cmd.bDryRun ){
6622 utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile,
6623 eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
6624 }
6625 rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
6626 eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
dand4b56e52017-12-12 20:04:59 +00006627 if( rc!=SQLITE_OK ){
drhb376b3d2018-01-10 13:11:51 +00006628 utf8_printf(stderr, "cannot open file: %s (%s)\n",
6629 cmd.zFile, sqlite3_errmsg(cmd.db)
dand4b56e52017-12-12 20:04:59 +00006630 );
drha5676c42018-01-10 15:17:34 +00006631 goto end_ar_command;
dand4b56e52017-12-12 20:04:59 +00006632 }
drhb376b3d2018-01-10 13:11:51 +00006633 sqlite3_fileio_init(cmd.db, 0, 0);
drhb376b3d2018-01-10 13:11:51 +00006634 sqlite3_sqlar_init(cmd.db, 0, 0);
drh34660642018-01-10 17:39:54 +00006635 sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p,
6636 shellPutsFunc, 0, 0);
6637
dand4b56e52017-12-12 20:04:59 +00006638 }
drhd0f9cdc2018-05-17 14:09:06 +00006639 if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){
drh634c70f2018-01-10 16:50:18 +00006640 if( cmd.eCmd!=AR_CMD_CREATE
6641 && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
6642 ){
drha5676c42018-01-10 15:17:34 +00006643 utf8_printf(stderr, "database does not contain an 'sqlar' table\n");
6644 rc = SQLITE_ERROR;
6645 goto end_ar_command;
6646 }
6647 cmd.zSrcTable = sqlite3_mprintf("sqlar");
6648 }
dand4b56e52017-12-12 20:04:59 +00006649
dan88be0202017-12-09 17:58:02 +00006650 switch( cmd.eCmd ){
6651 case AR_CMD_CREATE:
drhb17ea912019-03-25 14:24:19 +00006652 rc = arCreateOrUpdateCommand(&cmd, 0, 0);
dan88be0202017-12-09 17:58:02 +00006653 break;
danfd0245d2017-12-07 15:44:29 +00006654
dan88be0202017-12-09 17:58:02 +00006655 case AR_CMD_EXTRACT:
drhb376b3d2018-01-10 13:11:51 +00006656 rc = arExtractCommand(&cmd);
dan88be0202017-12-09 17:58:02 +00006657 break;
6658
6659 case AR_CMD_LIST:
drhb376b3d2018-01-10 13:11:51 +00006660 rc = arListCommand(&cmd);
dan88be0202017-12-09 17:58:02 +00006661 break;
6662
dan0d0547f2017-12-14 15:40:42 +00006663 case AR_CMD_HELP:
6664 arUsage(pState->out);
6665 break;
6666
drhb17ea912019-03-25 14:24:19 +00006667 case AR_CMD_INSERT:
6668 rc = arCreateOrUpdateCommand(&cmd, 1, 0);
6669 break;
6670
dan88be0202017-12-09 17:58:02 +00006671 default:
6672 assert( cmd.eCmd==AR_CMD_UPDATE );
drhb17ea912019-03-25 14:24:19 +00006673 rc = arCreateOrUpdateCommand(&cmd, 1, 1);
dan88be0202017-12-09 17:58:02 +00006674 break;
danfd0245d2017-12-07 15:44:29 +00006675 }
6676 }
drha5676c42018-01-10 15:17:34 +00006677end_ar_command:
6678 if( cmd.db!=pState->db ){
drh9e804032018-05-18 17:11:50 +00006679 close_db(cmd.db);
drha5676c42018-01-10 15:17:34 +00006680 }
6681 sqlite3_free(cmd.zSrcTable);
danfd0245d2017-12-07 15:44:29 +00006682
dan88be0202017-12-09 17:58:02 +00006683 return rc;
danfd0245d2017-12-07 15:44:29 +00006684}
drhe37c0e12018-01-06 19:19:50 +00006685/* End of the ".archive" or ".ar" command logic
drhe2754c12019-08-26 12:50:01 +00006686*******************************************************************************/
drhe37c0e12018-01-06 19:19:50 +00006687#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
danfd0245d2017-12-07 15:44:29 +00006688
dan1b162162019-04-27 20:15:15 +00006689#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
dan42ebb012019-04-27 18:47:03 +00006690/*
6691** If (*pRc) is not SQLITE_OK when this function is called, it is a no-op.
6692** Otherwise, the SQL statement or statements in zSql are executed using
6693** database connection db and the error code written to *pRc before
6694** this function returns.
6695*/
dan68cb86e2019-04-20 20:57:28 +00006696static void shellExec(sqlite3 *db, int *pRc, const char *zSql){
6697 int rc = *pRc;
6698 if( rc==SQLITE_OK ){
6699 char *zErr = 0;
6700 rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
6701 if( rc!=SQLITE_OK ){
6702 raw_printf(stderr, "SQL error: %s\n", zErr);
6703 }
6704 *pRc = rc;
6705 }
6706}
6707
dan42ebb012019-04-27 18:47:03 +00006708/*
6709** Like shellExec(), except that zFmt is a printf() style format string.
6710*/
danc0b42432019-04-26 15:14:53 +00006711static void shellExecPrintf(sqlite3 *db, int *pRc, const char *zFmt, ...){
6712 char *z = 0;
6713 if( *pRc==SQLITE_OK ){
6714 va_list ap;
6715 va_start(ap, zFmt);
6716 z = sqlite3_vmprintf(zFmt, ap);
6717 va_end(ap);
6718 if( z==0 ){
6719 *pRc = SQLITE_NOMEM;
6720 }else{
6721 shellExec(db, pRc, z);
6722 }
6723 sqlite3_free(z);
6724 }
6725}
6726
dan42ebb012019-04-27 18:47:03 +00006727/*
6728** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
6729** Otherwise, an attempt is made to allocate, zero and return a pointer
6730** to a buffer nByte bytes in size. If an OOM error occurs, *pRc is set
6731** to SQLITE_NOMEM and NULL returned.
6732*/
dan68cb86e2019-04-20 20:57:28 +00006733static void *shellMalloc(int *pRc, sqlite3_int64 nByte){
6734 void *pRet = 0;
6735 if( *pRc==SQLITE_OK ){
6736 pRet = sqlite3_malloc64(nByte);
6737 if( pRet==0 ){
6738 *pRc = SQLITE_NOMEM;
6739 }else{
6740 memset(pRet, 0, nByte);
6741 }
6742 }
6743 return pRet;
6744}
6745
dan42ebb012019-04-27 18:47:03 +00006746/*
6747** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
6748** Otherwise, zFmt is treated as a printf() style string. The result of
6749** formatting it along with any trailing arguments is written into a
6750** buffer obtained from sqlite3_malloc(), and pointer to which is returned.
6751** It is the responsibility of the caller to eventually free this buffer
6752** using a call to sqlite3_free().
6753**
6754** If an OOM error occurs, (*pRc) is set to SQLITE_NOMEM and a NULL
6755** pointer returned.
6756*/
dan68cb86e2019-04-20 20:57:28 +00006757static char *shellMPrintf(int *pRc, const char *zFmt, ...){
6758 char *z = 0;
6759 if( *pRc==SQLITE_OK ){
6760 va_list ap;
6761 va_start(ap, zFmt);
6762 z = sqlite3_vmprintf(zFmt, ap);
6763 va_end(ap);
6764 if( z==0 ){
6765 *pRc = SQLITE_NOMEM;
6766 }
6767 }
6768 return z;
6769}
6770
dan42ebb012019-04-27 18:47:03 +00006771/*
6772** When running the ".recover" command, each output table, and the special
6773** orphaned row table if it is required, is represented by an instance
6774** of the following struct.
6775*/
dan68cb86e2019-04-20 20:57:28 +00006776typedef struct RecoverTable RecoverTable;
6777struct RecoverTable {
dan42ebb012019-04-27 18:47:03 +00006778 char *zQuoted; /* Quoted version of table name */
dan68cb86e2019-04-20 20:57:28 +00006779 int nCol; /* Number of columns in table */
6780 char **azlCol; /* Array of column lists */
dan42ebb012019-04-27 18:47:03 +00006781 int iPk; /* Index of IPK column */
dan68cb86e2019-04-20 20:57:28 +00006782};
6783
6784/*
dan42ebb012019-04-27 18:47:03 +00006785** Free a RecoverTable object allocated by recoverFindTable() or
6786** recoverOrphanTable().
dan68cb86e2019-04-20 20:57:28 +00006787*/
6788static void recoverFreeTable(RecoverTable *pTab){
6789 if( pTab ){
dan68cb86e2019-04-20 20:57:28 +00006790 sqlite3_free(pTab->zQuoted);
dan68cb86e2019-04-20 20:57:28 +00006791 if( pTab->azlCol ){
6792 int i;
dan98c5ad32019-04-26 21:11:37 +00006793 for(i=0; i<=pTab->nCol; i++){
dan68cb86e2019-04-20 20:57:28 +00006794 sqlite3_free(pTab->azlCol[i]);
6795 }
6796 sqlite3_free(pTab->azlCol);
6797 }
6798 sqlite3_free(pTab);
6799 }
6800}
6801
dan42ebb012019-04-27 18:47:03 +00006802/*
6803** This function is a no-op if (*pRc) is not SQLITE_OK when it is called.
6804** Otherwise, it allocates and returns a RecoverTable object based on the
6805** final four arguments passed to this function. It is the responsibility
6806** of the caller to eventually free the returned object using
6807** recoverFreeTable().
6808*/
6809static RecoverTable *recoverNewTable(
danb40af492019-04-22 20:52:12 +00006810 int *pRc, /* IN/OUT: Error code */
danb40af492019-04-22 20:52:12 +00006811 const char *zName, /* Name of table */
6812 const char *zSql, /* CREATE TABLE statement */
6813 int bIntkey,
6814 int nCol
6815){
6816 sqlite3 *dbtmp = 0; /* sqlite3 handle for testing CREATE TABLE */
6817 int rc = *pRc;
dan98c5ad32019-04-26 21:11:37 +00006818 RecoverTable *pTab = 0;
danb40af492019-04-22 20:52:12 +00006819
dan98c5ad32019-04-26 21:11:37 +00006820 pTab = (RecoverTable*)shellMalloc(&rc, sizeof(RecoverTable));
danb40af492019-04-22 20:52:12 +00006821 if( rc==SQLITE_OK ){
6822 int nSqlCol = 0;
6823 int bSqlIntkey = 0;
6824 sqlite3_stmt *pStmt = 0;
dan98c5ad32019-04-26 21:11:37 +00006825
danb40af492019-04-22 20:52:12 +00006826 rc = sqlite3_open("", &dbtmp);
6827 if( rc==SQLITE_OK ){
drha2de66c2019-08-06 20:26:17 +00006828 sqlite3_create_function(dbtmp, "shell_idquote", 1, SQLITE_UTF8, 0,
6829 shellIdQuote, 0, 0);
6830 }
6831 if( rc==SQLITE_OK ){
dan38f9c712019-04-23 18:03:02 +00006832 rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0);
6833 }
6834 if( rc==SQLITE_OK ){
danb40af492019-04-22 20:52:12 +00006835 rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0);
6836 if( rc==SQLITE_ERROR ){
6837 rc = SQLITE_OK;
6838 goto finished;
6839 }
6840 }
6841 shellPreparePrintf(dbtmp, &rc, &pStmt,
6842 "SELECT count(*) FROM pragma_table_info(%Q)", zName
6843 );
6844 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
6845 nSqlCol = sqlite3_column_int(pStmt, 0);
6846 }
6847 shellFinalize(&rc, pStmt);
6848
6849 if( rc!=SQLITE_OK || nSqlCol<nCol ){
6850 goto finished;
6851 }
6852
6853 shellPreparePrintf(dbtmp, &rc, &pStmt,
6854 "SELECT ("
6855 " SELECT substr(data,1,1)==X'0D' FROM sqlite_dbpage WHERE pgno=rootpage"
drh067b92b2020-06-19 15:24:12 +00006856 ") FROM sqlite_schema WHERE name = %Q", zName
danb40af492019-04-22 20:52:12 +00006857 );
6858 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
6859 bSqlIntkey = sqlite3_column_int(pStmt, 0);
6860 }
6861 shellFinalize(&rc, pStmt);
6862
6863 if( bIntkey==bSqlIntkey ){
dan98c5ad32019-04-26 21:11:37 +00006864 int i;
danb40af492019-04-22 20:52:12 +00006865 const char *zPk = "_rowid_";
6866 sqlite3_stmt *pPkFinder = 0;
6867
danf57bea32019-04-27 15:35:45 +00006868 /* If this is an intkey table and there is an INTEGER PRIMARY KEY,
6869 ** set zPk to the name of the PK column, and pTab->iPk to the index
6870 ** of the column, where columns are 0-numbered from left to right.
6871 ** Or, if this is a WITHOUT ROWID table or if there is no IPK column,
6872 ** leave zPk as "_rowid_" and pTab->iPk at -2. */
dan98c5ad32019-04-26 21:11:37 +00006873 pTab->iPk = -2;
6874 if( bIntkey ){
6875 shellPreparePrintf(dbtmp, &rc, &pPkFinder,
danb40af492019-04-22 20:52:12 +00006876 "SELECT cid, name FROM pragma_table_info(%Q) "
6877 " WHERE pk=1 AND type='integer' COLLATE nocase"
dan98c5ad32019-04-26 21:11:37 +00006878 " AND NOT EXISTS (SELECT cid FROM pragma_table_info(%Q) WHERE pk=2)"
6879 , zName, zName
6880 );
6881 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){
6882 pTab->iPk = sqlite3_column_int(pPkFinder, 0);
6883 zPk = (const char*)sqlite3_column_text(pPkFinder, 1);
6884 }
danb40af492019-04-22 20:52:12 +00006885 }
6886
drha2de66c2019-08-06 20:26:17 +00006887 pTab->zQuoted = shellMPrintf(&rc, "\"%w\"", zName);
dan98c5ad32019-04-26 21:11:37 +00006888 pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1));
danb40af492019-04-22 20:52:12 +00006889 pTab->nCol = nSqlCol;
6890
dan98c5ad32019-04-26 21:11:37 +00006891 if( bIntkey ){
drha2de66c2019-08-06 20:26:17 +00006892 pTab->azlCol[0] = shellMPrintf(&rc, "\"%w\"", zPk);
danb40af492019-04-22 20:52:12 +00006893 }else{
dan98c5ad32019-04-26 21:11:37 +00006894 pTab->azlCol[0] = shellMPrintf(&rc, "");
danb40af492019-04-22 20:52:12 +00006895 }
dan98c5ad32019-04-26 21:11:37 +00006896 i = 1;
6897 shellPreparePrintf(dbtmp, &rc, &pStmt,
drha2de66c2019-08-06 20:26:17 +00006898 "SELECT %Q || group_concat(shell_idquote(name), ', ') "
danf57bea32019-04-27 15:35:45 +00006899 " FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) "
dan98c5ad32019-04-26 21:11:37 +00006900 "FROM pragma_table_info(%Q)",
danf57bea32019-04-27 15:35:45 +00006901 bIntkey ? ", " : "", pTab->iPk,
6902 bIntkey ? "" : "(CASE WHEN pk=0 THEN 1000000 ELSE pk END), ",
6903 zName
dan98c5ad32019-04-26 21:11:37 +00006904 );
6905 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
6906 const char *zText = (const char*)sqlite3_column_text(pStmt, 0);
6907 pTab->azlCol[i] = shellMPrintf(&rc, "%s%s", pTab->azlCol[0], zText);
6908 i++;
6909 }
6910 shellFinalize(&rc, pStmt);
6911
danb40af492019-04-22 20:52:12 +00006912 shellFinalize(&rc, pPkFinder);
6913 }
6914 }
6915
6916 finished:
6917 sqlite3_close(dbtmp);
6918 *pRc = rc;
dan98779652019-05-09 14:15:19 +00006919 if( rc!=SQLITE_OK || (pTab && pTab->zQuoted==0) ){
dan98c5ad32019-04-26 21:11:37 +00006920 recoverFreeTable(pTab);
6921 pTab = 0;
6922 }
6923 return pTab;
danb40af492019-04-22 20:52:12 +00006924}
6925
dan0aa01ee2019-04-27 19:36:49 +00006926/*
6927** This function is called to search the schema recovered from the
drh067b92b2020-06-19 15:24:12 +00006928** sqlite_schema table of the (possibly) corrupt database as part
dan0aa01ee2019-04-27 19:36:49 +00006929** of a ".recover" command. Specifically, for a table with root page
6930** iRoot and at least nCol columns. Additionally, if bIntkey is 0, the
6931** table must be a WITHOUT ROWID table, or if non-zero, not one of
6932** those.
6933**
6934** If a table is found, a (RecoverTable*) object is returned. Or, if
6935** no such table is found, but bIntkey is false and iRoot is the
6936** root page of an index in the recovered schema, then (*pbNoop) is
6937** set to true and NULL returned. Or, if there is no such table or
6938** index, NULL is returned and (*pbNoop) set to 0, indicating that
6939** the caller should write data to the orphans table.
6940*/
dan42ebb012019-04-27 18:47:03 +00006941static RecoverTable *recoverFindTable(
dan0aa01ee2019-04-27 19:36:49 +00006942 ShellState *pState, /* Shell state object */
6943 int *pRc, /* IN/OUT: Error code */
6944 int iRoot, /* Root page of table */
6945 int bIntkey, /* True for an intkey table */
6946 int nCol, /* Number of columns in table */
6947 int *pbNoop /* OUT: True if iRoot is root of index */
dan68cb86e2019-04-20 20:57:28 +00006948){
danb40af492019-04-22 20:52:12 +00006949 sqlite3_stmt *pStmt = 0;
dan68cb86e2019-04-20 20:57:28 +00006950 RecoverTable *pRet = 0;
danb40af492019-04-22 20:52:12 +00006951 int bNoop = 0;
6952 const char *zSql = 0;
6953 const char *zName = 0;
dan68cb86e2019-04-20 20:57:28 +00006954
danb40af492019-04-22 20:52:12 +00006955 /* Search the recovered schema for an object with root page iRoot. */
6956 shellPreparePrintf(pState->db, pRc, &pStmt,
6957 "SELECT type, name, sql FROM recovery.schema WHERE rootpage=%d", iRoot
6958 );
6959 while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
6960 const char *zType = (const char*)sqlite3_column_text(pStmt, 0);
6961 if( bIntkey==0 && sqlite3_stricmp(zType, "index")==0 ){
6962 bNoop = 1;
6963 break;
6964 }
6965 if( sqlite3_stricmp(zType, "table")==0 ){
6966 zName = (const char*)sqlite3_column_text(pStmt, 1);
6967 zSql = (const char*)sqlite3_column_text(pStmt, 2);
dan42ebb012019-04-27 18:47:03 +00006968 pRet = recoverNewTable(pRc, zName, zSql, bIntkey, nCol);
danb40af492019-04-22 20:52:12 +00006969 break;
6970 }
6971 }
dan98c5ad32019-04-26 21:11:37 +00006972
danb40af492019-04-22 20:52:12 +00006973 shellFinalize(pRc, pStmt);
dan98c5ad32019-04-26 21:11:37 +00006974 *pbNoop = bNoop;
6975 return pRet;
6976}
danb40af492019-04-22 20:52:12 +00006977
dan0aa01ee2019-04-27 19:36:49 +00006978/*
6979** Return a RecoverTable object representing the orphans table.
6980*/
dan98c5ad32019-04-26 21:11:37 +00006981static RecoverTable *recoverOrphanTable(
dan0aa01ee2019-04-27 19:36:49 +00006982 ShellState *pState, /* Shell state object */
6983 int *pRc, /* IN/OUT: Error code */
6984 const char *zLostAndFound, /* Base name for orphans table */
6985 int nCol /* Number of user data columns */
dan98c5ad32019-04-26 21:11:37 +00006986){
6987 RecoverTable *pTab = 0;
6988 if( nCol>=0 && *pRc==SQLITE_OK ){
6989 int i;
dan42ebb012019-04-27 18:47:03 +00006990
6991 /* This block determines the name of the orphan table. The prefered
6992 ** name is zLostAndFound. But if that clashes with another name
6993 ** in the recovered schema, try zLostAndFound_0, zLostAndFound_1
6994 ** and so on until a non-clashing name is found. */
6995 int iTab = 0;
6996 char *zTab = shellMPrintf(pRc, "%s", zLostAndFound);
6997 sqlite3_stmt *pTest = 0;
6998 shellPrepare(pState->db, pRc,
6999 "SELECT 1 FROM recovery.schema WHERE name=?", &pTest
dan68cb86e2019-04-20 20:57:28 +00007000 );
dan42ebb012019-04-27 18:47:03 +00007001 if( pTest ) sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
7002 while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pTest) ){
7003 shellReset(pRc, pTest);
7004 sqlite3_free(zTab);
7005 zTab = shellMPrintf(pRc, "%s_%d", zLostAndFound, iTab++);
7006 sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
dan68cb86e2019-04-20 20:57:28 +00007007 }
dan42ebb012019-04-27 18:47:03 +00007008 shellFinalize(pRc, pTest);
dan68cb86e2019-04-20 20:57:28 +00007009
dan98c5ad32019-04-26 21:11:37 +00007010 pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable));
7011 if( pTab ){
drha2de66c2019-08-06 20:26:17 +00007012 pTab->zQuoted = shellMPrintf(pRc, "\"%w\"", zTab);
dan98c5ad32019-04-26 21:11:37 +00007013 pTab->nCol = nCol;
7014 pTab->iPk = -2;
7015 if( nCol>0 ){
7016 pTab->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * (nCol+1));
7017 if( pTab->azlCol ){
7018 pTab->azlCol[nCol] = shellMPrintf(pRc, "");
7019 for(i=nCol-1; i>=0; i--){
7020 pTab->azlCol[i] = shellMPrintf(pRc, "%s, NULL", pTab->azlCol[i+1]);
7021 }
7022 }
danb40af492019-04-22 20:52:12 +00007023 }
dan68cb86e2019-04-20 20:57:28 +00007024
dan42ebb012019-04-27 18:47:03 +00007025 if( *pRc!=SQLITE_OK ){
7026 recoverFreeTable(pTab);
7027 pTab = 0;
7028 }else{
7029 raw_printf(pState->out,
7030 "CREATE TABLE %s(rootpgno INTEGER, "
7031 "pgno INTEGER, nfield INTEGER, id INTEGER", pTab->zQuoted
7032 );
7033 for(i=0; i<nCol; i++){
7034 raw_printf(pState->out, ", c%d", i);
7035 }
7036 raw_printf(pState->out, ");\n");
7037 }
dan98c5ad32019-04-26 21:11:37 +00007038 }
dan42ebb012019-04-27 18:47:03 +00007039 sqlite3_free(zTab);
dan68cb86e2019-04-20 20:57:28 +00007040 }
dan98c5ad32019-04-26 21:11:37 +00007041 return pTab;
dan68cb86e2019-04-20 20:57:28 +00007042}
7043
7044/*
7045** This function is called to recover data from the database. A script
7046** to construct a new database containing all recovered data is output
7047** on stream pState->out.
7048*/
danb9b71db2019-04-25 16:20:40 +00007049static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
dan68cb86e2019-04-20 20:57:28 +00007050 int rc = SQLITE_OK;
7051 sqlite3_stmt *pLoop = 0; /* Loop through all root pages */
danefa363b2019-04-24 20:48:55 +00007052 sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */
7053 sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */
danc0b42432019-04-26 15:14:53 +00007054 const char *zRecoveryDb = ""; /* Name of "recovery" database */
dan42ebb012019-04-27 18:47:03 +00007055 const char *zLostAndFound = "lost_and_found";
dan9c014f82019-04-25 19:23:15 +00007056 int i;
dan98c5ad32019-04-26 21:11:37 +00007057 int nOrphan = -1;
7058 RecoverTable *pOrphan = 0;
dan9c014f82019-04-25 19:23:15 +00007059
7060 int bFreelist = 1; /* 0 if --freelist-corrupt is specified */
dan8cce6b82019-09-14 16:44:51 +00007061 int bRowids = 1; /* 0 if --no-rowids */
dan9c014f82019-04-25 19:23:15 +00007062 for(i=1; i<nArg; i++){
7063 char *z = azArg[i];
7064 int n;
7065 if( z[0]=='-' && z[1]=='-' ) z++;
drh4245e042019-06-13 13:52:46 +00007066 n = strlen30(z);
dan9c014f82019-04-25 19:23:15 +00007067 if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
7068 bFreelist = 0;
dan42ebb012019-04-27 18:47:03 +00007069 }else
danc0b42432019-04-26 15:14:53 +00007070 if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
7071 i++;
7072 zRecoveryDb = azArg[i];
dan42ebb012019-04-27 18:47:03 +00007073 }else
7074 if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
7075 i++;
7076 zLostAndFound = azArg[i];
dan8cce6b82019-09-14 16:44:51 +00007077 }else
7078 if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
7079 bRowids = 0;
danc0b42432019-04-26 15:14:53 +00007080 }
dan9c014f82019-04-25 19:23:15 +00007081 else{
drhe2754c12019-08-26 12:50:01 +00007082 utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
7083 showHelp(pState->out, azArg[0]);
dan9c014f82019-04-25 19:23:15 +00007084 return 1;
7085 }
7086 }
dan68cb86e2019-04-20 20:57:28 +00007087
danc0b42432019-04-26 15:14:53 +00007088 shellExecPrintf(pState->db, &rc,
dan68cb86e2019-04-20 20:57:28 +00007089 /* Attach an in-memory database named 'recovery'. Create an indexed
7090 ** cache of the sqlite_dbptr virtual table. */
dan01c08bc2019-07-24 19:20:30 +00007091 "PRAGMA writable_schema = on;"
danc0b42432019-04-26 15:14:53 +00007092 "ATTACH %Q AS recovery;"
7093 "DROP TABLE IF EXISTS recovery.dbptr;"
7094 "DROP TABLE IF EXISTS recovery.freelist;"
7095 "DROP TABLE IF EXISTS recovery.map;"
7096 "DROP TABLE IF EXISTS recovery.schema;"
danc0b42432019-04-26 15:14:53 +00007097 "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb
dan9c014f82019-04-25 19:23:15 +00007098 );
7099
7100 if( bFreelist ){
7101 shellExec(pState->db, &rc,
7102 "WITH trunk(pgno) AS ("
7103 " SELECT shell_int32("
7104 " (SELECT data FROM sqlite_dbpage WHERE pgno=1), 8) AS x "
7105 " WHERE x>0"
7106 " UNION"
7107 " SELECT shell_int32("
7108 " (SELECT data FROM sqlite_dbpage WHERE pgno=trunk.pgno), 0) AS x "
7109 " FROM trunk WHERE x>0"
7110 "),"
7111 "freelist(data, n, freepgno) AS ("
danf6099e92019-05-09 16:57:39 +00007112 " SELECT data, min(16384, shell_int32(data, 1)-1), t.pgno "
dan9c014f82019-04-25 19:23:15 +00007113 " FROM trunk t, sqlite_dbpage s WHERE s.pgno=t.pgno"
7114 " UNION ALL"
7115 " SELECT data, n-1, shell_int32(data, 2+n) "
7116 " FROM freelist WHERE n>=0"
7117 ")"
7118 "REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;"
7119 );
7120 }
7121
dan95063c22019-07-24 08:15:09 +00007122 /* If this is an auto-vacuum database, add all pointer-map pages to
7123 ** the freelist table. Do this regardless of whether or not
7124 ** --freelist-corrupt was specified. */
7125 shellExec(pState->db, &rc,
7126 "WITH ptrmap(pgno) AS ("
7127 " SELECT 2 WHERE shell_int32("
7128 " (SELECT data FROM sqlite_dbpage WHERE pgno=1), 13"
7129 " )"
7130 " UNION ALL "
7131 " SELECT pgno+1+(SELECT page_size FROM pragma_page_size)/5 AS pp "
7132 " FROM ptrmap WHERE pp<=(SELECT page_count FROM pragma_page_count)"
7133 ")"
7134 "REPLACE INTO recovery.freelist SELECT pgno FROM ptrmap"
7135 );
7136
dan9c014f82019-04-25 19:23:15 +00007137 shellExec(pState->db, &rc,
danca424382019-04-26 15:40:27 +00007138 "CREATE TABLE recovery.dbptr("
7139 " pgno, child, PRIMARY KEY(child, pgno)"
7140 ") WITHOUT ROWID;"
7141 "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) "
7142 " SELECT * FROM sqlite_dbptr"
7143 " WHERE pgno NOT IN freelist AND child NOT IN freelist;"
7144
7145 /* Delete any pointer to page 1. This ensures that page 1 is considered
7146 ** a root page, regardless of how corrupt the db is. */
7147 "DELETE FROM recovery.dbptr WHERE child = 1;"
7148
7149 /* Delete all pointers to any pages that have more than one pointer
7150 ** to them. Such pages will be treated as root pages when recovering
7151 ** data. */
7152 "DELETE FROM recovery.dbptr WHERE child IN ("
7153 " SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1"
7154 ");"
7155
dan68cb86e2019-04-20 20:57:28 +00007156 /* Create the "map" table that will (eventually) contain instructions
7157 ** for dealing with each page in the db that contains one or more
7158 ** records. */
danb40af492019-04-22 20:52:12 +00007159 "CREATE TABLE recovery.map("
7160 "pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT"
7161 ");"
dan68cb86e2019-04-20 20:57:28 +00007162
7163 /* Populate table [map]. If there are circular loops of pages in the
7164 ** database, the following adds all pages in such a loop to the map
7165 ** as individual root pages. This could be handled better. */
7166 "WITH pages(i, maxlen) AS ("
danb9b71db2019-04-25 16:20:40 +00007167 " SELECT page_count, ("
7168 " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count"
dan13b87672019-05-09 11:45:21 +00007169 " ) FROM pragma_page_count WHERE page_count>0"
dan68cb86e2019-04-20 20:57:28 +00007170 " UNION ALL"
danb40af492019-04-22 20:52:12 +00007171 " SELECT i-1, ("
7172 " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1"
7173 " ) FROM pages WHERE i>=2"
dan68cb86e2019-04-20 20:57:28 +00007174 ")"
danb40af492019-04-22 20:52:12 +00007175 "INSERT INTO recovery.map(pgno, maxlen, intkey, root) "
7176 " SELECT i, maxlen, NULL, ("
dan68cb86e2019-04-20 20:57:28 +00007177 " WITH p(orig, pgno, parent) AS ("
7178 " SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)"
dan39e04f82019-05-09 18:33:32 +00007179 " UNION "
dan68cb86e2019-04-20 20:57:28 +00007180 " SELECT i, p.parent, "
7181 " (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p"
7182 " )"
7183 " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
7184 ") "
dand790c9a2019-08-26 14:57:58 +00007185 "FROM pages WHERE maxlen IS NOT NULL AND i NOT IN freelist;"
danb40af492019-04-22 20:52:12 +00007186 "UPDATE recovery.map AS o SET intkey = ("
7187 " SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno"
7188 ");"
dan68cb86e2019-04-20 20:57:28 +00007189
7190 /* Extract data from page 1 and any linked pages into table
drh067b92b2020-06-19 15:24:12 +00007191 ** recovery.schema. With the same schema as an sqlite_schema table. */
dan68cb86e2019-04-20 20:57:28 +00007192 "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
7193 "INSERT INTO recovery.schema SELECT "
7194 " max(CASE WHEN field=0 THEN value ELSE NULL END),"
7195 " max(CASE WHEN field=1 THEN value ELSE NULL END),"
7196 " max(CASE WHEN field=2 THEN value ELSE NULL END),"
7197 " max(CASE WHEN field=3 THEN value ELSE NULL END),"
7198 " max(CASE WHEN field=4 THEN value ELSE NULL END)"
7199 "FROM sqlite_dbdata WHERE pgno IN ("
7200 " SELECT pgno FROM recovery.map WHERE root=1"
7201 ")"
7202 "GROUP BY pgno, cell;"
dan98c5ad32019-04-26 21:11:37 +00007203 "CREATE INDEX recovery.schema_rootpage ON schema(rootpage);"
dan68cb86e2019-04-20 20:57:28 +00007204 );
7205
danb40af492019-04-22 20:52:12 +00007206 /* Open a transaction, then print out all non-virtual, non-"sqlite_%"
7207 ** CREATE TABLE statements that extracted from the existing schema. */
7208 if( rc==SQLITE_OK ){
7209 sqlite3_stmt *pStmt = 0;
danf3210572019-08-06 18:40:36 +00007210 /* ".recover" might output content in an order which causes immediate
7211 ** foreign key constraints to be violated. So disable foreign-key
7212 ** constraint enforcement to prevent problems when running the output
7213 ** script. */
7214 raw_printf(pState->out, "PRAGMA foreign_keys=OFF;\n");
danb40af492019-04-22 20:52:12 +00007215 raw_printf(pState->out, "BEGIN;\n");
dan38f9c712019-04-23 18:03:02 +00007216 raw_printf(pState->out, "PRAGMA writable_schema = on;\n");
7217 shellPrepare(pState->db, &rc,
danb40af492019-04-22 20:52:12 +00007218 "SELECT sql FROM recovery.schema "
dan38f9c712019-04-23 18:03:02 +00007219 "WHERE type='table' AND sql LIKE 'create table%'", &pStmt
danb40af492019-04-22 20:52:12 +00007220 );
7221 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
7222 const char *zCreateTable = (const char*)sqlite3_column_text(pStmt, 0);
dan38f9c712019-04-23 18:03:02 +00007223 raw_printf(pState->out, "CREATE TABLE IF NOT EXISTS %s;\n",
7224 &zCreateTable[12]
7225 );
danb40af492019-04-22 20:52:12 +00007226 }
7227 shellFinalize(&rc, pStmt);
7228 }
7229
dan98c5ad32019-04-26 21:11:37 +00007230 /* Figure out if an orphan table will be required. And if so, how many
7231 ** user columns it should contain */
7232 shellPrepare(pState->db, &rc,
dan98779652019-05-09 14:15:19 +00007233 "SELECT coalesce(max(maxlen), -2) FROM recovery.map WHERE root>1"
dan98c5ad32019-04-26 21:11:37 +00007234 , &pLoop
7235 );
7236 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
7237 nOrphan = sqlite3_column_int(pLoop, 0);
7238 }
7239 shellFinalize(&rc, pLoop);
7240 pLoop = 0;
dan98c5ad32019-04-26 21:11:37 +00007241
danefa363b2019-04-24 20:48:55 +00007242 shellPrepare(pState->db, &rc,
7243 "SELECT pgno FROM recovery.map WHERE root=?", &pPages
7244 );
dan8cce6b82019-09-14 16:44:51 +00007245
danefa363b2019-04-24 20:48:55 +00007246 shellPrepare(pState->db, &rc,
dan8cce6b82019-09-14 16:44:51 +00007247 "SELECT max(field), group_concat(shell_escape_crnl(quote"
7248 "(case when (? AND field<0) then NULL else value end)"
7249 "), ', ')"
dan9443dbc2019-07-24 20:10:27 +00007250 ", min(field) "
danefa363b2019-04-24 20:48:55 +00007251 "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
7252 "GROUP BY cell", &pCells
7253 );
7254
dan68cb86e2019-04-20 20:57:28 +00007255 /* Loop through each root page. */
danb40af492019-04-22 20:52:12 +00007256 shellPrepare(pState->db, &rc,
7257 "SELECT root, intkey, max(maxlen) FROM recovery.map"
dan38f9c712019-04-23 18:03:02 +00007258 " WHERE root>1 GROUP BY root, intkey ORDER BY root=("
7259 " SELECT rootpage FROM recovery.schema WHERE name='sqlite_sequence'"
7260 ")", &pLoop
danb40af492019-04-22 20:52:12 +00007261 );
dan68cb86e2019-04-20 20:57:28 +00007262 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
7263 int iRoot = sqlite3_column_int(pLoop, 0);
danb40af492019-04-22 20:52:12 +00007264 int bIntkey = sqlite3_column_int(pLoop, 1);
7265 int nCol = sqlite3_column_int(pLoop, 2);
dan98c5ad32019-04-26 21:11:37 +00007266 int bNoop = 0;
dan68cb86e2019-04-20 20:57:28 +00007267 RecoverTable *pTab;
7268
dan9443dbc2019-07-24 20:10:27 +00007269 assert( bIntkey==0 || bIntkey==1 );
dan42ebb012019-04-27 18:47:03 +00007270 pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
dan98c5ad32019-04-26 21:11:37 +00007271 if( bNoop || rc ) continue;
dan98779652019-05-09 14:15:19 +00007272 if( pTab==0 ){
7273 if( pOrphan==0 ){
7274 pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
7275 }
7276 pTab = pOrphan;
7277 if( pTab==0 ) break;
7278 }
dan98c5ad32019-04-26 21:11:37 +00007279
drha2de66c2019-08-06 20:26:17 +00007280 if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){
dan98c5ad32019-04-26 21:11:37 +00007281 raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
7282 }
7283 sqlite3_bind_int(pPages, 1, iRoot);
dan8cce6b82019-09-14 16:44:51 +00007284 if( bRowids==0 && pTab->iPk<0 ){
7285 sqlite3_bind_int(pCells, 1, 1);
7286 }else{
7287 sqlite3_bind_int(pCells, 1, 0);
7288 }
7289 sqlite3_bind_int(pCells, 3, pTab->iPk);
dan98c5ad32019-04-26 21:11:37 +00007290
7291 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
7292 int iPgno = sqlite3_column_int(pPages, 0);
dan8cce6b82019-09-14 16:44:51 +00007293 sqlite3_bind_int(pCells, 2, iPgno);
dan98c5ad32019-04-26 21:11:37 +00007294 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
7295 int nField = sqlite3_column_int(pCells, 0);
dan9443dbc2019-07-24 20:10:27 +00007296 int iMin = sqlite3_column_int(pCells, 2);
dan98c5ad32019-04-26 21:11:37 +00007297 const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
7298
dan9443dbc2019-07-24 20:10:27 +00007299 RecoverTable *pTab2 = pTab;
7300 if( pTab!=pOrphan && (iMin<0)!=bIntkey ){
7301 if( pOrphan==0 ){
7302 pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
7303 }
7304 pTab2 = pOrphan;
7305 if( pTab2==0 ) break;
7306 }
7307
dan98c5ad32019-04-26 21:11:37 +00007308 nField = nField+1;
dan9443dbc2019-07-24 20:10:27 +00007309 if( pTab2==pOrphan ){
dan98c5ad32019-04-26 21:11:37 +00007310 raw_printf(pState->out,
7311 "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
dan9443dbc2019-07-24 20:10:27 +00007312 pTab2->zQuoted, iRoot, iPgno, nField,
7313 iMin<0 ? "" : "NULL, ", zVal, pTab2->azlCol[nField]
dan98c5ad32019-04-26 21:11:37 +00007314 );
7315 }else{
danefa363b2019-04-24 20:48:55 +00007316 raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n",
dan9443dbc2019-07-24 20:10:27 +00007317 pTab2->zQuoted, pTab2->azlCol[nField], zVal
danefa363b2019-04-24 20:48:55 +00007318 );
7319 }
dan68cb86e2019-04-20 20:57:28 +00007320 }
dan98c5ad32019-04-26 21:11:37 +00007321 shellReset(&rc, pCells);
dan68cb86e2019-04-20 20:57:28 +00007322 }
dan98c5ad32019-04-26 21:11:37 +00007323 shellReset(&rc, pPages);
7324 if( pTab!=pOrphan ) recoverFreeTable(pTab);
dan68cb86e2019-04-20 20:57:28 +00007325 }
7326 shellFinalize(&rc, pLoop);
danefa363b2019-04-24 20:48:55 +00007327 shellFinalize(&rc, pPages);
7328 shellFinalize(&rc, pCells);
dan98c5ad32019-04-26 21:11:37 +00007329 recoverFreeTable(pOrphan);
dan68cb86e2019-04-20 20:57:28 +00007330
dan38f9c712019-04-23 18:03:02 +00007331 /* The rest of the schema */
danb40af492019-04-22 20:52:12 +00007332 if( rc==SQLITE_OK ){
dan38f9c712019-04-23 18:03:02 +00007333 sqlite3_stmt *pStmt = 0;
7334 shellPrepare(pState->db, &rc,
7335 "SELECT sql, name FROM recovery.schema "
danb1825882019-04-23 20:48:32 +00007336 "WHERE sql NOT LIKE 'create table%'", &pStmt
dan38f9c712019-04-23 18:03:02 +00007337 );
7338 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
7339 const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
7340 if( sqlite3_strnicmp(zSql, "create virt", 11)==0 ){
7341 const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
7342 char *zPrint = shellMPrintf(&rc,
drh067b92b2020-06-19 15:24:12 +00007343 "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
dan38f9c712019-04-23 18:03:02 +00007344 zName, zName, zSql
7345 );
7346 raw_printf(pState->out, "%s;\n", zPrint);
7347 sqlite3_free(zPrint);
7348 }else{
7349 raw_printf(pState->out, "%s;\n", zSql);
7350 }
7351 }
7352 shellFinalize(&rc, pStmt);
7353 }
7354
7355 if( rc==SQLITE_OK ){
7356 raw_printf(pState->out, "PRAGMA writable_schema = off;\n");
danb40af492019-04-22 20:52:12 +00007357 raw_printf(pState->out, "COMMIT;\n");
7358 }
dan68cb86e2019-04-20 20:57:28 +00007359 sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
7360 return rc;
7361}
dan1b162162019-04-27 20:15:15 +00007362#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
dan68cb86e2019-04-20 20:57:28 +00007363
drh2ce15c32017-07-11 13:34:40 +00007364
7365/*
7366** If an input line begins with "." then invoke this routine to
7367** process that line.
7368**
7369** Return 1 on error, 2 to exit, and 0 otherwise.
7370*/
7371static int do_meta_command(char *zLine, ShellState *p){
7372 int h = 1;
7373 int nArg = 0;
7374 int n, c;
7375 int rc = 0;
drh5df84282019-08-17 19:45:25 +00007376 char *azArg[52];
drh2ce15c32017-07-11 13:34:40 +00007377
dan6b046be2018-01-09 15:25:55 +00007378#ifndef SQLITE_OMIT_VIRTUALTABLE
dan43efc182017-12-19 17:42:13 +00007379 if( p->expert.pExpert ){
7380 expertFinish(p, 1, 0);
7381 }
dan6b046be2018-01-09 15:25:55 +00007382#endif
dan43efc182017-12-19 17:42:13 +00007383
drh2ce15c32017-07-11 13:34:40 +00007384 /* Parse the input line into tokens.
7385 */
drh5df84282019-08-17 19:45:25 +00007386 while( zLine[h] && nArg<ArraySize(azArg)-1 ){
drh2ce15c32017-07-11 13:34:40 +00007387 while( IsSpace(zLine[h]) ){ h++; }
7388 if( zLine[h]==0 ) break;
7389 if( zLine[h]=='\'' || zLine[h]=='"' ){
7390 int delim = zLine[h++];
7391 azArg[nArg++] = &zLine[h];
7392 while( zLine[h] && zLine[h]!=delim ){
7393 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
7394 h++;
7395 }
7396 if( zLine[h]==delim ){
7397 zLine[h++] = 0;
7398 }
7399 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
7400 }else{
7401 azArg[nArg++] = &zLine[h];
7402 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
7403 if( zLine[h] ) zLine[h++] = 0;
7404 resolve_backslashes(azArg[nArg-1]);
7405 }
7406 }
drh5df84282019-08-17 19:45:25 +00007407 azArg[nArg] = 0;
drh2ce15c32017-07-11 13:34:40 +00007408
7409 /* Process the input line.
7410 */
7411 if( nArg==0 ) return 0; /* no tokens, no error */
7412 n = strlen30(azArg[0]);
7413 c = azArg[0][0];
drh13c20932018-01-10 21:41:55 +00007414 clearTempFile(p);
drh2ce15c32017-07-11 13:34:40 +00007415
7416#ifndef SQLITE_OMIT_AUTHORIZATION
7417 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
7418 if( nArg!=2 ){
7419 raw_printf(stderr, "Usage: .auth ON|OFF\n");
7420 rc = 1;
7421 goto meta_command_exit;
7422 }
7423 open_db(p, 0);
7424 if( booleanValue(azArg[1]) ){
7425 sqlite3_set_authorizer(p->db, shellAuth, p);
7426 }else{
7427 sqlite3_set_authorizer(p->db, 0, 0);
7428 }
7429 }else
7430#endif
7431
drhe37c0e12018-01-06 19:19:50 +00007432#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
7433 if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
danfd0245d2017-12-07 15:44:29 +00007434 open_db(p, 0);
drhd0f9cdc2018-05-17 14:09:06 +00007435 rc = arDotCommand(p, 0, azArg, nArg);
danfd0245d2017-12-07 15:44:29 +00007436 }else
7437#endif
7438
drh2ce15c32017-07-11 13:34:40 +00007439 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
7440 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
7441 ){
7442 const char *zDestFile = 0;
7443 const char *zDb = 0;
7444 sqlite3 *pDest;
7445 sqlite3_backup *pBackup;
7446 int j;
drha50bffb2018-12-08 01:09:14 +00007447 int bAsync = 0;
drh69ed38a2018-05-14 00:23:08 +00007448 const char *zVfs = 0;
drh2ce15c32017-07-11 13:34:40 +00007449 for(j=1; j<nArg; j++){
7450 const char *z = azArg[j];
7451 if( z[0]=='-' ){
drh69ed38a2018-05-14 00:23:08 +00007452 if( z[1]=='-' ) z++;
7453 if( strcmp(z, "-append")==0 ){
7454 zVfs = "apndvfs";
7455 }else
drha50bffb2018-12-08 01:09:14 +00007456 if( strcmp(z, "-async")==0 ){
7457 bAsync = 1;
7458 }else
drh2ce15c32017-07-11 13:34:40 +00007459 {
7460 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
7461 return 1;
7462 }
7463 }else if( zDestFile==0 ){
7464 zDestFile = azArg[j];
7465 }else if( zDb==0 ){
7466 zDb = zDestFile;
7467 zDestFile = azArg[j];
7468 }else{
drha50bffb2018-12-08 01:09:14 +00007469 raw_printf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n");
drh2ce15c32017-07-11 13:34:40 +00007470 return 1;
7471 }
7472 }
7473 if( zDestFile==0 ){
7474 raw_printf(stderr, "missing FILENAME argument on .backup\n");
7475 return 1;
7476 }
7477 if( zDb==0 ) zDb = "main";
drh69ed38a2018-05-14 00:23:08 +00007478 rc = sqlite3_open_v2(zDestFile, &pDest,
7479 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
drh2ce15c32017-07-11 13:34:40 +00007480 if( rc!=SQLITE_OK ){
7481 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9e804032018-05-18 17:11:50 +00007482 close_db(pDest);
drh2ce15c32017-07-11 13:34:40 +00007483 return 1;
7484 }
drha50bffb2018-12-08 01:09:14 +00007485 if( bAsync ){
7486 sqlite3_exec(pDest, "PRAGMA synchronous=OFF; PRAGMA journal_mode=OFF;",
7487 0, 0, 0);
7488 }
drh2ce15c32017-07-11 13:34:40 +00007489 open_db(p, 0);
7490 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
7491 if( pBackup==0 ){
7492 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9e804032018-05-18 17:11:50 +00007493 close_db(pDest);
drh2ce15c32017-07-11 13:34:40 +00007494 return 1;
7495 }
7496 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
7497 sqlite3_backup_finish(pBackup);
7498 if( rc==SQLITE_DONE ){
7499 rc = 0;
7500 }else{
7501 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
7502 rc = 1;
7503 }
drh9e804032018-05-18 17:11:50 +00007504 close_db(pDest);
drh2ce15c32017-07-11 13:34:40 +00007505 }else
7506
7507 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
7508 if( nArg==2 ){
7509 bail_on_error = booleanValue(azArg[1]);
7510 }else{
7511 raw_printf(stderr, "Usage: .bail on|off\n");
7512 rc = 1;
7513 }
7514 }else
7515
7516 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
7517 if( nArg==2 ){
7518 if( booleanValue(azArg[1]) ){
7519 setBinaryMode(p->out, 1);
7520 }else{
7521 setTextMode(p->out, 1);
7522 }
7523 }else{
7524 raw_printf(stderr, "Usage: .binary on|off\n");
7525 rc = 1;
7526 }
7527 }else
7528
7529 if( c=='c' && strcmp(azArg[0],"cd")==0 ){
7530 if( nArg==2 ){
7531#if defined(_WIN32) || defined(WIN32)
7532 wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
7533 rc = !SetCurrentDirectoryW(z);
7534 sqlite3_free(z);
7535#else
7536 rc = chdir(azArg[1]);
7537#endif
7538 if( rc ){
7539 utf8_printf(stderr, "Cannot change to directory \"%s\"\n", azArg[1]);
7540 rc = 1;
7541 }
7542 }else{
7543 raw_printf(stderr, "Usage: .cd DIRECTORY\n");
7544 rc = 1;
7545 }
7546 }else
7547
7548 /* The undocumented ".breakpoint" command causes a call to the no-op
7549 ** routine named test_breakpoint().
7550 */
7551 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
7552 test_breakpoint();
7553 }else
7554
7555 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
7556 if( nArg==2 ){
7557 setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
7558 }else{
7559 raw_printf(stderr, "Usage: .changes on|off\n");
7560 rc = 1;
7561 }
7562 }else
7563
7564 /* Cancel output redirection, if it is currently set (by .testcase)
7565 ** Then read the content of the testcase-out.txt file and compare against
7566 ** azArg[1]. If there are differences, report an error and exit.
7567 */
7568 if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
7569 char *zRes = 0;
7570 output_reset(p);
7571 if( nArg!=2 ){
7572 raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
7573 rc = 2;
7574 }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
7575 raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
7576 rc = 2;
7577 }else if( testcase_glob(azArg[1],zRes)==0 ){
7578 utf8_printf(stderr,
7579 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
7580 p->zTestcase, azArg[1], zRes);
drhf30d3452017-10-17 13:44:46 +00007581 rc = 1;
drh2ce15c32017-07-11 13:34:40 +00007582 }else{
7583 utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
7584 p->nCheck++;
7585 }
7586 sqlite3_free(zRes);
7587 }else
7588
7589 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
7590 if( nArg==2 ){
7591 tryToClone(p, azArg[1]);
7592 }else{
7593 raw_printf(stderr, "Usage: .clone FILENAME\n");
7594 rc = 1;
7595 }
7596 }else
7597
7598 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drh60081a02020-08-26 19:07:18 +00007599 char **azName = 0;
7600 int nName = 0;
7601 sqlite3_stmt *pStmt;
drh60081a02020-08-26 19:07:18 +00007602 int i;
drh2ce15c32017-07-11 13:34:40 +00007603 open_db(p, 0);
drh60081a02020-08-26 19:07:18 +00007604 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
7605 if( rc ){
7606 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh2ce15c32017-07-11 13:34:40 +00007607 rc = 1;
drh60081a02020-08-26 19:07:18 +00007608 }else{
7609 while( sqlite3_step(pStmt)==SQLITE_ROW ){
7610 const char *zSchema = (const char *)sqlite3_column_text(pStmt,1);
7611 const char *zFile = (const char*)sqlite3_column_text(pStmt,2);
7612 azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*));
7613 if( azName==0 ){ shell_out_of_memory(); /* Does not return */ }
7614 azName[nName*2] = strdup(zSchema);
7615 azName[nName*2+1] = strdup(zFile);
7616 nName++;
7617 }
drh2ce15c32017-07-11 13:34:40 +00007618 }
drh60081a02020-08-26 19:07:18 +00007619 sqlite3_finalize(pStmt);
7620 for(i=0; i<nName; i++){
7621 int eTxn = sqlite3_txn_state(p->db, azName[i*2]);
7622 int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]);
7623 const char *z = azName[i*2+1];
7624 utf8_printf(p->out, "%s: %s %s%s\n",
7625 azName[i*2],
7626 z && z[0] ? z : "\"\"",
7627 bRdonly ? "r/o" : "r/w",
7628 eTxn==SQLITE_TXN_NONE ? "" :
7629 eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn");
7630 free(azName[i*2]);
7631 free(azName[i*2+1]);
7632 }
7633 sqlite3_free(azName);
drh2ce15c32017-07-11 13:34:40 +00007634 }else
7635
drh7df01192018-04-28 12:43:16 +00007636 if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
drheb7f2a02018-09-26 18:02:32 +00007637 static const struct DbConfigChoices {
7638 const char *zName;
7639 int op;
7640 } aDbConfig[] = {
drhb945bcd2019-12-31 22:52:10 +00007641 { "defensive", SQLITE_DBCONFIG_DEFENSIVE },
7642 { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
7643 { "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
drh0a6873b2019-06-14 21:25:25 +00007644 { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
drhb945bcd2019-12-31 22:52:10 +00007645 { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
drh0a6873b2019-06-14 21:25:25 +00007646 { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
drh11d88e62019-08-15 21:27:20 +00007647 { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
drh0a6873b2019-06-14 21:25:25 +00007648 { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
drhb945bcd2019-12-31 22:52:10 +00007649 { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
7650 { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT },
drh0a6873b2019-06-14 21:25:25 +00007651 { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
7652 { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
drh0a6873b2019-06-14 21:25:25 +00007653 { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
drhb945bcd2019-12-31 22:52:10 +00007654 { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
drhb77da372020-01-07 16:09:11 +00007655 { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA },
dan07312a62019-06-21 14:05:27 +00007656 { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA },
drh7df01192018-04-28 12:43:16 +00007657 };
7658 int ii, v;
7659 open_db(p, 0);
7660 for(ii=0; ii<ArraySize(aDbConfig); ii++){
7661 if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
7662 if( nArg>=3 ){
7663 sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
7664 }
7665 sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
drhb945bcd2019-12-31 22:52:10 +00007666 utf8_printf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
drh7df01192018-04-28 12:43:16 +00007667 if( nArg>1 ) break;
7668 }
7669 if( nArg>1 && ii==ArraySize(aDbConfig) ){
7670 utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
7671 utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
7672 }
7673 }else
7674
7675 if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
drh2ce15c32017-07-11 13:34:40 +00007676 rc = shell_dbinfo_command(p, nArg, azArg);
7677 }else
7678
dan1b162162019-04-27 20:15:15 +00007679#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
dan68cb86e2019-04-20 20:57:28 +00007680 if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
7681 open_db(p, 0);
danb9b71db2019-04-25 16:20:40 +00007682 rc = recoverDatabaseCmd(p, nArg, azArg);
dan68cb86e2019-04-20 20:57:28 +00007683 }else
dan1b162162019-04-27 20:15:15 +00007684#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
dan68cb86e2019-04-20 20:57:28 +00007685
drh2ce15c32017-07-11 13:34:40 +00007686 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh8e9297f2020-03-25 12:50:13 +00007687 char *zLike = 0;
7688 char *zSql;
drh2ce15c32017-07-11 13:34:40 +00007689 int i;
7690 int savedShowHeader = p->showHeader;
drhf213b332018-07-05 17:35:46 +00007691 int savedShellFlags = p->shellFlgs;
drhc1962192020-10-12 16:54:28 +00007692 ShellClearFlag(p,
7693 SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo
7694 |SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
drh2ce15c32017-07-11 13:34:40 +00007695 for(i=1; i<nArg; i++){
7696 if( azArg[i][0]=='-' ){
7697 const char *z = azArg[i]+1;
7698 if( z[0]=='-' ) z++;
7699 if( strcmp(z,"preserve-rowids")==0 ){
7700#ifdef SQLITE_OMIT_VIRTUALTABLE
7701 raw_printf(stderr, "The --preserve-rowids option is not compatible"
7702 " with SQLITE_OMIT_VIRTUALTABLE\n");
7703 rc = 1;
drh1d29fd82020-05-29 19:03:03 +00007704 sqlite3_free(zLike);
drh2ce15c32017-07-11 13:34:40 +00007705 goto meta_command_exit;
7706#else
7707 ShellSetFlag(p, SHFLG_PreserveRowid);
7708#endif
7709 }else
7710 if( strcmp(z,"newlines")==0 ){
7711 ShellSetFlag(p, SHFLG_Newlines);
7712 }else
drhc1962192020-10-12 16:54:28 +00007713 if( strcmp(z,"data-only")==0 ){
7714 ShellSetFlag(p, SHFLG_DumpDataOnly);
7715 }else
7716 if( strcmp(z,"nosys")==0 ){
7717 ShellSetFlag(p, SHFLG_DumpNoSys);
7718 }else
drh2ce15c32017-07-11 13:34:40 +00007719 {
7720 raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
7721 rc = 1;
drh1d29fd82020-05-29 19:03:03 +00007722 sqlite3_free(zLike);
drh2ce15c32017-07-11 13:34:40 +00007723 goto meta_command_exit;
7724 }
7725 }else if( zLike ){
drhcdbb2812020-03-25 20:31:45 +00007726 zLike = sqlite3_mprintf("%z OR name LIKE %Q ESCAPE '\\'",
7727 zLike, azArg[i]);
drh2ce15c32017-07-11 13:34:40 +00007728 }else{
drhcdbb2812020-03-25 20:31:45 +00007729 zLike = sqlite3_mprintf("name LIKE %Q ESCAPE '\\'", azArg[i]);
drh2ce15c32017-07-11 13:34:40 +00007730 }
7731 }
dan68cb86e2019-04-20 20:57:28 +00007732
drh2ce15c32017-07-11 13:34:40 +00007733 open_db(p, 0);
dan68cb86e2019-04-20 20:57:28 +00007734
drhc1962192020-10-12 16:54:28 +00007735 if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
7736 /* When playing back a "dump", the content might appear in an order
7737 ** which causes immediate foreign key constraints to be violated.
7738 ** So disable foreign-key constraint enforcement to prevent problems. */
7739 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
7740 raw_printf(p->out, "BEGIN TRANSACTION;\n");
7741 }
drh2ce15c32017-07-11 13:34:40 +00007742 p->writableSchema = 0;
7743 p->showHeader = 0;
7744 /* Set writable_schema=ON since doing so forces SQLite to initialize
drh067b92b2020-06-19 15:24:12 +00007745 ** as much of the schema as it can even if the sqlite_schema table is
drh2ce15c32017-07-11 13:34:40 +00007746 ** corrupt. */
7747 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
7748 p->nErr = 0;
drh8e9297f2020-03-25 12:50:13 +00007749 if( zLike==0 ) zLike = sqlite3_mprintf("true");
7750 zSql = sqlite3_mprintf(
drh067b92b2020-06-19 15:24:12 +00007751 "SELECT name, type, sql FROM sqlite_schema "
drh8e9297f2020-03-25 12:50:13 +00007752 "WHERE (%s) AND type=='table'"
7753 " AND sql NOT NULL"
7754 " ORDER BY tbl_name='sqlite_sequence', rowid",
7755 zLike
7756 );
7757 run_schema_dump_query(p,zSql);
7758 sqlite3_free(zSql);
drhc1962192020-10-12 16:54:28 +00007759 if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
7760 zSql = sqlite3_mprintf(
7761 "SELECT sql FROM sqlite_schema "
7762 "WHERE (%s) AND sql NOT NULL"
7763 " AND type IN ('index','trigger','view')",
7764 zLike
7765 );
7766 run_table_dump_query(p, zSql);
7767 sqlite3_free(zSql);
7768 }
drh8e9297f2020-03-25 12:50:13 +00007769 sqlite3_free(zLike);
drh2ce15c32017-07-11 13:34:40 +00007770 if( p->writableSchema ){
7771 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
7772 p->writableSchema = 0;
7773 }
7774 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
7775 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
drhc1962192020-10-12 16:54:28 +00007776 if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
7777 raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
7778 }
drh2ce15c32017-07-11 13:34:40 +00007779 p->showHeader = savedShowHeader;
drhf213b332018-07-05 17:35:46 +00007780 p->shellFlgs = savedShellFlags;
drh2ce15c32017-07-11 13:34:40 +00007781 }else
7782
7783 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
7784 if( nArg==2 ){
7785 setOrClearFlag(p, SHFLG_Echo, azArg[1]);
7786 }else{
7787 raw_printf(stderr, "Usage: .echo on|off\n");
7788 rc = 1;
7789 }
7790 }else
7791
7792 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
7793 if( nArg==2 ){
drhe2ca99c2018-05-02 00:33:43 +00007794 p->autoEQPtest = 0;
drhb4e50392019-01-26 15:40:04 +00007795 if( p->autoEQPtrace ){
7796 if( p->db ) sqlite3_exec(p->db, "PRAGMA vdbe_trace=OFF;", 0, 0, 0);
7797 p->autoEQPtrace = 0;
7798 }
drh2ce15c32017-07-11 13:34:40 +00007799 if( strcmp(azArg[1],"full")==0 ){
drhada70452017-12-21 21:02:27 +00007800 p->autoEQP = AUTOEQP_full;
7801 }else if( strcmp(azArg[1],"trigger")==0 ){
7802 p->autoEQP = AUTOEQP_trigger;
drhb4e50392019-01-26 15:40:04 +00007803#ifdef SQLITE_DEBUG
drhe2ca99c2018-05-02 00:33:43 +00007804 }else if( strcmp(azArg[1],"test")==0 ){
7805 p->autoEQP = AUTOEQP_on;
7806 p->autoEQPtest = 1;
drhb4e50392019-01-26 15:40:04 +00007807 }else if( strcmp(azArg[1],"trace")==0 ){
7808 p->autoEQP = AUTOEQP_full;
7809 p->autoEQPtrace = 1;
7810 open_db(p, 0);
drh067b92b2020-06-19 15:24:12 +00007811 sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1", 0, 0, 0);
drhb4e50392019-01-26 15:40:04 +00007812 sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;", 0, 0, 0);
7813#endif
drh2ce15c32017-07-11 13:34:40 +00007814 }else{
mistachkinb71aa092018-01-23 00:05:18 +00007815 p->autoEQP = (u8)booleanValue(azArg[1]);
drh2ce15c32017-07-11 13:34:40 +00007816 }
7817 }else{
drhb4e50392019-01-26 15:40:04 +00007818 raw_printf(stderr, "Usage: .eqp off|on|trace|trigger|full\n");
drh2ce15c32017-07-11 13:34:40 +00007819 rc = 1;
7820 }
7821 }else
7822
7823 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
7824 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
7825 rc = 2;
7826 }else
7827
7828 /* The ".explain" command is automatic now. It is largely pointless. It
7829 ** retained purely for backwards compatibility */
7830 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
7831 int val = 1;
7832 if( nArg>=2 ){
7833 if( strcmp(azArg[1],"auto")==0 ){
7834 val = 99;
7835 }else{
7836 val = booleanValue(azArg[1]);
7837 }
7838 }
7839 if( val==1 && p->mode!=MODE_Explain ){
7840 p->normalMode = p->mode;
7841 p->mode = MODE_Explain;
7842 p->autoExplain = 0;
7843 }else if( val==0 ){
7844 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
7845 p->autoExplain = 0;
7846 }else if( val==99 ){
7847 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
7848 p->autoExplain = 1;
7849 }
7850 }else
7851
dan6b046be2018-01-09 15:25:55 +00007852#ifndef SQLITE_OMIT_VIRTUALTABLE
dan43efc182017-12-19 17:42:13 +00007853 if( c=='e' && strncmp(azArg[0], "expert", n)==0 ){
7854 open_db(p, 0);
7855 expertDotCommand(p, azArg, nArg);
7856 }else
dan6b046be2018-01-09 15:25:55 +00007857#endif
dan43efc182017-12-19 17:42:13 +00007858
drhd985f722019-06-05 14:29:53 +00007859 if( c=='f' && strncmp(azArg[0], "filectrl", n)==0 ){
7860 static const struct {
7861 const char *zCtrlName; /* Name of a test-control option */
7862 int ctrlCode; /* Integer code for that option */
7863 const char *zUsage; /* Usage notes */
7864 } aCtrl[] = {
7865 { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" },
7866 { "chunk_size", SQLITE_FCNTL_CHUNK_SIZE, "SIZE" },
7867 /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/
7868 { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" },
7869 { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" },
7870 /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/
7871 { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" },
7872 { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" },
7873 { "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" },
drh541ef2c2020-04-20 16:21:30 +00007874 { "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" },
drhd985f722019-06-05 14:29:53 +00007875 };
7876 int filectrl = -1;
7877 int iCtrl = -1;
drh4245e042019-06-13 13:52:46 +00007878 sqlite3_int64 iRes = 0; /* Integer result to display if rc2==1 */
7879 int isOk = 0; /* 0: usage 1: %lld 2: no-result */
drhd985f722019-06-05 14:29:53 +00007880 int n2, i;
7881 const char *zCmd = 0;
drh541ef2c2020-04-20 16:21:30 +00007882 const char *zSchema = 0;
drhd985f722019-06-05 14:29:53 +00007883
7884 open_db(p, 0);
7885 zCmd = nArg>=2 ? azArg[1] : "help";
7886
drh541ef2c2020-04-20 16:21:30 +00007887 if( zCmd[0]=='-'
7888 && (strcmp(zCmd,"--schema")==0 || strcmp(zCmd,"-schema")==0)
7889 && nArg>=4
7890 ){
7891 zSchema = azArg[2];
7892 for(i=3; i<nArg; i++) azArg[i-2] = azArg[i];
7893 nArg -= 2;
7894 zCmd = azArg[1];
7895 }
7896
drhd985f722019-06-05 14:29:53 +00007897 /* The argument can optionally begin with "-" or "--" */
7898 if( zCmd[0]=='-' && zCmd[1] ){
7899 zCmd++;
7900 if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
7901 }
7902
7903 /* --help lists all file-controls */
7904 if( strcmp(zCmd,"help")==0 ){
7905 utf8_printf(p->out, "Available file-controls:\n");
7906 for(i=0; i<ArraySize(aCtrl); i++){
7907 utf8_printf(p->out, " .filectrl %s %s\n",
7908 aCtrl[i].zCtrlName, aCtrl[i].zUsage);
7909 }
7910 rc = 1;
7911 goto meta_command_exit;
7912 }
7913
7914 /* convert filectrl text option to value. allow any unique prefix
7915 ** of the option name, or a numerical value. */
7916 n2 = strlen30(zCmd);
7917 for(i=0; i<ArraySize(aCtrl); i++){
7918 if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
7919 if( filectrl<0 ){
7920 filectrl = aCtrl[i].ctrlCode;
7921 iCtrl = i;
7922 }else{
7923 utf8_printf(stderr, "Error: ambiguous file-control: \"%s\"\n"
7924 "Use \".filectrl --help\" for help\n", zCmd);
7925 rc = 1;
7926 goto meta_command_exit;
7927 }
7928 }
7929 }
7930 if( filectrl<0 ){
7931 utf8_printf(stderr,"Error: unknown file-control: %s\n"
7932 "Use \".filectrl --help\" for help\n", zCmd);
7933 }else{
7934 switch(filectrl){
7935 case SQLITE_FCNTL_SIZE_LIMIT: {
7936 if( nArg!=2 && nArg!=3 ) break;
7937 iRes = nArg==3 ? integerValue(azArg[2]) : -1;
drh541ef2c2020-04-20 16:21:30 +00007938 sqlite3_file_control(p->db, zSchema, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
drhd985f722019-06-05 14:29:53 +00007939 isOk = 1;
7940 break;
7941 }
7942 case SQLITE_FCNTL_LOCK_TIMEOUT:
7943 case SQLITE_FCNTL_CHUNK_SIZE: {
7944 int x;
7945 if( nArg!=3 ) break;
7946 x = (int)integerValue(azArg[2]);
drh541ef2c2020-04-20 16:21:30 +00007947 sqlite3_file_control(p->db, zSchema, filectrl, &x);
drhd985f722019-06-05 14:29:53 +00007948 isOk = 2;
7949 break;
7950 }
7951 case SQLITE_FCNTL_PERSIST_WAL:
7952 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
7953 int x;
7954 if( nArg!=2 && nArg!=3 ) break;
7955 x = nArg==3 ? booleanValue(azArg[2]) : -1;
drh541ef2c2020-04-20 16:21:30 +00007956 sqlite3_file_control(p->db, zSchema, filectrl, &x);
drhd985f722019-06-05 14:29:53 +00007957 iRes = x;
7958 isOk = 1;
7959 break;
7960 }
7961 case SQLITE_FCNTL_HAS_MOVED: {
7962 int x;
7963 if( nArg!=2 ) break;
drh541ef2c2020-04-20 16:21:30 +00007964 sqlite3_file_control(p->db, zSchema, filectrl, &x);
drhd985f722019-06-05 14:29:53 +00007965 iRes = x;
7966 isOk = 1;
7967 break;
7968 }
7969 case SQLITE_FCNTL_TEMPFILENAME: {
7970 char *z = 0;
7971 if( nArg!=2 ) break;
drh541ef2c2020-04-20 16:21:30 +00007972 sqlite3_file_control(p->db, zSchema, filectrl, &z);
drhd985f722019-06-05 14:29:53 +00007973 if( z ){
7974 utf8_printf(p->out, "%s\n", z);
7975 sqlite3_free(z);
7976 }
7977 isOk = 2;
7978 break;
7979 }
drh541ef2c2020-04-20 16:21:30 +00007980 case SQLITE_FCNTL_RESERVE_BYTES: {
7981 int x;
7982 if( nArg>=3 ){
7983 x = atoi(azArg[2]);
7984 sqlite3_file_control(p->db, zSchema, filectrl, &x);
7985 }
7986 x = -1;
7987 sqlite3_file_control(p->db, zSchema, filectrl, &x);
7988 utf8_printf(p->out,"%d\n", x);
7989 isOk = 2;
7990 break;
7991 }
drhd985f722019-06-05 14:29:53 +00007992 }
7993 }
7994 if( isOk==0 && iCtrl>=0 ){
7995 utf8_printf(p->out, "Usage: .filectrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
7996 rc = 1;
7997 }else if( isOk==1 ){
drhe2500762019-06-13 14:07:41 +00007998 char zBuf[100];
7999 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes);
8000 raw_printf(p->out, "%s\n", zBuf);
drhd985f722019-06-05 14:29:53 +00008001 }
8002 }else
8003
drh2ce15c32017-07-11 13:34:40 +00008004 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
8005 ShellState data;
8006 char *zErrMsg = 0;
8007 int doStats = 0;
8008 memcpy(&data, p, sizeof(data));
8009 data.showHeader = 0;
8010 data.cMode = data.mode = MODE_Semi;
8011 if( nArg==2 && optionMatch(azArg[1], "indent") ){
8012 data.cMode = data.mode = MODE_Pretty;
8013 nArg = 1;
8014 }
8015 if( nArg!=1 ){
8016 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
8017 rc = 1;
8018 goto meta_command_exit;
8019 }
8020 open_db(p, 0);
8021 rc = sqlite3_exec(p->db,
8022 "SELECT sql FROM"
8023 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh067b92b2020-06-19 15:24:12 +00008024 " FROM sqlite_schema UNION ALL"
8025 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
drh2ce15c32017-07-11 13:34:40 +00008026 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
8027 "ORDER BY rowid",
8028 callback, &data, &zErrMsg
8029 );
8030 if( rc==SQLITE_OK ){
8031 sqlite3_stmt *pStmt;
8032 rc = sqlite3_prepare_v2(p->db,
drh067b92b2020-06-19 15:24:12 +00008033 "SELECT rowid FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00008034 " WHERE name GLOB 'sqlite_stat[134]'",
8035 -1, &pStmt, 0);
8036 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
8037 sqlite3_finalize(pStmt);
8038 }
8039 if( doStats==0 ){
8040 raw_printf(p->out, "/* No STAT tables available */\n");
8041 }else{
drh067b92b2020-06-19 15:24:12 +00008042 raw_printf(p->out, "ANALYZE sqlite_schema;\n");
8043 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_schema'",
drh2ce15c32017-07-11 13:34:40 +00008044 callback, &data, &zErrMsg);
8045 data.cMode = data.mode = MODE_Insert;
8046 data.zDestTable = "sqlite_stat1";
drh4c540452018-05-08 23:17:36 +00008047 shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
drh2ce15c32017-07-11 13:34:40 +00008048 data.zDestTable = "sqlite_stat4";
drh4c540452018-05-08 23:17:36 +00008049 shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
drh067b92b2020-06-19 15:24:12 +00008050 raw_printf(p->out, "ANALYZE sqlite_schema;\n");
drh2ce15c32017-07-11 13:34:40 +00008051 }
8052 }else
8053
8054 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
8055 if( nArg==2 ){
8056 p->showHeader = booleanValue(azArg[1]);
drhc0605082020-06-05 00:54:27 +00008057 p->shellFlgs |= SHFLG_HeaderSet;
drh2ce15c32017-07-11 13:34:40 +00008058 }else{
8059 raw_printf(stderr, "Usage: .headers on|off\n");
8060 rc = 1;
8061 }
8062 }else
8063
8064 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drh98aa2ab2018-09-26 16:53:51 +00008065 if( nArg>=2 ){
drhe93f8262018-10-11 16:53:37 +00008066 n = showHelp(p->out, azArg[1]);
drh98aa2ab2018-09-26 16:53:51 +00008067 if( n==0 ){
8068 utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
8069 }
8070 }else{
8071 showHelp(p->out, 0);
8072 }
drh2ce15c32017-07-11 13:34:40 +00008073 }else
8074
8075 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drhccb37812020-03-09 15:39:39 +00008076 char *zTable = 0; /* Insert data into this table */
8077 char *zFile = 0; /* Name of file to extra content from */
drh2ce15c32017-07-11 13:34:40 +00008078 sqlite3_stmt *pStmt = NULL; /* A statement */
8079 int nCol; /* Number of columns in the table */
8080 int nByte; /* Number of bytes in an SQL string */
8081 int i, j; /* Loop counters */
8082 int needCommit; /* True to COMMIT or ROLLBACK at end */
8083 int nSep; /* Number of bytes in p->colSeparator[] */
8084 char *zSql; /* An SQL statement */
8085 ImportCtx sCtx; /* Reader context */
8086 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
drhccb37812020-03-09 15:39:39 +00008087 int eVerbose = 0; /* Larger for more console output */
8088 int nSkip = 0; /* Initial lines to skip */
8089 int useOutputMode = 1; /* Use output mode to determine separators */
drh2ce15c32017-07-11 13:34:40 +00008090
drhccb37812020-03-09 15:39:39 +00008091 memset(&sCtx, 0, sizeof(sCtx));
8092 if( p->mode==MODE_Ascii ){
8093 xRead = ascii_read_one_field;
8094 }else{
8095 xRead = csv_read_one_field;
8096 }
8097 for(i=1; i<nArg; i++){
8098 char *z = azArg[i];
8099 if( z[0]=='-' && z[1]=='-' ) z++;
8100 if( z[0]!='-' ){
8101 if( zFile==0 ){
8102 zFile = z;
8103 }else if( zTable==0 ){
8104 zTable = z;
8105 }else{
8106 utf8_printf(p->out, "ERROR: extra argument: \"%s\". Usage:\n", z);
8107 showHelp(p->out, "import");
8108 rc = 1;
8109 goto meta_command_exit;
8110 }
8111 }else if( strcmp(z,"-v")==0 ){
8112 eVerbose++;
8113 }else if( strcmp(z,"-skip")==0 && i<nArg-1 ){
8114 nSkip = integerValue(azArg[++i]);
8115 }else if( strcmp(z,"-ascii")==0 ){
8116 sCtx.cColSep = SEP_Unit[0];
8117 sCtx.cRowSep = SEP_Record[0];
8118 xRead = ascii_read_one_field;
8119 useOutputMode = 0;
8120 }else if( strcmp(z,"-csv")==0 ){
8121 sCtx.cColSep = ',';
8122 sCtx.cRowSep = '\n';
8123 xRead = csv_read_one_field;
8124 useOutputMode = 0;
8125 }else{
8126 utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z);
8127 showHelp(p->out, "import");
8128 rc = 1;
8129 goto meta_command_exit;
8130 }
8131 }
8132 if( zTable==0 ){
8133 utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
8134 zFile==0 ? "FILE" : "TABLE");
8135 showHelp(p->out, "import");
8136 rc = 1;
drh2ce15c32017-07-11 13:34:40 +00008137 goto meta_command_exit;
8138 }
drh2ce15c32017-07-11 13:34:40 +00008139 seenInterrupt = 0;
drh2ce15c32017-07-11 13:34:40 +00008140 open_db(p, 0);
drhccb37812020-03-09 15:39:39 +00008141 if( useOutputMode ){
8142 /* If neither the --csv or --ascii options are specified, then set
8143 ** the column and row separator characters from the output mode. */
8144 nSep = strlen30(p->colSeparator);
8145 if( nSep==0 ){
8146 raw_printf(stderr,
8147 "Error: non-null column separator required for import\n");
8148 rc = 1;
8149 goto meta_command_exit;
8150 }
8151 if( nSep>1 ){
8152 raw_printf(stderr,
8153 "Error: multi-character column separators not allowed"
8154 " for import\n");
8155 rc = 1;
8156 goto meta_command_exit;
8157 }
drh2ce15c32017-07-11 13:34:40 +00008158 nSep = strlen30(p->rowSeparator);
drhccb37812020-03-09 15:39:39 +00008159 if( nSep==0 ){
8160 raw_printf(stderr,
8161 "Error: non-null row separator required for import\n");
8162 rc = 1;
8163 goto meta_command_exit;
8164 }
8165 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
8166 /* When importing CSV (only), if the row separator is set to the
8167 ** default output row separator, change it to the default input
8168 ** row separator. This avoids having to maintain different input
8169 ** and output row separators. */
8170 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
8171 nSep = strlen30(p->rowSeparator);
8172 }
8173 if( nSep>1 ){
8174 raw_printf(stderr, "Error: multi-character row separators not allowed"
8175 " for import\n");
8176 rc = 1;
8177 goto meta_command_exit;
8178 }
8179 sCtx.cColSep = p->colSeparator[0];
8180 sCtx.cRowSep = p->rowSeparator[0];
drh2ce15c32017-07-11 13:34:40 +00008181 }
8182 sCtx.zFile = zFile;
8183 sCtx.nLine = 1;
8184 if( sCtx.zFile[0]=='|' ){
8185#ifdef SQLITE_OMIT_POPEN
8186 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drhccb37812020-03-09 15:39:39 +00008187 rc = 1;
8188 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008189#else
8190 sCtx.in = popen(sCtx.zFile+1, "r");
8191 sCtx.zFile = "<pipe>";
drh97767842020-05-29 19:39:35 +00008192 sCtx.xCloser = pclose;
drh2ce15c32017-07-11 13:34:40 +00008193#endif
8194 }else{
8195 sCtx.in = fopen(sCtx.zFile, "rb");
drh97767842020-05-29 19:39:35 +00008196 sCtx.xCloser = fclose;
drh2ce15c32017-07-11 13:34:40 +00008197 }
drh2ce15c32017-07-11 13:34:40 +00008198 if( sCtx.in==0 ){
8199 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhccb37812020-03-09 15:39:39 +00008200 rc = 1;
8201 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008202 }
drhccb37812020-03-09 15:39:39 +00008203 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
8204 char zSep[2];
8205 zSep[1] = 0;
8206 zSep[0] = sCtx.cColSep;
8207 utf8_printf(p->out, "Column separator ");
8208 output_c_string(p->out, zSep);
8209 utf8_printf(p->out, ", row separator ");
8210 zSep[0] = sCtx.cRowSep;
8211 output_c_string(p->out, zSep);
8212 utf8_printf(p->out, "\n");
8213 }
8214 while( (nSkip--)>0 ){
8215 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
drhccb37812020-03-09 15:39:39 +00008216 }
drhc6712642020-10-12 17:57:29 +00008217 zSql = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
drh2ce15c32017-07-11 13:34:40 +00008218 if( zSql==0 ){
drh97767842020-05-29 19:39:35 +00008219 import_cleanup(&sCtx);
drh4b5345c2018-04-24 13:07:40 +00008220 shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00008221 }
8222 nByte = strlen30(zSql);
8223 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8224 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
8225 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
drhc6712642020-10-12 17:57:29 +00008226 char *zCreate = sqlite3_mprintf("CREATE TABLE \"%w\"", zTable);
drh2ce15c32017-07-11 13:34:40 +00008227 char cSep = '(';
8228 while( xRead(&sCtx) ){
8229 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
8230 cSep = ',';
8231 if( sCtx.cTerm!=sCtx.cColSep ) break;
8232 }
8233 if( cSep=='(' ){
8234 sqlite3_free(zCreate);
drh97767842020-05-29 19:39:35 +00008235 import_cleanup(&sCtx);
drh2ce15c32017-07-11 13:34:40 +00008236 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drhccb37812020-03-09 15:39:39 +00008237 rc = 1;
8238 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008239 }
8240 zCreate = sqlite3_mprintf("%z\n)", zCreate);
drhccb37812020-03-09 15:39:39 +00008241 if( eVerbose>=1 ){
8242 utf8_printf(p->out, "%s\n", zCreate);
8243 }
drh2ce15c32017-07-11 13:34:40 +00008244 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
8245 sqlite3_free(zCreate);
8246 if( rc ){
drhc6712642020-10-12 17:57:29 +00008247 utf8_printf(stderr, "CREATE TABLE \"%s\"(...) failed: %s\n", zTable,
drh2ce15c32017-07-11 13:34:40 +00008248 sqlite3_errmsg(p->db));
drh97767842020-05-29 19:39:35 +00008249 import_cleanup(&sCtx);
drhccb37812020-03-09 15:39:39 +00008250 rc = 1;
8251 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008252 }
8253 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8254 }
8255 sqlite3_free(zSql);
8256 if( rc ){
8257 if (pStmt) sqlite3_finalize(pStmt);
8258 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
drh97767842020-05-29 19:39:35 +00008259 import_cleanup(&sCtx);
drhccb37812020-03-09 15:39:39 +00008260 rc = 1;
8261 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008262 }
8263 nCol = sqlite3_column_count(pStmt);
8264 sqlite3_finalize(pStmt);
8265 pStmt = 0;
8266 if( nCol==0 ) return 0; /* no columns, no error */
8267 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
8268 if( zSql==0 ){
drh97767842020-05-29 19:39:35 +00008269 import_cleanup(&sCtx);
drh4b5345c2018-04-24 13:07:40 +00008270 shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00008271 }
8272 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
8273 j = strlen30(zSql);
8274 for(i=1; i<nCol; i++){
8275 zSql[j++] = ',';
8276 zSql[j++] = '?';
8277 }
8278 zSql[j++] = ')';
8279 zSql[j] = 0;
drhccb37812020-03-09 15:39:39 +00008280 if( eVerbose>=2 ){
8281 utf8_printf(p->out, "Insert using: %s\n", zSql);
8282 }
drh2ce15c32017-07-11 13:34:40 +00008283 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8284 sqlite3_free(zSql);
8285 if( rc ){
8286 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
8287 if (pStmt) sqlite3_finalize(pStmt);
drh97767842020-05-29 19:39:35 +00008288 import_cleanup(&sCtx);
drhccb37812020-03-09 15:39:39 +00008289 rc = 1;
8290 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008291 }
8292 needCommit = sqlite3_get_autocommit(p->db);
8293 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
8294 do{
8295 int startLine = sCtx.nLine;
8296 for(i=0; i<nCol; i++){
8297 char *z = xRead(&sCtx);
8298 /*
8299 ** Did we reach end-of-file before finding any columns?
8300 ** If so, stop instead of NULL filling the remaining columns.
8301 */
8302 if( z==0 && i==0 ) break;
8303 /*
8304 ** Did we reach end-of-file OR end-of-line before finding any
8305 ** columns in ASCII mode? If so, stop instead of NULL filling
8306 ** the remaining columns.
8307 */
8308 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
8309 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
8310 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
8311 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
8312 "filling the rest with NULL\n",
8313 sCtx.zFile, startLine, nCol, i+1);
8314 i += 2;
8315 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
8316 }
8317 }
8318 if( sCtx.cTerm==sCtx.cColSep ){
8319 do{
8320 xRead(&sCtx);
8321 i++;
8322 }while( sCtx.cTerm==sCtx.cColSep );
8323 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
8324 "extras ignored\n",
8325 sCtx.zFile, startLine, nCol, i);
8326 }
8327 if( i>=nCol ){
8328 sqlite3_step(pStmt);
8329 rc = sqlite3_reset(pStmt);
8330 if( rc!=SQLITE_OK ){
8331 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
8332 startLine, sqlite3_errmsg(p->db));
drhccb37812020-03-09 15:39:39 +00008333 sCtx.nErr++;
8334 }else{
8335 sCtx.nRow++;
drh2ce15c32017-07-11 13:34:40 +00008336 }
8337 }
8338 }while( sCtx.cTerm!=EOF );
8339
drh97767842020-05-29 19:39:35 +00008340 import_cleanup(&sCtx);
drh2ce15c32017-07-11 13:34:40 +00008341 sqlite3_finalize(pStmt);
8342 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhccb37812020-03-09 15:39:39 +00008343 if( eVerbose>0 ){
8344 utf8_printf(p->out,
8345 "Added %d rows with %d errors using %d lines of input\n",
8346 sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
8347 }
drh2ce15c32017-07-11 13:34:40 +00008348 }else
8349
8350#ifndef SQLITE_UNTESTABLE
8351 if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
8352 char *zSql;
8353 char *zCollist = 0;
8354 sqlite3_stmt *pStmt;
8355 int tnum = 0;
drh491c5be2019-10-18 15:58:50 +00008356 int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */
8357 int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
drh2ce15c32017-07-11 13:34:40 +00008358 int i;
drh48d219a2018-04-23 18:38:48 +00008359 if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
8360 utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"
8361 " .imposter off\n");
drh491c5be2019-10-18 15:58:50 +00008362 /* Also allowed, but not documented:
8363 **
8364 ** .imposter TABLE IMPOSTER
8365 **
8366 ** where TABLE is a WITHOUT ROWID table. In that case, the
8367 ** imposter is another WITHOUT ROWID table with the columns in
8368 ** storage order. */
drh2ce15c32017-07-11 13:34:40 +00008369 rc = 1;
8370 goto meta_command_exit;
8371 }
8372 open_db(p, 0);
drh48d219a2018-04-23 18:38:48 +00008373 if( nArg==2 ){
8374 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1);
8375 goto meta_command_exit;
8376 }
drh491c5be2019-10-18 15:58:50 +00008377 zSql = sqlite3_mprintf(
drh067b92b2020-06-19 15:24:12 +00008378 "SELECT rootpage, 0 FROM sqlite_schema"
drh491c5be2019-10-18 15:58:50 +00008379 " WHERE name='%q' AND type='index'"
8380 "UNION ALL "
drh067b92b2020-06-19 15:24:12 +00008381 "SELECT rootpage, 1 FROM sqlite_schema"
drh491c5be2019-10-18 15:58:50 +00008382 " WHERE name='%q' AND type='table'"
8383 " AND sql LIKE '%%without%%rowid%%'",
8384 azArg[1], azArg[1]
8385 );
drh2ce15c32017-07-11 13:34:40 +00008386 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8387 sqlite3_free(zSql);
8388 if( sqlite3_step(pStmt)==SQLITE_ROW ){
8389 tnum = sqlite3_column_int(pStmt, 0);
drh491c5be2019-10-18 15:58:50 +00008390 isWO = sqlite3_column_int(pStmt, 1);
drh2ce15c32017-07-11 13:34:40 +00008391 }
8392 sqlite3_finalize(pStmt);
drh2ce15c32017-07-11 13:34:40 +00008393 zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
8394 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8395 sqlite3_free(zSql);
8396 i = 0;
8397 while( sqlite3_step(pStmt)==SQLITE_ROW ){
8398 char zLabel[20];
8399 const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
8400 i++;
8401 if( zCol==0 ){
8402 if( sqlite3_column_int(pStmt,1)==-1 ){
8403 zCol = "_ROWID_";
8404 }else{
8405 sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i);
8406 zCol = zLabel;
8407 }
8408 }
drh491c5be2019-10-18 15:58:50 +00008409 if( isWO && lenPK==0 && sqlite3_column_int(pStmt,5)==0 && zCollist ){
8410 lenPK = (int)strlen(zCollist);
8411 }
drh2ce15c32017-07-11 13:34:40 +00008412 if( zCollist==0 ){
8413 zCollist = sqlite3_mprintf("\"%w\"", zCol);
8414 }else{
8415 zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
8416 }
8417 }
8418 sqlite3_finalize(pStmt);
drh491c5be2019-10-18 15:58:50 +00008419 if( i==0 || tnum==0 ){
8420 utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
8421 rc = 1;
8422 sqlite3_free(zCollist);
8423 goto meta_command_exit;
8424 }
8425 if( lenPK==0 ) lenPK = 100000;
drh2ce15c32017-07-11 13:34:40 +00008426 zSql = sqlite3_mprintf(
drh491c5be2019-10-18 15:58:50 +00008427 "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID",
8428 azArg[2], zCollist, lenPK, zCollist);
drh2ce15c32017-07-11 13:34:40 +00008429 sqlite3_free(zCollist);
8430 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
8431 if( rc==SQLITE_OK ){
8432 rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
8433 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
8434 if( rc ){
8435 utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
8436 }else{
8437 utf8_printf(stdout, "%s;\n", zSql);
8438 raw_printf(stdout,
drh491c5be2019-10-18 15:58:50 +00008439 "WARNING: writing to an imposter table will corrupt the \"%s\" %s!\n",
8440 azArg[1], isWO ? "table" : "index"
drh2ce15c32017-07-11 13:34:40 +00008441 );
8442 }
8443 }else{
8444 raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
8445 rc = 1;
8446 }
8447 sqlite3_free(zSql);
8448 }else
8449#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
8450
8451#ifdef SQLITE_ENABLE_IOTRACE
8452 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
8453 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
8454 if( iotrace && iotrace!=stdout ) fclose(iotrace);
8455 iotrace = 0;
8456 if( nArg<2 ){
8457 sqlite3IoTrace = 0;
8458 }else if( strcmp(azArg[1], "-")==0 ){
8459 sqlite3IoTrace = iotracePrintf;
8460 iotrace = stdout;
8461 }else{
8462 iotrace = fopen(azArg[1], "w");
8463 if( iotrace==0 ){
8464 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
8465 sqlite3IoTrace = 0;
8466 rc = 1;
8467 }else{
8468 sqlite3IoTrace = iotracePrintf;
8469 }
8470 }
8471 }else
8472#endif
8473
8474 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
8475 static const struct {
8476 const char *zLimitName; /* Name of a limit */
8477 int limitCode; /* Integer code for that limit */
8478 } aLimit[] = {
8479 { "length", SQLITE_LIMIT_LENGTH },
8480 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
8481 { "column", SQLITE_LIMIT_COLUMN },
8482 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
8483 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
8484 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
8485 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
8486 { "attached", SQLITE_LIMIT_ATTACHED },
8487 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
8488 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
8489 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
8490 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
8491 };
8492 int i, n2;
8493 open_db(p, 0);
8494 if( nArg==1 ){
8495 for(i=0; i<ArraySize(aLimit); i++){
8496 printf("%20s %d\n", aLimit[i].zLimitName,
8497 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
8498 }
8499 }else if( nArg>3 ){
8500 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
8501 rc = 1;
8502 goto meta_command_exit;
8503 }else{
8504 int iLimit = -1;
8505 n2 = strlen30(azArg[1]);
8506 for(i=0; i<ArraySize(aLimit); i++){
8507 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
8508 if( iLimit<0 ){
8509 iLimit = i;
8510 }else{
8511 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
8512 rc = 1;
8513 goto meta_command_exit;
8514 }
8515 }
8516 }
8517 if( iLimit<0 ){
8518 utf8_printf(stderr, "unknown limit: \"%s\"\n"
8519 "enter \".limits\" with no arguments for a list.\n",
8520 azArg[1]);
8521 rc = 1;
8522 goto meta_command_exit;
8523 }
8524 if( nArg==3 ){
8525 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
8526 (int)integerValue(azArg[2]));
8527 }
8528 printf("%20s %d\n", aLimit[iLimit].zLimitName,
8529 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
8530 }
8531 }else
8532
8533 if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
8534 open_db(p, 0);
8535 lintDotCommand(p, azArg, nArg);
8536 }else
8537
8538#ifndef SQLITE_OMIT_LOAD_EXTENSION
8539 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
8540 const char *zFile, *zProc;
8541 char *zErrMsg = 0;
8542 if( nArg<2 ){
8543 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
8544 rc = 1;
8545 goto meta_command_exit;
8546 }
8547 zFile = azArg[1];
8548 zProc = nArg>=3 ? azArg[2] : 0;
8549 open_db(p, 0);
8550 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
8551 if( rc!=SQLITE_OK ){
8552 utf8_printf(stderr, "Error: %s\n", zErrMsg);
8553 sqlite3_free(zErrMsg);
8554 rc = 1;
8555 }
8556 }else
8557#endif
8558
8559 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
8560 if( nArg!=2 ){
8561 raw_printf(stderr, "Usage: .log FILENAME\n");
8562 rc = 1;
8563 }else{
8564 const char *zFile = azArg[1];
8565 output_file_close(p->pLog);
drha92a01a2018-01-10 22:15:37 +00008566 p->pLog = output_file_open(zFile, 0);
drh2ce15c32017-07-11 13:34:40 +00008567 }
8568 }else
8569
8570 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
8571 const char *zMode = nArg>=2 ? azArg[1] : "";
drhaf2770f2018-01-05 14:55:43 +00008572 int n2 = strlen30(zMode);
drh2ce15c32017-07-11 13:34:40 +00008573 int c2 = zMode[0];
8574 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
8575 p->mode = MODE_Line;
8576 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
8577 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
8578 p->mode = MODE_Column;
drhc0605082020-06-05 00:54:27 +00008579 if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
8580 p->showHeader = 1;
8581 }
drh2ce15c32017-07-11 13:34:40 +00008582 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
8583 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
8584 p->mode = MODE_List;
8585 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
8586 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
8587 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
8588 p->mode = MODE_Html;
8589 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
8590 p->mode = MODE_Tcl;
8591 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
8592 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
8593 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
8594 p->mode = MODE_Csv;
8595 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
8596 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
8597 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
8598 p->mode = MODE_List;
8599 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
8600 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
8601 p->mode = MODE_Insert;
8602 set_table_name(p, nArg>=3 ? azArg[2] : "table");
8603 }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
8604 p->mode = MODE_Quote;
drhc6835732020-05-28 20:37:17 +00008605 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
8606 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
drh2ce15c32017-07-11 13:34:40 +00008607 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
8608 p->mode = MODE_Ascii;
8609 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
8610 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drh30c54a02020-05-28 23:49:50 +00008611 }else if( c2=='m' && strncmp(azArg[1],"markdown",n2)==0 ){
8612 p->mode = MODE_Markdown;
8613 }else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
8614 p->mode = MODE_Table;
drh0908e382020-06-04 18:05:39 +00008615 }else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
8616 p->mode = MODE_Box;
drh30c54a02020-05-28 23:49:50 +00008617 }else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
8618 p->mode = MODE_Json;
drh2ce15c32017-07-11 13:34:40 +00008619 }else if( nArg==1 ){
8620 raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
8621 }else{
8622 raw_printf(stderr, "Error: mode should be one of: "
drh0908e382020-06-04 18:05:39 +00008623 "ascii box column csv html insert json line list markdown "
drh30c54a02020-05-28 23:49:50 +00008624 "quote table tabs tcl\n");
drh2ce15c32017-07-11 13:34:40 +00008625 rc = 1;
8626 }
8627 p->cMode = p->mode;
8628 }else
8629
8630 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
8631 if( nArg==2 ){
8632 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
8633 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
8634 }else{
8635 raw_printf(stderr, "Usage: .nullvalue STRING\n");
8636 rc = 1;
8637 }
8638 }else
8639
drh4a3a3eb2020-02-29 15:53:48 +00008640#ifdef SQLITE_DEBUG
8641 if( c=='o' && strcmp(azArg[0],"oom")==0 ){
8642 int i;
8643 for(i=1; i<nArg; i++){
8644 const char *z = azArg[i];
8645 if( z[0]=='-' && z[1]=='-' ) z++;
8646 if( strcmp(z,"-repeat")==0 ){
8647 if( i==nArg-1 ){
8648 raw_printf(p->out, "missing argument on \"%s\"\n", azArg[i]);
8649 rc = 1;
8650 }else{
8651 oomRepeat = (int)integerValue(azArg[++i]);
8652 }
8653 }else if( IsDigit(z[0]) ){
8654 oomCounter = (int)integerValue(azArg[i]);
8655 }else{
8656 raw_printf(p->out, "unknown argument: \"%s\"\n", azArg[i]);
8657 raw_printf(p->out, "Usage: .oom [--repeat N] [M]\n");
8658 rc = 1;
8659 }
8660 }
8661 if( rc==0 ){
8662 raw_printf(p->out, "oomCounter = %d\n", oomCounter);
8663 raw_printf(p->out, "oomRepeat = %d\n", oomRepeat);
8664 }
8665 }else
8666#endif /* SQLITE_DEBUG */
8667
drh2ce15c32017-07-11 13:34:40 +00008668 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
8669 char *zNewFilename; /* Name of the database file to open */
8670 int iName = 1; /* Index in azArg[] of the filename */
8671 int newFlag = 0; /* True to delete file before opening */
8672 /* Close the existing database */
8673 session_close_all(p);
drh9e804032018-05-18 17:11:50 +00008674 close_db(p->db);
drh2ce15c32017-07-11 13:34:40 +00008675 p->db = 0;
8676 p->zDbFilename = 0;
8677 sqlite3_free(p->zFreeOnClose);
8678 p->zFreeOnClose = 0;
drh1fa6d9f2018-01-06 21:46:01 +00008679 p->openMode = SHELL_OPEN_UNSPEC;
drh0933aad2019-11-18 17:46:38 +00008680 p->openFlags = 0;
drh6ca64482019-01-22 16:06:20 +00008681 p->szMax = 0;
drh2ce15c32017-07-11 13:34:40 +00008682 /* Check for command-line arguments */
8683 for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
8684 const char *z = azArg[iName];
8685 if( optionMatch(z,"new") ){
8686 newFlag = 1;
drh3baed312018-03-08 18:14:41 +00008687#ifdef SQLITE_HAVE_ZLIB
drh1fa6d9f2018-01-06 21:46:01 +00008688 }else if( optionMatch(z, "zip") ){
8689 p->openMode = SHELL_OPEN_ZIPFILE;
8690#endif
8691 }else if( optionMatch(z, "append") ){
8692 p->openMode = SHELL_OPEN_APPENDVFS;
drhee269a62018-02-14 23:27:43 +00008693 }else if( optionMatch(z, "readonly") ){
8694 p->openMode = SHELL_OPEN_READONLY;
drh0933aad2019-11-18 17:46:38 +00008695 }else if( optionMatch(z, "nofollow") ){
8696 p->openFlags |= SQLITE_OPEN_NOFOLLOW;
drha751f392018-10-30 15:31:22 +00008697#ifdef SQLITE_ENABLE_DESERIALIZE
drh60f34ae2018-10-30 13:19:49 +00008698 }else if( optionMatch(z, "deserialize") ){
8699 p->openMode = SHELL_OPEN_DESERIALIZE;
drh33746482018-12-13 15:06:26 +00008700 }else if( optionMatch(z, "hexdb") ){
8701 p->openMode = SHELL_OPEN_HEXDB;
drh6ca64482019-01-22 16:06:20 +00008702 }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
8703 p->szMax = integerValue(azArg[++iName]);
drh33746482018-12-13 15:06:26 +00008704#endif /* SQLITE_ENABLE_DESERIALIZE */
drh2ce15c32017-07-11 13:34:40 +00008705 }else if( z[0]=='-' ){
8706 utf8_printf(stderr, "unknown option: %s\n", z);
8707 rc = 1;
8708 goto meta_command_exit;
8709 }
8710 }
8711 /* If a filename is specified, try to open it first */
8712 zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
drh33746482018-12-13 15:06:26 +00008713 if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
drh2ce15c32017-07-11 13:34:40 +00008714 if( newFlag ) shellDeleteFile(zNewFilename);
8715 p->zDbFilename = zNewFilename;
drhbe4ccb22018-05-17 20:04:24 +00008716 open_db(p, OPEN_DB_KEEPALIVE);
drh2ce15c32017-07-11 13:34:40 +00008717 if( p->db==0 ){
8718 utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
8719 sqlite3_free(zNewFilename);
8720 }else{
8721 p->zFreeOnClose = zNewFilename;
8722 }
8723 }
8724 if( p->db==0 ){
8725 /* As a fall-back open a TEMP database */
8726 p->zDbFilename = 0;
8727 open_db(p, 0);
8728 }
8729 }else
8730
drh13c20932018-01-10 21:41:55 +00008731 if( (c=='o'
8732 && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
8733 || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
drh2ce15c32017-07-11 13:34:40 +00008734 ){
drh7a431002020-04-18 14:12:00 +00008735 const char *zFile = 0;
drha92a01a2018-01-10 22:15:37 +00008736 int bTxtMode = 0;
drh7a431002020-04-18 14:12:00 +00008737 int i;
8738 int eMode = 0;
8739 int bBOM = 0;
drh5415ab42020-04-23 20:45:46 +00008740 int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
drh7a431002020-04-18 14:12:00 +00008741
8742 if( c=='e' ){
8743 eMode = 'x';
8744 bOnce = 2;
8745 }else if( strncmp(azArg[0],"once",n)==0 ){
8746 bOnce = 1;
drh13c20932018-01-10 21:41:55 +00008747 }
drh7a431002020-04-18 14:12:00 +00008748 for(i=1; i<nArg; i++){
8749 char *z = azArg[i];
8750 if( z[0]=='-' ){
8751 if( z[1]=='-' ) z++;
8752 if( strcmp(z,"-bom")==0 ){
8753 bBOM = 1;
8754 }else if( c!='e' && strcmp(z,"-x")==0 ){
8755 eMode = 'x'; /* spreadsheet */
8756 }else if( c!='e' && strcmp(z,"-e")==0 ){
8757 eMode = 'e'; /* text editor */
8758 }else{
8759 utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n",
8760 azArg[i]);
8761 showHelp(p->out, azArg[0]);
8762 rc = 1;
8763 goto meta_command_exit;
8764 }
8765 }else if( zFile==0 ){
8766 zFile = z;
8767 }else{
8768 utf8_printf(p->out,"ERROR: extra parameter: \"%s\". Usage:\n",
8769 azArg[i]);
8770 showHelp(p->out, azArg[0]);
drh2ce15c32017-07-11 13:34:40 +00008771 rc = 1;
8772 goto meta_command_exit;
8773 }
drh7a431002020-04-18 14:12:00 +00008774 }
8775 if( zFile==0 ) zFile = "stdout";
8776 if( bOnce ){
drh2ce15c32017-07-11 13:34:40 +00008777 p->outCount = 2;
8778 }else{
8779 p->outCount = 0;
8780 }
8781 output_reset(p);
drh04a28c32018-01-31 01:38:44 +00008782#ifndef SQLITE_NOHAVE_SYSTEM
drh7a431002020-04-18 14:12:00 +00008783 if( eMode=='e' || eMode=='x' ){
drh3c484e82018-01-10 22:27:21 +00008784 p->doXdgOpen = 1;
8785 outputModePush(p);
drh7a431002020-04-18 14:12:00 +00008786 if( eMode=='x' ){
8787 /* spreadsheet mode. Output as CSV. */
drh13c20932018-01-10 21:41:55 +00008788 newTempFile(p, "csv");
drh7a431002020-04-18 14:12:00 +00008789 ShellClearFlag(p, SHFLG_Echo);
drh13c20932018-01-10 21:41:55 +00008790 p->mode = MODE_Csv;
8791 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
8792 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
8793 }else{
drh7a431002020-04-18 14:12:00 +00008794 /* text editor mode */
drh13c20932018-01-10 21:41:55 +00008795 newTempFile(p, "txt");
drha92a01a2018-01-10 22:15:37 +00008796 bTxtMode = 1;
drh13c20932018-01-10 21:41:55 +00008797 }
8798 zFile = p->zTempFile;
8799 }
drh04a28c32018-01-31 01:38:44 +00008800#endif /* SQLITE_NOHAVE_SYSTEM */
drh2ce15c32017-07-11 13:34:40 +00008801 if( zFile[0]=='|' ){
8802#ifdef SQLITE_OMIT_POPEN
8803 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
8804 rc = 1;
8805 p->out = stdout;
8806#else
8807 p->out = popen(zFile + 1, "w");
8808 if( p->out==0 ){
8809 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
8810 p->out = stdout;
8811 rc = 1;
8812 }else{
drh7a431002020-04-18 14:12:00 +00008813 if( bBOM ) fprintf(p->out,"\357\273\277");
drh2ce15c32017-07-11 13:34:40 +00008814 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
8815 }
8816#endif
8817 }else{
drha92a01a2018-01-10 22:15:37 +00008818 p->out = output_file_open(zFile, bTxtMode);
drh2ce15c32017-07-11 13:34:40 +00008819 if( p->out==0 ){
8820 if( strcmp(zFile,"off")!=0 ){
8821 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
8822 }
8823 p->out = stdout;
8824 rc = 1;
8825 } else {
drh7a431002020-04-18 14:12:00 +00008826 if( bBOM ) fprintf(p->out,"\357\273\277");
drh2ce15c32017-07-11 13:34:40 +00008827 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
8828 }
8829 }
8830 }else
8831
drh9cb02642019-02-28 20:10:52 +00008832 if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
8833 open_db(p,0);
8834 if( nArg<=1 ) goto parameter_syntax_error;
8835
8836 /* .parameter clear
8837 ** Clear all bind parameters by dropping the TEMP table that holds them.
8838 */
8839 if( nArg==2 && strcmp(azArg[1],"clear")==0 ){
drh65c29fd2019-03-25 21:56:26 +00008840 sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;",
drh9cb02642019-02-28 20:10:52 +00008841 0, 0, 0);
8842 }else
8843
8844 /* .parameter list
8845 ** List all bind parameters.
8846 */
8847 if( nArg==2 && strcmp(azArg[1],"list")==0 ){
8848 sqlite3_stmt *pStmt = 0;
8849 int rx;
8850 int len = 0;
8851 rx = sqlite3_prepare_v2(p->db,
8852 "SELECT max(length(key)) "
drh65c29fd2019-03-25 21:56:26 +00008853 "FROM temp.sqlite_parameters;", -1, &pStmt, 0);
drh9cb02642019-02-28 20:10:52 +00008854 if( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
8855 len = sqlite3_column_int(pStmt, 0);
8856 if( len>40 ) len = 40;
8857 }
8858 sqlite3_finalize(pStmt);
8859 pStmt = 0;
8860 if( len ){
8861 rx = sqlite3_prepare_v2(p->db,
8862 "SELECT key, quote(value) "
drh65c29fd2019-03-25 21:56:26 +00008863 "FROM temp.sqlite_parameters;", -1, &pStmt, 0);
drh9cb02642019-02-28 20:10:52 +00008864 while( sqlite3_step(pStmt)==SQLITE_ROW ){
8865 utf8_printf(p->out, "%-*s %s\n", len, sqlite3_column_text(pStmt,0),
8866 sqlite3_column_text(pStmt,1));
8867 }
8868 sqlite3_finalize(pStmt);
8869 }
8870 }else
8871
8872 /* .parameter init
8873 ** Make sure the TEMP table used to hold bind parameters exists.
8874 ** Create it if necessary.
8875 */
8876 if( nArg==2 && strcmp(azArg[1],"init")==0 ){
8877 bind_table_init(p);
8878 }else
8879
8880 /* .parameter set NAME VALUE
8881 ** Set or reset a bind parameter. NAME should be the full parameter
8882 ** name exactly as it appears in the query. (ex: $abc, @def). The
8883 ** VALUE can be in either SQL literal notation, or if not it will be
8884 ** understood to be a text string.
8885 */
8886 if( nArg==4 && strcmp(azArg[1],"set")==0 ){
8887 int rx;
8888 char *zSql;
8889 sqlite3_stmt *pStmt;
8890 const char *zKey = azArg[2];
8891 const char *zValue = azArg[3];
8892 bind_table_init(p);
8893 zSql = sqlite3_mprintf(
drh65c29fd2019-03-25 21:56:26 +00008894 "REPLACE INTO temp.sqlite_parameters(key,value)"
drh9cb02642019-02-28 20:10:52 +00008895 "VALUES(%Q,%s);", zKey, zValue);
8896 if( zSql==0 ) shell_out_of_memory();
8897 pStmt = 0;
8898 rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8899 sqlite3_free(zSql);
8900 if( rx!=SQLITE_OK ){
8901 sqlite3_finalize(pStmt);
8902 pStmt = 0;
8903 zSql = sqlite3_mprintf(
drh65c29fd2019-03-25 21:56:26 +00008904 "REPLACE INTO temp.sqlite_parameters(key,value)"
drh9cb02642019-02-28 20:10:52 +00008905 "VALUES(%Q,%Q);", zKey, zValue);
8906 if( zSql==0 ) shell_out_of_memory();
8907 rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8908 sqlite3_free(zSql);
8909 if( rx!=SQLITE_OK ){
8910 utf8_printf(p->out, "Error: %s\n", sqlite3_errmsg(p->db));
8911 sqlite3_finalize(pStmt);
8912 pStmt = 0;
8913 rc = 1;
8914 }
8915 }
8916 sqlite3_step(pStmt);
8917 sqlite3_finalize(pStmt);
8918 }else
8919
8920 /* .parameter unset NAME
8921 ** Remove the NAME binding from the parameter binding table, if it
8922 ** exists.
8923 */
8924 if( nArg==3 && strcmp(azArg[1],"unset")==0 ){
8925 char *zSql = sqlite3_mprintf(
drh65c29fd2019-03-25 21:56:26 +00008926 "DELETE FROM temp.sqlite_parameters WHERE key=%Q", azArg[2]);
drh9cb02642019-02-28 20:10:52 +00008927 if( zSql==0 ) shell_out_of_memory();
8928 sqlite3_exec(p->db, zSql, 0, 0, 0);
8929 sqlite3_free(zSql);
8930 }else
8931 /* If no command name matches, show a syntax error */
8932 parameter_syntax_error:
8933 showHelp(p->out, "parameter");
8934 }else
8935
drh2ce15c32017-07-11 13:34:40 +00008936 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
8937 int i;
8938 for(i=1; i<nArg; i++){
8939 if( i>1 ) raw_printf(p->out, " ");
8940 utf8_printf(p->out, "%s", azArg[i]);
8941 }
8942 raw_printf(p->out, "\n");
8943 }else
8944
drh569b1d92019-02-05 20:51:41 +00008945#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
drh3f83f592019-02-04 14:53:18 +00008946 if( c=='p' && n>=3 && strncmp(azArg[0], "progress", n)==0 ){
8947 int i;
drhfc4eeef2019-02-05 19:48:46 +00008948 int nn = 0;
drh3f83f592019-02-04 14:53:18 +00008949 p->flgProgress = 0;
8950 p->mxProgress = 0;
8951 p->nProgress = 0;
8952 for(i=1; i<nArg; i++){
8953 const char *z = azArg[i];
8954 if( z[0]=='-' ){
8955 z++;
8956 if( z[0]=='-' ) z++;
8957 if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
drhfc4eeef2019-02-05 19:48:46 +00008958 p->flgProgress |= SHELL_PROGRESS_QUIET;
drh3f83f592019-02-04 14:53:18 +00008959 continue;
8960 }
8961 if( strcmp(z,"reset")==0 ){
drhfc4eeef2019-02-05 19:48:46 +00008962 p->flgProgress |= SHELL_PROGRESS_RESET;
drh3f83f592019-02-04 14:53:18 +00008963 continue;
8964 }
8965 if( strcmp(z,"once")==0 ){
drhfc4eeef2019-02-05 19:48:46 +00008966 p->flgProgress |= SHELL_PROGRESS_ONCE;
drh3f83f592019-02-04 14:53:18 +00008967 continue;
8968 }
8969 if( strcmp(z,"limit")==0 ){
8970 if( i+1>=nArg ){
8971 utf8_printf(stderr, "Error: missing argument on --limit\n");
8972 rc = 1;
8973 goto meta_command_exit;
8974 }else{
8975 p->mxProgress = (int)integerValue(azArg[++i]);
8976 }
8977 continue;
8978 }
8979 utf8_printf(stderr, "Error: unknown option: \"%s\"\n", azArg[i]);
8980 rc = 1;
8981 goto meta_command_exit;
8982 }else{
drhfc4eeef2019-02-05 19:48:46 +00008983 nn = (int)integerValue(z);
drh3f83f592019-02-04 14:53:18 +00008984 }
8985 }
8986 open_db(p, 0);
drhfc4eeef2019-02-05 19:48:46 +00008987 sqlite3_progress_handler(p->db, nn, progress_handler, p);
drh3f83f592019-02-04 14:53:18 +00008988 }else
drh569b1d92019-02-05 20:51:41 +00008989#endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
drh3f83f592019-02-04 14:53:18 +00008990
drh2ce15c32017-07-11 13:34:40 +00008991 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
8992 if( nArg >= 2) {
8993 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
8994 }
8995 if( nArg >= 3) {
8996 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
8997 }
8998 }else
8999
9000 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
9001 rc = 2;
9002 }else
9003
9004 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
drh60379d42018-12-13 18:30:01 +00009005 FILE *inSaved = p->in;
drh2c8ee022018-12-13 18:59:30 +00009006 int savedLineno = p->lineno;
drh2ce15c32017-07-11 13:34:40 +00009007 if( nArg!=2 ){
9008 raw_printf(stderr, "Usage: .read FILE\n");
9009 rc = 1;
9010 goto meta_command_exit;
9011 }
drh30497f42020-08-26 10:50:48 +00009012 if( azArg[1][0]=='|' ){
9013 p->in = popen(azArg[1]+1, "r");
9014 if( p->in==0 ){
9015 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
9016 rc = 1;
9017 }else{
9018 rc = process_input(p);
9019 pclose(p->in);
9020 }
9021 }else if( notNormalFile(azArg[1]) || (p->in = fopen(azArg[1], "rb"))==0 ){
drh2ce15c32017-07-11 13:34:40 +00009022 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
9023 rc = 1;
9024 }else{
drh60379d42018-12-13 18:30:01 +00009025 rc = process_input(p);
9026 fclose(p->in);
drh2ce15c32017-07-11 13:34:40 +00009027 }
drh60379d42018-12-13 18:30:01 +00009028 p->in = inSaved;
drh2c8ee022018-12-13 18:59:30 +00009029 p->lineno = savedLineno;
drh2ce15c32017-07-11 13:34:40 +00009030 }else
9031
9032 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
9033 const char *zSrcFile;
9034 const char *zDb;
9035 sqlite3 *pSrc;
9036 sqlite3_backup *pBackup;
9037 int nTimeout = 0;
9038
9039 if( nArg==2 ){
9040 zSrcFile = azArg[1];
9041 zDb = "main";
9042 }else if( nArg==3 ){
9043 zSrcFile = azArg[2];
9044 zDb = azArg[1];
9045 }else{
9046 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
9047 rc = 1;
9048 goto meta_command_exit;
9049 }
9050 rc = sqlite3_open(zSrcFile, &pSrc);
9051 if( rc!=SQLITE_OK ){
9052 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9e804032018-05-18 17:11:50 +00009053 close_db(pSrc);
drh2ce15c32017-07-11 13:34:40 +00009054 return 1;
9055 }
9056 open_db(p, 0);
9057 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
9058 if( pBackup==0 ){
9059 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9e804032018-05-18 17:11:50 +00009060 close_db(pSrc);
drh2ce15c32017-07-11 13:34:40 +00009061 return 1;
9062 }
9063 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
9064 || rc==SQLITE_BUSY ){
9065 if( rc==SQLITE_BUSY ){
9066 if( nTimeout++ >= 3 ) break;
9067 sqlite3_sleep(100);
9068 }
9069 }
9070 sqlite3_backup_finish(pBackup);
9071 if( rc==SQLITE_DONE ){
9072 rc = 0;
9073 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
9074 raw_printf(stderr, "Error: source database is busy\n");
9075 rc = 1;
9076 }else{
9077 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
9078 rc = 1;
9079 }
drh9e804032018-05-18 17:11:50 +00009080 close_db(pSrc);
drh2ce15c32017-07-11 13:34:40 +00009081 }else
9082
drh2ce15c32017-07-11 13:34:40 +00009083 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
9084 if( nArg==2 ){
mistachkinb71aa092018-01-23 00:05:18 +00009085 p->scanstatsOn = (u8)booleanValue(azArg[1]);
drh2ce15c32017-07-11 13:34:40 +00009086#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
9087 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
9088#endif
9089 }else{
9090 raw_printf(stderr, "Usage: .scanstats on|off\n");
9091 rc = 1;
9092 }
9093 }else
9094
9095 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
9096 ShellText sSelect;
9097 ShellState data;
9098 char *zErrMsg = 0;
drh667a2a22018-01-02 00:04:37 +00009099 const char *zDiv = "(";
drhceba7922018-01-01 21:28:25 +00009100 const char *zName = 0;
drh2ce15c32017-07-11 13:34:40 +00009101 int iSchema = 0;
drhceba7922018-01-01 21:28:25 +00009102 int bDebug = 0;
drhbbb29ec2020-10-12 14:56:47 +00009103 int bNoSystemTabs = 0;
drhceba7922018-01-01 21:28:25 +00009104 int ii;
drh2ce15c32017-07-11 13:34:40 +00009105
9106 open_db(p, 0);
9107 memcpy(&data, p, sizeof(data));
9108 data.showHeader = 0;
9109 data.cMode = data.mode = MODE_Semi;
9110 initText(&sSelect);
drhceba7922018-01-01 21:28:25 +00009111 for(ii=1; ii<nArg; ii++){
9112 if( optionMatch(azArg[ii],"indent") ){
9113 data.cMode = data.mode = MODE_Pretty;
9114 }else if( optionMatch(azArg[ii],"debug") ){
9115 bDebug = 1;
drhbbb29ec2020-10-12 14:56:47 +00009116 }else if( optionMatch(azArg[ii],"nosys") ){
9117 bNoSystemTabs = 1;
9118 }else if( azArg[ii][0]=='-' ){
9119 utf8_printf(stderr, "Unknown option: \"%s\"\n", azArg[ii]);
9120 rc = 1;
9121 goto meta_command_exit;
drhceba7922018-01-01 21:28:25 +00009122 }else if( zName==0 ){
9123 zName = azArg[ii];
drh2ce15c32017-07-11 13:34:40 +00009124 }else{
drhbbb29ec2020-10-12 14:56:47 +00009125 raw_printf(stderr, "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
drhceba7922018-01-01 21:28:25 +00009126 rc = 1;
9127 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00009128 }
drh2ce15c32017-07-11 13:34:40 +00009129 }
drhceba7922018-01-01 21:28:25 +00009130 if( zName!=0 ){
drh067b92b2020-06-19 15:24:12 +00009131 int isSchema = sqlite3_strlike(zName, "sqlite_master", '\\')==0
drh346a70c2020-06-15 20:27:35 +00009132 || sqlite3_strlike(zName, "sqlite_schema", '\\')==0
9133 || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0
9134 || sqlite3_strlike(zName,"sqlite_temp_schema", '\\')==0;
drh067b92b2020-06-19 15:24:12 +00009135 if( isSchema ){
drh2ce15c32017-07-11 13:34:40 +00009136 char *new_argv[2], *new_colv[2];
drhc22b7162018-01-01 20:11:23 +00009137 new_argv[0] = sqlite3_mprintf(
9138 "CREATE TABLE %s (\n"
drh2ce15c32017-07-11 13:34:40 +00009139 " type text,\n"
9140 " name text,\n"
9141 " tbl_name text,\n"
9142 " rootpage integer,\n"
9143 " sql text\n"
drh346a70c2020-06-15 20:27:35 +00009144 ")", zName);
drh2ce15c32017-07-11 13:34:40 +00009145 new_argv[1] = 0;
9146 new_colv[0] = "sql";
9147 new_colv[1] = 0;
9148 callback(&data, 1, new_argv, new_colv);
drhc22b7162018-01-01 20:11:23 +00009149 sqlite3_free(new_argv[0]);
drh2ce15c32017-07-11 13:34:40 +00009150 }
drh2ce15c32017-07-11 13:34:40 +00009151 }
9152 if( zDiv ){
9153 sqlite3_stmt *pStmt = 0;
9154 rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
9155 -1, &pStmt, 0);
9156 if( rc ){
9157 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
9158 sqlite3_finalize(pStmt);
9159 rc = 1;
9160 goto meta_command_exit;
9161 }
9162 appendText(&sSelect, "SELECT sql FROM", 0);
9163 iSchema = 0;
9164 while( sqlite3_step(pStmt)==SQLITE_ROW ){
9165 const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
9166 char zScNum[30];
9167 sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
9168 appendText(&sSelect, zDiv, 0);
9169 zDiv = " UNION ALL ";
drhceba7922018-01-01 21:28:25 +00009170 appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
9171 if( sqlite3_stricmp(zDb, "main")!=0 ){
drhea38f4f2019-07-13 17:21:47 +00009172 appendText(&sSelect, zDb, '\'');
drh2ce15c32017-07-11 13:34:40 +00009173 }else{
drhceba7922018-01-01 21:28:25 +00009174 appendText(&sSelect, "NULL", 0);
drh2ce15c32017-07-11 13:34:40 +00009175 }
drhceba7922018-01-01 21:28:25 +00009176 appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0);
9177 appendText(&sSelect, zScNum, 0);
9178 appendText(&sSelect, " AS snum, ", 0);
9179 appendText(&sSelect, zDb, '\'');
9180 appendText(&sSelect, " AS sname FROM ", 0);
drhea38f4f2019-07-13 17:21:47 +00009181 appendText(&sSelect, zDb, quoteChar(zDb));
drh067b92b2020-06-19 15:24:12 +00009182 appendText(&sSelect, ".sqlite_schema", 0);
drh2ce15c32017-07-11 13:34:40 +00009183 }
9184 sqlite3_finalize(pStmt);
drhcc3f3d12019-08-17 15:27:58 +00009185#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
drh667a2a22018-01-02 00:04:37 +00009186 if( zName ){
9187 appendText(&sSelect,
9188 " UNION ALL SELECT shell_module_schema(name),"
drhe2754c12019-08-26 12:50:01 +00009189 " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list",
9190 0);
drh667a2a22018-01-02 00:04:37 +00009191 }
drhcde7b772018-01-02 12:50:40 +00009192#endif
drh2ce15c32017-07-11 13:34:40 +00009193 appendText(&sSelect, ") WHERE ", 0);
drhceba7922018-01-01 21:28:25 +00009194 if( zName ){
9195 char *zQarg = sqlite3_mprintf("%Q", zName);
mistachkin9d107262018-03-23 14:24:34 +00009196 int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
9197 strchr(zName, '[') != 0;
drhceba7922018-01-01 21:28:25 +00009198 if( strchr(zName, '.') ){
drh2ce15c32017-07-11 13:34:40 +00009199 appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
9200 }else{
9201 appendText(&sSelect, "lower(tbl_name)", 0);
9202 }
mistachkin9d107262018-03-23 14:24:34 +00009203 appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0);
drh2ce15c32017-07-11 13:34:40 +00009204 appendText(&sSelect, zQarg, 0);
mistachkin9d107262018-03-23 14:24:34 +00009205 if( !bGlob ){
9206 appendText(&sSelect, " ESCAPE '\\' ", 0);
9207 }
drh2ce15c32017-07-11 13:34:40 +00009208 appendText(&sSelect, " AND ", 0);
9209 sqlite3_free(zQarg);
9210 }
drhbbb29ec2020-10-12 14:56:47 +00009211 if( bNoSystemTabs ){
9212 appendText(&sSelect, "name NOT LIKE 'sqlite_%%' AND ", 0);
9213 }
9214 appendText(&sSelect, "sql IS NOT NULL"
drh2ce15c32017-07-11 13:34:40 +00009215 " ORDER BY snum, rowid", 0);
drhceba7922018-01-01 21:28:25 +00009216 if( bDebug ){
9217 utf8_printf(p->out, "SQL: %s;\n", sSelect.z);
9218 }else{
9219 rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
9220 }
drh2ce15c32017-07-11 13:34:40 +00009221 freeText(&sSelect);
9222 }
9223 if( zErrMsg ){
9224 utf8_printf(stderr,"Error: %s\n", zErrMsg);
9225 sqlite3_free(zErrMsg);
9226 rc = 1;
9227 }else if( rc != SQLITE_OK ){
9228 raw_printf(stderr,"Error: querying schema information\n");
9229 rc = 1;
9230 }else{
9231 rc = 0;
9232 }
9233 }else
9234
drh2ce15c32017-07-11 13:34:40 +00009235 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
drhfda8e492020-12-04 16:04:45 +00009236 unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
drhc0622a42020-12-04 01:17:57 +00009237 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x);
drh2ce15c32017-07-11 13:34:40 +00009238 }else
drh2ce15c32017-07-11 13:34:40 +00009239
9240#if defined(SQLITE_ENABLE_SESSION)
9241 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
9242 OpenSession *pSession = &p->aSession[0];
9243 char **azCmd = &azArg[1];
9244 int iSes = 0;
9245 int nCmd = nArg - 1;
9246 int i;
9247 if( nArg<=1 ) goto session_syntax_error;
9248 open_db(p, 0);
9249 if( nArg>=3 ){
9250 for(iSes=0; iSes<p->nSession; iSes++){
9251 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
9252 }
9253 if( iSes<p->nSession ){
9254 pSession = &p->aSession[iSes];
9255 azCmd++;
9256 nCmd--;
9257 }else{
9258 pSession = &p->aSession[0];
9259 iSes = 0;
9260 }
9261 }
9262
9263 /* .session attach TABLE
9264 ** Invoke the sqlite3session_attach() interface to attach a particular
9265 ** table so that it is never filtered.
9266 */
9267 if( strcmp(azCmd[0],"attach")==0 ){
9268 if( nCmd!=2 ) goto session_syntax_error;
9269 if( pSession->p==0 ){
9270 session_not_open:
9271 raw_printf(stderr, "ERROR: No sessions are open\n");
9272 }else{
9273 rc = sqlite3session_attach(pSession->p, azCmd[1]);
9274 if( rc ){
9275 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
9276 rc = 0;
9277 }
9278 }
9279 }else
9280
9281 /* .session changeset FILE
9282 ** .session patchset FILE
9283 ** Write a changeset or patchset into a file. The file is overwritten.
9284 */
9285 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
9286 FILE *out = 0;
9287 if( nCmd!=2 ) goto session_syntax_error;
9288 if( pSession->p==0 ) goto session_not_open;
9289 out = fopen(azCmd[1], "wb");
9290 if( out==0 ){
drhe2754c12019-08-26 12:50:01 +00009291 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n",
9292 azCmd[1]);
drh2ce15c32017-07-11 13:34:40 +00009293 }else{
9294 int szChng;
9295 void *pChng;
9296 if( azCmd[0][0]=='c' ){
9297 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
9298 }else{
9299 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
9300 }
9301 if( rc ){
9302 printf("Error: error code %d\n", rc);
9303 rc = 0;
9304 }
9305 if( pChng
9306 && fwrite(pChng, szChng, 1, out)!=1 ){
9307 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
9308 szChng);
9309 }
9310 sqlite3_free(pChng);
9311 fclose(out);
9312 }
9313 }else
9314
9315 /* .session close
9316 ** Close the identified session
9317 */
9318 if( strcmp(azCmd[0], "close")==0 ){
9319 if( nCmd!=1 ) goto session_syntax_error;
9320 if( p->nSession ){
9321 session_close(pSession);
9322 p->aSession[iSes] = p->aSession[--p->nSession];
9323 }
9324 }else
9325
9326 /* .session enable ?BOOLEAN?
9327 ** Query or set the enable flag
9328 */
9329 if( strcmp(azCmd[0], "enable")==0 ){
9330 int ii;
9331 if( nCmd>2 ) goto session_syntax_error;
9332 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
9333 if( p->nSession ){
9334 ii = sqlite3session_enable(pSession->p, ii);
9335 utf8_printf(p->out, "session %s enable flag = %d\n",
9336 pSession->zName, ii);
9337 }
9338 }else
9339
9340 /* .session filter GLOB ....
9341 ** Set a list of GLOB patterns of table names to be excluded.
9342 */
9343 if( strcmp(azCmd[0], "filter")==0 ){
9344 int ii, nByte;
9345 if( nCmd<2 ) goto session_syntax_error;
9346 if( p->nSession ){
9347 for(ii=0; ii<pSession->nFilter; ii++){
9348 sqlite3_free(pSession->azFilter[ii]);
9349 }
9350 sqlite3_free(pSession->azFilter);
9351 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
9352 pSession->azFilter = sqlite3_malloc( nByte );
9353 if( pSession->azFilter==0 ){
9354 raw_printf(stderr, "Error: out or memory\n");
9355 exit(1);
9356 }
9357 for(ii=1; ii<nCmd; ii++){
9358 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
9359 }
9360 pSession->nFilter = ii-1;
9361 }
9362 }else
9363
9364 /* .session indirect ?BOOLEAN?
9365 ** Query or set the indirect flag
9366 */
9367 if( strcmp(azCmd[0], "indirect")==0 ){
9368 int ii;
9369 if( nCmd>2 ) goto session_syntax_error;
9370 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
9371 if( p->nSession ){
9372 ii = sqlite3session_indirect(pSession->p, ii);
9373 utf8_printf(p->out, "session %s indirect flag = %d\n",
9374 pSession->zName, ii);
9375 }
9376 }else
9377
9378 /* .session isempty
9379 ** Determine if the session is empty
9380 */
9381 if( strcmp(azCmd[0], "isempty")==0 ){
9382 int ii;
9383 if( nCmd!=1 ) goto session_syntax_error;
9384 if( p->nSession ){
9385 ii = sqlite3session_isempty(pSession->p);
9386 utf8_printf(p->out, "session %s isempty flag = %d\n",
9387 pSession->zName, ii);
9388 }
9389 }else
9390
9391 /* .session list
9392 ** List all currently open sessions
9393 */
9394 if( strcmp(azCmd[0],"list")==0 ){
9395 for(i=0; i<p->nSession; i++){
9396 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
9397 }
9398 }else
9399
9400 /* .session open DB NAME
9401 ** Open a new session called NAME on the attached database DB.
9402 ** DB is normally "main".
9403 */
9404 if( strcmp(azCmd[0],"open")==0 ){
9405 char *zName;
9406 if( nCmd!=3 ) goto session_syntax_error;
9407 zName = azCmd[2];
9408 if( zName[0]==0 ) goto session_syntax_error;
9409 for(i=0; i<p->nSession; i++){
9410 if( strcmp(p->aSession[i].zName,zName)==0 ){
9411 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
9412 goto meta_command_exit;
9413 }
9414 }
9415 if( p->nSession>=ArraySize(p->aSession) ){
9416 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
9417 goto meta_command_exit;
9418 }
9419 pSession = &p->aSession[p->nSession];
9420 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
9421 if( rc ){
9422 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
9423 rc = 0;
9424 goto meta_command_exit;
9425 }
9426 pSession->nFilter = 0;
9427 sqlite3session_table_filter(pSession->p, session_filter, pSession);
9428 p->nSession++;
9429 pSession->zName = sqlite3_mprintf("%s", zName);
9430 }else
9431 /* If no command name matches, show a syntax error */
9432 session_syntax_error:
drheb7f2a02018-09-26 18:02:32 +00009433 showHelp(p->out, "session");
drh2ce15c32017-07-11 13:34:40 +00009434 }else
9435#endif
9436
9437#ifdef SQLITE_DEBUG
9438 /* Undocumented commands for internal testing. Subject to change
9439 ** without notice. */
9440 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
9441 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
9442 int i, v;
9443 for(i=1; i<nArg; i++){
9444 v = booleanValue(azArg[i]);
9445 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
9446 }
9447 }
9448 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
9449 int i; sqlite3_int64 v;
9450 for(i=1; i<nArg; i++){
9451 char zBuf[200];
9452 v = integerValue(azArg[i]);
9453 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
9454 utf8_printf(p->out, "%s", zBuf);
9455 }
9456 }
9457 }else
9458#endif
9459
9460 if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){
9461 int bIsInit = 0; /* True to initialize the SELFTEST table */
9462 int bVerbose = 0; /* Verbose output */
9463 int bSelftestExists; /* True if SELFTEST already exists */
9464 int i, k; /* Loop counters */
9465 int nTest = 0; /* Number of tests runs */
9466 int nErr = 0; /* Number of errors seen */
9467 ShellText str; /* Answer for a query */
9468 sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */
9469
9470 open_db(p,0);
9471 for(i=1; i<nArg; i++){
9472 const char *z = azArg[i];
9473 if( z[0]=='-' && z[1]=='-' ) z++;
9474 if( strcmp(z,"-init")==0 ){
9475 bIsInit = 1;
9476 }else
9477 if( strcmp(z,"-v")==0 ){
9478 bVerbose++;
9479 }else
9480 {
9481 utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
9482 azArg[i], azArg[0]);
9483 raw_printf(stderr, "Should be one of: --init -v\n");
9484 rc = 1;
9485 goto meta_command_exit;
9486 }
9487 }
9488 if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0)
9489 != SQLITE_OK ){
9490 bSelftestExists = 0;
9491 }else{
9492 bSelftestExists = 1;
9493 }
9494 if( bIsInit ){
9495 createSelftestTable(p);
9496 bSelftestExists = 1;
9497 }
9498 initText(&str);
9499 appendText(&str, "x", 0);
9500 for(k=bSelftestExists; k>=0; k--){
9501 if( k==1 ){
9502 rc = sqlite3_prepare_v2(p->db,
9503 "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno",
9504 -1, &pStmt, 0);
9505 }else{
9506 rc = sqlite3_prepare_v2(p->db,
9507 "VALUES(0,'memo','Missing SELFTEST table - default checks only',''),"
9508 " (1,'run','PRAGMA integrity_check','ok')",
9509 -1, &pStmt, 0);
9510 }
9511 if( rc ){
9512 raw_printf(stderr, "Error querying the selftest table\n");
9513 rc = 1;
9514 sqlite3_finalize(pStmt);
9515 goto meta_command_exit;
9516 }
9517 for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){
9518 int tno = sqlite3_column_int(pStmt, 0);
9519 const char *zOp = (const char*)sqlite3_column_text(pStmt, 1);
9520 const char *zSql = (const char*)sqlite3_column_text(pStmt, 2);
9521 const char *zAns = (const char*)sqlite3_column_text(pStmt, 3);
9522
9523 k = 0;
9524 if( bVerbose>0 ){
9525 char *zQuote = sqlite3_mprintf("%q", zSql);
9526 printf("%d: %s %s\n", tno, zOp, zSql);
9527 sqlite3_free(zQuote);
9528 }
9529 if( strcmp(zOp,"memo")==0 ){
9530 utf8_printf(p->out, "%s\n", zSql);
9531 }else
9532 if( strcmp(zOp,"run")==0 ){
9533 char *zErrMsg = 0;
9534 str.n = 0;
9535 str.z[0] = 0;
9536 rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
9537 nTest++;
9538 if( bVerbose ){
9539 utf8_printf(p->out, "Result: %s\n", str.z);
9540 }
9541 if( rc || zErrMsg ){
9542 nErr++;
9543 rc = 1;
9544 utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg);
9545 sqlite3_free(zErrMsg);
9546 }else if( strcmp(zAns,str.z)!=0 ){
9547 nErr++;
9548 rc = 1;
9549 utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns);
9550 utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z);
9551 }
9552 }else
9553 {
9554 utf8_printf(stderr,
9555 "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
9556 rc = 1;
9557 break;
9558 }
9559 } /* End loop over rows of content from SELFTEST */
9560 sqlite3_finalize(pStmt);
9561 } /* End loop over k */
9562 freeText(&str);
9563 utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest);
9564 }else
9565
9566 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
9567 if( nArg<2 || nArg>3 ){
9568 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
9569 rc = 1;
9570 }
9571 if( nArg>=2 ){
9572 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
9573 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
9574 }
9575 if( nArg>=3 ){
9576 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
9577 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
9578 }
9579 }else
9580
9581 if( c=='s' && n>=4 && strncmp(azArg[0],"sha3sum",n)==0 ){
9582 const char *zLike = 0; /* Which table to checksum. 0 means everything */
9583 int i; /* Loop counter */
9584 int bSchema = 0; /* Also hash the schema */
9585 int bSeparate = 0; /* Hash each table separately */
9586 int iSize = 224; /* Hash algorithm to use */
9587 int bDebug = 0; /* Only show the query that would have run */
9588 sqlite3_stmt *pStmt; /* For querying tables names */
9589 char *zSql; /* SQL to be run */
9590 char *zSep; /* Separator */
9591 ShellText sSql; /* Complete SQL for the query to run the hash */
9592 ShellText sQuery; /* Set of queries used to read all content */
9593 open_db(p, 0);
9594 for(i=1; i<nArg; i++){
9595 const char *z = azArg[i];
9596 if( z[0]=='-' ){
9597 z++;
9598 if( z[0]=='-' ) z++;
9599 if( strcmp(z,"schema")==0 ){
9600 bSchema = 1;
9601 }else
9602 if( strcmp(z,"sha3-224")==0 || strcmp(z,"sha3-256")==0
9603 || strcmp(z,"sha3-384")==0 || strcmp(z,"sha3-512")==0
9604 ){
9605 iSize = atoi(&z[5]);
9606 }else
9607 if( strcmp(z,"debug")==0 ){
9608 bDebug = 1;
9609 }else
9610 {
9611 utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
9612 azArg[i], azArg[0]);
drhe2754c12019-08-26 12:50:01 +00009613 showHelp(p->out, azArg[0]);
drh2ce15c32017-07-11 13:34:40 +00009614 rc = 1;
9615 goto meta_command_exit;
9616 }
9617 }else if( zLike ){
9618 raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
9619 rc = 1;
9620 goto meta_command_exit;
9621 }else{
9622 zLike = z;
9623 bSeparate = 1;
drhcedfecf2018-03-23 12:59:10 +00009624 if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1;
drh2ce15c32017-07-11 13:34:40 +00009625 }
9626 }
9627 if( bSchema ){
drh067b92b2020-06-19 15:24:12 +00009628 zSql = "SELECT lower(name) FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00009629 " WHERE type='table' AND coalesce(rootpage,0)>1"
drh067b92b2020-06-19 15:24:12 +00009630 " UNION ALL SELECT 'sqlite_schema'"
drh2ce15c32017-07-11 13:34:40 +00009631 " ORDER BY 1 collate nocase";
9632 }else{
drh067b92b2020-06-19 15:24:12 +00009633 zSql = "SELECT lower(name) FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00009634 " WHERE type='table' AND coalesce(rootpage,0)>1"
9635 " AND name NOT LIKE 'sqlite_%'"
9636 " ORDER BY 1 collate nocase";
9637 }
9638 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
9639 initText(&sQuery);
9640 initText(&sSql);
9641 appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0);
9642 zSep = "VALUES(";
9643 while( SQLITE_ROW==sqlite3_step(pStmt) ){
9644 const char *zTab = (const char*)sqlite3_column_text(pStmt,0);
9645 if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue;
9646 if( strncmp(zTab, "sqlite_",7)!=0 ){
9647 appendText(&sQuery,"SELECT * FROM ", 0);
9648 appendText(&sQuery,zTab,'"');
9649 appendText(&sQuery," NOT INDEXED;", 0);
drh067b92b2020-06-19 15:24:12 +00009650 }else if( strcmp(zTab, "sqlite_schema")==0 ){
9651 appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00009652 " ORDER BY name;", 0);
9653 }else if( strcmp(zTab, "sqlite_sequence")==0 ){
9654 appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence"
9655 " ORDER BY name;", 0);
9656 }else if( strcmp(zTab, "sqlite_stat1")==0 ){
9657 appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1"
9658 " ORDER BY tbl,idx;", 0);
drh175b8f02019-08-08 15:24:17 +00009659 }else if( strcmp(zTab, "sqlite_stat4")==0 ){
drh2ce15c32017-07-11 13:34:40 +00009660 appendText(&sQuery, "SELECT * FROM ", 0);
9661 appendText(&sQuery, zTab, 0);
9662 appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
9663 }
9664 appendText(&sSql, zSep, 0);
9665 appendText(&sSql, sQuery.z, '\'');
9666 sQuery.n = 0;
9667 appendText(&sSql, ",", 0);
9668 appendText(&sSql, zTab, '\'');
9669 zSep = "),(";
9670 }
9671 sqlite3_finalize(pStmt);
9672 if( bSeparate ){
9673 zSql = sqlite3_mprintf(
9674 "%s))"
9675 " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
9676 " FROM [sha3sum$query]",
9677 sSql.z, iSize);
9678 }else{
9679 zSql = sqlite3_mprintf(
9680 "%s))"
9681 " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
9682 " FROM [sha3sum$query]",
9683 sSql.z, iSize);
9684 }
9685 freeText(&sQuery);
9686 freeText(&sSql);
9687 if( bDebug ){
9688 utf8_printf(p->out, "%s\n", zSql);
9689 }else{
drha10b9992018-03-09 15:24:33 +00009690 shell_exec(p, zSql, 0);
drh2ce15c32017-07-11 13:34:40 +00009691 }
9692 sqlite3_free(zSql);
9693 }else
9694
drh04a28c32018-01-31 01:38:44 +00009695#ifndef SQLITE_NOHAVE_SYSTEM
drh2ce15c32017-07-11 13:34:40 +00009696 if( c=='s'
9697 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
9698 ){
9699 char *zCmd;
9700 int i, x;
9701 if( nArg<2 ){
9702 raw_printf(stderr, "Usage: .system COMMAND\n");
9703 rc = 1;
9704 goto meta_command_exit;
9705 }
9706 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
9707 for(i=2; i<nArg; i++){
9708 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
9709 zCmd, azArg[i]);
9710 }
9711 x = system(zCmd);
9712 sqlite3_free(zCmd);
9713 if( x ) raw_printf(stderr, "System command returns %d\n", x);
9714 }else
drh04a28c32018-01-31 01:38:44 +00009715#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
drh2ce15c32017-07-11 13:34:40 +00009716
9717 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drhada70452017-12-21 21:02:27 +00009718 static const char *azBool[] = { "off", "on", "trigger", "full"};
drh2ce15c32017-07-11 13:34:40 +00009719 int i;
9720 if( nArg!=1 ){
9721 raw_printf(stderr, "Usage: .show\n");
9722 rc = 1;
9723 goto meta_command_exit;
9724 }
9725 utf8_printf(p->out, "%12.12s: %s\n","echo",
9726 azBool[ShellHasFlag(p, SHFLG_Echo)]);
9727 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
9728 utf8_printf(p->out, "%12.12s: %s\n","explain",
9729 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
9730 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
9731 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
9732 utf8_printf(p->out, "%12.12s: ", "nullvalue");
9733 output_c_string(p->out, p->nullValue);
9734 raw_printf(p->out, "\n");
9735 utf8_printf(p->out,"%12.12s: %s\n","output",
9736 strlen30(p->outfile) ? p->outfile : "stdout");
9737 utf8_printf(p->out,"%12.12s: ", "colseparator");
9738 output_c_string(p->out, p->colSeparator);
9739 raw_printf(p->out, "\n");
9740 utf8_printf(p->out,"%12.12s: ", "rowseparator");
9741 output_c_string(p->out, p->rowSeparator);
9742 raw_printf(p->out, "\n");
9743 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
9744 utf8_printf(p->out, "%12.12s: ", "width");
drh0285d982020-05-29 14:38:43 +00009745 for (i=0;i<p->nWidth;i++) {
drh2ce15c32017-07-11 13:34:40 +00009746 raw_printf(p->out, "%d ", p->colWidth[i]);
9747 }
9748 raw_printf(p->out, "\n");
9749 utf8_printf(p->out, "%12.12s: %s\n", "filename",
9750 p->zDbFilename ? p->zDbFilename : "");
9751 }else
9752
9753 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
9754 if( nArg==2 ){
mistachkinb71aa092018-01-23 00:05:18 +00009755 p->statsOn = (u8)booleanValue(azArg[1]);
drh2ce15c32017-07-11 13:34:40 +00009756 }else if( nArg==1 ){
9757 display_stats(p->db, p, 0);
9758 }else{
9759 raw_printf(stderr, "Usage: .stats ?on|off?\n");
9760 rc = 1;
9761 }
9762 }else
9763
9764 if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
9765 || (c=='i' && (strncmp(azArg[0], "indices", n)==0
9766 || strncmp(azArg[0], "indexes", n)==0) )
9767 ){
9768 sqlite3_stmt *pStmt;
9769 char **azResult;
9770 int nRow, nAlloc;
9771 int ii;
9772 ShellText s;
9773 initText(&s);
9774 open_db(p, 0);
9775 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
drh9e804032018-05-18 17:11:50 +00009776 if( rc ){
9777 sqlite3_finalize(pStmt);
9778 return shellDatabaseError(p->db);
9779 }
drh2ce15c32017-07-11 13:34:40 +00009780
9781 if( nArg>2 && c=='i' ){
9782 /* It is an historical accident that the .indexes command shows an error
9783 ** when called with the wrong number of arguments whereas the .tables
9784 ** command does not. */
9785 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
9786 rc = 1;
drh9e804032018-05-18 17:11:50 +00009787 sqlite3_finalize(pStmt);
drh2ce15c32017-07-11 13:34:40 +00009788 goto meta_command_exit;
9789 }
9790 for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
9791 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
9792 if( zDbName==0 ) continue;
9793 if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
9794 if( sqlite3_stricmp(zDbName, "main")==0 ){
9795 appendText(&s, "SELECT name FROM ", 0);
9796 }else{
9797 appendText(&s, "SELECT ", 0);
9798 appendText(&s, zDbName, '\'');
9799 appendText(&s, "||'.'||name FROM ", 0);
9800 }
9801 appendText(&s, zDbName, '"');
drh067b92b2020-06-19 15:24:12 +00009802 appendText(&s, ".sqlite_schema ", 0);
drh2ce15c32017-07-11 13:34:40 +00009803 if( c=='t' ){
9804 appendText(&s," WHERE type IN ('table','view')"
9805 " AND name NOT LIKE 'sqlite_%'"
9806 " AND name LIKE ?1", 0);
9807 }else{
9808 appendText(&s," WHERE type='index'"
9809 " AND tbl_name LIKE ?1", 0);
9810 }
9811 }
9812 rc = sqlite3_finalize(pStmt);
9813 appendText(&s, " ORDER BY 1", 0);
9814 rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);
9815 freeText(&s);
9816 if( rc ) return shellDatabaseError(p->db);
9817
9818 /* Run the SQL statement prepared by the above block. Store the results
9819 ** as an array of nul-terminated strings in azResult[]. */
9820 nRow = nAlloc = 0;
9821 azResult = 0;
9822 if( nArg>1 ){
9823 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
9824 }else{
9825 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
9826 }
9827 while( sqlite3_step(pStmt)==SQLITE_ROW ){
9828 if( nRow>=nAlloc ){
9829 char **azNew;
9830 int n2 = nAlloc*2 + 10;
9831 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh4b5345c2018-04-24 13:07:40 +00009832 if( azNew==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00009833 nAlloc = n2;
9834 azResult = azNew;
9835 }
9836 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
drh4b5345c2018-04-24 13:07:40 +00009837 if( 0==azResult[nRow] ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00009838 nRow++;
9839 }
9840 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
9841 rc = shellDatabaseError(p->db);
9842 }
9843
9844 /* Pretty-print the contents of array azResult[] to the output */
9845 if( rc==0 && nRow>0 ){
9846 int len, maxlen = 0;
9847 int i, j;
9848 int nPrintCol, nPrintRow;
9849 for(i=0; i<nRow; i++){
9850 len = strlen30(azResult[i]);
9851 if( len>maxlen ) maxlen = len;
9852 }
9853 nPrintCol = 80/(maxlen+2);
9854 if( nPrintCol<1 ) nPrintCol = 1;
9855 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
9856 for(i=0; i<nPrintRow; i++){
9857 for(j=i; j<nRow; j+=nPrintRow){
9858 char *zSp = j<nPrintRow ? "" : " ";
9859 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
9860 azResult[j] ? azResult[j]:"");
9861 }
9862 raw_printf(p->out, "\n");
9863 }
9864 }
9865
9866 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
9867 sqlite3_free(azResult);
9868 }else
9869
9870 /* Begin redirecting output to the file "testcase-out.txt" */
9871 if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
9872 output_reset(p);
drha92a01a2018-01-10 22:15:37 +00009873 p->out = output_file_open("testcase-out.txt", 0);
drh2ce15c32017-07-11 13:34:40 +00009874 if( p->out==0 ){
9875 raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
9876 }
9877 if( nArg>=2 ){
9878 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
9879 }else{
9880 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
9881 }
9882 }else
9883
9884#ifndef SQLITE_UNTESTABLE
drh35f51a42017-11-15 17:07:22 +00009885 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
drh2ce15c32017-07-11 13:34:40 +00009886 static const struct {
9887 const char *zCtrlName; /* Name of a test-control option */
9888 int ctrlCode; /* Integer code for that option */
drhef302e82017-11-15 19:14:08 +00009889 const char *zUsage; /* Usage notes */
drh2ce15c32017-07-11 13:34:40 +00009890 } aCtrl[] = {
drhe2754c12019-08-26 12:50:01 +00009891 { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" },
9892 { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" },
9893 /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
9894 /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
9895 { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
9896 { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" },
9897 /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/
9898 { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
drh171c50e2020-01-01 15:43:30 +00009899 { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "" },
drhe2754c12019-08-26 12:50:01 +00009900 { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
9901 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
9902 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
drh0d9de992017-12-26 18:04:23 +00009903#ifdef YYCOVERAGE
drhe2754c12019-08-26 12:50:01 +00009904 { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
drh0d9de992017-12-26 18:04:23 +00009905#endif
drhe2754c12019-08-26 12:50:01 +00009906 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
9907 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
9908 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
9909 { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
drh37ccfcf2020-08-31 18:49:04 +00009910 { "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, "" },
drh2ce15c32017-07-11 13:34:40 +00009911 };
9912 int testctrl = -1;
drhef302e82017-11-15 19:14:08 +00009913 int iCtrl = -1;
9914 int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */
9915 int isOk = 0;
drh2ce15c32017-07-11 13:34:40 +00009916 int i, n2;
mistachkinc6bc15a2017-11-21 21:14:32 +00009917 const char *zCmd = 0;
9918
drh2ce15c32017-07-11 13:34:40 +00009919 open_db(p, 0);
mistachkinc6bc15a2017-11-21 21:14:32 +00009920 zCmd = nArg>=2 ? azArg[1] : "help";
drh35f51a42017-11-15 17:07:22 +00009921
9922 /* The argument can optionally begin with "-" or "--" */
9923 if( zCmd[0]=='-' && zCmd[1] ){
9924 zCmd++;
9925 if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
9926 }
9927
9928 /* --help lists all test-controls */
9929 if( strcmp(zCmd,"help")==0 ){
9930 utf8_printf(p->out, "Available test-controls:\n");
9931 for(i=0; i<ArraySize(aCtrl); i++){
drhef302e82017-11-15 19:14:08 +00009932 utf8_printf(p->out, " .testctrl %s %s\n",
9933 aCtrl[i].zCtrlName, aCtrl[i].zUsage);
drh35f51a42017-11-15 17:07:22 +00009934 }
9935 rc = 1;
9936 goto meta_command_exit;
9937 }
drh2ce15c32017-07-11 13:34:40 +00009938
9939 /* convert testctrl text option to value. allow any unique prefix
9940 ** of the option name, or a numerical value. */
drh35f51a42017-11-15 17:07:22 +00009941 n2 = strlen30(zCmd);
drh2ce15c32017-07-11 13:34:40 +00009942 for(i=0; i<ArraySize(aCtrl); i++){
drh35f51a42017-11-15 17:07:22 +00009943 if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
drh2ce15c32017-07-11 13:34:40 +00009944 if( testctrl<0 ){
9945 testctrl = aCtrl[i].ctrlCode;
drhef302e82017-11-15 19:14:08 +00009946 iCtrl = i;
drh2ce15c32017-07-11 13:34:40 +00009947 }else{
drh35f51a42017-11-15 17:07:22 +00009948 utf8_printf(stderr, "Error: ambiguous test-control: \"%s\"\n"
9949 "Use \".testctrl --help\" for help\n", zCmd);
9950 rc = 1;
9951 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00009952 }
9953 }
9954 }
drhef302e82017-11-15 19:14:08 +00009955 if( testctrl<0 ){
drh35f51a42017-11-15 17:07:22 +00009956 utf8_printf(stderr,"Error: unknown test-control: %s\n"
9957 "Use \".testctrl --help\" for help\n", zCmd);
drh2ce15c32017-07-11 13:34:40 +00009958 }else{
9959 switch(testctrl){
9960
9961 /* sqlite3_test_control(int, db, int) */
9962 case SQLITE_TESTCTRL_OPTIMIZATIONS:
drh2ce15c32017-07-11 13:34:40 +00009963 if( nArg==3 ){
9964 int opt = (int)strtol(azArg[2], 0, 0);
9965 rc2 = sqlite3_test_control(testctrl, p->db, opt);
drhef302e82017-11-15 19:14:08 +00009966 isOk = 3;
drh2ce15c32017-07-11 13:34:40 +00009967 }
9968 break;
9969
9970 /* sqlite3_test_control(int) */
9971 case SQLITE_TESTCTRL_PRNG_SAVE:
9972 case SQLITE_TESTCTRL_PRNG_RESTORE:
drh2ce15c32017-07-11 13:34:40 +00009973 case SQLITE_TESTCTRL_BYTEORDER:
9974 if( nArg==2 ){
9975 rc2 = sqlite3_test_control(testctrl);
drhef302e82017-11-15 19:14:08 +00009976 isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3;
drh2ce15c32017-07-11 13:34:40 +00009977 }
9978 break;
9979
9980 /* sqlite3_test_control(int, uint) */
9981 case SQLITE_TESTCTRL_PENDING_BYTE:
9982 if( nArg==3 ){
9983 unsigned int opt = (unsigned int)integerValue(azArg[2]);
9984 rc2 = sqlite3_test_control(testctrl, opt);
drhef302e82017-11-15 19:14:08 +00009985 isOk = 3;
drh2ce15c32017-07-11 13:34:40 +00009986 }
9987 break;
9988
drh2e6d83b2019-08-03 01:39:20 +00009989 /* sqlite3_test_control(int, int, sqlite3*) */
9990 case SQLITE_TESTCTRL_PRNG_SEED:
9991 if( nArg==3 || nArg==4 ){
drh51755a72019-08-08 19:40:29 +00009992 int ii = (int)integerValue(azArg[2]);
drh2e6d83b2019-08-03 01:39:20 +00009993 sqlite3 *db;
drh41428a92019-08-12 16:25:11 +00009994 if( ii==0 && strcmp(azArg[2],"random")==0 ){
9995 sqlite3_randomness(sizeof(ii),&ii);
9996 printf("-- random seed: %d\n", ii);
9997 }
drh2e6d83b2019-08-03 01:39:20 +00009998 if( nArg==3 ){
9999 db = 0;
10000 }else{
10001 db = p->db;
10002 /* Make sure the schema has been loaded */
10003 sqlite3_table_column_metadata(db, 0, "x", 0, 0, 0, 0, 0, 0);
10004 }
drh51755a72019-08-08 19:40:29 +000010005 rc2 = sqlite3_test_control(testctrl, ii, db);
drh2e6d83b2019-08-03 01:39:20 +000010006 isOk = 3;
10007 }
10008 break;
10009
drh2ce15c32017-07-11 13:34:40 +000010010 /* sqlite3_test_control(int, int) */
10011 case SQLITE_TESTCTRL_ASSERT:
10012 case SQLITE_TESTCTRL_ALWAYS:
drhef302e82017-11-15 19:14:08 +000010013 if( nArg==3 ){
10014 int opt = booleanValue(azArg[2]);
10015 rc2 = sqlite3_test_control(testctrl, opt);
10016 isOk = 1;
10017 }
10018 break;
10019
10020 /* sqlite3_test_control(int, int) */
10021 case SQLITE_TESTCTRL_LOCALTIME_FAULT:
drh2ce15c32017-07-11 13:34:40 +000010022 case SQLITE_TESTCTRL_NEVER_CORRUPT:
10023 if( nArg==3 ){
10024 int opt = booleanValue(azArg[2]);
10025 rc2 = sqlite3_test_control(testctrl, opt);
drhef302e82017-11-15 19:14:08 +000010026 isOk = 3;
drh2ce15c32017-07-11 13:34:40 +000010027 }
10028 break;
10029
drh171c50e2020-01-01 15:43:30 +000010030 /* sqlite3_test_control(sqlite3*) */
10031 case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
10032 rc2 = sqlite3_test_control(testctrl, p->db);
drh2a83c102020-01-01 23:02:35 +000010033 isOk = 3;
drh171c50e2020-01-01 15:43:30 +000010034 break;
10035
drh2ce15c32017-07-11 13:34:40 +000010036 case SQLITE_TESTCTRL_IMPOSTER:
10037 if( nArg==5 ){
10038 rc2 = sqlite3_test_control(testctrl, p->db,
10039 azArg[2],
10040 integerValue(azArg[3]),
10041 integerValue(azArg[4]));
drhef302e82017-11-15 19:14:08 +000010042 isOk = 3;
drh2ce15c32017-07-11 13:34:40 +000010043 }
10044 break;
drh0d9de992017-12-26 18:04:23 +000010045
drh37ccfcf2020-08-31 18:49:04 +000010046 case SQLITE_TESTCTRL_SEEK_COUNT: {
10047 u64 x = 0;
10048 rc2 = sqlite3_test_control(testctrl, p->db, &x);
10049 utf8_printf(p->out, "%llu\n", x);
10050 isOk = 3;
10051 break;
10052 }
10053
drh0d9de992017-12-26 18:04:23 +000010054#ifdef YYCOVERAGE
10055 case SQLITE_TESTCTRL_PARSER_COVERAGE:
10056 if( nArg==2 ){
10057 sqlite3_test_control(testctrl, p->out);
10058 isOk = 3;
10059 }
10060#endif
drh2ce15c32017-07-11 13:34:40 +000010061 }
10062 }
drhef302e82017-11-15 19:14:08 +000010063 if( isOk==0 && iCtrl>=0 ){
drhe2754c12019-08-26 12:50:01 +000010064 utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
drhef302e82017-11-15 19:14:08 +000010065 rc = 1;
10066 }else if( isOk==1 ){
10067 raw_printf(p->out, "%d\n", rc2);
10068 }else if( isOk==2 ){
10069 raw_printf(p->out, "0x%08x\n", rc2);
10070 }
drh2ce15c32017-07-11 13:34:40 +000010071 }else
10072#endif /* !defined(SQLITE_UNTESTABLE) */
10073
10074 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
10075 open_db(p, 0);
10076 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
10077 }else
10078
10079 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
10080 if( nArg==2 ){
10081 enableTimer = booleanValue(azArg[1]);
10082 if( enableTimer && !HAS_TIMER ){
10083 raw_printf(stderr, "Error: timer not available on this system.\n");
10084 enableTimer = 0;
10085 }
10086 }else{
10087 raw_printf(stderr, "Usage: .timer on|off\n");
10088 rc = 1;
10089 }
10090 }else
10091
drh707821f2018-12-05 13:39:06 +000010092#ifndef SQLITE_OMIT_TRACE
drh2ce15c32017-07-11 13:34:40 +000010093 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh707821f2018-12-05 13:39:06 +000010094 int mType = 0;
10095 int jj;
drh2ce15c32017-07-11 13:34:40 +000010096 open_db(p, 0);
drh707821f2018-12-05 13:39:06 +000010097 for(jj=1; jj<nArg; jj++){
10098 const char *z = azArg[jj];
10099 if( z[0]=='-' ){
10100 if( optionMatch(z, "expanded") ){
10101 p->eTraceType = SHELL_TRACE_EXPANDED;
10102 }
10103#ifdef SQLITE_ENABLE_NORMALIZE
10104 else if( optionMatch(z, "normalized") ){
10105 p->eTraceType = SHELL_TRACE_NORMALIZED;
10106 }
10107#endif
10108 else if( optionMatch(z, "plain") ){
10109 p->eTraceType = SHELL_TRACE_PLAIN;
10110 }
10111 else if( optionMatch(z, "profile") ){
10112 mType |= SQLITE_TRACE_PROFILE;
10113 }
10114 else if( optionMatch(z, "row") ){
10115 mType |= SQLITE_TRACE_ROW;
10116 }
10117 else if( optionMatch(z, "stmt") ){
10118 mType |= SQLITE_TRACE_STMT;
10119 }
10120 else if( optionMatch(z, "close") ){
10121 mType |= SQLITE_TRACE_CLOSE;
10122 }
10123 else {
10124 raw_printf(stderr, "Unknown option \"%s\" on \".trace\"\n", z);
10125 rc = 1;
10126 goto meta_command_exit;
10127 }
10128 }else{
10129 output_file_close(p->traceOut);
10130 p->traceOut = output_file_open(azArg[1], 0);
10131 }
drh2ce15c32017-07-11 13:34:40 +000010132 }
drh2ce15c32017-07-11 13:34:40 +000010133 if( p->traceOut==0 ){
10134 sqlite3_trace_v2(p->db, 0, 0, 0);
10135 }else{
drh707821f2018-12-05 13:39:06 +000010136 if( mType==0 ) mType = SQLITE_TRACE_STMT;
10137 sqlite3_trace_v2(p->db, mType, sql_trace_callback, p);
drh2ce15c32017-07-11 13:34:40 +000010138 }
drh2ce15c32017-07-11 13:34:40 +000010139 }else
drh707821f2018-12-05 13:39:06 +000010140#endif /* !defined(SQLITE_OMIT_TRACE) */
drh2ce15c32017-07-11 13:34:40 +000010141
drhe2b7a762019-10-02 00:25:08 +000010142#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
drhcc5979d2019-08-16 22:58:29 +000010143 if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
10144 int ii;
drh8c754a32019-08-19 20:35:30 +000010145 int lenOpt;
drh5df84282019-08-17 19:45:25 +000010146 char *zOpt;
drhcc5979d2019-08-16 22:58:29 +000010147 if( nArg<2 ){
drh5df84282019-08-17 19:45:25 +000010148 raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
drhcc5979d2019-08-16 22:58:29 +000010149 rc = 1;
10150 goto meta_command_exit;
10151 }
10152 open_db(p, 0);
drh5df84282019-08-17 19:45:25 +000010153 zOpt = azArg[1];
10154 if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++;
drh8c754a32019-08-19 20:35:30 +000010155 lenOpt = (int)strlen(zOpt);
10156 if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){
drh5df84282019-08-17 19:45:25 +000010157 assert( azArg[nArg]==0 );
drh8c754a32019-08-19 20:35:30 +000010158 sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0);
drh5df84282019-08-17 19:45:25 +000010159 }else{
10160 for(ii=1; ii<nArg; ii++){
10161 sqlite3_create_module(p->db, azArg[ii], 0, 0);
10162 }
drhcc5979d2019-08-16 22:58:29 +000010163 }
10164 }else
10165#endif
10166
drh2ce15c32017-07-11 13:34:40 +000010167#if SQLITE_USER_AUTHENTICATION
10168 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
10169 if( nArg<2 ){
10170 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
10171 rc = 1;
10172 goto meta_command_exit;
10173 }
10174 open_db(p, 0);
10175 if( strcmp(azArg[1],"login")==0 ){
10176 if( nArg!=4 ){
10177 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
10178 rc = 1;
10179 goto meta_command_exit;
10180 }
drhe2754c12019-08-26 12:50:01 +000010181 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
10182 strlen30(azArg[3]));
drh2ce15c32017-07-11 13:34:40 +000010183 if( rc ){
10184 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
10185 rc = 1;
10186 }
10187 }else if( strcmp(azArg[1],"add")==0 ){
10188 if( nArg!=5 ){
10189 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
10190 rc = 1;
10191 goto meta_command_exit;
10192 }
drhaf2770f2018-01-05 14:55:43 +000010193 rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
drh2ce15c32017-07-11 13:34:40 +000010194 booleanValue(azArg[4]));
10195 if( rc ){
10196 raw_printf(stderr, "User-Add failed: %d\n", rc);
10197 rc = 1;
10198 }
10199 }else if( strcmp(azArg[1],"edit")==0 ){
10200 if( nArg!=5 ){
10201 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
10202 rc = 1;
10203 goto meta_command_exit;
10204 }
drhaf2770f2018-01-05 14:55:43 +000010205 rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
drh2ce15c32017-07-11 13:34:40 +000010206 booleanValue(azArg[4]));
10207 if( rc ){
10208 raw_printf(stderr, "User-Edit failed: %d\n", rc);
10209 rc = 1;
10210 }
10211 }else if( strcmp(azArg[1],"delete")==0 ){
10212 if( nArg!=3 ){
10213 raw_printf(stderr, "Usage: .user delete USER\n");
10214 rc = 1;
10215 goto meta_command_exit;
10216 }
10217 rc = sqlite3_user_delete(p->db, azArg[2]);
10218 if( rc ){
10219 raw_printf(stderr, "User-Delete failed: %d\n", rc);
10220 rc = 1;
10221 }
10222 }else{
10223 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
10224 rc = 1;
10225 goto meta_command_exit;
10226 }
10227 }else
10228#endif /* SQLITE_USER_AUTHENTICATION */
10229
10230 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
10231 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
10232 sqlite3_libversion(), sqlite3_sourceid());
drh0ed2fd82018-01-16 20:05:27 +000010233#if SQLITE_HAVE_ZLIB
10234 utf8_printf(p->out, "zlib version %s\n", zlibVersion());
10235#endif
10236#define CTIMEOPT_VAL_(opt) #opt
10237#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
10238#if defined(__clang__) && defined(__clang_major__)
10239 utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
10240 CTIMEOPT_VAL(__clang_minor__) "."
10241 CTIMEOPT_VAL(__clang_patchlevel__) "\n");
10242#elif defined(_MSC_VER)
10243 utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n");
10244#elif defined(__GNUC__) && defined(__VERSION__)
10245 utf8_printf(p->out, "gcc-" __VERSION__ "\n");
10246#endif
drh2ce15c32017-07-11 13:34:40 +000010247 }else
10248
10249 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
10250 const char *zDbName = nArg==2 ? azArg[1] : "main";
10251 sqlite3_vfs *pVfs = 0;
10252 if( p->db ){
10253 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
10254 if( pVfs ){
10255 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
10256 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
10257 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
10258 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
10259 }
10260 }
10261 }else
10262
10263 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
10264 sqlite3_vfs *pVfs;
10265 sqlite3_vfs *pCurrent = 0;
10266 if( p->db ){
10267 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
10268 }
10269 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
10270 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
10271 pVfs==pCurrent ? " <--- CURRENT" : "");
10272 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
10273 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
10274 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
10275 if( pVfs->pNext ){
10276 raw_printf(p->out, "-----------------------------------\n");
10277 }
10278 }
10279 }else
10280
10281 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
10282 const char *zDbName = nArg==2 ? azArg[1] : "main";
10283 char *zVfsName = 0;
10284 if( p->db ){
10285 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
10286 if( zVfsName ){
10287 utf8_printf(p->out, "%s\n", zVfsName);
10288 sqlite3_free(zVfsName);
10289 }
10290 }
10291 }else
10292
drh2ce15c32017-07-11 13:34:40 +000010293 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
drhc0622a42020-12-04 01:17:57 +000010294 unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
10295 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
drh2ce15c32017-07-11 13:34:40 +000010296 }else
drh2ce15c32017-07-11 13:34:40 +000010297
10298 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
10299 int j;
10300 assert( nArg<=ArraySize(azArg) );
drh0285d982020-05-29 14:38:43 +000010301 p->nWidth = nArg-1;
10302 p->colWidth = realloc(p->colWidth, p->nWidth*sizeof(int)*2);
10303 if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory();
10304 if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
10305 for(j=1; j<nArg; j++){
drh2ce15c32017-07-11 13:34:40 +000010306 p->colWidth[j-1] = (int)integerValue(azArg[j]);
10307 }
10308 }else
10309
10310 {
10311 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
10312 " \"%s\". Enter \".help\" for help\n", azArg[0]);
10313 rc = 1;
10314 }
10315
10316meta_command_exit:
10317 if( p->outCount ){
10318 p->outCount--;
10319 if( p->outCount==0 ) output_reset(p);
10320 }
10321 return rc;
10322}
10323
10324/*
10325** Return TRUE if a semicolon occurs anywhere in the first N characters
10326** of string z[].
10327*/
10328static int line_contains_semicolon(const char *z, int N){
10329 int i;
10330 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
10331 return 0;
10332}
10333
10334/*
10335** Test to see if a line consists entirely of whitespace.
10336*/
10337static int _all_whitespace(const char *z){
10338 for(; *z; z++){
10339 if( IsSpace(z[0]) ) continue;
10340 if( *z=='/' && z[1]=='*' ){
10341 z += 2;
10342 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
10343 if( *z==0 ) return 0;
10344 z++;
10345 continue;
10346 }
10347 if( *z=='-' && z[1]=='-' ){
10348 z += 2;
10349 while( *z && *z!='\n' ){ z++; }
10350 if( *z==0 ) return 1;
10351 continue;
10352 }
10353 return 0;
10354 }
10355 return 1;
10356}
10357
10358/*
10359** Return TRUE if the line typed in is an SQL command terminator other
10360** than a semi-colon. The SQL Server style "go" command is understood
10361** as is the Oracle "/".
10362*/
10363static int line_is_command_terminator(const char *zLine){
10364 while( IsSpace(zLine[0]) ){ zLine++; };
10365 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
10366 return 1; /* Oracle */
10367 }
10368 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
10369 && _all_whitespace(&zLine[2]) ){
10370 return 1; /* SQL Server */
10371 }
10372 return 0;
10373}
10374
10375/*
drh56f17742018-01-24 01:58:49 +000010376** We need a default sqlite3_complete() implementation to use in case
10377** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
10378** any arbitrary text is a complete SQL statement. This is not very
10379** user-friendly, but it does seem to work.
10380*/
10381#ifdef SQLITE_OMIT_COMPLETE
danc86b23b2018-11-16 14:36:42 +000010382#define sqlite3_complete(x) 1
drh56f17742018-01-24 01:58:49 +000010383#endif
10384
10385/*
drh2ce15c32017-07-11 13:34:40 +000010386** Return true if zSql is a complete SQL statement. Return false if it
10387** ends in the middle of a string literal or C-style comment.
10388*/
10389static int line_is_complete(char *zSql, int nSql){
10390 int rc;
10391 if( zSql==0 ) return 1;
10392 zSql[nSql] = ';';
10393 zSql[nSql+1] = 0;
10394 rc = sqlite3_complete(zSql);
10395 zSql[nSql] = 0;
10396 return rc;
10397}
10398
10399/*
drhfc29a862018-05-11 19:11:18 +000010400** Run a single line of SQL. Return the number of errors.
drh2ce15c32017-07-11 13:34:40 +000010401*/
10402static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
10403 int rc;
10404 char *zErrMsg = 0;
10405
10406 open_db(p, 0);
10407 if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
drhfc4eeef2019-02-05 19:48:46 +000010408 if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
drh2ce15c32017-07-11 13:34:40 +000010409 BEGIN_TIMER;
drha10b9992018-03-09 15:24:33 +000010410 rc = shell_exec(p, zSql, &zErrMsg);
drh2ce15c32017-07-11 13:34:40 +000010411 END_TIMER;
10412 if( rc || zErrMsg ){
10413 char zPrefix[100];
10414 if( in!=0 || !stdin_is_interactive ){
10415 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
10416 "Error: near line %d:", startline);
10417 }else{
10418 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
10419 }
10420 if( zErrMsg!=0 ){
10421 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
10422 sqlite3_free(zErrMsg);
10423 zErrMsg = 0;
10424 }else{
10425 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
10426 }
10427 return 1;
10428 }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
10429 raw_printf(p->out, "changes: %3d total_changes: %d\n",
10430 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
10431 }
10432 return 0;
10433}
10434
10435
10436/*
10437** Read input from *in and process it. If *in==0 then input
10438** is interactive - the user is typing it it. Otherwise, input
10439** is coming from a file or device. A prompt is issued and history
10440** is saved only if input is interactive. An interrupt signal will
10441** cause this routine to exit immediately, unless input is interactive.
10442**
10443** Return the number of errors.
10444*/
drh60379d42018-12-13 18:30:01 +000010445static int process_input(ShellState *p){
drh2ce15c32017-07-11 13:34:40 +000010446 char *zLine = 0; /* A single input line */
10447 char *zSql = 0; /* Accumulated SQL text */
10448 int nLine; /* Length of current line */
10449 int nSql = 0; /* Bytes of zSql[] used */
10450 int nAlloc = 0; /* Allocated zSql[] space */
10451 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
10452 int rc; /* Error code */
10453 int errCnt = 0; /* Number of errors seen */
drh2ce15c32017-07-11 13:34:40 +000010454 int startline = 0; /* Line number for start of current input */
10455
drh2c8ee022018-12-13 18:59:30 +000010456 p->lineno = 0;
drh60379d42018-12-13 18:30:01 +000010457 while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
drh2ce15c32017-07-11 13:34:40 +000010458 fflush(p->out);
drh60379d42018-12-13 18:30:01 +000010459 zLine = one_input_line(p->in, zLine, nSql>0);
drh2ce15c32017-07-11 13:34:40 +000010460 if( zLine==0 ){
10461 /* End of input */
drh60379d42018-12-13 18:30:01 +000010462 if( p->in==0 && stdin_is_interactive ) printf("\n");
drh2ce15c32017-07-11 13:34:40 +000010463 break;
10464 }
10465 if( seenInterrupt ){
drh60379d42018-12-13 18:30:01 +000010466 if( p->in!=0 ) break;
drh2ce15c32017-07-11 13:34:40 +000010467 seenInterrupt = 0;
10468 }
drh2c8ee022018-12-13 18:59:30 +000010469 p->lineno++;
drh2ce15c32017-07-11 13:34:40 +000010470 if( nSql==0 && _all_whitespace(zLine) ){
10471 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
10472 continue;
10473 }
drh1615c372018-05-12 23:56:22 +000010474 if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
drh2ce15c32017-07-11 13:34:40 +000010475 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
drh1615c372018-05-12 23:56:22 +000010476 if( zLine[0]=='.' ){
10477 rc = do_meta_command(zLine, p);
10478 if( rc==2 ){ /* exit requested */
10479 break;
10480 }else if( rc ){
10481 errCnt++;
10482 }
drh2ce15c32017-07-11 13:34:40 +000010483 }
10484 continue;
10485 }
10486 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
10487 memcpy(zLine,";",2);
10488 }
10489 nLine = strlen30(zLine);
10490 if( nSql+nLine+2>=nAlloc ){
10491 nAlloc = nSql+nLine+100;
10492 zSql = realloc(zSql, nAlloc);
drh4b5345c2018-04-24 13:07:40 +000010493 if( zSql==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +000010494 }
10495 nSqlPrior = nSql;
10496 if( nSql==0 ){
10497 int i;
10498 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
10499 assert( nAlloc>0 && zSql!=0 );
10500 memcpy(zSql, zLine+i, nLine+1-i);
drh2c8ee022018-12-13 18:59:30 +000010501 startline = p->lineno;
drh2ce15c32017-07-11 13:34:40 +000010502 nSql = nLine-i;
10503 }else{
10504 zSql[nSql++] = '\n';
10505 memcpy(zSql+nSql, zLine, nLine+1);
10506 nSql += nLine;
10507 }
10508 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
10509 && sqlite3_complete(zSql) ){
drh60379d42018-12-13 18:30:01 +000010510 errCnt += runOneSqlLine(p, zSql, p->in, startline);
drh2ce15c32017-07-11 13:34:40 +000010511 nSql = 0;
10512 if( p->outCount ){
10513 output_reset(p);
10514 p->outCount = 0;
drh13c20932018-01-10 21:41:55 +000010515 }else{
10516 clearTempFile(p);
drh2ce15c32017-07-11 13:34:40 +000010517 }
10518 }else if( nSql && _all_whitespace(zSql) ){
10519 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
10520 nSql = 0;
10521 }
10522 }
10523 if( nSql && !_all_whitespace(zSql) ){
drh60379d42018-12-13 18:30:01 +000010524 errCnt += runOneSqlLine(p, zSql, p->in, startline);
drh2ce15c32017-07-11 13:34:40 +000010525 }
10526 free(zSql);
10527 free(zLine);
10528 return errCnt>0;
10529}
10530
10531/*
10532** Return a pathname which is the user's home directory. A
10533** 0 return indicates an error of some kind.
10534*/
10535static char *find_home_dir(int clearFlag){
10536 static char *home_dir = NULL;
10537 if( clearFlag ){
10538 free(home_dir);
10539 home_dir = 0;
10540 return 0;
10541 }
10542 if( home_dir ) return home_dir;
10543
10544#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
10545 && !defined(__RTP__) && !defined(_WRS_KERNEL)
10546 {
10547 struct passwd *pwent;
10548 uid_t uid = getuid();
10549 if( (pwent=getpwuid(uid)) != NULL) {
10550 home_dir = pwent->pw_dir;
10551 }
10552 }
10553#endif
10554
10555#if defined(_WIN32_WCE)
10556 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
10557 */
10558 home_dir = "/";
10559#else
10560
10561#if defined(_WIN32) || defined(WIN32)
10562 if (!home_dir) {
10563 home_dir = getenv("USERPROFILE");
10564 }
10565#endif
10566
10567 if (!home_dir) {
10568 home_dir = getenv("HOME");
10569 }
10570
10571#if defined(_WIN32) || defined(WIN32)
10572 if (!home_dir) {
10573 char *zDrive, *zPath;
10574 int n;
10575 zDrive = getenv("HOMEDRIVE");
10576 zPath = getenv("HOMEPATH");
10577 if( zDrive && zPath ){
10578 n = strlen30(zDrive) + strlen30(zPath) + 1;
10579 home_dir = malloc( n );
10580 if( home_dir==0 ) return 0;
10581 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
10582 return home_dir;
10583 }
10584 home_dir = "c:\\";
10585 }
10586#endif
10587
10588#endif /* !_WIN32_WCE */
10589
10590 if( home_dir ){
10591 int n = strlen30(home_dir) + 1;
10592 char *z = malloc( n );
10593 if( z ) memcpy(z, home_dir, n);
10594 home_dir = z;
10595 }
10596
10597 return home_dir;
10598}
10599
10600/*
10601** Read input from the file given by sqliterc_override. Or if that
10602** parameter is NULL, take input from ~/.sqliterc
10603**
10604** Returns the number of errors.
10605*/
10606static void process_sqliterc(
10607 ShellState *p, /* Configuration data */
10608 const char *sqliterc_override /* Name of config file. NULL to use default */
10609){
10610 char *home_dir = NULL;
10611 const char *sqliterc = sqliterc_override;
10612 char *zBuf = 0;
drh60379d42018-12-13 18:30:01 +000010613 FILE *inSaved = p->in;
drh2c8ee022018-12-13 18:59:30 +000010614 int savedLineno = p->lineno;
drh2ce15c32017-07-11 13:34:40 +000010615
10616 if (sqliterc == NULL) {
10617 home_dir = find_home_dir(0);
10618 if( home_dir==0 ){
10619 raw_printf(stderr, "-- warning: cannot find home directory;"
10620 " cannot read ~/.sqliterc\n");
10621 return;
10622 }
drh2ce15c32017-07-11 13:34:40 +000010623 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
10624 sqliterc = zBuf;
10625 }
drh60379d42018-12-13 18:30:01 +000010626 p->in = fopen(sqliterc,"rb");
10627 if( p->in ){
drh2ce15c32017-07-11 13:34:40 +000010628 if( stdin_is_interactive ){
10629 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
10630 }
drhb7c46aa2020-11-25 13:59:47 +000010631 if( process_input(p) && bail_on_error ) exit(1);
drh60379d42018-12-13 18:30:01 +000010632 fclose(p->in);
drhb7c46aa2020-11-25 13:59:47 +000010633 }else if( sqliterc_override!=0 ){
10634 utf8_printf(stderr,"cannot open: \"%s\"\n", sqliterc);
10635 if( bail_on_error ) exit(1);
drh2ce15c32017-07-11 13:34:40 +000010636 }
drh60379d42018-12-13 18:30:01 +000010637 p->in = inSaved;
drh2c8ee022018-12-13 18:59:30 +000010638 p->lineno = savedLineno;
drh2ce15c32017-07-11 13:34:40 +000010639 sqlite3_free(zBuf);
10640}
10641
10642/*
10643** Show available command line options
10644*/
10645static const char zOptions[] =
drhda57d962018-03-05 19:34:05 +000010646#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
drhad7fd5d2018-03-05 20:21:50 +000010647 " -A ARGS... run \".archive ARGS\" and exit\n"
drhda57d962018-03-05 19:34:05 +000010648#endif
drh3baed312018-03-08 18:14:41 +000010649 " -append append the database to the end of the file\n"
drh2ce15c32017-07-11 13:34:40 +000010650 " -ascii set output mode to 'ascii'\n"
10651 " -bail stop after hitting an error\n"
10652 " -batch force batch I/O\n"
drh0908e382020-06-04 18:05:39 +000010653 " -box set output mode to 'box'\n"
drh2ce15c32017-07-11 13:34:40 +000010654 " -column set output mode to 'column'\n"
10655 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
10656 " -csv set output mode to 'csv'\n"
drh6ca64482019-01-22 16:06:20 +000010657#if defined(SQLITE_ENABLE_DESERIALIZE)
10658 " -deserialize open the database using sqlite3_deserialize()\n"
10659#endif
drh2ce15c32017-07-11 13:34:40 +000010660 " -echo print commands before execution\n"
10661 " -init FILENAME read/process named file\n"
10662 " -[no]header turn headers on or off\n"
10663#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
10664 " -heap SIZE Size of heap for memsys3 or memsys5\n"
10665#endif
10666 " -help show this message\n"
10667 " -html set output mode to HTML\n"
10668 " -interactive force interactive I/O\n"
drh30c54a02020-05-28 23:49:50 +000010669 " -json set output mode to 'json'\n"
drh2ce15c32017-07-11 13:34:40 +000010670 " -line set output mode to 'line'\n"
10671 " -list set output mode to 'list'\n"
10672 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh30c54a02020-05-28 23:49:50 +000010673 " -markdown set output mode to 'markdown'\n"
drh6ca64482019-01-22 16:06:20 +000010674#if defined(SQLITE_ENABLE_DESERIALIZE)
10675 " -maxsize N maximum size for a --deserialize database\n"
10676#endif
drhaf482572019-02-04 19:52:39 +000010677 " -memtrace trace all memory allocations and deallocations\n"
drh2ce15c32017-07-11 13:34:40 +000010678 " -mmap N default mmap size set to N\n"
10679#ifdef SQLITE_ENABLE_MULTIPLEX
10680 " -multiplex enable the multiplexor VFS\n"
10681#endif
10682 " -newline SEP set output row separator. Default: '\\n'\n"
drh0933aad2019-11-18 17:46:38 +000010683 " -nofollow refuse to open symbolic links to database files\n"
drh2ce15c32017-07-11 13:34:40 +000010684 " -nullvalue TEXT set text string for NULL values. Default ''\n"
10685 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
10686 " -quote set output mode to 'quote'\n"
drhee269a62018-02-14 23:27:43 +000010687 " -readonly open the database read-only\n"
drh2ce15c32017-07-11 13:34:40 +000010688 " -separator SEP set output column separator. Default: '|'\n"
drha90d84f2018-04-18 15:21:13 +000010689#ifdef SQLITE_ENABLE_SORTER_REFERENCES
10690 " -sorterref SIZE sorter references threshold size\n"
10691#endif
drh2ce15c32017-07-11 13:34:40 +000010692 " -stats print memory stats before each finalize\n"
drh30c54a02020-05-28 23:49:50 +000010693 " -table set output mode to 'table'\n"
drh2fa78182020-10-31 18:58:37 +000010694 " -tabs set output mode to 'tabs'\n"
drh2ce15c32017-07-11 13:34:40 +000010695 " -version show SQLite version\n"
10696 " -vfs NAME use NAME as the default VFS\n"
10697#ifdef SQLITE_ENABLE_VFSTRACE
10698 " -vfstrace enable tracing of all VFS calls\n"
10699#endif
drh3baed312018-03-08 18:14:41 +000010700#ifdef SQLITE_HAVE_ZLIB
10701 " -zip open the file as a ZIP Archive\n"
10702#endif
drh2ce15c32017-07-11 13:34:40 +000010703;
10704static void usage(int showDetail){
10705 utf8_printf(stderr,
10706 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
10707 "FILENAME is the name of an SQLite database. A new database is created\n"
10708 "if the file does not previously exist.\n", Argv0);
10709 if( showDetail ){
10710 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
10711 }else{
10712 raw_printf(stderr, "Use the -help option for additional information\n");
10713 }
10714 exit(1);
10715}
10716
10717/*
drhe7df8922018-04-18 10:44:58 +000010718** Internal check: Verify that the SQLite is uninitialized. Print a
10719** error message if it is initialized.
10720*/
10721static void verify_uninitialized(void){
10722 if( sqlite3_config(-1)==SQLITE_MISUSE ){
drh8e02a182018-05-30 07:24:41 +000010723 utf8_printf(stdout, "WARNING: attempt to configure SQLite after"
drhe7df8922018-04-18 10:44:58 +000010724 " initialization.\n");
10725 }
10726}
10727
10728/*
drh2ce15c32017-07-11 13:34:40 +000010729** Initialize the state information in data
10730*/
10731static void main_init(ShellState *data) {
10732 memset(data, 0, sizeof(*data));
10733 data->normalMode = data->cMode = data->mode = MODE_List;
10734 data->autoExplain = 1;
10735 memcpy(data->colSeparator,SEP_Column, 2);
10736 memcpy(data->rowSeparator,SEP_Row, 2);
10737 data->showHeader = 0;
10738 data->shellFlgs = SHFLG_Lookaside;
drhe7df8922018-04-18 10:44:58 +000010739 verify_uninitialized();
drh2ce15c32017-07-11 13:34:40 +000010740 sqlite3_config(SQLITE_CONFIG_URI, 1);
10741 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
10742 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
10743 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
10744 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
10745}
10746
10747/*
10748** Output text to the console in a font that attracts extra attention.
10749*/
10750#ifdef _WIN32
10751static void printBold(const char *zText){
mistachkin43e86272020-04-09 15:31:22 +000010752#if !SQLITE_OS_WINRT
drh2ce15c32017-07-11 13:34:40 +000010753 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
10754 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
10755 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
10756 SetConsoleTextAttribute(out,
10757 FOREGROUND_RED|FOREGROUND_INTENSITY
10758 );
mistachkin43e86272020-04-09 15:31:22 +000010759#endif
drh2ce15c32017-07-11 13:34:40 +000010760 printf("%s", zText);
mistachkin43e86272020-04-09 15:31:22 +000010761#if !SQLITE_OS_WINRT
drh2ce15c32017-07-11 13:34:40 +000010762 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
mistachkin43e86272020-04-09 15:31:22 +000010763#endif
drh2ce15c32017-07-11 13:34:40 +000010764}
10765#else
10766static void printBold(const char *zText){
10767 printf("\033[1m%s\033[0m", zText);
10768}
10769#endif
10770
10771/*
10772** Get the argument to an --option. Throw an error and die if no argument
10773** is available.
10774*/
10775static char *cmdline_option_value(int argc, char **argv, int i){
10776 if( i==argc ){
10777 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
10778 argv[0], argv[argc-1]);
10779 exit(1);
10780 }
10781 return argv[i];
10782}
10783
10784#ifndef SQLITE_SHELL_IS_UTF8
10785# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
10786# define SQLITE_SHELL_IS_UTF8 (0)
10787# else
10788# define SQLITE_SHELL_IS_UTF8 (1)
10789# endif
10790#endif
10791
10792#if SQLITE_SHELL_IS_UTF8
10793int SQLITE_CDECL main(int argc, char **argv){
10794#else
10795int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
10796 char **argv;
10797#endif
10798 char *zErrMsg = 0;
10799 ShellState data;
10800 const char *zInitFile = 0;
10801 int i;
10802 int rc = 0;
10803 int warnInmemoryDb = 0;
10804 int readStdin = 1;
10805 int nCmd = 0;
10806 char **azCmd = 0;
dan16a47422018-04-18 09:16:11 +000010807 const char *zVfs = 0; /* Value of -vfs command-line option */
drh1f22f622018-05-17 13:29:14 +000010808#if !SQLITE_SHELL_IS_UTF8
10809 char **argvToFree = 0;
10810 int argcToFree = 0;
10811#endif
drh2ce15c32017-07-11 13:34:40 +000010812
10813 setBinaryMode(stdin, 0);
10814 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
10815 stdin_is_interactive = isatty(0);
10816 stdout_is_console = isatty(1);
10817
drh4a3a3eb2020-02-29 15:53:48 +000010818#ifdef SQLITE_DEBUG
10819 registerOomSimulator();
10820#endif
10821
mistachkin1e8487d2018-07-22 06:25:35 +000010822#if !defined(_WIN32_WCE)
10823 if( getenv("SQLITE_DEBUG_BREAK") ){
10824 if( isatty(0) && isatty(2) ){
10825 fprintf(stderr,
10826 "attach debugger to process %d and press any key to continue.\n",
10827 GETPID());
10828 fgetc(stdin);
10829 }else{
10830#if defined(_WIN32) || defined(WIN32)
mistachkin43e86272020-04-09 15:31:22 +000010831#if SQLITE_OS_WINRT
10832 __debugbreak();
10833#else
mistachkin1e8487d2018-07-22 06:25:35 +000010834 DebugBreak();
mistachkin43e86272020-04-09 15:31:22 +000010835#endif
mistachkin1e8487d2018-07-22 06:25:35 +000010836#elif defined(SIGTRAP)
10837 raise(SIGTRAP);
10838#endif
10839 }
10840 }
10841#endif
10842
drh2ce15c32017-07-11 13:34:40 +000010843#if USE_SYSTEM_SQLITE+0!=1
drhb3c45232017-08-28 14:33:27 +000010844 if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
drh2ce15c32017-07-11 13:34:40 +000010845 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
10846 sqlite3_sourceid(), SQLITE_SOURCE_ID);
10847 exit(1);
10848 }
10849#endif
10850 main_init(&data);
drh501ea052018-02-15 01:03:37 +000010851
10852 /* On Windows, we must translate command-line arguments into UTF-8.
10853 ** The SQLite memory allocator subsystem has to be enabled in order to
10854 ** do this. But we want to run an sqlite3_shutdown() afterwards so that
10855 ** subsequent sqlite3_config() calls will work. So copy all results into
10856 ** memory that does not come from the SQLite memory allocator.
10857 */
drh4b18c1d2018-02-04 20:33:13 +000010858#if !SQLITE_SHELL_IS_UTF8
drh501ea052018-02-15 01:03:37 +000010859 sqlite3_initialize();
drh1f22f622018-05-17 13:29:14 +000010860 argvToFree = malloc(sizeof(argv[0])*argc*2);
10861 argcToFree = argc;
10862 argv = argvToFree + argc;
drh4b5345c2018-04-24 13:07:40 +000010863 if( argv==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +000010864 for(i=0; i<argc; i++){
drh501ea052018-02-15 01:03:37 +000010865 char *z = sqlite3_win32_unicode_to_utf8(wargv[i]);
10866 int n;
drh4b5345c2018-04-24 13:07:40 +000010867 if( z==0 ) shell_out_of_memory();
drh501ea052018-02-15 01:03:37 +000010868 n = (int)strlen(z);
10869 argv[i] = malloc( n+1 );
drh4b5345c2018-04-24 13:07:40 +000010870 if( argv[i]==0 ) shell_out_of_memory();
drh501ea052018-02-15 01:03:37 +000010871 memcpy(argv[i], z, n+1);
drh1f22f622018-05-17 13:29:14 +000010872 argvToFree[i] = argv[i];
drh501ea052018-02-15 01:03:37 +000010873 sqlite3_free(z);
drh2ce15c32017-07-11 13:34:40 +000010874 }
drh501ea052018-02-15 01:03:37 +000010875 sqlite3_shutdown();
drh2ce15c32017-07-11 13:34:40 +000010876#endif
drh501ea052018-02-15 01:03:37 +000010877
drh2ce15c32017-07-11 13:34:40 +000010878 assert( argc>=1 && argv && argv[0] );
10879 Argv0 = argv[0];
10880
10881 /* Make sure we have a valid signal handler early, before anything
10882 ** else is done.
10883 */
10884#ifdef SIGINT
10885 signal(SIGINT, interrupt_handler);
mistachkinb4bab902017-10-27 17:09:44 +000010886#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
10887 SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
drh2ce15c32017-07-11 13:34:40 +000010888#endif
10889
10890#ifdef SQLITE_SHELL_DBNAME_PROC
10891 {
10892 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
10893 ** of a C-function that will provide the name of the database file. Use
10894 ** this compile-time option to embed this shell program in larger
10895 ** applications. */
10896 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
10897 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
10898 warnInmemoryDb = 0;
10899 }
10900#endif
10901
10902 /* Do an initial pass through the command-line argument to locate
10903 ** the name of the database file, the name of the initialization file,
10904 ** the size of the alternative malloc heap,
10905 ** and the first command to execute.
10906 */
drhe7df8922018-04-18 10:44:58 +000010907 verify_uninitialized();
drh2ce15c32017-07-11 13:34:40 +000010908 for(i=1; i<argc; i++){
10909 char *z;
10910 z = argv[i];
10911 if( z[0]!='-' ){
10912 if( data.zDbFilename==0 ){
10913 data.zDbFilename = z;
10914 }else{
10915 /* Excesss arguments are interpreted as SQL (or dot-commands) and
10916 ** mean that nothing is read from stdin */
10917 readStdin = 0;
10918 nCmd++;
10919 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
drh4b5345c2018-04-24 13:07:40 +000010920 if( azCmd==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +000010921 azCmd[nCmd-1] = z;
10922 }
10923 }
10924 if( z[1]=='-' ) z++;
10925 if( strcmp(z,"-separator")==0
10926 || strcmp(z,"-nullvalue")==0
10927 || strcmp(z,"-newline")==0
10928 || strcmp(z,"-cmd")==0
10929 ){
10930 (void)cmdline_option_value(argc, argv, ++i);
10931 }else if( strcmp(z,"-init")==0 ){
10932 zInitFile = cmdline_option_value(argc, argv, ++i);
10933 }else if( strcmp(z,"-batch")==0 ){
10934 /* Need to check for batch mode here to so we can avoid printing
10935 ** informational messages (like from process_sqliterc) before
10936 ** we do the actual processing of arguments later in a second pass.
10937 */
10938 stdin_is_interactive = 0;
10939 }else if( strcmp(z,"-heap")==0 ){
10940#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
10941 const char *zSize;
10942 sqlite3_int64 szHeap;
10943
10944 zSize = cmdline_option_value(argc, argv, ++i);
10945 szHeap = integerValue(zSize);
10946 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
10947 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
10948#else
10949 (void)cmdline_option_value(argc, argv, ++i);
10950#endif
drh2ce15c32017-07-11 13:34:40 +000010951 }else if( strcmp(z,"-pagecache")==0 ){
drhf573b4f2020-09-28 13:34:05 +000010952 sqlite3_int64 n, sz;
10953 sz = integerValue(cmdline_option_value(argc,argv,++i));
drh2ce15c32017-07-11 13:34:40 +000010954 if( sz>70000 ) sz = 70000;
10955 if( sz<0 ) sz = 0;
drhf573b4f2020-09-28 13:34:05 +000010956 n = integerValue(cmdline_option_value(argc,argv,++i));
10957 if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){
10958 n = 0xffffffffffffLL/sz;
10959 }
drh2ce15c32017-07-11 13:34:40 +000010960 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
10961 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
10962 data.shellFlgs |= SHFLG_Pagecache;
10963 }else if( strcmp(z,"-lookaside")==0 ){
10964 int n, sz;
10965 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
10966 if( sz<0 ) sz = 0;
10967 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
10968 if( n<0 ) n = 0;
10969 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
10970 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
10971#ifdef SQLITE_ENABLE_VFSTRACE
10972 }else if( strcmp(z,"-vfstrace")==0 ){
10973 extern int vfstrace_register(
10974 const char *zTraceName,
10975 const char *zOldVfsName,
10976 int (*xOut)(const char*,void*),
10977 void *pOutArg,
10978 int makeDefault
10979 );
10980 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
10981#endif
10982#ifdef SQLITE_ENABLE_MULTIPLEX
10983 }else if( strcmp(z,"-multiplex")==0 ){
10984 extern int sqlite3_multiple_initialize(const char*,int);
10985 sqlite3_multiplex_initialize(0, 1);
10986#endif
10987 }else if( strcmp(z,"-mmap")==0 ){
10988 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
10989 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drha90d84f2018-04-18 15:21:13 +000010990#ifdef SQLITE_ENABLE_SORTER_REFERENCES
10991 }else if( strcmp(z,"-sorterref")==0 ){
10992 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
10993 sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz);
10994#endif
drh2ce15c32017-07-11 13:34:40 +000010995 }else if( strcmp(z,"-vfs")==0 ){
dan16a47422018-04-18 09:16:11 +000010996 zVfs = cmdline_option_value(argc, argv, ++i);
drh3baed312018-03-08 18:14:41 +000010997#ifdef SQLITE_HAVE_ZLIB
drh8682e122018-01-07 20:38:10 +000010998 }else if( strcmp(z,"-zip")==0 ){
10999 data.openMode = SHELL_OPEN_ZIPFILE;
11000#endif
11001 }else if( strcmp(z,"-append")==0 ){
11002 data.openMode = SHELL_OPEN_APPENDVFS;
drha751f392018-10-30 15:31:22 +000011003#ifdef SQLITE_ENABLE_DESERIALIZE
drh60f34ae2018-10-30 13:19:49 +000011004 }else if( strcmp(z,"-deserialize")==0 ){
11005 data.openMode = SHELL_OPEN_DESERIALIZE;
drh6ca64482019-01-22 16:06:20 +000011006 }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
11007 data.szMax = integerValue(argv[++i]);
drha751f392018-10-30 15:31:22 +000011008#endif
drhee269a62018-02-14 23:27:43 +000011009 }else if( strcmp(z,"-readonly")==0 ){
11010 data.openMode = SHELL_OPEN_READONLY;
drh0933aad2019-11-18 17:46:38 +000011011 }else if( strcmp(z,"-nofollow")==0 ){
11012 data.openFlags = SQLITE_OPEN_NOFOLLOW;
drhda57d962018-03-05 19:34:05 +000011013#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
drh93b77312018-03-05 20:20:22 +000011014 }else if( strncmp(z, "-A",2)==0 ){
drhda57d962018-03-05 19:34:05 +000011015 /* All remaining command-line arguments are passed to the ".archive"
11016 ** command, so ignore them */
11017 break;
11018#endif
drh50b910a2019-01-21 14:55:03 +000011019 }else if( strcmp(z, "-memtrace")==0 ){
11020 sqlite3MemTraceActivate(stderr);
drhb7c46aa2020-11-25 13:59:47 +000011021 }else if( strcmp(z,"-bail")==0 ){
11022 bail_on_error = 1;
drh2ce15c32017-07-11 13:34:40 +000011023 }
11024 }
drhe7df8922018-04-18 10:44:58 +000011025 verify_uninitialized();
11026
dan16a47422018-04-18 09:16:11 +000011027
drhd11b8f62018-04-25 13:27:07 +000011028#ifdef SQLITE_SHELL_INIT_PROC
11029 {
11030 /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name
11031 ** of a C-function that will perform initialization actions on SQLite that
11032 ** occur just before or after sqlite3_initialize(). Use this compile-time
11033 ** option to embed this shell program in larger applications. */
11034 extern void SQLITE_SHELL_INIT_PROC(void);
11035 SQLITE_SHELL_INIT_PROC();
11036 }
11037#else
dan16a47422018-04-18 09:16:11 +000011038 /* All the sqlite3_config() calls have now been made. So it is safe
11039 ** to call sqlite3_initialize() and process any command line -vfs option. */
11040 sqlite3_initialize();
drhd11b8f62018-04-25 13:27:07 +000011041#endif
11042
dan16a47422018-04-18 09:16:11 +000011043 if( zVfs ){
11044 sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
11045 if( pVfs ){
11046 sqlite3_vfs_register(pVfs, 1);
11047 }else{
11048 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
11049 exit(1);
11050 }
11051 }
11052
drh2ce15c32017-07-11 13:34:40 +000011053 if( data.zDbFilename==0 ){
11054#ifndef SQLITE_OMIT_MEMORYDB
11055 data.zDbFilename = ":memory:";
11056 warnInmemoryDb = argc==1;
11057#else
11058 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
11059 return 1;
11060#endif
11061 }
11062 data.out = stdout;
drh8682e122018-01-07 20:38:10 +000011063 sqlite3_appendvfs_init(0,0,0);
drh2ce15c32017-07-11 13:34:40 +000011064
11065 /* Go ahead and open the database file if it already exists. If the
11066 ** file does not exist, delay opening it. This prevents empty database
11067 ** files from being created if a user mistypes the database name argument
11068 ** to the sqlite command-line tool.
11069 */
11070 if( access(data.zDbFilename, 0)==0 ){
11071 open_db(&data, 0);
11072 }
11073
11074 /* Process the initialization file if there is one. If no -init option
11075 ** is given on the command line, look for a file named ~/.sqliterc and
11076 ** try to process it.
11077 */
11078 process_sqliterc(&data,zInitFile);
11079
11080 /* Make a second pass through the command-line argument and set
11081 ** options. This second pass is delayed until after the initialization
11082 ** file is processed so that the command-line arguments will override
11083 ** settings in the initialization file.
11084 */
11085 for(i=1; i<argc; i++){
11086 char *z = argv[i];
11087 if( z[0]!='-' ) continue;
11088 if( z[1]=='-' ){ z++; }
11089 if( strcmp(z,"-init")==0 ){
11090 i++;
11091 }else if( strcmp(z,"-html")==0 ){
11092 data.mode = MODE_Html;
11093 }else if( strcmp(z,"-list")==0 ){
11094 data.mode = MODE_List;
11095 }else if( strcmp(z,"-quote")==0 ){
11096 data.mode = MODE_Quote;
drh9191c702020-08-17 09:11:21 +000011097 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Comma);
11098 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
drh2ce15c32017-07-11 13:34:40 +000011099 }else if( strcmp(z,"-line")==0 ){
11100 data.mode = MODE_Line;
11101 }else if( strcmp(z,"-column")==0 ){
11102 data.mode = MODE_Column;
drh30c54a02020-05-28 23:49:50 +000011103 }else if( strcmp(z,"-json")==0 ){
11104 data.mode = MODE_Json;
11105 }else if( strcmp(z,"-markdown")==0 ){
11106 data.mode = MODE_Markdown;
11107 }else if( strcmp(z,"-table")==0 ){
11108 data.mode = MODE_Table;
drh0908e382020-06-04 18:05:39 +000011109 }else if( strcmp(z,"-box")==0 ){
11110 data.mode = MODE_Box;
drh2ce15c32017-07-11 13:34:40 +000011111 }else if( strcmp(z,"-csv")==0 ){
11112 data.mode = MODE_Csv;
11113 memcpy(data.colSeparator,",",2);
drh3baed312018-03-08 18:14:41 +000011114#ifdef SQLITE_HAVE_ZLIB
drh1fa6d9f2018-01-06 21:46:01 +000011115 }else if( strcmp(z,"-zip")==0 ){
11116 data.openMode = SHELL_OPEN_ZIPFILE;
11117#endif
11118 }else if( strcmp(z,"-append")==0 ){
11119 data.openMode = SHELL_OPEN_APPENDVFS;
drha751f392018-10-30 15:31:22 +000011120#ifdef SQLITE_ENABLE_DESERIALIZE
drh60f34ae2018-10-30 13:19:49 +000011121 }else if( strcmp(z,"-deserialize")==0 ){
11122 data.openMode = SHELL_OPEN_DESERIALIZE;
drh6ca64482019-01-22 16:06:20 +000011123 }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
11124 data.szMax = integerValue(argv[++i]);
drha751f392018-10-30 15:31:22 +000011125#endif
drh4aafe592018-03-23 16:08:30 +000011126 }else if( strcmp(z,"-readonly")==0 ){
11127 data.openMode = SHELL_OPEN_READONLY;
drh0933aad2019-11-18 17:46:38 +000011128 }else if( strcmp(z,"-nofollow")==0 ){
11129 data.openFlags |= SQLITE_OPEN_NOFOLLOW;
drh2ce15c32017-07-11 13:34:40 +000011130 }else if( strcmp(z,"-ascii")==0 ){
11131 data.mode = MODE_Ascii;
drh2fa78182020-10-31 18:58:37 +000011132 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Unit);
11133 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Record);
11134 }else if( strcmp(z,"-tabs")==0 ){
11135 data.mode = MODE_List;
11136 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Tab);
11137 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
drh2ce15c32017-07-11 13:34:40 +000011138 }else if( strcmp(z,"-separator")==0 ){
11139 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
11140 "%s",cmdline_option_value(argc,argv,++i));
11141 }else if( strcmp(z,"-newline")==0 ){
11142 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
11143 "%s",cmdline_option_value(argc,argv,++i));
11144 }else if( strcmp(z,"-nullvalue")==0 ){
11145 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
11146 "%s",cmdline_option_value(argc,argv,++i));
11147 }else if( strcmp(z,"-header")==0 ){
11148 data.showHeader = 1;
11149 }else if( strcmp(z,"-noheader")==0 ){
11150 data.showHeader = 0;
11151 }else if( strcmp(z,"-echo")==0 ){
11152 ShellSetFlag(&data, SHFLG_Echo);
11153 }else if( strcmp(z,"-eqp")==0 ){
drhada70452017-12-21 21:02:27 +000011154 data.autoEQP = AUTOEQP_on;
drh2ce15c32017-07-11 13:34:40 +000011155 }else if( strcmp(z,"-eqpfull")==0 ){
drhada70452017-12-21 21:02:27 +000011156 data.autoEQP = AUTOEQP_full;
drh2ce15c32017-07-11 13:34:40 +000011157 }else if( strcmp(z,"-stats")==0 ){
11158 data.statsOn = 1;
11159 }else if( strcmp(z,"-scanstats")==0 ){
11160 data.scanstatsOn = 1;
11161 }else if( strcmp(z,"-backslash")==0 ){
11162 /* Undocumented command-line option: -backslash
11163 ** Causes C-style backslash escapes to be evaluated in SQL statements
11164 ** prior to sending the SQL into SQLite. Useful for injecting
11165 ** crazy bytes in the middle of SQL statements for testing and debugging.
11166 */
11167 ShellSetFlag(&data, SHFLG_Backslash);
11168 }else if( strcmp(z,"-bail")==0 ){
drhb7c46aa2020-11-25 13:59:47 +000011169 /* No-op. The bail_on_error flag should already be set. */
drh2ce15c32017-07-11 13:34:40 +000011170 }else if( strcmp(z,"-version")==0 ){
11171 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
11172 return 0;
11173 }else if( strcmp(z,"-interactive")==0 ){
11174 stdin_is_interactive = 1;
11175 }else if( strcmp(z,"-batch")==0 ){
11176 stdin_is_interactive = 0;
11177 }else if( strcmp(z,"-heap")==0 ){
11178 i++;
drh2ce15c32017-07-11 13:34:40 +000011179 }else if( strcmp(z,"-pagecache")==0 ){
11180 i+=2;
11181 }else if( strcmp(z,"-lookaside")==0 ){
11182 i+=2;
11183 }else if( strcmp(z,"-mmap")==0 ){
11184 i++;
drh50b910a2019-01-21 14:55:03 +000011185 }else if( strcmp(z,"-memtrace")==0 ){
11186 i++;
drha90d84f2018-04-18 15:21:13 +000011187#ifdef SQLITE_ENABLE_SORTER_REFERENCES
11188 }else if( strcmp(z,"-sorterref")==0 ){
11189 i++;
11190#endif
drh2ce15c32017-07-11 13:34:40 +000011191 }else if( strcmp(z,"-vfs")==0 ){
11192 i++;
11193#ifdef SQLITE_ENABLE_VFSTRACE
11194 }else if( strcmp(z,"-vfstrace")==0 ){
11195 i++;
11196#endif
11197#ifdef SQLITE_ENABLE_MULTIPLEX
11198 }else if( strcmp(z,"-multiplex")==0 ){
11199 i++;
11200#endif
11201 }else if( strcmp(z,"-help")==0 ){
11202 usage(1);
11203 }else if( strcmp(z,"-cmd")==0 ){
11204 /* Run commands that follow -cmd first and separately from commands
11205 ** that simply appear on the command-line. This seems goofy. It would
11206 ** be better if all commands ran in the order that they appear. But
11207 ** we retain the goofy behavior for historical compatibility. */
11208 if( i==argc-1 ) break;
11209 z = cmdline_option_value(argc,argv,++i);
11210 if( z[0]=='.' ){
11211 rc = do_meta_command(z, &data);
11212 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
11213 }else{
11214 open_db(&data, 0);
drha10b9992018-03-09 15:24:33 +000011215 rc = shell_exec(&data, z, &zErrMsg);
drh2ce15c32017-07-11 13:34:40 +000011216 if( zErrMsg!=0 ){
11217 utf8_printf(stderr,"Error: %s\n", zErrMsg);
11218 if( bail_on_error ) return rc!=0 ? rc : 1;
11219 }else if( rc!=0 ){
11220 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
11221 if( bail_on_error ) return rc;
11222 }
11223 }
drhda57d962018-03-05 19:34:05 +000011224#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
drh93b77312018-03-05 20:20:22 +000011225 }else if( strncmp(z, "-A", 2)==0 ){
drhda57d962018-03-05 19:34:05 +000011226 if( nCmd>0 ){
11227 utf8_printf(stderr, "Error: cannot mix regular SQL or dot-commands"
11228 " with \"%s\"\n", z);
11229 return 1;
11230 }
drhbe4ccb22018-05-17 20:04:24 +000011231 open_db(&data, OPEN_DB_ZIPFILE);
drh93b77312018-03-05 20:20:22 +000011232 if( z[2] ){
11233 argv[i] = &z[2];
drhd0f9cdc2018-05-17 14:09:06 +000011234 arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
drh93b77312018-03-05 20:20:22 +000011235 }else{
drhd0f9cdc2018-05-17 14:09:06 +000011236 arDotCommand(&data, 1, argv+i, argc-i);
drh93b77312018-03-05 20:20:22 +000011237 }
drhda57d962018-03-05 19:34:05 +000011238 readStdin = 0;
11239 break;
11240#endif
drh2ce15c32017-07-11 13:34:40 +000011241 }else{
11242 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
11243 raw_printf(stderr,"Use -help for a list of options.\n");
11244 return 1;
11245 }
11246 data.cMode = data.mode;
11247 }
11248
11249 if( !readStdin ){
11250 /* Run all arguments that do not begin with '-' as if they were separate
11251 ** command-line inputs, except for the argToSkip argument which contains
11252 ** the database filename.
11253 */
11254 for(i=0; i<nCmd; i++){
11255 if( azCmd[i][0]=='.' ){
11256 rc = do_meta_command(azCmd[i], &data);
danaff1a572020-11-17 21:09:56 +000011257 if( rc ){
11258 free(azCmd);
11259 return rc==2 ? 0 : rc;
11260 }
drh2ce15c32017-07-11 13:34:40 +000011261 }else{
11262 open_db(&data, 0);
drha10b9992018-03-09 15:24:33 +000011263 rc = shell_exec(&data, azCmd[i], &zErrMsg);
danaff1a572020-11-17 21:09:56 +000011264 if( zErrMsg || rc ){
11265 if( zErrMsg!=0 ){
11266 utf8_printf(stderr,"Error: %s\n", zErrMsg);
11267 }else{
11268 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
11269 }
11270 sqlite3_free(zErrMsg);
11271 free(azCmd);
drh2ce15c32017-07-11 13:34:40 +000011272 return rc!=0 ? rc : 1;
drh2ce15c32017-07-11 13:34:40 +000011273 }
11274 }
11275 }
drh2ce15c32017-07-11 13:34:40 +000011276 }else{
11277 /* Run commands received from standard input
11278 */
11279 if( stdin_is_interactive ){
11280 char *zHome;
drha9e4be32018-10-10 18:56:40 +000011281 char *zHistory;
drh2ce15c32017-07-11 13:34:40 +000011282 int nHistory;
11283 printf(
11284 "SQLite version %s %.19s\n" /*extra-version-info*/
11285 "Enter \".help\" for usage hints.\n",
11286 sqlite3_libversion(), sqlite3_sourceid()
11287 );
11288 if( warnInmemoryDb ){
11289 printf("Connected to a ");
11290 printBold("transient in-memory database");
11291 printf(".\nUse \".open FILENAME\" to reopen on a "
11292 "persistent database.\n");
11293 }
drha9e4be32018-10-10 18:56:40 +000011294 zHistory = getenv("SQLITE_HISTORY");
11295 if( zHistory ){
11296 zHistory = strdup(zHistory);
11297 }else if( (zHome = find_home_dir(0))!=0 ){
drh2ce15c32017-07-11 13:34:40 +000011298 nHistory = strlen30(zHome) + 20;
11299 if( (zHistory = malloc(nHistory))!=0 ){
11300 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
11301 }
11302 }
11303 if( zHistory ){ shell_read_history(zHistory); }
drh56eb09b2017-07-11 13:59:07 +000011304#if HAVE_READLINE || HAVE_EDITLINE
11305 rl_attempted_completion_function = readline_completion;
11306#elif HAVE_LINENOISE
11307 linenoiseSetCompletionCallback(linenoise_completion);
11308#endif
drh60379d42018-12-13 18:30:01 +000011309 data.in = 0;
11310 rc = process_input(&data);
drh2ce15c32017-07-11 13:34:40 +000011311 if( zHistory ){
drh5a75dd82017-07-18 20:59:40 +000011312 shell_stifle_history(2000);
drh2ce15c32017-07-11 13:34:40 +000011313 shell_write_history(zHistory);
11314 free(zHistory);
11315 }
11316 }else{
drh60379d42018-12-13 18:30:01 +000011317 data.in = stdin;
11318 rc = process_input(&data);
drh2ce15c32017-07-11 13:34:40 +000011319 }
11320 }
danaff1a572020-11-17 21:09:56 +000011321 free(azCmd);
drh2ce15c32017-07-11 13:34:40 +000011322 set_table_name(&data, 0);
11323 if( data.db ){
11324 session_close_all(&data);
drh9e804032018-05-18 17:11:50 +000011325 close_db(data.db);
drh2ce15c32017-07-11 13:34:40 +000011326 }
11327 sqlite3_free(data.zFreeOnClose);
11328 find_home_dir(1);
drh536c3452018-01-11 00:38:39 +000011329 output_reset(&data);
11330 data.doXdgOpen = 0;
drh13c20932018-01-10 21:41:55 +000011331 clearTempFile(&data);
drh2ce15c32017-07-11 13:34:40 +000011332#if !SQLITE_SHELL_IS_UTF8
drh1f22f622018-05-17 13:29:14 +000011333 for(i=0; i<argcToFree; i++) free(argvToFree[i]);
11334 free(argvToFree);
drh2ce15c32017-07-11 13:34:40 +000011335#endif
drh0285d982020-05-29 14:38:43 +000011336 free(data.colWidth);
drh9e804032018-05-18 17:11:50 +000011337 /* Clear the global data structure so that valgrind will detect memory
11338 ** leaks */
11339 memset(&data, 0, sizeof(data));
drh2ce15c32017-07-11 13:34:40 +000011340 return rc;
11341}