blob: 0a827335c3af537ec89895f49d67d718e1fac011 [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 */
drh2ce15c32017-07-11 13:34:40 +00001187
1188/*
1189** Macros for testing and setting shellFlgs
1190*/
1191#define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0)
1192#define ShellSetFlag(P,X) ((P)->shellFlgs|=(X))
1193#define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X)))
1194
1195/*
1196** These are the allowed modes.
1197*/
1198#define MODE_Line 0 /* One column per line. Blank line between records */
1199#define MODE_Column 1 /* One record per line in neat columns */
1200#define MODE_List 2 /* One record per line with a separator */
1201#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
1202#define MODE_Html 4 /* Generate an XHTML table */
1203#define MODE_Insert 5 /* Generate SQL "insert" statements */
1204#define MODE_Quote 6 /* Quote values as for SQL */
1205#define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */
1206#define MODE_Csv 8 /* Quote strings, numbers are plain */
1207#define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */
1208#define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */
1209#define MODE_Pretty 11 /* Pretty-print schemas */
drh4b5345c2018-04-24 13:07:40 +00001210#define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
drh30c54a02020-05-28 23:49:50 +00001211#define MODE_Json 13 /* Output JSON */
1212#define MODE_Markdown 14 /* Markdown formatting */
1213#define MODE_Table 15 /* MySQL-style table formatting */
drh0908e382020-06-04 18:05:39 +00001214#define MODE_Box 16 /* Unicode box-drawing characters */
drh2ce15c32017-07-11 13:34:40 +00001215
1216static const char *modeDescr[] = {
1217 "line",
1218 "column",
1219 "list",
1220 "semi",
1221 "html",
1222 "insert",
1223 "quote",
1224 "tcl",
1225 "csv",
1226 "explain",
1227 "ascii",
1228 "prettyprint",
drh30c54a02020-05-28 23:49:50 +00001229 "eqp",
1230 "json",
1231 "markdown",
drh0908e382020-06-04 18:05:39 +00001232 "table",
1233 "box"
drh2ce15c32017-07-11 13:34:40 +00001234};
1235
1236/*
1237** These are the column/row/line separators used by the various
1238** import/export modes.
1239*/
1240#define SEP_Column "|"
1241#define SEP_Row "\n"
1242#define SEP_Tab "\t"
1243#define SEP_Space " "
1244#define SEP_Comma ","
1245#define SEP_CrLf "\r\n"
1246#define SEP_Unit "\x1F"
1247#define SEP_Record "\x1E"
1248
1249/*
drh2ce15c32017-07-11 13:34:40 +00001250** A callback for the sqlite3_log() interface.
1251*/
1252static void shellLog(void *pArg, int iErrCode, const char *zMsg){
1253 ShellState *p = (ShellState*)pArg;
1254 if( p->pLog==0 ) return;
1255 utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
1256 fflush(p->pLog);
1257}
1258
1259/*
drh634c70f2018-01-10 16:50:18 +00001260** SQL function: shell_putsnl(X)
1261**
1262** Write the text X to the screen (or whatever output is being directed)
1263** adding a newline at the end, and then return X.
1264*/
1265static void shellPutsFunc(
1266 sqlite3_context *pCtx,
1267 int nVal,
1268 sqlite3_value **apVal
1269){
1270 ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
drhb9685182018-01-17 13:15:23 +00001271 (void)nVal;
drh634c70f2018-01-10 16:50:18 +00001272 utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
1273 sqlite3_result_value(pCtx, apVal[0]);
1274}
1275
1276/*
drh97913132018-01-11 00:04:00 +00001277** SQL function: edit(VALUE)
1278** edit(VALUE,EDITOR)
1279**
1280** These steps:
1281**
1282** (1) Write VALUE into a temporary file.
1283** (2) Run program EDITOR on that temporary file.
1284** (3) Read the temporary file back and return its content as the result.
1285** (4) Delete the temporary file
1286**
1287** If the EDITOR argument is omitted, use the value in the VISUAL
1288** environment variable. If still there is no EDITOR, through an error.
1289**
1290** Also throw an error if the EDITOR program returns a non-zero exit code.
1291*/
drh04a28c32018-01-31 01:38:44 +00001292#ifndef SQLITE_NOHAVE_SYSTEM
drh97913132018-01-11 00:04:00 +00001293static void editFunc(
1294 sqlite3_context *context,
1295 int argc,
1296 sqlite3_value **argv
1297){
1298 const char *zEditor;
1299 char *zTempFile = 0;
1300 sqlite3 *db;
1301 char *zCmd = 0;
1302 int bBin;
1303 int rc;
drhf018fd52018-08-06 02:08:53 +00001304 int hasCRNL = 0;
drh97913132018-01-11 00:04:00 +00001305 FILE *f = 0;
1306 sqlite3_int64 sz;
1307 sqlite3_int64 x;
1308 unsigned char *p = 0;
1309
1310 if( argc==2 ){
1311 zEditor = (const char*)sqlite3_value_text(argv[1]);
1312 }else{
1313 zEditor = getenv("VISUAL");
1314 }
1315 if( zEditor==0 ){
1316 sqlite3_result_error(context, "no editor for edit()", -1);
1317 return;
1318 }
1319 if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
1320 sqlite3_result_error(context, "NULL input to edit()", -1);
1321 return;
1322 }
1323 db = sqlite3_context_db_handle(context);
1324 zTempFile = 0;
1325 sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile);
1326 if( zTempFile==0 ){
1327 sqlite3_uint64 r = 0;
1328 sqlite3_randomness(sizeof(r), &r);
1329 zTempFile = sqlite3_mprintf("temp%llx", r);
1330 if( zTempFile==0 ){
1331 sqlite3_result_error_nomem(context);
1332 return;
1333 }
1334 }
1335 bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB;
drhf018fd52018-08-06 02:08:53 +00001336 /* When writing the file to be edited, do \n to \r\n conversions on systems
1337 ** that want \r\n line endings */
drh97913132018-01-11 00:04:00 +00001338 f = fopen(zTempFile, bBin ? "wb" : "w");
1339 if( f==0 ){
1340 sqlite3_result_error(context, "edit() cannot open temp file", -1);
1341 goto edit_func_end;
1342 }
1343 sz = sqlite3_value_bytes(argv[0]);
1344 if( bBin ){
dan4d02b5f2019-07-17 07:23:06 +00001345 x = fwrite(sqlite3_value_blob(argv[0]), 1, (size_t)sz, f);
drh97913132018-01-11 00:04:00 +00001346 }else{
drhf018fd52018-08-06 02:08:53 +00001347 const char *z = (const char*)sqlite3_value_text(argv[0]);
1348 /* Remember whether or not the value originally contained \r\n */
1349 if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
dan4d02b5f2019-07-17 07:23:06 +00001350 x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f);
drh97913132018-01-11 00:04:00 +00001351 }
1352 fclose(f);
1353 f = 0;
1354 if( x!=sz ){
1355 sqlite3_result_error(context, "edit() could not write the whole file", -1);
1356 goto edit_func_end;
1357 }
1358 zCmd = sqlite3_mprintf("%s \"%s\"", zEditor, zTempFile);
1359 if( zCmd==0 ){
1360 sqlite3_result_error_nomem(context);
1361 goto edit_func_end;
1362 }
1363 rc = system(zCmd);
1364 sqlite3_free(zCmd);
1365 if( rc ){
1366 sqlite3_result_error(context, "EDITOR returned non-zero", -1);
1367 goto edit_func_end;
1368 }
drhf018fd52018-08-06 02:08:53 +00001369 f = fopen(zTempFile, "rb");
drh97913132018-01-11 00:04:00 +00001370 if( f==0 ){
1371 sqlite3_result_error(context,
1372 "edit() cannot reopen temp file after edit", -1);
1373 goto edit_func_end;
1374 }
1375 fseek(f, 0, SEEK_END);
1376 sz = ftell(f);
1377 rewind(f);
drhee37f8b2019-08-23 23:05:32 +00001378 p = sqlite3_malloc64( sz+1 );
drh97913132018-01-11 00:04:00 +00001379 if( p==0 ){
1380 sqlite3_result_error_nomem(context);
1381 goto edit_func_end;
1382 }
dan4d02b5f2019-07-17 07:23:06 +00001383 x = fread(p, 1, (size_t)sz, f);
drh97913132018-01-11 00:04:00 +00001384 fclose(f);
1385 f = 0;
1386 if( x!=sz ){
1387 sqlite3_result_error(context, "could not read back the whole file", -1);
1388 goto edit_func_end;
1389 }
1390 if( bBin ){
mistachkinb71aa092018-01-23 00:05:18 +00001391 sqlite3_result_blob64(context, p, sz, sqlite3_free);
drh97913132018-01-11 00:04:00 +00001392 }else{
dan60bdcf52018-10-03 11:13:30 +00001393 sqlite3_int64 i, j;
drhf018fd52018-08-06 02:08:53 +00001394 if( hasCRNL ){
1395 /* If the original contains \r\n then do no conversions back to \n */
1396 j = sz;
1397 }else{
1398 /* If the file did not originally contain \r\n then convert any new
1399 ** \r\n back into \n */
1400 for(i=j=0; i<sz; i++){
1401 if( p[i]=='\r' && p[i+1]=='\n' ) i++;
1402 p[j++] = p[i];
1403 }
1404 sz = j;
1405 p[sz] = 0;
1406 }
mistachkinb71aa092018-01-23 00:05:18 +00001407 sqlite3_result_text64(context, (const char*)p, sz,
1408 sqlite3_free, SQLITE_UTF8);
drh97913132018-01-11 00:04:00 +00001409 }
1410 p = 0;
1411
1412edit_func_end:
1413 if( f ) fclose(f);
1414 unlink(zTempFile);
1415 sqlite3_free(zTempFile);
1416 sqlite3_free(p);
1417}
drh04a28c32018-01-31 01:38:44 +00001418#endif /* SQLITE_NOHAVE_SYSTEM */
drh97913132018-01-11 00:04:00 +00001419
1420/*
drh3c484e82018-01-10 22:27:21 +00001421** Save or restore the current output mode
1422*/
1423static void outputModePush(ShellState *p){
1424 p->modePrior = p->mode;
drh7a431002020-04-18 14:12:00 +00001425 p->priorShFlgs = p->shellFlgs;
drh3c484e82018-01-10 22:27:21 +00001426 memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
1427 memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
1428}
1429static void outputModePop(ShellState *p){
1430 p->mode = p->modePrior;
drh7a431002020-04-18 14:12:00 +00001431 p->shellFlgs = p->priorShFlgs;
drh3c484e82018-01-10 22:27:21 +00001432 memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
1433 memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
1434}
1435
1436/*
drh2ce15c32017-07-11 13:34:40 +00001437** Output the given string as a hex-encoded blob (eg. X'1234' )
1438*/
1439static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
1440 int i;
1441 char *zBlob = (char *)pBlob;
1442 raw_printf(out,"X'");
1443 for(i=0; i<nBlob; i++){ raw_printf(out,"%02x",zBlob[i]&0xff); }
1444 raw_printf(out,"'");
1445}
1446
1447/*
1448** Find a string that is not found anywhere in z[]. Return a pointer
1449** to that string.
1450**
1451** Try to use zA and zB first. If both of those are already found in z[]
1452** then make up some string and store it in the buffer zBuf.
1453*/
1454static const char *unused_string(
1455 const char *z, /* Result must not appear anywhere in z */
1456 const char *zA, const char *zB, /* Try these first */
1457 char *zBuf /* Space to store a generated string */
1458){
1459 unsigned i = 0;
1460 if( strstr(z, zA)==0 ) return zA;
1461 if( strstr(z, zB)==0 ) return zB;
1462 do{
1463 sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++);
1464 }while( strstr(z,zBuf)!=0 );
1465 return zBuf;
1466}
1467
1468/*
1469** Output the given string as a quoted string using SQL quoting conventions.
1470**
1471** See also: output_quoted_escaped_string()
1472*/
1473static void output_quoted_string(FILE *out, const char *z){
1474 int i;
1475 char c;
1476 setBinaryMode(out, 1);
1477 for(i=0; (c = z[i])!=0 && c!='\''; i++){}
1478 if( c==0 ){
1479 utf8_printf(out,"'%s'",z);
1480 }else{
1481 raw_printf(out, "'");
1482 while( *z ){
1483 for(i=0; (c = z[i])!=0 && c!='\''; i++){}
1484 if( c=='\'' ) i++;
1485 if( i ){
1486 utf8_printf(out, "%.*s", i, z);
1487 z += i;
1488 }
1489 if( c=='\'' ){
1490 raw_printf(out, "'");
1491 continue;
1492 }
1493 if( c==0 ){
1494 break;
1495 }
1496 z++;
1497 }
1498 raw_printf(out, "'");
1499 }
1500 setTextMode(out, 1);
1501}
1502
1503/*
1504** Output the given string as a quoted string using SQL quoting conventions.
1505** Additionallly , escape the "\n" and "\r" characters so that they do not
1506** get corrupted by end-of-line translation facilities in some operating
1507** systems.
1508**
1509** This is like output_quoted_string() but with the addition of the \r\n
1510** escape mechanism.
1511*/
1512static void output_quoted_escaped_string(FILE *out, const char *z){
1513 int i;
1514 char c;
1515 setBinaryMode(out, 1);
1516 for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
1517 if( c==0 ){
1518 utf8_printf(out,"'%s'",z);
1519 }else{
1520 const char *zNL = 0;
1521 const char *zCR = 0;
1522 int nNL = 0;
1523 int nCR = 0;
1524 char zBuf1[20], zBuf2[20];
1525 for(i=0; z[i]; i++){
1526 if( z[i]=='\n' ) nNL++;
1527 if( z[i]=='\r' ) nCR++;
1528 }
1529 if( nNL ){
1530 raw_printf(out, "replace(");
1531 zNL = unused_string(z, "\\n", "\\012", zBuf1);
1532 }
1533 if( nCR ){
1534 raw_printf(out, "replace(");
1535 zCR = unused_string(z, "\\r", "\\015", zBuf2);
1536 }
1537 raw_printf(out, "'");
1538 while( *z ){
1539 for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
1540 if( c=='\'' ) i++;
1541 if( i ){
1542 utf8_printf(out, "%.*s", i, z);
1543 z += i;
1544 }
1545 if( c=='\'' ){
1546 raw_printf(out, "'");
1547 continue;
1548 }
1549 if( c==0 ){
1550 break;
1551 }
1552 z++;
1553 if( c=='\n' ){
1554 raw_printf(out, "%s", zNL);
1555 continue;
1556 }
1557 raw_printf(out, "%s", zCR);
1558 }
1559 raw_printf(out, "'");
1560 if( nCR ){
1561 raw_printf(out, ",'%s',char(13))", zCR);
1562 }
1563 if( nNL ){
1564 raw_printf(out, ",'%s',char(10))", zNL);
1565 }
1566 }
1567 setTextMode(out, 1);
1568}
1569
1570/*
1571** Output the given string as a quoted according to C or TCL quoting rules.
1572*/
1573static void output_c_string(FILE *out, const char *z){
1574 unsigned int c;
1575 fputc('"', out);
1576 while( (c = *(z++))!=0 ){
1577 if( c=='\\' ){
1578 fputc(c, out);
1579 fputc(c, out);
1580 }else if( c=='"' ){
1581 fputc('\\', out);
1582 fputc('"', out);
1583 }else if( c=='\t' ){
1584 fputc('\\', out);
1585 fputc('t', out);
1586 }else if( c=='\n' ){
1587 fputc('\\', out);
1588 fputc('n', out);
1589 }else if( c=='\r' ){
1590 fputc('\\', out);
1591 fputc('r', out);
1592 }else if( !isprint(c&0xff) ){
1593 raw_printf(out, "\\%03o", c&0xff);
1594 }else{
1595 fputc(c, out);
1596 }
1597 }
1598 fputc('"', out);
1599}
1600
1601/*
drh69c093d2020-05-29 00:21:43 +00001602** Output the given string as a quoted according to JSON quoting rules.
1603*/
1604static void output_json_string(FILE *out, const char *z, int n){
1605 unsigned int c;
1606 if( n<0 ) n = (int)strlen(z);
1607 fputc('"', out);
1608 while( n-- ){
1609 c = *(z++);
1610 if( c=='\\' || c=='"' ){
1611 fputc('\\', out);
1612 fputc(c, out);
1613 }else if( c<=0x1f ){
1614 fputc('\\', out);
1615 if( c=='\b' ){
1616 fputc('b', out);
1617 }else if( c=='\f' ){
1618 fputc('f', out);
1619 }else if( c=='\n' ){
1620 fputc('n', out);
1621 }else if( c=='\r' ){
1622 fputc('r', out);
1623 }else if( c=='\t' ){
1624 fputc('t', out);
1625 }else{
1626 raw_printf(out, "u%04x",c);
1627 }
1628 }else{
1629 fputc(c, out);
1630 }
1631 }
1632 fputc('"', out);
1633}
1634
1635/*
drh2ce15c32017-07-11 13:34:40 +00001636** Output the given string with characters that are special to
1637** HTML escaped.
1638*/
1639static void output_html_string(FILE *out, const char *z){
1640 int i;
1641 if( z==0 ) z = "";
1642 while( *z ){
1643 for(i=0; z[i]
1644 && z[i]!='<'
1645 && z[i]!='&'
1646 && z[i]!='>'
1647 && z[i]!='\"'
1648 && z[i]!='\'';
1649 i++){}
1650 if( i>0 ){
1651 utf8_printf(out,"%.*s",i,z);
1652 }
1653 if( z[i]=='<' ){
1654 raw_printf(out,"&lt;");
1655 }else if( z[i]=='&' ){
1656 raw_printf(out,"&amp;");
1657 }else if( z[i]=='>' ){
1658 raw_printf(out,"&gt;");
1659 }else if( z[i]=='\"' ){
1660 raw_printf(out,"&quot;");
1661 }else if( z[i]=='\'' ){
1662 raw_printf(out,"&#39;");
1663 }else{
1664 break;
1665 }
1666 z += i + 1;
1667 }
1668}
1669
1670/*
1671** If a field contains any character identified by a 1 in the following
1672** array, then the string must be quoted for CSV.
1673*/
1674static const char needCsvQuote[] = {
1675 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1676 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1677 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1678 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1679 0, 0, 0, 0, 0, 0, 0, 0, 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, 1,
1683 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1684 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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};
1692
1693/*
1694** Output a single term of CSV. Actually, p->colSeparator is used for
1695** the separator, which may or may not be a comma. p->nullValue is
1696** the null value. Strings are quoted if necessary. The separator
1697** is only issued if bSep is true.
1698*/
1699static void output_csv(ShellState *p, const char *z, int bSep){
1700 FILE *out = p->out;
1701 if( z==0 ){
1702 utf8_printf(out,"%s",p->nullValue);
1703 }else{
1704 int i;
1705 int nSep = strlen30(p->colSeparator);
1706 for(i=0; z[i]; i++){
1707 if( needCsvQuote[((unsigned char*)z)[i]]
1708 || (z[i]==p->colSeparator[0] &&
1709 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
1710 i = 0;
1711 break;
1712 }
1713 }
1714 if( i==0 ){
drh9b7affc2017-11-26 02:14:18 +00001715 char *zQuoted = sqlite3_mprintf("\"%w\"", z);
1716 utf8_printf(out, "%s", zQuoted);
1717 sqlite3_free(zQuoted);
drh2ce15c32017-07-11 13:34:40 +00001718 }else{
1719 utf8_printf(out, "%s", z);
1720 }
1721 }
1722 if( bSep ){
1723 utf8_printf(p->out, "%s", p->colSeparator);
1724 }
1725}
1726
drh2ce15c32017-07-11 13:34:40 +00001727/*
1728** This routine runs when the user presses Ctrl-C
1729*/
1730static void interrupt_handler(int NotUsed){
1731 UNUSED_PARAMETER(NotUsed);
1732 seenInterrupt++;
1733 if( seenInterrupt>2 ) exit(1);
1734 if( globalDb ) sqlite3_interrupt(globalDb);
1735}
mistachkinb4bab902017-10-27 17:09:44 +00001736
1737#if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
1738/*
1739** This routine runs for console events (e.g. Ctrl-C) on Win32
1740*/
1741static BOOL WINAPI ConsoleCtrlHandler(
1742 DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */
1743){
1744 if( dwCtrlType==CTRL_C_EVENT ){
1745 interrupt_handler(0);
1746 return TRUE;
1747 }
1748 return FALSE;
1749}
drh2ce15c32017-07-11 13:34:40 +00001750#endif
1751
1752#ifndef SQLITE_OMIT_AUTHORIZATION
1753/*
1754** When the ".auth ON" is set, the following authorizer callback is
1755** invoked. It always returns SQLITE_OK.
1756*/
1757static int shellAuth(
1758 void *pClientData,
1759 int op,
1760 const char *zA1,
1761 const char *zA2,
1762 const char *zA3,
1763 const char *zA4
1764){
1765 ShellState *p = (ShellState*)pClientData;
1766 static const char *azAction[] = { 0,
1767 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX",
1768 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW",
1769 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE",
1770 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX",
1771 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW",
1772 "DROP_TRIGGER", "DROP_VIEW", "INSERT",
1773 "PRAGMA", "READ", "SELECT",
1774 "TRANSACTION", "UPDATE", "ATTACH",
1775 "DETACH", "ALTER_TABLE", "REINDEX",
1776 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE",
1777 "FUNCTION", "SAVEPOINT", "RECURSIVE"
1778 };
1779 int i;
1780 const char *az[4];
1781 az[0] = zA1;
1782 az[1] = zA2;
1783 az[2] = zA3;
1784 az[3] = zA4;
1785 utf8_printf(p->out, "authorizer: %s", azAction[op]);
1786 for(i=0; i<4; i++){
1787 raw_printf(p->out, " ");
1788 if( az[i] ){
1789 output_c_string(p->out, az[i]);
1790 }else{
1791 raw_printf(p->out, "NULL");
1792 }
1793 }
1794 raw_printf(p->out, "\n");
1795 return SQLITE_OK;
1796}
1797#endif
1798
1799/*
1800** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
1801**
1802** This routine converts some CREATE TABLE statements for shadow tables
1803** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
1804*/
1805static void printSchemaLine(FILE *out, const char *z, const char *zTail){
drh0a0536a2019-05-09 18:13:30 +00001806 if( z==0 ) return;
1807 if( zTail==0 ) return;
drh2ce15c32017-07-11 13:34:40 +00001808 if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
1809 utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
1810 }else{
1811 utf8_printf(out, "%s%s", z, zTail);
1812 }
1813}
1814static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
1815 char c = z[n];
1816 z[n] = 0;
1817 printSchemaLine(out, z, zTail);
1818 z[n] = c;
1819}
1820
1821/*
drh11be81d2018-01-06 15:46:20 +00001822** Return true if string z[] has nothing but whitespace and comments to the
1823** end of the first line.
1824*/
1825static int wsToEol(const char *z){
1826 int i;
1827 for(i=0; z[i]; i++){
1828 if( z[i]=='\n' ) return 1;
1829 if( IsSpace(z[i]) ) continue;
1830 if( z[i]=='-' && z[i+1]=='-' ) return 1;
1831 return 0;
1832 }
1833 return 1;
1834}
drh4b5345c2018-04-24 13:07:40 +00001835
1836/*
1837** Add a new entry to the EXPLAIN QUERY PLAN data
1838*/
drhe2ca99c2018-05-02 00:33:43 +00001839static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
drh4b5345c2018-04-24 13:07:40 +00001840 EQPGraphRow *pNew;
1841 int nText = strlen30(zText);
drhe2ca99c2018-05-02 00:33:43 +00001842 if( p->autoEQPtest ){
1843 utf8_printf(p->out, "%d,%d,%s\n", iEqpId, p2, zText);
1844 }
drh4b5345c2018-04-24 13:07:40 +00001845 pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
1846 if( pNew==0 ) shell_out_of_memory();
drhe2ca99c2018-05-02 00:33:43 +00001847 pNew->iEqpId = iEqpId;
1848 pNew->iParentId = p2;
drh4b5345c2018-04-24 13:07:40 +00001849 memcpy(pNew->zText, zText, nText+1);
1850 pNew->pNext = 0;
1851 if( p->sGraph.pLast ){
1852 p->sGraph.pLast->pNext = pNew;
1853 }else{
1854 p->sGraph.pRow = pNew;
1855 }
1856 p->sGraph.pLast = pNew;
1857}
1858
1859/*
1860** Free and reset the EXPLAIN QUERY PLAN data that has been collected
1861** in p->sGraph.
1862*/
1863static void eqp_reset(ShellState *p){
1864 EQPGraphRow *pRow, *pNext;
1865 for(pRow = p->sGraph.pRow; pRow; pRow = pNext){
1866 pNext = pRow->pNext;
1867 sqlite3_free(pRow);
1868 }
1869 memset(&p->sGraph, 0, sizeof(p->sGraph));
1870}
1871
drhe2ca99c2018-05-02 00:33:43 +00001872/* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after
drh4b5345c2018-04-24 13:07:40 +00001873** pOld, or return the first such line if pOld is NULL
1874*/
drhe2ca99c2018-05-02 00:33:43 +00001875static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){
drh4b5345c2018-04-24 13:07:40 +00001876 EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow;
drhe2ca99c2018-05-02 00:33:43 +00001877 while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext;
drh4b5345c2018-04-24 13:07:40 +00001878 return pRow;
1879}
1880
drhe2ca99c2018-05-02 00:33:43 +00001881/* Render a single level of the graph that has iEqpId as its parent. Called
drh4b5345c2018-04-24 13:07:40 +00001882** recursively to render sublevels.
1883*/
drhe2ca99c2018-05-02 00:33:43 +00001884static void eqp_render_level(ShellState *p, int iEqpId){
drh4b5345c2018-04-24 13:07:40 +00001885 EQPGraphRow *pRow, *pNext;
drh4b5345c2018-04-24 13:07:40 +00001886 int n = strlen30(p->sGraph.zPrefix);
1887 char *z;
drhe2ca99c2018-05-02 00:33:43 +00001888 for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
1889 pNext = eqp_next_row(p, iEqpId, pRow);
drh4b5345c2018-04-24 13:07:40 +00001890 z = pRow->zText;
drhe2754c12019-08-26 12:50:01 +00001891 utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix,
1892 pNext ? "|--" : "`--", z);
drhe2188f02018-05-07 11:37:34 +00001893 if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){
drh4b5345c2018-04-24 13:07:40 +00001894 memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4);
drhe2ca99c2018-05-02 00:33:43 +00001895 eqp_render_level(p, pRow->iEqpId);
drh4b5345c2018-04-24 13:07:40 +00001896 p->sGraph.zPrefix[n] = 0;
1897 }
1898 }
1899}
1900
1901/*
1902** Display and reset the EXPLAIN QUERY PLAN data
1903*/
1904static void eqp_render(ShellState *p){
1905 EQPGraphRow *pRow = p->sGraph.pRow;
1906 if( pRow ){
1907 if( pRow->zText[0]=='-' ){
1908 if( pRow->pNext==0 ){
1909 eqp_reset(p);
1910 return;
1911 }
1912 utf8_printf(p->out, "%s\n", pRow->zText+3);
1913 p->sGraph.pRow = pRow->pNext;
1914 sqlite3_free(pRow);
1915 }else{
1916 utf8_printf(p->out, "QUERY PLAN\n");
1917 }
1918 p->sGraph.zPrefix[0] = 0;
1919 eqp_render_level(p, 0);
1920 eqp_reset(p);
1921 }
1922}
drh11be81d2018-01-06 15:46:20 +00001923
drh569b1d92019-02-05 20:51:41 +00001924#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
drh11be81d2018-01-06 15:46:20 +00001925/*
drh3f83f592019-02-04 14:53:18 +00001926** Progress handler callback.
1927*/
1928static int progress_handler(void *pClientData) {
1929 ShellState *p = (ShellState*)pClientData;
1930 p->nProgress++;
1931 if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
1932 raw_printf(p->out, "Progress limit reached (%u)\n", p->nProgress);
drhfc4eeef2019-02-05 19:48:46 +00001933 if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
1934 if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0;
drh3f83f592019-02-04 14:53:18 +00001935 return 1;
1936 }
drhfc4eeef2019-02-05 19:48:46 +00001937 if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
drh3f83f592019-02-04 14:53:18 +00001938 raw_printf(p->out, "Progress %u\n", p->nProgress);
1939 }
1940 return 0;
1941}
drh569b1d92019-02-05 20:51:41 +00001942#endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
drh3f83f592019-02-04 14:53:18 +00001943
1944/*
drh30c54a02020-05-28 23:49:50 +00001945** Print N dashes
1946*/
1947static void print_dashes(FILE *out, int N){
1948 const char zDash[] = "--------------------------------------------------";
1949 const int nDash = sizeof(zDash) - 1;
1950 while( N>nDash ){
1951 fputs(zDash, out);
1952 N -= nDash;
1953 }
1954 raw_printf(out, "%.*s", N, zDash);
1955}
1956
1957/*
drh0908e382020-06-04 18:05:39 +00001958** Print a markdown or table-style row separator using ascii-art
drh30c54a02020-05-28 23:49:50 +00001959*/
1960static void print_row_separator(
1961 ShellState *p,
1962 int nArg,
1963 const char *zSep
1964){
1965 int i;
drh0908e382020-06-04 18:05:39 +00001966 if( nArg>0 ){
drh30c54a02020-05-28 23:49:50 +00001967 fputs(zSep, p->out);
drh0908e382020-06-04 18:05:39 +00001968 print_dashes(p->out, p->actualWidth[0]+2);
1969 for(i=1; i<nArg; i++){
1970 fputs(zSep, p->out);
1971 print_dashes(p->out, p->actualWidth[i]+2);
1972 }
1973 fputs(zSep, p->out);
drh30c54a02020-05-28 23:49:50 +00001974 }
drh30c54a02020-05-28 23:49:50 +00001975 fputs("\n", p->out);
1976}
1977
1978/*
drh2ce15c32017-07-11 13:34:40 +00001979** This is the callback routine that the shell
1980** invokes for each row of a query result.
1981*/
1982static int shell_callback(
1983 void *pArg,
1984 int nArg, /* Number of result columns */
1985 char **azArg, /* Text of each result column */
1986 char **azCol, /* Column names */
drhd6f25242020-05-29 12:31:53 +00001987 int *aiType /* Column types. Might be NULL */
drh2ce15c32017-07-11 13:34:40 +00001988){
1989 int i;
1990 ShellState *p = (ShellState*)pArg;
1991
drhb3c45232017-08-28 14:33:27 +00001992 if( azArg==0 ) return 0;
drh2ce15c32017-07-11 13:34:40 +00001993 switch( p->cMode ){
1994 case MODE_Line: {
1995 int w = 5;
1996 if( azArg==0 ) break;
1997 for(i=0; i<nArg; i++){
1998 int len = strlen30(azCol[i] ? azCol[i] : "");
1999 if( len>w ) w = len;
2000 }
2001 if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
2002 for(i=0; i<nArg; i++){
2003 utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
2004 azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
2005 }
2006 break;
2007 }
drh8c748632020-05-29 16:15:58 +00002008 case MODE_Explain: {
2009 static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
2010 if( nArg>ArraySize(aExplainWidth) ){
2011 nArg = ArraySize(aExplainWidth);
drh2ce15c32017-07-11 13:34:40 +00002012 }
2013 if( p->cnt++==0 ){
2014 for(i=0; i<nArg; i++){
drh8c748632020-05-29 16:15:58 +00002015 int w = aExplainWidth[i];
2016 utf8_width_print(p->out, w, azCol[i]);
2017 fputs(i==nArg-1 ? "\n" : " ", p->out);
drh2ce15c32017-07-11 13:34:40 +00002018 }
drhe566ceb2020-05-30 15:34:49 +00002019 for(i=0; i<nArg; i++){
2020 int w = aExplainWidth[i];
2021 print_dashes(p->out, w);
2022 fputs(i==nArg-1 ? "\n" : " ", p->out);
2023 }
drh2ce15c32017-07-11 13:34:40 +00002024 }
2025 if( azArg==0 ) break;
2026 for(i=0; i<nArg; i++){
drh8c748632020-05-29 16:15:58 +00002027 int w = aExplainWidth[i];
2028 if( azArg[i] && strlenChar(azArg[i])>w ){
2029 w = strlenChar(azArg[i]);
drh2ce15c32017-07-11 13:34:40 +00002030 }
drh8c748632020-05-29 16:15:58 +00002031 if( i==1 && p->aiIndent && p->pStmt ){
2032 if( p->iIndent<p->nIndent ){
2033 utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
drh2ce15c32017-07-11 13:34:40 +00002034 }
drh8c748632020-05-29 16:15:58 +00002035 p->iIndent++;
drh2ce15c32017-07-11 13:34:40 +00002036 }
2037 utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue);
drh8c748632020-05-29 16:15:58 +00002038 fputs(i==nArg-1 ? "\n" : " ", p->out);
drh2ce15c32017-07-11 13:34:40 +00002039 }
2040 break;
2041 }
2042 case MODE_Semi: { /* .schema and .fullschema output */
2043 printSchemaLine(p->out, azArg[0], ";\n");
2044 break;
2045 }
2046 case MODE_Pretty: { /* .schema and .fullschema with --indent */
2047 char *z;
2048 int j;
2049 int nParen = 0;
2050 char cEnd = 0;
2051 char c;
2052 int nLine = 0;
2053 assert( nArg==1 );
2054 if( azArg[0]==0 ) break;
2055 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
2056 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
2057 ){
2058 utf8_printf(p->out, "%s;\n", azArg[0]);
2059 break;
2060 }
2061 z = sqlite3_mprintf("%s", azArg[0]);
2062 j = 0;
2063 for(i=0; IsSpace(z[i]); i++){}
2064 for(; (c = z[i])!=0; i++){
2065 if( IsSpace(c) ){
drhc3cbd672017-10-05 19:12:10 +00002066 if( z[j-1]=='\r' ) z[j-1] = '\n';
drh2ce15c32017-07-11 13:34:40 +00002067 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue;
2068 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){
2069 j--;
2070 }
2071 z[j++] = c;
2072 }
2073 while( j>0 && IsSpace(z[j-1]) ){ j--; }
2074 z[j] = 0;
2075 if( strlen30(z)>=79 ){
drhe2754c12019-08-26 12:50:01 +00002076 for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
drh2ce15c32017-07-11 13:34:40 +00002077 if( c==cEnd ){
2078 cEnd = 0;
2079 }else if( c=='"' || c=='\'' || c=='`' ){
2080 cEnd = c;
2081 }else if( c=='[' ){
2082 cEnd = ']';
drh11be81d2018-01-06 15:46:20 +00002083 }else if( c=='-' && z[i+1]=='-' ){
2084 cEnd = '\n';
drh2ce15c32017-07-11 13:34:40 +00002085 }else if( c=='(' ){
2086 nParen++;
2087 }else if( c==')' ){
2088 nParen--;
2089 if( nLine>0 && nParen==0 && j>0 ){
2090 printSchemaLineN(p->out, z, j, "\n");
2091 j = 0;
2092 }
2093 }
2094 z[j++] = c;
drh11be81d2018-01-06 15:46:20 +00002095 if( nParen==1 && cEnd==0
2096 && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
2097 ){
drh2ce15c32017-07-11 13:34:40 +00002098 if( c=='\n' ) j--;
2099 printSchemaLineN(p->out, z, j, "\n ");
2100 j = 0;
2101 nLine++;
2102 while( IsSpace(z[i+1]) ){ i++; }
2103 }
2104 }
2105 z[j] = 0;
2106 }
2107 printSchemaLine(p->out, z, ";\n");
2108 sqlite3_free(z);
2109 break;
2110 }
2111 case MODE_List: {
2112 if( p->cnt++==0 && p->showHeader ){
2113 for(i=0; i<nArg; i++){
2114 utf8_printf(p->out,"%s%s",azCol[i],
2115 i==nArg-1 ? p->rowSeparator : p->colSeparator);
2116 }
2117 }
2118 if( azArg==0 ) break;
2119 for(i=0; i<nArg; i++){
2120 char *z = azArg[i];
2121 if( z==0 ) z = p->nullValue;
2122 utf8_printf(p->out, "%s", z);
2123 if( i<nArg-1 ){
2124 utf8_printf(p->out, "%s", p->colSeparator);
2125 }else{
2126 utf8_printf(p->out, "%s", p->rowSeparator);
2127 }
2128 }
2129 break;
2130 }
2131 case MODE_Html: {
2132 if( p->cnt++==0 && p->showHeader ){
2133 raw_printf(p->out,"<TR>");
2134 for(i=0; i<nArg; i++){
2135 raw_printf(p->out,"<TH>");
2136 output_html_string(p->out, azCol[i]);
2137 raw_printf(p->out,"</TH>\n");
2138 }
2139 raw_printf(p->out,"</TR>\n");
2140 }
2141 if( azArg==0 ) break;
2142 raw_printf(p->out,"<TR>");
2143 for(i=0; i<nArg; i++){
2144 raw_printf(p->out,"<TD>");
2145 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
2146 raw_printf(p->out,"</TD>\n");
2147 }
2148 raw_printf(p->out,"</TR>\n");
2149 break;
2150 }
2151 case MODE_Tcl: {
2152 if( p->cnt++==0 && p->showHeader ){
2153 for(i=0; i<nArg; i++){
2154 output_c_string(p->out,azCol[i] ? azCol[i] : "");
2155 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
2156 }
2157 utf8_printf(p->out, "%s", p->rowSeparator);
2158 }
2159 if( azArg==0 ) break;
2160 for(i=0; i<nArg; i++){
2161 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
2162 if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
2163 }
2164 utf8_printf(p->out, "%s", p->rowSeparator);
2165 break;
2166 }
2167 case MODE_Csv: {
2168 setBinaryMode(p->out, 1);
2169 if( p->cnt++==0 && p->showHeader ){
2170 for(i=0; i<nArg; i++){
2171 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
2172 }
2173 utf8_printf(p->out, "%s", p->rowSeparator);
2174 }
2175 if( nArg>0 ){
2176 for(i=0; i<nArg; i++){
2177 output_csv(p, azArg[i], i<nArg-1);
2178 }
2179 utf8_printf(p->out, "%s", p->rowSeparator);
2180 }
2181 setTextMode(p->out, 1);
2182 break;
2183 }
2184 case MODE_Insert: {
2185 if( azArg==0 ) break;
2186 utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
2187 if( p->showHeader ){
2188 raw_printf(p->out,"(");
2189 for(i=0; i<nArg; i++){
2190 if( i>0 ) raw_printf(p->out, ",");
2191 if( quoteChar(azCol[i]) ){
2192 char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
2193 utf8_printf(p->out, "%s", z);
2194 sqlite3_free(z);
2195 }else{
2196 raw_printf(p->out, "%s", azCol[i]);
2197 }
2198 }
2199 raw_printf(p->out,")");
2200 }
2201 p->cnt++;
2202 for(i=0; i<nArg; i++){
2203 raw_printf(p->out, i>0 ? "," : " VALUES(");
2204 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
2205 utf8_printf(p->out,"NULL");
2206 }else if( aiType && aiType[i]==SQLITE_TEXT ){
2207 if( ShellHasFlag(p, SHFLG_Newlines) ){
2208 output_quoted_string(p->out, azArg[i]);
2209 }else{
2210 output_quoted_escaped_string(p->out, azArg[i]);
2211 }
2212 }else if( aiType && aiType[i]==SQLITE_INTEGER ){
2213 utf8_printf(p->out,"%s", azArg[i]);
2214 }else if( aiType && aiType[i]==SQLITE_FLOAT ){
2215 char z[50];
2216 double r = sqlite3_column_double(p->pStmt, i);
drh2f1f8802018-06-13 17:19:20 +00002217 sqlite3_uint64 ur;
2218 memcpy(&ur,&r,sizeof(r));
2219 if( ur==0x7ff0000000000000LL ){
2220 raw_printf(p->out, "1e999");
2221 }else if( ur==0xfff0000000000000LL ){
2222 raw_printf(p->out, "-1e999");
2223 }else{
2224 sqlite3_snprintf(50,z,"%!.20g", r);
2225 raw_printf(p->out, "%s", z);
2226 }
drh2ce15c32017-07-11 13:34:40 +00002227 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
2228 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
2229 int nBlob = sqlite3_column_bytes(p->pStmt, i);
2230 output_hex_blob(p->out, pBlob, nBlob);
2231 }else if( isNumber(azArg[i], 0) ){
2232 utf8_printf(p->out,"%s", azArg[i]);
2233 }else if( ShellHasFlag(p, SHFLG_Newlines) ){
2234 output_quoted_string(p->out, azArg[i]);
2235 }else{
2236 output_quoted_escaped_string(p->out, azArg[i]);
2237 }
2238 }
2239 raw_printf(p->out,");\n");
2240 break;
2241 }
drh30c54a02020-05-28 23:49:50 +00002242 case MODE_Json: {
2243 if( azArg==0 ) break;
2244 if( p->cnt==0 ){
2245 fputs("[{", p->out);
2246 }else{
2247 fputs(",\n{", p->out);
2248 }
2249 p->cnt++;
2250 for(i=0; i<nArg; i++){
drh69c093d2020-05-29 00:21:43 +00002251 output_json_string(p->out, azCol[i], -1);
drh30c54a02020-05-28 23:49:50 +00002252 putc(':', p->out);
2253 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
2254 fputs("null",p->out);
2255 }else if( aiType && aiType[i]==SQLITE_FLOAT ){
2256 char z[50];
2257 double r = sqlite3_column_double(p->pStmt, i);
2258 sqlite3_uint64 ur;
2259 memcpy(&ur,&r,sizeof(r));
2260 if( ur==0x7ff0000000000000LL ){
2261 raw_printf(p->out, "1e999");
2262 }else if( ur==0xfff0000000000000LL ){
2263 raw_printf(p->out, "-1e999");
2264 }else{
2265 sqlite3_snprintf(50,z,"%!.20g", r);
2266 raw_printf(p->out, "%s", z);
2267 }
2268 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
2269 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
2270 int nBlob = sqlite3_column_bytes(p->pStmt, i);
drh69c093d2020-05-29 00:21:43 +00002271 output_json_string(p->out, pBlob, nBlob);
drh30c54a02020-05-28 23:49:50 +00002272 }else if( aiType && aiType[i]==SQLITE_TEXT ){
drh69c093d2020-05-29 00:21:43 +00002273 output_json_string(p->out, azArg[i], -1);
drh30c54a02020-05-28 23:49:50 +00002274 }else{
2275 utf8_printf(p->out,"%s", azArg[i]);
2276 }
2277 if( i<nArg-1 ){
2278 putc(',', p->out);
2279 }
2280 }
2281 putc('}', p->out);
2282 break;
2283 }
drh2ce15c32017-07-11 13:34:40 +00002284 case MODE_Quote: {
2285 if( azArg==0 ) break;
2286 if( p->cnt==0 && p->showHeader ){
2287 for(i=0; i<nArg; i++){
drhc6835732020-05-28 20:37:17 +00002288 if( i>0 ) fputs(p->colSeparator, p->out);
drh2ce15c32017-07-11 13:34:40 +00002289 output_quoted_string(p->out, azCol[i]);
2290 }
drhc6835732020-05-28 20:37:17 +00002291 fputs(p->rowSeparator, p->out);
drh2ce15c32017-07-11 13:34:40 +00002292 }
2293 p->cnt++;
2294 for(i=0; i<nArg; i++){
drhc6835732020-05-28 20:37:17 +00002295 if( i>0 ) fputs(p->colSeparator, p->out);
drh2ce15c32017-07-11 13:34:40 +00002296 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
2297 utf8_printf(p->out,"NULL");
2298 }else if( aiType && aiType[i]==SQLITE_TEXT ){
2299 output_quoted_string(p->out, azArg[i]);
2300 }else if( aiType && aiType[i]==SQLITE_INTEGER ){
2301 utf8_printf(p->out,"%s", azArg[i]);
2302 }else if( aiType && aiType[i]==SQLITE_FLOAT ){
2303 char z[50];
2304 double r = sqlite3_column_double(p->pStmt, i);
2305 sqlite3_snprintf(50,z,"%!.20g", r);
2306 raw_printf(p->out, "%s", z);
2307 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
2308 const void *pBlob = sqlite3_column_blob(p->pStmt, i);
2309 int nBlob = sqlite3_column_bytes(p->pStmt, i);
2310 output_hex_blob(p->out, pBlob, nBlob);
2311 }else if( isNumber(azArg[i], 0) ){
2312 utf8_printf(p->out,"%s", azArg[i]);
2313 }else{
2314 output_quoted_string(p->out, azArg[i]);
2315 }
2316 }
drhc6835732020-05-28 20:37:17 +00002317 fputs(p->rowSeparator, p->out);
drh2ce15c32017-07-11 13:34:40 +00002318 break;
2319 }
2320 case MODE_Ascii: {
2321 if( p->cnt++==0 && p->showHeader ){
2322 for(i=0; i<nArg; i++){
2323 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
2324 utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
2325 }
2326 utf8_printf(p->out, "%s", p->rowSeparator);
2327 }
2328 if( azArg==0 ) break;
2329 for(i=0; i<nArg; i++){
2330 if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
2331 utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
2332 }
2333 utf8_printf(p->out, "%s", p->rowSeparator);
2334 break;
2335 }
drh4b5345c2018-04-24 13:07:40 +00002336 case MODE_EQP: {
drhe2ca99c2018-05-02 00:33:43 +00002337 eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
drh4b5345c2018-04-24 13:07:40 +00002338 break;
2339 }
drh2ce15c32017-07-11 13:34:40 +00002340 }
2341 return 0;
2342}
2343
2344/*
2345** This is the callback routine that the SQLite library
2346** invokes for each row of a query result.
2347*/
2348static int callback(void *pArg, int nArg, char **azArg, char **azCol){
2349 /* since we don't have type info, call the shell_callback with a NULL value */
2350 return shell_callback(pArg, nArg, azArg, azCol, NULL);
2351}
2352
2353/*
2354** This is the callback routine from sqlite3_exec() that appends all
2355** output onto the end of a ShellText object.
2356*/
2357static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){
2358 ShellText *p = (ShellText*)pArg;
2359 int i;
2360 UNUSED_PARAMETER(az);
drhb3c45232017-08-28 14:33:27 +00002361 if( azArg==0 ) return 0;
drh2ce15c32017-07-11 13:34:40 +00002362 if( p->n ) appendText(p, "|", 0);
2363 for(i=0; i<nArg; i++){
2364 if( i ) appendText(p, ",", 0);
2365 if( azArg[i] ) appendText(p, azArg[i], 0);
2366 }
2367 return 0;
2368}
2369
2370/*
2371** Generate an appropriate SELFTEST table in the main database.
2372*/
2373static void createSelftestTable(ShellState *p){
2374 char *zErrMsg = 0;
2375 sqlite3_exec(p->db,
2376 "SAVEPOINT selftest_init;\n"
2377 "CREATE TABLE IF NOT EXISTS selftest(\n"
2378 " tno INTEGER PRIMARY KEY,\n" /* Test number */
2379 " op TEXT,\n" /* Operator: memo run */
2380 " cmd TEXT,\n" /* Command text */
2381 " ans TEXT\n" /* Desired answer */
2382 ");"
2383 "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n"
2384 "INSERT INTO [_shell$self](rowid,op,cmd)\n"
2385 " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n"
2386 " 'memo','Tests generated by --init');\n"
2387 "INSERT INTO [_shell$self]\n"
2388 " SELECT 'run',\n"
2389 " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql "
drh067b92b2020-06-19 15:24:12 +00002390 "FROM sqlite_schema ORDER BY 2'',224))',\n"
drh2ce15c32017-07-11 13:34:40 +00002391 " 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 "INSERT INTO [_shell$self]\n"
2394 " SELECT 'run',"
2395 " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||"
2396 " printf('%w',name) || '\" NOT INDEXED'',224))',\n"
2397 " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n"
2398 " FROM (\n"
drh067b92b2020-06-19 15:24:12 +00002399 " SELECT name FROM sqlite_schema\n"
drh2ce15c32017-07-11 13:34:40 +00002400 " WHERE type='table'\n"
2401 " AND name<>'selftest'\n"
2402 " AND coalesce(rootpage,0)>0\n"
2403 " )\n"
2404 " ORDER BY name;\n"
2405 "INSERT INTO [_shell$self]\n"
2406 " VALUES('run','PRAGMA integrity_check','ok');\n"
2407 "INSERT INTO selftest(tno,op,cmd,ans)"
2408 " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
2409 "DROP TABLE [_shell$self];"
2410 ,0,0,&zErrMsg);
2411 if( zErrMsg ){
2412 utf8_printf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg);
2413 sqlite3_free(zErrMsg);
2414 }
2415 sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
2416}
2417
2418
2419/*
2420** Set the destination table field of the ShellState structure to
2421** the name of the table given. Escape any quote characters in the
2422** table name.
2423*/
2424static void set_table_name(ShellState *p, const char *zName){
2425 int i, n;
mistachkin2158a0c2017-09-09 00:51:36 +00002426 char cQuote;
drh2ce15c32017-07-11 13:34:40 +00002427 char *z;
2428
2429 if( p->zDestTable ){
2430 free(p->zDestTable);
2431 p->zDestTable = 0;
2432 }
2433 if( zName==0 ) return;
2434 cQuote = quoteChar(zName);
2435 n = strlen30(zName);
2436 if( cQuote ) n += n+2;
2437 z = p->zDestTable = malloc( n+1 );
drh4b5345c2018-04-24 13:07:40 +00002438 if( z==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00002439 n = 0;
2440 if( cQuote ) z[n++] = cQuote;
2441 for(i=0; zName[i]; i++){
2442 z[n++] = zName[i];
2443 if( zName[i]==cQuote ) z[n++] = cQuote;
2444 }
2445 if( cQuote ) z[n++] = cQuote;
2446 z[n] = 0;
2447}
2448
2449
2450/*
2451** Execute a query statement that will generate SQL output. Print
2452** the result columns, comma-separated, on a line and then add a
2453** semicolon terminator to the end of that line.
2454**
2455** If the number of columns is 1 and that column contains text "--"
2456** then write the semicolon on a separate line. That way, if a
2457** "--" comment occurs at the end of the statement, the comment
2458** won't consume the semicolon terminator.
2459*/
2460static int run_table_dump_query(
2461 ShellState *p, /* Query context */
drh8e9297f2020-03-25 12:50:13 +00002462 const char *zSelect /* SELECT statement to extract content */
drh2ce15c32017-07-11 13:34:40 +00002463){
2464 sqlite3_stmt *pSelect;
2465 int rc;
2466 int nResult;
2467 int i;
2468 const char *z;
2469 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
2470 if( rc!=SQLITE_OK || !pSelect ){
2471 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
2472 sqlite3_errmsg(p->db));
2473 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
2474 return rc;
2475 }
2476 rc = sqlite3_step(pSelect);
2477 nResult = sqlite3_column_count(pSelect);
2478 while( rc==SQLITE_ROW ){
drh2ce15c32017-07-11 13:34:40 +00002479 z = (const char*)sqlite3_column_text(pSelect, 0);
2480 utf8_printf(p->out, "%s", z);
2481 for(i=1; i<nResult; i++){
2482 utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
2483 }
2484 if( z==0 ) z = "";
2485 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
2486 if( z[0] ){
2487 raw_printf(p->out, "\n;\n");
2488 }else{
2489 raw_printf(p->out, ";\n");
2490 }
2491 rc = sqlite3_step(pSelect);
2492 }
2493 rc = sqlite3_finalize(pSelect);
2494 if( rc!=SQLITE_OK ){
2495 utf8_printf(p->out, "/**** ERROR: (%d) %s *****/\n", rc,
2496 sqlite3_errmsg(p->db));
2497 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
2498 }
2499 return rc;
2500}
2501
2502/*
2503** Allocate space and save off current error string.
2504*/
2505static char *save_err_msg(
2506 sqlite3 *db /* Database to query */
2507){
2508 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
2509 char *zErrMsg = sqlite3_malloc64(nErrMsg);
2510 if( zErrMsg ){
2511 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
2512 }
2513 return zErrMsg;
2514}
2515
2516#ifdef __linux__
2517/*
2518** Attempt to display I/O stats on Linux using /proc/PID/io
2519*/
2520static void displayLinuxIoStats(FILE *out){
2521 FILE *in;
2522 char z[200];
2523 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
2524 in = fopen(z, "rb");
2525 if( in==0 ) return;
2526 while( fgets(z, sizeof(z), in)!=0 ){
2527 static const struct {
2528 const char *zPattern;
2529 const char *zDesc;
2530 } aTrans[] = {
2531 { "rchar: ", "Bytes received by read():" },
2532 { "wchar: ", "Bytes sent to write():" },
2533 { "syscr: ", "Read() system calls:" },
2534 { "syscw: ", "Write() system calls:" },
2535 { "read_bytes: ", "Bytes read from storage:" },
2536 { "write_bytes: ", "Bytes written to storage:" },
2537 { "cancelled_write_bytes: ", "Cancelled write bytes:" },
2538 };
2539 int i;
2540 for(i=0; i<ArraySize(aTrans); i++){
drhaf2770f2018-01-05 14:55:43 +00002541 int n = strlen30(aTrans[i].zPattern);
drh2ce15c32017-07-11 13:34:40 +00002542 if( strncmp(aTrans[i].zPattern, z, n)==0 ){
2543 utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
2544 break;
2545 }
2546 }
2547 }
2548 fclose(in);
2549}
2550#endif
2551
2552/*
2553** Display a single line of status using 64-bit values.
2554*/
2555static void displayStatLine(
2556 ShellState *p, /* The shell context */
2557 char *zLabel, /* Label for this one line */
2558 char *zFormat, /* Format for the result */
2559 int iStatusCtrl, /* Which status to display */
2560 int bReset /* True to reset the stats */
2561){
2562 sqlite3_int64 iCur = -1;
2563 sqlite3_int64 iHiwtr = -1;
2564 int i, nPercent;
2565 char zLine[200];
2566 sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset);
2567 for(i=0, nPercent=0; zFormat[i]; i++){
2568 if( zFormat[i]=='%' ) nPercent++;
2569 }
2570 if( nPercent>1 ){
2571 sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
2572 }else{
2573 sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
2574 }
2575 raw_printf(p->out, "%-36s %s\n", zLabel, zLine);
2576}
2577
2578/*
2579** Display memory stats.
2580*/
2581static int display_stats(
2582 sqlite3 *db, /* Database to query */
2583 ShellState *pArg, /* Pointer to ShellState */
2584 int bReset /* True to reset the stats */
2585){
2586 int iCur;
2587 int iHiwtr;
drh393344f2018-03-09 16:37:05 +00002588 FILE *out;
2589 if( pArg==0 || pArg->out==0 ) return 0;
2590 out = pArg->out;
drh2ce15c32017-07-11 13:34:40 +00002591
drh393344f2018-03-09 16:37:05 +00002592 if( pArg->pStmt && (pArg->statsOn & 2) ){
2593 int nCol, i, x;
2594 sqlite3_stmt *pStmt = pArg->pStmt;
2595 char z[100];
2596 nCol = sqlite3_column_count(pStmt);
2597 raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
2598 for(i=0; i<nCol; i++){
2599 sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
2600 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
drh929cce82018-03-17 16:26:36 +00002601#ifndef SQLITE_OMIT_DECLTYPE
drh393344f2018-03-09 16:37:05 +00002602 sqlite3_snprintf(30, z+x, "declared type:");
2603 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
drh929cce82018-03-17 16:26:36 +00002604#endif
2605#ifdef SQLITE_ENABLE_COLUMN_METADATA
drh393344f2018-03-09 16:37:05 +00002606 sqlite3_snprintf(30, z+x, "database name:");
2607 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_database_name(pStmt,i));
2608 sqlite3_snprintf(30, z+x, "table name:");
2609 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
2610 sqlite3_snprintf(30, z+x, "origin name:");
2611 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
drh929cce82018-03-17 16:26:36 +00002612#endif
drh2ce15c32017-07-11 13:34:40 +00002613 }
drh929cce82018-03-17 16:26:36 +00002614 }
drh2ce15c32017-07-11 13:34:40 +00002615
drh393344f2018-03-09 16:37:05 +00002616 displayStatLine(pArg, "Memory Used:",
2617 "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
2618 displayStatLine(pArg, "Number of Outstanding Allocations:",
2619 "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
2620 if( pArg->shellFlgs & SHFLG_Pagecache ){
2621 displayStatLine(pArg, "Number of Pcache Pages Used:",
2622 "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
2623 }
2624 displayStatLine(pArg, "Number of Pcache Overflow Bytes:",
2625 "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
2626 displayStatLine(pArg, "Largest Allocation:",
2627 "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
2628 displayStatLine(pArg, "Largest Pcache Allocation:",
2629 "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
2630#ifdef YYTRACKMAXSTACKDEPTH
2631 displayStatLine(pArg, "Deepest Parser Stack:",
2632 "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
2633#endif
2634
2635 if( db ){
drh2ce15c32017-07-11 13:34:40 +00002636 if( pArg->shellFlgs & SHFLG_Lookaside ){
2637 iHiwtr = iCur = -1;
2638 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
2639 &iCur, &iHiwtr, bReset);
2640 raw_printf(pArg->out,
2641 "Lookaside Slots Used: %d (max %d)\n",
2642 iCur, iHiwtr);
2643 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
2644 &iCur, &iHiwtr, bReset);
2645 raw_printf(pArg->out, "Successful lookaside attempts: %d\n",
2646 iHiwtr);
2647 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
2648 &iCur, &iHiwtr, bReset);
2649 raw_printf(pArg->out, "Lookaside failures due to size: %d\n",
2650 iHiwtr);
2651 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
2652 &iCur, &iHiwtr, bReset);
2653 raw_printf(pArg->out, "Lookaside failures due to OOM: %d\n",
2654 iHiwtr);
2655 }
2656 iHiwtr = iCur = -1;
2657 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
2658 raw_printf(pArg->out, "Pager Heap Usage: %d bytes\n",
2659 iCur);
2660 iHiwtr = iCur = -1;
2661 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
2662 raw_printf(pArg->out, "Page cache hits: %d\n", iCur);
2663 iHiwtr = iCur = -1;
2664 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
2665 raw_printf(pArg->out, "Page cache misses: %d\n", iCur);
2666 iHiwtr = iCur = -1;
2667 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
2668 raw_printf(pArg->out, "Page cache writes: %d\n", iCur);
2669 iHiwtr = iCur = -1;
drhffc78a42018-03-14 14:53:50 +00002670 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
2671 raw_printf(pArg->out, "Page cache spills: %d\n", iCur);
2672 iHiwtr = iCur = -1;
drh2ce15c32017-07-11 13:34:40 +00002673 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
2674 raw_printf(pArg->out, "Schema Heap Usage: %d bytes\n",
2675 iCur);
2676 iHiwtr = iCur = -1;
2677 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
2678 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
2679 iCur);
2680 }
2681
drh393344f2018-03-09 16:37:05 +00002682 if( pArg->pStmt ){
drh2ce15c32017-07-11 13:34:40 +00002683 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
2684 bReset);
2685 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
2686 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
2687 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
2688 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
2689 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
2690 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
2691 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
drhe2754c12019-08-26 12:50:01 +00002692 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
drh393344f2018-03-09 16:37:05 +00002693 raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
2694 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
2695 raw_printf(pArg->out, "Number of times run: %d\n", iCur);
2696 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
2697 raw_printf(pArg->out, "Memory used by prepared stmt: %d\n", iCur);
drh2ce15c32017-07-11 13:34:40 +00002698 }
2699
2700#ifdef __linux__
2701 displayLinuxIoStats(pArg->out);
2702#endif
2703
2704 /* Do not remove this machine readable comment: extra-stats-output-here */
2705
2706 return 0;
2707}
2708
2709/*
2710** Display scan stats.
2711*/
2712static void display_scanstats(
2713 sqlite3 *db, /* Database to query */
2714 ShellState *pArg /* Pointer to ShellState */
2715){
2716#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
2717 UNUSED_PARAMETER(db);
2718 UNUSED_PARAMETER(pArg);
2719#else
2720 int i, k, n, mx;
2721 raw_printf(pArg->out, "-------- scanstats --------\n");
2722 mx = 0;
2723 for(k=0; k<=mx; k++){
2724 double rEstLoop = 1.0;
2725 for(i=n=0; 1; i++){
2726 sqlite3_stmt *p = pArg->pStmt;
2727 sqlite3_int64 nLoop, nVisit;
2728 double rEst;
2729 int iSid;
2730 const char *zExplain;
2731 if( sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop) ){
2732 break;
2733 }
2734 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_SELECTID, (void*)&iSid);
2735 if( iSid>mx ) mx = iSid;
2736 if( iSid!=k ) continue;
2737 if( n==0 ){
2738 rEstLoop = (double)nLoop;
2739 if( k>0 ) raw_printf(pArg->out, "-------- subquery %d -------\n", k);
2740 }
2741 n++;
2742 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
2743 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
2744 sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
2745 utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
2746 rEstLoop *= rEst;
2747 raw_printf(pArg->out,
2748 " nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
2749 nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
2750 );
2751 }
2752 }
2753 raw_printf(pArg->out, "---------------------------\n");
2754#endif
2755}
2756
2757/*
2758** Parameter azArray points to a zero-terminated array of strings. zStr
2759** points to a single nul-terminated string. Return non-zero if zStr
2760** is equal, according to strcmp(), to any of the strings in the array.
2761** Otherwise, return zero.
2762*/
2763static int str_in_array(const char *zStr, const char **azArray){
2764 int i;
2765 for(i=0; azArray[i]; i++){
2766 if( 0==strcmp(zStr, azArray[i]) ) return 1;
2767 }
2768 return 0;
2769}
2770
2771/*
2772** If compiled statement pSql appears to be an EXPLAIN statement, allocate
2773** and populate the ShellState.aiIndent[] array with the number of
2774** spaces each opcode should be indented before it is output.
2775**
2776** The indenting rules are:
2777**
2778** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
2779** all opcodes that occur between the p2 jump destination and the opcode
2780** itself by 2 spaces.
2781**
2782** * For each "Goto", if the jump destination is earlier in the program
2783** and ends on one of:
2784** Yield SeekGt SeekLt RowSetRead Rewind
2785** or if the P1 parameter is one instead of zero,
2786** then indent all opcodes between the earlier instruction
2787** and "Goto" by 2 spaces.
2788*/
2789static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){
2790 const char *zSql; /* The text of the SQL statement */
2791 const char *z; /* Used to check if this is an EXPLAIN */
2792 int *abYield = 0; /* True if op is an OP_Yield */
2793 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */
2794 int iOp; /* Index of operation in p->aiIndent[] */
2795
drhf1949b62018-06-07 17:32:59 +00002796 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
drh2ce15c32017-07-11 13:34:40 +00002797 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
2798 "Rewind", 0 };
2799 const char *azGoto[] = { "Goto", 0 };
2800
2801 /* Try to figure out if this is really an EXPLAIN statement. If this
2802 ** cannot be verified, return early. */
2803 if( sqlite3_column_count(pSql)!=8 ){
2804 p->cMode = p->mode;
2805 return;
2806 }
2807 zSql = sqlite3_sql(pSql);
2808 if( zSql==0 ) return;
2809 for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
2810 if( sqlite3_strnicmp(z, "explain", 7) ){
2811 p->cMode = p->mode;
2812 return;
2813 }
2814
2815 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
2816 int i;
2817 int iAddr = sqlite3_column_int(pSql, 0);
2818 const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
2819
2820 /* Set p2 to the P2 field of the current opcode. Then, assuming that
2821 ** p2 is an instruction address, set variable p2op to the index of that
2822 ** instruction in the aiIndent[] array. p2 and p2op may be different if
2823 ** the current instruction is part of a sub-program generated by an
2824 ** SQL trigger or foreign key. */
2825 int p2 = sqlite3_column_int(pSql, 3);
2826 int p2op = (p2 + (iOp-iAddr));
2827
2828 /* Grow the p->aiIndent array as required */
2829 if( iOp>=nAlloc ){
2830 if( iOp==0 ){
2831 /* Do further verfication that this is explain output. Abort if
2832 ** it is not */
2833 static const char *explainCols[] = {
2834 "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
2835 int jj;
2836 for(jj=0; jj<ArraySize(explainCols); jj++){
2837 if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
2838 p->cMode = p->mode;
2839 sqlite3_reset(pSql);
2840 return;
2841 }
2842 }
2843 }
2844 nAlloc += 100;
2845 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
drh884406b2018-07-29 18:56:35 +00002846 if( p->aiIndent==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00002847 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
drh884406b2018-07-29 18:56:35 +00002848 if( abYield==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00002849 }
2850 abYield[iOp] = str_in_array(zOp, azYield);
2851 p->aiIndent[iOp] = 0;
2852 p->nIndent = iOp+1;
2853
2854 if( str_in_array(zOp, azNext) ){
2855 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
2856 }
2857 if( str_in_array(zOp, azGoto) && p2op<p->nIndent
2858 && (abYield[p2op] || sqlite3_column_int(pSql, 2))
2859 ){
2860 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
2861 }
2862 }
2863
2864 p->iIndent = 0;
2865 sqlite3_free(abYield);
2866 sqlite3_reset(pSql);
2867}
2868
2869/*
2870** Free the array allocated by explain_data_prepare().
2871*/
2872static void explain_data_delete(ShellState *p){
2873 sqlite3_free(p->aiIndent);
2874 p->aiIndent = 0;
2875 p->nIndent = 0;
2876 p->iIndent = 0;
2877}
2878
2879/*
2880** Disable and restore .wheretrace and .selecttrace settings.
2881*/
2882#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
dan12a4c412020-08-10 14:34:36 +00002883extern unsigned int sqlite3_unsupported_selecttrace;
drh2ce15c32017-07-11 13:34:40 +00002884static int savedSelectTrace;
2885#endif
2886#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2887extern int sqlite3WhereTrace;
2888static int savedWhereTrace;
2889#endif
2890static void disable_debug_trace_modes(void){
2891#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
dana6c13b22020-08-08 17:02:39 +00002892 savedSelectTrace = sqlite3_unsupported_selecttrace;
2893 sqlite3_unsupported_selecttrace = 0;
drh2ce15c32017-07-11 13:34:40 +00002894#endif
2895#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2896 savedWhereTrace = sqlite3WhereTrace;
2897 sqlite3WhereTrace = 0;
2898#endif
2899}
2900static void restore_debug_trace_modes(void){
2901#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
dana6c13b22020-08-08 17:02:39 +00002902 sqlite3_unsupported_selecttrace = savedSelectTrace;
drh2ce15c32017-07-11 13:34:40 +00002903#endif
2904#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
2905 sqlite3WhereTrace = savedWhereTrace;
2906#endif
2907}
2908
drh9cb02642019-02-28 20:10:52 +00002909/* Create the TEMP table used to store parameter bindings */
2910static void bind_table_init(ShellState *p){
drh346f4e22019-03-25 21:35:41 +00002911 int wrSchema = 0;
drh4b86e202020-01-19 20:37:26 +00002912 int defensiveMode = 0;
2913 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &defensiveMode);
2914 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0);
drh346f4e22019-03-25 21:35:41 +00002915 sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema);
2916 sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0);
drh9cb02642019-02-28 20:10:52 +00002917 sqlite3_exec(p->db,
drh65c29fd2019-03-25 21:56:26 +00002918 "CREATE TABLE IF NOT EXISTS temp.sqlite_parameters(\n"
drh9cb02642019-02-28 20:10:52 +00002919 " key TEXT PRIMARY KEY,\n"
2920 " value ANY\n"
2921 ") WITHOUT ROWID;",
2922 0, 0, 0);
drh346f4e22019-03-25 21:35:41 +00002923 sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0);
drh4b86e202020-01-19 20:37:26 +00002924 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, defensiveMode, 0);
drh9cb02642019-02-28 20:10:52 +00002925}
2926
drh8b738d02019-02-25 18:43:54 +00002927/*
2928** Bind parameters on a prepared statement.
2929**
2930** Parameter bindings are taken from a TEMP table of the form:
2931**
drh1cb02632019-03-25 22:05:22 +00002932** CREATE TEMP TABLE sqlite_parameters(key TEXT PRIMARY KEY, value)
drh8b738d02019-02-25 18:43:54 +00002933** WITHOUT ROWID;
2934**
drh91654b22020-04-02 13:21:10 +00002935** No bindings occur if this table does not exist. The name of the table
2936** begins with "sqlite_" so that it will not collide with ordinary application
2937** tables. The table must be in the TEMP schema.
drh8b738d02019-02-25 18:43:54 +00002938*/
2939static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
2940 int nVar;
2941 int i;
2942 int rc;
2943 sqlite3_stmt *pQ = 0;
2944
2945 nVar = sqlite3_bind_parameter_count(pStmt);
2946 if( nVar==0 ) return; /* Nothing to do */
drh65c29fd2019-03-25 21:56:26 +00002947 if( sqlite3_table_column_metadata(pArg->db, "TEMP", "sqlite_parameters",
drh8b738d02019-02-25 18:43:54 +00002948 "key", 0, 0, 0, 0, 0)!=SQLITE_OK ){
2949 return; /* Parameter table does not exist */
2950 }
2951 rc = sqlite3_prepare_v2(pArg->db,
drh65c29fd2019-03-25 21:56:26 +00002952 "SELECT value FROM temp.sqlite_parameters"
drh8b738d02019-02-25 18:43:54 +00002953 " WHERE key=?1", -1, &pQ, 0);
2954 if( rc || pQ==0 ) return;
2955 for(i=1; i<=nVar; i++){
2956 char zNum[30];
2957 const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
2958 if( zVar==0 ){
2959 sqlite3_snprintf(sizeof(zNum),zNum,"?%d",i);
2960 zVar = zNum;
2961 }
2962 sqlite3_bind_text(pQ, 1, zVar, -1, SQLITE_STATIC);
2963 if( sqlite3_step(pQ)==SQLITE_ROW ){
2964 sqlite3_bind_value(pStmt, i, sqlite3_column_value(pQ, 0));
2965 }else{
2966 sqlite3_bind_null(pStmt, i);
2967 }
2968 sqlite3_reset(pQ);
2969 }
2970 sqlite3_finalize(pQ);
2971}
2972
drh30c54a02020-05-28 23:49:50 +00002973/*
drh0908e382020-06-04 18:05:39 +00002974** UTF8 box-drawing characters. Imagine box lines like this:
2975**
2976** 1
2977** |
2978** 4 --+-- 2
2979** |
2980** 3
2981**
2982** Each box characters has between 2 and 4 of the lines leading from
2983** the center. The characters are here identified by the numbers of
2984** their corresponding lines.
2985*/
2986#define BOX_24 "\342\224\200" /* U+2500 --- */
2987#define BOX_13 "\342\224\202" /* U+2502 | */
2988#define BOX_23 "\342\224\214" /* U+250c ,- */
2989#define BOX_34 "\342\224\220" /* U+2510 -, */
2990#define BOX_12 "\342\224\224" /* U+2514 '- */
2991#define BOX_14 "\342\224\230" /* U+2518 -' */
2992#define BOX_123 "\342\224\234" /* U+251c |- */
2993#define BOX_134 "\342\224\244" /* U+2524 -| */
2994#define BOX_234 "\342\224\254" /* U+252c -,- */
2995#define BOX_124 "\342\224\264" /* U+2534 -'- */
2996#define BOX_1234 "\342\224\274" /* U+253c -|- */
2997
2998/* Draw horizontal line N characters long using unicode box
2999** characters
3000*/
3001static void print_box_line(FILE *out, int N){
3002 const char zDash[] =
3003 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
3004 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
3005 const int nDash = sizeof(zDash) - 1;
3006 N *= 3;
3007 while( N>nDash ){
3008 utf8_printf(out, zDash);
3009 N -= nDash;
3010 }
3011 utf8_printf(out, "%.*s", N, zDash);
3012}
3013
3014/*
3015** Draw a horizontal separator for a MODE_Box table.
3016*/
3017static void print_box_row_separator(
3018 ShellState *p,
3019 int nArg,
3020 const char *zSep1,
3021 const char *zSep2,
3022 const char *zSep3
3023){
3024 int i;
3025 if( nArg>0 ){
3026 utf8_printf(p->out, "%s", zSep1);
3027 print_box_line(p->out, p->actualWidth[0]+2);
3028 for(i=1; i<nArg; i++){
3029 utf8_printf(p->out, "%s", zSep2);
3030 print_box_line(p->out, p->actualWidth[i]+2);
3031 }
3032 utf8_printf(p->out, "%s", zSep3);
3033 }
3034 fputs("\n", p->out);
3035}
3036
3037
3038
3039/*
drh30c54a02020-05-28 23:49:50 +00003040** Run a prepared statement and output the result in one of the
drh0908e382020-06-04 18:05:39 +00003041** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table,
3042** or MODE_Box.
drh30c54a02020-05-28 23:49:50 +00003043**
3044** This is different from ordinary exec_prepared_stmt() in that
3045** it has to run the entire query and gather the results into memory
3046** first, in order to determine column widths, before providing
3047** any output.
3048*/
drh8c748632020-05-29 16:15:58 +00003049static void exec_prepared_stmt_columnar(
3050 ShellState *p, /* Pointer to ShellState */
3051 sqlite3_stmt *pStmt /* Statment to run */
drh30c54a02020-05-28 23:49:50 +00003052){
drhf82ce382020-08-06 16:45:22 +00003053 sqlite3_int64 nRow = 0;
drh8c748632020-05-29 16:15:58 +00003054 int nColumn = 0;
3055 char **azData = 0;
drhf82ce382020-08-06 16:45:22 +00003056 sqlite3_int64 nAlloc = 0;
drh8c748632020-05-29 16:15:58 +00003057 const char *z;
3058 int rc;
drhf82ce382020-08-06 16:45:22 +00003059 sqlite3_int64 i, nData;
3060 int j, nTotal, w, n;
drh0908e382020-06-04 18:05:39 +00003061 const char *colSep = 0;
3062 const char *rowSep = 0;
drh30c54a02020-05-28 23:49:50 +00003063
drhf82ce382020-08-06 16:45:22 +00003064 rc = sqlite3_step(pStmt);
3065 if( rc!=SQLITE_ROW ) return;
3066 nColumn = sqlite3_column_count(pStmt);
3067 nAlloc = nColumn*4;
3068 azData = sqlite3_malloc64( nAlloc*sizeof(char*) );
3069 if( azData==0 ) shell_out_of_memory();
3070 for(i=0; i<nColumn; i++){
3071 azData[i] = strdup(sqlite3_column_name(pStmt,i));
drh8c748632020-05-29 16:15:58 +00003072 }
drhf82ce382020-08-06 16:45:22 +00003073 do{
3074 if( (nRow+2)*nColumn >= nAlloc ){
3075 nAlloc *= 2;
3076 azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*));
3077 if( azData==0 ) shell_out_of_memory();
3078 }
3079 nRow++;
3080 for(i=0; i<nColumn; i++){
3081 z = (const char*)sqlite3_column_text(pStmt,i);
3082 azData[nRow*nColumn + i] = z ? strdup(z) : 0;
3083 }
3084 }while( (rc = sqlite3_step(pStmt))==SQLITE_ROW );
drh8c748632020-05-29 16:15:58 +00003085 if( nColumn>p->nWidth ){
3086 p->colWidth = realloc(p->colWidth, nColumn*2*sizeof(int));
3087 if( p->colWidth==0 ) shell_out_of_memory();
3088 for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
3089 p->nWidth = nColumn;
3090 p->actualWidth = &p->colWidth[nColumn];
3091 }
3092 memset(p->actualWidth, 0, nColumn*sizeof(int));
3093 for(i=0; i<nColumn; i++){
3094 w = p->colWidth[i];
3095 if( w<0 ) w = -w;
3096 p->actualWidth[i] = w;
3097 }
3098 nTotal = nColumn*(nRow+1);
3099 for(i=0; i<nTotal; i++){
3100 z = azData[i];
3101 if( z==0 ) z = p->nullValue;
3102 n = strlenChar(z);
3103 j = i%nColumn;
3104 if( n>p->actualWidth[j] ) p->actualWidth[j] = n;
3105 }
drh99942982020-06-15 20:05:37 +00003106 if( seenInterrupt ) goto columnar_end;
drh0908e382020-06-04 18:05:39 +00003107 switch( p->cMode ){
3108 case MODE_Column: {
3109 colSep = " ";
3110 rowSep = "\n";
3111 if( p->showHeader ){
3112 for(i=0; i<nColumn; i++){
3113 w = p->actualWidth[i];
3114 if( p->colWidth[i]<0 ) w = -w;
3115 utf8_width_print(p->out, w, azData[i]);
3116 fputs(i==nColumn-1?"\n":" ", p->out);
3117 }
3118 for(i=0; i<nColumn; i++){
3119 print_dashes(p->out, p->actualWidth[i]);
3120 fputs(i==nColumn-1?"\n":" ", p->out);
3121 }
3122 }
3123 break;
3124 }
3125 case MODE_Table: {
3126 colSep = " | ";
3127 rowSep = " |\n";
3128 print_row_separator(p, nColumn, "+");
3129 fputs("| ", p->out);
drh8c748632020-05-29 16:15:58 +00003130 for(i=0; i<nColumn; i++){
3131 w = p->actualWidth[i];
drh0908e382020-06-04 18:05:39 +00003132 n = strlenChar(azData[i]);
3133 utf8_printf(p->out, "%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
3134 fputs(i==nColumn-1?" |\n":" | ", p->out);
drh8c748632020-05-29 16:15:58 +00003135 }
drh0908e382020-06-04 18:05:39 +00003136 print_row_separator(p, nColumn, "+");
3137 break;
3138 }
3139 case MODE_Markdown: {
3140 colSep = " | ";
3141 rowSep = " |\n";
3142 fputs("| ", p->out);
drh8c748632020-05-29 16:15:58 +00003143 for(i=0; i<nColumn; i++){
drh0908e382020-06-04 18:05:39 +00003144 w = p->actualWidth[i];
3145 n = strlenChar(azData[i]);
3146 utf8_printf(p->out, "%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
3147 fputs(i==nColumn-1?" |\n":" | ", p->out);
drh8c748632020-05-29 16:15:58 +00003148 }
drh0908e382020-06-04 18:05:39 +00003149 print_row_separator(p, nColumn, "|");
3150 break;
drh8c748632020-05-29 16:15:58 +00003151 }
drh0908e382020-06-04 18:05:39 +00003152 case MODE_Box: {
3153 colSep = " " BOX_13 " ";
3154 rowSep = " " BOX_13 "\n";
3155 print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34);
3156 utf8_printf(p->out, BOX_13 " ");
3157 for(i=0; i<nColumn; i++){
3158 w = p->actualWidth[i];
3159 n = strlenChar(azData[i]);
3160 utf8_printf(p->out, "%*s%s%*s%s",
3161 (w-n)/2, "", azData[i], (w-n+1)/2, "",
3162 i==nColumn-1?" "BOX_13"\n":" "BOX_13" ");
3163 }
3164 print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
3165 break;
drh8c748632020-05-29 16:15:58 +00003166 }
drh8c748632020-05-29 16:15:58 +00003167 }
3168 for(i=nColumn, j=0; i<nTotal; i++, j++){
drh0908e382020-06-04 18:05:39 +00003169 if( j==0 && p->cMode!=MODE_Column ){
3170 utf8_printf(p->out, "%s", p->cMode==MODE_Box?BOX_13" ":"| ");
3171 }
drh8c748632020-05-29 16:15:58 +00003172 z = azData[i];
3173 if( z==0 ) z = p->nullValue;
3174 w = p->actualWidth[j];
3175 if( p->colWidth[j]<0 ) w = -w;
3176 utf8_width_print(p->out, w, z);
3177 if( j==nColumn-1 ){
drh0908e382020-06-04 18:05:39 +00003178 utf8_printf(p->out, "%s", rowSep);
drh8c748632020-05-29 16:15:58 +00003179 j = -1;
drhdd853c32020-06-16 17:34:40 +00003180 if( seenInterrupt ) goto columnar_end;
drh8c748632020-05-29 16:15:58 +00003181 }else{
drh0908e382020-06-04 18:05:39 +00003182 utf8_printf(p->out, "%s", colSep);
drh8c748632020-05-29 16:15:58 +00003183 }
3184 }
3185 if( p->cMode==MODE_Table ){
3186 print_row_separator(p, nColumn, "+");
drh0908e382020-06-04 18:05:39 +00003187 }else if( p->cMode==MODE_Box ){
3188 print_box_row_separator(p, nColumn, BOX_12, BOX_124, BOX_14);
drh8c748632020-05-29 16:15:58 +00003189 }
drh99942982020-06-15 20:05:37 +00003190columnar_end:
drhdd853c32020-06-16 17:34:40 +00003191 if( seenInterrupt ){
3192 utf8_printf(p->out, "Interrupt\n");
3193 }
drhf82ce382020-08-06 16:45:22 +00003194 nData = (nRow+1)*nColumn;
3195 for(i=0; i<nData; i++) free(azData[i]);
3196 sqlite3_free(azData);
drh30c54a02020-05-28 23:49:50 +00003197}
drh30c54a02020-05-28 23:49:50 +00003198
drh2ce15c32017-07-11 13:34:40 +00003199/*
3200** Run a prepared statement
3201*/
3202static void exec_prepared_stmt(
3203 ShellState *pArg, /* Pointer to ShellState */
drha10b9992018-03-09 15:24:33 +00003204 sqlite3_stmt *pStmt /* Statment to run */
drh2ce15c32017-07-11 13:34:40 +00003205){
3206 int rc;
3207
drh8c748632020-05-29 16:15:58 +00003208 if( pArg->cMode==MODE_Column
3209 || pArg->cMode==MODE_Table
drh0908e382020-06-04 18:05:39 +00003210 || pArg->cMode==MODE_Box
drh8c748632020-05-29 16:15:58 +00003211 || pArg->cMode==MODE_Markdown
3212 ){
3213 exec_prepared_stmt_columnar(pArg, pStmt);
3214 return;
3215 }
3216
drh2ce15c32017-07-11 13:34:40 +00003217 /* perform the first step. this will tell us if we
3218 ** have a result set or not and how wide it is.
3219 */
3220 rc = sqlite3_step(pStmt);
3221 /* if we have a result set... */
3222 if( SQLITE_ROW == rc ){
drha10b9992018-03-09 15:24:33 +00003223 /* allocate space for col name ptr, value ptr, and type */
3224 int nCol = sqlite3_column_count(pStmt);
3225 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
3226 if( !pData ){
3227 rc = SQLITE_NOMEM;
drh2ce15c32017-07-11 13:34:40 +00003228 }else{
drha10b9992018-03-09 15:24:33 +00003229 char **azCols = (char **)pData; /* Names of result columns */
3230 char **azVals = &azCols[nCol]; /* Results */
3231 int *aiTypes = (int *)&azVals[nCol]; /* Result types */
3232 int i, x;
3233 assert(sizeof(int) <= sizeof(char *));
3234 /* save off ptrs to column names */
3235 for(i=0; i<nCol; i++){
3236 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
3237 }
drh2ce15c32017-07-11 13:34:40 +00003238 do{
drha10b9992018-03-09 15:24:33 +00003239 /* extract the data and data types */
3240 for(i=0; i<nCol; i++){
3241 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
3242 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
3243 azVals[i] = "";
3244 }else{
3245 azVals[i] = (char*)sqlite3_column_text(pStmt, i);
3246 }
3247 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
3248 rc = SQLITE_NOMEM;
3249 break; /* from for */
3250 }
3251 } /* end for */
3252
3253 /* if data and types extracted successfully... */
3254 if( SQLITE_ROW == rc ){
3255 /* call the supplied callback with the result row data */
3256 if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){
3257 rc = SQLITE_ABORT;
3258 }else{
3259 rc = sqlite3_step(pStmt);
3260 }
3261 }
3262 } while( SQLITE_ROW == rc );
3263 sqlite3_free(pData);
drh0908e382020-06-04 18:05:39 +00003264 if( pArg->cMode==MODE_Json ){
drh30c54a02020-05-28 23:49:50 +00003265 fputs("]\n", pArg->out);
3266 }
drh2ce15c32017-07-11 13:34:40 +00003267 }
3268 }
3269}
3270
dan6b046be2018-01-09 15:25:55 +00003271#ifndef SQLITE_OMIT_VIRTUALTABLE
drh2ce15c32017-07-11 13:34:40 +00003272/*
dan43efc182017-12-19 17:42:13 +00003273** This function is called to process SQL if the previous shell command
3274** was ".expert". It passes the SQL in the second argument directly to
3275** the sqlite3expert object.
3276**
3277** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
3278** code. In this case, (*pzErr) may be set to point to a buffer containing
3279** an English language error message. It is the responsibility of the
3280** caller to eventually free this buffer using sqlite3_free().
3281*/
3282static int expertHandleSQL(
3283 ShellState *pState,
3284 const char *zSql,
3285 char **pzErr
3286){
3287 assert( pState->expert.pExpert );
3288 assert( pzErr==0 || *pzErr==0 );
3289 return sqlite3_expert_sql(pState->expert.pExpert, zSql, pzErr);
3290}
3291
3292/*
3293** This function is called either to silently clean up the object
3294** created by the ".expert" command (if bCancel==1), or to generate a
3295** report from it and then clean it up (if bCancel==0).
3296**
3297** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
3298** code. In this case, (*pzErr) may be set to point to a buffer containing
3299** an English language error message. It is the responsibility of the
3300** caller to eventually free this buffer using sqlite3_free().
3301*/
3302static int expertFinish(
3303 ShellState *pState,
3304 int bCancel,
3305 char **pzErr
3306){
3307 int rc = SQLITE_OK;
3308 sqlite3expert *p = pState->expert.pExpert;
3309 assert( p );
3310 assert( bCancel || pzErr==0 || *pzErr==0 );
3311 if( bCancel==0 ){
3312 FILE *out = pState->out;
3313 int bVerbose = pState->expert.bVerbose;
3314
3315 rc = sqlite3_expert_analyze(p, pzErr);
3316 if( rc==SQLITE_OK ){
3317 int nQuery = sqlite3_expert_count(p);
3318 int i;
3319
3320 if( bVerbose ){
3321 const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
3322 raw_printf(out, "-- Candidates -----------------------------\n");
3323 raw_printf(out, "%s\n", zCand);
3324 }
3325 for(i=0; i<nQuery; i++){
3326 const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
3327 const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES);
3328 const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
3329 if( zIdx==0 ) zIdx = "(no new indexes)\n";
3330 if( bVerbose ){
3331 raw_printf(out, "-- Query %d --------------------------------\n",i+1);
3332 raw_printf(out, "%s\n\n", zSql);
3333 }
3334 raw_printf(out, "%s\n", zIdx);
3335 raw_printf(out, "%s\n", zEQP);
3336 }
3337 }
3338 }
3339 sqlite3_expert_destroy(p);
3340 pState->expert.pExpert = 0;
3341 return rc;
3342}
3343
dan6b046be2018-01-09 15:25:55 +00003344/*
3345** Implementation of ".expert" dot command.
3346*/
3347static int expertDotCommand(
3348 ShellState *pState, /* Current shell tool state */
3349 char **azArg, /* Array of arguments passed to dot command */
3350 int nArg /* Number of entries in azArg[] */
3351){
3352 int rc = SQLITE_OK;
3353 char *zErr = 0;
3354 int i;
3355 int iSample = 0;
3356
3357 assert( pState->expert.pExpert==0 );
3358 memset(&pState->expert, 0, sizeof(ExpertInfo));
3359
3360 for(i=1; rc==SQLITE_OK && i<nArg; i++){
3361 char *z = azArg[i];
3362 int n;
3363 if( z[0]=='-' && z[1]=='-' ) z++;
3364 n = strlen30(z);
3365 if( n>=2 && 0==strncmp(z, "-verbose", n) ){
3366 pState->expert.bVerbose = 1;
3367 }
3368 else if( n>=2 && 0==strncmp(z, "-sample", n) ){
3369 if( i==(nArg-1) ){
3370 raw_printf(stderr, "option requires an argument: %s\n", z);
3371 rc = SQLITE_ERROR;
3372 }else{
3373 iSample = (int)integerValue(azArg[++i]);
3374 if( iSample<0 || iSample>100 ){
3375 raw_printf(stderr, "value out of range: %s\n", azArg[i]);
3376 rc = SQLITE_ERROR;
3377 }
3378 }
3379 }
3380 else{
3381 raw_printf(stderr, "unknown option: %s\n", z);
3382 rc = SQLITE_ERROR;
3383 }
3384 }
3385
3386 if( rc==SQLITE_OK ){
3387 pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
3388 if( pState->expert.pExpert==0 ){
3389 raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr);
3390 rc = SQLITE_ERROR;
3391 }else{
3392 sqlite3_expert_config(
3393 pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
3394 );
3395 }
3396 }
3397
3398 return rc;
3399}
3400#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
dan43efc182017-12-19 17:42:13 +00003401
3402/*
drh2ce15c32017-07-11 13:34:40 +00003403** Execute a statement or set of statements. Print
3404** any result rows/columns depending on the current mode
3405** set via the supplied callback.
3406**
3407** This is very similar to SQLite's built-in sqlite3_exec()
3408** function except it takes a slightly different callback
3409** and callback data argument.
3410*/
3411static int shell_exec(
drh2ce15c32017-07-11 13:34:40 +00003412 ShellState *pArg, /* Pointer to ShellState */
drha10b9992018-03-09 15:24:33 +00003413 const char *zSql, /* SQL to be evaluated */
drh2ce15c32017-07-11 13:34:40 +00003414 char **pzErrMsg /* Error msg written here */
3415){
3416 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
3417 int rc = SQLITE_OK; /* Return Code */
3418 int rc2;
3419 const char *zLeftover; /* Tail of unprocessed SQL */
drha10b9992018-03-09 15:24:33 +00003420 sqlite3 *db = pArg->db;
drh2ce15c32017-07-11 13:34:40 +00003421
3422 if( pzErrMsg ){
3423 *pzErrMsg = NULL;
3424 }
3425
dan6b046be2018-01-09 15:25:55 +00003426#ifndef SQLITE_OMIT_VIRTUALTABLE
dan43efc182017-12-19 17:42:13 +00003427 if( pArg->expert.pExpert ){
3428 rc = expertHandleSQL(pArg, zSql, pzErrMsg);
3429 return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg);
3430 }
dan6b046be2018-01-09 15:25:55 +00003431#endif
dan43efc182017-12-19 17:42:13 +00003432
drh2ce15c32017-07-11 13:34:40 +00003433 while( zSql[0] && (SQLITE_OK == rc) ){
3434 static const char *zStmtSql;
3435 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
3436 if( SQLITE_OK != rc ){
3437 if( pzErrMsg ){
3438 *pzErrMsg = save_err_msg(db);
3439 }
3440 }else{
3441 if( !pStmt ){
3442 /* this happens for a comment or white-space */
3443 zSql = zLeftover;
3444 while( IsSpace(zSql[0]) ) zSql++;
3445 continue;
3446 }
3447 zStmtSql = sqlite3_sql(pStmt);
3448 if( zStmtSql==0 ) zStmtSql = "";
3449 while( IsSpace(zStmtSql[0]) ) zStmtSql++;
3450
3451 /* save off the prepared statment handle and reset row count */
3452 if( pArg ){
3453 pArg->pStmt = pStmt;
3454 pArg->cnt = 0;
3455 }
3456
3457 /* echo the sql statement if echo on */
3458 if( pArg && ShellHasFlag(pArg, SHFLG_Echo) ){
3459 utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
3460 }
3461
3462 /* Show the EXPLAIN QUERY PLAN if .eqp is on */
drh39c5c4a2019-03-06 14:53:27 +00003463 if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){
drh2ce15c32017-07-11 13:34:40 +00003464 sqlite3_stmt *pExplain;
3465 char *zEQP;
drhada70452017-12-21 21:02:27 +00003466 int triggerEQP = 0;
drh2ce15c32017-07-11 13:34:40 +00003467 disable_debug_trace_modes();
drhada70452017-12-21 21:02:27 +00003468 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP);
3469 if( pArg->autoEQP>=AUTOEQP_trigger ){
3470 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0);
3471 }
drh2ce15c32017-07-11 13:34:40 +00003472 zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql);
3473 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
3474 if( rc==SQLITE_OK ){
3475 while( sqlite3_step(pExplain)==SQLITE_ROW ){
drh4b5345c2018-04-24 13:07:40 +00003476 const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3);
drhe2ca99c2018-05-02 00:33:43 +00003477 int iEqpId = sqlite3_column_int(pExplain, 0);
3478 int iParentId = sqlite3_column_int(pExplain, 1);
drh7e088a62020-05-02 00:01:39 +00003479 if( zEQPLine==0 ) zEQPLine = "";
drh4b5345c2018-04-24 13:07:40 +00003480 if( zEQPLine[0]=='-' ) eqp_render(pArg);
drhe2ca99c2018-05-02 00:33:43 +00003481 eqp_append(pArg, iEqpId, iParentId, zEQPLine);
drh2ce15c32017-07-11 13:34:40 +00003482 }
drh4b5345c2018-04-24 13:07:40 +00003483 eqp_render(pArg);
drh2ce15c32017-07-11 13:34:40 +00003484 }
3485 sqlite3_finalize(pExplain);
3486 sqlite3_free(zEQP);
drhada70452017-12-21 21:02:27 +00003487 if( pArg->autoEQP>=AUTOEQP_full ){
drh2ce15c32017-07-11 13:34:40 +00003488 /* Also do an EXPLAIN for ".eqp full" mode */
3489 zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql);
3490 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
3491 if( rc==SQLITE_OK ){
3492 pArg->cMode = MODE_Explain;
3493 explain_data_prepare(pArg, pExplain);
drha10b9992018-03-09 15:24:33 +00003494 exec_prepared_stmt(pArg, pExplain);
drh2ce15c32017-07-11 13:34:40 +00003495 explain_data_delete(pArg);
3496 }
3497 sqlite3_finalize(pExplain);
3498 sqlite3_free(zEQP);
3499 }
drh51efe092018-03-20 12:04:38 +00003500 if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
3501 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
3502 /* Reprepare pStmt before reactiving trace modes */
3503 sqlite3_finalize(pStmt);
3504 sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
drh3c49eaf2018-06-07 15:23:43 +00003505 if( pArg ) pArg->pStmt = pStmt;
drh51efe092018-03-20 12:04:38 +00003506 }
drh2ce15c32017-07-11 13:34:40 +00003507 restore_debug_trace_modes();
3508 }
3509
3510 if( pArg ){
3511 pArg->cMode = pArg->mode;
drh4b5345c2018-04-24 13:07:40 +00003512 if( pArg->autoExplain ){
drh39c5c4a2019-03-06 14:53:27 +00003513 if( sqlite3_stmt_isexplain(pStmt)==1 ){
drh4b5345c2018-04-24 13:07:40 +00003514 pArg->cMode = MODE_Explain;
3515 }
drh39c5c4a2019-03-06 14:53:27 +00003516 if( sqlite3_stmt_isexplain(pStmt)==2 ){
drh4b5345c2018-04-24 13:07:40 +00003517 pArg->cMode = MODE_EQP;
3518 }
drh2ce15c32017-07-11 13:34:40 +00003519 }
3520
3521 /* If the shell is currently in ".explain" mode, gather the extra
3522 ** data required to add indents to the output.*/
3523 if( pArg->cMode==MODE_Explain ){
3524 explain_data_prepare(pArg, pStmt);
3525 }
3526 }
3527
drh8b738d02019-02-25 18:43:54 +00003528 bind_prepared_stmt(pArg, pStmt);
drha10b9992018-03-09 15:24:33 +00003529 exec_prepared_stmt(pArg, pStmt);
drh2ce15c32017-07-11 13:34:40 +00003530 explain_data_delete(pArg);
drh4b5345c2018-04-24 13:07:40 +00003531 eqp_render(pArg);
drh2ce15c32017-07-11 13:34:40 +00003532
3533 /* print usage stats if stats on */
3534 if( pArg && pArg->statsOn ){
3535 display_stats(db, pArg, 0);
3536 }
3537
3538 /* print loop-counters if required */
3539 if( pArg && pArg->scanstatsOn ){
3540 display_scanstats(db, pArg);
3541 }
3542
3543 /* Finalize the statement just executed. If this fails, save a
3544 ** copy of the error message. Otherwise, set zSql to point to the
3545 ** next statement to execute. */
3546 rc2 = sqlite3_finalize(pStmt);
3547 if( rc!=SQLITE_NOMEM ) rc = rc2;
3548 if( rc==SQLITE_OK ){
3549 zSql = zLeftover;
3550 while( IsSpace(zSql[0]) ) zSql++;
3551 }else if( pzErrMsg ){
3552 *pzErrMsg = save_err_msg(db);
3553 }
3554
3555 /* clear saved stmt handle */
3556 if( pArg ){
3557 pArg->pStmt = NULL;
3558 }
3559 }
3560 } /* end while */
3561
3562 return rc;
3563}
3564
3565/*
3566** Release memory previously allocated by tableColumnList().
3567*/
3568static void freeColumnList(char **azCol){
3569 int i;
3570 for(i=1; azCol[i]; i++){
3571 sqlite3_free(azCol[i]);
3572 }
3573 /* azCol[0] is a static string */
3574 sqlite3_free(azCol);
3575}
3576
3577/*
3578** Return a list of pointers to strings which are the names of all
3579** columns in table zTab. The memory to hold the names is dynamically
3580** allocated and must be released by the caller using a subsequent call
3581** to freeColumnList().
3582**
3583** The azCol[0] entry is usually NULL. However, if zTab contains a rowid
3584** value that needs to be preserved, then azCol[0] is filled in with the
3585** name of the rowid column.
3586**
3587** The first regular column in the table is azCol[1]. The list is terminated
3588** by an entry with azCol[i]==0.
3589*/
3590static char **tableColumnList(ShellState *p, const char *zTab){
3591 char **azCol = 0;
3592 sqlite3_stmt *pStmt;
3593 char *zSql;
3594 int nCol = 0;
3595 int nAlloc = 0;
3596 int nPK = 0; /* Number of PRIMARY KEY columns seen */
3597 int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */
3598 int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid);
3599 int rc;
3600
3601 zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab);
3602 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3603 sqlite3_free(zSql);
3604 if( rc ) return 0;
3605 while( sqlite3_step(pStmt)==SQLITE_ROW ){
3606 if( nCol>=nAlloc-2 ){
3607 nAlloc = nAlloc*2 + nCol + 10;
3608 azCol = sqlite3_realloc(azCol, nAlloc*sizeof(azCol[0]));
drh4b5345c2018-04-24 13:07:40 +00003609 if( azCol==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00003610 }
3611 azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
3612 if( sqlite3_column_int(pStmt, 5) ){
3613 nPK++;
3614 if( nPK==1
3615 && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2),
3616 "INTEGER")==0
3617 ){
3618 isIPK = 1;
3619 }else{
3620 isIPK = 0;
3621 }
3622 }
3623 }
3624 sqlite3_finalize(pStmt);
drh4c6cddc2017-10-12 10:28:30 +00003625 if( azCol==0 ) return 0;
drh2ce15c32017-07-11 13:34:40 +00003626 azCol[0] = 0;
3627 azCol[nCol+1] = 0;
3628
3629 /* The decision of whether or not a rowid really needs to be preserved
3630 ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table
3631 ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve
3632 ** rowids on tables where the rowid is inaccessible because there are other
3633 ** columns in the table named "rowid", "_rowid_", and "oid".
3634 */
3635 if( preserveRowid && isIPK ){
3636 /* If a single PRIMARY KEY column with type INTEGER was seen, then it
3637 ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID
3638 ** table or a INTEGER PRIMARY KEY DESC column, neither of which are
3639 ** ROWID aliases. To distinguish these cases, check to see if
3640 ** there is a "pk" entry in "PRAGMA index_list". There will be
3641 ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID.
3642 */
3643 zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)"
3644 " WHERE origin='pk'", zTab);
3645 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
3646 sqlite3_free(zSql);
3647 if( rc ){
3648 freeColumnList(azCol);
3649 return 0;
3650 }
3651 rc = sqlite3_step(pStmt);
3652 sqlite3_finalize(pStmt);
3653 preserveRowid = rc==SQLITE_ROW;
3654 }
3655 if( preserveRowid ){
3656 /* Only preserve the rowid if we can find a name to use for the
3657 ** rowid */
3658 static char *azRowid[] = { "rowid", "_rowid_", "oid" };
3659 int i, j;
3660 for(j=0; j<3; j++){
3661 for(i=1; i<=nCol; i++){
3662 if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break;
3663 }
3664 if( i>nCol ){
3665 /* At this point, we know that azRowid[j] is not the name of any
3666 ** ordinary column in the table. Verify that azRowid[j] is a valid
3667 ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID
3668 ** tables will fail this last check */
3669 rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0);
3670 if( rc==SQLITE_OK ) azCol[0] = azRowid[j];
3671 break;
3672 }
3673 }
3674 }
3675 return azCol;
3676}
3677
3678/*
3679** Toggle the reverse_unordered_selects setting.
3680*/
3681static void toggleSelectOrder(sqlite3 *db){
3682 sqlite3_stmt *pStmt = 0;
3683 int iSetting = 0;
3684 char zStmt[100];
3685 sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0);
3686 if( sqlite3_step(pStmt)==SQLITE_ROW ){
3687 iSetting = sqlite3_column_int(pStmt, 0);
3688 }
3689 sqlite3_finalize(pStmt);
3690 sqlite3_snprintf(sizeof(zStmt), zStmt,
3691 "PRAGMA reverse_unordered_selects(%d)", !iSetting);
3692 sqlite3_exec(db, zStmt, 0, 0, 0);
3693}
3694
3695/*
3696** This is a different callback routine used for dumping the database.
3697** Each row received by this callback consists of a table name,
3698** the table type ("index" or "table") and SQL to create the table.
3699** This routine should print text sufficient to recreate the table.
3700*/
3701static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
3702 int rc;
3703 const char *zTable;
3704 const char *zType;
3705 const char *zSql;
3706 ShellState *p = (ShellState *)pArg;
3707
3708 UNUSED_PARAMETER(azNotUsed);
drhb3c45232017-08-28 14:33:27 +00003709 if( nArg!=3 || azArg==0 ) return 0;
drh2ce15c32017-07-11 13:34:40 +00003710 zTable = azArg[0];
3711 zType = azArg[1];
3712 zSql = azArg[2];
3713
3714 if( strcmp(zTable, "sqlite_sequence")==0 ){
3715 raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
3716 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 ){
drh067b92b2020-06-19 15:24:12 +00003717 raw_printf(p->out, "ANALYZE sqlite_schema;\n");
drh2ce15c32017-07-11 13:34:40 +00003718 }else if( strncmp(zTable, "sqlite_", 7)==0 ){
3719 return 0;
3720 }else if( strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
3721 char *zIns;
3722 if( !p->writableSchema ){
3723 raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
3724 p->writableSchema = 1;
3725 }
3726 zIns = sqlite3_mprintf(
drh067b92b2020-06-19 15:24:12 +00003727 "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)"
drh2ce15c32017-07-11 13:34:40 +00003728 "VALUES('table','%q','%q',0,'%q');",
3729 zTable, zTable, zSql);
3730 utf8_printf(p->out, "%s\n", zIns);
3731 sqlite3_free(zIns);
3732 return 0;
3733 }else{
3734 printSchemaLine(p->out, zSql, ";\n");
3735 }
3736
3737 if( strcmp(zType, "table")==0 ){
3738 ShellText sSelect;
3739 ShellText sTable;
3740 char **azCol;
3741 int i;
3742 char *savedDestTable;
3743 int savedMode;
3744
3745 azCol = tableColumnList(p, zTable);
3746 if( azCol==0 ){
3747 p->nErr++;
3748 return 0;
3749 }
3750
3751 /* Always quote the table name, even if it appears to be pure ascii,
3752 ** in case it is a keyword. Ex: INSERT INTO "table" ... */
3753 initText(&sTable);
3754 appendText(&sTable, zTable, quoteChar(zTable));
3755 /* If preserving the rowid, add a column list after the table name.
3756 ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)"
3757 ** instead of the usual "INSERT INTO tab VALUES(...)".
3758 */
3759 if( azCol[0] ){
3760 appendText(&sTable, "(", 0);
3761 appendText(&sTable, azCol[0], 0);
3762 for(i=1; azCol[i]; i++){
3763 appendText(&sTable, ",", 0);
3764 appendText(&sTable, azCol[i], quoteChar(azCol[i]));
3765 }
3766 appendText(&sTable, ")", 0);
3767 }
3768
3769 /* Build an appropriate SELECT statement */
3770 initText(&sSelect);
3771 appendText(&sSelect, "SELECT ", 0);
3772 if( azCol[0] ){
3773 appendText(&sSelect, azCol[0], 0);
3774 appendText(&sSelect, ",", 0);
3775 }
3776 for(i=1; azCol[i]; i++){
3777 appendText(&sSelect, azCol[i], quoteChar(azCol[i]));
3778 if( azCol[i+1] ){
3779 appendText(&sSelect, ",", 0);
3780 }
3781 }
3782 freeColumnList(azCol);
3783 appendText(&sSelect, " FROM ", 0);
3784 appendText(&sSelect, zTable, quoteChar(zTable));
3785
3786 savedDestTable = p->zDestTable;
3787 savedMode = p->mode;
3788 p->zDestTable = sTable.z;
3789 p->mode = p->cMode = MODE_Insert;
drha10b9992018-03-09 15:24:33 +00003790 rc = shell_exec(p, sSelect.z, 0);
drh2ce15c32017-07-11 13:34:40 +00003791 if( (rc&0xff)==SQLITE_CORRUPT ){
3792 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
3793 toggleSelectOrder(p->db);
drha10b9992018-03-09 15:24:33 +00003794 shell_exec(p, sSelect.z, 0);
drh2ce15c32017-07-11 13:34:40 +00003795 toggleSelectOrder(p->db);
3796 }
3797 p->zDestTable = savedDestTable;
3798 p->mode = savedMode;
3799 freeText(&sTable);
3800 freeText(&sSelect);
3801 if( rc ) p->nErr++;
3802 }
3803 return 0;
3804}
3805
3806/*
3807** Run zQuery. Use dump_callback() as the callback routine so that
3808** the contents of the query are output as SQL statements.
3809**
3810** If we get a SQLITE_CORRUPT error, rerun the query after appending
3811** "ORDER BY rowid DESC" to the end.
3812*/
3813static int run_schema_dump_query(
3814 ShellState *p,
3815 const char *zQuery
3816){
3817 int rc;
3818 char *zErr = 0;
3819 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
3820 if( rc==SQLITE_CORRUPT ){
3821 char *zQ2;
3822 int len = strlen30(zQuery);
3823 raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
3824 if( zErr ){
3825 utf8_printf(p->out, "/****** %s ******/\n", zErr);
3826 sqlite3_free(zErr);
3827 zErr = 0;
3828 }
3829 zQ2 = malloc( len+100 );
3830 if( zQ2==0 ) return rc;
3831 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
3832 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
3833 if( rc ){
3834 utf8_printf(p->out, "/****** ERROR: %s ******/\n", zErr);
3835 }else{
3836 rc = SQLITE_CORRUPT;
3837 }
3838 sqlite3_free(zErr);
3839 free(zQ2);
3840 }
3841 return rc;
3842}
3843
3844/*
drh98aa2ab2018-09-26 16:53:51 +00003845** Text of help messages.
3846**
3847** The help text for each individual command begins with a line that starts
3848** with ".". Subsequent lines are supplimental information.
3849**
3850** There must be two or more spaces between the end of the command and the
3851** start of the description of what that command does.
drh2ce15c32017-07-11 13:34:40 +00003852*/
drh98aa2ab2018-09-26 16:53:51 +00003853static const char *(azHelp[]) = {
drhe37c0e12018-01-06 19:19:50 +00003854#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
drh98aa2ab2018-09-26 16:53:51 +00003855 ".archive ... Manage SQL archives",
3856 " Each command must have exactly one of the following options:",
3857 " -c, --create Create a new archive",
drhe2754c12019-08-26 12:50:01 +00003858 " -u, --update Add or update files with changed mtime",
3859 " -i, --insert Like -u but always add even if unchanged",
drh98aa2ab2018-09-26 16:53:51 +00003860 " -t, --list List contents of archive",
3861 " -x, --extract Extract files from archive",
3862 " Optional arguments:",
3863 " -v, --verbose Print each filename as it is processed",
drhe2754c12019-08-26 12:50:01 +00003864 " -f FILE, --file FILE Use archive FILE (default is current db)",
3865 " -a FILE, --append FILE Open FILE using the apndvfs VFS",
3866 " -C DIR, --directory DIR Read/extract files from directory DIR",
drh98aa2ab2018-09-26 16:53:51 +00003867 " -n, --dryrun Show the SQL that would have occurred",
3868 " Examples:",
drhe2754c12019-08-26 12:50:01 +00003869 " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
3870 " .ar -tf ARCHIVE # List members of ARCHIVE",
3871 " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
drh98aa2ab2018-09-26 16:53:51 +00003872 " See also:",
3873 " http://sqlite.org/cli.html#sqlar_archive_support",
drhe37c0e12018-01-06 19:19:50 +00003874#endif
drh2ce15c32017-07-11 13:34:40 +00003875#ifndef SQLITE_OMIT_AUTHORIZATION
drh98aa2ab2018-09-26 16:53:51 +00003876 ".auth ON|OFF Show authorizer callbacks",
drh2ce15c32017-07-11 13:34:40 +00003877#endif
drh98aa2ab2018-09-26 16:53:51 +00003878 ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
3879 " --append Use the appendvfs",
drhe2754c12019-08-26 12:50:01 +00003880 " --async Write to FILE without journal and fsync()",
drh98aa2ab2018-09-26 16:53:51 +00003881 ".bail on|off Stop after hitting an error. Default OFF",
3882 ".binary on|off Turn binary output on or off. Default OFF",
3883 ".cd DIRECTORY Change the working directory to DIRECTORY",
3884 ".changes on|off Show number of rows changed by SQL",
3885 ".check GLOB Fail if output since .testcase does not match",
3886 ".clone NEWDB Clone data into NEWDB from the existing database",
3887 ".databases List names and files of attached databases",
3888 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options",
3889 ".dbinfo ?DB? Show status information about the database",
drh8e9297f2020-03-25 12:50:13 +00003890 ".dump ?TABLE? Render database content as SQL",
drheb7f2a02018-09-26 18:02:32 +00003891 " Options:",
3892 " --preserve-rowids Include ROWID values in the output",
3893 " --newlines Allow unescaped newline characters in output",
drhe551b512019-04-17 13:58:07 +00003894 " TABLE is a LIKE pattern for the tables to dump",
drh8e9297f2020-03-25 12:50:13 +00003895 " Additional LIKE patterns can be given in subsequent arguments",
drh98aa2ab2018-09-26 16:53:51 +00003896 ".echo on|off Turn command echo on or off",
drhb4e50392019-01-26 15:40:04 +00003897 ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN",
3898 " Other Modes:",
3899#ifdef SQLITE_DEBUG
3900 " test Show raw EXPLAIN QUERY PLAN output",
drhe2754c12019-08-26 12:50:01 +00003901 " trace Like \"full\" but enable \"PRAGMA vdbe_trace\"",
drhb4e50392019-01-26 15:40:04 +00003902#endif
3903 " trigger Like \"full\" but also show trigger bytecode",
drhe2754c12019-08-26 12:50:01 +00003904 ".excel Display the output of next command in spreadsheet",
drh7a431002020-04-18 14:12:00 +00003905 " --bom Put a UTF8 byte-order mark on intermediate file",
drheb7f2a02018-09-26 18:02:32 +00003906 ".exit ?CODE? Exit this program with return-code CODE",
drhe2754c12019-08-26 12:50:01 +00003907 ".expert EXPERIMENTAL. Suggest indexes for queries",
drh978256f2019-11-02 00:00:14 +00003908 ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
drhd985f722019-06-05 14:29:53 +00003909 ".filectrl CMD ... Run various sqlite3_file_control() operations",
drh541ef2c2020-04-20 16:21:30 +00003910 " --schema SCHEMA Use SCHEMA instead of \"main\"",
3911 " --help Show CMD details",
drh98aa2ab2018-09-26 16:53:51 +00003912 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
3913 ".headers on|off Turn display of headers on or off",
3914 ".help ?-all? ?PATTERN? Show help text for PATTERN",
3915 ".import FILE TABLE Import data from FILE into TABLE",
drhccb37812020-03-09 15:39:39 +00003916 " Options:",
3917 " --ascii Use \\037 and \\036 as column and row separators",
3918 " --csv Use , and \\n as column and row separators",
3919 " --skip N Skip the first N rows of input",
3920 " -v \"Verbose\" - increase auxiliary output",
3921 " Notes:",
3922 " * If TABLE does not exist, it is created. The first row of input",
3923 " determines the column names.",
3924 " * If neither --csv or --ascii are used, the input mode is derived",
3925 " from the \".mode\" output mode",
3926 " * If FILE begins with \"|\" then it is a command that generates the",
3927 " input text.",
drh2ce15c32017-07-11 13:34:40 +00003928#ifndef SQLITE_OMIT_TEST_CONTROL
drh98aa2ab2018-09-26 16:53:51 +00003929 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX",
drh2ce15c32017-07-11 13:34:40 +00003930#endif
drh98aa2ab2018-09-26 16:53:51 +00003931 ".indexes ?TABLE? Show names of indexes",
3932 " If TABLE is specified, only show indexes for",
3933 " tables matching TABLE using the LIKE operator.",
drh2ce15c32017-07-11 13:34:40 +00003934#ifdef SQLITE_ENABLE_IOTRACE
drh98aa2ab2018-09-26 16:53:51 +00003935 ".iotrace FILE Enable I/O diagnostic logging to FILE",
drh2ce15c32017-07-11 13:34:40 +00003936#endif
drh98aa2ab2018-09-26 16:53:51 +00003937 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT",
3938 ".lint OPTIONS Report potential schema issues.",
3939 " Options:",
3940 " fkey-indexes Find missing foreign key indexes",
drh2ce15c32017-07-11 13:34:40 +00003941#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh98aa2ab2018-09-26 16:53:51 +00003942 ".load FILE ?ENTRY? Load an extension library",
drh2ce15c32017-07-11 13:34:40 +00003943#endif
drh98aa2ab2018-09-26 16:53:51 +00003944 ".log FILE|off Turn logging on or off. FILE can be stderr/stdout",
3945 ".mode MODE ?TABLE? Set output mode",
3946 " MODE is one of:",
drh7da29a32020-05-29 19:17:20 +00003947 " ascii Columns/rows delimited by 0x1F and 0x1E",
drh0908e382020-06-04 18:05:39 +00003948 " box Tables using unicode box-drawing characters",
drh7da29a32020-05-29 19:17:20 +00003949 " csv Comma-separated values",
3950 " column Output in columns. (See .width)",
3951 " html HTML <table> code",
3952 " insert SQL insert statements for TABLE",
3953 " json Results in a JSON array",
3954 " line One value per line",
3955 " list Values delimited by \"|\"",
3956 " markdown Markdown table format",
3957 " quote Escape answers as for SQL",
3958 " table ASCII-art table",
3959 " tabs Tab-separated values",
3960 " tcl TCL list elements",
drh98aa2ab2018-09-26 16:53:51 +00003961 ".nullvalue STRING Use STRING in place of NULL values",
drh7a431002020-04-18 14:12:00 +00003962 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
drh98aa2ab2018-09-26 16:53:51 +00003963 " If FILE begins with '|' then open as a pipe",
drh7a431002020-04-18 14:12:00 +00003964 " --bom Put a UTF8 byte-order mark at the beginning",
3965 " -e Send output to the system text editor",
3966 " -x Send output as CSV to a spreadsheet (same as \".excel\")",
drh4a3a3eb2020-02-29 15:53:48 +00003967#ifdef SQLITE_DEBUG
drhc0605082020-06-05 00:54:27 +00003968 ".oom ?--repeat M? ?N? Simulate an OOM error on the N-th allocation",
drh4a3a3eb2020-02-29 15:53:48 +00003969#endif
drh98aa2ab2018-09-26 16:53:51 +00003970 ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
3971 " Options:",
drh60f34ae2018-10-30 13:19:49 +00003972 " --append Use appendvfs to append database to the end of FILE",
drha751f392018-10-30 15:31:22 +00003973#ifdef SQLITE_ENABLE_DESERIALIZE
drh60f34ae2018-10-30 13:19:49 +00003974 " --deserialize Load into memory useing sqlite3_deserialize()",
drhe2754c12019-08-26 12:50:01 +00003975 " --hexdb Load the output of \"dbtotxt\" as an in-memory db",
drh6ca64482019-01-22 16:06:20 +00003976 " --maxsize N Maximum size for --hexdb or --deserialized database",
drha751f392018-10-30 15:31:22 +00003977#endif
drh60f34ae2018-10-30 13:19:49 +00003978 " --new Initialize FILE to an empty database",
drh0933aad2019-11-18 17:46:38 +00003979 " --nofollow Do not follow symbolic links",
drh60f34ae2018-10-30 13:19:49 +00003980 " --readonly Open FILE readonly",
3981 " --zip FILE is a ZIP archive",
drh98aa2ab2018-09-26 16:53:51 +00003982 ".output ?FILE? Send output to FILE or stdout if FILE is omitted",
drh7a431002020-04-18 14:12:00 +00003983 " If FILE begins with '|' then open it as a pipe.",
3984 " Options:",
3985 " --bom Prefix output with a UTF8 byte-order mark",
3986 " -e Send output to the system text editor",
3987 " -x Send output as CSV to a spreadsheet",
drh9cb02642019-02-28 20:10:52 +00003988 ".parameter CMD ... Manage SQL parameter bindings",
3989 " clear Erase all bindings",
3990 " init Initialize the TEMP table that holds bindings",
3991 " list List the current parameter bindings",
3992 " set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE",
drhe2754c12019-08-26 12:50:01 +00003993 " PARAMETER should start with one of: $ : @ ?",
drh9cb02642019-02-28 20:10:52 +00003994 " unset PARAMETER Remove PARAMETER from the binding table",
drh98aa2ab2018-09-26 16:53:51 +00003995 ".print STRING... Print literal STRING",
drh569b1d92019-02-05 20:51:41 +00003996#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
drh3f83f592019-02-04 14:53:18 +00003997 ".progress N Invoke progress handler after every N opcodes",
3998 " --limit N Interrupt after N progress callbacks",
3999 " --once Do no more than one progress interrupt",
4000 " --quiet|-q No output except at interrupts",
4001 " --reset Reset the count for each input and interrupt",
drh569b1d92019-02-05 20:51:41 +00004002#endif
drh98aa2ab2018-09-26 16:53:51 +00004003 ".prompt MAIN CONTINUE Replace the standard prompts",
4004 ".quit Exit this program",
4005 ".read FILE Read input from FILE",
dan1b162162019-04-27 20:15:15 +00004006#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
dan42ebb012019-04-27 18:47:03 +00004007 ".recover Recover as much data as possible from corrupt db.",
drhe2754c12019-08-26 12:50:01 +00004008 " --freelist-corrupt Assume the freelist is corrupt",
4009 " --recovery-db NAME Store recovery metadata in database file NAME",
4010 " --lost-and-found TABLE Alternative name for the lost-and-found table",
dan8cce6b82019-09-14 16:44:51 +00004011 " --no-rowids Do not attempt to recover rowid values",
4012 " that are not also INTEGER PRIMARY KEYs",
dan1b162162019-04-27 20:15:15 +00004013#endif
drh98aa2ab2018-09-26 16:53:51 +00004014 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
4015 ".save FILE Write in-memory database into FILE",
4016 ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
4017 ".schema ?PATTERN? Show the CREATE statements matching PATTERN",
4018 " Options:",
4019 " --indent Try to pretty-print the schema",
drheb7f2a02018-09-26 18:02:32 +00004020 ".selftest ?OPTIONS? Run tests defined in the SELFTEST table",
4021 " Options:",
4022 " --init Create a new SELFTEST table",
4023 " -v Verbose output",
drh98aa2ab2018-09-26 16:53:51 +00004024 ".separator COL ?ROW? Change the column and row separators",
drh2ce15c32017-07-11 13:34:40 +00004025#if defined(SQLITE_ENABLE_SESSION)
drheb7f2a02018-09-26 18:02:32 +00004026 ".session ?NAME? CMD ... Create or control sessions",
4027 " Subcommands:",
4028 " attach TABLE Attach TABLE",
4029 " changeset FILE Write a changeset into FILE",
4030 " close Close one session",
4031 " enable ?BOOLEAN? Set or query the enable bit",
4032 " filter GLOB... Reject tables matching GLOBs",
4033 " indirect ?BOOLEAN? Mark or query the indirect status",
4034 " isempty Query whether the session is empty",
4035 " list List currently open session names",
4036 " open DB NAME Open a new session on DB",
4037 " patchset FILE Write a patchset into FILE",
4038 " If ?NAME? is omitted, the first defined session is used.",
drh2ce15c32017-07-11 13:34:40 +00004039#endif
drheb7f2a02018-09-26 18:02:32 +00004040 ".sha3sum ... Compute a SHA3 hash of database content",
4041 " Options:",
drh067b92b2020-06-19 15:24:12 +00004042 " --schema Also hash the sqlite_schema table",
drheb7f2a02018-09-26 18:02:32 +00004043 " --sha3-224 Use the sha3-224 algorithm",
drhe2754c12019-08-26 12:50:01 +00004044 " --sha3-256 Use the sha3-256 algorithm (default)",
drheb7f2a02018-09-26 18:02:32 +00004045 " --sha3-384 Use the sha3-384 algorithm",
4046 " --sha3-512 Use the sha3-512 algorithm",
4047 " Any other argument is a LIKE pattern for tables to hash",
drh04a28c32018-01-31 01:38:44 +00004048#ifndef SQLITE_NOHAVE_SYSTEM
drh98aa2ab2018-09-26 16:53:51 +00004049 ".shell CMD ARGS... Run CMD ARGS... in a system shell",
drh04a28c32018-01-31 01:38:44 +00004050#endif
drh98aa2ab2018-09-26 16:53:51 +00004051 ".show Show the current values for various settings",
4052 ".stats ?on|off? Show stats or turn stats on or off",
drh04a28c32018-01-31 01:38:44 +00004053#ifndef SQLITE_NOHAVE_SYSTEM
drh98aa2ab2018-09-26 16:53:51 +00004054 ".system CMD ARGS... Run CMD ARGS... in a system shell",
drh04a28c32018-01-31 01:38:44 +00004055#endif
drh98aa2ab2018-09-26 16:53:51 +00004056 ".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
4057 ".testcase NAME Begin redirecting output to 'testcase-out.txt'",
drhd985f722019-06-05 14:29:53 +00004058 ".testctrl CMD ... Run various sqlite3_test_control() operations",
4059 " Run \".testctrl\" with no arguments for details",
drh98aa2ab2018-09-26 16:53:51 +00004060 ".timeout MS Try opening locked tables for MS milliseconds",
4061 ".timer on|off Turn SQL timer on or off",
drh707821f2018-12-05 13:39:06 +00004062#ifndef SQLITE_OMIT_TRACE
4063 ".trace ?OPTIONS? Output each SQL statement as it is run",
4064 " FILE Send output to FILE",
4065 " stdout Send output to stdout",
4066 " stderr Send output to stderr",
4067 " off Disable tracing",
4068 " --expanded Expand query parameters",
4069#ifdef SQLITE_ENABLE_NORMALIZE
4070 " --normalized Normal the SQL statements",
4071#endif
4072 " --plain Show SQL as it is input",
4073 " --stmt Trace statement execution (SQLITE_TRACE_STMT)",
4074 " --profile Profile statements (SQLITE_TRACE_PROFILE)",
4075 " --row Trace each row (SQLITE_TRACE_ROW)",
4076 " --close Trace connection close (SQLITE_TRACE_CLOSE)",
4077#endif /* SQLITE_OMIT_TRACE */
drhcc5979d2019-08-16 22:58:29 +00004078#ifdef SQLITE_DEBUG
4079 ".unmodule NAME ... Unregister virtual table modules",
drh5df84282019-08-17 19:45:25 +00004080 " --allexcept Unregister everything except those named",
drhcc5979d2019-08-16 22:58:29 +00004081#endif
drh98aa2ab2018-09-26 16:53:51 +00004082 ".vfsinfo ?AUX? Information about the top-level VFS",
4083 ".vfslist List all available VFSes",
4084 ".vfsname ?AUX? Print the name of the VFS stack",
drh7da29a32020-05-29 19:17:20 +00004085 ".width NUM1 NUM2 ... Set minimum column widths for columnar output",
drh98aa2ab2018-09-26 16:53:51 +00004086 " Negative values right-justify",
4087};
4088
4089/*
4090** Output help text.
4091**
4092** zPattern describes the set of commands for which help text is provided.
4093** If zPattern is NULL, then show all commands, but only give a one-line
4094** description of each.
4095**
4096** Return the number of matches.
4097*/
4098static int showHelp(FILE *out, const char *zPattern){
drhe93f8262018-10-11 16:53:37 +00004099 int i = 0;
4100 int j = 0;
drh98aa2ab2018-09-26 16:53:51 +00004101 int n = 0;
4102 char *zPat;
drh488cddf2018-10-06 14:38:17 +00004103 if( zPattern==0
4104 || zPattern[0]=='0'
4105 || strcmp(zPattern,"-a")==0
4106 || strcmp(zPattern,"-all")==0
drh7a431002020-04-18 14:12:00 +00004107 || strcmp(zPattern,"--all")==0
drh488cddf2018-10-06 14:38:17 +00004108 ){
drh98aa2ab2018-09-26 16:53:51 +00004109 /* Show all commands, but only one line per command */
drh488cddf2018-10-06 14:38:17 +00004110 if( zPattern==0 ) zPattern = "";
drh98aa2ab2018-09-26 16:53:51 +00004111 for(i=0; i<ArraySize(azHelp); i++){
drh488cddf2018-10-06 14:38:17 +00004112 if( azHelp[i][0]=='.' || zPattern[0] ){
drh98aa2ab2018-09-26 16:53:51 +00004113 utf8_printf(out, "%s\n", azHelp[i]);
4114 n++;
4115 }
4116 }
4117 }else{
4118 /* Look for commands that for which zPattern is an exact prefix */
4119 zPat = sqlite3_mprintf(".%s*", zPattern);
4120 for(i=0; i<ArraySize(azHelp); i++){
4121 if( sqlite3_strglob(zPat, azHelp[i])==0 ){
4122 utf8_printf(out, "%s\n", azHelp[i]);
drheb7f2a02018-09-26 18:02:32 +00004123 j = i+1;
drh98aa2ab2018-09-26 16:53:51 +00004124 n++;
4125 }
4126 }
4127 sqlite3_free(zPat);
drheb7f2a02018-09-26 18:02:32 +00004128 if( n ){
4129 if( n==1 ){
4130 /* when zPattern is a prefix of exactly one command, then include the
4131 ** details of that command, which should begin at offset j */
4132 while( j<ArraySize(azHelp)-1 && azHelp[j][0]!='.' ){
4133 utf8_printf(out, "%s\n", azHelp[j]);
4134 j++;
4135 }
4136 }
4137 return n;
4138 }
4139 /* Look for commands that contain zPattern anywhere. Show the complete
4140 ** text of all commands that match. */
drh98aa2ab2018-09-26 16:53:51 +00004141 zPat = sqlite3_mprintf("%%%s%%", zPattern);
4142 for(i=0; i<ArraySize(azHelp); i++){
4143 if( azHelp[i][0]=='.' ) j = i;
4144 if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
4145 utf8_printf(out, "%s\n", azHelp[j]);
4146 while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]!='.' ){
4147 j++;
4148 utf8_printf(out, "%s\n", azHelp[j]);
4149 }
4150 i = j;
4151 n++;
4152 }
4153 }
4154 sqlite3_free(zPat);
4155 }
4156 return n;
4157}
drh2ce15c32017-07-11 13:34:40 +00004158
drh2ce15c32017-07-11 13:34:40 +00004159/* Forward reference */
drh60379d42018-12-13 18:30:01 +00004160static int process_input(ShellState *p);
drh2ce15c32017-07-11 13:34:40 +00004161
4162/*
4163** Read the content of file zName into memory obtained from sqlite3_malloc64()
4164** and return a pointer to the buffer. The caller is responsible for freeing
4165** the memory.
4166**
4167** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes
4168** read.
4169**
4170** For convenience, a nul-terminator byte is always appended to the data read
4171** from the file before the buffer is returned. This byte is not included in
4172** the final value of (*pnByte), if applicable.
4173**
4174** NULL is returned if any error is encountered. The final value of *pnByte
4175** is undefined in this case.
4176*/
4177static char *readFile(const char *zName, int *pnByte){
4178 FILE *in = fopen(zName, "rb");
4179 long nIn;
4180 size_t nRead;
4181 char *pBuf;
4182 if( in==0 ) return 0;
4183 fseek(in, 0, SEEK_END);
4184 nIn = ftell(in);
4185 rewind(in);
4186 pBuf = sqlite3_malloc64( nIn+1 );
drh1dbb1472018-10-11 10:37:24 +00004187 if( pBuf==0 ){ fclose(in); return 0; }
drh2ce15c32017-07-11 13:34:40 +00004188 nRead = fread(pBuf, nIn, 1, in);
4189 fclose(in);
4190 if( nRead!=1 ){
4191 sqlite3_free(pBuf);
4192 return 0;
4193 }
4194 pBuf[nIn] = 0;
4195 if( pnByte ) *pnByte = nIn;
4196 return pBuf;
4197}
4198
4199#if defined(SQLITE_ENABLE_SESSION)
4200/*
4201** Close a single OpenSession object and release all of its associated
4202** resources.
4203*/
4204static void session_close(OpenSession *pSession){
4205 int i;
4206 sqlite3session_delete(pSession->p);
4207 sqlite3_free(pSession->zName);
4208 for(i=0; i<pSession->nFilter; i++){
4209 sqlite3_free(pSession->azFilter[i]);
4210 }
4211 sqlite3_free(pSession->azFilter);
4212 memset(pSession, 0, sizeof(OpenSession));
4213}
4214#endif
4215
4216/*
4217** Close all OpenSession objects and release all associated resources.
4218*/
4219#if defined(SQLITE_ENABLE_SESSION)
4220static void session_close_all(ShellState *p){
4221 int i;
4222 for(i=0; i<p->nSession; i++){
4223 session_close(&p->aSession[i]);
4224 }
4225 p->nSession = 0;
4226}
4227#else
4228# define session_close_all(X)
4229#endif
4230
4231/*
4232** Implementation of the xFilter function for an open session. Omit
4233** any tables named by ".session filter" but let all other table through.
4234*/
4235#if defined(SQLITE_ENABLE_SESSION)
4236static int session_filter(void *pCtx, const char *zTab){
4237 OpenSession *pSession = (OpenSession*)pCtx;
4238 int i;
4239 for(i=0; i<pSession->nFilter; i++){
4240 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
4241 }
4242 return 1;
4243}
4244#endif
4245
4246/*
drh1fa6d9f2018-01-06 21:46:01 +00004247** Try to deduce the type of file for zName based on its content. Return
4248** one of the SHELL_OPEN_* constants.
drh1bf208c2018-03-09 21:54:01 +00004249**
4250** If the file does not exist or is empty but its name looks like a ZIP
4251** archive and the dfltZip flag is true, then assume it is a ZIP archive.
4252** Otherwise, assume an ordinary database regardless of the filename if
4253** the type cannot be determined from content.
drh1fa6d9f2018-01-06 21:46:01 +00004254*/
drhfc97c1c2018-05-14 00:41:12 +00004255int deduceDatabaseType(const char *zName, int dfltZip){
drh1fa6d9f2018-01-06 21:46:01 +00004256 FILE *f = fopen(zName, "rb");
4257 size_t n;
4258 int rc = SHELL_OPEN_UNSPEC;
4259 char zBuf[100];
drh1bf208c2018-03-09 21:54:01 +00004260 if( f==0 ){
drhbe4ccb22018-05-17 20:04:24 +00004261 if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
4262 return SHELL_OPEN_ZIPFILE;
4263 }else{
4264 return SHELL_OPEN_NORMAL;
4265 }
drh1bf208c2018-03-09 21:54:01 +00004266 }
drh2b3c4af2018-10-30 14:36:21 +00004267 n = fread(zBuf, 16, 1, f);
4268 if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){
4269 fclose(f);
4270 return SHELL_OPEN_NORMAL;
4271 }
drh1fa6d9f2018-01-06 21:46:01 +00004272 fseek(f, -25, SEEK_END);
4273 n = fread(zBuf, 25, 1, f);
4274 if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
4275 rc = SHELL_OPEN_APPENDVFS;
4276 }else{
4277 fseek(f, -22, SEEK_END);
4278 n = fread(zBuf, 22, 1, f);
4279 if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05
4280 && zBuf[3]==0x06 ){
4281 rc = SHELL_OPEN_ZIPFILE;
drh1bf208c2018-03-09 21:54:01 +00004282 }else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){
mistachkina3926f42018-05-14 12:23:04 +00004283 rc = SHELL_OPEN_ZIPFILE;
drh1fa6d9f2018-01-06 21:46:01 +00004284 }
4285 }
4286 fclose(f);
4287 return rc;
4288}
4289
drh33746482018-12-13 15:06:26 +00004290#ifdef SQLITE_ENABLE_DESERIALIZE
4291/*
4292** Reconstruct an in-memory database using the output from the "dbtotxt"
4293** program. Read content from the file in p->zDbFilename. If p->zDbFilename
4294** is 0, then read from standard input.
4295*/
4296static unsigned char *readHexDb(ShellState *p, int *pnData){
4297 unsigned char *a = 0;
drh2c8ee022018-12-13 18:59:30 +00004298 int nLine;
drh33746482018-12-13 15:06:26 +00004299 int n = 0;
4300 int pgsz = 0;
4301 int iOffset = 0;
4302 int j, k;
4303 int rc;
4304 FILE *in;
drh3ea557e2019-04-23 15:30:58 +00004305 unsigned int x[16];
drh2c8ee022018-12-13 18:59:30 +00004306 char zLine[1000];
drh33746482018-12-13 15:06:26 +00004307 if( p->zDbFilename ){
4308 in = fopen(p->zDbFilename, "r");
4309 if( in==0 ){
4310 utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename);
4311 return 0;
4312 }
drh2c8ee022018-12-13 18:59:30 +00004313 nLine = 0;
drh33746482018-12-13 15:06:26 +00004314 }else{
drh60379d42018-12-13 18:30:01 +00004315 in = p->in;
drh2c8ee022018-12-13 18:59:30 +00004316 nLine = p->lineno;
drh5bf46442019-05-03 02:41:36 +00004317 if( in==0 ) in = stdin;
drh33746482018-12-13 15:06:26 +00004318 }
4319 *pnData = 0;
drh2c8ee022018-12-13 18:59:30 +00004320 nLine++;
drh33746482018-12-13 15:06:26 +00004321 if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
4322 rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
4323 if( rc!=2 ) goto readHexDb_error;
drh68feae52019-05-09 11:18:41 +00004324 if( n<0 ) goto readHexDb_error;
drh09ea1252019-07-17 15:05:16 +00004325 if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error;
4326 n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */
drh68feae52019-05-09 11:18:41 +00004327 a = sqlite3_malloc( n ? n : 1 );
drh33746482018-12-13 15:06:26 +00004328 if( a==0 ){
4329 utf8_printf(stderr, "Out of memory!\n");
4330 goto readHexDb_error;
4331 }
4332 memset(a, 0, n);
4333 if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
4334 utf8_printf(stderr, "invalid pagesize\n");
4335 goto readHexDb_error;
4336 }
drh2c8ee022018-12-13 18:59:30 +00004337 for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){
drh33746482018-12-13 15:06:26 +00004338 rc = sscanf(zLine, "| page %d offset %d", &j, &k);
4339 if( rc==2 ){
4340 iOffset = k;
4341 continue;
4342 }
4343 if( strncmp(zLine, "| end ", 6)==0 ){
4344 break;
4345 }
drh3ea557e2019-04-23 15:30:58 +00004346 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 +00004347 &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
4348 &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
4349 if( rc==17 ){
4350 k = iOffset+j;
drhf354e772018-12-13 22:58:52 +00004351 if( k+16<=n ){
drh3ea557e2019-04-23 15:30:58 +00004352 int ii;
4353 for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
drh33746482018-12-13 15:06:26 +00004354 }
drh33746482018-12-13 15:06:26 +00004355 }
4356 }
4357 *pnData = n;
drh2c8ee022018-12-13 18:59:30 +00004358 if( in!=p->in ){
4359 fclose(in);
4360 }else{
4361 p->lineno = nLine;
4362 }
drh33746482018-12-13 15:06:26 +00004363 return a;
4364
4365readHexDb_error:
drh68feae52019-05-09 11:18:41 +00004366 if( in!=p->in ){
drh33746482018-12-13 15:06:26 +00004367 fclose(in);
4368 }else{
drh60379d42018-12-13 18:30:01 +00004369 while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
drh2c8ee022018-12-13 18:59:30 +00004370 nLine++;
drh33746482018-12-13 15:06:26 +00004371 if(strncmp(zLine, "| end ", 6)==0 ) break;
4372 }
drh2c8ee022018-12-13 18:59:30 +00004373 p->lineno = nLine;
drh33746482018-12-13 15:06:26 +00004374 }
4375 sqlite3_free(a);
4376 utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine);
4377 return 0;
4378}
4379#endif /* SQLITE_ENABLE_DESERIALIZE */
4380
danb1825882019-04-23 20:48:32 +00004381/*
dan9c014f82019-04-25 19:23:15 +00004382** Scalar function "shell_int32". The first argument to this function
4383** must be a blob. The second a non-negative integer. This function
4384** reads and returns a 32-bit big-endian integer from byte
4385** offset (4*<arg2>) of the blob.
4386*/
4387static void shellInt32(
4388 sqlite3_context *context,
4389 int argc,
4390 sqlite3_value **argv
4391){
4392 const unsigned char *pBlob;
4393 int nBlob;
4394 int iInt;
drh9546c762019-05-10 17:50:33 +00004395
4396 UNUSED_PARAMETER(argc);
dan9c014f82019-04-25 19:23:15 +00004397 nBlob = sqlite3_value_bytes(argv[0]);
4398 pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]);
4399 iInt = sqlite3_value_int(argv[1]);
4400
4401 if( iInt>=0 && (iInt+1)*4<=nBlob ){
4402 const unsigned char *a = &pBlob[iInt*4];
4403 sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24)
4404 + ((sqlite3_int64)a[1]<<16)
4405 + ((sqlite3_int64)a[2]<< 8)
4406 + ((sqlite3_int64)a[3]<< 0);
4407 sqlite3_result_int64(context, iVal);
4408 }
4409}
4410
4411/*
drha2de66c2019-08-06 20:26:17 +00004412** Scalar function "shell_idquote(X)" returns string X quoted as an identifier,
4413** using "..." with internal double-quote characters doubled.
4414*/
4415static void shellIdQuote(
4416 sqlite3_context *context,
4417 int argc,
4418 sqlite3_value **argv
4419){
4420 const char *zName = (const char*)sqlite3_value_text(argv[0]);
drh51755a72019-08-08 19:40:29 +00004421 UNUSED_PARAMETER(argc);
drha2de66c2019-08-06 20:26:17 +00004422 if( zName ){
4423 char *z = sqlite3_mprintf("\"%w\"", zName);
4424 sqlite3_result_text(context, z, -1, sqlite3_free);
4425 }
4426}
4427
4428/*
drhddcfe922020-09-15 12:29:35 +00004429** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X.
4430*/
4431static void shellUSleepFunc(
4432 sqlite3_context *context,
4433 int argc,
4434 sqlite3_value **argv
4435){
4436 int sleep = sqlite3_value_int(argv[0]);
4437 sqlite3_sleep(sleep/1000);
4438 sqlite3_result_int(context, sleep);
4439}
4440
4441/*
danb1825882019-04-23 20:48:32 +00004442** Scalar function "shell_escape_crnl" used by the .recover command.
4443** The argument passed to this function is the output of built-in
4444** function quote(). If the first character of the input is "'",
4445** indicating that the value passed to quote() was a text value,
4446** then this function searches the input for "\n" and "\r" characters
4447** and adds a wrapper similar to the following:
4448**
4449** replace(replace(<input>, '\n', char(10), '\r', char(13));
4450**
4451** Or, if the first character of the input is not "'", then a copy
4452** of the input is returned.
4453*/
4454static void shellEscapeCrnl(
4455 sqlite3_context *context,
4456 int argc,
4457 sqlite3_value **argv
4458){
4459 const char *zText = (const char*)sqlite3_value_text(argv[0]);
drh9546c762019-05-10 17:50:33 +00004460 UNUSED_PARAMETER(argc);
danb1825882019-04-23 20:48:32 +00004461 if( zText[0]=='\'' ){
4462 int nText = sqlite3_value_bytes(argv[0]);
4463 int i;
4464 char zBuf1[20];
4465 char zBuf2[20];
4466 const char *zNL = 0;
4467 const char *zCR = 0;
4468 int nCR = 0;
4469 int nNL = 0;
4470
4471 for(i=0; zText[i]; i++){
4472 if( zNL==0 && zText[i]=='\n' ){
4473 zNL = unused_string(zText, "\\n", "\\012", zBuf1);
4474 nNL = (int)strlen(zNL);
4475 }
4476 if( zCR==0 && zText[i]=='\r' ){
4477 zCR = unused_string(zText, "\\r", "\\015", zBuf2);
4478 nCR = (int)strlen(zCR);
4479 }
4480 }
4481
4482 if( zNL || zCR ){
4483 int iOut = 0;
4484 i64 nMax = (nNL > nCR) ? nNL : nCR;
dan51f5ffa2019-04-29 11:41:46 +00004485 i64 nAlloc = nMax * nText + (nMax+64)*2;
danb1825882019-04-23 20:48:32 +00004486 char *zOut = (char*)sqlite3_malloc64(nAlloc);
4487 if( zOut==0 ){
4488 sqlite3_result_error_nomem(context);
4489 return;
4490 }
4491
4492 if( zNL && zCR ){
4493 memcpy(&zOut[iOut], "replace(replace(", 16);
4494 iOut += 16;
4495 }else{
4496 memcpy(&zOut[iOut], "replace(", 8);
4497 iOut += 8;
4498 }
4499 for(i=0; zText[i]; i++){
4500 if( zText[i]=='\n' ){
4501 memcpy(&zOut[iOut], zNL, nNL);
4502 iOut += nNL;
4503 }else if( zText[i]=='\r' ){
4504 memcpy(&zOut[iOut], zCR, nCR);
4505 iOut += nCR;
4506 }else{
4507 zOut[iOut] = zText[i];
4508 iOut++;
4509 }
4510 }
4511
4512 if( zNL ){
4513 memcpy(&zOut[iOut], ",'", 2); iOut += 2;
4514 memcpy(&zOut[iOut], zNL, nNL); iOut += nNL;
4515 memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12;
4516 }
4517 if( zCR ){
4518 memcpy(&zOut[iOut], ",'", 2); iOut += 2;
4519 memcpy(&zOut[iOut], zCR, nCR); iOut += nCR;
4520 memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12;
4521 }
4522
4523 sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT);
4524 sqlite3_free(zOut);
4525 return;
4526 }
4527 }
4528
4529 sqlite3_result_value(context, argv[0]);
4530}
4531
drhbe4ccb22018-05-17 20:04:24 +00004532/* Flags for open_db().
4533**
4534** The default behavior of open_db() is to exit(1) if the database fails to
4535** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
4536** but still returns without calling exit.
4537**
4538** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a
4539** ZIP archive if the file does not exist or is empty and its name matches
4540** the *.zip pattern.
4541*/
4542#define OPEN_DB_KEEPALIVE 0x001 /* Return after error if true */
4543#define OPEN_DB_ZIPFILE 0x002 /* Open as ZIP if name matches *.zip */
4544
drh1fa6d9f2018-01-06 21:46:01 +00004545/*
drh2ce15c32017-07-11 13:34:40 +00004546** Make sure the database is open. If it is not, then open it. If
4547** the database fails to open, print an error message and exit.
4548*/
drhbe4ccb22018-05-17 20:04:24 +00004549static void open_db(ShellState *p, int openFlags){
drh2ce15c32017-07-11 13:34:40 +00004550 if( p->db==0 ){
drhf2072d12018-05-11 15:10:11 +00004551 if( p->openMode==SHELL_OPEN_UNSPEC ){
4552 if( p->zDbFilename==0 || p->zDbFilename[0]==0 ){
4553 p->openMode = SHELL_OPEN_NORMAL;
drhbe4ccb22018-05-17 20:04:24 +00004554 }else{
4555 p->openMode = (u8)deduceDatabaseType(p->zDbFilename,
4556 (openFlags & OPEN_DB_ZIPFILE)!=0);
drhf2072d12018-05-11 15:10:11 +00004557 }
drh1fa6d9f2018-01-06 21:46:01 +00004558 }
4559 switch( p->openMode ){
4560 case SHELL_OPEN_APPENDVFS: {
4561 sqlite3_open_v2(p->zDbFilename, &p->db,
drh0933aad2019-11-18 17:46:38 +00004562 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, "apndvfs");
drh1fa6d9f2018-01-06 21:46:01 +00004563 break;
4564 }
drh33746482018-12-13 15:06:26 +00004565 case SHELL_OPEN_HEXDB:
drh60f34ae2018-10-30 13:19:49 +00004566 case SHELL_OPEN_DESERIALIZE: {
4567 sqlite3_open(0, &p->db);
4568 break;
4569 }
drh1fa6d9f2018-01-06 21:46:01 +00004570 case SHELL_OPEN_ZIPFILE: {
4571 sqlite3_open(":memory:", &p->db);
4572 break;
4573 }
drhee269a62018-02-14 23:27:43 +00004574 case SHELL_OPEN_READONLY: {
drh0933aad2019-11-18 17:46:38 +00004575 sqlite3_open_v2(p->zDbFilename, &p->db,
4576 SQLITE_OPEN_READONLY|p->openFlags, 0);
drhee269a62018-02-14 23:27:43 +00004577 break;
4578 }
drh1fa6d9f2018-01-06 21:46:01 +00004579 case SHELL_OPEN_UNSPEC:
4580 case SHELL_OPEN_NORMAL: {
drh0933aad2019-11-18 17:46:38 +00004581 sqlite3_open_v2(p->zDbFilename, &p->db,
4582 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
drh1fa6d9f2018-01-06 21:46:01 +00004583 break;
4584 }
4585 }
drh2ce15c32017-07-11 13:34:40 +00004586 globalDb = p->db;
4587 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
4588 utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
4589 p->zDbFilename, sqlite3_errmsg(p->db));
drhf25cc4f2019-01-04 14:29:21 +00004590 if( openFlags & OPEN_DB_KEEPALIVE ){
4591 sqlite3_open(":memory:", &p->db);
4592 return;
4593 }
drh2ce15c32017-07-11 13:34:40 +00004594 exit(1);
4595 }
4596#ifndef SQLITE_OMIT_LOAD_EXTENSION
4597 sqlite3_enable_load_extension(p->db, 1);
4598#endif
4599 sqlite3_fileio_init(p->db, 0, 0);
4600 sqlite3_shathree_init(p->db, 0, 0);
drh56eb09b2017-07-11 13:59:07 +00004601 sqlite3_completion_init(p->db, 0, 0);
drhf05dd032020-04-14 15:53:58 +00004602 sqlite3_uint_init(p->db, 0, 0);
drhbeb9def2020-06-22 19:12:23 +00004603 sqlite3_decimal_init(p->db, 0, 0);
drh8cda77d2020-06-24 15:06:29 +00004604 sqlite3_ieee_init(p->db, 0, 0);
mistachkin72c38d82020-08-28 18:47:39 +00004605 sqlite3_series_init(p->db, 0, 0);
dan1b162162019-04-27 20:15:15 +00004606#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
dan68cb86e2019-04-20 20:57:28 +00004607 sqlite3_dbdata_init(p->db, 0, 0);
dan1b162162019-04-27 20:15:15 +00004608#endif
dan72afc3c2017-12-05 18:32:40 +00004609#ifdef SQLITE_HAVE_ZLIB
dan9ebfaad2017-12-26 20:39:58 +00004610 sqlite3_zipfile_init(p->db, 0, 0);
dand1b51d42017-12-16 19:11:26 +00004611 sqlite3_sqlar_init(p->db, 0, 0);
dan72afc3c2017-12-05 18:32:40 +00004612#endif
drhceba7922018-01-01 21:28:25 +00004613 sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
drh2ce15c32017-07-11 13:34:40 +00004614 shellAddSchemaName, 0, 0);
drh667a2a22018-01-02 00:04:37 +00004615 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
4616 shellModuleSchema, 0, 0);
drh634c70f2018-01-10 16:50:18 +00004617 sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
4618 shellPutsFunc, 0, 0);
danb1825882019-04-23 20:48:32 +00004619 sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0,
4620 shellEscapeCrnl, 0, 0);
dan9c014f82019-04-25 19:23:15 +00004621 sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0,
4622 shellInt32, 0, 0);
drha2de66c2019-08-06 20:26:17 +00004623 sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,
4624 shellIdQuote, 0, 0);
drhddcfe922020-09-15 12:29:35 +00004625 sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0,
4626 shellUSleepFunc, 0, 0);
drh04a28c32018-01-31 01:38:44 +00004627#ifndef SQLITE_NOHAVE_SYSTEM
drh97913132018-01-11 00:04:00 +00004628 sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
4629 editFunc, 0, 0);
4630 sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
4631 editFunc, 0, 0);
drh04a28c32018-01-31 01:38:44 +00004632#endif
drh1fa6d9f2018-01-06 21:46:01 +00004633 if( p->openMode==SHELL_OPEN_ZIPFILE ){
4634 char *zSql = sqlite3_mprintf(
4635 "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
4636 sqlite3_exec(p->db, zSql, 0, 0, 0);
4637 sqlite3_free(zSql);
drha751f392018-10-30 15:31:22 +00004638 }
4639#ifdef SQLITE_ENABLE_DESERIALIZE
drh33746482018-12-13 15:06:26 +00004640 else
4641 if( p->openMode==SHELL_OPEN_DESERIALIZE || p->openMode==SHELL_OPEN_HEXDB ){
mistachkin99490932018-12-17 22:19:57 +00004642 int rc;
drh60f34ae2018-10-30 13:19:49 +00004643 int nData = 0;
drh33746482018-12-13 15:06:26 +00004644 unsigned char *aData;
4645 if( p->openMode==SHELL_OPEN_DESERIALIZE ){
4646 aData = (unsigned char*)readFile(p->zDbFilename, &nData);
4647 }else{
4648 aData = readHexDb(p, &nData);
4649 if( aData==0 ){
drh33746482018-12-13 15:06:26 +00004650 return;
4651 }
4652 }
mistachkin99490932018-12-17 22:19:57 +00004653 rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
drh60f34ae2018-10-30 13:19:49 +00004654 SQLITE_DESERIALIZE_RESIZEABLE |
4655 SQLITE_DESERIALIZE_FREEONCLOSE);
4656 if( rc ){
4657 utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
4658 }
drh6ca64482019-01-22 16:06:20 +00004659 if( p->szMax>0 ){
4660 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax);
4661 }
drh1fa6d9f2018-01-06 21:46:01 +00004662 }
drha751f392018-10-30 15:31:22 +00004663#endif
drh2ce15c32017-07-11 13:34:40 +00004664 }
4665}
4666
drh9e804032018-05-18 17:11:50 +00004667/*
4668** Attempt to close the databaes connection. Report errors.
4669*/
4670void close_db(sqlite3 *db){
4671 int rc = sqlite3_close(db);
4672 if( rc ){
4673 utf8_printf(stderr, "Error: sqlite3_close() returns %d: %s\n",
4674 rc, sqlite3_errmsg(db));
4675 }
4676}
4677
drh56eb09b2017-07-11 13:59:07 +00004678#if HAVE_READLINE || HAVE_EDITLINE
4679/*
4680** Readline completion callbacks
4681*/
4682static char *readline_completion_generator(const char *text, int state){
4683 static sqlite3_stmt *pStmt = 0;
4684 char *zRet;
4685 if( state==0 ){
4686 char *zSql;
drh56eb09b2017-07-11 13:59:07 +00004687 sqlite3_finalize(pStmt);
4688 zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
4689 " FROM completion(%Q) ORDER BY 1", text);
4690 sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
4691 sqlite3_free(zSql);
4692 }
4693 if( sqlite3_step(pStmt)==SQLITE_ROW ){
drh968d8712017-07-14 00:28:28 +00004694 zRet = strdup((const char*)sqlite3_column_text(pStmt, 0));
drh56eb09b2017-07-11 13:59:07 +00004695 }else{
4696 sqlite3_finalize(pStmt);
4697 pStmt = 0;
4698 zRet = 0;
4699 }
4700 return zRet;
4701}
4702static char **readline_completion(const char *zText, int iStart, int iEnd){
4703 rl_attempted_completion_over = 1;
4704 return rl_completion_matches(zText, readline_completion_generator);
4705}
4706
4707#elif HAVE_LINENOISE
4708/*
4709** Linenoise completion callback
4710*/
4711static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
drhaf2770f2018-01-05 14:55:43 +00004712 int nLine = strlen30(zLine);
drh56eb09b2017-07-11 13:59:07 +00004713 int i, iStart;
4714 sqlite3_stmt *pStmt = 0;
4715 char *zSql;
4716 char zBuf[1000];
4717
4718 if( nLine>sizeof(zBuf)-30 ) return;
drh1615c372018-05-12 23:56:22 +00004719 if( zLine[0]=='.' || zLine[0]=='#') return;
drh56eb09b2017-07-11 13:59:07 +00004720 for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
4721 if( i==nLine-1 ) return;
4722 iStart = i+1;
4723 memcpy(zBuf, zLine, iStart);
4724 zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
4725 " FROM completion(%Q,%Q) ORDER BY 1",
4726 &zLine[iStart], zLine);
4727 sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0);
4728 sqlite3_free(zSql);
4729 sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */
4730 while( sqlite3_step(pStmt)==SQLITE_ROW ){
4731 const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0);
4732 int nCompletion = sqlite3_column_bytes(pStmt, 0);
4733 if( iStart+nCompletion < sizeof(zBuf)-1 ){
4734 memcpy(zBuf+iStart, zCompletion, nCompletion+1);
4735 linenoiseAddCompletion(lc, zBuf);
4736 }
4737 }
4738 sqlite3_finalize(pStmt);
4739}
4740#endif
4741
drh2ce15c32017-07-11 13:34:40 +00004742/*
4743** Do C-language style dequoting.
4744**
4745** \a -> alarm
4746** \b -> backspace
4747** \t -> tab
4748** \n -> newline
4749** \v -> vertical tab
4750** \f -> form feed
4751** \r -> carriage return
4752** \s -> space
4753** \" -> "
4754** \' -> '
4755** \\ -> backslash
4756** \NNN -> ascii character NNN in octal
4757*/
4758static void resolve_backslashes(char *z){
4759 int i, j;
4760 char c;
4761 while( *z && *z!='\\' ) z++;
4762 for(i=j=0; (c = z[i])!=0; i++, j++){
4763 if( c=='\\' && z[i+1]!=0 ){
4764 c = z[++i];
4765 if( c=='a' ){
4766 c = '\a';
4767 }else if( c=='b' ){
4768 c = '\b';
4769 }else if( c=='t' ){
4770 c = '\t';
4771 }else if( c=='n' ){
4772 c = '\n';
4773 }else if( c=='v' ){
4774 c = '\v';
4775 }else if( c=='f' ){
4776 c = '\f';
4777 }else if( c=='r' ){
4778 c = '\r';
4779 }else if( c=='"' ){
4780 c = '"';
4781 }else if( c=='\'' ){
4782 c = '\'';
4783 }else if( c=='\\' ){
4784 c = '\\';
4785 }else if( c>='0' && c<='7' ){
4786 c -= '0';
4787 if( z[i+1]>='0' && z[i+1]<='7' ){
4788 i++;
4789 c = (c<<3) + z[i] - '0';
4790 if( z[i+1]>='0' && z[i+1]<='7' ){
4791 i++;
4792 c = (c<<3) + z[i] - '0';
4793 }
4794 }
4795 }
4796 }
4797 z[j] = c;
4798 }
4799 if( j<i ) z[j] = 0;
4800}
4801
4802/*
drh2ce15c32017-07-11 13:34:40 +00004803** Interpret zArg as either an integer or a boolean value. Return 1 or 0
4804** for TRUE and FALSE. Return the integer value if appropriate.
4805*/
4806static int booleanValue(const char *zArg){
4807 int i;
4808 if( zArg[0]=='0' && zArg[1]=='x' ){
4809 for(i=2; hexDigitValue(zArg[i])>=0; i++){}
4810 }else{
4811 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
4812 }
4813 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
4814 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
4815 return 1;
4816 }
4817 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
4818 return 0;
4819 }
4820 utf8_printf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
4821 zArg);
4822 return 0;
4823}
4824
4825/*
4826** Set or clear a shell flag according to a boolean value.
4827*/
4828static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){
4829 if( booleanValue(zArg) ){
4830 ShellSetFlag(p, mFlag);
4831 }else{
4832 ShellClearFlag(p, mFlag);
4833 }
4834}
4835
4836/*
4837** Close an output file, assuming it is not stderr or stdout
4838*/
4839static void output_file_close(FILE *f){
4840 if( f && f!=stdout && f!=stderr ) fclose(f);
4841}
4842
4843/*
4844** Try to open an output file. The names "stdout" and "stderr" are
4845** recognized and do the right thing. NULL is returned if the output
4846** filename is "off".
4847*/
drha92a01a2018-01-10 22:15:37 +00004848static FILE *output_file_open(const char *zFile, int bTextMode){
drh2ce15c32017-07-11 13:34:40 +00004849 FILE *f;
4850 if( strcmp(zFile,"stdout")==0 ){
4851 f = stdout;
4852 }else if( strcmp(zFile, "stderr")==0 ){
4853 f = stderr;
4854 }else if( strcmp(zFile, "off")==0 ){
4855 f = 0;
4856 }else{
drha92a01a2018-01-10 22:15:37 +00004857 f = fopen(zFile, bTextMode ? "w" : "wb");
drh2ce15c32017-07-11 13:34:40 +00004858 if( f==0 ){
4859 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
4860 }
4861 }
4862 return f;
4863}
4864
drh707821f2018-12-05 13:39:06 +00004865#ifndef SQLITE_OMIT_TRACE
drh2ce15c32017-07-11 13:34:40 +00004866/*
4867** A routine for handling output from sqlite3_trace().
4868*/
4869static int sql_trace_callback(
drh707821f2018-12-05 13:39:06 +00004870 unsigned mType, /* The trace type */
4871 void *pArg, /* The ShellState pointer */
4872 void *pP, /* Usually a pointer to sqlite_stmt */
4873 void *pX /* Auxiliary output */
drh2ce15c32017-07-11 13:34:40 +00004874){
drh707821f2018-12-05 13:39:06 +00004875 ShellState *p = (ShellState*)pArg;
4876 sqlite3_stmt *pStmt;
4877 const char *zSql;
4878 int nSql;
4879 if( p->traceOut==0 ) return 0;
4880 if( mType==SQLITE_TRACE_CLOSE ){
4881 utf8_printf(p->traceOut, "-- closing database connection\n");
4882 return 0;
4883 }
4884 if( mType!=SQLITE_TRACE_ROW && ((const char*)pX)[0]=='-' ){
4885 zSql = (const char*)pX;
4886 }else{
4887 pStmt = (sqlite3_stmt*)pP;
4888 switch( p->eTraceType ){
4889 case SHELL_TRACE_EXPANDED: {
4890 zSql = sqlite3_expanded_sql(pStmt);
4891 break;
4892 }
4893#ifdef SQLITE_ENABLE_NORMALIZE
4894 case SHELL_TRACE_NORMALIZED: {
4895 zSql = sqlite3_normalized_sql(pStmt);
4896 break;
4897 }
4898#endif
4899 default: {
4900 zSql = sqlite3_sql(pStmt);
4901 break;
4902 }
4903 }
4904 }
4905 if( zSql==0 ) return 0;
4906 nSql = strlen30(zSql);
4907 while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; }
4908 switch( mType ){
4909 case SQLITE_TRACE_ROW:
4910 case SQLITE_TRACE_STMT: {
4911 utf8_printf(p->traceOut, "%.*s;\n", nSql, zSql);
4912 break;
4913 }
4914 case SQLITE_TRACE_PROFILE: {
4915 sqlite3_int64 nNanosec = *(sqlite3_int64*)pX;
4916 utf8_printf(p->traceOut, "%.*s; -- %lld ns\n", nSql, zSql, nNanosec);
4917 break;
4918 }
drh2ce15c32017-07-11 13:34:40 +00004919 }
4920 return 0;
4921}
4922#endif
drh2ce15c32017-07-11 13:34:40 +00004923
4924/*
4925** A no-op routine that runs with the ".breakpoint" doc-command. This is
4926** a useful spot to set a debugger breakpoint.
4927*/
4928static void test_breakpoint(void){
4929 static int nCall = 0;
4930 nCall++;
4931}
4932
4933/*
4934** An object used to read a CSV and other files for import.
4935*/
4936typedef struct ImportCtx ImportCtx;
4937struct ImportCtx {
4938 const char *zFile; /* Name of the input file */
4939 FILE *in; /* Read the CSV text from this input stream */
drh97767842020-05-29 19:39:35 +00004940 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close in */
drh2ce15c32017-07-11 13:34:40 +00004941 char *z; /* Accumulated text for a field */
4942 int n; /* Number of bytes in z */
4943 int nAlloc; /* Space allocated for z[] */
4944 int nLine; /* Current line number */
drhccb37812020-03-09 15:39:39 +00004945 int nRow; /* Number of rows imported */
4946 int nErr; /* Number of errors encountered */
drh2ce15c32017-07-11 13:34:40 +00004947 int bNotFirst; /* True if one or more bytes already read */
4948 int cTerm; /* Character that terminated the most recent field */
4949 int cColSep; /* The column separator character. (Usually ",") */
4950 int cRowSep; /* The row separator character. (Usually "\n") */
4951};
4952
drh97767842020-05-29 19:39:35 +00004953/* Clean up resourced used by an ImportCtx */
4954static void import_cleanup(ImportCtx *p){
drh42c2a042020-05-29 20:16:19 +00004955 if( p->in!=0 && p->xCloser!=0 ){
drh97767842020-05-29 19:39:35 +00004956 p->xCloser(p->in);
4957 p->in = 0;
4958 }
4959 sqlite3_free(p->z);
4960 p->z = 0;
4961}
4962
drh2ce15c32017-07-11 13:34:40 +00004963/* Append a single byte to z[] */
4964static void import_append_char(ImportCtx *p, int c){
4965 if( p->n+1>=p->nAlloc ){
4966 p->nAlloc += p->nAlloc + 100;
4967 p->z = sqlite3_realloc64(p->z, p->nAlloc);
drh4b5345c2018-04-24 13:07:40 +00004968 if( p->z==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00004969 }
4970 p->z[p->n++] = (char)c;
4971}
4972
4973/* Read a single field of CSV text. Compatible with rfc4180 and extended
4974** with the option of having a separator other than ",".
4975**
4976** + Input comes from p->in.
4977** + Store results in p->z of length p->n. Space to hold p->z comes
4978** from sqlite3_malloc64().
4979** + Use p->cSep as the column separator. The default is ",".
4980** + Use p->rSep as the row separator. The default is "\n".
4981** + Keep track of the line number in p->nLine.
4982** + Store the character that terminates the field in p->cTerm. Store
4983** EOF on end-of-file.
4984** + Report syntax errors on stderr
4985*/
4986static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){
4987 int c;
4988 int cSep = p->cColSep;
4989 int rSep = p->cRowSep;
4990 p->n = 0;
4991 c = fgetc(p->in);
4992 if( c==EOF || seenInterrupt ){
4993 p->cTerm = EOF;
4994 return 0;
4995 }
4996 if( c=='"' ){
4997 int pc, ppc;
4998 int startLine = p->nLine;
4999 int cQuote = c;
5000 pc = ppc = 0;
5001 while( 1 ){
5002 c = fgetc(p->in);
5003 if( c==rSep ) p->nLine++;
5004 if( c==cQuote ){
5005 if( pc==cQuote ){
5006 pc = 0;
5007 continue;
5008 }
5009 }
5010 if( (c==cSep && pc==cQuote)
5011 || (c==rSep && pc==cQuote)
5012 || (c==rSep && pc=='\r' && ppc==cQuote)
5013 || (c==EOF && pc==cQuote)
5014 ){
5015 do{ p->n--; }while( p->z[p->n]!=cQuote );
5016 p->cTerm = c;
5017 break;
5018 }
5019 if( pc==cQuote && c!='\r' ){
5020 utf8_printf(stderr, "%s:%d: unescaped %c character\n",
5021 p->zFile, p->nLine, cQuote);
5022 }
5023 if( c==EOF ){
5024 utf8_printf(stderr, "%s:%d: unterminated %c-quoted field\n",
5025 p->zFile, startLine, cQuote);
5026 p->cTerm = c;
5027 break;
5028 }
5029 import_append_char(p, c);
5030 ppc = pc;
5031 pc = c;
5032 }
5033 }else{
5034 /* If this is the first field being parsed and it begins with the
5035 ** UTF-8 BOM (0xEF BB BF) then skip the BOM */
5036 if( (c&0xff)==0xef && p->bNotFirst==0 ){
5037 import_append_char(p, c);
5038 c = fgetc(p->in);
5039 if( (c&0xff)==0xbb ){
5040 import_append_char(p, c);
5041 c = fgetc(p->in);
5042 if( (c&0xff)==0xbf ){
5043 p->bNotFirst = 1;
5044 p->n = 0;
5045 return csv_read_one_field(p);
5046 }
5047 }
5048 }
5049 while( c!=EOF && c!=cSep && c!=rSep ){
5050 import_append_char(p, c);
5051 c = fgetc(p->in);
5052 }
5053 if( c==rSep ){
5054 p->nLine++;
5055 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
5056 }
5057 p->cTerm = c;
5058 }
5059 if( p->z ) p->z[p->n] = 0;
5060 p->bNotFirst = 1;
5061 return p->z;
5062}
5063
5064/* Read a single field of ASCII delimited text.
5065**
5066** + Input comes from p->in.
5067** + Store results in p->z of length p->n. Space to hold p->z comes
5068** from sqlite3_malloc64().
5069** + Use p->cSep as the column separator. The default is "\x1F".
5070** + Use p->rSep as the row separator. The default is "\x1E".
5071** + Keep track of the row number in p->nLine.
5072** + Store the character that terminates the field in p->cTerm. Store
5073** EOF on end-of-file.
5074** + Report syntax errors on stderr
5075*/
5076static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){
5077 int c;
5078 int cSep = p->cColSep;
5079 int rSep = p->cRowSep;
5080 p->n = 0;
5081 c = fgetc(p->in);
5082 if( c==EOF || seenInterrupt ){
5083 p->cTerm = EOF;
5084 return 0;
5085 }
5086 while( c!=EOF && c!=cSep && c!=rSep ){
5087 import_append_char(p, c);
5088 c = fgetc(p->in);
5089 }
5090 if( c==rSep ){
5091 p->nLine++;
5092 }
5093 p->cTerm = c;
5094 if( p->z ) p->z[p->n] = 0;
5095 return p->z;
5096}
5097
5098/*
5099** Try to transfer data for table zTable. If an error is seen while
5100** moving forward, try to go backwards. The backwards movement won't
5101** work for WITHOUT ROWID tables.
5102*/
5103static void tryToCloneData(
5104 ShellState *p,
5105 sqlite3 *newDb,
5106 const char *zTable
5107){
5108 sqlite3_stmt *pQuery = 0;
5109 sqlite3_stmt *pInsert = 0;
5110 char *zQuery = 0;
5111 char *zInsert = 0;
5112 int rc;
5113 int i, j, n;
drhaf2770f2018-01-05 14:55:43 +00005114 int nTable = strlen30(zTable);
drh2ce15c32017-07-11 13:34:40 +00005115 int k = 0;
5116 int cnt = 0;
5117 const int spinRate = 10000;
5118
5119 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
5120 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
5121 if( rc ){
5122 utf8_printf(stderr, "Error %d: %s on [%s]\n",
5123 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
5124 zQuery);
5125 goto end_data_xfer;
5126 }
5127 n = sqlite3_column_count(pQuery);
5128 zInsert = sqlite3_malloc64(200 + nTable + n*3);
drh4b5345c2018-04-24 13:07:40 +00005129 if( zInsert==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00005130 sqlite3_snprintf(200+nTable,zInsert,
5131 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
drhaf2770f2018-01-05 14:55:43 +00005132 i = strlen30(zInsert);
drh2ce15c32017-07-11 13:34:40 +00005133 for(j=1; j<n; j++){
5134 memcpy(zInsert+i, ",?", 2);
5135 i += 2;
5136 }
5137 memcpy(zInsert+i, ");", 3);
5138 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
5139 if( rc ){
5140 utf8_printf(stderr, "Error %d: %s on [%s]\n",
5141 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
5142 zQuery);
5143 goto end_data_xfer;
5144 }
5145 for(k=0; k<2; k++){
5146 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
5147 for(i=0; i<n; i++){
5148 switch( sqlite3_column_type(pQuery, i) ){
5149 case SQLITE_NULL: {
5150 sqlite3_bind_null(pInsert, i+1);
5151 break;
5152 }
5153 case SQLITE_INTEGER: {
5154 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
5155 break;
5156 }
5157 case SQLITE_FLOAT: {
5158 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
5159 break;
5160 }
5161 case SQLITE_TEXT: {
5162 sqlite3_bind_text(pInsert, i+1,
5163 (const char*)sqlite3_column_text(pQuery,i),
5164 -1, SQLITE_STATIC);
5165 break;
5166 }
5167 case SQLITE_BLOB: {
5168 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
5169 sqlite3_column_bytes(pQuery,i),
5170 SQLITE_STATIC);
5171 break;
5172 }
5173 }
5174 } /* End for */
5175 rc = sqlite3_step(pInsert);
5176 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
5177 utf8_printf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
5178 sqlite3_errmsg(newDb));
5179 }
5180 sqlite3_reset(pInsert);
5181 cnt++;
5182 if( (cnt%spinRate)==0 ){
5183 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
5184 fflush(stdout);
5185 }
5186 } /* End while */
5187 if( rc==SQLITE_DONE ) break;
5188 sqlite3_finalize(pQuery);
5189 sqlite3_free(zQuery);
5190 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
5191 zTable);
5192 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
5193 if( rc ){
5194 utf8_printf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
5195 break;
5196 }
5197 } /* End for(k=0...) */
5198
5199end_data_xfer:
5200 sqlite3_finalize(pQuery);
5201 sqlite3_finalize(pInsert);
5202 sqlite3_free(zQuery);
5203 sqlite3_free(zInsert);
5204}
5205
5206
5207/*
5208** Try to transfer all rows of the schema that match zWhere. For
5209** each row, invoke xForEach() on the object defined by that row.
5210** If an error is encountered while moving forward through the
drh067b92b2020-06-19 15:24:12 +00005211** sqlite_schema table, try again moving backwards.
drh2ce15c32017-07-11 13:34:40 +00005212*/
5213static void tryToCloneSchema(
5214 ShellState *p,
5215 sqlite3 *newDb,
5216 const char *zWhere,
5217 void (*xForEach)(ShellState*,sqlite3*,const char*)
5218){
5219 sqlite3_stmt *pQuery = 0;
5220 char *zQuery = 0;
5221 int rc;
5222 const unsigned char *zName;
5223 const unsigned char *zSql;
5224 char *zErrMsg = 0;
5225
drh067b92b2020-06-19 15:24:12 +00005226 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00005227 " WHERE %s", zWhere);
5228 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
5229 if( rc ){
5230 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
5231 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
5232 zQuery);
5233 goto end_schema_xfer;
5234 }
5235 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
5236 zName = sqlite3_column_text(pQuery, 0);
5237 zSql = sqlite3_column_text(pQuery, 1);
5238 printf("%s... ", zName); fflush(stdout);
5239 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
5240 if( zErrMsg ){
5241 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
5242 sqlite3_free(zErrMsg);
5243 zErrMsg = 0;
5244 }
5245 if( xForEach ){
5246 xForEach(p, newDb, (const char*)zName);
5247 }
5248 printf("done\n");
5249 }
5250 if( rc!=SQLITE_DONE ){
5251 sqlite3_finalize(pQuery);
5252 sqlite3_free(zQuery);
drh067b92b2020-06-19 15:24:12 +00005253 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00005254 " WHERE %s ORDER BY rowid DESC", zWhere);
5255 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
5256 if( rc ){
5257 utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
5258 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
5259 zQuery);
5260 goto end_schema_xfer;
5261 }
5262 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
5263 zName = sqlite3_column_text(pQuery, 0);
5264 zSql = sqlite3_column_text(pQuery, 1);
5265 printf("%s... ", zName); fflush(stdout);
5266 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
5267 if( zErrMsg ){
5268 utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
5269 sqlite3_free(zErrMsg);
5270 zErrMsg = 0;
5271 }
5272 if( xForEach ){
5273 xForEach(p, newDb, (const char*)zName);
5274 }
5275 printf("done\n");
5276 }
5277 }
5278end_schema_xfer:
5279 sqlite3_finalize(pQuery);
5280 sqlite3_free(zQuery);
5281}
5282
5283/*
5284** Open a new database file named "zNewDb". Try to recover as much information
5285** as possible out of the main database (which might be corrupt) and write it
5286** into zNewDb.
5287*/
5288static void tryToClone(ShellState *p, const char *zNewDb){
5289 int rc;
5290 sqlite3 *newDb = 0;
5291 if( access(zNewDb,0)==0 ){
5292 utf8_printf(stderr, "File \"%s\" already exists.\n", zNewDb);
5293 return;
5294 }
5295 rc = sqlite3_open(zNewDb, &newDb);
5296 if( rc ){
5297 utf8_printf(stderr, "Cannot create output database: %s\n",
5298 sqlite3_errmsg(newDb));
5299 }else{
5300 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
5301 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
5302 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
5303 tryToCloneSchema(p, newDb, "type!='table'", 0);
5304 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
5305 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
5306 }
drh9e804032018-05-18 17:11:50 +00005307 close_db(newDb);
drh2ce15c32017-07-11 13:34:40 +00005308}
5309
5310/*
drh13c20932018-01-10 21:41:55 +00005311** Change the output file back to stdout.
5312**
5313** If the p->doXdgOpen flag is set, that means the output was being
5314** redirected to a temporary file named by p->zTempFile. In that case,
5315** launch start/open/xdg-open on that temporary file.
drh2ce15c32017-07-11 13:34:40 +00005316*/
5317static void output_reset(ShellState *p){
5318 if( p->outfile[0]=='|' ){
5319#ifndef SQLITE_OMIT_POPEN
5320 pclose(p->out);
5321#endif
5322 }else{
5323 output_file_close(p->out);
drh04a28c32018-01-31 01:38:44 +00005324#ifndef SQLITE_NOHAVE_SYSTEM
drh13c20932018-01-10 21:41:55 +00005325 if( p->doXdgOpen ){
5326 const char *zXdgOpenCmd =
5327#if defined(_WIN32)
5328 "start";
5329#elif defined(__APPLE__)
5330 "open";
5331#else
5332 "xdg-open";
5333#endif
5334 char *zCmd;
5335 zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
drha92a01a2018-01-10 22:15:37 +00005336 if( system(zCmd) ){
5337 utf8_printf(stderr, "Failed: [%s]\n", zCmd);
drh1d9ea272020-04-17 23:46:54 +00005338 }else{
5339 /* Give the start/open/xdg-open command some time to get
5340 ** going before we continue, and potential delete the
5341 ** p->zTempFile data file out from under it */
5342 sqlite3_sleep(2000);
drha92a01a2018-01-10 22:15:37 +00005343 }
drh13c20932018-01-10 21:41:55 +00005344 sqlite3_free(zCmd);
drh3c484e82018-01-10 22:27:21 +00005345 outputModePop(p);
drh13c20932018-01-10 21:41:55 +00005346 p->doXdgOpen = 0;
5347 }
drh04a28c32018-01-31 01:38:44 +00005348#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
drh2ce15c32017-07-11 13:34:40 +00005349 }
5350 p->outfile[0] = 0;
5351 p->out = stdout;
5352}
5353
5354/*
5355** Run an SQL command and return the single integer result.
5356*/
5357static int db_int(ShellState *p, const char *zSql){
5358 sqlite3_stmt *pStmt;
5359 int res = 0;
5360 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
5361 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
5362 res = sqlite3_column_int(pStmt,0);
5363 }
5364 sqlite3_finalize(pStmt);
5365 return res;
5366}
5367
5368/*
5369** Convert a 2-byte or 4-byte big-endian integer into a native integer
5370*/
5371static unsigned int get2byteInt(unsigned char *a){
5372 return (a[0]<<8) + a[1];
5373}
5374static unsigned int get4byteInt(unsigned char *a){
5375 return (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
5376}
5377
5378/*
drh76c12062020-01-14 13:13:19 +00005379** Implementation of the ".dbinfo" command.
drh2ce15c32017-07-11 13:34:40 +00005380**
5381** Return 1 on error, 2 to exit, and 0 otherwise.
5382*/
5383static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
5384 static const struct { const char *zName; int ofst; } aField[] = {
5385 { "file change counter:", 24 },
5386 { "database page count:", 28 },
5387 { "freelist page count:", 36 },
5388 { "schema cookie:", 40 },
5389 { "schema format:", 44 },
5390 { "default cache size:", 48 },
5391 { "autovacuum top root:", 52 },
5392 { "incremental vacuum:", 64 },
5393 { "text encoding:", 56 },
5394 { "user version:", 60 },
5395 { "application id:", 68 },
5396 { "software version:", 96 },
5397 };
5398 static const struct { const char *zName; const char *zSql; } aQuery[] = {
5399 { "number of tables:",
5400 "SELECT count(*) FROM %s WHERE type='table'" },
5401 { "number of indexes:",
5402 "SELECT count(*) FROM %s WHERE type='index'" },
5403 { "number of triggers:",
5404 "SELECT count(*) FROM %s WHERE type='trigger'" },
5405 { "number of views:",
5406 "SELECT count(*) FROM %s WHERE type='view'" },
5407 { "schema size:",
5408 "SELECT total(length(sql)) FROM %s" },
5409 };
drh87c889c2019-03-20 18:22:51 +00005410 int i, rc;
drhea99a312018-07-18 19:09:07 +00005411 unsigned iDataVersion;
drh2ce15c32017-07-11 13:34:40 +00005412 char *zSchemaTab;
5413 char *zDb = nArg>=2 ? azArg[1] : "main";
drh512e6c32017-10-11 17:51:08 +00005414 sqlite3_stmt *pStmt = 0;
drh2ce15c32017-07-11 13:34:40 +00005415 unsigned char aHdr[100];
5416 open_db(p, 0);
5417 if( p->db==0 ) return 1;
drh87c889c2019-03-20 18:22:51 +00005418 rc = sqlite3_prepare_v2(p->db,
5419 "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
5420 -1, &pStmt, 0);
5421 if( rc ){
drh451f89a2020-04-28 23:09:56 +00005422 utf8_printf(stderr, "error: %s\n", sqlite3_errmsg(p->db));
drh87c889c2019-03-20 18:22:51 +00005423 sqlite3_finalize(pStmt);
5424 return 1;
5425 }
drh512e6c32017-10-11 17:51:08 +00005426 sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
5427 if( sqlite3_step(pStmt)==SQLITE_ROW
5428 && sqlite3_column_bytes(pStmt,0)>100
5429 ){
5430 memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100);
5431 sqlite3_finalize(pStmt);
5432 }else{
drh2ce15c32017-07-11 13:34:40 +00005433 raw_printf(stderr, "unable to read database header\n");
drh512e6c32017-10-11 17:51:08 +00005434 sqlite3_finalize(pStmt);
drh2ce15c32017-07-11 13:34:40 +00005435 return 1;
5436 }
5437 i = get2byteInt(aHdr+16);
5438 if( i==1 ) i = 65536;
5439 utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
5440 utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
5441 utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
5442 utf8_printf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]);
5443 for(i=0; i<ArraySize(aField); i++){
5444 int ofst = aField[i].ofst;
5445 unsigned int val = get4byteInt(aHdr + ofst);
5446 utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
5447 switch( ofst ){
5448 case 56: {
5449 if( val==1 ) raw_printf(p->out, " (utf8)");
5450 if( val==2 ) raw_printf(p->out, " (utf16le)");
5451 if( val==3 ) raw_printf(p->out, " (utf16be)");
5452 }
5453 }
5454 raw_printf(p->out, "\n");
5455 }
5456 if( zDb==0 ){
drh067b92b2020-06-19 15:24:12 +00005457 zSchemaTab = sqlite3_mprintf("main.sqlite_schema");
drh2ce15c32017-07-11 13:34:40 +00005458 }else if( strcmp(zDb,"temp")==0 ){
drh067b92b2020-06-19 15:24:12 +00005459 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
drh2ce15c32017-07-11 13:34:40 +00005460 }else{
drh067b92b2020-06-19 15:24:12 +00005461 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
drh2ce15c32017-07-11 13:34:40 +00005462 }
5463 for(i=0; i<ArraySize(aQuery); i++){
5464 char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
5465 int val = db_int(p, zSql);
5466 sqlite3_free(zSql);
5467 utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
5468 }
5469 sqlite3_free(zSchemaTab);
drhea99a312018-07-18 19:09:07 +00005470 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
5471 utf8_printf(p->out, "%-20s %u\n", "data version", iDataVersion);
drh2ce15c32017-07-11 13:34:40 +00005472 return 0;
5473}
5474
5475/*
5476** Print the current sqlite3_errmsg() value to stderr and return 1.
5477*/
5478static int shellDatabaseError(sqlite3 *db){
5479 const char *zErr = sqlite3_errmsg(db);
5480 utf8_printf(stderr, "Error: %s\n", zErr);
5481 return 1;
5482}
5483
5484/*
drh2ce15c32017-07-11 13:34:40 +00005485** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
5486** if they match and FALSE (0) if they do not match.
5487**
5488** Globbing rules:
5489**
5490** '*' Matches any sequence of zero or more characters.
5491**
5492** '?' Matches exactly one character.
5493**
5494** [...] Matches one character from the enclosed list of
5495** characters.
5496**
5497** [^...] Matches one character not in the enclosed list.
5498**
5499** '#' Matches any sequence of one or more digits with an
5500** optional + or - sign in front
5501**
5502** ' ' Any span of whitespace matches any other span of
5503** whitespace.
5504**
5505** Extra whitespace at the end of z[] is ignored.
5506*/
5507static int testcase_glob(const char *zGlob, const char *z){
5508 int c, c2;
5509 int invert;
5510 int seen;
5511
5512 while( (c = (*(zGlob++)))!=0 ){
5513 if( IsSpace(c) ){
5514 if( !IsSpace(*z) ) return 0;
5515 while( IsSpace(*zGlob) ) zGlob++;
5516 while( IsSpace(*z) ) z++;
5517 }else if( c=='*' ){
5518 while( (c=(*(zGlob++))) == '*' || c=='?' ){
5519 if( c=='?' && (*(z++))==0 ) return 0;
5520 }
5521 if( c==0 ){
5522 return 1;
5523 }else if( c=='[' ){
5524 while( *z && testcase_glob(zGlob-1,z)==0 ){
5525 z++;
5526 }
5527 return (*z)!=0;
5528 }
5529 while( (c2 = (*(z++)))!=0 ){
5530 while( c2!=c ){
5531 c2 = *(z++);
5532 if( c2==0 ) return 0;
5533 }
5534 if( testcase_glob(zGlob,z) ) return 1;
5535 }
5536 return 0;
5537 }else if( c=='?' ){
5538 if( (*(z++))==0 ) return 0;
5539 }else if( c=='[' ){
5540 int prior_c = 0;
5541 seen = 0;
5542 invert = 0;
5543 c = *(z++);
5544 if( c==0 ) return 0;
5545 c2 = *(zGlob++);
5546 if( c2=='^' ){
5547 invert = 1;
5548 c2 = *(zGlob++);
5549 }
5550 if( c2==']' ){
5551 if( c==']' ) seen = 1;
5552 c2 = *(zGlob++);
5553 }
5554 while( c2 && c2!=']' ){
5555 if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
5556 c2 = *(zGlob++);
5557 if( c>=prior_c && c<=c2 ) seen = 1;
5558 prior_c = 0;
5559 }else{
5560 if( c==c2 ){
5561 seen = 1;
5562 }
5563 prior_c = c2;
5564 }
5565 c2 = *(zGlob++);
5566 }
5567 if( c2==0 || (seen ^ invert)==0 ) return 0;
5568 }else if( c=='#' ){
5569 if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
5570 if( !IsDigit(z[0]) ) return 0;
5571 z++;
5572 while( IsDigit(z[0]) ){ z++; }
5573 }else{
5574 if( c!=(*(z++)) ) return 0;
5575 }
5576 }
5577 while( IsSpace(*z) ){ z++; }
5578 return *z==0;
5579}
5580
5581
5582/*
5583** Compare the string as a command-line option with either one or two
5584** initial "-" characters.
5585*/
5586static int optionMatch(const char *zStr, const char *zOpt){
5587 if( zStr[0]!='-' ) return 0;
5588 zStr++;
5589 if( zStr[0]=='-' ) zStr++;
5590 return strcmp(zStr, zOpt)==0;
5591}
5592
5593/*
5594** Delete a file.
5595*/
5596int shellDeleteFile(const char *zFilename){
5597 int rc;
5598#ifdef _WIN32
5599 wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
5600 rc = _wunlink(z);
5601 sqlite3_free(z);
5602#else
5603 rc = unlink(zFilename);
5604#endif
5605 return rc;
5606}
5607
drh13c20932018-01-10 21:41:55 +00005608/*
5609** Try to delete the temporary file (if there is one) and free the
5610** memory used to hold the name of the temp file.
5611*/
5612static void clearTempFile(ShellState *p){
5613 if( p->zTempFile==0 ) return;
drh536c3452018-01-11 00:38:39 +00005614 if( p->doXdgOpen ) return;
drh13c20932018-01-10 21:41:55 +00005615 if( shellDeleteFile(p->zTempFile) ) return;
5616 sqlite3_free(p->zTempFile);
5617 p->zTempFile = 0;
5618}
5619
5620/*
5621** Create a new temp file name with the given suffix.
5622*/
5623static void newTempFile(ShellState *p, const char *zSuffix){
5624 clearTempFile(p);
5625 sqlite3_free(p->zTempFile);
5626 p->zTempFile = 0;
drh7f3bf8a2018-01-10 21:50:08 +00005627 if( p->db ){
5628 sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
5629 }
drh13c20932018-01-10 21:41:55 +00005630 if( p->zTempFile==0 ){
drh1d9ea272020-04-17 23:46:54 +00005631 /* If p->db is an in-memory database then the TEMPFILENAME file-control
5632 ** will not work and we will need to fallback to guessing */
5633 char *zTemp;
drh13c20932018-01-10 21:41:55 +00005634 sqlite3_uint64 r;
5635 sqlite3_randomness(sizeof(r), &r);
drh1d9ea272020-04-17 23:46:54 +00005636 zTemp = getenv("TEMP");
5637 if( zTemp==0 ) zTemp = getenv("TMP");
5638 if( zTemp==0 ){
5639#ifdef _WIN32
5640 zTemp = "\\tmp";
5641#else
5642 zTemp = "/tmp";
5643#endif
5644 }
5645 p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
drh13c20932018-01-10 21:41:55 +00005646 }else{
5647 p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
5648 }
5649 if( p->zTempFile==0 ){
5650 raw_printf(stderr, "out of memory\n");
5651 exit(1);
5652 }
5653}
5654
drh2ce15c32017-07-11 13:34:40 +00005655
5656/*
5657** The implementation of SQL scalar function fkey_collate_clause(), used
5658** by the ".lint fkey-indexes" command. This scalar function is always
5659** called with four arguments - the parent table name, the parent column name,
5660** the child table name and the child column name.
5661**
5662** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col')
5663**
5664** If either of the named tables or columns do not exist, this function
5665** returns an empty string. An empty string is also returned if both tables
5666** and columns exist but have the same default collation sequence. Or,
5667** if both exist but the default collation sequences are different, this
5668** function returns the string " COLLATE <parent-collation>", where
5669** <parent-collation> is the default collation sequence of the parent column.
5670*/
5671static void shellFkeyCollateClause(
5672 sqlite3_context *pCtx,
5673 int nVal,
5674 sqlite3_value **apVal
5675){
5676 sqlite3 *db = sqlite3_context_db_handle(pCtx);
5677 const char *zParent;
5678 const char *zParentCol;
5679 const char *zParentSeq;
5680 const char *zChild;
5681 const char *zChildCol;
5682 const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */
5683 int rc;
5684
5685 assert( nVal==4 );
5686 zParent = (const char*)sqlite3_value_text(apVal[0]);
5687 zParentCol = (const char*)sqlite3_value_text(apVal[1]);
5688 zChild = (const char*)sqlite3_value_text(apVal[2]);
5689 zChildCol = (const char*)sqlite3_value_text(apVal[3]);
5690
5691 sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC);
5692 rc = sqlite3_table_column_metadata(
5693 db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0
5694 );
5695 if( rc==SQLITE_OK ){
5696 rc = sqlite3_table_column_metadata(
5697 db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0
5698 );
5699 }
5700
5701 if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){
5702 char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq);
5703 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
5704 sqlite3_free(z);
5705 }
5706}
5707
5708
5709/*
5710** The implementation of dot-command ".lint fkey-indexes".
5711*/
5712static int lintFkeyIndexes(
5713 ShellState *pState, /* Current shell tool state */
5714 char **azArg, /* Array of arguments passed to dot command */
5715 int nArg /* Number of entries in azArg[] */
5716){
5717 sqlite3 *db = pState->db; /* Database handle to query "main" db of */
5718 FILE *out = pState->out; /* Stream to write non-error output to */
5719 int bVerbose = 0; /* If -verbose is present */
5720 int bGroupByParent = 0; /* If -groupbyparent is present */
5721 int i; /* To iterate through azArg[] */
5722 const char *zIndent = ""; /* How much to indent CREATE INDEX by */
5723 int rc; /* Return code */
5724 sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */
5725
5726 /*
5727 ** This SELECT statement returns one row for each foreign key constraint
5728 ** in the schema of the main database. The column values are:
5729 **
5730 ** 0. The text of an SQL statement similar to:
5731 **
danf9679312017-12-01 18:40:18 +00005732 ** "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?"
drh2ce15c32017-07-11 13:34:40 +00005733 **
danf9679312017-12-01 18:40:18 +00005734 ** This SELECT is similar to the one that the foreign keys implementation
5735 ** needs to run internally on child tables. If there is an index that can
drh2ce15c32017-07-11 13:34:40 +00005736 ** be used to optimize this query, then it can also be used by the FK
5737 ** implementation to optimize DELETE or UPDATE statements on the parent
5738 ** table.
5739 **
5740 ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by
5741 ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema
5742 ** contains an index that can be used to optimize the query.
5743 **
5744 ** 2. Human readable text that describes the child table and columns. e.g.
5745 **
5746 ** "child_table(child_key1, child_key2)"
5747 **
5748 ** 3. Human readable text that describes the parent table and columns. e.g.
5749 **
5750 ** "parent_table(parent_key1, parent_key2)"
5751 **
5752 ** 4. A full CREATE INDEX statement for an index that could be used to
5753 ** optimize DELETE or UPDATE statements on the parent table. e.g.
5754 **
5755 ** "CREATE INDEX child_table_child_key ON child_table(child_key)"
5756 **
5757 ** 5. The name of the parent table.
5758 **
5759 ** These six values are used by the C logic below to generate the report.
5760 */
5761 const char *zSql =
5762 "SELECT "
danf9679312017-12-01 18:40:18 +00005763 " 'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '"
drh2ce15c32017-07-11 13:34:40 +00005764 " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' "
5765 " || fkey_collate_clause("
5766 " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')"
5767 ", "
5768 " 'SEARCH TABLE ' || s.name || ' USING COVERING INDEX*('"
5769 " || group_concat('*=?', ' AND ') || ')'"
5770 ", "
5771 " s.name || '(' || group_concat(f.[from], ', ') || ')'"
5772 ", "
5773 " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'"
5774 ", "
5775 " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))"
5776 " || ' ON ' || quote(s.name) || '('"
5777 " || group_concat(quote(f.[from]) ||"
5778 " fkey_collate_clause("
5779 " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')"
5780 " || ');'"
5781 ", "
5782 " f.[table] "
drh067b92b2020-06-19 15:24:12 +00005783 "FROM sqlite_schema AS s, pragma_foreign_key_list(s.name) AS f "
drh2ce15c32017-07-11 13:34:40 +00005784 "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) "
5785 "GROUP BY s.name, f.id "
5786 "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
5787 ;
5788 const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)";
5789
5790 for(i=2; i<nArg; i++){
drhaf2770f2018-01-05 14:55:43 +00005791 int n = strlen30(azArg[i]);
drh2ce15c32017-07-11 13:34:40 +00005792 if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
5793 bVerbose = 1;
5794 }
5795 else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
5796 bGroupByParent = 1;
5797 zIndent = " ";
5798 }
5799 else{
5800 raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
5801 azArg[0], azArg[1]
5802 );
5803 return SQLITE_ERROR;
5804 }
5805 }
5806
5807 /* Register the fkey_collate_clause() SQL function */
5808 rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8,
5809 0, shellFkeyCollateClause, 0, 0
5810 );
5811
5812
5813 if( rc==SQLITE_OK ){
5814 rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0);
5815 }
5816 if( rc==SQLITE_OK ){
5817 sqlite3_bind_int(pSql, 1, bGroupByParent);
5818 }
5819
5820 if( rc==SQLITE_OK ){
5821 int rc2;
5822 char *zPrev = 0;
5823 while( SQLITE_ROW==sqlite3_step(pSql) ){
5824 int res = -1;
5825 sqlite3_stmt *pExplain = 0;
5826 const char *zEQP = (const char*)sqlite3_column_text(pSql, 0);
5827 const char *zGlob = (const char*)sqlite3_column_text(pSql, 1);
5828 const char *zFrom = (const char*)sqlite3_column_text(pSql, 2);
5829 const char *zTarget = (const char*)sqlite3_column_text(pSql, 3);
5830 const char *zCI = (const char*)sqlite3_column_text(pSql, 4);
5831 const char *zParent = (const char*)sqlite3_column_text(pSql, 5);
5832
5833 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
5834 if( rc!=SQLITE_OK ) break;
5835 if( SQLITE_ROW==sqlite3_step(pExplain) ){
5836 const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3);
5837 res = (
5838 0==sqlite3_strglob(zGlob, zPlan)
5839 || 0==sqlite3_strglob(zGlobIPK, zPlan)
5840 );
5841 }
5842 rc = sqlite3_finalize(pExplain);
5843 if( rc!=SQLITE_OK ) break;
5844
5845 if( res<0 ){
5846 raw_printf(stderr, "Error: internal error");
5847 break;
5848 }else{
5849 if( bGroupByParent
5850 && (bVerbose || res==0)
5851 && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
5852 ){
5853 raw_printf(out, "-- Parent table %s\n", zParent);
5854 sqlite3_free(zPrev);
5855 zPrev = sqlite3_mprintf("%s", zParent);
5856 }
5857
5858 if( res==0 ){
5859 raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
5860 }else if( bVerbose ){
5861 raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
5862 zIndent, zFrom, zTarget
5863 );
5864 }
5865 }
5866 }
5867 sqlite3_free(zPrev);
5868
5869 if( rc!=SQLITE_OK ){
5870 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
5871 }
5872
5873 rc2 = sqlite3_finalize(pSql);
5874 if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
5875 rc = rc2;
5876 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
5877 }
5878 }else{
5879 raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
5880 }
5881
5882 return rc;
5883}
5884
5885/*
5886** Implementation of ".lint" dot command.
5887*/
5888static int lintDotCommand(
5889 ShellState *pState, /* Current shell tool state */
5890 char **azArg, /* Array of arguments passed to dot command */
5891 int nArg /* Number of entries in azArg[] */
5892){
5893 int n;
drhaf2770f2018-01-05 14:55:43 +00005894 n = (nArg>=2 ? strlen30(azArg[1]) : 0);
drh2ce15c32017-07-11 13:34:40 +00005895 if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
5896 return lintFkeyIndexes(pState, azArg, nArg);
5897
5898 usage:
5899 raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
5900 raw_printf(stderr, "Where sub-commands are:\n");
5901 raw_printf(stderr, " fkey-indexes\n");
5902 return SQLITE_ERROR;
5903}
5904
dan1b162162019-04-27 20:15:15 +00005905#if !defined SQLITE_OMIT_VIRTUALTABLE
danfd0245d2017-12-07 15:44:29 +00005906static void shellPrepare(
dand4b56e52017-12-12 20:04:59 +00005907 sqlite3 *db,
danfd0245d2017-12-07 15:44:29 +00005908 int *pRc,
5909 const char *zSql,
5910 sqlite3_stmt **ppStmt
5911){
5912 *ppStmt = 0;
5913 if( *pRc==SQLITE_OK ){
dand4b56e52017-12-12 20:04:59 +00005914 int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
danfd0245d2017-12-07 15:44:29 +00005915 if( rc!=SQLITE_OK ){
5916 raw_printf(stderr, "sql error: %s (%d)\n",
dand4b56e52017-12-12 20:04:59 +00005917 sqlite3_errmsg(db), sqlite3_errcode(db)
danfd0245d2017-12-07 15:44:29 +00005918 );
5919 *pRc = rc;
5920 }
5921 }
5922}
5923
drh9546c762019-05-10 17:50:33 +00005924/*
5925** Create a prepared statement using printf-style arguments for the SQL.
5926**
5927** This routine is could be marked "static". But it is not always used,
5928** depending on compile-time options. By omitting the "static", we avoid
5929** nuisance compiler warnings about "defined but not used".
5930*/
5931void shellPreparePrintf(
dan3f67ddf2017-12-13 20:04:53 +00005932 sqlite3 *db,
5933 int *pRc,
danac15e2d2017-12-14 19:15:07 +00005934 sqlite3_stmt **ppStmt,
5935 const char *zFmt,
5936 ...
dan3f67ddf2017-12-13 20:04:53 +00005937){
danac15e2d2017-12-14 19:15:07 +00005938 *ppStmt = 0;
5939 if( *pRc==SQLITE_OK ){
5940 va_list ap;
5941 char *z;
5942 va_start(ap, zFmt);
5943 z = sqlite3_vmprintf(zFmt, ap);
drh1dbb1472018-10-11 10:37:24 +00005944 va_end(ap);
dan3f67ddf2017-12-13 20:04:53 +00005945 if( z==0 ){
5946 *pRc = SQLITE_NOMEM;
5947 }else{
5948 shellPrepare(db, pRc, z, ppStmt);
5949 sqlite3_free(z);
5950 }
dan3f67ddf2017-12-13 20:04:53 +00005951 }
5952}
5953
drh9546c762019-05-10 17:50:33 +00005954/* Finalize the prepared statement created using shellPreparePrintf().
5955**
5956** This routine is could be marked "static". But it is not always used,
5957** depending on compile-time options. By omitting the "static", we avoid
5958** nuisance compiler warnings about "defined but not used".
5959*/
5960void shellFinalize(
danfd0245d2017-12-07 15:44:29 +00005961 int *pRc,
5962 sqlite3_stmt *pStmt
5963){
dan25c12182017-12-07 21:03:33 +00005964 if( pStmt ){
5965 sqlite3 *db = sqlite3_db_handle(pStmt);
5966 int rc = sqlite3_finalize(pStmt);
5967 if( *pRc==SQLITE_OK ){
5968 if( rc!=SQLITE_OK ){
5969 raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
5970 }
5971 *pRc = rc;
5972 }
5973 }
danfd0245d2017-12-07 15:44:29 +00005974}
5975
drh9546c762019-05-10 17:50:33 +00005976/* Reset the prepared statement created using shellPreparePrintf().
5977**
5978** This routine is could be marked "static". But it is not always used,
5979** depending on compile-time options. By omitting the "static", we avoid
5980** nuisance compiler warnings about "defined but not used".
5981*/
5982void shellReset(
danfd0245d2017-12-07 15:44:29 +00005983 int *pRc,
5984 sqlite3_stmt *pStmt
5985){
5986 int rc = sqlite3_reset(pStmt);
dan5a78b812017-12-27 18:54:11 +00005987 if( *pRc==SQLITE_OK ){
5988 if( rc!=SQLITE_OK ){
5989 sqlite3 *db = sqlite3_db_handle(pStmt);
5990 raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
5991 }
5992 *pRc = rc;
5993 }
danfd0245d2017-12-07 15:44:29 +00005994}
dan1b162162019-04-27 20:15:15 +00005995#endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
5996
5997#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
drhe2754c12019-08-26 12:50:01 +00005998/******************************************************************************
dan1b162162019-04-27 20:15:15 +00005999** The ".archive" or ".ar" command.
6000*/
drhe37c0e12018-01-06 19:19:50 +00006001/*
dan88be0202017-12-09 17:58:02 +00006002** Structure representing a single ".ar" command.
6003*/
6004typedef struct ArCommand ArCommand;
6005struct ArCommand {
drhb376b3d2018-01-10 13:11:51 +00006006 u8 eCmd; /* An AR_CMD_* value */
6007 u8 bVerbose; /* True if --verbose */
drha5676c42018-01-10 15:17:34 +00006008 u8 bZip; /* True if the archive is a ZIP */
drhb376b3d2018-01-10 13:11:51 +00006009 u8 bDryRun; /* True if --dry-run */
drha5676c42018-01-10 15:17:34 +00006010 u8 bAppend; /* True if --append */
drhd0f9cdc2018-05-17 14:09:06 +00006011 u8 fromCmdLine; /* Run from -A instead of .archive */
drhb376b3d2018-01-10 13:11:51 +00006012 int nArg; /* Number of command arguments */
drha5676c42018-01-10 15:17:34 +00006013 char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
dan88be0202017-12-09 17:58:02 +00006014 const char *zFile; /* --file argument, or NULL */
6015 const char *zDir; /* --directory argument, or NULL */
dan88be0202017-12-09 17:58:02 +00006016 char **azArg; /* Array of command arguments */
drhb376b3d2018-01-10 13:11:51 +00006017 ShellState *p; /* Shell state */
6018 sqlite3 *db; /* Database containing the archive */
dan88be0202017-12-09 17:58:02 +00006019};
6020
6021/*
6022** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
6023*/
dan0d0547f2017-12-14 15:40:42 +00006024static int arUsage(FILE *f){
drh98aa2ab2018-09-26 16:53:51 +00006025 showHelp(f,"archive");
dan0d0547f2017-12-14 15:40:42 +00006026 return SQLITE_ERROR;
6027}
6028
6029/*
6030** Print an error message for the .ar command to stderr and return
6031** SQLITE_ERROR.
6032*/
drhd0f9cdc2018-05-17 14:09:06 +00006033static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
dan0d0547f2017-12-14 15:40:42 +00006034 va_list ap;
6035 char *z;
6036 va_start(ap, zFmt);
6037 z = sqlite3_vmprintf(zFmt, ap);
6038 va_end(ap);
drhd0f9cdc2018-05-17 14:09:06 +00006039 utf8_printf(stderr, "Error: %s\n", z);
6040 if( pAr->fromCmdLine ){
6041 utf8_printf(stderr, "Use \"-A\" for more help\n");
6042 }else{
6043 utf8_printf(stderr, "Use \".archive --help\" for more help\n");
6044 }
dan0d0547f2017-12-14 15:40:42 +00006045 sqlite3_free(z);
dan88be0202017-12-09 17:58:02 +00006046 return SQLITE_ERROR;
6047}
6048
6049/*
6050** Values for ArCommand.eCmd.
6051*/
dand4b56e52017-12-12 20:04:59 +00006052#define AR_CMD_CREATE 1
drhb17ea912019-03-25 14:24:19 +00006053#define AR_CMD_UPDATE 2
6054#define AR_CMD_INSERT 3
6055#define AR_CMD_EXTRACT 4
6056#define AR_CMD_LIST 5
6057#define AR_CMD_HELP 6
dand4b56e52017-12-12 20:04:59 +00006058
6059/*
6060** Other (non-command) switches.
6061*/
drhb17ea912019-03-25 14:24:19 +00006062#define AR_SWITCH_VERBOSE 7
6063#define AR_SWITCH_FILE 8
6064#define AR_SWITCH_DIRECTORY 9
6065#define AR_SWITCH_APPEND 10
6066#define AR_SWITCH_DRYRUN 11
dand4b56e52017-12-12 20:04:59 +00006067
6068static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
6069 switch( eSwitch ){
6070 case AR_CMD_CREATE:
6071 case AR_CMD_EXTRACT:
6072 case AR_CMD_LIST:
6073 case AR_CMD_UPDATE:
drhb17ea912019-03-25 14:24:19 +00006074 case AR_CMD_INSERT:
dan0d0547f2017-12-14 15:40:42 +00006075 case AR_CMD_HELP:
6076 if( pAr->eCmd ){
drhd0f9cdc2018-05-17 14:09:06 +00006077 return arErrorMsg(pAr, "multiple command options");
dan0d0547f2017-12-14 15:40:42 +00006078 }
dand4b56e52017-12-12 20:04:59 +00006079 pAr->eCmd = eSwitch;
6080 break;
6081
drhb376b3d2018-01-10 13:11:51 +00006082 case AR_SWITCH_DRYRUN:
6083 pAr->bDryRun = 1;
6084 break;
dand4b56e52017-12-12 20:04:59 +00006085 case AR_SWITCH_VERBOSE:
6086 pAr->bVerbose = 1;
6087 break;
drha5676c42018-01-10 15:17:34 +00006088 case AR_SWITCH_APPEND:
6089 pAr->bAppend = 1;
drhca7733b2018-01-10 18:09:20 +00006090 /* Fall thru into --file */
dand4b56e52017-12-12 20:04:59 +00006091 case AR_SWITCH_FILE:
6092 pAr->zFile = zArg;
6093 break;
6094 case AR_SWITCH_DIRECTORY:
6095 pAr->zDir = zArg;
6096 break;
6097 }
6098
6099 return SQLITE_OK;
6100}
dan88be0202017-12-09 17:58:02 +00006101
6102/*
6103** Parse the command line for an ".ar" command. The results are written into
6104** structure (*pAr). SQLITE_OK is returned if the command line is parsed
6105** successfully, otherwise an error message is written to stderr and
6106** SQLITE_ERROR returned.
6107*/
6108static int arParseCommand(
6109 char **azArg, /* Array of arguments passed to dot command */
6110 int nArg, /* Number of entries in azArg[] */
6111 ArCommand *pAr /* Populate this object */
6112){
dand4b56e52017-12-12 20:04:59 +00006113 struct ArSwitch {
dand4b56e52017-12-12 20:04:59 +00006114 const char *zLong;
drhb376b3d2018-01-10 13:11:51 +00006115 char cShort;
6116 u8 eSwitch;
6117 u8 bArg;
dand4b56e52017-12-12 20:04:59 +00006118 } aSwitch[] = {
drhb376b3d2018-01-10 13:11:51 +00006119 { "create", 'c', AR_CMD_CREATE, 0 },
6120 { "extract", 'x', AR_CMD_EXTRACT, 0 },
drhb17ea912019-03-25 14:24:19 +00006121 { "insert", 'i', AR_CMD_INSERT, 0 },
drhb376b3d2018-01-10 13:11:51 +00006122 { "list", 't', AR_CMD_LIST, 0 },
6123 { "update", 'u', AR_CMD_UPDATE, 0 },
6124 { "help", 'h', AR_CMD_HELP, 0 },
6125 { "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
6126 { "file", 'f', AR_SWITCH_FILE, 1 },
drhca7733b2018-01-10 18:09:20 +00006127 { "append", 'a', AR_SWITCH_APPEND, 1 },
drhb376b3d2018-01-10 13:11:51 +00006128 { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
drhb376b3d2018-01-10 13:11:51 +00006129 { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
dand4b56e52017-12-12 20:04:59 +00006130 };
6131 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
6132 struct ArSwitch *pEnd = &aSwitch[nSwitch];
6133
dan88be0202017-12-09 17:58:02 +00006134 if( nArg<=1 ){
drh98aa2ab2018-09-26 16:53:51 +00006135 utf8_printf(stderr, "Wrong number of arguments. Usage:\n");
dan0d0547f2017-12-14 15:40:42 +00006136 return arUsage(stderr);
dan88be0202017-12-09 17:58:02 +00006137 }else{
6138 char *z = azArg[1];
dan88be0202017-12-09 17:58:02 +00006139 if( z[0]!='-' ){
6140 /* Traditional style [tar] invocation */
6141 int i;
6142 int iArg = 2;
6143 for(i=0; z[i]; i++){
dand4b56e52017-12-12 20:04:59 +00006144 const char *zArg = 0;
6145 struct ArSwitch *pOpt;
6146 for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
6147 if( z[i]==pOpt->cShort ) break;
dan88be0202017-12-09 17:58:02 +00006148 }
dan0d0547f2017-12-14 15:40:42 +00006149 if( pOpt==pEnd ){
drhd0f9cdc2018-05-17 14:09:06 +00006150 return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
dan0d0547f2017-12-14 15:40:42 +00006151 }
dand4b56e52017-12-12 20:04:59 +00006152 if( pOpt->bArg ){
dan0d0547f2017-12-14 15:40:42 +00006153 if( iArg>=nArg ){
drhd0f9cdc2018-05-17 14:09:06 +00006154 return arErrorMsg(pAr, "option requires an argument: %c",z[i]);
dan0d0547f2017-12-14 15:40:42 +00006155 }
dand4b56e52017-12-12 20:04:59 +00006156 zArg = azArg[iArg++];
6157 }
6158 if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
dan88be0202017-12-09 17:58:02 +00006159 }
dan88be0202017-12-09 17:58:02 +00006160 pAr->nArg = nArg-iArg;
6161 if( pAr->nArg>0 ){
6162 pAr->azArg = &azArg[iArg];
6163 }
dand4b56e52017-12-12 20:04:59 +00006164 }else{
6165 /* Non-traditional invocation */
6166 int iArg;
6167 for(iArg=1; iArg<nArg; iArg++){
6168 int n;
6169 z = azArg[iArg];
6170 if( z[0]!='-' ){
6171 /* All remaining command line words are command arguments. */
6172 pAr->azArg = &azArg[iArg];
6173 pAr->nArg = nArg-iArg;
6174 break;
6175 }
drhaf2770f2018-01-05 14:55:43 +00006176 n = strlen30(z);
dand4b56e52017-12-12 20:04:59 +00006177
6178 if( z[1]!='-' ){
6179 int i;
6180 /* One or more short options */
6181 for(i=1; i<n; i++){
6182 const char *zArg = 0;
6183 struct ArSwitch *pOpt;
6184 for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
6185 if( z[i]==pOpt->cShort ) break;
6186 }
dan0d0547f2017-12-14 15:40:42 +00006187 if( pOpt==pEnd ){
drhd0f9cdc2018-05-17 14:09:06 +00006188 return arErrorMsg(pAr, "unrecognized option: %c", z[i]);
dan0d0547f2017-12-14 15:40:42 +00006189 }
dand4b56e52017-12-12 20:04:59 +00006190 if( pOpt->bArg ){
6191 if( i<(n-1) ){
6192 zArg = &z[i+1];
6193 i = n;
6194 }else{
dan0d0547f2017-12-14 15:40:42 +00006195 if( iArg>=(nArg-1) ){
drhe2754c12019-08-26 12:50:01 +00006196 return arErrorMsg(pAr, "option requires an argument: %c",
6197 z[i]);
dan0d0547f2017-12-14 15:40:42 +00006198 }
dand4b56e52017-12-12 20:04:59 +00006199 zArg = azArg[++iArg];
6200 }
6201 }
6202 if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
6203 }
6204 }else if( z[2]=='\0' ){
6205 /* A -- option, indicating that all remaining command line words
6206 ** are command arguments. */
6207 pAr->azArg = &azArg[iArg+1];
6208 pAr->nArg = nArg-iArg-1;
6209 break;
6210 }else{
6211 /* A long option */
6212 const char *zArg = 0; /* Argument for option, if any */
6213 struct ArSwitch *pMatch = 0; /* Matching option */
6214 struct ArSwitch *pOpt; /* Iterator */
6215 for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
6216 const char *zLong = pOpt->zLong;
drhaf2770f2018-01-05 14:55:43 +00006217 if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){
dand4b56e52017-12-12 20:04:59 +00006218 if( pMatch ){
drhd0f9cdc2018-05-17 14:09:06 +00006219 return arErrorMsg(pAr, "ambiguous option: %s",z);
dand4b56e52017-12-12 20:04:59 +00006220 }else{
6221 pMatch = pOpt;
6222 }
6223 }
6224 }
6225
6226 if( pMatch==0 ){
drhd0f9cdc2018-05-17 14:09:06 +00006227 return arErrorMsg(pAr, "unrecognized option: %s", z);
dand4b56e52017-12-12 20:04:59 +00006228 }
6229 if( pMatch->bArg ){
dan0d0547f2017-12-14 15:40:42 +00006230 if( iArg>=(nArg-1) ){
drhd0f9cdc2018-05-17 14:09:06 +00006231 return arErrorMsg(pAr, "option requires an argument: %s", z);
dan0d0547f2017-12-14 15:40:42 +00006232 }
dand4b56e52017-12-12 20:04:59 +00006233 zArg = azArg[++iArg];
6234 }
6235 if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR;
6236 }
6237 }
dan88be0202017-12-09 17:58:02 +00006238 }
6239 }
6240
6241 return SQLITE_OK;
6242}
6243
6244/*
dan3f67ddf2017-12-13 20:04:53 +00006245** This function assumes that all arguments within the ArCommand.azArg[]
6246** array refer to archive members, as for the --extract or --list commands.
6247** It checks that each of them are present. If any specified file is not
6248** present in the archive, an error is printed to stderr and an error
6249** code returned. Otherwise, if all specified arguments are present in
6250** the archive, SQLITE_OK is returned.
6251**
6252** This function strips any trailing '/' characters from each argument.
6253** This is consistent with the way the [tar] command seems to work on
6254** Linux.
6255*/
drhb376b3d2018-01-10 13:11:51 +00006256static int arCheckEntries(ArCommand *pAr){
dan3f67ddf2017-12-13 20:04:53 +00006257 int rc = SQLITE_OK;
6258 if( pAr->nArg ){
drhb376b3d2018-01-10 13:11:51 +00006259 int i, j;
dan3f67ddf2017-12-13 20:04:53 +00006260 sqlite3_stmt *pTest = 0;
6261
drhb376b3d2018-01-10 13:11:51 +00006262 shellPreparePrintf(pAr->db, &rc, &pTest,
6263 "SELECT name FROM %s WHERE name=$name",
6264 pAr->zSrcTable
dan5a78b812017-12-27 18:54:11 +00006265 );
drhb376b3d2018-01-10 13:11:51 +00006266 j = sqlite3_bind_parameter_index(pTest, "$name");
dan3f67ddf2017-12-13 20:04:53 +00006267 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
6268 char *z = pAr->azArg[i];
drhaf2770f2018-01-05 14:55:43 +00006269 int n = strlen30(z);
dan3f67ddf2017-12-13 20:04:53 +00006270 int bOk = 0;
6271 while( n>0 && z[n-1]=='/' ) n--;
6272 z[n] = '\0';
drhb376b3d2018-01-10 13:11:51 +00006273 sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC);
dan3f67ddf2017-12-13 20:04:53 +00006274 if( SQLITE_ROW==sqlite3_step(pTest) ){
6275 bOk = 1;
6276 }
6277 shellReset(&rc, pTest);
6278 if( rc==SQLITE_OK && bOk==0 ){
drhb376b3d2018-01-10 13:11:51 +00006279 utf8_printf(stderr, "not found in archive: %s\n", z);
dan3f67ddf2017-12-13 20:04:53 +00006280 rc = SQLITE_ERROR;
6281 }
6282 }
6283 shellFinalize(&rc, pTest);
6284 }
dan3f67ddf2017-12-13 20:04:53 +00006285 return rc;
6286}
6287
6288/*
6289** Format a WHERE clause that can be used against the "sqlar" table to
6290** identify all archive members that match the command arguments held
6291** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
6292** The caller is responsible for eventually calling sqlite3_free() on
6293** any non-NULL (*pzWhere) value.
6294*/
6295static void arWhereClause(
6296 int *pRc,
6297 ArCommand *pAr,
danac15e2d2017-12-14 19:15:07 +00006298 char **pzWhere /* OUT: New WHERE clause */
dan3f67ddf2017-12-13 20:04:53 +00006299){
6300 char *zWhere = 0;
6301 if( *pRc==SQLITE_OK ){
danac15e2d2017-12-14 19:15:07 +00006302 if( pAr->nArg==0 ){
6303 zWhere = sqlite3_mprintf("1");
6304 }else{
6305 int i;
6306 const char *zSep = "";
6307 for(i=0; i<pAr->nArg; i++){
6308 const char *z = pAr->azArg[i];
6309 zWhere = sqlite3_mprintf(
drhb376b3d2018-01-10 13:11:51 +00006310 "%z%s name = '%q' OR substr(name,1,%d) = '%q/'",
6311 zWhere, zSep, z, strlen30(z)+1, z
6312 );
danac15e2d2017-12-14 19:15:07 +00006313 if( zWhere==0 ){
6314 *pRc = SQLITE_NOMEM;
6315 break;
6316 }
6317 zSep = " OR ";
dan3f67ddf2017-12-13 20:04:53 +00006318 }
dan3f67ddf2017-12-13 20:04:53 +00006319 }
6320 }
6321 *pzWhere = zWhere;
6322}
6323
6324/*
dan88be0202017-12-09 17:58:02 +00006325** Implementation of .ar "lisT" command.
6326*/
drhb376b3d2018-01-10 13:11:51 +00006327static int arListCommand(ArCommand *pAr){
danb5090e42017-12-27 21:13:21 +00006328 const char *zSql = "SELECT %s FROM %s WHERE %s";
danb5090e42017-12-27 21:13:21 +00006329 const char *azCols[] = {
6330 "name",
drh410cad92018-01-10 17:19:16 +00006331 "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name"
danb5090e42017-12-27 21:13:21 +00006332 };
dan5a78b812017-12-27 18:54:11 +00006333
dan3f67ddf2017-12-13 20:04:53 +00006334 char *zWhere = 0;
6335 sqlite3_stmt *pSql = 0;
6336 int rc;
6337
drhb376b3d2018-01-10 13:11:51 +00006338 rc = arCheckEntries(pAr);
dan3f67ddf2017-12-13 20:04:53 +00006339 arWhereClause(&rc, pAr, &zWhere);
6340
drhb376b3d2018-01-10 13:11:51 +00006341 shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
6342 pAr->zSrcTable, zWhere);
drhb376b3d2018-01-10 13:11:51 +00006343 if( pAr->bDryRun ){
6344 utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
6345 }else{
6346 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
6347 if( pAr->bVerbose ){
drh410cad92018-01-10 17:19:16 +00006348 utf8_printf(pAr->p->out, "%s % 10d %s %s\n",
6349 sqlite3_column_text(pSql, 0),
drhb376b3d2018-01-10 13:11:51 +00006350 sqlite3_column_int(pSql, 1),
6351 sqlite3_column_text(pSql, 2),
6352 sqlite3_column_text(pSql, 3)
6353 );
6354 }else{
6355 utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
6356 }
danb5090e42017-12-27 21:13:21 +00006357 }
dan3f67ddf2017-12-13 20:04:53 +00006358 }
dan5a78b812017-12-27 18:54:11 +00006359 shellFinalize(&rc, pSql);
drhd0f9cdc2018-05-17 14:09:06 +00006360 sqlite3_free(zWhere);
dan3f67ddf2017-12-13 20:04:53 +00006361 return rc;
dan88be0202017-12-09 17:58:02 +00006362}
6363
6364
danfd0245d2017-12-07 15:44:29 +00006365/*
6366** Implementation of .ar "eXtract" command.
6367*/
drhb376b3d2018-01-10 13:11:51 +00006368static int arExtractCommand(ArCommand *pAr){
dan25c12182017-12-07 21:03:33 +00006369 const char *zSql1 =
dand1b51d42017-12-16 19:11:26 +00006370 "SELECT "
drhb376b3d2018-01-10 13:11:51 +00006371 " ($dir || name),"
6372 " writefile(($dir || name), %s, mode, mtime) "
drh0cfd46a2018-06-06 01:18:01 +00006373 "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)"
6374 " AND name NOT GLOB '*..[/\\]*'";
dan5a78b812017-12-27 18:54:11 +00006375
6376 const char *azExtraArg[] = {
6377 "sqlar_uncompress(data, sz)",
dan7c15ac12018-01-08 19:59:59 +00006378 "data"
dan5a78b812017-12-27 18:54:11 +00006379 };
dan5a78b812017-12-27 18:54:11 +00006380
danfd0245d2017-12-07 15:44:29 +00006381 sqlite3_stmt *pSql = 0;
6382 int rc = SQLITE_OK;
dan2ad09492017-12-09 18:28:22 +00006383 char *zDir = 0;
dan3f67ddf2017-12-13 20:04:53 +00006384 char *zWhere = 0;
drhb376b3d2018-01-10 13:11:51 +00006385 int i, j;
dan2ad09492017-12-09 18:28:22 +00006386
dan3f67ddf2017-12-13 20:04:53 +00006387 /* If arguments are specified, check that they actually exist within
6388 ** the archive before proceeding. And formulate a WHERE clause to
6389 ** match them. */
drhb376b3d2018-01-10 13:11:51 +00006390 rc = arCheckEntries(pAr);
dan3f67ddf2017-12-13 20:04:53 +00006391 arWhereClause(&rc, pAr, &zWhere);
6392
6393 if( rc==SQLITE_OK ){
6394 if( pAr->zDir ){
6395 zDir = sqlite3_mprintf("%s/", pAr->zDir);
6396 }else{
6397 zDir = sqlite3_mprintf("");
6398 }
6399 if( zDir==0 ) rc = SQLITE_NOMEM;
dan2ad09492017-12-09 18:28:22 +00006400 }
danfd0245d2017-12-07 15:44:29 +00006401
drhb376b3d2018-01-10 13:11:51 +00006402 shellPreparePrintf(pAr->db, &rc, &pSql, zSql1,
6403 azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere
dan5a78b812017-12-27 18:54:11 +00006404 );
6405
dan2ad09492017-12-09 18:28:22 +00006406 if( rc==SQLITE_OK ){
drhb376b3d2018-01-10 13:11:51 +00006407 j = sqlite3_bind_parameter_index(pSql, "$dir");
6408 sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC);
dan25c12182017-12-07 21:03:33 +00006409
danac15e2d2017-12-14 19:15:07 +00006410 /* Run the SELECT statement twice. The first time, writefile() is called
6411 ** for all archive members that should be extracted. The second time,
6412 ** only for the directories. This is because the timestamps for
6413 ** extracted directories must be reset after they are populated (as
6414 ** populating them changes the timestamp). */
6415 for(i=0; i<2; i++){
drhb376b3d2018-01-10 13:11:51 +00006416 j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
6417 sqlite3_bind_int(pSql, j, i);
6418 if( pAr->bDryRun ){
6419 utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
6420 }else{
6421 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
6422 if( i==0 && pAr->bVerbose ){
6423 utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
6424 }
danac15e2d2017-12-14 19:15:07 +00006425 }
6426 }
6427 shellReset(&rc, pSql);
dan25c12182017-12-07 21:03:33 +00006428 }
danac15e2d2017-12-14 19:15:07 +00006429 shellFinalize(&rc, pSql);
dan25c12182017-12-07 21:03:33 +00006430 }
dan25c12182017-12-07 21:03:33 +00006431
dan2ad09492017-12-09 18:28:22 +00006432 sqlite3_free(zDir);
dan3f67ddf2017-12-13 20:04:53 +00006433 sqlite3_free(zWhere);
danfd0245d2017-12-07 15:44:29 +00006434 return rc;
6435}
6436
drhb376b3d2018-01-10 13:11:51 +00006437/*
6438** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out.
6439*/
6440static int arExecSql(ArCommand *pAr, const char *zSql){
6441 int rc;
6442 if( pAr->bDryRun ){
6443 utf8_printf(pAr->p->out, "%s\n", zSql);
6444 rc = SQLITE_OK;
6445 }else{
drh410cad92018-01-10 17:19:16 +00006446 char *zErr = 0;
6447 rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
6448 if( zErr ){
6449 utf8_printf(stdout, "ERROR: %s\n", zErr);
6450 sqlite3_free(zErr);
6451 }
drhb376b3d2018-01-10 13:11:51 +00006452 }
6453 return rc;
6454}
6455
dan1ad3f612017-12-11 20:22:02 +00006456
danfd0245d2017-12-07 15:44:29 +00006457/*
drhb17ea912019-03-25 14:24:19 +00006458** Implementation of .ar "create", "insert", and "update" commands.
6459**
6460** create -> Create a new SQL archive
6461** insert -> Insert or reinsert all files listed
6462** update -> Insert files that have changed or that were not
6463** previously in the archive
danfd0245d2017-12-07 15:44:29 +00006464**
6465** Create the "sqlar" table in the database if it does not already exist.
6466** Then add each file in the azFile[] array to the archive. Directories
6467** are added recursively. If argument bVerbose is non-zero, a message is
6468** printed on stdout for each file archived.
dan06741a32017-12-13 20:17:18 +00006469**
6470** The create command is the same as update, except that it drops
drhb17ea912019-03-25 14:24:19 +00006471** any existing "sqlar" table before beginning. The "insert" command
6472** always overwrites every file named on the command-line, where as
6473** "update" only overwrites if the size or mtime or mode has changed.
danfd0245d2017-12-07 15:44:29 +00006474*/
drhb376b3d2018-01-10 13:11:51 +00006475static int arCreateOrUpdateCommand(
dan06741a32017-12-13 20:17:18 +00006476 ArCommand *pAr, /* Command arguments and options */
drhb17ea912019-03-25 14:24:19 +00006477 int bUpdate, /* true for a --create. */
6478 int bOnlyIfChanged /* Only update if file has changed */
danfd0245d2017-12-07 15:44:29 +00006479){
dand4b56e52017-12-12 20:04:59 +00006480 const char *zCreate =
drhafba1802018-01-06 15:49:57 +00006481 "CREATE TABLE IF NOT EXISTS sqlar(\n"
6482 " name TEXT PRIMARY KEY, -- name of the file\n"
6483 " mode INT, -- access permissions\n"
6484 " mtime INT, -- last modification time\n"
6485 " sz INT, -- original file size\n"
6486 " data BLOB -- compressed content\n"
6487 ")";
dand4b56e52017-12-12 20:04:59 +00006488 const char *zDrop = "DROP TABLE IF EXISTS sqlar";
drh1bf208c2018-03-09 21:54:01 +00006489 const char *zInsertFmt[2] = {
6490 "REPLACE INTO %s(name,mode,mtime,sz,data)\n"
drh634c70f2018-01-10 16:50:18 +00006491 " SELECT\n"
6492 " %s,\n"
6493 " mode,\n"
6494 " mtime,\n"
drh410cad92018-01-10 17:19:16 +00006495 " CASE substr(lsmode(mode),1,1)\n"
6496 " WHEN '-' THEN length(data)\n"
6497 " WHEN 'd' THEN 0\n"
drh634c70f2018-01-10 16:50:18 +00006498 " ELSE -1 END,\n"
drh69d2d352018-03-09 22:18:53 +00006499 " sqlar_compress(data)\n"
drhb17ea912019-03-25 14:24:19 +00006500 " FROM fsdir(%Q,%Q) AS disk\n"
6501 " WHERE lsmode(mode) NOT LIKE '?%%'%s;"
6502 ,
drh1bf208c2018-03-09 21:54:01 +00006503 "REPLACE INTO %s(name,mode,mtime,data)\n"
6504 " SELECT\n"
6505 " %s,\n"
6506 " mode,\n"
6507 " mtime,\n"
6508 " data\n"
drhb17ea912019-03-25 14:24:19 +00006509 " FROM fsdir(%Q,%Q) AS disk\n"
6510 " WHERE lsmode(mode) NOT LIKE '?%%'%s;"
drh1bf208c2018-03-09 21:54:01 +00006511 };
danfd0245d2017-12-07 15:44:29 +00006512 int i; /* For iterating through azFile[] */
6513 int rc; /* Return code */
drh1bf208c2018-03-09 21:54:01 +00006514 const char *zTab = 0; /* SQL table into which to insert */
6515 char *zSql;
6516 char zTemp[50];
drhb17ea912019-03-25 14:24:19 +00006517 char *zExists = 0;
danfd0245d2017-12-07 15:44:29 +00006518
drh1bf208c2018-03-09 21:54:01 +00006519 arExecSql(pAr, "PRAGMA page_size=512");
drhb376b3d2018-01-10 13:11:51 +00006520 rc = arExecSql(pAr, "SAVEPOINT ar;");
danfd0245d2017-12-07 15:44:29 +00006521 if( rc!=SQLITE_OK ) return rc;
drh1bf208c2018-03-09 21:54:01 +00006522 zTemp[0] = 0;
6523 if( pAr->bZip ){
6524 /* Initialize the zipfile virtual table, if necessary */
6525 if( pAr->zFile ){
6526 sqlite3_uint64 r;
6527 sqlite3_randomness(sizeof(r),&r);
6528 sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r);
6529 zTab = zTemp;
6530 zSql = sqlite3_mprintf(
6531 "CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)",
6532 zTab, pAr->zFile
6533 );
6534 rc = arExecSql(pAr, zSql);
6535 sqlite3_free(zSql);
6536 }else{
6537 zTab = "zip";
6538 }
6539 }else{
6540 /* Initialize the table for an SQLAR */
6541 zTab = "sqlar";
6542 if( bUpdate==0 ){
6543 rc = arExecSql(pAr, zDrop);
6544 if( rc!=SQLITE_OK ) goto end_ar_transaction;
6545 }
6546 rc = arExecSql(pAr, zCreate);
dan06741a32017-12-13 20:17:18 +00006547 }
drhb17ea912019-03-25 14:24:19 +00006548 if( bOnlyIfChanged ){
6549 zExists = sqlite3_mprintf(
6550 " AND NOT EXISTS("
6551 "SELECT 1 FROM %s AS mem"
6552 " WHERE mem.name=disk.name"
6553 " AND mem.mtime=disk.mtime"
6554 " AND mem.mode=disk.mode)", zTab);
6555 }else{
6556 zExists = sqlite3_mprintf("");
6557 }
6558 if( zExists==0 ) rc = SQLITE_NOMEM;
dan88be0202017-12-09 17:58:02 +00006559 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
mistachkince2052b2018-03-23 00:31:53 +00006560 char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab,
drh634c70f2018-01-10 16:50:18 +00006561 pAr->bVerbose ? "shell_putsnl(name)" : "name",
drhb17ea912019-03-25 14:24:19 +00006562 pAr->azArg[i], pAr->zDir, zExists);
mistachkince2052b2018-03-23 00:31:53 +00006563 rc = arExecSql(pAr, zSql2);
6564 sqlite3_free(zSql2);
danfd0245d2017-12-07 15:44:29 +00006565 }
drh1bf208c2018-03-09 21:54:01 +00006566end_ar_transaction:
danfd0245d2017-12-07 15:44:29 +00006567 if( rc!=SQLITE_OK ){
drh2bd207f2019-01-11 17:19:59 +00006568 sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0);
danfd0245d2017-12-07 15:44:29 +00006569 }else{
drhb376b3d2018-01-10 13:11:51 +00006570 rc = arExecSql(pAr, "RELEASE ar;");
drh1bf208c2018-03-09 21:54:01 +00006571 if( pAr->bZip && pAr->zFile ){
6572 zSql = sqlite3_mprintf("DROP TABLE %s", zTemp);
6573 arExecSql(pAr, zSql);
6574 sqlite3_free(zSql);
6575 }
danfd0245d2017-12-07 15:44:29 +00006576 }
drhb17ea912019-03-25 14:24:19 +00006577 sqlite3_free(zExists);
danfd0245d2017-12-07 15:44:29 +00006578 return rc;
6579}
6580
6581/*
6582** Implementation of ".ar" dot command.
6583*/
6584static int arDotCommand(
drhe2754c12019-08-26 12:50:01 +00006585 ShellState *pState, /* Current shell tool state */
6586 int fromCmdLine, /* True if -A command-line option, not .ar cmd */
6587 char **azArg, /* Array of arguments passed to dot command */
6588 int nArg /* Number of entries in azArg[] */
danfd0245d2017-12-07 15:44:29 +00006589){
dan88be0202017-12-09 17:58:02 +00006590 ArCommand cmd;
6591 int rc;
drh34660642018-01-10 17:39:54 +00006592 memset(&cmd, 0, sizeof(cmd));
drhd0f9cdc2018-05-17 14:09:06 +00006593 cmd.fromCmdLine = fromCmdLine;
dan88be0202017-12-09 17:58:02 +00006594 rc = arParseCommand(azArg, nArg, &cmd);
6595 if( rc==SQLITE_OK ){
drha5676c42018-01-10 15:17:34 +00006596 int eDbType = SHELL_OPEN_UNSPEC;
drhb376b3d2018-01-10 13:11:51 +00006597 cmd.p = pState;
6598 cmd.db = pState->db;
drha5676c42018-01-10 15:17:34 +00006599 if( cmd.zFile ){
drh1bf208c2018-03-09 21:54:01 +00006600 eDbType = deduceDatabaseType(cmd.zFile, 1);
drha5676c42018-01-10 15:17:34 +00006601 }else{
6602 eDbType = pState->openMode;
6603 }
6604 if( eDbType==SHELL_OPEN_ZIPFILE ){
drh1bf208c2018-03-09 21:54:01 +00006605 if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){
6606 if( cmd.zFile==0 ){
6607 cmd.zSrcTable = sqlite3_mprintf("zip");
6608 }else{
6609 cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile);
6610 }
dan5a78b812017-12-27 18:54:11 +00006611 }
drha5676c42018-01-10 15:17:34 +00006612 cmd.bZip = 1;
dan5a78b812017-12-27 18:54:11 +00006613 }else if( cmd.zFile ){
dand4b56e52017-12-12 20:04:59 +00006614 int flags;
drha5676c42018-01-10 15:17:34 +00006615 if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
drhb17ea912019-03-25 14:24:19 +00006616 if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
6617 || cmd.eCmd==AR_CMD_UPDATE ){
dand4b56e52017-12-12 20:04:59 +00006618 flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
6619 }else{
6620 flags = SQLITE_OPEN_READONLY;
6621 }
drha82c95b2018-01-10 14:00:00 +00006622 cmd.db = 0;
drha5676c42018-01-10 15:17:34 +00006623 if( cmd.bDryRun ){
6624 utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile,
6625 eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
6626 }
6627 rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
6628 eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
dand4b56e52017-12-12 20:04:59 +00006629 if( rc!=SQLITE_OK ){
drhb376b3d2018-01-10 13:11:51 +00006630 utf8_printf(stderr, "cannot open file: %s (%s)\n",
6631 cmd.zFile, sqlite3_errmsg(cmd.db)
dand4b56e52017-12-12 20:04:59 +00006632 );
drha5676c42018-01-10 15:17:34 +00006633 goto end_ar_command;
dand4b56e52017-12-12 20:04:59 +00006634 }
drhb376b3d2018-01-10 13:11:51 +00006635 sqlite3_fileio_init(cmd.db, 0, 0);
drhb376b3d2018-01-10 13:11:51 +00006636 sqlite3_sqlar_init(cmd.db, 0, 0);
drh34660642018-01-10 17:39:54 +00006637 sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p,
6638 shellPutsFunc, 0, 0);
6639
dand4b56e52017-12-12 20:04:59 +00006640 }
drhd0f9cdc2018-05-17 14:09:06 +00006641 if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){
drh634c70f2018-01-10 16:50:18 +00006642 if( cmd.eCmd!=AR_CMD_CREATE
6643 && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
6644 ){
drha5676c42018-01-10 15:17:34 +00006645 utf8_printf(stderr, "database does not contain an 'sqlar' table\n");
6646 rc = SQLITE_ERROR;
6647 goto end_ar_command;
6648 }
6649 cmd.zSrcTable = sqlite3_mprintf("sqlar");
6650 }
dand4b56e52017-12-12 20:04:59 +00006651
dan88be0202017-12-09 17:58:02 +00006652 switch( cmd.eCmd ){
6653 case AR_CMD_CREATE:
drhb17ea912019-03-25 14:24:19 +00006654 rc = arCreateOrUpdateCommand(&cmd, 0, 0);
dan88be0202017-12-09 17:58:02 +00006655 break;
danfd0245d2017-12-07 15:44:29 +00006656
dan88be0202017-12-09 17:58:02 +00006657 case AR_CMD_EXTRACT:
drhb376b3d2018-01-10 13:11:51 +00006658 rc = arExtractCommand(&cmd);
dan88be0202017-12-09 17:58:02 +00006659 break;
6660
6661 case AR_CMD_LIST:
drhb376b3d2018-01-10 13:11:51 +00006662 rc = arListCommand(&cmd);
dan88be0202017-12-09 17:58:02 +00006663 break;
6664
dan0d0547f2017-12-14 15:40:42 +00006665 case AR_CMD_HELP:
6666 arUsage(pState->out);
6667 break;
6668
drhb17ea912019-03-25 14:24:19 +00006669 case AR_CMD_INSERT:
6670 rc = arCreateOrUpdateCommand(&cmd, 1, 0);
6671 break;
6672
dan88be0202017-12-09 17:58:02 +00006673 default:
6674 assert( cmd.eCmd==AR_CMD_UPDATE );
drhb17ea912019-03-25 14:24:19 +00006675 rc = arCreateOrUpdateCommand(&cmd, 1, 1);
dan88be0202017-12-09 17:58:02 +00006676 break;
danfd0245d2017-12-07 15:44:29 +00006677 }
6678 }
drha5676c42018-01-10 15:17:34 +00006679end_ar_command:
6680 if( cmd.db!=pState->db ){
drh9e804032018-05-18 17:11:50 +00006681 close_db(cmd.db);
drha5676c42018-01-10 15:17:34 +00006682 }
6683 sqlite3_free(cmd.zSrcTable);
danfd0245d2017-12-07 15:44:29 +00006684
dan88be0202017-12-09 17:58:02 +00006685 return rc;
danfd0245d2017-12-07 15:44:29 +00006686}
drhe37c0e12018-01-06 19:19:50 +00006687/* End of the ".archive" or ".ar" command logic
drhe2754c12019-08-26 12:50:01 +00006688*******************************************************************************/
drhe37c0e12018-01-06 19:19:50 +00006689#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
danfd0245d2017-12-07 15:44:29 +00006690
dan1b162162019-04-27 20:15:15 +00006691#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
dan42ebb012019-04-27 18:47:03 +00006692/*
6693** If (*pRc) is not SQLITE_OK when this function is called, it is a no-op.
6694** Otherwise, the SQL statement or statements in zSql are executed using
6695** database connection db and the error code written to *pRc before
6696** this function returns.
6697*/
dan68cb86e2019-04-20 20:57:28 +00006698static void shellExec(sqlite3 *db, int *pRc, const char *zSql){
6699 int rc = *pRc;
6700 if( rc==SQLITE_OK ){
6701 char *zErr = 0;
6702 rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
6703 if( rc!=SQLITE_OK ){
6704 raw_printf(stderr, "SQL error: %s\n", zErr);
6705 }
6706 *pRc = rc;
6707 }
6708}
6709
dan42ebb012019-04-27 18:47:03 +00006710/*
6711** Like shellExec(), except that zFmt is a printf() style format string.
6712*/
danc0b42432019-04-26 15:14:53 +00006713static void shellExecPrintf(sqlite3 *db, int *pRc, const char *zFmt, ...){
6714 char *z = 0;
6715 if( *pRc==SQLITE_OK ){
6716 va_list ap;
6717 va_start(ap, zFmt);
6718 z = sqlite3_vmprintf(zFmt, ap);
6719 va_end(ap);
6720 if( z==0 ){
6721 *pRc = SQLITE_NOMEM;
6722 }else{
6723 shellExec(db, pRc, z);
6724 }
6725 sqlite3_free(z);
6726 }
6727}
6728
dan42ebb012019-04-27 18:47:03 +00006729/*
6730** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
6731** Otherwise, an attempt is made to allocate, zero and return a pointer
6732** to a buffer nByte bytes in size. If an OOM error occurs, *pRc is set
6733** to SQLITE_NOMEM and NULL returned.
6734*/
dan68cb86e2019-04-20 20:57:28 +00006735static void *shellMalloc(int *pRc, sqlite3_int64 nByte){
6736 void *pRet = 0;
6737 if( *pRc==SQLITE_OK ){
6738 pRet = sqlite3_malloc64(nByte);
6739 if( pRet==0 ){
6740 *pRc = SQLITE_NOMEM;
6741 }else{
6742 memset(pRet, 0, nByte);
6743 }
6744 }
6745 return pRet;
6746}
6747
dan42ebb012019-04-27 18:47:03 +00006748/*
6749** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
6750** Otherwise, zFmt is treated as a printf() style string. The result of
6751** formatting it along with any trailing arguments is written into a
6752** buffer obtained from sqlite3_malloc(), and pointer to which is returned.
6753** It is the responsibility of the caller to eventually free this buffer
6754** using a call to sqlite3_free().
6755**
6756** If an OOM error occurs, (*pRc) is set to SQLITE_NOMEM and a NULL
6757** pointer returned.
6758*/
dan68cb86e2019-04-20 20:57:28 +00006759static char *shellMPrintf(int *pRc, const char *zFmt, ...){
6760 char *z = 0;
6761 if( *pRc==SQLITE_OK ){
6762 va_list ap;
6763 va_start(ap, zFmt);
6764 z = sqlite3_vmprintf(zFmt, ap);
6765 va_end(ap);
6766 if( z==0 ){
6767 *pRc = SQLITE_NOMEM;
6768 }
6769 }
6770 return z;
6771}
6772
dan42ebb012019-04-27 18:47:03 +00006773/*
6774** When running the ".recover" command, each output table, and the special
6775** orphaned row table if it is required, is represented by an instance
6776** of the following struct.
6777*/
dan68cb86e2019-04-20 20:57:28 +00006778typedef struct RecoverTable RecoverTable;
6779struct RecoverTable {
dan42ebb012019-04-27 18:47:03 +00006780 char *zQuoted; /* Quoted version of table name */
dan68cb86e2019-04-20 20:57:28 +00006781 int nCol; /* Number of columns in table */
6782 char **azlCol; /* Array of column lists */
dan42ebb012019-04-27 18:47:03 +00006783 int iPk; /* Index of IPK column */
dan68cb86e2019-04-20 20:57:28 +00006784};
6785
6786/*
dan42ebb012019-04-27 18:47:03 +00006787** Free a RecoverTable object allocated by recoverFindTable() or
6788** recoverOrphanTable().
dan68cb86e2019-04-20 20:57:28 +00006789*/
6790static void recoverFreeTable(RecoverTable *pTab){
6791 if( pTab ){
dan68cb86e2019-04-20 20:57:28 +00006792 sqlite3_free(pTab->zQuoted);
dan68cb86e2019-04-20 20:57:28 +00006793 if( pTab->azlCol ){
6794 int i;
dan98c5ad32019-04-26 21:11:37 +00006795 for(i=0; i<=pTab->nCol; i++){
dan68cb86e2019-04-20 20:57:28 +00006796 sqlite3_free(pTab->azlCol[i]);
6797 }
6798 sqlite3_free(pTab->azlCol);
6799 }
6800 sqlite3_free(pTab);
6801 }
6802}
6803
dan42ebb012019-04-27 18:47:03 +00006804/*
6805** This function is a no-op if (*pRc) is not SQLITE_OK when it is called.
6806** Otherwise, it allocates and returns a RecoverTable object based on the
6807** final four arguments passed to this function. It is the responsibility
6808** of the caller to eventually free the returned object using
6809** recoverFreeTable().
6810*/
6811static RecoverTable *recoverNewTable(
danb40af492019-04-22 20:52:12 +00006812 int *pRc, /* IN/OUT: Error code */
danb40af492019-04-22 20:52:12 +00006813 const char *zName, /* Name of table */
6814 const char *zSql, /* CREATE TABLE statement */
6815 int bIntkey,
6816 int nCol
6817){
6818 sqlite3 *dbtmp = 0; /* sqlite3 handle for testing CREATE TABLE */
6819 int rc = *pRc;
dan98c5ad32019-04-26 21:11:37 +00006820 RecoverTable *pTab = 0;
danb40af492019-04-22 20:52:12 +00006821
dan98c5ad32019-04-26 21:11:37 +00006822 pTab = (RecoverTable*)shellMalloc(&rc, sizeof(RecoverTable));
danb40af492019-04-22 20:52:12 +00006823 if( rc==SQLITE_OK ){
6824 int nSqlCol = 0;
6825 int bSqlIntkey = 0;
6826 sqlite3_stmt *pStmt = 0;
dan98c5ad32019-04-26 21:11:37 +00006827
danb40af492019-04-22 20:52:12 +00006828 rc = sqlite3_open("", &dbtmp);
6829 if( rc==SQLITE_OK ){
drha2de66c2019-08-06 20:26:17 +00006830 sqlite3_create_function(dbtmp, "shell_idquote", 1, SQLITE_UTF8, 0,
6831 shellIdQuote, 0, 0);
6832 }
6833 if( rc==SQLITE_OK ){
dan38f9c712019-04-23 18:03:02 +00006834 rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0);
6835 }
6836 if( rc==SQLITE_OK ){
danb40af492019-04-22 20:52:12 +00006837 rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0);
6838 if( rc==SQLITE_ERROR ){
6839 rc = SQLITE_OK;
6840 goto finished;
6841 }
6842 }
6843 shellPreparePrintf(dbtmp, &rc, &pStmt,
6844 "SELECT count(*) FROM pragma_table_info(%Q)", zName
6845 );
6846 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
6847 nSqlCol = sqlite3_column_int(pStmt, 0);
6848 }
6849 shellFinalize(&rc, pStmt);
6850
6851 if( rc!=SQLITE_OK || nSqlCol<nCol ){
6852 goto finished;
6853 }
6854
6855 shellPreparePrintf(dbtmp, &rc, &pStmt,
6856 "SELECT ("
6857 " SELECT substr(data,1,1)==X'0D' FROM sqlite_dbpage WHERE pgno=rootpage"
drh067b92b2020-06-19 15:24:12 +00006858 ") FROM sqlite_schema WHERE name = %Q", zName
danb40af492019-04-22 20:52:12 +00006859 );
6860 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
6861 bSqlIntkey = sqlite3_column_int(pStmt, 0);
6862 }
6863 shellFinalize(&rc, pStmt);
6864
6865 if( bIntkey==bSqlIntkey ){
dan98c5ad32019-04-26 21:11:37 +00006866 int i;
danb40af492019-04-22 20:52:12 +00006867 const char *zPk = "_rowid_";
6868 sqlite3_stmt *pPkFinder = 0;
6869
danf57bea32019-04-27 15:35:45 +00006870 /* If this is an intkey table and there is an INTEGER PRIMARY KEY,
6871 ** set zPk to the name of the PK column, and pTab->iPk to the index
6872 ** of the column, where columns are 0-numbered from left to right.
6873 ** Or, if this is a WITHOUT ROWID table or if there is no IPK column,
6874 ** leave zPk as "_rowid_" and pTab->iPk at -2. */
dan98c5ad32019-04-26 21:11:37 +00006875 pTab->iPk = -2;
6876 if( bIntkey ){
6877 shellPreparePrintf(dbtmp, &rc, &pPkFinder,
danb40af492019-04-22 20:52:12 +00006878 "SELECT cid, name FROM pragma_table_info(%Q) "
6879 " WHERE pk=1 AND type='integer' COLLATE nocase"
dan98c5ad32019-04-26 21:11:37 +00006880 " AND NOT EXISTS (SELECT cid FROM pragma_table_info(%Q) WHERE pk=2)"
6881 , zName, zName
6882 );
6883 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){
6884 pTab->iPk = sqlite3_column_int(pPkFinder, 0);
6885 zPk = (const char*)sqlite3_column_text(pPkFinder, 1);
6886 }
danb40af492019-04-22 20:52:12 +00006887 }
6888
drha2de66c2019-08-06 20:26:17 +00006889 pTab->zQuoted = shellMPrintf(&rc, "\"%w\"", zName);
dan98c5ad32019-04-26 21:11:37 +00006890 pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1));
danb40af492019-04-22 20:52:12 +00006891 pTab->nCol = nSqlCol;
6892
dan98c5ad32019-04-26 21:11:37 +00006893 if( bIntkey ){
drha2de66c2019-08-06 20:26:17 +00006894 pTab->azlCol[0] = shellMPrintf(&rc, "\"%w\"", zPk);
danb40af492019-04-22 20:52:12 +00006895 }else{
dan98c5ad32019-04-26 21:11:37 +00006896 pTab->azlCol[0] = shellMPrintf(&rc, "");
danb40af492019-04-22 20:52:12 +00006897 }
dan98c5ad32019-04-26 21:11:37 +00006898 i = 1;
6899 shellPreparePrintf(dbtmp, &rc, &pStmt,
drha2de66c2019-08-06 20:26:17 +00006900 "SELECT %Q || group_concat(shell_idquote(name), ', ') "
danf57bea32019-04-27 15:35:45 +00006901 " FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) "
dan98c5ad32019-04-26 21:11:37 +00006902 "FROM pragma_table_info(%Q)",
danf57bea32019-04-27 15:35:45 +00006903 bIntkey ? ", " : "", pTab->iPk,
6904 bIntkey ? "" : "(CASE WHEN pk=0 THEN 1000000 ELSE pk END), ",
6905 zName
dan98c5ad32019-04-26 21:11:37 +00006906 );
6907 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
6908 const char *zText = (const char*)sqlite3_column_text(pStmt, 0);
6909 pTab->azlCol[i] = shellMPrintf(&rc, "%s%s", pTab->azlCol[0], zText);
6910 i++;
6911 }
6912 shellFinalize(&rc, pStmt);
6913
danb40af492019-04-22 20:52:12 +00006914 shellFinalize(&rc, pPkFinder);
6915 }
6916 }
6917
6918 finished:
6919 sqlite3_close(dbtmp);
6920 *pRc = rc;
dan98779652019-05-09 14:15:19 +00006921 if( rc!=SQLITE_OK || (pTab && pTab->zQuoted==0) ){
dan98c5ad32019-04-26 21:11:37 +00006922 recoverFreeTable(pTab);
6923 pTab = 0;
6924 }
6925 return pTab;
danb40af492019-04-22 20:52:12 +00006926}
6927
dan0aa01ee2019-04-27 19:36:49 +00006928/*
6929** This function is called to search the schema recovered from the
drh067b92b2020-06-19 15:24:12 +00006930** sqlite_schema table of the (possibly) corrupt database as part
dan0aa01ee2019-04-27 19:36:49 +00006931** of a ".recover" command. Specifically, for a table with root page
6932** iRoot and at least nCol columns. Additionally, if bIntkey is 0, the
6933** table must be a WITHOUT ROWID table, or if non-zero, not one of
6934** those.
6935**
6936** If a table is found, a (RecoverTable*) object is returned. Or, if
6937** no such table is found, but bIntkey is false and iRoot is the
6938** root page of an index in the recovered schema, then (*pbNoop) is
6939** set to true and NULL returned. Or, if there is no such table or
6940** index, NULL is returned and (*pbNoop) set to 0, indicating that
6941** the caller should write data to the orphans table.
6942*/
dan42ebb012019-04-27 18:47:03 +00006943static RecoverTable *recoverFindTable(
dan0aa01ee2019-04-27 19:36:49 +00006944 ShellState *pState, /* Shell state object */
6945 int *pRc, /* IN/OUT: Error code */
6946 int iRoot, /* Root page of table */
6947 int bIntkey, /* True for an intkey table */
6948 int nCol, /* Number of columns in table */
6949 int *pbNoop /* OUT: True if iRoot is root of index */
dan68cb86e2019-04-20 20:57:28 +00006950){
danb40af492019-04-22 20:52:12 +00006951 sqlite3_stmt *pStmt = 0;
dan68cb86e2019-04-20 20:57:28 +00006952 RecoverTable *pRet = 0;
danb40af492019-04-22 20:52:12 +00006953 int bNoop = 0;
6954 const char *zSql = 0;
6955 const char *zName = 0;
dan68cb86e2019-04-20 20:57:28 +00006956
danb40af492019-04-22 20:52:12 +00006957 /* Search the recovered schema for an object with root page iRoot. */
6958 shellPreparePrintf(pState->db, pRc, &pStmt,
6959 "SELECT type, name, sql FROM recovery.schema WHERE rootpage=%d", iRoot
6960 );
6961 while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
6962 const char *zType = (const char*)sqlite3_column_text(pStmt, 0);
6963 if( bIntkey==0 && sqlite3_stricmp(zType, "index")==0 ){
6964 bNoop = 1;
6965 break;
6966 }
6967 if( sqlite3_stricmp(zType, "table")==0 ){
6968 zName = (const char*)sqlite3_column_text(pStmt, 1);
6969 zSql = (const char*)sqlite3_column_text(pStmt, 2);
dan42ebb012019-04-27 18:47:03 +00006970 pRet = recoverNewTable(pRc, zName, zSql, bIntkey, nCol);
danb40af492019-04-22 20:52:12 +00006971 break;
6972 }
6973 }
dan98c5ad32019-04-26 21:11:37 +00006974
danb40af492019-04-22 20:52:12 +00006975 shellFinalize(pRc, pStmt);
dan98c5ad32019-04-26 21:11:37 +00006976 *pbNoop = bNoop;
6977 return pRet;
6978}
danb40af492019-04-22 20:52:12 +00006979
dan0aa01ee2019-04-27 19:36:49 +00006980/*
6981** Return a RecoverTable object representing the orphans table.
6982*/
dan98c5ad32019-04-26 21:11:37 +00006983static RecoverTable *recoverOrphanTable(
dan0aa01ee2019-04-27 19:36:49 +00006984 ShellState *pState, /* Shell state object */
6985 int *pRc, /* IN/OUT: Error code */
6986 const char *zLostAndFound, /* Base name for orphans table */
6987 int nCol /* Number of user data columns */
dan98c5ad32019-04-26 21:11:37 +00006988){
6989 RecoverTable *pTab = 0;
6990 if( nCol>=0 && *pRc==SQLITE_OK ){
6991 int i;
dan42ebb012019-04-27 18:47:03 +00006992
6993 /* This block determines the name of the orphan table. The prefered
6994 ** name is zLostAndFound. But if that clashes with another name
6995 ** in the recovered schema, try zLostAndFound_0, zLostAndFound_1
6996 ** and so on until a non-clashing name is found. */
6997 int iTab = 0;
6998 char *zTab = shellMPrintf(pRc, "%s", zLostAndFound);
6999 sqlite3_stmt *pTest = 0;
7000 shellPrepare(pState->db, pRc,
7001 "SELECT 1 FROM recovery.schema WHERE name=?", &pTest
dan68cb86e2019-04-20 20:57:28 +00007002 );
dan42ebb012019-04-27 18:47:03 +00007003 if( pTest ) sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
7004 while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pTest) ){
7005 shellReset(pRc, pTest);
7006 sqlite3_free(zTab);
7007 zTab = shellMPrintf(pRc, "%s_%d", zLostAndFound, iTab++);
7008 sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT);
dan68cb86e2019-04-20 20:57:28 +00007009 }
dan42ebb012019-04-27 18:47:03 +00007010 shellFinalize(pRc, pTest);
dan68cb86e2019-04-20 20:57:28 +00007011
dan98c5ad32019-04-26 21:11:37 +00007012 pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable));
7013 if( pTab ){
drha2de66c2019-08-06 20:26:17 +00007014 pTab->zQuoted = shellMPrintf(pRc, "\"%w\"", zTab);
dan98c5ad32019-04-26 21:11:37 +00007015 pTab->nCol = nCol;
7016 pTab->iPk = -2;
7017 if( nCol>0 ){
7018 pTab->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * (nCol+1));
7019 if( pTab->azlCol ){
7020 pTab->azlCol[nCol] = shellMPrintf(pRc, "");
7021 for(i=nCol-1; i>=0; i--){
7022 pTab->azlCol[i] = shellMPrintf(pRc, "%s, NULL", pTab->azlCol[i+1]);
7023 }
7024 }
danb40af492019-04-22 20:52:12 +00007025 }
dan68cb86e2019-04-20 20:57:28 +00007026
dan42ebb012019-04-27 18:47:03 +00007027 if( *pRc!=SQLITE_OK ){
7028 recoverFreeTable(pTab);
7029 pTab = 0;
7030 }else{
7031 raw_printf(pState->out,
7032 "CREATE TABLE %s(rootpgno INTEGER, "
7033 "pgno INTEGER, nfield INTEGER, id INTEGER", pTab->zQuoted
7034 );
7035 for(i=0; i<nCol; i++){
7036 raw_printf(pState->out, ", c%d", i);
7037 }
7038 raw_printf(pState->out, ");\n");
7039 }
dan98c5ad32019-04-26 21:11:37 +00007040 }
dan42ebb012019-04-27 18:47:03 +00007041 sqlite3_free(zTab);
dan68cb86e2019-04-20 20:57:28 +00007042 }
dan98c5ad32019-04-26 21:11:37 +00007043 return pTab;
dan68cb86e2019-04-20 20:57:28 +00007044}
7045
7046/*
7047** This function is called to recover data from the database. A script
7048** to construct a new database containing all recovered data is output
7049** on stream pState->out.
7050*/
danb9b71db2019-04-25 16:20:40 +00007051static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
dan68cb86e2019-04-20 20:57:28 +00007052 int rc = SQLITE_OK;
7053 sqlite3_stmt *pLoop = 0; /* Loop through all root pages */
danefa363b2019-04-24 20:48:55 +00007054 sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */
7055 sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */
danc0b42432019-04-26 15:14:53 +00007056 const char *zRecoveryDb = ""; /* Name of "recovery" database */
dan42ebb012019-04-27 18:47:03 +00007057 const char *zLostAndFound = "lost_and_found";
dan9c014f82019-04-25 19:23:15 +00007058 int i;
dan98c5ad32019-04-26 21:11:37 +00007059 int nOrphan = -1;
7060 RecoverTable *pOrphan = 0;
dan9c014f82019-04-25 19:23:15 +00007061
7062 int bFreelist = 1; /* 0 if --freelist-corrupt is specified */
dan8cce6b82019-09-14 16:44:51 +00007063 int bRowids = 1; /* 0 if --no-rowids */
dan9c014f82019-04-25 19:23:15 +00007064 for(i=1; i<nArg; i++){
7065 char *z = azArg[i];
7066 int n;
7067 if( z[0]=='-' && z[1]=='-' ) z++;
drh4245e042019-06-13 13:52:46 +00007068 n = strlen30(z);
dan9c014f82019-04-25 19:23:15 +00007069 if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){
7070 bFreelist = 0;
dan42ebb012019-04-27 18:47:03 +00007071 }else
danc0b42432019-04-26 15:14:53 +00007072 if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){
7073 i++;
7074 zRecoveryDb = azArg[i];
dan42ebb012019-04-27 18:47:03 +00007075 }else
7076 if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
7077 i++;
7078 zLostAndFound = azArg[i];
dan8cce6b82019-09-14 16:44:51 +00007079 }else
7080 if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
7081 bRowids = 0;
danc0b42432019-04-26 15:14:53 +00007082 }
dan9c014f82019-04-25 19:23:15 +00007083 else{
drhe2754c12019-08-26 12:50:01 +00007084 utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
7085 showHelp(pState->out, azArg[0]);
dan9c014f82019-04-25 19:23:15 +00007086 return 1;
7087 }
7088 }
dan68cb86e2019-04-20 20:57:28 +00007089
danc0b42432019-04-26 15:14:53 +00007090 shellExecPrintf(pState->db, &rc,
dan68cb86e2019-04-20 20:57:28 +00007091 /* Attach an in-memory database named 'recovery'. Create an indexed
7092 ** cache of the sqlite_dbptr virtual table. */
dan01c08bc2019-07-24 19:20:30 +00007093 "PRAGMA writable_schema = on;"
danc0b42432019-04-26 15:14:53 +00007094 "ATTACH %Q AS recovery;"
7095 "DROP TABLE IF EXISTS recovery.dbptr;"
7096 "DROP TABLE IF EXISTS recovery.freelist;"
7097 "DROP TABLE IF EXISTS recovery.map;"
7098 "DROP TABLE IF EXISTS recovery.schema;"
danc0b42432019-04-26 15:14:53 +00007099 "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb
dan9c014f82019-04-25 19:23:15 +00007100 );
7101
7102 if( bFreelist ){
7103 shellExec(pState->db, &rc,
7104 "WITH trunk(pgno) AS ("
7105 " SELECT shell_int32("
7106 " (SELECT data FROM sqlite_dbpage WHERE pgno=1), 8) AS x "
7107 " WHERE x>0"
7108 " UNION"
7109 " SELECT shell_int32("
7110 " (SELECT data FROM sqlite_dbpage WHERE pgno=trunk.pgno), 0) AS x "
7111 " FROM trunk WHERE x>0"
7112 "),"
7113 "freelist(data, n, freepgno) AS ("
danf6099e92019-05-09 16:57:39 +00007114 " SELECT data, min(16384, shell_int32(data, 1)-1), t.pgno "
dan9c014f82019-04-25 19:23:15 +00007115 " FROM trunk t, sqlite_dbpage s WHERE s.pgno=t.pgno"
7116 " UNION ALL"
7117 " SELECT data, n-1, shell_int32(data, 2+n) "
7118 " FROM freelist WHERE n>=0"
7119 ")"
7120 "REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;"
7121 );
7122 }
7123
dan95063c22019-07-24 08:15:09 +00007124 /* If this is an auto-vacuum database, add all pointer-map pages to
7125 ** the freelist table. Do this regardless of whether or not
7126 ** --freelist-corrupt was specified. */
7127 shellExec(pState->db, &rc,
7128 "WITH ptrmap(pgno) AS ("
7129 " SELECT 2 WHERE shell_int32("
7130 " (SELECT data FROM sqlite_dbpage WHERE pgno=1), 13"
7131 " )"
7132 " UNION ALL "
7133 " SELECT pgno+1+(SELECT page_size FROM pragma_page_size)/5 AS pp "
7134 " FROM ptrmap WHERE pp<=(SELECT page_count FROM pragma_page_count)"
7135 ")"
7136 "REPLACE INTO recovery.freelist SELECT pgno FROM ptrmap"
7137 );
7138
dan9c014f82019-04-25 19:23:15 +00007139 shellExec(pState->db, &rc,
danca424382019-04-26 15:40:27 +00007140 "CREATE TABLE recovery.dbptr("
7141 " pgno, child, PRIMARY KEY(child, pgno)"
7142 ") WITHOUT ROWID;"
7143 "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) "
7144 " SELECT * FROM sqlite_dbptr"
7145 " WHERE pgno NOT IN freelist AND child NOT IN freelist;"
7146
7147 /* Delete any pointer to page 1. This ensures that page 1 is considered
7148 ** a root page, regardless of how corrupt the db is. */
7149 "DELETE FROM recovery.dbptr WHERE child = 1;"
7150
7151 /* Delete all pointers to any pages that have more than one pointer
7152 ** to them. Such pages will be treated as root pages when recovering
7153 ** data. */
7154 "DELETE FROM recovery.dbptr WHERE child IN ("
7155 " SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1"
7156 ");"
7157
dan68cb86e2019-04-20 20:57:28 +00007158 /* Create the "map" table that will (eventually) contain instructions
7159 ** for dealing with each page in the db that contains one or more
7160 ** records. */
danb40af492019-04-22 20:52:12 +00007161 "CREATE TABLE recovery.map("
7162 "pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT"
7163 ");"
dan68cb86e2019-04-20 20:57:28 +00007164
7165 /* Populate table [map]. If there are circular loops of pages in the
7166 ** database, the following adds all pages in such a loop to the map
7167 ** as individual root pages. This could be handled better. */
7168 "WITH pages(i, maxlen) AS ("
danb9b71db2019-04-25 16:20:40 +00007169 " SELECT page_count, ("
7170 " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count"
dan13b87672019-05-09 11:45:21 +00007171 " ) FROM pragma_page_count WHERE page_count>0"
dan68cb86e2019-04-20 20:57:28 +00007172 " UNION ALL"
danb40af492019-04-22 20:52:12 +00007173 " SELECT i-1, ("
7174 " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1"
7175 " ) FROM pages WHERE i>=2"
dan68cb86e2019-04-20 20:57:28 +00007176 ")"
danb40af492019-04-22 20:52:12 +00007177 "INSERT INTO recovery.map(pgno, maxlen, intkey, root) "
7178 " SELECT i, maxlen, NULL, ("
dan68cb86e2019-04-20 20:57:28 +00007179 " WITH p(orig, pgno, parent) AS ("
7180 " SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)"
dan39e04f82019-05-09 18:33:32 +00007181 " UNION "
dan68cb86e2019-04-20 20:57:28 +00007182 " SELECT i, p.parent, "
7183 " (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p"
7184 " )"
7185 " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
7186 ") "
dand790c9a2019-08-26 14:57:58 +00007187 "FROM pages WHERE maxlen IS NOT NULL AND i NOT IN freelist;"
danb40af492019-04-22 20:52:12 +00007188 "UPDATE recovery.map AS o SET intkey = ("
7189 " SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno"
7190 ");"
dan68cb86e2019-04-20 20:57:28 +00007191
7192 /* Extract data from page 1 and any linked pages into table
drh067b92b2020-06-19 15:24:12 +00007193 ** recovery.schema. With the same schema as an sqlite_schema table. */
dan68cb86e2019-04-20 20:57:28 +00007194 "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);"
7195 "INSERT INTO recovery.schema SELECT "
7196 " max(CASE WHEN field=0 THEN value ELSE NULL END),"
7197 " max(CASE WHEN field=1 THEN value ELSE NULL END),"
7198 " max(CASE WHEN field=2 THEN value ELSE NULL END),"
7199 " max(CASE WHEN field=3 THEN value ELSE NULL END),"
7200 " max(CASE WHEN field=4 THEN value ELSE NULL END)"
7201 "FROM sqlite_dbdata WHERE pgno IN ("
7202 " SELECT pgno FROM recovery.map WHERE root=1"
7203 ")"
7204 "GROUP BY pgno, cell;"
dan98c5ad32019-04-26 21:11:37 +00007205 "CREATE INDEX recovery.schema_rootpage ON schema(rootpage);"
dan68cb86e2019-04-20 20:57:28 +00007206 );
7207
danb40af492019-04-22 20:52:12 +00007208 /* Open a transaction, then print out all non-virtual, non-"sqlite_%"
7209 ** CREATE TABLE statements that extracted from the existing schema. */
7210 if( rc==SQLITE_OK ){
7211 sqlite3_stmt *pStmt = 0;
danf3210572019-08-06 18:40:36 +00007212 /* ".recover" might output content in an order which causes immediate
7213 ** foreign key constraints to be violated. So disable foreign-key
7214 ** constraint enforcement to prevent problems when running the output
7215 ** script. */
7216 raw_printf(pState->out, "PRAGMA foreign_keys=OFF;\n");
danb40af492019-04-22 20:52:12 +00007217 raw_printf(pState->out, "BEGIN;\n");
dan38f9c712019-04-23 18:03:02 +00007218 raw_printf(pState->out, "PRAGMA writable_schema = on;\n");
7219 shellPrepare(pState->db, &rc,
danb40af492019-04-22 20:52:12 +00007220 "SELECT sql FROM recovery.schema "
dan38f9c712019-04-23 18:03:02 +00007221 "WHERE type='table' AND sql LIKE 'create table%'", &pStmt
danb40af492019-04-22 20:52:12 +00007222 );
7223 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
7224 const char *zCreateTable = (const char*)sqlite3_column_text(pStmt, 0);
dan38f9c712019-04-23 18:03:02 +00007225 raw_printf(pState->out, "CREATE TABLE IF NOT EXISTS %s;\n",
7226 &zCreateTable[12]
7227 );
danb40af492019-04-22 20:52:12 +00007228 }
7229 shellFinalize(&rc, pStmt);
7230 }
7231
dan98c5ad32019-04-26 21:11:37 +00007232 /* Figure out if an orphan table will be required. And if so, how many
7233 ** user columns it should contain */
7234 shellPrepare(pState->db, &rc,
dan98779652019-05-09 14:15:19 +00007235 "SELECT coalesce(max(maxlen), -2) FROM recovery.map WHERE root>1"
dan98c5ad32019-04-26 21:11:37 +00007236 , &pLoop
7237 );
7238 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
7239 nOrphan = sqlite3_column_int(pLoop, 0);
7240 }
7241 shellFinalize(&rc, pLoop);
7242 pLoop = 0;
dan98c5ad32019-04-26 21:11:37 +00007243
danefa363b2019-04-24 20:48:55 +00007244 shellPrepare(pState->db, &rc,
7245 "SELECT pgno FROM recovery.map WHERE root=?", &pPages
7246 );
dan8cce6b82019-09-14 16:44:51 +00007247
danefa363b2019-04-24 20:48:55 +00007248 shellPrepare(pState->db, &rc,
dan8cce6b82019-09-14 16:44:51 +00007249 "SELECT max(field), group_concat(shell_escape_crnl(quote"
7250 "(case when (? AND field<0) then NULL else value end)"
7251 "), ', ')"
dan9443dbc2019-07-24 20:10:27 +00007252 ", min(field) "
danefa363b2019-04-24 20:48:55 +00007253 "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
7254 "GROUP BY cell", &pCells
7255 );
7256
dan68cb86e2019-04-20 20:57:28 +00007257 /* Loop through each root page. */
danb40af492019-04-22 20:52:12 +00007258 shellPrepare(pState->db, &rc,
7259 "SELECT root, intkey, max(maxlen) FROM recovery.map"
dan38f9c712019-04-23 18:03:02 +00007260 " WHERE root>1 GROUP BY root, intkey ORDER BY root=("
7261 " SELECT rootpage FROM recovery.schema WHERE name='sqlite_sequence'"
7262 ")", &pLoop
danb40af492019-04-22 20:52:12 +00007263 );
dan68cb86e2019-04-20 20:57:28 +00007264 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){
7265 int iRoot = sqlite3_column_int(pLoop, 0);
danb40af492019-04-22 20:52:12 +00007266 int bIntkey = sqlite3_column_int(pLoop, 1);
7267 int nCol = sqlite3_column_int(pLoop, 2);
dan98c5ad32019-04-26 21:11:37 +00007268 int bNoop = 0;
dan68cb86e2019-04-20 20:57:28 +00007269 RecoverTable *pTab;
7270
dan9443dbc2019-07-24 20:10:27 +00007271 assert( bIntkey==0 || bIntkey==1 );
dan42ebb012019-04-27 18:47:03 +00007272 pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
dan98c5ad32019-04-26 21:11:37 +00007273 if( bNoop || rc ) continue;
dan98779652019-05-09 14:15:19 +00007274 if( pTab==0 ){
7275 if( pOrphan==0 ){
7276 pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
7277 }
7278 pTab = pOrphan;
7279 if( pTab==0 ) break;
7280 }
dan98c5ad32019-04-26 21:11:37 +00007281
drha2de66c2019-08-06 20:26:17 +00007282 if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){
dan98c5ad32019-04-26 21:11:37 +00007283 raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
7284 }
7285 sqlite3_bind_int(pPages, 1, iRoot);
dan8cce6b82019-09-14 16:44:51 +00007286 if( bRowids==0 && pTab->iPk<0 ){
7287 sqlite3_bind_int(pCells, 1, 1);
7288 }else{
7289 sqlite3_bind_int(pCells, 1, 0);
7290 }
7291 sqlite3_bind_int(pCells, 3, pTab->iPk);
dan98c5ad32019-04-26 21:11:37 +00007292
7293 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
7294 int iPgno = sqlite3_column_int(pPages, 0);
dan8cce6b82019-09-14 16:44:51 +00007295 sqlite3_bind_int(pCells, 2, iPgno);
dan98c5ad32019-04-26 21:11:37 +00007296 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
7297 int nField = sqlite3_column_int(pCells, 0);
dan9443dbc2019-07-24 20:10:27 +00007298 int iMin = sqlite3_column_int(pCells, 2);
dan98c5ad32019-04-26 21:11:37 +00007299 const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
7300
dan9443dbc2019-07-24 20:10:27 +00007301 RecoverTable *pTab2 = pTab;
7302 if( pTab!=pOrphan && (iMin<0)!=bIntkey ){
7303 if( pOrphan==0 ){
7304 pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
7305 }
7306 pTab2 = pOrphan;
7307 if( pTab2==0 ) break;
7308 }
7309
dan98c5ad32019-04-26 21:11:37 +00007310 nField = nField+1;
dan9443dbc2019-07-24 20:10:27 +00007311 if( pTab2==pOrphan ){
dan98c5ad32019-04-26 21:11:37 +00007312 raw_printf(pState->out,
7313 "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
dan9443dbc2019-07-24 20:10:27 +00007314 pTab2->zQuoted, iRoot, iPgno, nField,
7315 iMin<0 ? "" : "NULL, ", zVal, pTab2->azlCol[nField]
dan98c5ad32019-04-26 21:11:37 +00007316 );
7317 }else{
danefa363b2019-04-24 20:48:55 +00007318 raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n",
dan9443dbc2019-07-24 20:10:27 +00007319 pTab2->zQuoted, pTab2->azlCol[nField], zVal
danefa363b2019-04-24 20:48:55 +00007320 );
7321 }
dan68cb86e2019-04-20 20:57:28 +00007322 }
dan98c5ad32019-04-26 21:11:37 +00007323 shellReset(&rc, pCells);
dan68cb86e2019-04-20 20:57:28 +00007324 }
dan98c5ad32019-04-26 21:11:37 +00007325 shellReset(&rc, pPages);
7326 if( pTab!=pOrphan ) recoverFreeTable(pTab);
dan68cb86e2019-04-20 20:57:28 +00007327 }
7328 shellFinalize(&rc, pLoop);
danefa363b2019-04-24 20:48:55 +00007329 shellFinalize(&rc, pPages);
7330 shellFinalize(&rc, pCells);
dan98c5ad32019-04-26 21:11:37 +00007331 recoverFreeTable(pOrphan);
dan68cb86e2019-04-20 20:57:28 +00007332
dan38f9c712019-04-23 18:03:02 +00007333 /* The rest of the schema */
danb40af492019-04-22 20:52:12 +00007334 if( rc==SQLITE_OK ){
dan38f9c712019-04-23 18:03:02 +00007335 sqlite3_stmt *pStmt = 0;
7336 shellPrepare(pState->db, &rc,
7337 "SELECT sql, name FROM recovery.schema "
danb1825882019-04-23 20:48:32 +00007338 "WHERE sql NOT LIKE 'create table%'", &pStmt
dan38f9c712019-04-23 18:03:02 +00007339 );
7340 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
7341 const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
7342 if( sqlite3_strnicmp(zSql, "create virt", 11)==0 ){
7343 const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
7344 char *zPrint = shellMPrintf(&rc,
drh067b92b2020-06-19 15:24:12 +00007345 "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)",
dan38f9c712019-04-23 18:03:02 +00007346 zName, zName, zSql
7347 );
7348 raw_printf(pState->out, "%s;\n", zPrint);
7349 sqlite3_free(zPrint);
7350 }else{
7351 raw_printf(pState->out, "%s;\n", zSql);
7352 }
7353 }
7354 shellFinalize(&rc, pStmt);
7355 }
7356
7357 if( rc==SQLITE_OK ){
7358 raw_printf(pState->out, "PRAGMA writable_schema = off;\n");
danb40af492019-04-22 20:52:12 +00007359 raw_printf(pState->out, "COMMIT;\n");
7360 }
dan68cb86e2019-04-20 20:57:28 +00007361 sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0);
7362 return rc;
7363}
dan1b162162019-04-27 20:15:15 +00007364#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
dan68cb86e2019-04-20 20:57:28 +00007365
drh2ce15c32017-07-11 13:34:40 +00007366
7367/*
7368** If an input line begins with "." then invoke this routine to
7369** process that line.
7370**
7371** Return 1 on error, 2 to exit, and 0 otherwise.
7372*/
7373static int do_meta_command(char *zLine, ShellState *p){
7374 int h = 1;
7375 int nArg = 0;
7376 int n, c;
7377 int rc = 0;
drh5df84282019-08-17 19:45:25 +00007378 char *azArg[52];
drh2ce15c32017-07-11 13:34:40 +00007379
dan6b046be2018-01-09 15:25:55 +00007380#ifndef SQLITE_OMIT_VIRTUALTABLE
dan43efc182017-12-19 17:42:13 +00007381 if( p->expert.pExpert ){
7382 expertFinish(p, 1, 0);
7383 }
dan6b046be2018-01-09 15:25:55 +00007384#endif
dan43efc182017-12-19 17:42:13 +00007385
drh2ce15c32017-07-11 13:34:40 +00007386 /* Parse the input line into tokens.
7387 */
drh5df84282019-08-17 19:45:25 +00007388 while( zLine[h] && nArg<ArraySize(azArg)-1 ){
drh2ce15c32017-07-11 13:34:40 +00007389 while( IsSpace(zLine[h]) ){ h++; }
7390 if( zLine[h]==0 ) break;
7391 if( zLine[h]=='\'' || zLine[h]=='"' ){
7392 int delim = zLine[h++];
7393 azArg[nArg++] = &zLine[h];
7394 while( zLine[h] && zLine[h]!=delim ){
7395 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++;
7396 h++;
7397 }
7398 if( zLine[h]==delim ){
7399 zLine[h++] = 0;
7400 }
7401 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
7402 }else{
7403 azArg[nArg++] = &zLine[h];
7404 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; }
7405 if( zLine[h] ) zLine[h++] = 0;
7406 resolve_backslashes(azArg[nArg-1]);
7407 }
7408 }
drh5df84282019-08-17 19:45:25 +00007409 azArg[nArg] = 0;
drh2ce15c32017-07-11 13:34:40 +00007410
7411 /* Process the input line.
7412 */
7413 if( nArg==0 ) return 0; /* no tokens, no error */
7414 n = strlen30(azArg[0]);
7415 c = azArg[0][0];
drh13c20932018-01-10 21:41:55 +00007416 clearTempFile(p);
drh2ce15c32017-07-11 13:34:40 +00007417
7418#ifndef SQLITE_OMIT_AUTHORIZATION
7419 if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
7420 if( nArg!=2 ){
7421 raw_printf(stderr, "Usage: .auth ON|OFF\n");
7422 rc = 1;
7423 goto meta_command_exit;
7424 }
7425 open_db(p, 0);
7426 if( booleanValue(azArg[1]) ){
7427 sqlite3_set_authorizer(p->db, shellAuth, p);
7428 }else{
7429 sqlite3_set_authorizer(p->db, 0, 0);
7430 }
7431 }else
7432#endif
7433
drhe37c0e12018-01-06 19:19:50 +00007434#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
7435 if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
danfd0245d2017-12-07 15:44:29 +00007436 open_db(p, 0);
drhd0f9cdc2018-05-17 14:09:06 +00007437 rc = arDotCommand(p, 0, azArg, nArg);
danfd0245d2017-12-07 15:44:29 +00007438 }else
7439#endif
7440
drh2ce15c32017-07-11 13:34:40 +00007441 if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
7442 || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
7443 ){
7444 const char *zDestFile = 0;
7445 const char *zDb = 0;
7446 sqlite3 *pDest;
7447 sqlite3_backup *pBackup;
7448 int j;
drha50bffb2018-12-08 01:09:14 +00007449 int bAsync = 0;
drh69ed38a2018-05-14 00:23:08 +00007450 const char *zVfs = 0;
drh2ce15c32017-07-11 13:34:40 +00007451 for(j=1; j<nArg; j++){
7452 const char *z = azArg[j];
7453 if( z[0]=='-' ){
drh69ed38a2018-05-14 00:23:08 +00007454 if( z[1]=='-' ) z++;
7455 if( strcmp(z, "-append")==0 ){
7456 zVfs = "apndvfs";
7457 }else
drha50bffb2018-12-08 01:09:14 +00007458 if( strcmp(z, "-async")==0 ){
7459 bAsync = 1;
7460 }else
drh2ce15c32017-07-11 13:34:40 +00007461 {
7462 utf8_printf(stderr, "unknown option: %s\n", azArg[j]);
7463 return 1;
7464 }
7465 }else if( zDestFile==0 ){
7466 zDestFile = azArg[j];
7467 }else if( zDb==0 ){
7468 zDb = zDestFile;
7469 zDestFile = azArg[j];
7470 }else{
drha50bffb2018-12-08 01:09:14 +00007471 raw_printf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n");
drh2ce15c32017-07-11 13:34:40 +00007472 return 1;
7473 }
7474 }
7475 if( zDestFile==0 ){
7476 raw_printf(stderr, "missing FILENAME argument on .backup\n");
7477 return 1;
7478 }
7479 if( zDb==0 ) zDb = "main";
drh69ed38a2018-05-14 00:23:08 +00007480 rc = sqlite3_open_v2(zDestFile, &pDest,
7481 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
drh2ce15c32017-07-11 13:34:40 +00007482 if( rc!=SQLITE_OK ){
7483 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
drh9e804032018-05-18 17:11:50 +00007484 close_db(pDest);
drh2ce15c32017-07-11 13:34:40 +00007485 return 1;
7486 }
drha50bffb2018-12-08 01:09:14 +00007487 if( bAsync ){
7488 sqlite3_exec(pDest, "PRAGMA synchronous=OFF; PRAGMA journal_mode=OFF;",
7489 0, 0, 0);
7490 }
drh2ce15c32017-07-11 13:34:40 +00007491 open_db(p, 0);
7492 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
7493 if( pBackup==0 ){
7494 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
drh9e804032018-05-18 17:11:50 +00007495 close_db(pDest);
drh2ce15c32017-07-11 13:34:40 +00007496 return 1;
7497 }
7498 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
7499 sqlite3_backup_finish(pBackup);
7500 if( rc==SQLITE_DONE ){
7501 rc = 0;
7502 }else{
7503 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
7504 rc = 1;
7505 }
drh9e804032018-05-18 17:11:50 +00007506 close_db(pDest);
drh2ce15c32017-07-11 13:34:40 +00007507 }else
7508
7509 if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
7510 if( nArg==2 ){
7511 bail_on_error = booleanValue(azArg[1]);
7512 }else{
7513 raw_printf(stderr, "Usage: .bail on|off\n");
7514 rc = 1;
7515 }
7516 }else
7517
7518 if( c=='b' && n>=3 && strncmp(azArg[0], "binary", n)==0 ){
7519 if( nArg==2 ){
7520 if( booleanValue(azArg[1]) ){
7521 setBinaryMode(p->out, 1);
7522 }else{
7523 setTextMode(p->out, 1);
7524 }
7525 }else{
7526 raw_printf(stderr, "Usage: .binary on|off\n");
7527 rc = 1;
7528 }
7529 }else
7530
7531 if( c=='c' && strcmp(azArg[0],"cd")==0 ){
7532 if( nArg==2 ){
7533#if defined(_WIN32) || defined(WIN32)
7534 wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
7535 rc = !SetCurrentDirectoryW(z);
7536 sqlite3_free(z);
7537#else
7538 rc = chdir(azArg[1]);
7539#endif
7540 if( rc ){
7541 utf8_printf(stderr, "Cannot change to directory \"%s\"\n", azArg[1]);
7542 rc = 1;
7543 }
7544 }else{
7545 raw_printf(stderr, "Usage: .cd DIRECTORY\n");
7546 rc = 1;
7547 }
7548 }else
7549
7550 /* The undocumented ".breakpoint" command causes a call to the no-op
7551 ** routine named test_breakpoint().
7552 */
7553 if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
7554 test_breakpoint();
7555 }else
7556
7557 if( c=='c' && n>=3 && strncmp(azArg[0], "changes", n)==0 ){
7558 if( nArg==2 ){
7559 setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
7560 }else{
7561 raw_printf(stderr, "Usage: .changes on|off\n");
7562 rc = 1;
7563 }
7564 }else
7565
7566 /* Cancel output redirection, if it is currently set (by .testcase)
7567 ** Then read the content of the testcase-out.txt file and compare against
7568 ** azArg[1]. If there are differences, report an error and exit.
7569 */
7570 if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
7571 char *zRes = 0;
7572 output_reset(p);
7573 if( nArg!=2 ){
7574 raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
7575 rc = 2;
7576 }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
7577 raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
7578 rc = 2;
7579 }else if( testcase_glob(azArg[1],zRes)==0 ){
7580 utf8_printf(stderr,
7581 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
7582 p->zTestcase, azArg[1], zRes);
drhf30d3452017-10-17 13:44:46 +00007583 rc = 1;
drh2ce15c32017-07-11 13:34:40 +00007584 }else{
7585 utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
7586 p->nCheck++;
7587 }
7588 sqlite3_free(zRes);
7589 }else
7590
7591 if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
7592 if( nArg==2 ){
7593 tryToClone(p, azArg[1]);
7594 }else{
7595 raw_printf(stderr, "Usage: .clone FILENAME\n");
7596 rc = 1;
7597 }
7598 }else
7599
7600 if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
drh60081a02020-08-26 19:07:18 +00007601 char **azName = 0;
7602 int nName = 0;
7603 sqlite3_stmt *pStmt;
drh60081a02020-08-26 19:07:18 +00007604 int i;
drh2ce15c32017-07-11 13:34:40 +00007605 open_db(p, 0);
drh60081a02020-08-26 19:07:18 +00007606 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
7607 if( rc ){
7608 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh2ce15c32017-07-11 13:34:40 +00007609 rc = 1;
drh60081a02020-08-26 19:07:18 +00007610 }else{
7611 while( sqlite3_step(pStmt)==SQLITE_ROW ){
7612 const char *zSchema = (const char *)sqlite3_column_text(pStmt,1);
7613 const char *zFile = (const char*)sqlite3_column_text(pStmt,2);
7614 azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*));
7615 if( azName==0 ){ shell_out_of_memory(); /* Does not return */ }
7616 azName[nName*2] = strdup(zSchema);
7617 azName[nName*2+1] = strdup(zFile);
7618 nName++;
7619 }
drh2ce15c32017-07-11 13:34:40 +00007620 }
drh60081a02020-08-26 19:07:18 +00007621 sqlite3_finalize(pStmt);
7622 for(i=0; i<nName; i++){
7623 int eTxn = sqlite3_txn_state(p->db, azName[i*2]);
7624 int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]);
7625 const char *z = azName[i*2+1];
7626 utf8_printf(p->out, "%s: %s %s%s\n",
7627 azName[i*2],
7628 z && z[0] ? z : "\"\"",
7629 bRdonly ? "r/o" : "r/w",
7630 eTxn==SQLITE_TXN_NONE ? "" :
7631 eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn");
7632 free(azName[i*2]);
7633 free(azName[i*2+1]);
7634 }
7635 sqlite3_free(azName);
drh2ce15c32017-07-11 13:34:40 +00007636 }else
7637
drh7df01192018-04-28 12:43:16 +00007638 if( c=='d' && n>=3 && strncmp(azArg[0], "dbconfig", n)==0 ){
drheb7f2a02018-09-26 18:02:32 +00007639 static const struct DbConfigChoices {
7640 const char *zName;
7641 int op;
7642 } aDbConfig[] = {
drhb945bcd2019-12-31 22:52:10 +00007643 { "defensive", SQLITE_DBCONFIG_DEFENSIVE },
7644 { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
7645 { "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
drh0a6873b2019-06-14 21:25:25 +00007646 { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
drhb945bcd2019-12-31 22:52:10 +00007647 { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
drh0a6873b2019-06-14 21:25:25 +00007648 { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
drh11d88e62019-08-15 21:27:20 +00007649 { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
drh0a6873b2019-06-14 21:25:25 +00007650 { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
drhb945bcd2019-12-31 22:52:10 +00007651 { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
7652 { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT },
drh0a6873b2019-06-14 21:25:25 +00007653 { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
7654 { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
drh0a6873b2019-06-14 21:25:25 +00007655 { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
drhb945bcd2019-12-31 22:52:10 +00007656 { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
drhb77da372020-01-07 16:09:11 +00007657 { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA },
dan07312a62019-06-21 14:05:27 +00007658 { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA },
drh7df01192018-04-28 12:43:16 +00007659 };
7660 int ii, v;
7661 open_db(p, 0);
7662 for(ii=0; ii<ArraySize(aDbConfig); ii++){
7663 if( nArg>1 && strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
7664 if( nArg>=3 ){
7665 sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
7666 }
7667 sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
drhb945bcd2019-12-31 22:52:10 +00007668 utf8_printf(p->out, "%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
drh7df01192018-04-28 12:43:16 +00007669 if( nArg>1 ) break;
7670 }
7671 if( nArg>1 && ii==ArraySize(aDbConfig) ){
7672 utf8_printf(stderr, "Error: unknown dbconfig \"%s\"\n", azArg[1]);
7673 utf8_printf(stderr, "Enter \".dbconfig\" with no arguments for a list\n");
7674 }
7675 }else
7676
7677 if( c=='d' && n>=3 && strncmp(azArg[0], "dbinfo", n)==0 ){
drh2ce15c32017-07-11 13:34:40 +00007678 rc = shell_dbinfo_command(p, nArg, azArg);
7679 }else
7680
dan1b162162019-04-27 20:15:15 +00007681#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
dan68cb86e2019-04-20 20:57:28 +00007682 if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){
7683 open_db(p, 0);
danb9b71db2019-04-25 16:20:40 +00007684 rc = recoverDatabaseCmd(p, nArg, azArg);
dan68cb86e2019-04-20 20:57:28 +00007685 }else
dan1b162162019-04-27 20:15:15 +00007686#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */
dan68cb86e2019-04-20 20:57:28 +00007687
drh2ce15c32017-07-11 13:34:40 +00007688 if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
drh8e9297f2020-03-25 12:50:13 +00007689 char *zLike = 0;
7690 char *zSql;
drh2ce15c32017-07-11 13:34:40 +00007691 int i;
7692 int savedShowHeader = p->showHeader;
drhf213b332018-07-05 17:35:46 +00007693 int savedShellFlags = p->shellFlgs;
7694 ShellClearFlag(p, SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo);
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
7713 {
7714 raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
7715 rc = 1;
drh1d29fd82020-05-29 19:03:03 +00007716 sqlite3_free(zLike);
drh2ce15c32017-07-11 13:34:40 +00007717 goto meta_command_exit;
7718 }
7719 }else if( zLike ){
drhcdbb2812020-03-25 20:31:45 +00007720 zLike = sqlite3_mprintf("%z OR name LIKE %Q ESCAPE '\\'",
7721 zLike, azArg[i]);
drh2ce15c32017-07-11 13:34:40 +00007722 }else{
drhcdbb2812020-03-25 20:31:45 +00007723 zLike = sqlite3_mprintf("name LIKE %Q ESCAPE '\\'", azArg[i]);
drh2ce15c32017-07-11 13:34:40 +00007724 }
7725 }
dan68cb86e2019-04-20 20:57:28 +00007726
drh2ce15c32017-07-11 13:34:40 +00007727 open_db(p, 0);
dan68cb86e2019-04-20 20:57:28 +00007728
drh2ce15c32017-07-11 13:34:40 +00007729 /* When playing back a "dump", the content might appear in an order
7730 ** which causes immediate foreign key constraints to be violated.
7731 ** So disable foreign-key constraint enforcement to prevent problems. */
7732 raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
7733 raw_printf(p->out, "BEGIN TRANSACTION;\n");
7734 p->writableSchema = 0;
7735 p->showHeader = 0;
7736 /* Set writable_schema=ON since doing so forces SQLite to initialize
drh067b92b2020-06-19 15:24:12 +00007737 ** as much of the schema as it can even if the sqlite_schema table is
drh2ce15c32017-07-11 13:34:40 +00007738 ** corrupt. */
7739 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
7740 p->nErr = 0;
drh8e9297f2020-03-25 12:50:13 +00007741 if( zLike==0 ) zLike = sqlite3_mprintf("true");
7742 zSql = sqlite3_mprintf(
drh067b92b2020-06-19 15:24:12 +00007743 "SELECT name, type, sql FROM sqlite_schema "
drh8e9297f2020-03-25 12:50:13 +00007744 "WHERE (%s) AND type=='table'"
7745 " AND sql NOT NULL"
7746 " ORDER BY tbl_name='sqlite_sequence', rowid",
7747 zLike
7748 );
7749 run_schema_dump_query(p,zSql);
7750 sqlite3_free(zSql);
7751 zSql = sqlite3_mprintf(
drh067b92b2020-06-19 15:24:12 +00007752 "SELECT sql FROM sqlite_schema "
drh8e9297f2020-03-25 12:50:13 +00007753 "WHERE (%s) AND sql NOT NULL"
7754 " AND type IN ('index','trigger','view')",
7755 zLike
7756 );
7757 run_table_dump_query(p, zSql);
7758 sqlite3_free(zSql);
7759 sqlite3_free(zLike);
drh2ce15c32017-07-11 13:34:40 +00007760 if( p->writableSchema ){
7761 raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
7762 p->writableSchema = 0;
7763 }
7764 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
7765 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
dan68cb86e2019-04-20 20:57:28 +00007766 raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
drh2ce15c32017-07-11 13:34:40 +00007767 p->showHeader = savedShowHeader;
drhf213b332018-07-05 17:35:46 +00007768 p->shellFlgs = savedShellFlags;
drh2ce15c32017-07-11 13:34:40 +00007769 }else
7770
7771 if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
7772 if( nArg==2 ){
7773 setOrClearFlag(p, SHFLG_Echo, azArg[1]);
7774 }else{
7775 raw_printf(stderr, "Usage: .echo on|off\n");
7776 rc = 1;
7777 }
7778 }else
7779
7780 if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
7781 if( nArg==2 ){
drhe2ca99c2018-05-02 00:33:43 +00007782 p->autoEQPtest = 0;
drhb4e50392019-01-26 15:40:04 +00007783 if( p->autoEQPtrace ){
7784 if( p->db ) sqlite3_exec(p->db, "PRAGMA vdbe_trace=OFF;", 0, 0, 0);
7785 p->autoEQPtrace = 0;
7786 }
drh2ce15c32017-07-11 13:34:40 +00007787 if( strcmp(azArg[1],"full")==0 ){
drhada70452017-12-21 21:02:27 +00007788 p->autoEQP = AUTOEQP_full;
7789 }else if( strcmp(azArg[1],"trigger")==0 ){
7790 p->autoEQP = AUTOEQP_trigger;
drhb4e50392019-01-26 15:40:04 +00007791#ifdef SQLITE_DEBUG
drhe2ca99c2018-05-02 00:33:43 +00007792 }else if( strcmp(azArg[1],"test")==0 ){
7793 p->autoEQP = AUTOEQP_on;
7794 p->autoEQPtest = 1;
drhb4e50392019-01-26 15:40:04 +00007795 }else if( strcmp(azArg[1],"trace")==0 ){
7796 p->autoEQP = AUTOEQP_full;
7797 p->autoEQPtrace = 1;
7798 open_db(p, 0);
drh067b92b2020-06-19 15:24:12 +00007799 sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1", 0, 0, 0);
drhb4e50392019-01-26 15:40:04 +00007800 sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;", 0, 0, 0);
7801#endif
drh2ce15c32017-07-11 13:34:40 +00007802 }else{
mistachkinb71aa092018-01-23 00:05:18 +00007803 p->autoEQP = (u8)booleanValue(azArg[1]);
drh2ce15c32017-07-11 13:34:40 +00007804 }
7805 }else{
drhb4e50392019-01-26 15:40:04 +00007806 raw_printf(stderr, "Usage: .eqp off|on|trace|trigger|full\n");
drh2ce15c32017-07-11 13:34:40 +00007807 rc = 1;
7808 }
7809 }else
7810
7811 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
7812 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
7813 rc = 2;
7814 }else
7815
7816 /* The ".explain" command is automatic now. It is largely pointless. It
7817 ** retained purely for backwards compatibility */
7818 if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
7819 int val = 1;
7820 if( nArg>=2 ){
7821 if( strcmp(azArg[1],"auto")==0 ){
7822 val = 99;
7823 }else{
7824 val = booleanValue(azArg[1]);
7825 }
7826 }
7827 if( val==1 && p->mode!=MODE_Explain ){
7828 p->normalMode = p->mode;
7829 p->mode = MODE_Explain;
7830 p->autoExplain = 0;
7831 }else if( val==0 ){
7832 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
7833 p->autoExplain = 0;
7834 }else if( val==99 ){
7835 if( p->mode==MODE_Explain ) p->mode = p->normalMode;
7836 p->autoExplain = 1;
7837 }
7838 }else
7839
dan6b046be2018-01-09 15:25:55 +00007840#ifndef SQLITE_OMIT_VIRTUALTABLE
dan43efc182017-12-19 17:42:13 +00007841 if( c=='e' && strncmp(azArg[0], "expert", n)==0 ){
7842 open_db(p, 0);
7843 expertDotCommand(p, azArg, nArg);
7844 }else
dan6b046be2018-01-09 15:25:55 +00007845#endif
dan43efc182017-12-19 17:42:13 +00007846
drhd985f722019-06-05 14:29:53 +00007847 if( c=='f' && strncmp(azArg[0], "filectrl", n)==0 ){
7848 static const struct {
7849 const char *zCtrlName; /* Name of a test-control option */
7850 int ctrlCode; /* Integer code for that option */
7851 const char *zUsage; /* Usage notes */
7852 } aCtrl[] = {
7853 { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" },
7854 { "chunk_size", SQLITE_FCNTL_CHUNK_SIZE, "SIZE" },
7855 /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/
7856 { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" },
7857 { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" },
7858 /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/
7859 { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" },
7860 { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" },
7861 { "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" },
drh541ef2c2020-04-20 16:21:30 +00007862 { "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" },
drhd985f722019-06-05 14:29:53 +00007863 };
7864 int filectrl = -1;
7865 int iCtrl = -1;
drh4245e042019-06-13 13:52:46 +00007866 sqlite3_int64 iRes = 0; /* Integer result to display if rc2==1 */
7867 int isOk = 0; /* 0: usage 1: %lld 2: no-result */
drhd985f722019-06-05 14:29:53 +00007868 int n2, i;
7869 const char *zCmd = 0;
drh541ef2c2020-04-20 16:21:30 +00007870 const char *zSchema = 0;
drhd985f722019-06-05 14:29:53 +00007871
7872 open_db(p, 0);
7873 zCmd = nArg>=2 ? azArg[1] : "help";
7874
drh541ef2c2020-04-20 16:21:30 +00007875 if( zCmd[0]=='-'
7876 && (strcmp(zCmd,"--schema")==0 || strcmp(zCmd,"-schema")==0)
7877 && nArg>=4
7878 ){
7879 zSchema = azArg[2];
7880 for(i=3; i<nArg; i++) azArg[i-2] = azArg[i];
7881 nArg -= 2;
7882 zCmd = azArg[1];
7883 }
7884
drhd985f722019-06-05 14:29:53 +00007885 /* The argument can optionally begin with "-" or "--" */
7886 if( zCmd[0]=='-' && zCmd[1] ){
7887 zCmd++;
7888 if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
7889 }
7890
7891 /* --help lists all file-controls */
7892 if( strcmp(zCmd,"help")==0 ){
7893 utf8_printf(p->out, "Available file-controls:\n");
7894 for(i=0; i<ArraySize(aCtrl); i++){
7895 utf8_printf(p->out, " .filectrl %s %s\n",
7896 aCtrl[i].zCtrlName, aCtrl[i].zUsage);
7897 }
7898 rc = 1;
7899 goto meta_command_exit;
7900 }
7901
7902 /* convert filectrl text option to value. allow any unique prefix
7903 ** of the option name, or a numerical value. */
7904 n2 = strlen30(zCmd);
7905 for(i=0; i<ArraySize(aCtrl); i++){
7906 if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
7907 if( filectrl<0 ){
7908 filectrl = aCtrl[i].ctrlCode;
7909 iCtrl = i;
7910 }else{
7911 utf8_printf(stderr, "Error: ambiguous file-control: \"%s\"\n"
7912 "Use \".filectrl --help\" for help\n", zCmd);
7913 rc = 1;
7914 goto meta_command_exit;
7915 }
7916 }
7917 }
7918 if( filectrl<0 ){
7919 utf8_printf(stderr,"Error: unknown file-control: %s\n"
7920 "Use \".filectrl --help\" for help\n", zCmd);
7921 }else{
7922 switch(filectrl){
7923 case SQLITE_FCNTL_SIZE_LIMIT: {
7924 if( nArg!=2 && nArg!=3 ) break;
7925 iRes = nArg==3 ? integerValue(azArg[2]) : -1;
drh541ef2c2020-04-20 16:21:30 +00007926 sqlite3_file_control(p->db, zSchema, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
drhd985f722019-06-05 14:29:53 +00007927 isOk = 1;
7928 break;
7929 }
7930 case SQLITE_FCNTL_LOCK_TIMEOUT:
7931 case SQLITE_FCNTL_CHUNK_SIZE: {
7932 int x;
7933 if( nArg!=3 ) break;
7934 x = (int)integerValue(azArg[2]);
drh541ef2c2020-04-20 16:21:30 +00007935 sqlite3_file_control(p->db, zSchema, filectrl, &x);
drhd985f722019-06-05 14:29:53 +00007936 isOk = 2;
7937 break;
7938 }
7939 case SQLITE_FCNTL_PERSIST_WAL:
7940 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
7941 int x;
7942 if( nArg!=2 && nArg!=3 ) break;
7943 x = nArg==3 ? booleanValue(azArg[2]) : -1;
drh541ef2c2020-04-20 16:21:30 +00007944 sqlite3_file_control(p->db, zSchema, filectrl, &x);
drhd985f722019-06-05 14:29:53 +00007945 iRes = x;
7946 isOk = 1;
7947 break;
7948 }
7949 case SQLITE_FCNTL_HAS_MOVED: {
7950 int x;
7951 if( nArg!=2 ) break;
drh541ef2c2020-04-20 16:21:30 +00007952 sqlite3_file_control(p->db, zSchema, filectrl, &x);
drhd985f722019-06-05 14:29:53 +00007953 iRes = x;
7954 isOk = 1;
7955 break;
7956 }
7957 case SQLITE_FCNTL_TEMPFILENAME: {
7958 char *z = 0;
7959 if( nArg!=2 ) break;
drh541ef2c2020-04-20 16:21:30 +00007960 sqlite3_file_control(p->db, zSchema, filectrl, &z);
drhd985f722019-06-05 14:29:53 +00007961 if( z ){
7962 utf8_printf(p->out, "%s\n", z);
7963 sqlite3_free(z);
7964 }
7965 isOk = 2;
7966 break;
7967 }
drh541ef2c2020-04-20 16:21:30 +00007968 case SQLITE_FCNTL_RESERVE_BYTES: {
7969 int x;
7970 if( nArg>=3 ){
7971 x = atoi(azArg[2]);
7972 sqlite3_file_control(p->db, zSchema, filectrl, &x);
7973 }
7974 x = -1;
7975 sqlite3_file_control(p->db, zSchema, filectrl, &x);
7976 utf8_printf(p->out,"%d\n", x);
7977 isOk = 2;
7978 break;
7979 }
drhd985f722019-06-05 14:29:53 +00007980 }
7981 }
7982 if( isOk==0 && iCtrl>=0 ){
7983 utf8_printf(p->out, "Usage: .filectrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
7984 rc = 1;
7985 }else if( isOk==1 ){
drhe2500762019-06-13 14:07:41 +00007986 char zBuf[100];
7987 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes);
7988 raw_printf(p->out, "%s\n", zBuf);
drhd985f722019-06-05 14:29:53 +00007989 }
7990 }else
7991
drh2ce15c32017-07-11 13:34:40 +00007992 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
7993 ShellState data;
7994 char *zErrMsg = 0;
7995 int doStats = 0;
7996 memcpy(&data, p, sizeof(data));
7997 data.showHeader = 0;
7998 data.cMode = data.mode = MODE_Semi;
7999 if( nArg==2 && optionMatch(azArg[1], "indent") ){
8000 data.cMode = data.mode = MODE_Pretty;
8001 nArg = 1;
8002 }
8003 if( nArg!=1 ){
8004 raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
8005 rc = 1;
8006 goto meta_command_exit;
8007 }
8008 open_db(p, 0);
8009 rc = sqlite3_exec(p->db,
8010 "SELECT sql FROM"
8011 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
drh067b92b2020-06-19 15:24:12 +00008012 " FROM sqlite_schema UNION ALL"
8013 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) "
drh2ce15c32017-07-11 13:34:40 +00008014 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
8015 "ORDER BY rowid",
8016 callback, &data, &zErrMsg
8017 );
8018 if( rc==SQLITE_OK ){
8019 sqlite3_stmt *pStmt;
8020 rc = sqlite3_prepare_v2(p->db,
drh067b92b2020-06-19 15:24:12 +00008021 "SELECT rowid FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00008022 " WHERE name GLOB 'sqlite_stat[134]'",
8023 -1, &pStmt, 0);
8024 doStats = sqlite3_step(pStmt)==SQLITE_ROW;
8025 sqlite3_finalize(pStmt);
8026 }
8027 if( doStats==0 ){
8028 raw_printf(p->out, "/* No STAT tables available */\n");
8029 }else{
drh067b92b2020-06-19 15:24:12 +00008030 raw_printf(p->out, "ANALYZE sqlite_schema;\n");
8031 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_schema'",
drh2ce15c32017-07-11 13:34:40 +00008032 callback, &data, &zErrMsg);
8033 data.cMode = data.mode = MODE_Insert;
8034 data.zDestTable = "sqlite_stat1";
drh4c540452018-05-08 23:17:36 +00008035 shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
drh2ce15c32017-07-11 13:34:40 +00008036 data.zDestTable = "sqlite_stat4";
drh4c540452018-05-08 23:17:36 +00008037 shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
drh067b92b2020-06-19 15:24:12 +00008038 raw_printf(p->out, "ANALYZE sqlite_schema;\n");
drh2ce15c32017-07-11 13:34:40 +00008039 }
8040 }else
8041
8042 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
8043 if( nArg==2 ){
8044 p->showHeader = booleanValue(azArg[1]);
drhc0605082020-06-05 00:54:27 +00008045 p->shellFlgs |= SHFLG_HeaderSet;
drh2ce15c32017-07-11 13:34:40 +00008046 }else{
8047 raw_printf(stderr, "Usage: .headers on|off\n");
8048 rc = 1;
8049 }
8050 }else
8051
8052 if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
drh98aa2ab2018-09-26 16:53:51 +00008053 if( nArg>=2 ){
drhe93f8262018-10-11 16:53:37 +00008054 n = showHelp(p->out, azArg[1]);
drh98aa2ab2018-09-26 16:53:51 +00008055 if( n==0 ){
8056 utf8_printf(p->out, "Nothing matches '%s'\n", azArg[1]);
8057 }
8058 }else{
8059 showHelp(p->out, 0);
8060 }
drh2ce15c32017-07-11 13:34:40 +00008061 }else
8062
8063 if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
drhccb37812020-03-09 15:39:39 +00008064 char *zTable = 0; /* Insert data into this table */
8065 char *zFile = 0; /* Name of file to extra content from */
drh2ce15c32017-07-11 13:34:40 +00008066 sqlite3_stmt *pStmt = NULL; /* A statement */
8067 int nCol; /* Number of columns in the table */
8068 int nByte; /* Number of bytes in an SQL string */
8069 int i, j; /* Loop counters */
8070 int needCommit; /* True to COMMIT or ROLLBACK at end */
8071 int nSep; /* Number of bytes in p->colSeparator[] */
8072 char *zSql; /* An SQL statement */
8073 ImportCtx sCtx; /* Reader context */
8074 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
drhccb37812020-03-09 15:39:39 +00008075 int eVerbose = 0; /* Larger for more console output */
8076 int nSkip = 0; /* Initial lines to skip */
8077 int useOutputMode = 1; /* Use output mode to determine separators */
drh2ce15c32017-07-11 13:34:40 +00008078
drhccb37812020-03-09 15:39:39 +00008079 memset(&sCtx, 0, sizeof(sCtx));
8080 if( p->mode==MODE_Ascii ){
8081 xRead = ascii_read_one_field;
8082 }else{
8083 xRead = csv_read_one_field;
8084 }
8085 for(i=1; i<nArg; i++){
8086 char *z = azArg[i];
8087 if( z[0]=='-' && z[1]=='-' ) z++;
8088 if( z[0]!='-' ){
8089 if( zFile==0 ){
8090 zFile = z;
8091 }else if( zTable==0 ){
8092 zTable = z;
8093 }else{
8094 utf8_printf(p->out, "ERROR: extra argument: \"%s\". Usage:\n", z);
8095 showHelp(p->out, "import");
8096 rc = 1;
8097 goto meta_command_exit;
8098 }
8099 }else if( strcmp(z,"-v")==0 ){
8100 eVerbose++;
8101 }else if( strcmp(z,"-skip")==0 && i<nArg-1 ){
8102 nSkip = integerValue(azArg[++i]);
8103 }else if( strcmp(z,"-ascii")==0 ){
8104 sCtx.cColSep = SEP_Unit[0];
8105 sCtx.cRowSep = SEP_Record[0];
8106 xRead = ascii_read_one_field;
8107 useOutputMode = 0;
8108 }else if( strcmp(z,"-csv")==0 ){
8109 sCtx.cColSep = ',';
8110 sCtx.cRowSep = '\n';
8111 xRead = csv_read_one_field;
8112 useOutputMode = 0;
8113 }else{
8114 utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z);
8115 showHelp(p->out, "import");
8116 rc = 1;
8117 goto meta_command_exit;
8118 }
8119 }
8120 if( zTable==0 ){
8121 utf8_printf(p->out, "ERROR: missing %s argument. Usage:\n",
8122 zFile==0 ? "FILE" : "TABLE");
8123 showHelp(p->out, "import");
8124 rc = 1;
drh2ce15c32017-07-11 13:34:40 +00008125 goto meta_command_exit;
8126 }
drh2ce15c32017-07-11 13:34:40 +00008127 seenInterrupt = 0;
drh2ce15c32017-07-11 13:34:40 +00008128 open_db(p, 0);
drhccb37812020-03-09 15:39:39 +00008129 if( useOutputMode ){
8130 /* If neither the --csv or --ascii options are specified, then set
8131 ** the column and row separator characters from the output mode. */
8132 nSep = strlen30(p->colSeparator);
8133 if( nSep==0 ){
8134 raw_printf(stderr,
8135 "Error: non-null column separator required for import\n");
8136 rc = 1;
8137 goto meta_command_exit;
8138 }
8139 if( nSep>1 ){
8140 raw_printf(stderr,
8141 "Error: multi-character column separators not allowed"
8142 " for import\n");
8143 rc = 1;
8144 goto meta_command_exit;
8145 }
drh2ce15c32017-07-11 13:34:40 +00008146 nSep = strlen30(p->rowSeparator);
drhccb37812020-03-09 15:39:39 +00008147 if( nSep==0 ){
8148 raw_printf(stderr,
8149 "Error: non-null row separator required for import\n");
8150 rc = 1;
8151 goto meta_command_exit;
8152 }
8153 if( nSep==2 && p->mode==MODE_Csv && strcmp(p->rowSeparator,SEP_CrLf)==0 ){
8154 /* When importing CSV (only), if the row separator is set to the
8155 ** default output row separator, change it to the default input
8156 ** row separator. This avoids having to maintain different input
8157 ** and output row separators. */
8158 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
8159 nSep = strlen30(p->rowSeparator);
8160 }
8161 if( nSep>1 ){
8162 raw_printf(stderr, "Error: multi-character row separators not allowed"
8163 " for import\n");
8164 rc = 1;
8165 goto meta_command_exit;
8166 }
8167 sCtx.cColSep = p->colSeparator[0];
8168 sCtx.cRowSep = p->rowSeparator[0];
drh2ce15c32017-07-11 13:34:40 +00008169 }
8170 sCtx.zFile = zFile;
8171 sCtx.nLine = 1;
8172 if( sCtx.zFile[0]=='|' ){
8173#ifdef SQLITE_OMIT_POPEN
8174 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
drhccb37812020-03-09 15:39:39 +00008175 rc = 1;
8176 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008177#else
8178 sCtx.in = popen(sCtx.zFile+1, "r");
8179 sCtx.zFile = "<pipe>";
drh97767842020-05-29 19:39:35 +00008180 sCtx.xCloser = pclose;
drh2ce15c32017-07-11 13:34:40 +00008181#endif
8182 }else{
8183 sCtx.in = fopen(sCtx.zFile, "rb");
drh97767842020-05-29 19:39:35 +00008184 sCtx.xCloser = fclose;
drh2ce15c32017-07-11 13:34:40 +00008185 }
drh2ce15c32017-07-11 13:34:40 +00008186 if( sCtx.in==0 ){
8187 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
drhccb37812020-03-09 15:39:39 +00008188 rc = 1;
8189 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008190 }
drhccb37812020-03-09 15:39:39 +00008191 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
8192 char zSep[2];
8193 zSep[1] = 0;
8194 zSep[0] = sCtx.cColSep;
8195 utf8_printf(p->out, "Column separator ");
8196 output_c_string(p->out, zSep);
8197 utf8_printf(p->out, ", row separator ");
8198 zSep[0] = sCtx.cRowSep;
8199 output_c_string(p->out, zSep);
8200 utf8_printf(p->out, "\n");
8201 }
8202 while( (nSkip--)>0 ){
8203 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){}
drhccb37812020-03-09 15:39:39 +00008204 }
drh2ce15c32017-07-11 13:34:40 +00008205 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
8206 if( zSql==0 ){
drh97767842020-05-29 19:39:35 +00008207 import_cleanup(&sCtx);
drh4b5345c2018-04-24 13:07:40 +00008208 shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00008209 }
8210 nByte = strlen30(zSql);
8211 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8212 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */
8213 if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(p->db))==0 ){
8214 char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
8215 char cSep = '(';
8216 while( xRead(&sCtx) ){
8217 zCreate = sqlite3_mprintf("%z%c\n \"%w\" TEXT", zCreate, cSep, sCtx.z);
8218 cSep = ',';
8219 if( sCtx.cTerm!=sCtx.cColSep ) break;
8220 }
8221 if( cSep=='(' ){
8222 sqlite3_free(zCreate);
drh97767842020-05-29 19:39:35 +00008223 import_cleanup(&sCtx);
drh2ce15c32017-07-11 13:34:40 +00008224 utf8_printf(stderr,"%s: empty file\n", sCtx.zFile);
drhccb37812020-03-09 15:39:39 +00008225 rc = 1;
8226 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008227 }
8228 zCreate = sqlite3_mprintf("%z\n)", zCreate);
drhccb37812020-03-09 15:39:39 +00008229 if( eVerbose>=1 ){
8230 utf8_printf(p->out, "%s\n", zCreate);
8231 }
drh2ce15c32017-07-11 13:34:40 +00008232 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
8233 sqlite3_free(zCreate);
8234 if( rc ){
8235 utf8_printf(stderr, "CREATE TABLE %s(...) failed: %s\n", zTable,
8236 sqlite3_errmsg(p->db));
drh97767842020-05-29 19:39:35 +00008237 import_cleanup(&sCtx);
drhccb37812020-03-09 15:39:39 +00008238 rc = 1;
8239 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008240 }
8241 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8242 }
8243 sqlite3_free(zSql);
8244 if( rc ){
8245 if (pStmt) sqlite3_finalize(pStmt);
8246 utf8_printf(stderr,"Error: %s\n", sqlite3_errmsg(p->db));
drh97767842020-05-29 19:39:35 +00008247 import_cleanup(&sCtx);
drhccb37812020-03-09 15:39:39 +00008248 rc = 1;
8249 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008250 }
8251 nCol = sqlite3_column_count(pStmt);
8252 sqlite3_finalize(pStmt);
8253 pStmt = 0;
8254 if( nCol==0 ) return 0; /* no columns, no error */
8255 zSql = sqlite3_malloc64( nByte*2 + 20 + nCol*2 );
8256 if( zSql==0 ){
drh97767842020-05-29 19:39:35 +00008257 import_cleanup(&sCtx);
drh4b5345c2018-04-24 13:07:40 +00008258 shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00008259 }
8260 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO \"%w\" VALUES(?", zTable);
8261 j = strlen30(zSql);
8262 for(i=1; i<nCol; i++){
8263 zSql[j++] = ',';
8264 zSql[j++] = '?';
8265 }
8266 zSql[j++] = ')';
8267 zSql[j] = 0;
drhccb37812020-03-09 15:39:39 +00008268 if( eVerbose>=2 ){
8269 utf8_printf(p->out, "Insert using: %s\n", zSql);
8270 }
drh2ce15c32017-07-11 13:34:40 +00008271 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8272 sqlite3_free(zSql);
8273 if( rc ){
8274 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
8275 if (pStmt) sqlite3_finalize(pStmt);
drh97767842020-05-29 19:39:35 +00008276 import_cleanup(&sCtx);
drhccb37812020-03-09 15:39:39 +00008277 rc = 1;
8278 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00008279 }
8280 needCommit = sqlite3_get_autocommit(p->db);
8281 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
8282 do{
8283 int startLine = sCtx.nLine;
8284 for(i=0; i<nCol; i++){
8285 char *z = xRead(&sCtx);
8286 /*
8287 ** Did we reach end-of-file before finding any columns?
8288 ** If so, stop instead of NULL filling the remaining columns.
8289 */
8290 if( z==0 && i==0 ) break;
8291 /*
8292 ** Did we reach end-of-file OR end-of-line before finding any
8293 ** columns in ASCII mode? If so, stop instead of NULL filling
8294 ** the remaining columns.
8295 */
8296 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
8297 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
8298 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
8299 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
8300 "filling the rest with NULL\n",
8301 sCtx.zFile, startLine, nCol, i+1);
8302 i += 2;
8303 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
8304 }
8305 }
8306 if( sCtx.cTerm==sCtx.cColSep ){
8307 do{
8308 xRead(&sCtx);
8309 i++;
8310 }while( sCtx.cTerm==sCtx.cColSep );
8311 utf8_printf(stderr, "%s:%d: expected %d columns but found %d - "
8312 "extras ignored\n",
8313 sCtx.zFile, startLine, nCol, i);
8314 }
8315 if( i>=nCol ){
8316 sqlite3_step(pStmt);
8317 rc = sqlite3_reset(pStmt);
8318 if( rc!=SQLITE_OK ){
8319 utf8_printf(stderr, "%s:%d: INSERT failed: %s\n", sCtx.zFile,
8320 startLine, sqlite3_errmsg(p->db));
drhccb37812020-03-09 15:39:39 +00008321 sCtx.nErr++;
8322 }else{
8323 sCtx.nRow++;
drh2ce15c32017-07-11 13:34:40 +00008324 }
8325 }
8326 }while( sCtx.cTerm!=EOF );
8327
drh97767842020-05-29 19:39:35 +00008328 import_cleanup(&sCtx);
drh2ce15c32017-07-11 13:34:40 +00008329 sqlite3_finalize(pStmt);
8330 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
drhccb37812020-03-09 15:39:39 +00008331 if( eVerbose>0 ){
8332 utf8_printf(p->out,
8333 "Added %d rows with %d errors using %d lines of input\n",
8334 sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
8335 }
drh2ce15c32017-07-11 13:34:40 +00008336 }else
8337
8338#ifndef SQLITE_UNTESTABLE
8339 if( c=='i' && strncmp(azArg[0], "imposter", n)==0 ){
8340 char *zSql;
8341 char *zCollist = 0;
8342 sqlite3_stmt *pStmt;
8343 int tnum = 0;
drh491c5be2019-10-18 15:58:50 +00008344 int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */
8345 int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
drh2ce15c32017-07-11 13:34:40 +00008346 int i;
drh48d219a2018-04-23 18:38:48 +00008347 if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
8348 utf8_printf(stderr, "Usage: .imposter INDEX IMPOSTER\n"
8349 " .imposter off\n");
drh491c5be2019-10-18 15:58:50 +00008350 /* Also allowed, but not documented:
8351 **
8352 ** .imposter TABLE IMPOSTER
8353 **
8354 ** where TABLE is a WITHOUT ROWID table. In that case, the
8355 ** imposter is another WITHOUT ROWID table with the columns in
8356 ** storage order. */
drh2ce15c32017-07-11 13:34:40 +00008357 rc = 1;
8358 goto meta_command_exit;
8359 }
8360 open_db(p, 0);
drh48d219a2018-04-23 18:38:48 +00008361 if( nArg==2 ){
8362 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1);
8363 goto meta_command_exit;
8364 }
drh491c5be2019-10-18 15:58:50 +00008365 zSql = sqlite3_mprintf(
drh067b92b2020-06-19 15:24:12 +00008366 "SELECT rootpage, 0 FROM sqlite_schema"
drh491c5be2019-10-18 15:58:50 +00008367 " WHERE name='%q' AND type='index'"
8368 "UNION ALL "
drh067b92b2020-06-19 15:24:12 +00008369 "SELECT rootpage, 1 FROM sqlite_schema"
drh491c5be2019-10-18 15:58:50 +00008370 " WHERE name='%q' AND type='table'"
8371 " AND sql LIKE '%%without%%rowid%%'",
8372 azArg[1], azArg[1]
8373 );
drh2ce15c32017-07-11 13:34:40 +00008374 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8375 sqlite3_free(zSql);
8376 if( sqlite3_step(pStmt)==SQLITE_ROW ){
8377 tnum = sqlite3_column_int(pStmt, 0);
drh491c5be2019-10-18 15:58:50 +00008378 isWO = sqlite3_column_int(pStmt, 1);
drh2ce15c32017-07-11 13:34:40 +00008379 }
8380 sqlite3_finalize(pStmt);
drh2ce15c32017-07-11 13:34:40 +00008381 zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
8382 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8383 sqlite3_free(zSql);
8384 i = 0;
8385 while( sqlite3_step(pStmt)==SQLITE_ROW ){
8386 char zLabel[20];
8387 const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
8388 i++;
8389 if( zCol==0 ){
8390 if( sqlite3_column_int(pStmt,1)==-1 ){
8391 zCol = "_ROWID_";
8392 }else{
8393 sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i);
8394 zCol = zLabel;
8395 }
8396 }
drh491c5be2019-10-18 15:58:50 +00008397 if( isWO && lenPK==0 && sqlite3_column_int(pStmt,5)==0 && zCollist ){
8398 lenPK = (int)strlen(zCollist);
8399 }
drh2ce15c32017-07-11 13:34:40 +00008400 if( zCollist==0 ){
8401 zCollist = sqlite3_mprintf("\"%w\"", zCol);
8402 }else{
8403 zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
8404 }
8405 }
8406 sqlite3_finalize(pStmt);
drh491c5be2019-10-18 15:58:50 +00008407 if( i==0 || tnum==0 ){
8408 utf8_printf(stderr, "no such index: \"%s\"\n", azArg[1]);
8409 rc = 1;
8410 sqlite3_free(zCollist);
8411 goto meta_command_exit;
8412 }
8413 if( lenPK==0 ) lenPK = 100000;
drh2ce15c32017-07-11 13:34:40 +00008414 zSql = sqlite3_mprintf(
drh491c5be2019-10-18 15:58:50 +00008415 "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID",
8416 azArg[2], zCollist, lenPK, zCollist);
drh2ce15c32017-07-11 13:34:40 +00008417 sqlite3_free(zCollist);
8418 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
8419 if( rc==SQLITE_OK ){
8420 rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
8421 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
8422 if( rc ){
8423 utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
8424 }else{
8425 utf8_printf(stdout, "%s;\n", zSql);
8426 raw_printf(stdout,
drh491c5be2019-10-18 15:58:50 +00008427 "WARNING: writing to an imposter table will corrupt the \"%s\" %s!\n",
8428 azArg[1], isWO ? "table" : "index"
drh2ce15c32017-07-11 13:34:40 +00008429 );
8430 }
8431 }else{
8432 raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
8433 rc = 1;
8434 }
8435 sqlite3_free(zSql);
8436 }else
8437#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
8438
8439#ifdef SQLITE_ENABLE_IOTRACE
8440 if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
8441 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
8442 if( iotrace && iotrace!=stdout ) fclose(iotrace);
8443 iotrace = 0;
8444 if( nArg<2 ){
8445 sqlite3IoTrace = 0;
8446 }else if( strcmp(azArg[1], "-")==0 ){
8447 sqlite3IoTrace = iotracePrintf;
8448 iotrace = stdout;
8449 }else{
8450 iotrace = fopen(azArg[1], "w");
8451 if( iotrace==0 ){
8452 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
8453 sqlite3IoTrace = 0;
8454 rc = 1;
8455 }else{
8456 sqlite3IoTrace = iotracePrintf;
8457 }
8458 }
8459 }else
8460#endif
8461
8462 if( c=='l' && n>=5 && strncmp(azArg[0], "limits", n)==0 ){
8463 static const struct {
8464 const char *zLimitName; /* Name of a limit */
8465 int limitCode; /* Integer code for that limit */
8466 } aLimit[] = {
8467 { "length", SQLITE_LIMIT_LENGTH },
8468 { "sql_length", SQLITE_LIMIT_SQL_LENGTH },
8469 { "column", SQLITE_LIMIT_COLUMN },
8470 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH },
8471 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT },
8472 { "vdbe_op", SQLITE_LIMIT_VDBE_OP },
8473 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG },
8474 { "attached", SQLITE_LIMIT_ATTACHED },
8475 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH },
8476 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER },
8477 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
8478 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
8479 };
8480 int i, n2;
8481 open_db(p, 0);
8482 if( nArg==1 ){
8483 for(i=0; i<ArraySize(aLimit); i++){
8484 printf("%20s %d\n", aLimit[i].zLimitName,
8485 sqlite3_limit(p->db, aLimit[i].limitCode, -1));
8486 }
8487 }else if( nArg>3 ){
8488 raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
8489 rc = 1;
8490 goto meta_command_exit;
8491 }else{
8492 int iLimit = -1;
8493 n2 = strlen30(azArg[1]);
8494 for(i=0; i<ArraySize(aLimit); i++){
8495 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
8496 if( iLimit<0 ){
8497 iLimit = i;
8498 }else{
8499 utf8_printf(stderr, "ambiguous limit: \"%s\"\n", azArg[1]);
8500 rc = 1;
8501 goto meta_command_exit;
8502 }
8503 }
8504 }
8505 if( iLimit<0 ){
8506 utf8_printf(stderr, "unknown limit: \"%s\"\n"
8507 "enter \".limits\" with no arguments for a list.\n",
8508 azArg[1]);
8509 rc = 1;
8510 goto meta_command_exit;
8511 }
8512 if( nArg==3 ){
8513 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
8514 (int)integerValue(azArg[2]));
8515 }
8516 printf("%20s %d\n", aLimit[iLimit].zLimitName,
8517 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
8518 }
8519 }else
8520
8521 if( c=='l' && n>2 && strncmp(azArg[0], "lint", n)==0 ){
8522 open_db(p, 0);
8523 lintDotCommand(p, azArg, nArg);
8524 }else
8525
8526#ifndef SQLITE_OMIT_LOAD_EXTENSION
8527 if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
8528 const char *zFile, *zProc;
8529 char *zErrMsg = 0;
8530 if( nArg<2 ){
8531 raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
8532 rc = 1;
8533 goto meta_command_exit;
8534 }
8535 zFile = azArg[1];
8536 zProc = nArg>=3 ? azArg[2] : 0;
8537 open_db(p, 0);
8538 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
8539 if( rc!=SQLITE_OK ){
8540 utf8_printf(stderr, "Error: %s\n", zErrMsg);
8541 sqlite3_free(zErrMsg);
8542 rc = 1;
8543 }
8544 }else
8545#endif
8546
8547 if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
8548 if( nArg!=2 ){
8549 raw_printf(stderr, "Usage: .log FILENAME\n");
8550 rc = 1;
8551 }else{
8552 const char *zFile = azArg[1];
8553 output_file_close(p->pLog);
drha92a01a2018-01-10 22:15:37 +00008554 p->pLog = output_file_open(zFile, 0);
drh2ce15c32017-07-11 13:34:40 +00008555 }
8556 }else
8557
8558 if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
8559 const char *zMode = nArg>=2 ? azArg[1] : "";
drhaf2770f2018-01-05 14:55:43 +00008560 int n2 = strlen30(zMode);
drh2ce15c32017-07-11 13:34:40 +00008561 int c2 = zMode[0];
8562 if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
8563 p->mode = MODE_Line;
8564 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
8565 }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
8566 p->mode = MODE_Column;
drhc0605082020-06-05 00:54:27 +00008567 if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){
8568 p->showHeader = 1;
8569 }
drh2ce15c32017-07-11 13:34:40 +00008570 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
8571 }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
8572 p->mode = MODE_List;
8573 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column);
8574 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
8575 }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
8576 p->mode = MODE_Html;
8577 }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
8578 p->mode = MODE_Tcl;
8579 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space);
8580 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
8581 }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
8582 p->mode = MODE_Csv;
8583 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
8584 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
8585 }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
8586 p->mode = MODE_List;
8587 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab);
8588 }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
8589 p->mode = MODE_Insert;
8590 set_table_name(p, nArg>=3 ? azArg[2] : "table");
8591 }else if( c2=='q' && strncmp(azArg[1],"quote",n2)==0 ){
8592 p->mode = MODE_Quote;
drhc6835732020-05-28 20:37:17 +00008593 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
8594 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
drh2ce15c32017-07-11 13:34:40 +00008595 }else if( c2=='a' && strncmp(azArg[1],"ascii",n2)==0 ){
8596 p->mode = MODE_Ascii;
8597 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
8598 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
drh30c54a02020-05-28 23:49:50 +00008599 }else if( c2=='m' && strncmp(azArg[1],"markdown",n2)==0 ){
8600 p->mode = MODE_Markdown;
8601 }else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
8602 p->mode = MODE_Table;
drh0908e382020-06-04 18:05:39 +00008603 }else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
8604 p->mode = MODE_Box;
drh30c54a02020-05-28 23:49:50 +00008605 }else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
8606 p->mode = MODE_Json;
drh2ce15c32017-07-11 13:34:40 +00008607 }else if( nArg==1 ){
8608 raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
8609 }else{
8610 raw_printf(stderr, "Error: mode should be one of: "
drh0908e382020-06-04 18:05:39 +00008611 "ascii box column csv html insert json line list markdown "
drh30c54a02020-05-28 23:49:50 +00008612 "quote table tabs tcl\n");
drh2ce15c32017-07-11 13:34:40 +00008613 rc = 1;
8614 }
8615 p->cMode = p->mode;
8616 }else
8617
8618 if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
8619 if( nArg==2 ){
8620 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
8621 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
8622 }else{
8623 raw_printf(stderr, "Usage: .nullvalue STRING\n");
8624 rc = 1;
8625 }
8626 }else
8627
drh4a3a3eb2020-02-29 15:53:48 +00008628#ifdef SQLITE_DEBUG
8629 if( c=='o' && strcmp(azArg[0],"oom")==0 ){
8630 int i;
8631 for(i=1; i<nArg; i++){
8632 const char *z = azArg[i];
8633 if( z[0]=='-' && z[1]=='-' ) z++;
8634 if( strcmp(z,"-repeat")==0 ){
8635 if( i==nArg-1 ){
8636 raw_printf(p->out, "missing argument on \"%s\"\n", azArg[i]);
8637 rc = 1;
8638 }else{
8639 oomRepeat = (int)integerValue(azArg[++i]);
8640 }
8641 }else if( IsDigit(z[0]) ){
8642 oomCounter = (int)integerValue(azArg[i]);
8643 }else{
8644 raw_printf(p->out, "unknown argument: \"%s\"\n", azArg[i]);
8645 raw_printf(p->out, "Usage: .oom [--repeat N] [M]\n");
8646 rc = 1;
8647 }
8648 }
8649 if( rc==0 ){
8650 raw_printf(p->out, "oomCounter = %d\n", oomCounter);
8651 raw_printf(p->out, "oomRepeat = %d\n", oomRepeat);
8652 }
8653 }else
8654#endif /* SQLITE_DEBUG */
8655
drh2ce15c32017-07-11 13:34:40 +00008656 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
8657 char *zNewFilename; /* Name of the database file to open */
8658 int iName = 1; /* Index in azArg[] of the filename */
8659 int newFlag = 0; /* True to delete file before opening */
8660 /* Close the existing database */
8661 session_close_all(p);
drh9e804032018-05-18 17:11:50 +00008662 close_db(p->db);
drh2ce15c32017-07-11 13:34:40 +00008663 p->db = 0;
8664 p->zDbFilename = 0;
8665 sqlite3_free(p->zFreeOnClose);
8666 p->zFreeOnClose = 0;
drh1fa6d9f2018-01-06 21:46:01 +00008667 p->openMode = SHELL_OPEN_UNSPEC;
drh0933aad2019-11-18 17:46:38 +00008668 p->openFlags = 0;
drh6ca64482019-01-22 16:06:20 +00008669 p->szMax = 0;
drh2ce15c32017-07-11 13:34:40 +00008670 /* Check for command-line arguments */
8671 for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
8672 const char *z = azArg[iName];
8673 if( optionMatch(z,"new") ){
8674 newFlag = 1;
drh3baed312018-03-08 18:14:41 +00008675#ifdef SQLITE_HAVE_ZLIB
drh1fa6d9f2018-01-06 21:46:01 +00008676 }else if( optionMatch(z, "zip") ){
8677 p->openMode = SHELL_OPEN_ZIPFILE;
8678#endif
8679 }else if( optionMatch(z, "append") ){
8680 p->openMode = SHELL_OPEN_APPENDVFS;
drhee269a62018-02-14 23:27:43 +00008681 }else if( optionMatch(z, "readonly") ){
8682 p->openMode = SHELL_OPEN_READONLY;
drh0933aad2019-11-18 17:46:38 +00008683 }else if( optionMatch(z, "nofollow") ){
8684 p->openFlags |= SQLITE_OPEN_NOFOLLOW;
drha751f392018-10-30 15:31:22 +00008685#ifdef SQLITE_ENABLE_DESERIALIZE
drh60f34ae2018-10-30 13:19:49 +00008686 }else if( optionMatch(z, "deserialize") ){
8687 p->openMode = SHELL_OPEN_DESERIALIZE;
drh33746482018-12-13 15:06:26 +00008688 }else if( optionMatch(z, "hexdb") ){
8689 p->openMode = SHELL_OPEN_HEXDB;
drh6ca64482019-01-22 16:06:20 +00008690 }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
8691 p->szMax = integerValue(azArg[++iName]);
drh33746482018-12-13 15:06:26 +00008692#endif /* SQLITE_ENABLE_DESERIALIZE */
drh2ce15c32017-07-11 13:34:40 +00008693 }else if( z[0]=='-' ){
8694 utf8_printf(stderr, "unknown option: %s\n", z);
8695 rc = 1;
8696 goto meta_command_exit;
8697 }
8698 }
8699 /* If a filename is specified, try to open it first */
8700 zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
drh33746482018-12-13 15:06:26 +00008701 if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
drh2ce15c32017-07-11 13:34:40 +00008702 if( newFlag ) shellDeleteFile(zNewFilename);
8703 p->zDbFilename = zNewFilename;
drhbe4ccb22018-05-17 20:04:24 +00008704 open_db(p, OPEN_DB_KEEPALIVE);
drh2ce15c32017-07-11 13:34:40 +00008705 if( p->db==0 ){
8706 utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
8707 sqlite3_free(zNewFilename);
8708 }else{
8709 p->zFreeOnClose = zNewFilename;
8710 }
8711 }
8712 if( p->db==0 ){
8713 /* As a fall-back open a TEMP database */
8714 p->zDbFilename = 0;
8715 open_db(p, 0);
8716 }
8717 }else
8718
drh13c20932018-01-10 21:41:55 +00008719 if( (c=='o'
8720 && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
8721 || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
drh2ce15c32017-07-11 13:34:40 +00008722 ){
drh7a431002020-04-18 14:12:00 +00008723 const char *zFile = 0;
drha92a01a2018-01-10 22:15:37 +00008724 int bTxtMode = 0;
drh7a431002020-04-18 14:12:00 +00008725 int i;
8726 int eMode = 0;
8727 int bBOM = 0;
drh5415ab42020-04-23 20:45:46 +00008728 int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
drh7a431002020-04-18 14:12:00 +00008729
8730 if( c=='e' ){
8731 eMode = 'x';
8732 bOnce = 2;
8733 }else if( strncmp(azArg[0],"once",n)==0 ){
8734 bOnce = 1;
drh13c20932018-01-10 21:41:55 +00008735 }
drh7a431002020-04-18 14:12:00 +00008736 for(i=1; i<nArg; i++){
8737 char *z = azArg[i];
8738 if( z[0]=='-' ){
8739 if( z[1]=='-' ) z++;
8740 if( strcmp(z,"-bom")==0 ){
8741 bBOM = 1;
8742 }else if( c!='e' && strcmp(z,"-x")==0 ){
8743 eMode = 'x'; /* spreadsheet */
8744 }else if( c!='e' && strcmp(z,"-e")==0 ){
8745 eMode = 'e'; /* text editor */
8746 }else{
8747 utf8_printf(p->out, "ERROR: unknown option: \"%s\". Usage:\n",
8748 azArg[i]);
8749 showHelp(p->out, azArg[0]);
8750 rc = 1;
8751 goto meta_command_exit;
8752 }
8753 }else if( zFile==0 ){
8754 zFile = z;
8755 }else{
8756 utf8_printf(p->out,"ERROR: extra parameter: \"%s\". Usage:\n",
8757 azArg[i]);
8758 showHelp(p->out, azArg[0]);
drh2ce15c32017-07-11 13:34:40 +00008759 rc = 1;
8760 goto meta_command_exit;
8761 }
drh7a431002020-04-18 14:12:00 +00008762 }
8763 if( zFile==0 ) zFile = "stdout";
8764 if( bOnce ){
drh2ce15c32017-07-11 13:34:40 +00008765 p->outCount = 2;
8766 }else{
8767 p->outCount = 0;
8768 }
8769 output_reset(p);
drh04a28c32018-01-31 01:38:44 +00008770#ifndef SQLITE_NOHAVE_SYSTEM
drh7a431002020-04-18 14:12:00 +00008771 if( eMode=='e' || eMode=='x' ){
drh3c484e82018-01-10 22:27:21 +00008772 p->doXdgOpen = 1;
8773 outputModePush(p);
drh7a431002020-04-18 14:12:00 +00008774 if( eMode=='x' ){
8775 /* spreadsheet mode. Output as CSV. */
drh13c20932018-01-10 21:41:55 +00008776 newTempFile(p, "csv");
drh7a431002020-04-18 14:12:00 +00008777 ShellClearFlag(p, SHFLG_Echo);
drh13c20932018-01-10 21:41:55 +00008778 p->mode = MODE_Csv;
8779 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
8780 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
8781 }else{
drh7a431002020-04-18 14:12:00 +00008782 /* text editor mode */
drh13c20932018-01-10 21:41:55 +00008783 newTempFile(p, "txt");
drha92a01a2018-01-10 22:15:37 +00008784 bTxtMode = 1;
drh13c20932018-01-10 21:41:55 +00008785 }
8786 zFile = p->zTempFile;
8787 }
drh04a28c32018-01-31 01:38:44 +00008788#endif /* SQLITE_NOHAVE_SYSTEM */
drh2ce15c32017-07-11 13:34:40 +00008789 if( zFile[0]=='|' ){
8790#ifdef SQLITE_OMIT_POPEN
8791 raw_printf(stderr, "Error: pipes are not supported in this OS\n");
8792 rc = 1;
8793 p->out = stdout;
8794#else
8795 p->out = popen(zFile + 1, "w");
8796 if( p->out==0 ){
8797 utf8_printf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
8798 p->out = stdout;
8799 rc = 1;
8800 }else{
drh7a431002020-04-18 14:12:00 +00008801 if( bBOM ) fprintf(p->out,"\357\273\277");
drh2ce15c32017-07-11 13:34:40 +00008802 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
8803 }
8804#endif
8805 }else{
drha92a01a2018-01-10 22:15:37 +00008806 p->out = output_file_open(zFile, bTxtMode);
drh2ce15c32017-07-11 13:34:40 +00008807 if( p->out==0 ){
8808 if( strcmp(zFile,"off")!=0 ){
8809 utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
8810 }
8811 p->out = stdout;
8812 rc = 1;
8813 } else {
drh7a431002020-04-18 14:12:00 +00008814 if( bBOM ) fprintf(p->out,"\357\273\277");
drh2ce15c32017-07-11 13:34:40 +00008815 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
8816 }
8817 }
8818 }else
8819
drh9cb02642019-02-28 20:10:52 +00008820 if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
8821 open_db(p,0);
8822 if( nArg<=1 ) goto parameter_syntax_error;
8823
8824 /* .parameter clear
8825 ** Clear all bind parameters by dropping the TEMP table that holds them.
8826 */
8827 if( nArg==2 && strcmp(azArg[1],"clear")==0 ){
drh65c29fd2019-03-25 21:56:26 +00008828 sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;",
drh9cb02642019-02-28 20:10:52 +00008829 0, 0, 0);
8830 }else
8831
8832 /* .parameter list
8833 ** List all bind parameters.
8834 */
8835 if( nArg==2 && strcmp(azArg[1],"list")==0 ){
8836 sqlite3_stmt *pStmt = 0;
8837 int rx;
8838 int len = 0;
8839 rx = sqlite3_prepare_v2(p->db,
8840 "SELECT max(length(key)) "
drh65c29fd2019-03-25 21:56:26 +00008841 "FROM temp.sqlite_parameters;", -1, &pStmt, 0);
drh9cb02642019-02-28 20:10:52 +00008842 if( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
8843 len = sqlite3_column_int(pStmt, 0);
8844 if( len>40 ) len = 40;
8845 }
8846 sqlite3_finalize(pStmt);
8847 pStmt = 0;
8848 if( len ){
8849 rx = sqlite3_prepare_v2(p->db,
8850 "SELECT key, quote(value) "
drh65c29fd2019-03-25 21:56:26 +00008851 "FROM temp.sqlite_parameters;", -1, &pStmt, 0);
drh9cb02642019-02-28 20:10:52 +00008852 while( sqlite3_step(pStmt)==SQLITE_ROW ){
8853 utf8_printf(p->out, "%-*s %s\n", len, sqlite3_column_text(pStmt,0),
8854 sqlite3_column_text(pStmt,1));
8855 }
8856 sqlite3_finalize(pStmt);
8857 }
8858 }else
8859
8860 /* .parameter init
8861 ** Make sure the TEMP table used to hold bind parameters exists.
8862 ** Create it if necessary.
8863 */
8864 if( nArg==2 && strcmp(azArg[1],"init")==0 ){
8865 bind_table_init(p);
8866 }else
8867
8868 /* .parameter set NAME VALUE
8869 ** Set or reset a bind parameter. NAME should be the full parameter
8870 ** name exactly as it appears in the query. (ex: $abc, @def). The
8871 ** VALUE can be in either SQL literal notation, or if not it will be
8872 ** understood to be a text string.
8873 */
8874 if( nArg==4 && strcmp(azArg[1],"set")==0 ){
8875 int rx;
8876 char *zSql;
8877 sqlite3_stmt *pStmt;
8878 const char *zKey = azArg[2];
8879 const char *zValue = azArg[3];
8880 bind_table_init(p);
8881 zSql = sqlite3_mprintf(
drh65c29fd2019-03-25 21:56:26 +00008882 "REPLACE INTO temp.sqlite_parameters(key,value)"
drh9cb02642019-02-28 20:10:52 +00008883 "VALUES(%Q,%s);", zKey, zValue);
8884 if( zSql==0 ) shell_out_of_memory();
8885 pStmt = 0;
8886 rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8887 sqlite3_free(zSql);
8888 if( rx!=SQLITE_OK ){
8889 sqlite3_finalize(pStmt);
8890 pStmt = 0;
8891 zSql = sqlite3_mprintf(
drh65c29fd2019-03-25 21:56:26 +00008892 "REPLACE INTO temp.sqlite_parameters(key,value)"
drh9cb02642019-02-28 20:10:52 +00008893 "VALUES(%Q,%Q);", zKey, zValue);
8894 if( zSql==0 ) shell_out_of_memory();
8895 rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
8896 sqlite3_free(zSql);
8897 if( rx!=SQLITE_OK ){
8898 utf8_printf(p->out, "Error: %s\n", sqlite3_errmsg(p->db));
8899 sqlite3_finalize(pStmt);
8900 pStmt = 0;
8901 rc = 1;
8902 }
8903 }
8904 sqlite3_step(pStmt);
8905 sqlite3_finalize(pStmt);
8906 }else
8907
8908 /* .parameter unset NAME
8909 ** Remove the NAME binding from the parameter binding table, if it
8910 ** exists.
8911 */
8912 if( nArg==3 && strcmp(azArg[1],"unset")==0 ){
8913 char *zSql = sqlite3_mprintf(
drh65c29fd2019-03-25 21:56:26 +00008914 "DELETE FROM temp.sqlite_parameters WHERE key=%Q", azArg[2]);
drh9cb02642019-02-28 20:10:52 +00008915 if( zSql==0 ) shell_out_of_memory();
8916 sqlite3_exec(p->db, zSql, 0, 0, 0);
8917 sqlite3_free(zSql);
8918 }else
8919 /* If no command name matches, show a syntax error */
8920 parameter_syntax_error:
8921 showHelp(p->out, "parameter");
8922 }else
8923
drh2ce15c32017-07-11 13:34:40 +00008924 if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
8925 int i;
8926 for(i=1; i<nArg; i++){
8927 if( i>1 ) raw_printf(p->out, " ");
8928 utf8_printf(p->out, "%s", azArg[i]);
8929 }
8930 raw_printf(p->out, "\n");
8931 }else
8932
drh569b1d92019-02-05 20:51:41 +00008933#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
drh3f83f592019-02-04 14:53:18 +00008934 if( c=='p' && n>=3 && strncmp(azArg[0], "progress", n)==0 ){
8935 int i;
drhfc4eeef2019-02-05 19:48:46 +00008936 int nn = 0;
drh3f83f592019-02-04 14:53:18 +00008937 p->flgProgress = 0;
8938 p->mxProgress = 0;
8939 p->nProgress = 0;
8940 for(i=1; i<nArg; i++){
8941 const char *z = azArg[i];
8942 if( z[0]=='-' ){
8943 z++;
8944 if( z[0]=='-' ) z++;
8945 if( strcmp(z,"quiet")==0 || strcmp(z,"q")==0 ){
drhfc4eeef2019-02-05 19:48:46 +00008946 p->flgProgress |= SHELL_PROGRESS_QUIET;
drh3f83f592019-02-04 14:53:18 +00008947 continue;
8948 }
8949 if( strcmp(z,"reset")==0 ){
drhfc4eeef2019-02-05 19:48:46 +00008950 p->flgProgress |= SHELL_PROGRESS_RESET;
drh3f83f592019-02-04 14:53:18 +00008951 continue;
8952 }
8953 if( strcmp(z,"once")==0 ){
drhfc4eeef2019-02-05 19:48:46 +00008954 p->flgProgress |= SHELL_PROGRESS_ONCE;
drh3f83f592019-02-04 14:53:18 +00008955 continue;
8956 }
8957 if( strcmp(z,"limit")==0 ){
8958 if( i+1>=nArg ){
8959 utf8_printf(stderr, "Error: missing argument on --limit\n");
8960 rc = 1;
8961 goto meta_command_exit;
8962 }else{
8963 p->mxProgress = (int)integerValue(azArg[++i]);
8964 }
8965 continue;
8966 }
8967 utf8_printf(stderr, "Error: unknown option: \"%s\"\n", azArg[i]);
8968 rc = 1;
8969 goto meta_command_exit;
8970 }else{
drhfc4eeef2019-02-05 19:48:46 +00008971 nn = (int)integerValue(z);
drh3f83f592019-02-04 14:53:18 +00008972 }
8973 }
8974 open_db(p, 0);
drhfc4eeef2019-02-05 19:48:46 +00008975 sqlite3_progress_handler(p->db, nn, progress_handler, p);
drh3f83f592019-02-04 14:53:18 +00008976 }else
drh569b1d92019-02-05 20:51:41 +00008977#endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
drh3f83f592019-02-04 14:53:18 +00008978
drh2ce15c32017-07-11 13:34:40 +00008979 if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
8980 if( nArg >= 2) {
8981 strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
8982 }
8983 if( nArg >= 3) {
8984 strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
8985 }
8986 }else
8987
8988 if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
8989 rc = 2;
8990 }else
8991
8992 if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
drh60379d42018-12-13 18:30:01 +00008993 FILE *inSaved = p->in;
drh2c8ee022018-12-13 18:59:30 +00008994 int savedLineno = p->lineno;
drh2ce15c32017-07-11 13:34:40 +00008995 if( nArg!=2 ){
8996 raw_printf(stderr, "Usage: .read FILE\n");
8997 rc = 1;
8998 goto meta_command_exit;
8999 }
drh30497f42020-08-26 10:50:48 +00009000 if( azArg[1][0]=='|' ){
9001 p->in = popen(azArg[1]+1, "r");
9002 if( p->in==0 ){
9003 utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
9004 rc = 1;
9005 }else{
9006 rc = process_input(p);
9007 pclose(p->in);
9008 }
9009 }else if( notNormalFile(azArg[1]) || (p->in = fopen(azArg[1], "rb"))==0 ){
drh2ce15c32017-07-11 13:34:40 +00009010 utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
9011 rc = 1;
9012 }else{
drh60379d42018-12-13 18:30:01 +00009013 rc = process_input(p);
9014 fclose(p->in);
drh2ce15c32017-07-11 13:34:40 +00009015 }
drh60379d42018-12-13 18:30:01 +00009016 p->in = inSaved;
drh2c8ee022018-12-13 18:59:30 +00009017 p->lineno = savedLineno;
drh2ce15c32017-07-11 13:34:40 +00009018 }else
9019
9020 if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
9021 const char *zSrcFile;
9022 const char *zDb;
9023 sqlite3 *pSrc;
9024 sqlite3_backup *pBackup;
9025 int nTimeout = 0;
9026
9027 if( nArg==2 ){
9028 zSrcFile = azArg[1];
9029 zDb = "main";
9030 }else if( nArg==3 ){
9031 zSrcFile = azArg[2];
9032 zDb = azArg[1];
9033 }else{
9034 raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
9035 rc = 1;
9036 goto meta_command_exit;
9037 }
9038 rc = sqlite3_open(zSrcFile, &pSrc);
9039 if( rc!=SQLITE_OK ){
9040 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zSrcFile);
drh9e804032018-05-18 17:11:50 +00009041 close_db(pSrc);
drh2ce15c32017-07-11 13:34:40 +00009042 return 1;
9043 }
9044 open_db(p, 0);
9045 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
9046 if( pBackup==0 ){
9047 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
drh9e804032018-05-18 17:11:50 +00009048 close_db(pSrc);
drh2ce15c32017-07-11 13:34:40 +00009049 return 1;
9050 }
9051 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
9052 || rc==SQLITE_BUSY ){
9053 if( rc==SQLITE_BUSY ){
9054 if( nTimeout++ >= 3 ) break;
9055 sqlite3_sleep(100);
9056 }
9057 }
9058 sqlite3_backup_finish(pBackup);
9059 if( rc==SQLITE_DONE ){
9060 rc = 0;
9061 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
9062 raw_printf(stderr, "Error: source database is busy\n");
9063 rc = 1;
9064 }else{
9065 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
9066 rc = 1;
9067 }
drh9e804032018-05-18 17:11:50 +00009068 close_db(pSrc);
drh2ce15c32017-07-11 13:34:40 +00009069 }else
9070
drh2ce15c32017-07-11 13:34:40 +00009071 if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
9072 if( nArg==2 ){
mistachkinb71aa092018-01-23 00:05:18 +00009073 p->scanstatsOn = (u8)booleanValue(azArg[1]);
drh2ce15c32017-07-11 13:34:40 +00009074#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
9075 raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
9076#endif
9077 }else{
9078 raw_printf(stderr, "Usage: .scanstats on|off\n");
9079 rc = 1;
9080 }
9081 }else
9082
9083 if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
9084 ShellText sSelect;
9085 ShellState data;
9086 char *zErrMsg = 0;
drh667a2a22018-01-02 00:04:37 +00009087 const char *zDiv = "(";
drhceba7922018-01-01 21:28:25 +00009088 const char *zName = 0;
drh2ce15c32017-07-11 13:34:40 +00009089 int iSchema = 0;
drhceba7922018-01-01 21:28:25 +00009090 int bDebug = 0;
9091 int ii;
drh2ce15c32017-07-11 13:34:40 +00009092
9093 open_db(p, 0);
9094 memcpy(&data, p, sizeof(data));
9095 data.showHeader = 0;
9096 data.cMode = data.mode = MODE_Semi;
9097 initText(&sSelect);
drhceba7922018-01-01 21:28:25 +00009098 for(ii=1; ii<nArg; ii++){
9099 if( optionMatch(azArg[ii],"indent") ){
9100 data.cMode = data.mode = MODE_Pretty;
9101 }else if( optionMatch(azArg[ii],"debug") ){
9102 bDebug = 1;
9103 }else if( zName==0 ){
9104 zName = azArg[ii];
drh2ce15c32017-07-11 13:34:40 +00009105 }else{
drhceba7922018-01-01 21:28:25 +00009106 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n");
9107 rc = 1;
9108 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00009109 }
drh2ce15c32017-07-11 13:34:40 +00009110 }
drhceba7922018-01-01 21:28:25 +00009111 if( zName!=0 ){
drh067b92b2020-06-19 15:24:12 +00009112 int isSchema = sqlite3_strlike(zName, "sqlite_master", '\\')==0
drh346a70c2020-06-15 20:27:35 +00009113 || sqlite3_strlike(zName, "sqlite_schema", '\\')==0
9114 || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0
9115 || sqlite3_strlike(zName,"sqlite_temp_schema", '\\')==0;
drh067b92b2020-06-19 15:24:12 +00009116 if( isSchema ){
drh2ce15c32017-07-11 13:34:40 +00009117 char *new_argv[2], *new_colv[2];
drhc22b7162018-01-01 20:11:23 +00009118 new_argv[0] = sqlite3_mprintf(
9119 "CREATE TABLE %s (\n"
drh2ce15c32017-07-11 13:34:40 +00009120 " type text,\n"
9121 " name text,\n"
9122 " tbl_name text,\n"
9123 " rootpage integer,\n"
9124 " sql text\n"
drh346a70c2020-06-15 20:27:35 +00009125 ")", zName);
drh2ce15c32017-07-11 13:34:40 +00009126 new_argv[1] = 0;
9127 new_colv[0] = "sql";
9128 new_colv[1] = 0;
9129 callback(&data, 1, new_argv, new_colv);
drhc22b7162018-01-01 20:11:23 +00009130 sqlite3_free(new_argv[0]);
drh2ce15c32017-07-11 13:34:40 +00009131 }
drh2ce15c32017-07-11 13:34:40 +00009132 }
9133 if( zDiv ){
9134 sqlite3_stmt *pStmt = 0;
9135 rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
9136 -1, &pStmt, 0);
9137 if( rc ){
9138 utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
9139 sqlite3_finalize(pStmt);
9140 rc = 1;
9141 goto meta_command_exit;
9142 }
9143 appendText(&sSelect, "SELECT sql FROM", 0);
9144 iSchema = 0;
9145 while( sqlite3_step(pStmt)==SQLITE_ROW ){
9146 const char *zDb = (const char*)sqlite3_column_text(pStmt, 0);
9147 char zScNum[30];
9148 sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema);
9149 appendText(&sSelect, zDiv, 0);
9150 zDiv = " UNION ALL ";
drhceba7922018-01-01 21:28:25 +00009151 appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
9152 if( sqlite3_stricmp(zDb, "main")!=0 ){
drhea38f4f2019-07-13 17:21:47 +00009153 appendText(&sSelect, zDb, '\'');
drh2ce15c32017-07-11 13:34:40 +00009154 }else{
drhceba7922018-01-01 21:28:25 +00009155 appendText(&sSelect, "NULL", 0);
drh2ce15c32017-07-11 13:34:40 +00009156 }
drhceba7922018-01-01 21:28:25 +00009157 appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0);
9158 appendText(&sSelect, zScNum, 0);
9159 appendText(&sSelect, " AS snum, ", 0);
9160 appendText(&sSelect, zDb, '\'');
9161 appendText(&sSelect, " AS sname FROM ", 0);
drhea38f4f2019-07-13 17:21:47 +00009162 appendText(&sSelect, zDb, quoteChar(zDb));
drh067b92b2020-06-19 15:24:12 +00009163 appendText(&sSelect, ".sqlite_schema", 0);
drh2ce15c32017-07-11 13:34:40 +00009164 }
9165 sqlite3_finalize(pStmt);
drhcc3f3d12019-08-17 15:27:58 +00009166#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
drh667a2a22018-01-02 00:04:37 +00009167 if( zName ){
9168 appendText(&sSelect,
9169 " UNION ALL SELECT shell_module_schema(name),"
drhe2754c12019-08-26 12:50:01 +00009170 " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list",
9171 0);
drh667a2a22018-01-02 00:04:37 +00009172 }
drhcde7b772018-01-02 12:50:40 +00009173#endif
drh2ce15c32017-07-11 13:34:40 +00009174 appendText(&sSelect, ") WHERE ", 0);
drhceba7922018-01-01 21:28:25 +00009175 if( zName ){
9176 char *zQarg = sqlite3_mprintf("%Q", zName);
mistachkin9d107262018-03-23 14:24:34 +00009177 int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
9178 strchr(zName, '[') != 0;
drhceba7922018-01-01 21:28:25 +00009179 if( strchr(zName, '.') ){
drh2ce15c32017-07-11 13:34:40 +00009180 appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
9181 }else{
9182 appendText(&sSelect, "lower(tbl_name)", 0);
9183 }
mistachkin9d107262018-03-23 14:24:34 +00009184 appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0);
drh2ce15c32017-07-11 13:34:40 +00009185 appendText(&sSelect, zQarg, 0);
mistachkin9d107262018-03-23 14:24:34 +00009186 if( !bGlob ){
9187 appendText(&sSelect, " ESCAPE '\\' ", 0);
9188 }
drh2ce15c32017-07-11 13:34:40 +00009189 appendText(&sSelect, " AND ", 0);
9190 sqlite3_free(zQarg);
9191 }
9192 appendText(&sSelect, "type!='meta' AND sql IS NOT NULL"
9193 " ORDER BY snum, rowid", 0);
drhceba7922018-01-01 21:28:25 +00009194 if( bDebug ){
9195 utf8_printf(p->out, "SQL: %s;\n", sSelect.z);
9196 }else{
9197 rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
9198 }
drh2ce15c32017-07-11 13:34:40 +00009199 freeText(&sSelect);
9200 }
9201 if( zErrMsg ){
9202 utf8_printf(stderr,"Error: %s\n", zErrMsg);
9203 sqlite3_free(zErrMsg);
9204 rc = 1;
9205 }else if( rc != SQLITE_OK ){
9206 raw_printf(stderr,"Error: querying schema information\n");
9207 rc = 1;
9208 }else{
9209 rc = 0;
9210 }
9211 }else
9212
9213#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_SELECTTRACE)
9214 if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){
dana6c13b22020-08-08 17:02:39 +00009215 sqlite3_unsupported_selecttrace = nArg>=2 ? (int)integerValue(azArg[1]) : 0xffff;
drh2ce15c32017-07-11 13:34:40 +00009216 }else
9217#endif
9218
9219#if defined(SQLITE_ENABLE_SESSION)
9220 if( c=='s' && strncmp(azArg[0],"session",n)==0 && n>=3 ){
9221 OpenSession *pSession = &p->aSession[0];
9222 char **azCmd = &azArg[1];
9223 int iSes = 0;
9224 int nCmd = nArg - 1;
9225 int i;
9226 if( nArg<=1 ) goto session_syntax_error;
9227 open_db(p, 0);
9228 if( nArg>=3 ){
9229 for(iSes=0; iSes<p->nSession; iSes++){
9230 if( strcmp(p->aSession[iSes].zName, azArg[1])==0 ) break;
9231 }
9232 if( iSes<p->nSession ){
9233 pSession = &p->aSession[iSes];
9234 azCmd++;
9235 nCmd--;
9236 }else{
9237 pSession = &p->aSession[0];
9238 iSes = 0;
9239 }
9240 }
9241
9242 /* .session attach TABLE
9243 ** Invoke the sqlite3session_attach() interface to attach a particular
9244 ** table so that it is never filtered.
9245 */
9246 if( strcmp(azCmd[0],"attach")==0 ){
9247 if( nCmd!=2 ) goto session_syntax_error;
9248 if( pSession->p==0 ){
9249 session_not_open:
9250 raw_printf(stderr, "ERROR: No sessions are open\n");
9251 }else{
9252 rc = sqlite3session_attach(pSession->p, azCmd[1]);
9253 if( rc ){
9254 raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
9255 rc = 0;
9256 }
9257 }
9258 }else
9259
9260 /* .session changeset FILE
9261 ** .session patchset FILE
9262 ** Write a changeset or patchset into a file. The file is overwritten.
9263 */
9264 if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
9265 FILE *out = 0;
9266 if( nCmd!=2 ) goto session_syntax_error;
9267 if( pSession->p==0 ) goto session_not_open;
9268 out = fopen(azCmd[1], "wb");
9269 if( out==0 ){
drhe2754c12019-08-26 12:50:01 +00009270 utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n",
9271 azCmd[1]);
drh2ce15c32017-07-11 13:34:40 +00009272 }else{
9273 int szChng;
9274 void *pChng;
9275 if( azCmd[0][0]=='c' ){
9276 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
9277 }else{
9278 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
9279 }
9280 if( rc ){
9281 printf("Error: error code %d\n", rc);
9282 rc = 0;
9283 }
9284 if( pChng
9285 && fwrite(pChng, szChng, 1, out)!=1 ){
9286 raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
9287 szChng);
9288 }
9289 sqlite3_free(pChng);
9290 fclose(out);
9291 }
9292 }else
9293
9294 /* .session close
9295 ** Close the identified session
9296 */
9297 if( strcmp(azCmd[0], "close")==0 ){
9298 if( nCmd!=1 ) goto session_syntax_error;
9299 if( p->nSession ){
9300 session_close(pSession);
9301 p->aSession[iSes] = p->aSession[--p->nSession];
9302 }
9303 }else
9304
9305 /* .session enable ?BOOLEAN?
9306 ** Query or set the enable flag
9307 */
9308 if( strcmp(azCmd[0], "enable")==0 ){
9309 int ii;
9310 if( nCmd>2 ) goto session_syntax_error;
9311 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
9312 if( p->nSession ){
9313 ii = sqlite3session_enable(pSession->p, ii);
9314 utf8_printf(p->out, "session %s enable flag = %d\n",
9315 pSession->zName, ii);
9316 }
9317 }else
9318
9319 /* .session filter GLOB ....
9320 ** Set a list of GLOB patterns of table names to be excluded.
9321 */
9322 if( strcmp(azCmd[0], "filter")==0 ){
9323 int ii, nByte;
9324 if( nCmd<2 ) goto session_syntax_error;
9325 if( p->nSession ){
9326 for(ii=0; ii<pSession->nFilter; ii++){
9327 sqlite3_free(pSession->azFilter[ii]);
9328 }
9329 sqlite3_free(pSession->azFilter);
9330 nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
9331 pSession->azFilter = sqlite3_malloc( nByte );
9332 if( pSession->azFilter==0 ){
9333 raw_printf(stderr, "Error: out or memory\n");
9334 exit(1);
9335 }
9336 for(ii=1; ii<nCmd; ii++){
9337 pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
9338 }
9339 pSession->nFilter = ii-1;
9340 }
9341 }else
9342
9343 /* .session indirect ?BOOLEAN?
9344 ** Query or set the indirect flag
9345 */
9346 if( strcmp(azCmd[0], "indirect")==0 ){
9347 int ii;
9348 if( nCmd>2 ) goto session_syntax_error;
9349 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
9350 if( p->nSession ){
9351 ii = sqlite3session_indirect(pSession->p, ii);
9352 utf8_printf(p->out, "session %s indirect flag = %d\n",
9353 pSession->zName, ii);
9354 }
9355 }else
9356
9357 /* .session isempty
9358 ** Determine if the session is empty
9359 */
9360 if( strcmp(azCmd[0], "isempty")==0 ){
9361 int ii;
9362 if( nCmd!=1 ) goto session_syntax_error;
9363 if( p->nSession ){
9364 ii = sqlite3session_isempty(pSession->p);
9365 utf8_printf(p->out, "session %s isempty flag = %d\n",
9366 pSession->zName, ii);
9367 }
9368 }else
9369
9370 /* .session list
9371 ** List all currently open sessions
9372 */
9373 if( strcmp(azCmd[0],"list")==0 ){
9374 for(i=0; i<p->nSession; i++){
9375 utf8_printf(p->out, "%d %s\n", i, p->aSession[i].zName);
9376 }
9377 }else
9378
9379 /* .session open DB NAME
9380 ** Open a new session called NAME on the attached database DB.
9381 ** DB is normally "main".
9382 */
9383 if( strcmp(azCmd[0],"open")==0 ){
9384 char *zName;
9385 if( nCmd!=3 ) goto session_syntax_error;
9386 zName = azCmd[2];
9387 if( zName[0]==0 ) goto session_syntax_error;
9388 for(i=0; i<p->nSession; i++){
9389 if( strcmp(p->aSession[i].zName,zName)==0 ){
9390 utf8_printf(stderr, "Session \"%s\" already exists\n", zName);
9391 goto meta_command_exit;
9392 }
9393 }
9394 if( p->nSession>=ArraySize(p->aSession) ){
9395 raw_printf(stderr, "Maximum of %d sessions\n", ArraySize(p->aSession));
9396 goto meta_command_exit;
9397 }
9398 pSession = &p->aSession[p->nSession];
9399 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
9400 if( rc ){
9401 raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
9402 rc = 0;
9403 goto meta_command_exit;
9404 }
9405 pSession->nFilter = 0;
9406 sqlite3session_table_filter(pSession->p, session_filter, pSession);
9407 p->nSession++;
9408 pSession->zName = sqlite3_mprintf("%s", zName);
9409 }else
9410 /* If no command name matches, show a syntax error */
9411 session_syntax_error:
drheb7f2a02018-09-26 18:02:32 +00009412 showHelp(p->out, "session");
drh2ce15c32017-07-11 13:34:40 +00009413 }else
9414#endif
9415
9416#ifdef SQLITE_DEBUG
9417 /* Undocumented commands for internal testing. Subject to change
9418 ** without notice. */
9419 if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
9420 if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
9421 int i, v;
9422 for(i=1; i<nArg; i++){
9423 v = booleanValue(azArg[i]);
9424 utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
9425 }
9426 }
9427 if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
9428 int i; sqlite3_int64 v;
9429 for(i=1; i<nArg; i++){
9430 char zBuf[200];
9431 v = integerValue(azArg[i]);
9432 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
9433 utf8_printf(p->out, "%s", zBuf);
9434 }
9435 }
9436 }else
9437#endif
9438
9439 if( c=='s' && n>=4 && strncmp(azArg[0],"selftest",n)==0 ){
9440 int bIsInit = 0; /* True to initialize the SELFTEST table */
9441 int bVerbose = 0; /* Verbose output */
9442 int bSelftestExists; /* True if SELFTEST already exists */
9443 int i, k; /* Loop counters */
9444 int nTest = 0; /* Number of tests runs */
9445 int nErr = 0; /* Number of errors seen */
9446 ShellText str; /* Answer for a query */
9447 sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */
9448
9449 open_db(p,0);
9450 for(i=1; i<nArg; i++){
9451 const char *z = azArg[i];
9452 if( z[0]=='-' && z[1]=='-' ) z++;
9453 if( strcmp(z,"-init")==0 ){
9454 bIsInit = 1;
9455 }else
9456 if( strcmp(z,"-v")==0 ){
9457 bVerbose++;
9458 }else
9459 {
9460 utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
9461 azArg[i], azArg[0]);
9462 raw_printf(stderr, "Should be one of: --init -v\n");
9463 rc = 1;
9464 goto meta_command_exit;
9465 }
9466 }
9467 if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0)
9468 != SQLITE_OK ){
9469 bSelftestExists = 0;
9470 }else{
9471 bSelftestExists = 1;
9472 }
9473 if( bIsInit ){
9474 createSelftestTable(p);
9475 bSelftestExists = 1;
9476 }
9477 initText(&str);
9478 appendText(&str, "x", 0);
9479 for(k=bSelftestExists; k>=0; k--){
9480 if( k==1 ){
9481 rc = sqlite3_prepare_v2(p->db,
9482 "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno",
9483 -1, &pStmt, 0);
9484 }else{
9485 rc = sqlite3_prepare_v2(p->db,
9486 "VALUES(0,'memo','Missing SELFTEST table - default checks only',''),"
9487 " (1,'run','PRAGMA integrity_check','ok')",
9488 -1, &pStmt, 0);
9489 }
9490 if( rc ){
9491 raw_printf(stderr, "Error querying the selftest table\n");
9492 rc = 1;
9493 sqlite3_finalize(pStmt);
9494 goto meta_command_exit;
9495 }
9496 for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){
9497 int tno = sqlite3_column_int(pStmt, 0);
9498 const char *zOp = (const char*)sqlite3_column_text(pStmt, 1);
9499 const char *zSql = (const char*)sqlite3_column_text(pStmt, 2);
9500 const char *zAns = (const char*)sqlite3_column_text(pStmt, 3);
9501
9502 k = 0;
9503 if( bVerbose>0 ){
9504 char *zQuote = sqlite3_mprintf("%q", zSql);
9505 printf("%d: %s %s\n", tno, zOp, zSql);
9506 sqlite3_free(zQuote);
9507 }
9508 if( strcmp(zOp,"memo")==0 ){
9509 utf8_printf(p->out, "%s\n", zSql);
9510 }else
9511 if( strcmp(zOp,"run")==0 ){
9512 char *zErrMsg = 0;
9513 str.n = 0;
9514 str.z[0] = 0;
9515 rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
9516 nTest++;
9517 if( bVerbose ){
9518 utf8_printf(p->out, "Result: %s\n", str.z);
9519 }
9520 if( rc || zErrMsg ){
9521 nErr++;
9522 rc = 1;
9523 utf8_printf(p->out, "%d: error-code-%d: %s\n", tno, rc, zErrMsg);
9524 sqlite3_free(zErrMsg);
9525 }else if( strcmp(zAns,str.z)!=0 ){
9526 nErr++;
9527 rc = 1;
9528 utf8_printf(p->out, "%d: Expected: [%s]\n", tno, zAns);
9529 utf8_printf(p->out, "%d: Got: [%s]\n", tno, str.z);
9530 }
9531 }else
9532 {
9533 utf8_printf(stderr,
9534 "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
9535 rc = 1;
9536 break;
9537 }
9538 } /* End loop over rows of content from SELFTEST */
9539 sqlite3_finalize(pStmt);
9540 } /* End loop over k */
9541 freeText(&str);
9542 utf8_printf(p->out, "%d errors out of %d tests\n", nErr, nTest);
9543 }else
9544
9545 if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
9546 if( nArg<2 || nArg>3 ){
9547 raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
9548 rc = 1;
9549 }
9550 if( nArg>=2 ){
9551 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
9552 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
9553 }
9554 if( nArg>=3 ){
9555 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator,
9556 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]);
9557 }
9558 }else
9559
9560 if( c=='s' && n>=4 && strncmp(azArg[0],"sha3sum",n)==0 ){
9561 const char *zLike = 0; /* Which table to checksum. 0 means everything */
9562 int i; /* Loop counter */
9563 int bSchema = 0; /* Also hash the schema */
9564 int bSeparate = 0; /* Hash each table separately */
9565 int iSize = 224; /* Hash algorithm to use */
9566 int bDebug = 0; /* Only show the query that would have run */
9567 sqlite3_stmt *pStmt; /* For querying tables names */
9568 char *zSql; /* SQL to be run */
9569 char *zSep; /* Separator */
9570 ShellText sSql; /* Complete SQL for the query to run the hash */
9571 ShellText sQuery; /* Set of queries used to read all content */
9572 open_db(p, 0);
9573 for(i=1; i<nArg; i++){
9574 const char *z = azArg[i];
9575 if( z[0]=='-' ){
9576 z++;
9577 if( z[0]=='-' ) z++;
9578 if( strcmp(z,"schema")==0 ){
9579 bSchema = 1;
9580 }else
9581 if( strcmp(z,"sha3-224")==0 || strcmp(z,"sha3-256")==0
9582 || strcmp(z,"sha3-384")==0 || strcmp(z,"sha3-512")==0
9583 ){
9584 iSize = atoi(&z[5]);
9585 }else
9586 if( strcmp(z,"debug")==0 ){
9587 bDebug = 1;
9588 }else
9589 {
9590 utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
9591 azArg[i], azArg[0]);
drhe2754c12019-08-26 12:50:01 +00009592 showHelp(p->out, azArg[0]);
drh2ce15c32017-07-11 13:34:40 +00009593 rc = 1;
9594 goto meta_command_exit;
9595 }
9596 }else if( zLike ){
9597 raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
9598 rc = 1;
9599 goto meta_command_exit;
9600 }else{
9601 zLike = z;
9602 bSeparate = 1;
drhcedfecf2018-03-23 12:59:10 +00009603 if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1;
drh2ce15c32017-07-11 13:34:40 +00009604 }
9605 }
9606 if( bSchema ){
drh067b92b2020-06-19 15:24:12 +00009607 zSql = "SELECT lower(name) FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00009608 " WHERE type='table' AND coalesce(rootpage,0)>1"
drh067b92b2020-06-19 15:24:12 +00009609 " UNION ALL SELECT 'sqlite_schema'"
drh2ce15c32017-07-11 13:34:40 +00009610 " ORDER BY 1 collate nocase";
9611 }else{
drh067b92b2020-06-19 15:24:12 +00009612 zSql = "SELECT lower(name) FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00009613 " WHERE type='table' AND coalesce(rootpage,0)>1"
9614 " AND name NOT LIKE 'sqlite_%'"
9615 " ORDER BY 1 collate nocase";
9616 }
9617 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
9618 initText(&sQuery);
9619 initText(&sSql);
9620 appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0);
9621 zSep = "VALUES(";
9622 while( SQLITE_ROW==sqlite3_step(pStmt) ){
9623 const char *zTab = (const char*)sqlite3_column_text(pStmt,0);
9624 if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue;
9625 if( strncmp(zTab, "sqlite_",7)!=0 ){
9626 appendText(&sQuery,"SELECT * FROM ", 0);
9627 appendText(&sQuery,zTab,'"');
9628 appendText(&sQuery," NOT INDEXED;", 0);
drh067b92b2020-06-19 15:24:12 +00009629 }else if( strcmp(zTab, "sqlite_schema")==0 ){
9630 appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_schema"
drh2ce15c32017-07-11 13:34:40 +00009631 " ORDER BY name;", 0);
9632 }else if( strcmp(zTab, "sqlite_sequence")==0 ){
9633 appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence"
9634 " ORDER BY name;", 0);
9635 }else if( strcmp(zTab, "sqlite_stat1")==0 ){
9636 appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1"
9637 " ORDER BY tbl,idx;", 0);
drh175b8f02019-08-08 15:24:17 +00009638 }else if( strcmp(zTab, "sqlite_stat4")==0 ){
drh2ce15c32017-07-11 13:34:40 +00009639 appendText(&sQuery, "SELECT * FROM ", 0);
9640 appendText(&sQuery, zTab, 0);
9641 appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
9642 }
9643 appendText(&sSql, zSep, 0);
9644 appendText(&sSql, sQuery.z, '\'');
9645 sQuery.n = 0;
9646 appendText(&sSql, ",", 0);
9647 appendText(&sSql, zTab, '\'');
9648 zSep = "),(";
9649 }
9650 sqlite3_finalize(pStmt);
9651 if( bSeparate ){
9652 zSql = sqlite3_mprintf(
9653 "%s))"
9654 " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
9655 " FROM [sha3sum$query]",
9656 sSql.z, iSize);
9657 }else{
9658 zSql = sqlite3_mprintf(
9659 "%s))"
9660 " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
9661 " FROM [sha3sum$query]",
9662 sSql.z, iSize);
9663 }
9664 freeText(&sQuery);
9665 freeText(&sSql);
9666 if( bDebug ){
9667 utf8_printf(p->out, "%s\n", zSql);
9668 }else{
drha10b9992018-03-09 15:24:33 +00009669 shell_exec(p, zSql, 0);
drh2ce15c32017-07-11 13:34:40 +00009670 }
9671 sqlite3_free(zSql);
9672 }else
9673
drh04a28c32018-01-31 01:38:44 +00009674#ifndef SQLITE_NOHAVE_SYSTEM
drh2ce15c32017-07-11 13:34:40 +00009675 if( c=='s'
9676 && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
9677 ){
9678 char *zCmd;
9679 int i, x;
9680 if( nArg<2 ){
9681 raw_printf(stderr, "Usage: .system COMMAND\n");
9682 rc = 1;
9683 goto meta_command_exit;
9684 }
9685 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
9686 for(i=2; i<nArg; i++){
9687 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
9688 zCmd, azArg[i]);
9689 }
9690 x = system(zCmd);
9691 sqlite3_free(zCmd);
9692 if( x ) raw_printf(stderr, "System command returns %d\n", x);
9693 }else
drh04a28c32018-01-31 01:38:44 +00009694#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
drh2ce15c32017-07-11 13:34:40 +00009695
9696 if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
drhada70452017-12-21 21:02:27 +00009697 static const char *azBool[] = { "off", "on", "trigger", "full"};
drh2ce15c32017-07-11 13:34:40 +00009698 int i;
9699 if( nArg!=1 ){
9700 raw_printf(stderr, "Usage: .show\n");
9701 rc = 1;
9702 goto meta_command_exit;
9703 }
9704 utf8_printf(p->out, "%12.12s: %s\n","echo",
9705 azBool[ShellHasFlag(p, SHFLG_Echo)]);
9706 utf8_printf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
9707 utf8_printf(p->out, "%12.12s: %s\n","explain",
9708 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
9709 utf8_printf(p->out,"%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
9710 utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
9711 utf8_printf(p->out, "%12.12s: ", "nullvalue");
9712 output_c_string(p->out, p->nullValue);
9713 raw_printf(p->out, "\n");
9714 utf8_printf(p->out,"%12.12s: %s\n","output",
9715 strlen30(p->outfile) ? p->outfile : "stdout");
9716 utf8_printf(p->out,"%12.12s: ", "colseparator");
9717 output_c_string(p->out, p->colSeparator);
9718 raw_printf(p->out, "\n");
9719 utf8_printf(p->out,"%12.12s: ", "rowseparator");
9720 output_c_string(p->out, p->rowSeparator);
9721 raw_printf(p->out, "\n");
9722 utf8_printf(p->out, "%12.12s: %s\n","stats", azBool[p->statsOn!=0]);
9723 utf8_printf(p->out, "%12.12s: ", "width");
drh0285d982020-05-29 14:38:43 +00009724 for (i=0;i<p->nWidth;i++) {
drh2ce15c32017-07-11 13:34:40 +00009725 raw_printf(p->out, "%d ", p->colWidth[i]);
9726 }
9727 raw_printf(p->out, "\n");
9728 utf8_printf(p->out, "%12.12s: %s\n", "filename",
9729 p->zDbFilename ? p->zDbFilename : "");
9730 }else
9731
9732 if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
9733 if( nArg==2 ){
mistachkinb71aa092018-01-23 00:05:18 +00009734 p->statsOn = (u8)booleanValue(azArg[1]);
drh2ce15c32017-07-11 13:34:40 +00009735 }else if( nArg==1 ){
9736 display_stats(p->db, p, 0);
9737 }else{
9738 raw_printf(stderr, "Usage: .stats ?on|off?\n");
9739 rc = 1;
9740 }
9741 }else
9742
9743 if( (c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0)
9744 || (c=='i' && (strncmp(azArg[0], "indices", n)==0
9745 || strncmp(azArg[0], "indexes", n)==0) )
9746 ){
9747 sqlite3_stmt *pStmt;
9748 char **azResult;
9749 int nRow, nAlloc;
9750 int ii;
9751 ShellText s;
9752 initText(&s);
9753 open_db(p, 0);
9754 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
drh9e804032018-05-18 17:11:50 +00009755 if( rc ){
9756 sqlite3_finalize(pStmt);
9757 return shellDatabaseError(p->db);
9758 }
drh2ce15c32017-07-11 13:34:40 +00009759
9760 if( nArg>2 && c=='i' ){
9761 /* It is an historical accident that the .indexes command shows an error
9762 ** when called with the wrong number of arguments whereas the .tables
9763 ** command does not. */
9764 raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
9765 rc = 1;
drh9e804032018-05-18 17:11:50 +00009766 sqlite3_finalize(pStmt);
drh2ce15c32017-07-11 13:34:40 +00009767 goto meta_command_exit;
9768 }
9769 for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
9770 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
9771 if( zDbName==0 ) continue;
9772 if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
9773 if( sqlite3_stricmp(zDbName, "main")==0 ){
9774 appendText(&s, "SELECT name FROM ", 0);
9775 }else{
9776 appendText(&s, "SELECT ", 0);
9777 appendText(&s, zDbName, '\'');
9778 appendText(&s, "||'.'||name FROM ", 0);
9779 }
9780 appendText(&s, zDbName, '"');
drh067b92b2020-06-19 15:24:12 +00009781 appendText(&s, ".sqlite_schema ", 0);
drh2ce15c32017-07-11 13:34:40 +00009782 if( c=='t' ){
9783 appendText(&s," WHERE type IN ('table','view')"
9784 " AND name NOT LIKE 'sqlite_%'"
9785 " AND name LIKE ?1", 0);
9786 }else{
9787 appendText(&s," WHERE type='index'"
9788 " AND tbl_name LIKE ?1", 0);
9789 }
9790 }
9791 rc = sqlite3_finalize(pStmt);
9792 appendText(&s, " ORDER BY 1", 0);
9793 rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);
9794 freeText(&s);
9795 if( rc ) return shellDatabaseError(p->db);
9796
9797 /* Run the SQL statement prepared by the above block. Store the results
9798 ** as an array of nul-terminated strings in azResult[]. */
9799 nRow = nAlloc = 0;
9800 azResult = 0;
9801 if( nArg>1 ){
9802 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
9803 }else{
9804 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
9805 }
9806 while( sqlite3_step(pStmt)==SQLITE_ROW ){
9807 if( nRow>=nAlloc ){
9808 char **azNew;
9809 int n2 = nAlloc*2 + 10;
9810 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
drh4b5345c2018-04-24 13:07:40 +00009811 if( azNew==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00009812 nAlloc = n2;
9813 azResult = azNew;
9814 }
9815 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
drh4b5345c2018-04-24 13:07:40 +00009816 if( 0==azResult[nRow] ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +00009817 nRow++;
9818 }
9819 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
9820 rc = shellDatabaseError(p->db);
9821 }
9822
9823 /* Pretty-print the contents of array azResult[] to the output */
9824 if( rc==0 && nRow>0 ){
9825 int len, maxlen = 0;
9826 int i, j;
9827 int nPrintCol, nPrintRow;
9828 for(i=0; i<nRow; i++){
9829 len = strlen30(azResult[i]);
9830 if( len>maxlen ) maxlen = len;
9831 }
9832 nPrintCol = 80/(maxlen+2);
9833 if( nPrintCol<1 ) nPrintCol = 1;
9834 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
9835 for(i=0; i<nPrintRow; i++){
9836 for(j=i; j<nRow; j+=nPrintRow){
9837 char *zSp = j<nPrintRow ? "" : " ";
9838 utf8_printf(p->out, "%s%-*s", zSp, maxlen,
9839 azResult[j] ? azResult[j]:"");
9840 }
9841 raw_printf(p->out, "\n");
9842 }
9843 }
9844
9845 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
9846 sqlite3_free(azResult);
9847 }else
9848
9849 /* Begin redirecting output to the file "testcase-out.txt" */
9850 if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
9851 output_reset(p);
drha92a01a2018-01-10 22:15:37 +00009852 p->out = output_file_open("testcase-out.txt", 0);
drh2ce15c32017-07-11 13:34:40 +00009853 if( p->out==0 ){
9854 raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
9855 }
9856 if( nArg>=2 ){
9857 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
9858 }else{
9859 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
9860 }
9861 }else
9862
9863#ifndef SQLITE_UNTESTABLE
drh35f51a42017-11-15 17:07:22 +00009864 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
drh2ce15c32017-07-11 13:34:40 +00009865 static const struct {
9866 const char *zCtrlName; /* Name of a test-control option */
9867 int ctrlCode; /* Integer code for that option */
drhef302e82017-11-15 19:14:08 +00009868 const char *zUsage; /* Usage notes */
drh2ce15c32017-07-11 13:34:40 +00009869 } aCtrl[] = {
drhe2754c12019-08-26 12:50:01 +00009870 { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" },
9871 { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" },
9872 /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
9873 /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
9874 { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
9875 { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" },
9876 /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/
9877 { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
drh171c50e2020-01-01 15:43:30 +00009878 { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "" },
drhe2754c12019-08-26 12:50:01 +00009879 { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
9880 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
9881 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
drh0d9de992017-12-26 18:04:23 +00009882#ifdef YYCOVERAGE
drhe2754c12019-08-26 12:50:01 +00009883 { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
drh0d9de992017-12-26 18:04:23 +00009884#endif
drhe2754c12019-08-26 12:50:01 +00009885 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
9886 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
9887 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
9888 { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
drh37ccfcf2020-08-31 18:49:04 +00009889 { "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, "" },
drh2ce15c32017-07-11 13:34:40 +00009890 };
9891 int testctrl = -1;
drhef302e82017-11-15 19:14:08 +00009892 int iCtrl = -1;
9893 int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */
9894 int isOk = 0;
drh2ce15c32017-07-11 13:34:40 +00009895 int i, n2;
mistachkinc6bc15a2017-11-21 21:14:32 +00009896 const char *zCmd = 0;
9897
drh2ce15c32017-07-11 13:34:40 +00009898 open_db(p, 0);
mistachkinc6bc15a2017-11-21 21:14:32 +00009899 zCmd = nArg>=2 ? azArg[1] : "help";
drh35f51a42017-11-15 17:07:22 +00009900
9901 /* The argument can optionally begin with "-" or "--" */
9902 if( zCmd[0]=='-' && zCmd[1] ){
9903 zCmd++;
9904 if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
9905 }
9906
9907 /* --help lists all test-controls */
9908 if( strcmp(zCmd,"help")==0 ){
9909 utf8_printf(p->out, "Available test-controls:\n");
9910 for(i=0; i<ArraySize(aCtrl); i++){
drhef302e82017-11-15 19:14:08 +00009911 utf8_printf(p->out, " .testctrl %s %s\n",
9912 aCtrl[i].zCtrlName, aCtrl[i].zUsage);
drh35f51a42017-11-15 17:07:22 +00009913 }
9914 rc = 1;
9915 goto meta_command_exit;
9916 }
drh2ce15c32017-07-11 13:34:40 +00009917
9918 /* convert testctrl text option to value. allow any unique prefix
9919 ** of the option name, or a numerical value. */
drh35f51a42017-11-15 17:07:22 +00009920 n2 = strlen30(zCmd);
drh2ce15c32017-07-11 13:34:40 +00009921 for(i=0; i<ArraySize(aCtrl); i++){
drh35f51a42017-11-15 17:07:22 +00009922 if( strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
drh2ce15c32017-07-11 13:34:40 +00009923 if( testctrl<0 ){
9924 testctrl = aCtrl[i].ctrlCode;
drhef302e82017-11-15 19:14:08 +00009925 iCtrl = i;
drh2ce15c32017-07-11 13:34:40 +00009926 }else{
drh35f51a42017-11-15 17:07:22 +00009927 utf8_printf(stderr, "Error: ambiguous test-control: \"%s\"\n"
9928 "Use \".testctrl --help\" for help\n", zCmd);
9929 rc = 1;
9930 goto meta_command_exit;
drh2ce15c32017-07-11 13:34:40 +00009931 }
9932 }
9933 }
drhef302e82017-11-15 19:14:08 +00009934 if( testctrl<0 ){
drh35f51a42017-11-15 17:07:22 +00009935 utf8_printf(stderr,"Error: unknown test-control: %s\n"
9936 "Use \".testctrl --help\" for help\n", zCmd);
drh2ce15c32017-07-11 13:34:40 +00009937 }else{
9938 switch(testctrl){
9939
9940 /* sqlite3_test_control(int, db, int) */
9941 case SQLITE_TESTCTRL_OPTIMIZATIONS:
drh2ce15c32017-07-11 13:34:40 +00009942 if( nArg==3 ){
9943 int opt = (int)strtol(azArg[2], 0, 0);
9944 rc2 = sqlite3_test_control(testctrl, p->db, opt);
drhef302e82017-11-15 19:14:08 +00009945 isOk = 3;
drh2ce15c32017-07-11 13:34:40 +00009946 }
9947 break;
9948
9949 /* sqlite3_test_control(int) */
9950 case SQLITE_TESTCTRL_PRNG_SAVE:
9951 case SQLITE_TESTCTRL_PRNG_RESTORE:
drh2ce15c32017-07-11 13:34:40 +00009952 case SQLITE_TESTCTRL_BYTEORDER:
9953 if( nArg==2 ){
9954 rc2 = sqlite3_test_control(testctrl);
drhef302e82017-11-15 19:14:08 +00009955 isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3;
drh2ce15c32017-07-11 13:34:40 +00009956 }
9957 break;
9958
9959 /* sqlite3_test_control(int, uint) */
9960 case SQLITE_TESTCTRL_PENDING_BYTE:
9961 if( nArg==3 ){
9962 unsigned int opt = (unsigned int)integerValue(azArg[2]);
9963 rc2 = sqlite3_test_control(testctrl, opt);
drhef302e82017-11-15 19:14:08 +00009964 isOk = 3;
drh2ce15c32017-07-11 13:34:40 +00009965 }
9966 break;
9967
drh2e6d83b2019-08-03 01:39:20 +00009968 /* sqlite3_test_control(int, int, sqlite3*) */
9969 case SQLITE_TESTCTRL_PRNG_SEED:
9970 if( nArg==3 || nArg==4 ){
drh51755a72019-08-08 19:40:29 +00009971 int ii = (int)integerValue(azArg[2]);
drh2e6d83b2019-08-03 01:39:20 +00009972 sqlite3 *db;
drh41428a92019-08-12 16:25:11 +00009973 if( ii==0 && strcmp(azArg[2],"random")==0 ){
9974 sqlite3_randomness(sizeof(ii),&ii);
9975 printf("-- random seed: %d\n", ii);
9976 }
drh2e6d83b2019-08-03 01:39:20 +00009977 if( nArg==3 ){
9978 db = 0;
9979 }else{
9980 db = p->db;
9981 /* Make sure the schema has been loaded */
9982 sqlite3_table_column_metadata(db, 0, "x", 0, 0, 0, 0, 0, 0);
9983 }
drh51755a72019-08-08 19:40:29 +00009984 rc2 = sqlite3_test_control(testctrl, ii, db);
drh2e6d83b2019-08-03 01:39:20 +00009985 isOk = 3;
9986 }
9987 break;
9988
drh2ce15c32017-07-11 13:34:40 +00009989 /* sqlite3_test_control(int, int) */
9990 case SQLITE_TESTCTRL_ASSERT:
9991 case SQLITE_TESTCTRL_ALWAYS:
drhef302e82017-11-15 19:14:08 +00009992 if( nArg==3 ){
9993 int opt = booleanValue(azArg[2]);
9994 rc2 = sqlite3_test_control(testctrl, opt);
9995 isOk = 1;
9996 }
9997 break;
9998
9999 /* sqlite3_test_control(int, int) */
10000 case SQLITE_TESTCTRL_LOCALTIME_FAULT:
drh2ce15c32017-07-11 13:34:40 +000010001 case SQLITE_TESTCTRL_NEVER_CORRUPT:
10002 if( nArg==3 ){
10003 int opt = booleanValue(azArg[2]);
10004 rc2 = sqlite3_test_control(testctrl, opt);
drhef302e82017-11-15 19:14:08 +000010005 isOk = 3;
drh2ce15c32017-07-11 13:34:40 +000010006 }
10007 break;
10008
drh171c50e2020-01-01 15:43:30 +000010009 /* sqlite3_test_control(sqlite3*) */
10010 case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS:
10011 rc2 = sqlite3_test_control(testctrl, p->db);
drh2a83c102020-01-01 23:02:35 +000010012 isOk = 3;
drh171c50e2020-01-01 15:43:30 +000010013 break;
10014
drh2ce15c32017-07-11 13:34:40 +000010015 case SQLITE_TESTCTRL_IMPOSTER:
10016 if( nArg==5 ){
10017 rc2 = sqlite3_test_control(testctrl, p->db,
10018 azArg[2],
10019 integerValue(azArg[3]),
10020 integerValue(azArg[4]));
drhef302e82017-11-15 19:14:08 +000010021 isOk = 3;
drh2ce15c32017-07-11 13:34:40 +000010022 }
10023 break;
drh0d9de992017-12-26 18:04:23 +000010024
drh37ccfcf2020-08-31 18:49:04 +000010025 case SQLITE_TESTCTRL_SEEK_COUNT: {
10026 u64 x = 0;
10027 rc2 = sqlite3_test_control(testctrl, p->db, &x);
10028 utf8_printf(p->out, "%llu\n", x);
10029 isOk = 3;
10030 break;
10031 }
10032
drh0d9de992017-12-26 18:04:23 +000010033#ifdef YYCOVERAGE
10034 case SQLITE_TESTCTRL_PARSER_COVERAGE:
10035 if( nArg==2 ){
10036 sqlite3_test_control(testctrl, p->out);
10037 isOk = 3;
10038 }
10039#endif
drh2ce15c32017-07-11 13:34:40 +000010040 }
10041 }
drhef302e82017-11-15 19:14:08 +000010042 if( isOk==0 && iCtrl>=0 ){
drhe2754c12019-08-26 12:50:01 +000010043 utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
drhef302e82017-11-15 19:14:08 +000010044 rc = 1;
10045 }else if( isOk==1 ){
10046 raw_printf(p->out, "%d\n", rc2);
10047 }else if( isOk==2 ){
10048 raw_printf(p->out, "0x%08x\n", rc2);
10049 }
drh2ce15c32017-07-11 13:34:40 +000010050 }else
10051#endif /* !defined(SQLITE_UNTESTABLE) */
10052
10053 if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
10054 open_db(p, 0);
10055 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
10056 }else
10057
10058 if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
10059 if( nArg==2 ){
10060 enableTimer = booleanValue(azArg[1]);
10061 if( enableTimer && !HAS_TIMER ){
10062 raw_printf(stderr, "Error: timer not available on this system.\n");
10063 enableTimer = 0;
10064 }
10065 }else{
10066 raw_printf(stderr, "Usage: .timer on|off\n");
10067 rc = 1;
10068 }
10069 }else
10070
drh707821f2018-12-05 13:39:06 +000010071#ifndef SQLITE_OMIT_TRACE
drh2ce15c32017-07-11 13:34:40 +000010072 if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
drh707821f2018-12-05 13:39:06 +000010073 int mType = 0;
10074 int jj;
drh2ce15c32017-07-11 13:34:40 +000010075 open_db(p, 0);
drh707821f2018-12-05 13:39:06 +000010076 for(jj=1; jj<nArg; jj++){
10077 const char *z = azArg[jj];
10078 if( z[0]=='-' ){
10079 if( optionMatch(z, "expanded") ){
10080 p->eTraceType = SHELL_TRACE_EXPANDED;
10081 }
10082#ifdef SQLITE_ENABLE_NORMALIZE
10083 else if( optionMatch(z, "normalized") ){
10084 p->eTraceType = SHELL_TRACE_NORMALIZED;
10085 }
10086#endif
10087 else if( optionMatch(z, "plain") ){
10088 p->eTraceType = SHELL_TRACE_PLAIN;
10089 }
10090 else if( optionMatch(z, "profile") ){
10091 mType |= SQLITE_TRACE_PROFILE;
10092 }
10093 else if( optionMatch(z, "row") ){
10094 mType |= SQLITE_TRACE_ROW;
10095 }
10096 else if( optionMatch(z, "stmt") ){
10097 mType |= SQLITE_TRACE_STMT;
10098 }
10099 else if( optionMatch(z, "close") ){
10100 mType |= SQLITE_TRACE_CLOSE;
10101 }
10102 else {
10103 raw_printf(stderr, "Unknown option \"%s\" on \".trace\"\n", z);
10104 rc = 1;
10105 goto meta_command_exit;
10106 }
10107 }else{
10108 output_file_close(p->traceOut);
10109 p->traceOut = output_file_open(azArg[1], 0);
10110 }
drh2ce15c32017-07-11 13:34:40 +000010111 }
drh2ce15c32017-07-11 13:34:40 +000010112 if( p->traceOut==0 ){
10113 sqlite3_trace_v2(p->db, 0, 0, 0);
10114 }else{
drh707821f2018-12-05 13:39:06 +000010115 if( mType==0 ) mType = SQLITE_TRACE_STMT;
10116 sqlite3_trace_v2(p->db, mType, sql_trace_callback, p);
drh2ce15c32017-07-11 13:34:40 +000010117 }
drh2ce15c32017-07-11 13:34:40 +000010118 }else
drh707821f2018-12-05 13:39:06 +000010119#endif /* !defined(SQLITE_OMIT_TRACE) */
drh2ce15c32017-07-11 13:34:40 +000010120
drhe2b7a762019-10-02 00:25:08 +000010121#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
drhcc5979d2019-08-16 22:58:29 +000010122 if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
10123 int ii;
drh8c754a32019-08-19 20:35:30 +000010124 int lenOpt;
drh5df84282019-08-17 19:45:25 +000010125 char *zOpt;
drhcc5979d2019-08-16 22:58:29 +000010126 if( nArg<2 ){
drh5df84282019-08-17 19:45:25 +000010127 raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
drhcc5979d2019-08-16 22:58:29 +000010128 rc = 1;
10129 goto meta_command_exit;
10130 }
10131 open_db(p, 0);
drh5df84282019-08-17 19:45:25 +000010132 zOpt = azArg[1];
10133 if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++;
drh8c754a32019-08-19 20:35:30 +000010134 lenOpt = (int)strlen(zOpt);
10135 if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){
drh5df84282019-08-17 19:45:25 +000010136 assert( azArg[nArg]==0 );
drh8c754a32019-08-19 20:35:30 +000010137 sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0);
drh5df84282019-08-17 19:45:25 +000010138 }else{
10139 for(ii=1; ii<nArg; ii++){
10140 sqlite3_create_module(p->db, azArg[ii], 0, 0);
10141 }
drhcc5979d2019-08-16 22:58:29 +000010142 }
10143 }else
10144#endif
10145
drh2ce15c32017-07-11 13:34:40 +000010146#if SQLITE_USER_AUTHENTICATION
10147 if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
10148 if( nArg<2 ){
10149 raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
10150 rc = 1;
10151 goto meta_command_exit;
10152 }
10153 open_db(p, 0);
10154 if( strcmp(azArg[1],"login")==0 ){
10155 if( nArg!=4 ){
10156 raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
10157 rc = 1;
10158 goto meta_command_exit;
10159 }
drhe2754c12019-08-26 12:50:01 +000010160 rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
10161 strlen30(azArg[3]));
drh2ce15c32017-07-11 13:34:40 +000010162 if( rc ){
10163 utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
10164 rc = 1;
10165 }
10166 }else if( strcmp(azArg[1],"add")==0 ){
10167 if( nArg!=5 ){
10168 raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
10169 rc = 1;
10170 goto meta_command_exit;
10171 }
drhaf2770f2018-01-05 14:55:43 +000010172 rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
drh2ce15c32017-07-11 13:34:40 +000010173 booleanValue(azArg[4]));
10174 if( rc ){
10175 raw_printf(stderr, "User-Add failed: %d\n", rc);
10176 rc = 1;
10177 }
10178 }else if( strcmp(azArg[1],"edit")==0 ){
10179 if( nArg!=5 ){
10180 raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
10181 rc = 1;
10182 goto meta_command_exit;
10183 }
drhaf2770f2018-01-05 14:55:43 +000010184 rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
drh2ce15c32017-07-11 13:34:40 +000010185 booleanValue(azArg[4]));
10186 if( rc ){
10187 raw_printf(stderr, "User-Edit failed: %d\n", rc);
10188 rc = 1;
10189 }
10190 }else if( strcmp(azArg[1],"delete")==0 ){
10191 if( nArg!=3 ){
10192 raw_printf(stderr, "Usage: .user delete USER\n");
10193 rc = 1;
10194 goto meta_command_exit;
10195 }
10196 rc = sqlite3_user_delete(p->db, azArg[2]);
10197 if( rc ){
10198 raw_printf(stderr, "User-Delete failed: %d\n", rc);
10199 rc = 1;
10200 }
10201 }else{
10202 raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
10203 rc = 1;
10204 goto meta_command_exit;
10205 }
10206 }else
10207#endif /* SQLITE_USER_AUTHENTICATION */
10208
10209 if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
10210 utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
10211 sqlite3_libversion(), sqlite3_sourceid());
drh0ed2fd82018-01-16 20:05:27 +000010212#if SQLITE_HAVE_ZLIB
10213 utf8_printf(p->out, "zlib version %s\n", zlibVersion());
10214#endif
10215#define CTIMEOPT_VAL_(opt) #opt
10216#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
10217#if defined(__clang__) && defined(__clang_major__)
10218 utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
10219 CTIMEOPT_VAL(__clang_minor__) "."
10220 CTIMEOPT_VAL(__clang_patchlevel__) "\n");
10221#elif defined(_MSC_VER)
10222 utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n");
10223#elif defined(__GNUC__) && defined(__VERSION__)
10224 utf8_printf(p->out, "gcc-" __VERSION__ "\n");
10225#endif
drh2ce15c32017-07-11 13:34:40 +000010226 }else
10227
10228 if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
10229 const char *zDbName = nArg==2 ? azArg[1] : "main";
10230 sqlite3_vfs *pVfs = 0;
10231 if( p->db ){
10232 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
10233 if( pVfs ){
10234 utf8_printf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName);
10235 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
10236 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
10237 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
10238 }
10239 }
10240 }else
10241
10242 if( c=='v' && strncmp(azArg[0], "vfslist", n)==0 ){
10243 sqlite3_vfs *pVfs;
10244 sqlite3_vfs *pCurrent = 0;
10245 if( p->db ){
10246 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
10247 }
10248 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
10249 utf8_printf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName,
10250 pVfs==pCurrent ? " <--- CURRENT" : "");
10251 raw_printf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion);
10252 raw_printf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile);
10253 raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
10254 if( pVfs->pNext ){
10255 raw_printf(p->out, "-----------------------------------\n");
10256 }
10257 }
10258 }else
10259
10260 if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
10261 const char *zDbName = nArg==2 ? azArg[1] : "main";
10262 char *zVfsName = 0;
10263 if( p->db ){
10264 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
10265 if( zVfsName ){
10266 utf8_printf(p->out, "%s\n", zVfsName);
10267 sqlite3_free(zVfsName);
10268 }
10269 }
10270 }else
10271
10272#if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
10273 if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
10274 sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
10275 }else
10276#endif
10277
10278 if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
10279 int j;
10280 assert( nArg<=ArraySize(azArg) );
drh0285d982020-05-29 14:38:43 +000010281 p->nWidth = nArg-1;
10282 p->colWidth = realloc(p->colWidth, p->nWidth*sizeof(int)*2);
10283 if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory();
10284 if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
10285 for(j=1; j<nArg; j++){
drh2ce15c32017-07-11 13:34:40 +000010286 p->colWidth[j-1] = (int)integerValue(azArg[j]);
10287 }
10288 }else
10289
10290 {
10291 utf8_printf(stderr, "Error: unknown command or invalid arguments: "
10292 " \"%s\". Enter \".help\" for help\n", azArg[0]);
10293 rc = 1;
10294 }
10295
10296meta_command_exit:
10297 if( p->outCount ){
10298 p->outCount--;
10299 if( p->outCount==0 ) output_reset(p);
10300 }
10301 return rc;
10302}
10303
10304/*
10305** Return TRUE if a semicolon occurs anywhere in the first N characters
10306** of string z[].
10307*/
10308static int line_contains_semicolon(const char *z, int N){
10309 int i;
10310 for(i=0; i<N; i++){ if( z[i]==';' ) return 1; }
10311 return 0;
10312}
10313
10314/*
10315** Test to see if a line consists entirely of whitespace.
10316*/
10317static int _all_whitespace(const char *z){
10318 for(; *z; z++){
10319 if( IsSpace(z[0]) ) continue;
10320 if( *z=='/' && z[1]=='*' ){
10321 z += 2;
10322 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
10323 if( *z==0 ) return 0;
10324 z++;
10325 continue;
10326 }
10327 if( *z=='-' && z[1]=='-' ){
10328 z += 2;
10329 while( *z && *z!='\n' ){ z++; }
10330 if( *z==0 ) return 1;
10331 continue;
10332 }
10333 return 0;
10334 }
10335 return 1;
10336}
10337
10338/*
10339** Return TRUE if the line typed in is an SQL command terminator other
10340** than a semi-colon. The SQL Server style "go" command is understood
10341** as is the Oracle "/".
10342*/
10343static int line_is_command_terminator(const char *zLine){
10344 while( IsSpace(zLine[0]) ){ zLine++; };
10345 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
10346 return 1; /* Oracle */
10347 }
10348 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
10349 && _all_whitespace(&zLine[2]) ){
10350 return 1; /* SQL Server */
10351 }
10352 return 0;
10353}
10354
10355/*
drh56f17742018-01-24 01:58:49 +000010356** We need a default sqlite3_complete() implementation to use in case
10357** the shell is compiled with SQLITE_OMIT_COMPLETE. The default assumes
10358** any arbitrary text is a complete SQL statement. This is not very
10359** user-friendly, but it does seem to work.
10360*/
10361#ifdef SQLITE_OMIT_COMPLETE
danc86b23b2018-11-16 14:36:42 +000010362#define sqlite3_complete(x) 1
drh56f17742018-01-24 01:58:49 +000010363#endif
10364
10365/*
drh2ce15c32017-07-11 13:34:40 +000010366** Return true if zSql is a complete SQL statement. Return false if it
10367** ends in the middle of a string literal or C-style comment.
10368*/
10369static int line_is_complete(char *zSql, int nSql){
10370 int rc;
10371 if( zSql==0 ) return 1;
10372 zSql[nSql] = ';';
10373 zSql[nSql+1] = 0;
10374 rc = sqlite3_complete(zSql);
10375 zSql[nSql] = 0;
10376 return rc;
10377}
10378
10379/*
drhfc29a862018-05-11 19:11:18 +000010380** Run a single line of SQL. Return the number of errors.
drh2ce15c32017-07-11 13:34:40 +000010381*/
10382static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
10383 int rc;
10384 char *zErrMsg = 0;
10385
10386 open_db(p, 0);
10387 if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql);
drhfc4eeef2019-02-05 19:48:46 +000010388 if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
drh2ce15c32017-07-11 13:34:40 +000010389 BEGIN_TIMER;
drha10b9992018-03-09 15:24:33 +000010390 rc = shell_exec(p, zSql, &zErrMsg);
drh2ce15c32017-07-11 13:34:40 +000010391 END_TIMER;
10392 if( rc || zErrMsg ){
10393 char zPrefix[100];
10394 if( in!=0 || !stdin_is_interactive ){
10395 sqlite3_snprintf(sizeof(zPrefix), zPrefix,
10396 "Error: near line %d:", startline);
10397 }else{
10398 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
10399 }
10400 if( zErrMsg!=0 ){
10401 utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
10402 sqlite3_free(zErrMsg);
10403 zErrMsg = 0;
10404 }else{
10405 utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
10406 }
10407 return 1;
10408 }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
10409 raw_printf(p->out, "changes: %3d total_changes: %d\n",
10410 sqlite3_changes(p->db), sqlite3_total_changes(p->db));
10411 }
10412 return 0;
10413}
10414
10415
10416/*
10417** Read input from *in and process it. If *in==0 then input
10418** is interactive - the user is typing it it. Otherwise, input
10419** is coming from a file or device. A prompt is issued and history
10420** is saved only if input is interactive. An interrupt signal will
10421** cause this routine to exit immediately, unless input is interactive.
10422**
10423** Return the number of errors.
10424*/
drh60379d42018-12-13 18:30:01 +000010425static int process_input(ShellState *p){
drh2ce15c32017-07-11 13:34:40 +000010426 char *zLine = 0; /* A single input line */
10427 char *zSql = 0; /* Accumulated SQL text */
10428 int nLine; /* Length of current line */
10429 int nSql = 0; /* Bytes of zSql[] used */
10430 int nAlloc = 0; /* Allocated zSql[] space */
10431 int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
10432 int rc; /* Error code */
10433 int errCnt = 0; /* Number of errors seen */
drh2ce15c32017-07-11 13:34:40 +000010434 int startline = 0; /* Line number for start of current input */
10435
drh2c8ee022018-12-13 18:59:30 +000010436 p->lineno = 0;
drh60379d42018-12-13 18:30:01 +000010437 while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
drh2ce15c32017-07-11 13:34:40 +000010438 fflush(p->out);
drh60379d42018-12-13 18:30:01 +000010439 zLine = one_input_line(p->in, zLine, nSql>0);
drh2ce15c32017-07-11 13:34:40 +000010440 if( zLine==0 ){
10441 /* End of input */
drh60379d42018-12-13 18:30:01 +000010442 if( p->in==0 && stdin_is_interactive ) printf("\n");
drh2ce15c32017-07-11 13:34:40 +000010443 break;
10444 }
10445 if( seenInterrupt ){
drh60379d42018-12-13 18:30:01 +000010446 if( p->in!=0 ) break;
drh2ce15c32017-07-11 13:34:40 +000010447 seenInterrupt = 0;
10448 }
drh2c8ee022018-12-13 18:59:30 +000010449 p->lineno++;
drh2ce15c32017-07-11 13:34:40 +000010450 if( nSql==0 && _all_whitespace(zLine) ){
10451 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
10452 continue;
10453 }
drh1615c372018-05-12 23:56:22 +000010454 if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
drh2ce15c32017-07-11 13:34:40 +000010455 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
drh1615c372018-05-12 23:56:22 +000010456 if( zLine[0]=='.' ){
10457 rc = do_meta_command(zLine, p);
10458 if( rc==2 ){ /* exit requested */
10459 break;
10460 }else if( rc ){
10461 errCnt++;
10462 }
drh2ce15c32017-07-11 13:34:40 +000010463 }
10464 continue;
10465 }
10466 if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
10467 memcpy(zLine,";",2);
10468 }
10469 nLine = strlen30(zLine);
10470 if( nSql+nLine+2>=nAlloc ){
10471 nAlloc = nSql+nLine+100;
10472 zSql = realloc(zSql, nAlloc);
drh4b5345c2018-04-24 13:07:40 +000010473 if( zSql==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +000010474 }
10475 nSqlPrior = nSql;
10476 if( nSql==0 ){
10477 int i;
10478 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
10479 assert( nAlloc>0 && zSql!=0 );
10480 memcpy(zSql, zLine+i, nLine+1-i);
drh2c8ee022018-12-13 18:59:30 +000010481 startline = p->lineno;
drh2ce15c32017-07-11 13:34:40 +000010482 nSql = nLine-i;
10483 }else{
10484 zSql[nSql++] = '\n';
10485 memcpy(zSql+nSql, zLine, nLine+1);
10486 nSql += nLine;
10487 }
10488 if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
10489 && sqlite3_complete(zSql) ){
drh60379d42018-12-13 18:30:01 +000010490 errCnt += runOneSqlLine(p, zSql, p->in, startline);
drh2ce15c32017-07-11 13:34:40 +000010491 nSql = 0;
10492 if( p->outCount ){
10493 output_reset(p);
10494 p->outCount = 0;
drh13c20932018-01-10 21:41:55 +000010495 }else{
10496 clearTempFile(p);
drh2ce15c32017-07-11 13:34:40 +000010497 }
10498 }else if( nSql && _all_whitespace(zSql) ){
10499 if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
10500 nSql = 0;
10501 }
10502 }
10503 if( nSql && !_all_whitespace(zSql) ){
drh60379d42018-12-13 18:30:01 +000010504 errCnt += runOneSqlLine(p, zSql, p->in, startline);
drh2ce15c32017-07-11 13:34:40 +000010505 }
10506 free(zSql);
10507 free(zLine);
10508 return errCnt>0;
10509}
10510
10511/*
10512** Return a pathname which is the user's home directory. A
10513** 0 return indicates an error of some kind.
10514*/
10515static char *find_home_dir(int clearFlag){
10516 static char *home_dir = NULL;
10517 if( clearFlag ){
10518 free(home_dir);
10519 home_dir = 0;
10520 return 0;
10521 }
10522 if( home_dir ) return home_dir;
10523
10524#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
10525 && !defined(__RTP__) && !defined(_WRS_KERNEL)
10526 {
10527 struct passwd *pwent;
10528 uid_t uid = getuid();
10529 if( (pwent=getpwuid(uid)) != NULL) {
10530 home_dir = pwent->pw_dir;
10531 }
10532 }
10533#endif
10534
10535#if defined(_WIN32_WCE)
10536 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv()
10537 */
10538 home_dir = "/";
10539#else
10540
10541#if defined(_WIN32) || defined(WIN32)
10542 if (!home_dir) {
10543 home_dir = getenv("USERPROFILE");
10544 }
10545#endif
10546
10547 if (!home_dir) {
10548 home_dir = getenv("HOME");
10549 }
10550
10551#if defined(_WIN32) || defined(WIN32)
10552 if (!home_dir) {
10553 char *zDrive, *zPath;
10554 int n;
10555 zDrive = getenv("HOMEDRIVE");
10556 zPath = getenv("HOMEPATH");
10557 if( zDrive && zPath ){
10558 n = strlen30(zDrive) + strlen30(zPath) + 1;
10559 home_dir = malloc( n );
10560 if( home_dir==0 ) return 0;
10561 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath);
10562 return home_dir;
10563 }
10564 home_dir = "c:\\";
10565 }
10566#endif
10567
10568#endif /* !_WIN32_WCE */
10569
10570 if( home_dir ){
10571 int n = strlen30(home_dir) + 1;
10572 char *z = malloc( n );
10573 if( z ) memcpy(z, home_dir, n);
10574 home_dir = z;
10575 }
10576
10577 return home_dir;
10578}
10579
10580/*
10581** Read input from the file given by sqliterc_override. Or if that
10582** parameter is NULL, take input from ~/.sqliterc
10583**
10584** Returns the number of errors.
10585*/
10586static void process_sqliterc(
10587 ShellState *p, /* Configuration data */
10588 const char *sqliterc_override /* Name of config file. NULL to use default */
10589){
10590 char *home_dir = NULL;
10591 const char *sqliterc = sqliterc_override;
10592 char *zBuf = 0;
drh60379d42018-12-13 18:30:01 +000010593 FILE *inSaved = p->in;
drh2c8ee022018-12-13 18:59:30 +000010594 int savedLineno = p->lineno;
drh2ce15c32017-07-11 13:34:40 +000010595
10596 if (sqliterc == NULL) {
10597 home_dir = find_home_dir(0);
10598 if( home_dir==0 ){
10599 raw_printf(stderr, "-- warning: cannot find home directory;"
10600 " cannot read ~/.sqliterc\n");
10601 return;
10602 }
drh2ce15c32017-07-11 13:34:40 +000010603 zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
10604 sqliterc = zBuf;
10605 }
drh60379d42018-12-13 18:30:01 +000010606 p->in = fopen(sqliterc,"rb");
10607 if( p->in ){
drh2ce15c32017-07-11 13:34:40 +000010608 if( stdin_is_interactive ){
10609 utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
10610 }
drh60379d42018-12-13 18:30:01 +000010611 process_input(p);
10612 fclose(p->in);
drh2ce15c32017-07-11 13:34:40 +000010613 }
drh60379d42018-12-13 18:30:01 +000010614 p->in = inSaved;
drh2c8ee022018-12-13 18:59:30 +000010615 p->lineno = savedLineno;
drh2ce15c32017-07-11 13:34:40 +000010616 sqlite3_free(zBuf);
10617}
10618
10619/*
10620** Show available command line options
10621*/
10622static const char zOptions[] =
drhda57d962018-03-05 19:34:05 +000010623#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
drhad7fd5d2018-03-05 20:21:50 +000010624 " -A ARGS... run \".archive ARGS\" and exit\n"
drhda57d962018-03-05 19:34:05 +000010625#endif
drh3baed312018-03-08 18:14:41 +000010626 " -append append the database to the end of the file\n"
drh2ce15c32017-07-11 13:34:40 +000010627 " -ascii set output mode to 'ascii'\n"
10628 " -bail stop after hitting an error\n"
10629 " -batch force batch I/O\n"
drh0908e382020-06-04 18:05:39 +000010630 " -box set output mode to 'box'\n"
drh2ce15c32017-07-11 13:34:40 +000010631 " -column set output mode to 'column'\n"
10632 " -cmd COMMAND run \"COMMAND\" before reading stdin\n"
10633 " -csv set output mode to 'csv'\n"
drh6ca64482019-01-22 16:06:20 +000010634#if defined(SQLITE_ENABLE_DESERIALIZE)
10635 " -deserialize open the database using sqlite3_deserialize()\n"
10636#endif
drh2ce15c32017-07-11 13:34:40 +000010637 " -echo print commands before execution\n"
10638 " -init FILENAME read/process named file\n"
10639 " -[no]header turn headers on or off\n"
10640#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
10641 " -heap SIZE Size of heap for memsys3 or memsys5\n"
10642#endif
10643 " -help show this message\n"
10644 " -html set output mode to HTML\n"
10645 " -interactive force interactive I/O\n"
drh30c54a02020-05-28 23:49:50 +000010646 " -json set output mode to 'json'\n"
drh2ce15c32017-07-11 13:34:40 +000010647 " -line set output mode to 'line'\n"
10648 " -list set output mode to 'list'\n"
10649 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n"
drh30c54a02020-05-28 23:49:50 +000010650 " -markdown set output mode to 'markdown'\n"
drh6ca64482019-01-22 16:06:20 +000010651#if defined(SQLITE_ENABLE_DESERIALIZE)
10652 " -maxsize N maximum size for a --deserialize database\n"
10653#endif
drhaf482572019-02-04 19:52:39 +000010654 " -memtrace trace all memory allocations and deallocations\n"
drh2ce15c32017-07-11 13:34:40 +000010655 " -mmap N default mmap size set to N\n"
10656#ifdef SQLITE_ENABLE_MULTIPLEX
10657 " -multiplex enable the multiplexor VFS\n"
10658#endif
10659 " -newline SEP set output row separator. Default: '\\n'\n"
drh0933aad2019-11-18 17:46:38 +000010660 " -nofollow refuse to open symbolic links to database files\n"
drh2ce15c32017-07-11 13:34:40 +000010661 " -nullvalue TEXT set text string for NULL values. Default ''\n"
10662 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
10663 " -quote set output mode to 'quote'\n"
drhee269a62018-02-14 23:27:43 +000010664 " -readonly open the database read-only\n"
drh2ce15c32017-07-11 13:34:40 +000010665 " -separator SEP set output column separator. Default: '|'\n"
drha90d84f2018-04-18 15:21:13 +000010666#ifdef SQLITE_ENABLE_SORTER_REFERENCES
10667 " -sorterref SIZE sorter references threshold size\n"
10668#endif
drh2ce15c32017-07-11 13:34:40 +000010669 " -stats print memory stats before each finalize\n"
drh30c54a02020-05-28 23:49:50 +000010670 " -table set output mode to 'table'\n"
drh2ce15c32017-07-11 13:34:40 +000010671 " -version show SQLite version\n"
10672 " -vfs NAME use NAME as the default VFS\n"
10673#ifdef SQLITE_ENABLE_VFSTRACE
10674 " -vfstrace enable tracing of all VFS calls\n"
10675#endif
drh3baed312018-03-08 18:14:41 +000010676#ifdef SQLITE_HAVE_ZLIB
10677 " -zip open the file as a ZIP Archive\n"
10678#endif
drh2ce15c32017-07-11 13:34:40 +000010679;
10680static void usage(int showDetail){
10681 utf8_printf(stderr,
10682 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
10683 "FILENAME is the name of an SQLite database. A new database is created\n"
10684 "if the file does not previously exist.\n", Argv0);
10685 if( showDetail ){
10686 utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
10687 }else{
10688 raw_printf(stderr, "Use the -help option for additional information\n");
10689 }
10690 exit(1);
10691}
10692
10693/*
drhe7df8922018-04-18 10:44:58 +000010694** Internal check: Verify that the SQLite is uninitialized. Print a
10695** error message if it is initialized.
10696*/
10697static void verify_uninitialized(void){
10698 if( sqlite3_config(-1)==SQLITE_MISUSE ){
drh8e02a182018-05-30 07:24:41 +000010699 utf8_printf(stdout, "WARNING: attempt to configure SQLite after"
drhe7df8922018-04-18 10:44:58 +000010700 " initialization.\n");
10701 }
10702}
10703
10704/*
drh2ce15c32017-07-11 13:34:40 +000010705** Initialize the state information in data
10706*/
10707static void main_init(ShellState *data) {
10708 memset(data, 0, sizeof(*data));
10709 data->normalMode = data->cMode = data->mode = MODE_List;
10710 data->autoExplain = 1;
10711 memcpy(data->colSeparator,SEP_Column, 2);
10712 memcpy(data->rowSeparator,SEP_Row, 2);
10713 data->showHeader = 0;
10714 data->shellFlgs = SHFLG_Lookaside;
drhe7df8922018-04-18 10:44:58 +000010715 verify_uninitialized();
drh2ce15c32017-07-11 13:34:40 +000010716 sqlite3_config(SQLITE_CONFIG_URI, 1);
10717 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
10718 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
10719 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
10720 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
10721}
10722
10723/*
10724** Output text to the console in a font that attracts extra attention.
10725*/
10726#ifdef _WIN32
10727static void printBold(const char *zText){
mistachkin43e86272020-04-09 15:31:22 +000010728#if !SQLITE_OS_WINRT
drh2ce15c32017-07-11 13:34:40 +000010729 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
10730 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
10731 GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
10732 SetConsoleTextAttribute(out,
10733 FOREGROUND_RED|FOREGROUND_INTENSITY
10734 );
mistachkin43e86272020-04-09 15:31:22 +000010735#endif
drh2ce15c32017-07-11 13:34:40 +000010736 printf("%s", zText);
mistachkin43e86272020-04-09 15:31:22 +000010737#if !SQLITE_OS_WINRT
drh2ce15c32017-07-11 13:34:40 +000010738 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
mistachkin43e86272020-04-09 15:31:22 +000010739#endif
drh2ce15c32017-07-11 13:34:40 +000010740}
10741#else
10742static void printBold(const char *zText){
10743 printf("\033[1m%s\033[0m", zText);
10744}
10745#endif
10746
10747/*
10748** Get the argument to an --option. Throw an error and die if no argument
10749** is available.
10750*/
10751static char *cmdline_option_value(int argc, char **argv, int i){
10752 if( i==argc ){
10753 utf8_printf(stderr, "%s: Error: missing argument to %s\n",
10754 argv[0], argv[argc-1]);
10755 exit(1);
10756 }
10757 return argv[i];
10758}
10759
10760#ifndef SQLITE_SHELL_IS_UTF8
10761# if (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER)
10762# define SQLITE_SHELL_IS_UTF8 (0)
10763# else
10764# define SQLITE_SHELL_IS_UTF8 (1)
10765# endif
10766#endif
10767
10768#if SQLITE_SHELL_IS_UTF8
10769int SQLITE_CDECL main(int argc, char **argv){
10770#else
10771int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
10772 char **argv;
10773#endif
10774 char *zErrMsg = 0;
10775 ShellState data;
10776 const char *zInitFile = 0;
10777 int i;
10778 int rc = 0;
10779 int warnInmemoryDb = 0;
10780 int readStdin = 1;
10781 int nCmd = 0;
10782 char **azCmd = 0;
dan16a47422018-04-18 09:16:11 +000010783 const char *zVfs = 0; /* Value of -vfs command-line option */
drh1f22f622018-05-17 13:29:14 +000010784#if !SQLITE_SHELL_IS_UTF8
10785 char **argvToFree = 0;
10786 int argcToFree = 0;
10787#endif
drh2ce15c32017-07-11 13:34:40 +000010788
10789 setBinaryMode(stdin, 0);
10790 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
10791 stdin_is_interactive = isatty(0);
10792 stdout_is_console = isatty(1);
10793
drh4a3a3eb2020-02-29 15:53:48 +000010794#ifdef SQLITE_DEBUG
10795 registerOomSimulator();
10796#endif
10797
mistachkin1e8487d2018-07-22 06:25:35 +000010798#if !defined(_WIN32_WCE)
10799 if( getenv("SQLITE_DEBUG_BREAK") ){
10800 if( isatty(0) && isatty(2) ){
10801 fprintf(stderr,
10802 "attach debugger to process %d and press any key to continue.\n",
10803 GETPID());
10804 fgetc(stdin);
10805 }else{
10806#if defined(_WIN32) || defined(WIN32)
mistachkin43e86272020-04-09 15:31:22 +000010807#if SQLITE_OS_WINRT
10808 __debugbreak();
10809#else
mistachkin1e8487d2018-07-22 06:25:35 +000010810 DebugBreak();
mistachkin43e86272020-04-09 15:31:22 +000010811#endif
mistachkin1e8487d2018-07-22 06:25:35 +000010812#elif defined(SIGTRAP)
10813 raise(SIGTRAP);
10814#endif
10815 }
10816 }
10817#endif
10818
drh2ce15c32017-07-11 13:34:40 +000010819#if USE_SYSTEM_SQLITE+0!=1
drhb3c45232017-08-28 14:33:27 +000010820 if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
drh2ce15c32017-07-11 13:34:40 +000010821 utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
10822 sqlite3_sourceid(), SQLITE_SOURCE_ID);
10823 exit(1);
10824 }
10825#endif
10826 main_init(&data);
drh501ea052018-02-15 01:03:37 +000010827
10828 /* On Windows, we must translate command-line arguments into UTF-8.
10829 ** The SQLite memory allocator subsystem has to be enabled in order to
10830 ** do this. But we want to run an sqlite3_shutdown() afterwards so that
10831 ** subsequent sqlite3_config() calls will work. So copy all results into
10832 ** memory that does not come from the SQLite memory allocator.
10833 */
drh4b18c1d2018-02-04 20:33:13 +000010834#if !SQLITE_SHELL_IS_UTF8
drh501ea052018-02-15 01:03:37 +000010835 sqlite3_initialize();
drh1f22f622018-05-17 13:29:14 +000010836 argvToFree = malloc(sizeof(argv[0])*argc*2);
10837 argcToFree = argc;
10838 argv = argvToFree + argc;
drh4b5345c2018-04-24 13:07:40 +000010839 if( argv==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +000010840 for(i=0; i<argc; i++){
drh501ea052018-02-15 01:03:37 +000010841 char *z = sqlite3_win32_unicode_to_utf8(wargv[i]);
10842 int n;
drh4b5345c2018-04-24 13:07:40 +000010843 if( z==0 ) shell_out_of_memory();
drh501ea052018-02-15 01:03:37 +000010844 n = (int)strlen(z);
10845 argv[i] = malloc( n+1 );
drh4b5345c2018-04-24 13:07:40 +000010846 if( argv[i]==0 ) shell_out_of_memory();
drh501ea052018-02-15 01:03:37 +000010847 memcpy(argv[i], z, n+1);
drh1f22f622018-05-17 13:29:14 +000010848 argvToFree[i] = argv[i];
drh501ea052018-02-15 01:03:37 +000010849 sqlite3_free(z);
drh2ce15c32017-07-11 13:34:40 +000010850 }
drh501ea052018-02-15 01:03:37 +000010851 sqlite3_shutdown();
drh2ce15c32017-07-11 13:34:40 +000010852#endif
drh501ea052018-02-15 01:03:37 +000010853
drh2ce15c32017-07-11 13:34:40 +000010854 assert( argc>=1 && argv && argv[0] );
10855 Argv0 = argv[0];
10856
10857 /* Make sure we have a valid signal handler early, before anything
10858 ** else is done.
10859 */
10860#ifdef SIGINT
10861 signal(SIGINT, interrupt_handler);
mistachkinb4bab902017-10-27 17:09:44 +000010862#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
10863 SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
drh2ce15c32017-07-11 13:34:40 +000010864#endif
10865
10866#ifdef SQLITE_SHELL_DBNAME_PROC
10867 {
10868 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
10869 ** of a C-function that will provide the name of the database file. Use
10870 ** this compile-time option to embed this shell program in larger
10871 ** applications. */
10872 extern void SQLITE_SHELL_DBNAME_PROC(const char**);
10873 SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
10874 warnInmemoryDb = 0;
10875 }
10876#endif
10877
10878 /* Do an initial pass through the command-line argument to locate
10879 ** the name of the database file, the name of the initialization file,
10880 ** the size of the alternative malloc heap,
10881 ** and the first command to execute.
10882 */
drhe7df8922018-04-18 10:44:58 +000010883 verify_uninitialized();
drh2ce15c32017-07-11 13:34:40 +000010884 for(i=1; i<argc; i++){
10885 char *z;
10886 z = argv[i];
10887 if( z[0]!='-' ){
10888 if( data.zDbFilename==0 ){
10889 data.zDbFilename = z;
10890 }else{
10891 /* Excesss arguments are interpreted as SQL (or dot-commands) and
10892 ** mean that nothing is read from stdin */
10893 readStdin = 0;
10894 nCmd++;
10895 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
drh4b5345c2018-04-24 13:07:40 +000010896 if( azCmd==0 ) shell_out_of_memory();
drh2ce15c32017-07-11 13:34:40 +000010897 azCmd[nCmd-1] = z;
10898 }
10899 }
10900 if( z[1]=='-' ) z++;
10901 if( strcmp(z,"-separator")==0
10902 || strcmp(z,"-nullvalue")==0
10903 || strcmp(z,"-newline")==0
10904 || strcmp(z,"-cmd")==0
10905 ){
10906 (void)cmdline_option_value(argc, argv, ++i);
10907 }else if( strcmp(z,"-init")==0 ){
10908 zInitFile = cmdline_option_value(argc, argv, ++i);
10909 }else if( strcmp(z,"-batch")==0 ){
10910 /* Need to check for batch mode here to so we can avoid printing
10911 ** informational messages (like from process_sqliterc) before
10912 ** we do the actual processing of arguments later in a second pass.
10913 */
10914 stdin_is_interactive = 0;
10915 }else if( strcmp(z,"-heap")==0 ){
10916#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
10917 const char *zSize;
10918 sqlite3_int64 szHeap;
10919
10920 zSize = cmdline_option_value(argc, argv, ++i);
10921 szHeap = integerValue(zSize);
10922 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
10923 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
10924#else
10925 (void)cmdline_option_value(argc, argv, ++i);
10926#endif
drh2ce15c32017-07-11 13:34:40 +000010927 }else if( strcmp(z,"-pagecache")==0 ){
drhf573b4f2020-09-28 13:34:05 +000010928 sqlite3_int64 n, sz;
10929 sz = integerValue(cmdline_option_value(argc,argv,++i));
drh2ce15c32017-07-11 13:34:40 +000010930 if( sz>70000 ) sz = 70000;
10931 if( sz<0 ) sz = 0;
drhf573b4f2020-09-28 13:34:05 +000010932 n = integerValue(cmdline_option_value(argc,argv,++i));
10933 if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){
10934 n = 0xffffffffffffLL/sz;
10935 }
drh2ce15c32017-07-11 13:34:40 +000010936 sqlite3_config(SQLITE_CONFIG_PAGECACHE,
10937 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n);
10938 data.shellFlgs |= SHFLG_Pagecache;
10939 }else if( strcmp(z,"-lookaside")==0 ){
10940 int n, sz;
10941 sz = (int)integerValue(cmdline_option_value(argc,argv,++i));
10942 if( sz<0 ) sz = 0;
10943 n = (int)integerValue(cmdline_option_value(argc,argv,++i));
10944 if( n<0 ) n = 0;
10945 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n);
10946 if( sz*n==0 ) data.shellFlgs &= ~SHFLG_Lookaside;
10947#ifdef SQLITE_ENABLE_VFSTRACE
10948 }else if( strcmp(z,"-vfstrace")==0 ){
10949 extern int vfstrace_register(
10950 const char *zTraceName,
10951 const char *zOldVfsName,
10952 int (*xOut)(const char*,void*),
10953 void *pOutArg,
10954 int makeDefault
10955 );
10956 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
10957#endif
10958#ifdef SQLITE_ENABLE_MULTIPLEX
10959 }else if( strcmp(z,"-multiplex")==0 ){
10960 extern int sqlite3_multiple_initialize(const char*,int);
10961 sqlite3_multiplex_initialize(0, 1);
10962#endif
10963 }else if( strcmp(z,"-mmap")==0 ){
10964 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
10965 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz);
drha90d84f2018-04-18 15:21:13 +000010966#ifdef SQLITE_ENABLE_SORTER_REFERENCES
10967 }else if( strcmp(z,"-sorterref")==0 ){
10968 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i));
10969 sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz);
10970#endif
drh2ce15c32017-07-11 13:34:40 +000010971 }else if( strcmp(z,"-vfs")==0 ){
dan16a47422018-04-18 09:16:11 +000010972 zVfs = cmdline_option_value(argc, argv, ++i);
drh3baed312018-03-08 18:14:41 +000010973#ifdef SQLITE_HAVE_ZLIB
drh8682e122018-01-07 20:38:10 +000010974 }else if( strcmp(z,"-zip")==0 ){
10975 data.openMode = SHELL_OPEN_ZIPFILE;
10976#endif
10977 }else if( strcmp(z,"-append")==0 ){
10978 data.openMode = SHELL_OPEN_APPENDVFS;
drha751f392018-10-30 15:31:22 +000010979#ifdef SQLITE_ENABLE_DESERIALIZE
drh60f34ae2018-10-30 13:19:49 +000010980 }else if( strcmp(z,"-deserialize")==0 ){
10981 data.openMode = SHELL_OPEN_DESERIALIZE;
drh6ca64482019-01-22 16:06:20 +000010982 }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
10983 data.szMax = integerValue(argv[++i]);
drha751f392018-10-30 15:31:22 +000010984#endif
drhee269a62018-02-14 23:27:43 +000010985 }else if( strcmp(z,"-readonly")==0 ){
10986 data.openMode = SHELL_OPEN_READONLY;
drh0933aad2019-11-18 17:46:38 +000010987 }else if( strcmp(z,"-nofollow")==0 ){
10988 data.openFlags = SQLITE_OPEN_NOFOLLOW;
drhda57d962018-03-05 19:34:05 +000010989#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
drh93b77312018-03-05 20:20:22 +000010990 }else if( strncmp(z, "-A",2)==0 ){
drhda57d962018-03-05 19:34:05 +000010991 /* All remaining command-line arguments are passed to the ".archive"
10992 ** command, so ignore them */
10993 break;
10994#endif
drh50b910a2019-01-21 14:55:03 +000010995 }else if( strcmp(z, "-memtrace")==0 ){
10996 sqlite3MemTraceActivate(stderr);
drh2ce15c32017-07-11 13:34:40 +000010997 }
10998 }
drhe7df8922018-04-18 10:44:58 +000010999 verify_uninitialized();
11000
dan16a47422018-04-18 09:16:11 +000011001
drhd11b8f62018-04-25 13:27:07 +000011002#ifdef SQLITE_SHELL_INIT_PROC
11003 {
11004 /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name
11005 ** of a C-function that will perform initialization actions on SQLite that
11006 ** occur just before or after sqlite3_initialize(). Use this compile-time
11007 ** option to embed this shell program in larger applications. */
11008 extern void SQLITE_SHELL_INIT_PROC(void);
11009 SQLITE_SHELL_INIT_PROC();
11010 }
11011#else
dan16a47422018-04-18 09:16:11 +000011012 /* All the sqlite3_config() calls have now been made. So it is safe
11013 ** to call sqlite3_initialize() and process any command line -vfs option. */
11014 sqlite3_initialize();
drhd11b8f62018-04-25 13:27:07 +000011015#endif
11016
dan16a47422018-04-18 09:16:11 +000011017 if( zVfs ){
11018 sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
11019 if( pVfs ){
11020 sqlite3_vfs_register(pVfs, 1);
11021 }else{
11022 utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
11023 exit(1);
11024 }
11025 }
11026
drh2ce15c32017-07-11 13:34:40 +000011027 if( data.zDbFilename==0 ){
11028#ifndef SQLITE_OMIT_MEMORYDB
11029 data.zDbFilename = ":memory:";
11030 warnInmemoryDb = argc==1;
11031#else
11032 utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
11033 return 1;
11034#endif
11035 }
11036 data.out = stdout;
drh8682e122018-01-07 20:38:10 +000011037 sqlite3_appendvfs_init(0,0,0);
drh2ce15c32017-07-11 13:34:40 +000011038
11039 /* Go ahead and open the database file if it already exists. If the
11040 ** file does not exist, delay opening it. This prevents empty database
11041 ** files from being created if a user mistypes the database name argument
11042 ** to the sqlite command-line tool.
11043 */
11044 if( access(data.zDbFilename, 0)==0 ){
11045 open_db(&data, 0);
11046 }
11047
11048 /* Process the initialization file if there is one. If no -init option
11049 ** is given on the command line, look for a file named ~/.sqliterc and
11050 ** try to process it.
11051 */
11052 process_sqliterc(&data,zInitFile);
11053
11054 /* Make a second pass through the command-line argument and set
11055 ** options. This second pass is delayed until after the initialization
11056 ** file is processed so that the command-line arguments will override
11057 ** settings in the initialization file.
11058 */
11059 for(i=1; i<argc; i++){
11060 char *z = argv[i];
11061 if( z[0]!='-' ) continue;
11062 if( z[1]=='-' ){ z++; }
11063 if( strcmp(z,"-init")==0 ){
11064 i++;
11065 }else if( strcmp(z,"-html")==0 ){
11066 data.mode = MODE_Html;
11067 }else if( strcmp(z,"-list")==0 ){
11068 data.mode = MODE_List;
11069 }else if( strcmp(z,"-quote")==0 ){
11070 data.mode = MODE_Quote;
drh9191c702020-08-17 09:11:21 +000011071 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Comma);
11072 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row);
drh2ce15c32017-07-11 13:34:40 +000011073 }else if( strcmp(z,"-line")==0 ){
11074 data.mode = MODE_Line;
11075 }else if( strcmp(z,"-column")==0 ){
11076 data.mode = MODE_Column;
drh30c54a02020-05-28 23:49:50 +000011077 }else if( strcmp(z,"-json")==0 ){
11078 data.mode = MODE_Json;
11079 }else if( strcmp(z,"-markdown")==0 ){
11080 data.mode = MODE_Markdown;
11081 }else if( strcmp(z,"-table")==0 ){
11082 data.mode = MODE_Table;
drh0908e382020-06-04 18:05:39 +000011083 }else if( strcmp(z,"-box")==0 ){
11084 data.mode = MODE_Box;
drh2ce15c32017-07-11 13:34:40 +000011085 }else if( strcmp(z,"-csv")==0 ){
11086 data.mode = MODE_Csv;
11087 memcpy(data.colSeparator,",",2);
drh3baed312018-03-08 18:14:41 +000011088#ifdef SQLITE_HAVE_ZLIB
drh1fa6d9f2018-01-06 21:46:01 +000011089 }else if( strcmp(z,"-zip")==0 ){
11090 data.openMode = SHELL_OPEN_ZIPFILE;
11091#endif
11092 }else if( strcmp(z,"-append")==0 ){
11093 data.openMode = SHELL_OPEN_APPENDVFS;
drha751f392018-10-30 15:31:22 +000011094#ifdef SQLITE_ENABLE_DESERIALIZE
drh60f34ae2018-10-30 13:19:49 +000011095 }else if( strcmp(z,"-deserialize")==0 ){
11096 data.openMode = SHELL_OPEN_DESERIALIZE;
drh6ca64482019-01-22 16:06:20 +000011097 }else if( strcmp(z,"-maxsize")==0 && i+1<argc ){
11098 data.szMax = integerValue(argv[++i]);
drha751f392018-10-30 15:31:22 +000011099#endif
drh4aafe592018-03-23 16:08:30 +000011100 }else if( strcmp(z,"-readonly")==0 ){
11101 data.openMode = SHELL_OPEN_READONLY;
drh0933aad2019-11-18 17:46:38 +000011102 }else if( strcmp(z,"-nofollow")==0 ){
11103 data.openFlags |= SQLITE_OPEN_NOFOLLOW;
drh2ce15c32017-07-11 13:34:40 +000011104 }else if( strcmp(z,"-ascii")==0 ){
11105 data.mode = MODE_Ascii;
11106 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
11107 SEP_Unit);
11108 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
11109 SEP_Record);
11110 }else if( strcmp(z,"-separator")==0 ){
11111 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
11112 "%s",cmdline_option_value(argc,argv,++i));
11113 }else if( strcmp(z,"-newline")==0 ){
11114 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
11115 "%s",cmdline_option_value(argc,argv,++i));
11116 }else if( strcmp(z,"-nullvalue")==0 ){
11117 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
11118 "%s",cmdline_option_value(argc,argv,++i));
11119 }else if( strcmp(z,"-header")==0 ){
11120 data.showHeader = 1;
11121 }else if( strcmp(z,"-noheader")==0 ){
11122 data.showHeader = 0;
11123 }else if( strcmp(z,"-echo")==0 ){
11124 ShellSetFlag(&data, SHFLG_Echo);
11125 }else if( strcmp(z,"-eqp")==0 ){
drhada70452017-12-21 21:02:27 +000011126 data.autoEQP = AUTOEQP_on;
drh2ce15c32017-07-11 13:34:40 +000011127 }else if( strcmp(z,"-eqpfull")==0 ){
drhada70452017-12-21 21:02:27 +000011128 data.autoEQP = AUTOEQP_full;
drh2ce15c32017-07-11 13:34:40 +000011129 }else if( strcmp(z,"-stats")==0 ){
11130 data.statsOn = 1;
11131 }else if( strcmp(z,"-scanstats")==0 ){
11132 data.scanstatsOn = 1;
11133 }else if( strcmp(z,"-backslash")==0 ){
11134 /* Undocumented command-line option: -backslash
11135 ** Causes C-style backslash escapes to be evaluated in SQL statements
11136 ** prior to sending the SQL into SQLite. Useful for injecting
11137 ** crazy bytes in the middle of SQL statements for testing and debugging.
11138 */
11139 ShellSetFlag(&data, SHFLG_Backslash);
11140 }else if( strcmp(z,"-bail")==0 ){
11141 bail_on_error = 1;
11142 }else if( strcmp(z,"-version")==0 ){
11143 printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid());
11144 return 0;
11145 }else if( strcmp(z,"-interactive")==0 ){
11146 stdin_is_interactive = 1;
11147 }else if( strcmp(z,"-batch")==0 ){
11148 stdin_is_interactive = 0;
11149 }else if( strcmp(z,"-heap")==0 ){
11150 i++;
drh2ce15c32017-07-11 13:34:40 +000011151 }else if( strcmp(z,"-pagecache")==0 ){
11152 i+=2;
11153 }else if( strcmp(z,"-lookaside")==0 ){
11154 i+=2;
11155 }else if( strcmp(z,"-mmap")==0 ){
11156 i++;
drh50b910a2019-01-21 14:55:03 +000011157 }else if( strcmp(z,"-memtrace")==0 ){
11158 i++;
drha90d84f2018-04-18 15:21:13 +000011159#ifdef SQLITE_ENABLE_SORTER_REFERENCES
11160 }else if( strcmp(z,"-sorterref")==0 ){
11161 i++;
11162#endif
drh2ce15c32017-07-11 13:34:40 +000011163 }else if( strcmp(z,"-vfs")==0 ){
11164 i++;
11165#ifdef SQLITE_ENABLE_VFSTRACE
11166 }else if( strcmp(z,"-vfstrace")==0 ){
11167 i++;
11168#endif
11169#ifdef SQLITE_ENABLE_MULTIPLEX
11170 }else if( strcmp(z,"-multiplex")==0 ){
11171 i++;
11172#endif
11173 }else if( strcmp(z,"-help")==0 ){
11174 usage(1);
11175 }else if( strcmp(z,"-cmd")==0 ){
11176 /* Run commands that follow -cmd first and separately from commands
11177 ** that simply appear on the command-line. This seems goofy. It would
11178 ** be better if all commands ran in the order that they appear. But
11179 ** we retain the goofy behavior for historical compatibility. */
11180 if( i==argc-1 ) break;
11181 z = cmdline_option_value(argc,argv,++i);
11182 if( z[0]=='.' ){
11183 rc = do_meta_command(z, &data);
11184 if( rc && bail_on_error ) return rc==2 ? 0 : rc;
11185 }else{
11186 open_db(&data, 0);
drha10b9992018-03-09 15:24:33 +000011187 rc = shell_exec(&data, z, &zErrMsg);
drh2ce15c32017-07-11 13:34:40 +000011188 if( zErrMsg!=0 ){
11189 utf8_printf(stderr,"Error: %s\n", zErrMsg);
11190 if( bail_on_error ) return rc!=0 ? rc : 1;
11191 }else if( rc!=0 ){
11192 utf8_printf(stderr,"Error: unable to process SQL \"%s\"\n", z);
11193 if( bail_on_error ) return rc;
11194 }
11195 }
drhda57d962018-03-05 19:34:05 +000011196#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
drh93b77312018-03-05 20:20:22 +000011197 }else if( strncmp(z, "-A", 2)==0 ){
drhda57d962018-03-05 19:34:05 +000011198 if( nCmd>0 ){
11199 utf8_printf(stderr, "Error: cannot mix regular SQL or dot-commands"
11200 " with \"%s\"\n", z);
11201 return 1;
11202 }
drhbe4ccb22018-05-17 20:04:24 +000011203 open_db(&data, OPEN_DB_ZIPFILE);
drh93b77312018-03-05 20:20:22 +000011204 if( z[2] ){
11205 argv[i] = &z[2];
drhd0f9cdc2018-05-17 14:09:06 +000011206 arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
drh93b77312018-03-05 20:20:22 +000011207 }else{
drhd0f9cdc2018-05-17 14:09:06 +000011208 arDotCommand(&data, 1, argv+i, argc-i);
drh93b77312018-03-05 20:20:22 +000011209 }
drhda57d962018-03-05 19:34:05 +000011210 readStdin = 0;
11211 break;
11212#endif
drh2ce15c32017-07-11 13:34:40 +000011213 }else{
11214 utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
11215 raw_printf(stderr,"Use -help for a list of options.\n");
11216 return 1;
11217 }
11218 data.cMode = data.mode;
11219 }
11220
11221 if( !readStdin ){
11222 /* Run all arguments that do not begin with '-' as if they were separate
11223 ** command-line inputs, except for the argToSkip argument which contains
11224 ** the database filename.
11225 */
11226 for(i=0; i<nCmd; i++){
11227 if( azCmd[i][0]=='.' ){
11228 rc = do_meta_command(azCmd[i], &data);
11229 if( rc ) return rc==2 ? 0 : rc;
11230 }else{
11231 open_db(&data, 0);
drha10b9992018-03-09 15:24:33 +000011232 rc = shell_exec(&data, azCmd[i], &zErrMsg);
drh2ce15c32017-07-11 13:34:40 +000011233 if( zErrMsg!=0 ){
11234 utf8_printf(stderr,"Error: %s\n", zErrMsg);
11235 return rc!=0 ? rc : 1;
11236 }else if( rc!=0 ){
11237 utf8_printf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
11238 return rc;
11239 }
11240 }
11241 }
11242 free(azCmd);
11243 }else{
11244 /* Run commands received from standard input
11245 */
11246 if( stdin_is_interactive ){
11247 char *zHome;
drha9e4be32018-10-10 18:56:40 +000011248 char *zHistory;
drh2ce15c32017-07-11 13:34:40 +000011249 int nHistory;
11250 printf(
11251 "SQLite version %s %.19s\n" /*extra-version-info*/
11252 "Enter \".help\" for usage hints.\n",
11253 sqlite3_libversion(), sqlite3_sourceid()
11254 );
11255 if( warnInmemoryDb ){
11256 printf("Connected to a ");
11257 printBold("transient in-memory database");
11258 printf(".\nUse \".open FILENAME\" to reopen on a "
11259 "persistent database.\n");
11260 }
drha9e4be32018-10-10 18:56:40 +000011261 zHistory = getenv("SQLITE_HISTORY");
11262 if( zHistory ){
11263 zHistory = strdup(zHistory);
11264 }else if( (zHome = find_home_dir(0))!=0 ){
drh2ce15c32017-07-11 13:34:40 +000011265 nHistory = strlen30(zHome) + 20;
11266 if( (zHistory = malloc(nHistory))!=0 ){
11267 sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
11268 }
11269 }
11270 if( zHistory ){ shell_read_history(zHistory); }
drh56eb09b2017-07-11 13:59:07 +000011271#if HAVE_READLINE || HAVE_EDITLINE
11272 rl_attempted_completion_function = readline_completion;
11273#elif HAVE_LINENOISE
11274 linenoiseSetCompletionCallback(linenoise_completion);
11275#endif
drh60379d42018-12-13 18:30:01 +000011276 data.in = 0;
11277 rc = process_input(&data);
drh2ce15c32017-07-11 13:34:40 +000011278 if( zHistory ){
drh5a75dd82017-07-18 20:59:40 +000011279 shell_stifle_history(2000);
drh2ce15c32017-07-11 13:34:40 +000011280 shell_write_history(zHistory);
11281 free(zHistory);
11282 }
11283 }else{
drh60379d42018-12-13 18:30:01 +000011284 data.in = stdin;
11285 rc = process_input(&data);
drh2ce15c32017-07-11 13:34:40 +000011286 }
11287 }
11288 set_table_name(&data, 0);
11289 if( data.db ){
11290 session_close_all(&data);
drh9e804032018-05-18 17:11:50 +000011291 close_db(data.db);
drh2ce15c32017-07-11 13:34:40 +000011292 }
11293 sqlite3_free(data.zFreeOnClose);
11294 find_home_dir(1);
drh536c3452018-01-11 00:38:39 +000011295 output_reset(&data);
11296 data.doXdgOpen = 0;
drh13c20932018-01-10 21:41:55 +000011297 clearTempFile(&data);
drh2ce15c32017-07-11 13:34:40 +000011298#if !SQLITE_SHELL_IS_UTF8
drh1f22f622018-05-17 13:29:14 +000011299 for(i=0; i<argcToFree; i++) free(argvToFree[i]);
11300 free(argvToFree);
drh2ce15c32017-07-11 13:34:40 +000011301#endif
drh0285d982020-05-29 14:38:43 +000011302 free(data.colWidth);
drh9e804032018-05-18 17:11:50 +000011303 /* Clear the global data structure so that valgrind will detect memory
11304 ** leaks */
11305 memset(&data, 0, sizeof(data));
drh2ce15c32017-07-11 13:34:40 +000011306 return rc;
11307}