Mercurial
comparison third_party/sqlite3/shell.c @ 173:827c6ac504cd hg-web
Merged in default here.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 19 Jan 2026 18:59:10 -0800 |
| parents | 589bab390fb4 |
| children |
comparison
equal
deleted
inserted
replaced
| 151:c033667da5f9 | 173:827c6ac504cd |
|---|---|
| 1 /* DO NOT EDIT! | |
| 2 ** This file is automatically generated by the script in the canonical | |
| 3 ** SQLite source tree at tool/mkshellc.tcl. That script combines source | |
| 4 ** code from various constituent source files of SQLite into this single | |
| 5 ** "shell.c" file used to implement the SQLite command-line shell. | |
| 6 ** | |
| 7 ** Most of the code found below comes from the "src/shell.c.in" file in | |
| 8 ** the canonical SQLite source tree. That main file contains "INCLUDE" | |
| 9 ** lines that specify other files in the canonical source tree that are | |
| 10 ** inserted to getnerate this complete program source file. | |
| 11 ** | |
| 12 ** The code from multiple files is combined into this single "shell.c" | |
| 13 ** source file to help make the command-line program easier to compile. | |
| 14 ** | |
| 15 ** To modify this program, get a copy of the canonical SQLite source tree, | |
| 16 ** edit the src/shell.c.in" and/or some of the other files that are included | |
| 17 ** by "src/shell.c.in", then rerun the tool/mkshellc.tcl script. | |
| 18 */ | |
| 19 /* | |
| 20 ** 2001 September 15 | |
| 21 ** | |
| 22 ** The author disclaims copyright to this source code. In place of | |
| 23 ** a legal notice, here is a blessing: | |
| 24 ** | |
| 25 ** May you do good and not evil. | |
| 26 ** May you find forgiveness for yourself and forgive others. | |
| 27 ** May you share freely, never taking more than you give. | |
| 28 ** | |
| 29 ************************************************************************* | |
| 30 ** This file contains code to implement the "sqlite" command line | |
| 31 ** utility for accessing SQLite databases. | |
| 32 */ | |
| 33 #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) | |
| 34 /* This needs to come before any includes for MSVC compiler */ | |
| 35 #define _CRT_SECURE_NO_WARNINGS | |
| 36 #endif | |
| 37 typedef unsigned int u32; | |
| 38 typedef unsigned short int u16; | |
| 39 | |
| 40 /* | |
| 41 ** Optionally #include a user-defined header, whereby compilation options | |
| 42 ** may be set prior to where they take effect, but after platform setup. | |
| 43 ** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include | |
| 44 ** file. Note that this macro has a like effect on sqlite3.c compilation. | |
| 45 */ | |
| 46 # define SHELL_STRINGIFY_(f) #f | |
| 47 # define SHELL_STRINGIFY(f) SHELL_STRINGIFY_(f) | |
| 48 #ifdef SQLITE_CUSTOM_INCLUDE | |
| 49 # include SHELL_STRINGIFY(SQLITE_CUSTOM_INCLUDE) | |
| 50 #endif | |
| 51 | |
| 52 /* | |
| 53 ** Determine if we are dealing with WinRT, which provides only a subset of | |
| 54 ** the full Win32 API. | |
| 55 */ | |
| 56 #if !defined(SQLITE_OS_WINRT) | |
| 57 # define SQLITE_OS_WINRT 0 | |
| 58 #endif | |
| 59 | |
| 60 /* | |
| 61 ** If SQLITE_SHELL_FIDDLE is defined then the shell is modified | |
| 62 ** somewhat for use as a WASM module in a web browser. This flag | |
| 63 ** should only be used when building the "fiddle" web application, as | |
| 64 ** the browser-mode build has much different user input requirements | |
| 65 ** and this build mode rewires the user input subsystem to account for | |
| 66 ** that. | |
| 67 */ | |
| 68 | |
| 69 /* | |
| 70 ** Warning pragmas copied from msvc.h in the core. | |
| 71 */ | |
| 72 #if defined(_MSC_VER) | |
| 73 #pragma warning(disable : 4054) | |
| 74 #pragma warning(disable : 4055) | |
| 75 #pragma warning(disable : 4100) | |
| 76 #pragma warning(disable : 4127) | |
| 77 #pragma warning(disable : 4130) | |
| 78 #pragma warning(disable : 4152) | |
| 79 #pragma warning(disable : 4189) | |
| 80 #pragma warning(disable : 4206) | |
| 81 #pragma warning(disable : 4210) | |
| 82 #pragma warning(disable : 4232) | |
| 83 #pragma warning(disable : 4244) | |
| 84 #pragma warning(disable : 4305) | |
| 85 #pragma warning(disable : 4306) | |
| 86 #pragma warning(disable : 4702) | |
| 87 #pragma warning(disable : 4706) | |
| 88 #endif /* defined(_MSC_VER) */ | |
| 89 | |
| 90 /* | |
| 91 ** No support for loadable extensions in VxWorks. | |
| 92 */ | |
| 93 #if (defined(__RTP__) || defined(_WRS_KERNEL)) && !SQLITE_OMIT_LOAD_EXTENSION | |
| 94 # define SQLITE_OMIT_LOAD_EXTENSION 1 | |
| 95 #endif | |
| 96 | |
| 97 /* | |
| 98 ** Enable large-file support for fopen() and friends on unix. | |
| 99 */ | |
| 100 #ifndef SQLITE_DISABLE_LFS | |
| 101 # define _LARGE_FILE 1 | |
| 102 # ifndef _FILE_OFFSET_BITS | |
| 103 # define _FILE_OFFSET_BITS 64 | |
| 104 # endif | |
| 105 # define _LARGEFILE_SOURCE 1 | |
| 106 #endif | |
| 107 | |
| 108 #if defined(SQLITE_SHELL_FIDDLE) && !defined(_POSIX_SOURCE) | |
| 109 /* | |
| 110 ** emcc requires _POSIX_SOURCE (or one of several similar defines) | |
| 111 ** to expose strdup(). | |
| 112 */ | |
| 113 # define _POSIX_SOURCE | |
| 114 #endif | |
| 115 | |
| 116 #include <stdlib.h> | |
| 117 #include <string.h> | |
| 118 #include <stdio.h> | |
| 119 #include <assert.h> | |
| 120 #include <math.h> | |
| 121 #include "sqlite3.h" | |
| 122 typedef sqlite3_int64 i64; | |
| 123 typedef sqlite3_uint64 u64; | |
| 124 typedef unsigned char u8; | |
| 125 #include <ctype.h> | |
| 126 #include <stdarg.h> | |
| 127 #ifndef _WIN32 | |
| 128 # include <sys/time.h> | |
| 129 #endif | |
| 130 | |
| 131 #if !defined(_WIN32) && !defined(WIN32) | |
| 132 # include <signal.h> | |
| 133 # if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI) | |
| 134 # include <pwd.h> | |
| 135 # endif | |
| 136 #endif | |
| 137 #if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__) | |
| 138 # include <unistd.h> | |
| 139 # include <dirent.h> | |
| 140 # define GETPID getpid | |
| 141 # if defined(__MINGW32__) | |
| 142 # define DIRENT dirent | |
| 143 # ifndef S_ISLNK | |
| 144 # define S_ISLNK(mode) (0) | |
| 145 # endif | |
| 146 # endif | |
| 147 #else | |
| 148 # define GETPID (int)GetCurrentProcessId | |
| 149 #endif | |
| 150 #include <sys/types.h> | |
| 151 #include <sys/stat.h> | |
| 152 | |
| 153 #if HAVE_READLINE | |
| 154 # include <readline/readline.h> | |
| 155 # include <readline/history.h> | |
| 156 #endif | |
| 157 | |
| 158 #if HAVE_EDITLINE | |
| 159 # include <editline/readline.h> | |
| 160 #endif | |
| 161 | |
| 162 #if HAVE_EDITLINE || HAVE_READLINE | |
| 163 | |
| 164 # define shell_add_history(X) add_history(X) | |
| 165 # define shell_read_history(X) read_history(X) | |
| 166 # define shell_write_history(X) write_history(X) | |
| 167 # define shell_stifle_history(X) stifle_history(X) | |
| 168 # define shell_readline(X) readline(X) | |
| 169 | |
| 170 #elif HAVE_LINENOISE | |
| 171 | |
| 172 # include "linenoise.h" | |
| 173 # define shell_add_history(X) linenoiseHistoryAdd(X) | |
| 174 # define shell_read_history(X) linenoiseHistoryLoad(X) | |
| 175 # define shell_write_history(X) linenoiseHistorySave(X) | |
| 176 # define shell_stifle_history(X) linenoiseHistorySetMaxLen(X) | |
| 177 # define shell_readline(X) linenoise(X) | |
| 178 | |
| 179 #else | |
| 180 | |
| 181 # define shell_read_history(X) | |
| 182 # define shell_write_history(X) | |
| 183 # define shell_stifle_history(X) | |
| 184 | |
| 185 # define SHELL_USE_LOCAL_GETLINE 1 | |
| 186 #endif | |
| 187 | |
| 188 #ifndef deliberate_fall_through | |
| 189 /* Quiet some compilers about some of our intentional code. */ | |
| 190 # if defined(GCC_VERSION) && GCC_VERSION>=7000000 | |
| 191 # define deliberate_fall_through __attribute__((fallthrough)); | |
| 192 # else | |
| 193 # define deliberate_fall_through | |
| 194 # endif | |
| 195 #endif | |
| 196 | |
| 197 #if defined(_WIN32) || defined(WIN32) | |
| 198 # if SQLITE_OS_WINRT | |
| 199 # define SQLITE_OMIT_POPEN 1 | |
| 200 # else | |
| 201 # include <io.h> | |
| 202 # include <fcntl.h> | |
| 203 # define isatty(h) _isatty(h) | |
| 204 # ifndef access | |
| 205 # define access(f,m) _access((f),(m)) | |
| 206 # endif | |
| 207 # ifndef unlink | |
| 208 # define unlink _unlink | |
| 209 # endif | |
| 210 # ifndef strdup | |
| 211 # define strdup _strdup | |
| 212 # endif | |
| 213 # undef pclose | |
| 214 # define pclose _pclose | |
| 215 # endif | |
| 216 #else | |
| 217 /* Make sure isatty() has a prototype. */ | |
| 218 extern int isatty(int); | |
| 219 | |
| 220 # if !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI) | |
| 221 /* popen and pclose are not C89 functions and so are | |
| 222 ** sometimes omitted from the <stdio.h> header */ | |
| 223 extern FILE *popen(const char*,const char*); | |
| 224 extern int pclose(FILE*); | |
| 225 # else | |
| 226 # define SQLITE_OMIT_POPEN 1 | |
| 227 # endif | |
| 228 #endif | |
| 229 | |
| 230 #if defined(_WIN32_WCE) | |
| 231 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() | |
| 232 * thus we always assume that we have a console. That can be | |
| 233 * overridden with the -batch command line option. | |
| 234 */ | |
| 235 #define isatty(x) 1 | |
| 236 #endif | |
| 237 | |
| 238 /* ctype macros that work with signed characters */ | |
| 239 #define IsSpace(X) isspace((unsigned char)X) | |
| 240 #define IsDigit(X) isdigit((unsigned char)X) | |
| 241 #define ToLower(X) (char)tolower((unsigned char)X) | |
| 242 #define IsAlnum(X) isalnum((unsigned char)X) | |
| 243 #define IsAlpha(X) isalpha((unsigned char)X) | |
| 244 | |
| 245 #if defined(_WIN32) || defined(WIN32) | |
| 246 #if SQLITE_OS_WINRT | |
| 247 #include <intrin.h> | |
| 248 #endif | |
| 249 #undef WIN32_LEAN_AND_MEAN | |
| 250 #define WIN32_LEAN_AND_MEAN | |
| 251 #include <windows.h> | |
| 252 | |
| 253 /* string conversion routines only needed on Win32 */ | |
| 254 extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); | |
| 255 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); | |
| 256 #endif | |
| 257 | |
| 258 /************************* Begin ../ext/misc/sqlite3_stdio.h ******************/ | |
| 259 /* | |
| 260 ** 2024-09-24 | |
| 261 ** | |
| 262 ** The author disclaims copyright to this source code. In place of | |
| 263 ** a legal notice, here is a blessing: | |
| 264 ** | |
| 265 ** May you do good and not evil. | |
| 266 ** May you find forgiveness for yourself and forgive others. | |
| 267 ** May you share freely, never taking more than you give. | |
| 268 ** | |
| 269 ************************************************************************* | |
| 270 ** | |
| 271 ** This header file contains definitions of interfaces that provide | |
| 272 ** cross-platform I/O for UTF-8 content. | |
| 273 ** | |
| 274 ** On most platforms, the interfaces definitions in this file are | |
| 275 ** just #defines. For example sqlite3_fopen() is a macro that resolves | |
| 276 ** to the standard fopen() in the C-library. | |
| 277 ** | |
| 278 ** But Windows does not have a standard C-library, at least not one that | |
| 279 ** can handle UTF-8. So for windows build, the interfaces resolve to new | |
| 280 ** C-language routines contained in the separate sqlite3_stdio.c source file. | |
| 281 ** | |
| 282 ** So on all non-Windows platforms, simply #include this header file and | |
| 283 ** use the interfaces defined herein. Then to run your application on Windows, | |
| 284 ** also link in the accompanying sqlite3_stdio.c source file when compiling | |
| 285 ** to get compatible interfaces. | |
| 286 */ | |
| 287 #ifndef _SQLITE3_STDIO_H_ | |
| 288 #define _SQLITE3_STDIO_H_ 1 | |
| 289 #ifdef _WIN32 | |
| 290 /**** Definitions For Windows ****/ | |
| 291 #include <stdio.h> | |
| 292 #include <windows.h> | |
| 293 | |
| 294 FILE *sqlite3_fopen(const char *zFilename, const char *zMode); | |
| 295 FILE *sqlite3_popen(const char *zCommand, const char *type); | |
| 296 char *sqlite3_fgets(char *s, int size, FILE *stream); | |
| 297 int sqlite3_fputs(const char *s, FILE *stream); | |
| 298 int sqlite3_fprintf(FILE *stream, const char *format, ...); | |
| 299 void sqlite3_fsetmode(FILE *stream, int mode); | |
| 300 | |
| 301 | |
| 302 #else | |
| 303 /**** Definitions For All Other Platforms ****/ | |
| 304 #include <stdio.h> | |
| 305 #define sqlite3_fopen fopen | |
| 306 #define sqlite3_popen popen | |
| 307 #define sqlite3_fgets fgets | |
| 308 #define sqlite3_fputs fputs | |
| 309 #define sqlite3_fprintf fprintf | |
| 310 #define sqlite3_fsetmode(F,X) /*no-op*/ | |
| 311 | |
| 312 #endif | |
| 313 #endif /* _SQLITE3_STDIO_H_ */ | |
| 314 | |
| 315 /************************* End ../ext/misc/sqlite3_stdio.h ********************/ | |
| 316 /************************* Begin ../ext/misc/sqlite3_stdio.c ******************/ | |
| 317 /* | |
| 318 ** 2024-09-24 | |
| 319 ** | |
| 320 ** The author disclaims copyright to this source code. In place of | |
| 321 ** a legal notice, here is a blessing: | |
| 322 ** | |
| 323 ** May you do good and not evil. | |
| 324 ** May you find forgiveness for yourself and forgive others. | |
| 325 ** May you share freely, never taking more than you give. | |
| 326 ** | |
| 327 ************************************************************************* | |
| 328 ** | |
| 329 ** Implementation of standard I/O interfaces for UTF-8 that are missing | |
| 330 ** on Windows. | |
| 331 */ | |
| 332 #ifdef _WIN32 /* This file is a no-op on all platforms except Windows */ | |
| 333 #ifndef _SQLITE3_STDIO_H_ | |
| 334 /* #include "sqlite3_stdio.h" */ | |
| 335 #endif | |
| 336 #undef WIN32_LEAN_AND_MEAN | |
| 337 #define WIN32_LEAN_AND_MEAN | |
| 338 #include <windows.h> | |
| 339 #include <stdlib.h> | |
| 340 #include <string.h> | |
| 341 #include <stdio.h> | |
| 342 #include <assert.h> | |
| 343 /* #include "sqlite3.h" */ | |
| 344 #include <ctype.h> | |
| 345 #include <stdarg.h> | |
| 346 #include <io.h> | |
| 347 #include <fcntl.h> | |
| 348 | |
| 349 /* | |
| 350 ** If the SQLITE_U8TEXT_ONLY option is defined, then use O_U8TEXT | |
| 351 ** when appropriate on all output. (Sometimes use O_BINARY when | |
| 352 ** rendering ASCII text in cases where NL-to-CRLF expansion would | |
| 353 ** not be correct.) | |
| 354 ** | |
| 355 ** If the SQLITE_U8TEXT_STDIO option is defined, then use O_U8TEXT | |
| 356 ** when appropriate when writing to stdout or stderr. Use O_BINARY | |
| 357 ** or O_TEXT (depending on things like the .mode and the .crlf setting | |
| 358 ** in the CLI, or other context clues in other applications) for all | |
| 359 ** other output channels. | |
| 360 ** | |
| 361 ** The default behavior, if neither of the above is defined is to | |
| 362 ** use O_U8TEXT when writing to the Windows console (or anything | |
| 363 ** else for which _isatty() returns true) and to use O_BINARY or O_TEXT | |
| 364 ** for all other output channels. | |
| 365 ** | |
| 366 ** The SQLITE_USE_W32_FOR_CONSOLE_IO macro is also available. If | |
| 367 ** defined, it forces the use of Win32 APIs for all console I/O, both | |
| 368 ** input and output. This is necessary for some non-Microsoft run-times | |
| 369 ** that implement stdio differently from Microsoft/Visual-Studio. | |
| 370 */ | |
| 371 #if defined(SQLITE_U8TEXT_ONLY) | |
| 372 # define UseWtextForOutput(fd) 1 | |
| 373 # define UseWtextForInput(fd) 1 | |
| 374 # define IsConsole(fd) _isatty(_fileno(fd)) | |
| 375 #elif defined(SQLITE_U8TEXT_STDIO) | |
| 376 # define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) | |
| 377 # define UseWtextForInput(fd) ((fd)==stdin) | |
| 378 # define IsConsole(fd) _isatty(_fileno(fd)) | |
| 379 #else | |
| 380 # define UseWtextForOutput(fd) _isatty(_fileno(fd)) | |
| 381 # define UseWtextForInput(fd) _isatty(_fileno(fd)) | |
| 382 # define IsConsole(fd) 1 | |
| 383 #endif | |
| 384 | |
| 385 /* | |
| 386 ** Global variables determine if simulated O_BINARY mode is to be | |
| 387 ** used for stdout or other, respectively. Simulated O_BINARY mode | |
| 388 ** means the mode is usually O_BINARY, but switches to O_U8TEXT for | |
| 389 ** unicode characters U+0080 or greater (any character that has a | |
| 390 ** multi-byte representation in UTF-8). This is the only way we | |
| 391 ** have found to render Unicode characters on a Windows console while | |
| 392 ** at the same time avoiding undesirable \n to \r\n translation. | |
| 393 */ | |
| 394 static int simBinaryStdout = 0; | |
| 395 static int simBinaryOther = 0; | |
| 396 | |
| 397 | |
| 398 /* | |
| 399 ** Determine if simulated binary mode should be used for output to fd | |
| 400 */ | |
| 401 static int UseBinaryWText(FILE *fd){ | |
| 402 if( fd==stdout || fd==stderr ){ | |
| 403 return simBinaryStdout; | |
| 404 }else{ | |
| 405 return simBinaryOther; | |
| 406 } | |
| 407 } | |
| 408 | |
| 409 | |
| 410 /* | |
| 411 ** Work-alike for the fopen() routine from the standard C library. | |
| 412 */ | |
| 413 FILE *sqlite3_fopen(const char *zFilename, const char *zMode){ | |
| 414 FILE *fp = 0; | |
| 415 wchar_t *b1, *b2; | |
| 416 int sz1, sz2; | |
| 417 | |
| 418 sz1 = (int)strlen(zFilename); | |
| 419 sz2 = (int)strlen(zMode); | |
| 420 b1 = sqlite3_malloc( (sz1+1)*sizeof(b1[0]) ); | |
| 421 b2 = sqlite3_malloc( (sz2+1)*sizeof(b1[0]) ); | |
| 422 if( b1 && b2 ){ | |
| 423 sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1); | |
| 424 b1[sz1] = 0; | |
| 425 sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); | |
| 426 b2[sz2] = 0; | |
| 427 fp = _wfopen(b1, b2); | |
| 428 } | |
| 429 sqlite3_free(b1); | |
| 430 sqlite3_free(b2); | |
| 431 simBinaryOther = 0; | |
| 432 return fp; | |
| 433 } | |
| 434 | |
| 435 | |
| 436 /* | |
| 437 ** Work-alike for the popen() routine from the standard C library. | |
| 438 */ | |
| 439 FILE *sqlite3_popen(const char *zCommand, const char *zMode){ | |
| 440 FILE *fp = 0; | |
| 441 wchar_t *b1, *b2; | |
| 442 int sz1, sz2; | |
| 443 | |
| 444 sz1 = (int)strlen(zCommand); | |
| 445 sz2 = (int)strlen(zMode); | |
| 446 b1 = sqlite3_malloc( (sz1+1)*sizeof(b1[0]) ); | |
| 447 b2 = sqlite3_malloc( (sz2+1)*sizeof(b1[0]) ); | |
| 448 if( b1 && b2 ){ | |
| 449 sz1 = MultiByteToWideChar(CP_UTF8, 0, zCommand, sz1, b1, sz1); | |
| 450 b1[sz1] = 0; | |
| 451 sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); | |
| 452 b2[sz2] = 0; | |
| 453 fp = _wpopen(b1, b2); | |
| 454 } | |
| 455 sqlite3_free(b1); | |
| 456 sqlite3_free(b2); | |
| 457 return fp; | |
| 458 } | |
| 459 | |
| 460 /* | |
| 461 ** Work-alike for fgets() from the standard C library. | |
| 462 */ | |
| 463 char *sqlite3_fgets(char *buf, int sz, FILE *in){ | |
| 464 if( UseWtextForInput(in) ){ | |
| 465 /* When reading from the command-prompt in Windows, it is necessary | |
| 466 ** to use _O_WTEXT input mode to read UTF-16 characters, then translate | |
| 467 ** that into UTF-8. Otherwise, non-ASCII characters all get translated | |
| 468 ** into '?'. | |
| 469 */ | |
| 470 wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) ); | |
| 471 if( b1==0 ) return 0; | |
| 472 #ifdef SQLITE_USE_W32_FOR_CONSOLE_IO | |
| 473 DWORD nRead = 0; | |
| 474 if( IsConsole(in) | |
| 475 && ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz-1, &nRead, 0) | |
| 476 ){ | |
| 477 b1[nRead] = 0; | |
| 478 }else | |
| 479 #endif | |
| 480 { | |
| 481 _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT); | |
| 482 if( fgetws(b1, sz/4, in)==0 ){ | |
| 483 sqlite3_free(b1); | |
| 484 return 0; | |
| 485 } | |
| 486 } | |
| 487 WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0); | |
| 488 sqlite3_free(b1); | |
| 489 return buf; | |
| 490 }else{ | |
| 491 /* Reading from a file or other input source, just read bytes without | |
| 492 ** any translation. */ | |
| 493 return fgets(buf, sz, in); | |
| 494 } | |
| 495 } | |
| 496 | |
| 497 /* | |
| 498 ** Send ASCII text as O_BINARY. But for Unicode characters U+0080 and | |
| 499 ** greater, switch to O_U8TEXT. | |
| 500 */ | |
| 501 static void piecemealOutput(wchar_t *b1, int sz, FILE *out){ | |
| 502 int i; | |
| 503 wchar_t c; | |
| 504 while( sz>0 ){ | |
| 505 for(i=0; i<sz && b1[i]>=0x80; i++){} | |
| 506 if( i>0 ){ | |
| 507 c = b1[i]; | |
| 508 b1[i] = 0; | |
| 509 fflush(out); | |
| 510 _setmode(_fileno(out), _O_U8TEXT); | |
| 511 fputws(b1, out); | |
| 512 fflush(out); | |
| 513 b1 += i; | |
| 514 b1[0] = c; | |
| 515 sz -= i; | |
| 516 }else{ | |
| 517 fflush(out); | |
| 518 _setmode(_fileno(out), _O_TEXT); | |
| 519 _setmode(_fileno(out), _O_BINARY); | |
| 520 fwrite(&b1[0], 1, 1, out); | |
| 521 for(i=1; i<sz && b1[i]<0x80; i++){ | |
| 522 fwrite(&b1[i], 1, 1, out); | |
| 523 } | |
| 524 fflush(out); | |
| 525 _setmode(_fileno(out), _O_U8TEXT); | |
| 526 b1 += i; | |
| 527 sz -= i; | |
| 528 } | |
| 529 } | |
| 530 } | |
| 531 | |
| 532 /* | |
| 533 ** Work-alike for fputs() from the standard C library. | |
| 534 */ | |
| 535 int sqlite3_fputs(const char *z, FILE *out){ | |
| 536 if( !UseWtextForOutput(out) ){ | |
| 537 /* Writing to a file or other destination, just write bytes without | |
| 538 ** any translation. */ | |
| 539 return fputs(z, out); | |
| 540 }else{ | |
| 541 /* One must use UTF16 in order to get unicode support when writing | |
| 542 ** to the console on Windows. | |
| 543 */ | |
| 544 int sz = (int)strlen(z); | |
| 545 wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) ); | |
| 546 if( b1==0 ) return 0; | |
| 547 sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); | |
| 548 b1[sz] = 0; | |
| 549 | |
| 550 #ifdef SQLITE_USE_W32_FOR_CONSOLE_IO | |
| 551 DWORD nWr = 0; | |
| 552 if( IsConsole(out) | |
| 553 && WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),b1,sz,&nWr,0) | |
| 554 ){ | |
| 555 /* If writing to the console, then the WriteConsoleW() is all we | |
| 556 ** need to do. */ | |
| 557 }else | |
| 558 #endif | |
| 559 { | |
| 560 /* As long as SQLITE_USE_W32_FOR_CONSOLE_IO is not defined, or for | |
| 561 ** non-console I/O even if that macro is defined, write using the | |
| 562 ** standard library. */ | |
| 563 _setmode(_fileno(out), _O_U8TEXT); | |
| 564 if( UseBinaryWText(out) ){ | |
| 565 piecemealOutput(b1, sz, out); | |
| 566 }else{ | |
| 567 fputws(b1, out); | |
| 568 } | |
| 569 } | |
| 570 sqlite3_free(b1); | |
| 571 return 0; | |
| 572 } | |
| 573 } | |
| 574 | |
| 575 | |
| 576 /* | |
| 577 ** Work-alike for fprintf() from the standard C library. | |
| 578 */ | |
| 579 int sqlite3_fprintf(FILE *out, const char *zFormat, ...){ | |
| 580 int rc; | |
| 581 if( UseWtextForOutput(out) ){ | |
| 582 /* When writing to the command-prompt in Windows, it is necessary | |
| 583 ** to use _O_WTEXT input mode and write UTF-16 characters. | |
| 584 */ | |
| 585 char *z; | |
| 586 va_list ap; | |
| 587 | |
| 588 va_start(ap, zFormat); | |
| 589 z = sqlite3_vmprintf(zFormat, ap); | |
| 590 va_end(ap); | |
| 591 sqlite3_fputs(z, out); | |
| 592 rc = (int)strlen(z); | |
| 593 sqlite3_free(z); | |
| 594 }else{ | |
| 595 /* Writing to a file or other destination, just write bytes without | |
| 596 ** any translation. */ | |
| 597 va_list ap; | |
| 598 va_start(ap, zFormat); | |
| 599 rc = vfprintf(out, zFormat, ap); | |
| 600 va_end(ap); | |
| 601 } | |
| 602 return rc; | |
| 603 } | |
| 604 | |
| 605 /* | |
| 606 ** Set the mode for an output stream. mode argument is typically _O_BINARY or | |
| 607 ** _O_TEXT. | |
| 608 */ | |
| 609 void sqlite3_fsetmode(FILE *fp, int mode){ | |
| 610 if( !UseWtextForOutput(fp) ){ | |
| 611 fflush(fp); | |
| 612 _setmode(_fileno(fp), mode); | |
| 613 }else if( fp==stdout || fp==stderr ){ | |
| 614 simBinaryStdout = (mode==_O_BINARY); | |
| 615 }else{ | |
| 616 simBinaryOther = (mode==_O_BINARY); | |
| 617 } | |
| 618 } | |
| 619 | |
| 620 #endif /* defined(_WIN32) */ | |
| 621 | |
| 622 /************************* End ../ext/misc/sqlite3_stdio.c ********************/ | |
| 623 | |
| 624 /* Use console I/O package as a direct INCLUDE. */ | |
| 625 #define SQLITE_INTERNAL_LINKAGE static | |
| 626 | |
| 627 #ifdef SQLITE_SHELL_FIDDLE | |
| 628 /* Deselect most features from the console I/O package for Fiddle. */ | |
| 629 # define SQLITE_CIO_NO_REDIRECT | |
| 630 # define SQLITE_CIO_NO_CLASSIFY | |
| 631 # define SQLITE_CIO_NO_TRANSLATE | |
| 632 # define SQLITE_CIO_NO_SETMODE | |
| 633 # define SQLITE_CIO_NO_FLUSH | |
| 634 #endif | |
| 635 | |
| 636 #define eputz(z) sqlite3_fputs(z,stderr) | |
| 637 #define sputz(fp,z) sqlite3_fputs(z,fp) | |
| 638 | |
| 639 /* True if the timer is enabled */ | |
| 640 static int enableTimer = 0; | |
| 641 | |
| 642 /* A version of strcmp() that works with NULL values */ | |
| 643 static int cli_strcmp(const char *a, const char *b){ | |
| 644 if( a==0 ) a = ""; | |
| 645 if( b==0 ) b = ""; | |
| 646 return strcmp(a,b); | |
| 647 } | |
| 648 static int cli_strncmp(const char *a, const char *b, size_t n){ | |
| 649 if( a==0 ) a = ""; | |
| 650 if( b==0 ) b = ""; | |
| 651 return strncmp(a,b,n); | |
| 652 } | |
| 653 | |
| 654 /* Return the current wall-clock time in microseconds since the | |
| 655 ** Unix epoch (1970-01-01T00:00:00Z) | |
| 656 */ | |
| 657 static sqlite3_int64 timeOfDay(void){ | |
| 658 #if defined(_WIN64) | |
| 659 sqlite3_uint64 t; | |
| 660 FILETIME tm; | |
| 661 GetSystemTimePreciseAsFileTime(&tm); | |
| 662 t = ((u64)tm.dwHighDateTime<<32) | (u64)tm.dwLowDateTime; | |
| 663 t += 116444736000000000LL; | |
| 664 t /= 10; | |
| 665 return t; | |
| 666 #elif defined(_WIN32) | |
| 667 static sqlite3_vfs *clockVfs = 0; | |
| 668 sqlite3_int64 t; | |
| 669 if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); | |
| 670 if( clockVfs==0 ) return 0; /* Never actually happens */ | |
| 671 if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ | |
| 672 clockVfs->xCurrentTimeInt64(clockVfs, &t); | |
| 673 }else{ | |
| 674 double r; | |
| 675 clockVfs->xCurrentTime(clockVfs, &r); | |
| 676 t = (sqlite3_int64)(r*86400000.0); | |
| 677 } | |
| 678 return t*1000; | |
| 679 #else | |
| 680 struct timeval sNow; | |
| 681 (void)gettimeofday(&sNow,0); | |
| 682 return ((i64)sNow.tv_sec)*1000000 + sNow.tv_usec; | |
| 683 #endif | |
| 684 } | |
| 685 | |
| 686 #if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) | |
| 687 #include <sys/time.h> | |
| 688 #include <sys/resource.h> | |
| 689 | |
| 690 /* VxWorks does not support getrusage() as far as we can determine */ | |
| 691 #if defined(_WRS_KERNEL) || defined(__RTP__) | |
| 692 struct rusage { | |
| 693 struct timeval ru_utime; /* user CPU time used */ | |
| 694 struct timeval ru_stime; /* system CPU time used */ | |
| 695 }; | |
| 696 #define getrusage(A,B) memset(B,0,sizeof(*B)) | |
| 697 #endif | |
| 698 | |
| 699 | |
| 700 /* Saved resource information for the beginning of an operation */ | |
| 701 static struct rusage sBegin; /* CPU time at start */ | |
| 702 static sqlite3_int64 iBegin; /* Wall-clock time at start */ | |
| 703 | |
| 704 /* | |
| 705 ** Begin timing an operation | |
| 706 */ | |
| 707 static void beginTimer(void){ | |
| 708 if( enableTimer ){ | |
| 709 getrusage(RUSAGE_SELF, &sBegin); | |
| 710 iBegin = timeOfDay(); | |
| 711 } | |
| 712 } | |
| 713 | |
| 714 /* Return the difference of two time_structs in seconds */ | |
| 715 static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ | |
| 716 return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + | |
| 717 (double)(pEnd->tv_sec - pStart->tv_sec); | |
| 718 } | |
| 719 | |
| 720 /* | |
| 721 ** Print the timing results. | |
| 722 */ | |
| 723 static void endTimer(FILE *out){ | |
| 724 if( enableTimer ){ | |
| 725 sqlite3_int64 iEnd = timeOfDay(); | |
| 726 struct rusage sEnd; | |
| 727 getrusage(RUSAGE_SELF, &sEnd); | |
| 728 sqlite3_fprintf(out, "Run Time: real %.6f user %.6f sys %.6f\n", | |
| 729 (iEnd - iBegin)*0.000001, | |
| 730 timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), | |
| 731 timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); | |
| 732 } | |
| 733 } | |
| 734 | |
| 735 #define BEGIN_TIMER beginTimer() | |
| 736 #define END_TIMER(X) endTimer(X) | |
| 737 #define HAS_TIMER 1 | |
| 738 | |
| 739 #elif (defined(_WIN32) || defined(WIN32)) | |
| 740 | |
| 741 /* Saved resource information for the beginning of an operation */ | |
| 742 static HANDLE hProcess; | |
| 743 static FILETIME ftKernelBegin; | |
| 744 static FILETIME ftUserBegin; | |
| 745 static sqlite3_int64 ftWallBegin; | |
| 746 typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, | |
| 747 LPFILETIME, LPFILETIME); | |
| 748 static GETPROCTIMES getProcessTimesAddr = NULL; | |
| 749 | |
| 750 /* | |
| 751 ** Check to see if we have timer support. Return 1 if necessary | |
| 752 ** support found (or found previously). | |
| 753 */ | |
| 754 static int hasTimer(void){ | |
| 755 if( getProcessTimesAddr ){ | |
| 756 return 1; | |
| 757 } else { | |
| 758 #if !SQLITE_OS_WINRT | |
| 759 /* GetProcessTimes() isn't supported in WIN95 and some other Windows | |
| 760 ** versions. See if the version we are running on has it, and if it | |
| 761 ** does, save off a pointer to it and the current process handle. | |
| 762 */ | |
| 763 hProcess = GetCurrentProcess(); | |
| 764 if( hProcess ){ | |
| 765 HINSTANCE hinstLib = LoadLibrary(TEXT("Kernel32.dll")); | |
| 766 if( NULL != hinstLib ){ | |
| 767 getProcessTimesAddr = | |
| 768 (GETPROCTIMES) GetProcAddress(hinstLib, "GetProcessTimes"); | |
| 769 if( NULL != getProcessTimesAddr ){ | |
| 770 return 1; | |
| 771 } | |
| 772 FreeLibrary(hinstLib); | |
| 773 } | |
| 774 } | |
| 775 #endif | |
| 776 } | |
| 777 return 0; | |
| 778 } | |
| 779 | |
| 780 /* | |
| 781 ** Begin timing an operation | |
| 782 */ | |
| 783 static void beginTimer(void){ | |
| 784 if( enableTimer && getProcessTimesAddr ){ | |
| 785 FILETIME ftCreation, ftExit; | |
| 786 getProcessTimesAddr(hProcess,&ftCreation,&ftExit, | |
| 787 &ftKernelBegin,&ftUserBegin); | |
| 788 ftWallBegin = timeOfDay(); | |
| 789 } | |
| 790 } | |
| 791 | |
| 792 /* Return the difference of two FILETIME structs in seconds */ | |
| 793 static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ | |
| 794 sqlite_int64 i64Start = *((sqlite_int64 *) pStart); | |
| 795 sqlite_int64 i64End = *((sqlite_int64 *) pEnd); | |
| 796 return (double) ((i64End - i64Start) / 10000000.0); | |
| 797 } | |
| 798 | |
| 799 /* | |
| 800 ** Print the timing results. | |
| 801 */ | |
| 802 static void endTimer(FILE *out){ | |
| 803 if( enableTimer && getProcessTimesAddr){ | |
| 804 FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; | |
| 805 sqlite3_int64 ftWallEnd = timeOfDay(); | |
| 806 getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); | |
| 807 #ifdef _WIN64 | |
| 808 /* microsecond precision on 64-bit windows */ | |
| 809 sqlite3_fprintf(out, "Run Time: real %.6f user %f sys %f\n", | |
| 810 (ftWallEnd - ftWallBegin)*0.000001, | |
| 811 timeDiff(&ftUserBegin, &ftUserEnd), | |
| 812 timeDiff(&ftKernelBegin, &ftKernelEnd)); | |
| 813 #else | |
| 814 /* millisecond precisino on 32-bit windows */ | |
| 815 sqlite3_fprintf(out, "Run Time: real %.3f user %.3f sys %.3f\n", | |
| 816 (ftWallEnd - ftWallBegin)*0.000001, | |
| 817 timeDiff(&ftUserBegin, &ftUserEnd), | |
| 818 timeDiff(&ftKernelBegin, &ftKernelEnd)); | |
| 819 #endif | |
| 820 } | |
| 821 } | |
| 822 | |
| 823 #define BEGIN_TIMER beginTimer() | |
| 824 #define END_TIMER(X) endTimer(X) | |
| 825 #define HAS_TIMER hasTimer() | |
| 826 | |
| 827 #else | |
| 828 #define BEGIN_TIMER | |
| 829 #define END_TIMER(X) /*no-op*/ | |
| 830 #define HAS_TIMER 0 | |
| 831 #endif | |
| 832 | |
| 833 /* | |
| 834 ** Used to prevent warnings about unused parameters | |
| 835 */ | |
| 836 #define UNUSED_PARAMETER(x) (void)(x) | |
| 837 | |
| 838 /* | |
| 839 ** Number of elements in an array | |
| 840 */ | |
| 841 #define ArraySize(X) (int)(sizeof(X)/sizeof(X[0])) | |
| 842 | |
| 843 /* | |
| 844 ** If the following flag is set, then command execution stops | |
| 845 ** at an error if we are not interactive. | |
| 846 */ | |
| 847 static int bail_on_error = 0; | |
| 848 | |
| 849 /* | |
| 850 ** Treat stdin as an interactive input if the following variable | |
| 851 ** is true. Otherwise, assume stdin is connected to a file or pipe. | |
| 852 */ | |
| 853 static int stdin_is_interactive = 1; | |
| 854 | |
| 855 /* | |
| 856 ** On Windows systems we need to know if standard output is a console | |
| 857 ** in order to show that UTF-16 translation is done in the sign-on | |
| 858 ** banner. The following variable is true if it is the console. | |
| 859 */ | |
| 860 static int stdout_is_console = 1; | |
| 861 | |
| 862 /* | |
| 863 ** The following is the open SQLite database. We make a pointer | |
| 864 ** to this database a static variable so that it can be accessed | |
| 865 ** by the SIGINT handler to interrupt database processing. | |
| 866 */ | |
| 867 static sqlite3 *globalDb = 0; | |
| 868 | |
| 869 /* | |
| 870 ** True if an interrupt (Control-C) has been received. | |
| 871 */ | |
| 872 static volatile int seenInterrupt = 0; | |
| 873 | |
| 874 /* | |
| 875 ** This is the name of our program. It is set in main(), used | |
| 876 ** in a number of other places, mostly for error messages. | |
| 877 */ | |
| 878 static char *Argv0; | |
| 879 | |
| 880 /* | |
| 881 ** Prompt strings. Initialized in main. Settable with | |
| 882 ** .prompt main continue | |
| 883 */ | |
| 884 #define PROMPT_LEN_MAX 128 | |
| 885 /* First line prompt. default: "sqlite> " */ | |
| 886 static char mainPrompt[PROMPT_LEN_MAX]; | |
| 887 /* Continuation prompt. default: " ...> " */ | |
| 888 static char continuePrompt[PROMPT_LEN_MAX]; | |
| 889 | |
| 890 /* This is variant of the standard-library strncpy() routine with the | |
| 891 ** one change that the destination string is always zero-terminated, even | |
| 892 ** if there is no zero-terminator in the first n-1 characters of the source | |
| 893 ** string. | |
| 894 */ | |
| 895 static char *shell_strncpy(char *dest, const char *src, size_t n){ | |
| 896 size_t i; | |
| 897 for(i=0; i<n-1 && src[i]!=0; i++) dest[i] = src[i]; | |
| 898 dest[i] = 0; | |
| 899 return dest; | |
| 900 } | |
| 901 | |
| 902 /* | |
| 903 ** strcpy() workalike to squelch an unwarranted link-time warning | |
| 904 ** from OpenBSD. | |
| 905 */ | |
| 906 static void shell_strcpy(char *dest, const char *src){ | |
| 907 while( (*(dest++) = *(src++))!=0 ){} | |
| 908 } | |
| 909 | |
| 910 /* | |
| 911 ** Optionally disable dynamic continuation prompt. | |
| 912 ** Unless disabled, the continuation prompt shows open SQL lexemes if any, | |
| 913 ** or open parentheses level if non-zero, or continuation prompt as set. | |
| 914 ** This facility interacts with the scanner and process_input() where the | |
| 915 ** below 5 macros are used. | |
| 916 */ | |
| 917 #ifdef SQLITE_OMIT_DYNAPROMPT | |
| 918 # define CONTINUATION_PROMPT continuePrompt | |
| 919 # define CONTINUE_PROMPT_RESET | |
| 920 # define CONTINUE_PROMPT_AWAITS(p,s) | |
| 921 # define CONTINUE_PROMPT_AWAITC(p,c) | |
| 922 # define CONTINUE_PAREN_INCR(p,n) | |
| 923 # define CONTINUE_PROMPT_PSTATE 0 | |
| 924 typedef void *t_NoDynaPrompt; | |
| 925 # define SCAN_TRACKER_REFTYPE t_NoDynaPrompt | |
| 926 #else | |
| 927 # define CONTINUATION_PROMPT dynamicContinuePrompt() | |
| 928 # define CONTINUE_PROMPT_RESET \ | |
| 929 do {setLexemeOpen(&dynPrompt,0,0); trackParenLevel(&dynPrompt,0);} while(0) | |
| 930 # define CONTINUE_PROMPT_AWAITS(p,s) \ | |
| 931 if(p && stdin_is_interactive) setLexemeOpen(p, s, 0) | |
| 932 # define CONTINUE_PROMPT_AWAITC(p,c) \ | |
| 933 if(p && stdin_is_interactive) setLexemeOpen(p, 0, c) | |
| 934 # define CONTINUE_PAREN_INCR(p,n) \ | |
| 935 if(p && stdin_is_interactive) (trackParenLevel(p,n)) | |
| 936 # define CONTINUE_PROMPT_PSTATE (&dynPrompt) | |
| 937 typedef struct DynaPrompt *t_DynaPromptRef; | |
| 938 # define SCAN_TRACKER_REFTYPE t_DynaPromptRef | |
| 939 | |
| 940 static struct DynaPrompt { | |
| 941 char dynamicPrompt[PROMPT_LEN_MAX]; | |
| 942 char acAwait[2]; | |
| 943 int inParenLevel; | |
| 944 char *zScannerAwaits; | |
| 945 } dynPrompt = { {0}, {0}, 0, 0 }; | |
| 946 | |
| 947 /* Record parenthesis nesting level change, or force level to 0. */ | |
| 948 static void trackParenLevel(struct DynaPrompt *p, int ni){ | |
| 949 p->inParenLevel += ni; | |
| 950 if( ni==0 ) p->inParenLevel = 0; | |
| 951 p->zScannerAwaits = 0; | |
| 952 } | |
| 953 | |
| 954 /* Record that a lexeme is opened, or closed with args==0. */ | |
| 955 static void setLexemeOpen(struct DynaPrompt *p, char *s, char c){ | |
| 956 if( s!=0 || c==0 ){ | |
| 957 p->zScannerAwaits = s; | |
| 958 p->acAwait[0] = 0; | |
| 959 }else{ | |
| 960 p->acAwait[0] = c; | |
| 961 p->zScannerAwaits = p->acAwait; | |
| 962 } | |
| 963 } | |
| 964 | |
| 965 /* Upon demand, derive the continuation prompt to display. */ | |
| 966 static char *dynamicContinuePrompt(void){ | |
| 967 if( continuePrompt[0]==0 | |
| 968 || (dynPrompt.zScannerAwaits==0 && dynPrompt.inParenLevel == 0) ){ | |
| 969 return continuePrompt; | |
| 970 }else{ | |
| 971 if( dynPrompt.zScannerAwaits ){ | |
| 972 size_t ncp = strlen(continuePrompt); | |
| 973 size_t ndp = strlen(dynPrompt.zScannerAwaits); | |
| 974 if( ndp > ncp-3 ) return continuePrompt; | |
| 975 shell_strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits); | |
| 976 while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' '; | |
| 977 shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3, | |
| 978 PROMPT_LEN_MAX-4); | |
| 979 }else{ | |
| 980 if( dynPrompt.inParenLevel>9 ){ | |
| 981 shell_strncpy(dynPrompt.dynamicPrompt, "(..", 4); | |
| 982 }else if( dynPrompt.inParenLevel<0 ){ | |
| 983 shell_strncpy(dynPrompt.dynamicPrompt, ")x!", 4); | |
| 984 }else{ | |
| 985 shell_strncpy(dynPrompt.dynamicPrompt, "(x.", 4); | |
| 986 dynPrompt.dynamicPrompt[2] = (char)('0'+dynPrompt.inParenLevel); | |
| 987 } | |
| 988 shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3, | |
| 989 PROMPT_LEN_MAX-4); | |
| 990 } | |
| 991 } | |
| 992 return dynPrompt.dynamicPrompt; | |
| 993 } | |
| 994 #endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */ | |
| 995 | |
| 996 /* Indicate out-of-memory and exit. */ | |
| 997 static void shell_out_of_memory(void){ | |
| 998 eputz("Error: out of memory\n"); | |
| 999 exit(1); | |
| 1000 } | |
| 1001 | |
| 1002 /* Check a pointer to see if it is NULL. If it is NULL, exit with an | |
| 1003 ** out-of-memory error. | |
| 1004 */ | |
| 1005 static void shell_check_oom(const void *p){ | |
| 1006 if( p==0 ) shell_out_of_memory(); | |
| 1007 } | |
| 1008 | |
| 1009 /* | |
| 1010 ** Write I/O traces to the following stream. | |
| 1011 */ | |
| 1012 #ifdef SQLITE_ENABLE_IOTRACE | |
| 1013 static FILE *iotrace = 0; | |
| 1014 #endif | |
| 1015 | |
| 1016 /* | |
| 1017 ** This routine works like printf in that its first argument is a | |
| 1018 ** format string and subsequent arguments are values to be substituted | |
| 1019 ** in place of % fields. The result of formatting this string | |
| 1020 ** is written to iotrace. | |
| 1021 */ | |
| 1022 #ifdef SQLITE_ENABLE_IOTRACE | |
| 1023 static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ | |
| 1024 va_list ap; | |
| 1025 char *z; | |
| 1026 if( iotrace==0 ) return; | |
| 1027 va_start(ap, zFormat); | |
| 1028 z = sqlite3_vmprintf(zFormat, ap); | |
| 1029 va_end(ap); | |
| 1030 sqlite3_fprintf(iotrace, "%s", z); | |
| 1031 sqlite3_free(z); | |
| 1032 } | |
| 1033 #endif | |
| 1034 | |
| 1035 /* Lookup table to estimate the number of columns consumed by a Unicode | |
| 1036 ** character. | |
| 1037 */ | |
| 1038 static const struct { | |
| 1039 unsigned char w; /* Width of the character in columns */ | |
| 1040 int iFirst; /* First character in a span having this width */ | |
| 1041 } aUWidth[] = { | |
| 1042 /* {1, 0x00000}, */ | |
| 1043 {0, 0x00300}, {1, 0x00370}, {0, 0x00483}, {1, 0x00487}, {0, 0x00488}, | |
| 1044 {1, 0x0048a}, {0, 0x00591}, {1, 0x005be}, {0, 0x005bf}, {1, 0x005c0}, | |
| 1045 {0, 0x005c1}, {1, 0x005c3}, {0, 0x005c4}, {1, 0x005c6}, {0, 0x005c7}, | |
| 1046 {1, 0x005c8}, {0, 0x00600}, {1, 0x00604}, {0, 0x00610}, {1, 0x00616}, | |
| 1047 {0, 0x0064b}, {1, 0x0065f}, {0, 0x00670}, {1, 0x00671}, {0, 0x006d6}, | |
| 1048 {1, 0x006e5}, {0, 0x006e7}, {1, 0x006e9}, {0, 0x006ea}, {1, 0x006ee}, | |
| 1049 {0, 0x0070f}, {1, 0x00710}, {0, 0x00711}, {1, 0x00712}, {0, 0x00730}, | |
| 1050 {1, 0x0074b}, {0, 0x007a6}, {1, 0x007b1}, {0, 0x007eb}, {1, 0x007f4}, | |
| 1051 {0, 0x00901}, {1, 0x00903}, {0, 0x0093c}, {1, 0x0093d}, {0, 0x00941}, | |
| 1052 {1, 0x00949}, {0, 0x0094d}, {1, 0x0094e}, {0, 0x00951}, {1, 0x00955}, | |
| 1053 {0, 0x00962}, {1, 0x00964}, {0, 0x00981}, {1, 0x00982}, {0, 0x009bc}, | |
| 1054 {1, 0x009bd}, {0, 0x009c1}, {1, 0x009c5}, {0, 0x009cd}, {1, 0x009ce}, | |
| 1055 {0, 0x009e2}, {1, 0x009e4}, {0, 0x00a01}, {1, 0x00a03}, {0, 0x00a3c}, | |
| 1056 {1, 0x00a3d}, {0, 0x00a41}, {1, 0x00a43}, {0, 0x00a47}, {1, 0x00a49}, | |
| 1057 {0, 0x00a4b}, {1, 0x00a4e}, {0, 0x00a70}, {1, 0x00a72}, {0, 0x00a81}, | |
| 1058 {1, 0x00a83}, {0, 0x00abc}, {1, 0x00abd}, {0, 0x00ac1}, {1, 0x00ac6}, | |
| 1059 {0, 0x00ac7}, {1, 0x00ac9}, {0, 0x00acd}, {1, 0x00ace}, {0, 0x00ae2}, | |
| 1060 {1, 0x00ae4}, {0, 0x00b01}, {1, 0x00b02}, {0, 0x00b3c}, {1, 0x00b3d}, | |
| 1061 {0, 0x00b3f}, {1, 0x00b40}, {0, 0x00b41}, {1, 0x00b44}, {0, 0x00b4d}, | |
| 1062 {1, 0x00b4e}, {0, 0x00b56}, {1, 0x00b57}, {0, 0x00b82}, {1, 0x00b83}, | |
| 1063 {0, 0x00bc0}, {1, 0x00bc1}, {0, 0x00bcd}, {1, 0x00bce}, {0, 0x00c3e}, | |
| 1064 {1, 0x00c41}, {0, 0x00c46}, {1, 0x00c49}, {0, 0x00c4a}, {1, 0x00c4e}, | |
| 1065 {0, 0x00c55}, {1, 0x00c57}, {0, 0x00cbc}, {1, 0x00cbd}, {0, 0x00cbf}, | |
| 1066 {1, 0x00cc0}, {0, 0x00cc6}, {1, 0x00cc7}, {0, 0x00ccc}, {1, 0x00cce}, | |
| 1067 {0, 0x00ce2}, {1, 0x00ce4}, {0, 0x00d41}, {1, 0x00d44}, {0, 0x00d4d}, | |
| 1068 {1, 0x00d4e}, {0, 0x00dca}, {1, 0x00dcb}, {0, 0x00dd2}, {1, 0x00dd5}, | |
| 1069 {0, 0x00dd6}, {1, 0x00dd7}, {0, 0x00e31}, {1, 0x00e32}, {0, 0x00e34}, | |
| 1070 {1, 0x00e3b}, {0, 0x00e47}, {1, 0x00e4f}, {0, 0x00eb1}, {1, 0x00eb2}, | |
| 1071 {0, 0x00eb4}, {1, 0x00eba}, {0, 0x00ebb}, {1, 0x00ebd}, {0, 0x00ec8}, | |
| 1072 {1, 0x00ece}, {0, 0x00f18}, {1, 0x00f1a}, {0, 0x00f35}, {1, 0x00f36}, | |
| 1073 {0, 0x00f37}, {1, 0x00f38}, {0, 0x00f39}, {1, 0x00f3a}, {0, 0x00f71}, | |
| 1074 {1, 0x00f7f}, {0, 0x00f80}, {1, 0x00f85}, {0, 0x00f86}, {1, 0x00f88}, | |
| 1075 {0, 0x00f90}, {1, 0x00f98}, {0, 0x00f99}, {1, 0x00fbd}, {0, 0x00fc6}, | |
| 1076 {1, 0x00fc7}, {0, 0x0102d}, {1, 0x01031}, {0, 0x01032}, {1, 0x01033}, | |
| 1077 {0, 0x01036}, {1, 0x01038}, {0, 0x01039}, {1, 0x0103a}, {0, 0x01058}, | |
| 1078 {1, 0x0105a}, {2, 0x01100}, {0, 0x01160}, {1, 0x01200}, {0, 0x0135f}, | |
| 1079 {1, 0x01360}, {0, 0x01712}, {1, 0x01715}, {0, 0x01732}, {1, 0x01735}, | |
| 1080 {0, 0x01752}, {1, 0x01754}, {0, 0x01772}, {1, 0x01774}, {0, 0x017b4}, | |
| 1081 {1, 0x017b6}, {0, 0x017b7}, {1, 0x017be}, {0, 0x017c6}, {1, 0x017c7}, | |
| 1082 {0, 0x017c9}, {1, 0x017d4}, {0, 0x017dd}, {1, 0x017de}, {0, 0x0180b}, | |
| 1083 {1, 0x0180e}, {0, 0x018a9}, {1, 0x018aa}, {0, 0x01920}, {1, 0x01923}, | |
| 1084 {0, 0x01927}, {1, 0x01929}, {0, 0x01932}, {1, 0x01933}, {0, 0x01939}, | |
| 1085 {1, 0x0193c}, {0, 0x01a17}, {1, 0x01a19}, {0, 0x01b00}, {1, 0x01b04}, | |
| 1086 {0, 0x01b34}, {1, 0x01b35}, {0, 0x01b36}, {1, 0x01b3b}, {0, 0x01b3c}, | |
| 1087 {1, 0x01b3d}, {0, 0x01b42}, {1, 0x01b43}, {0, 0x01b6b}, {1, 0x01b74}, | |
| 1088 {0, 0x01dc0}, {1, 0x01dcb}, {0, 0x01dfe}, {1, 0x01e00}, {0, 0x0200b}, | |
| 1089 {1, 0x02010}, {0, 0x0202a}, {1, 0x0202f}, {0, 0x02060}, {1, 0x02064}, | |
| 1090 {0, 0x0206a}, {1, 0x02070}, {0, 0x020d0}, {1, 0x020f0}, {2, 0x02329}, | |
| 1091 {1, 0x0232b}, {2, 0x02e80}, {0, 0x0302a}, {2, 0x03030}, {1, 0x0303f}, | |
| 1092 {2, 0x03040}, {0, 0x03099}, {2, 0x0309b}, {1, 0x0a4d0}, {0, 0x0a806}, | |
| 1093 {1, 0x0a807}, {0, 0x0a80b}, {1, 0x0a80c}, {0, 0x0a825}, {1, 0x0a827}, | |
| 1094 {2, 0x0ac00}, {1, 0x0d7a4}, {2, 0x0f900}, {1, 0x0fb00}, {0, 0x0fb1e}, | |
| 1095 {1, 0x0fb1f}, {0, 0x0fe00}, {2, 0x0fe10}, {1, 0x0fe1a}, {0, 0x0fe20}, | |
| 1096 {1, 0x0fe24}, {2, 0x0fe30}, {1, 0x0fe70}, {0, 0x0feff}, {2, 0x0ff00}, | |
| 1097 {1, 0x0ff61}, {2, 0x0ffe0}, {1, 0x0ffe7}, {0, 0x0fff9}, {1, 0x0fffc}, | |
| 1098 {0, 0x10a01}, {1, 0x10a04}, {0, 0x10a05}, {1, 0x10a07}, {0, 0x10a0c}, | |
| 1099 {1, 0x10a10}, {0, 0x10a38}, {1, 0x10a3b}, {0, 0x10a3f}, {1, 0x10a40}, | |
| 1100 {0, 0x1d167}, {1, 0x1d16a}, {0, 0x1d173}, {1, 0x1d183}, {0, 0x1d185}, | |
| 1101 {1, 0x1d18c}, {0, 0x1d1aa}, {1, 0x1d1ae}, {0, 0x1d242}, {1, 0x1d245}, | |
| 1102 {2, 0x20000}, {1, 0x2fffe}, {2, 0x30000}, {1, 0x3fffe}, {0, 0xe0001}, | |
| 1103 {1, 0xe0002}, {0, 0xe0020}, {1, 0xe0080}, {0, 0xe0100}, {1, 0xe01f0} | |
| 1104 }; | |
| 1105 | |
| 1106 /* | |
| 1107 ** Return an estimate of the width, in columns, for the single Unicode | |
| 1108 ** character c. For normal characters, the answer is always 1. But the | |
| 1109 ** estimate might be 0 or 2 for zero-width and double-width characters. | |
| 1110 ** | |
| 1111 ** Different display devices display unicode using different widths. So | |
| 1112 ** it is impossible to know that true display width with 100% accuracy. | |
| 1113 ** Inaccuracies in the width estimates might cause columns to be misaligned. | |
| 1114 ** Unfortunately, there is nothing we can do about that. | |
| 1115 */ | |
| 1116 int cli_wcwidth(int c){ | |
| 1117 int iFirst, iLast; | |
| 1118 | |
| 1119 /* Fast path for common characters */ | |
| 1120 if( c<=0x300 ) return 1; | |
| 1121 | |
| 1122 /* The general case */ | |
| 1123 iFirst = 0; | |
| 1124 iLast = sizeof(aUWidth)/sizeof(aUWidth[0]) - 1; | |
| 1125 while( iFirst<iLast-1 ){ | |
| 1126 int iMid = (iFirst+iLast)/2; | |
| 1127 int cMid = aUWidth[iMid].iFirst; | |
| 1128 if( cMid < c ){ | |
| 1129 iFirst = iMid; | |
| 1130 }else if( cMid > c ){ | |
| 1131 iLast = iMid - 1; | |
| 1132 }else{ | |
| 1133 return aUWidth[iMid].w; | |
| 1134 } | |
| 1135 } | |
| 1136 if( aUWidth[iLast].iFirst > c ) return aUWidth[iFirst].w; | |
| 1137 return aUWidth[iLast].w; | |
| 1138 } | |
| 1139 | |
| 1140 /* | |
| 1141 ** Compute the value and length of a multi-byte UTF-8 character that | |
| 1142 ** begins at z[0]. Return the length. Write the Unicode value into *pU. | |
| 1143 ** | |
| 1144 ** This routine only works for *multi-byte* UTF-8 characters. | |
| 1145 */ | |
| 1146 static int decodeUtf8(const unsigned char *z, int *pU){ | |
| 1147 if( (z[0] & 0xe0)==0xc0 && (z[1] & 0xc0)==0x80 ){ | |
| 1148 *pU = ((z[0] & 0x1f)<<6) | (z[1] & 0x3f); | |
| 1149 return 2; | |
| 1150 } | |
| 1151 if( (z[0] & 0xf0)==0xe0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 ){ | |
| 1152 *pU = ((z[0] & 0x0f)<<12) | ((z[1] & 0x3f)<<6) | (z[2] & 0x3f); | |
| 1153 return 3; | |
| 1154 } | |
| 1155 if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 | |
| 1156 && (z[3] & 0xc0)==0x80 | |
| 1157 ){ | |
| 1158 *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6 | |
| 1159 | (z[3] & 0x3f); | |
| 1160 return 4; | |
| 1161 } | |
| 1162 *pU = 0; | |
| 1163 return 1; | |
| 1164 } | |
| 1165 | |
| 1166 | |
| 1167 #if 0 /* NOT USED */ | |
| 1168 /* | |
| 1169 ** Return the width, in display columns, of a UTF-8 string. | |
| 1170 ** | |
| 1171 ** Each normal character counts as 1. Zero-width characters count | |
| 1172 ** as zero, and double-width characters count as 2. | |
| 1173 */ | |
| 1174 int cli_wcswidth(const char *z){ | |
| 1175 const unsigned char *a = (const unsigned char*)z; | |
| 1176 int n = 0; | |
| 1177 int i = 0; | |
| 1178 unsigned char c; | |
| 1179 while( (c = a[i])!=0 ){ | |
| 1180 if( c>=0xc0 ){ | |
| 1181 int u; | |
| 1182 int len = decodeUtf8(&a[i], &u); | |
| 1183 i += len; | |
| 1184 n += cli_wcwidth(u); | |
| 1185 }else if( c>=' ' ){ | |
| 1186 n++; | |
| 1187 i++; | |
| 1188 }else{ | |
| 1189 i++; | |
| 1190 } | |
| 1191 } | |
| 1192 return n; | |
| 1193 } | |
| 1194 #endif | |
| 1195 | |
| 1196 /* | |
| 1197 ** Check to see if z[] is a valid VT100 escape. If it is, then | |
| 1198 ** return the number of bytes in the escape sequence. Return 0 if | |
| 1199 ** z[] is not a VT100 escape. | |
| 1200 ** | |
| 1201 ** This routine assumes that z[0] is \033 (ESC). | |
| 1202 */ | |
| 1203 static int isVt100(const unsigned char *z){ | |
| 1204 int i; | |
| 1205 if( z[1]!='[' ) return 0; | |
| 1206 i = 2; | |
| 1207 while( z[i]>=0x30 && z[i]<=0x3f ){ i++; } | |
| 1208 while( z[i]>=0x20 && z[i]<=0x2f ){ i++; } | |
| 1209 if( z[i]<0x40 || z[i]>0x7e ) return 0; | |
| 1210 return i+1; | |
| 1211 } | |
| 1212 | |
| 1213 /* | |
| 1214 ** Output string zUtf to stdout as w characters. If w is negative, | |
| 1215 ** then right-justify the text. W is the width in UTF-8 characters, not | |
| 1216 ** in bytes. This is different from the %*.*s specification in printf | |
| 1217 ** since with %*.*s the width is measured in bytes, not characters. | |
| 1218 ** | |
| 1219 ** Take into account zero-width and double-width Unicode characters. | |
| 1220 ** In other words, a zero-width character does not count toward the | |
| 1221 ** the w limit. A double-width character counts as two. | |
| 1222 ** | |
| 1223 ** w should normally be a small number. A couple hundred at most. This | |
| 1224 ** routine caps w at 100 million to avoid integer overflow issues. | |
| 1225 */ | |
| 1226 static void utf8_width_print(FILE *out, int w, const char *zUtf){ | |
| 1227 const unsigned char *a = (const unsigned char*)zUtf; | |
| 1228 static const int mxW = 10000000; | |
| 1229 unsigned char c; | |
| 1230 int i = 0; | |
| 1231 int n = 0; | |
| 1232 int k; | |
| 1233 int aw; | |
| 1234 if( w<-mxW ){ | |
| 1235 w = -mxW; | |
| 1236 }else if( w>mxW ){ | |
| 1237 w= mxW; | |
| 1238 } | |
| 1239 aw = w<0 ? -w : w; | |
| 1240 if( zUtf==0 ) zUtf = ""; | |
| 1241 while( (c = a[i])!=0 ){ | |
| 1242 if( (c&0xc0)==0xc0 ){ | |
| 1243 int u; | |
| 1244 int len = decodeUtf8(a+i, &u); | |
| 1245 int x = cli_wcwidth(u); | |
| 1246 if( x+n>aw ){ | |
| 1247 break; | |
| 1248 } | |
| 1249 i += len; | |
| 1250 n += x; | |
| 1251 }else if( c==0x1b && (k = isVt100(&a[i]))>0 ){ | |
| 1252 i += k; | |
| 1253 }else if( n>=aw ){ | |
| 1254 break; | |
| 1255 }else{ | |
| 1256 n++; | |
| 1257 i++; | |
| 1258 } | |
| 1259 } | |
| 1260 if( n>=aw ){ | |
| 1261 sqlite3_fprintf(out, "%.*s", i, zUtf); | |
| 1262 }else if( w<0 ){ | |
| 1263 sqlite3_fprintf(out, "%*s%s", aw-n, "", zUtf); | |
| 1264 }else{ | |
| 1265 sqlite3_fprintf(out, "%s%*s", zUtf, aw-n, ""); | |
| 1266 } | |
| 1267 } | |
| 1268 | |
| 1269 | |
| 1270 /* | |
| 1271 ** Determines if a string is a number of not. | |
| 1272 */ | |
| 1273 static int isNumber(const char *z, int *realnum){ | |
| 1274 if( *z=='-' || *z=='+' ) z++; | |
| 1275 if( !IsDigit(*z) ){ | |
| 1276 return 0; | |
| 1277 } | |
| 1278 z++; | |
| 1279 if( realnum ) *realnum = 0; | |
| 1280 while( IsDigit(*z) ){ z++; } | |
| 1281 if( *z=='.' ){ | |
| 1282 z++; | |
| 1283 if( !IsDigit(*z) ) return 0; | |
| 1284 while( IsDigit(*z) ){ z++; } | |
| 1285 if( realnum ) *realnum = 1; | |
| 1286 } | |
| 1287 if( *z=='e' || *z=='E' ){ | |
| 1288 z++; | |
| 1289 if( *z=='+' || *z=='-' ) z++; | |
| 1290 if( !IsDigit(*z) ) return 0; | |
| 1291 while( IsDigit(*z) ){ z++; } | |
| 1292 if( realnum ) *realnum = 1; | |
| 1293 } | |
| 1294 return *z==0; | |
| 1295 } | |
| 1296 | |
| 1297 /* | |
| 1298 ** Compute a string length that is limited to what can be stored in | |
| 1299 ** lower 30 bits of a 32-bit signed integer. | |
| 1300 */ | |
| 1301 static int strlen30(const char *z){ | |
| 1302 const char *z2 = z; | |
| 1303 while( *z2 ){ z2++; } | |
| 1304 return 0x3fffffff & (int)(z2 - z); | |
| 1305 } | |
| 1306 | |
| 1307 /* | |
| 1308 ** Return the length of a string in characters. Multibyte UTF8 characters | |
| 1309 ** count as a single character for single-width characters, or as two | |
| 1310 ** characters for double-width characters. | |
| 1311 */ | |
| 1312 static int strlenChar(const char *z){ | |
| 1313 int n = 0; | |
| 1314 while( *z ){ | |
| 1315 if( (0x80&z[0])==0 ){ | |
| 1316 n++; | |
| 1317 z++; | |
| 1318 }else{ | |
| 1319 int u = 0; | |
| 1320 int len = decodeUtf8((const u8*)z, &u); | |
| 1321 z += len; | |
| 1322 n += cli_wcwidth(u); | |
| 1323 } | |
| 1324 } | |
| 1325 return n; | |
| 1326 } | |
| 1327 | |
| 1328 /* | |
| 1329 ** Return open FILE * if zFile exists, can be opened for read | |
| 1330 ** and is an ordinary file or a character stream source. | |
| 1331 ** Otherwise return 0. | |
| 1332 */ | |
| 1333 static FILE * openChrSource(const char *zFile){ | |
| 1334 #if defined(_WIN32) || defined(WIN32) | |
| 1335 struct __stat64 x = {0}; | |
| 1336 # define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0) | |
| 1337 /* On Windows, open first, then check the stream nature. This order | |
| 1338 ** is necessary because _stat() and sibs, when checking a named pipe, | |
| 1339 ** effectively break the pipe as its supplier sees it. */ | |
| 1340 FILE *rv = sqlite3_fopen(zFile, "rb"); | |
| 1341 if( rv==0 ) return 0; | |
| 1342 if( _fstat64(_fileno(rv), &x) != 0 | |
| 1343 || !STAT_CHR_SRC(x.st_mode)){ | |
| 1344 fclose(rv); | |
| 1345 rv = 0; | |
| 1346 } | |
| 1347 return rv; | |
| 1348 #else | |
| 1349 struct stat x = {0}; | |
| 1350 int rc = stat(zFile, &x); | |
| 1351 # define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode)) | |
| 1352 if( rc!=0 ) return 0; | |
| 1353 if( STAT_CHR_SRC(x.st_mode) ){ | |
| 1354 return sqlite3_fopen(zFile, "rb"); | |
| 1355 }else{ | |
| 1356 return 0; | |
| 1357 } | |
| 1358 #endif | |
| 1359 #undef STAT_CHR_SRC | |
| 1360 } | |
| 1361 | |
| 1362 /* | |
| 1363 ** This routine reads a line of text from FILE in, stores | |
| 1364 ** the text in memory obtained from malloc() and returns a pointer | |
| 1365 ** to the text. NULL is returned at end of file, or if malloc() | |
| 1366 ** fails, or if the length of the line is longer than about a gigabyte. | |
| 1367 ** | |
| 1368 ** If zLine is not NULL then it is a malloced buffer returned from | |
| 1369 ** a previous call to this routine that may be reused. | |
| 1370 */ | |
| 1371 static char *local_getline(char *zLine, FILE *in){ | |
| 1372 int nLine = zLine==0 ? 0 : 100; | |
| 1373 int n = 0; | |
| 1374 | |
| 1375 while( 1 ){ | |
| 1376 if( n+100>nLine ){ | |
| 1377 if( nLine>=1073741773 ){ | |
| 1378 free(zLine); | |
| 1379 return 0; | |
| 1380 } | |
| 1381 nLine = nLine*2 + 100; | |
| 1382 zLine = realloc(zLine, nLine); | |
| 1383 shell_check_oom(zLine); | |
| 1384 } | |
| 1385 if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){ | |
| 1386 if( n==0 ){ | |
| 1387 free(zLine); | |
| 1388 return 0; | |
| 1389 } | |
| 1390 zLine[n] = 0; | |
| 1391 break; | |
| 1392 } | |
| 1393 while( zLine[n] ) n++; | |
| 1394 if( n>0 && zLine[n-1]=='\n' ){ | |
| 1395 n--; | |
| 1396 if( n>0 && zLine[n-1]=='\r' ) n--; | |
| 1397 zLine[n] = 0; | |
| 1398 break; | |
| 1399 } | |
| 1400 } | |
| 1401 return zLine; | |
| 1402 } | |
| 1403 | |
| 1404 /* | |
| 1405 ** Retrieve a single line of input text. | |
| 1406 ** | |
| 1407 ** If in==0 then read from standard input and prompt before each line. | |
| 1408 ** If isContinuation is true, then a continuation prompt is appropriate. | |
| 1409 ** If isContinuation is zero, then the main prompt should be used. | |
| 1410 ** | |
| 1411 ** If zPrior is not NULL then it is a buffer from a prior call to this | |
| 1412 ** routine that can be reused. | |
| 1413 ** | |
| 1414 ** The result is stored in space obtained from malloc() and must either | |
| 1415 ** be freed by the caller or else passed back into this routine via the | |
| 1416 ** zPrior argument for reuse. | |
| 1417 */ | |
| 1418 #ifndef SQLITE_SHELL_FIDDLE | |
| 1419 static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ | |
| 1420 char *zPrompt; | |
| 1421 char *zResult; | |
| 1422 if( in!=0 ){ | |
| 1423 zResult = local_getline(zPrior, in); | |
| 1424 }else{ | |
| 1425 zPrompt = isContinuation ? CONTINUATION_PROMPT : mainPrompt; | |
| 1426 #if SHELL_USE_LOCAL_GETLINE | |
| 1427 sputz(stdout, zPrompt); | |
| 1428 fflush(stdout); | |
| 1429 do{ | |
| 1430 zResult = local_getline(zPrior, stdin); | |
| 1431 zPrior = 0; | |
| 1432 /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */ | |
| 1433 if( zResult==0 ) sqlite3_sleep(50); | |
| 1434 }while( zResult==0 && seenInterrupt>0 ); | |
| 1435 #else | |
| 1436 free(zPrior); | |
| 1437 zResult = shell_readline(zPrompt); | |
| 1438 while( zResult==0 ){ | |
| 1439 /* ^C trap creates a false EOF, so let "interrupt" thread catch up. */ | |
| 1440 sqlite3_sleep(50); | |
| 1441 if( seenInterrupt==0 ) break; | |
| 1442 zResult = shell_readline(""); | |
| 1443 } | |
| 1444 if( zResult && *zResult ) shell_add_history(zResult); | |
| 1445 #endif | |
| 1446 } | |
| 1447 return zResult; | |
| 1448 } | |
| 1449 #endif /* !SQLITE_SHELL_FIDDLE */ | |
| 1450 | |
| 1451 /* | |
| 1452 ** Return the value of a hexadecimal digit. Return -1 if the input | |
| 1453 ** is not a hex digit. | |
| 1454 */ | |
| 1455 static int hexDigitValue(char c){ | |
| 1456 if( c>='0' && c<='9' ) return c - '0'; | |
| 1457 if( c>='a' && c<='f' ) return c - 'a' + 10; | |
| 1458 if( c>='A' && c<='F' ) return c - 'A' + 10; | |
| 1459 return -1; | |
| 1460 } | |
| 1461 | |
| 1462 /* | |
| 1463 ** Interpret zArg as an integer value, possibly with suffixes. | |
| 1464 ** | |
| 1465 ** If the value specified by zArg is outside the range of values that | |
| 1466 ** can be represented using a 64-bit twos-complement integer, then return | |
| 1467 ** the nearest representable value. | |
| 1468 */ | |
| 1469 static sqlite3_int64 integerValue(const char *zArg){ | |
| 1470 sqlite3_uint64 v = 0; | |
| 1471 static const struct { char *zSuffix; unsigned int iMult; } aMult[] = { | |
| 1472 { "KiB", 1024 }, | |
| 1473 { "MiB", 1024*1024 }, | |
| 1474 { "GiB", 1024*1024*1024 }, | |
| 1475 { "KB", 1000 }, | |
| 1476 { "MB", 1000000 }, | |
| 1477 { "GB", 1000000000 }, | |
| 1478 { "K", 1000 }, | |
| 1479 { "M", 1000000 }, | |
| 1480 { "G", 1000000000 }, | |
| 1481 }; | |
| 1482 int i; | |
| 1483 int isNeg = 0; | |
| 1484 if( zArg[0]=='-' ){ | |
| 1485 isNeg = 1; | |
| 1486 zArg++; | |
| 1487 }else if( zArg[0]=='+' ){ | |
| 1488 zArg++; | |
| 1489 } | |
| 1490 if( zArg[0]=='0' && zArg[1]=='x' ){ | |
| 1491 int x; | |
| 1492 zArg += 2; | |
| 1493 while( (x = hexDigitValue(zArg[0]))>=0 ){ | |
| 1494 if( v > 0x0fffffffffffffffULL ) goto integer_overflow; | |
| 1495 v = (v<<4) + x; | |
| 1496 zArg++; | |
| 1497 } | |
| 1498 }else{ | |
| 1499 while( IsDigit(zArg[0]) ){ | |
| 1500 if( v>=922337203685477580LL ){ | |
| 1501 if( v>922337203685477580LL || zArg[0]>='8' ) goto integer_overflow; | |
| 1502 } | |
| 1503 v = v*10 + (zArg[0] - '0'); | |
| 1504 zArg++; | |
| 1505 } | |
| 1506 } | |
| 1507 for(i=0; i<ArraySize(aMult); i++){ | |
| 1508 if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){ | |
| 1509 if( 0x7fffffffffffffffULL/aMult[i].iMult < v ) goto integer_overflow; | |
| 1510 v *= aMult[i].iMult; | |
| 1511 break; | |
| 1512 } | |
| 1513 } | |
| 1514 if( isNeg && v>0x7fffffffffffffffULL ) goto integer_overflow; | |
| 1515 return isNeg? -(sqlite3_int64)v : (sqlite3_int64)v; | |
| 1516 integer_overflow: | |
| 1517 return isNeg ? (i64)0x8000000000000000LL : 0x7fffffffffffffffLL; | |
| 1518 } | |
| 1519 | |
| 1520 /* | |
| 1521 ** A variable length string to which one can append text. | |
| 1522 */ | |
| 1523 typedef struct ShellText ShellText; | |
| 1524 struct ShellText { | |
| 1525 char *zTxt; /* The text */ | |
| 1526 i64 n; /* Number of bytes of zTxt[] actually used */ | |
| 1527 i64 nAlloc; /* Number of bytes allocated for zTxt[] */ | |
| 1528 }; | |
| 1529 | |
| 1530 /* | |
| 1531 ** Initialize and destroy a ShellText object | |
| 1532 */ | |
| 1533 static void initText(ShellText *p){ | |
| 1534 memset(p, 0, sizeof(*p)); | |
| 1535 } | |
| 1536 static void freeText(ShellText *p){ | |
| 1537 sqlite3_free(p->zTxt); | |
| 1538 initText(p); | |
| 1539 } | |
| 1540 | |
| 1541 /* zIn is either a pointer to a NULL-terminated string in memory obtained | |
| 1542 ** from malloc(), or a NULL pointer. The string pointed to by zAppend is | |
| 1543 ** added to zIn, and the result returned in memory obtained from malloc(). | |
| 1544 ** zIn, if it was not NULL, is freed. | |
| 1545 ** | |
| 1546 ** If the third argument, quote, is not '\0', then it is used as a | |
| 1547 ** quote character for zAppend. | |
| 1548 */ | |
| 1549 static void appendText(ShellText *p, const char *zAppend, char quote){ | |
| 1550 i64 len; | |
| 1551 i64 i; | |
| 1552 i64 nAppend = strlen30(zAppend); | |
| 1553 | |
| 1554 len = nAppend+p->n+1; | |
| 1555 if( quote ){ | |
| 1556 len += 2; | |
| 1557 for(i=0; i<nAppend; i++){ | |
| 1558 if( zAppend[i]==quote ) len++; | |
| 1559 } | |
| 1560 } | |
| 1561 | |
| 1562 if( p->zTxt==0 || p->n+len>=p->nAlloc ){ | |
| 1563 p->nAlloc = p->nAlloc*2 + len + 20; | |
| 1564 p->zTxt = sqlite3_realloc64(p->zTxt, p->nAlloc); | |
| 1565 shell_check_oom(p->zTxt); | |
| 1566 } | |
| 1567 | |
| 1568 if( quote ){ | |
| 1569 char *zCsr = p->zTxt+p->n; | |
| 1570 *zCsr++ = quote; | |
| 1571 for(i=0; i<nAppend; i++){ | |
| 1572 *zCsr++ = zAppend[i]; | |
| 1573 if( zAppend[i]==quote ) *zCsr++ = quote; | |
| 1574 } | |
| 1575 *zCsr++ = quote; | |
| 1576 p->n = (i64)(zCsr - p->zTxt); | |
| 1577 *zCsr = '\0'; | |
| 1578 }else{ | |
| 1579 memcpy(p->zTxt+p->n, zAppend, nAppend); | |
| 1580 p->n += nAppend; | |
| 1581 p->zTxt[p->n] = '\0'; | |
| 1582 } | |
| 1583 } | |
| 1584 | |
| 1585 /* | |
| 1586 ** Attempt to determine if identifier zName needs to be quoted, either | |
| 1587 ** because it contains non-alphanumeric characters, or because it is an | |
| 1588 ** SQLite keyword. Be conservative in this estimate: When in doubt assume | |
| 1589 ** that quoting is required. | |
| 1590 ** | |
| 1591 ** Return '"' if quoting is required. Return 0 if no quoting is required. | |
| 1592 */ | |
| 1593 static char quoteChar(const char *zName){ | |
| 1594 int i; | |
| 1595 if( zName==0 ) return '"'; | |
| 1596 if( !IsAlpha(zName[0]) && zName[0]!='_' ) return '"'; | |
| 1597 for(i=0; zName[i]; i++){ | |
| 1598 if( !IsAlnum(zName[i]) && zName[i]!='_' ) return '"'; | |
| 1599 } | |
| 1600 return sqlite3_keyword_check(zName, i) ? '"' : 0; | |
| 1601 } | |
| 1602 | |
| 1603 /* | |
| 1604 ** Construct a fake object name and column list to describe the structure | |
| 1605 ** of the view, virtual table, or table valued function zSchema.zName. | |
| 1606 ** | |
| 1607 ** The returned string comes from sqlite3_mprintf() and should be freed | |
| 1608 ** by the caller using sqlite3_free(). | |
| 1609 */ | |
| 1610 static char *shellFakeSchema( | |
| 1611 sqlite3 *db, /* The database connection containing the vtab */ | |
| 1612 const char *zSchema, /* Schema of the database holding the vtab */ | |
| 1613 const char *zName /* The name of the virtual table */ | |
| 1614 ){ | |
| 1615 sqlite3_stmt *pStmt = 0; | |
| 1616 char *zSql; | |
| 1617 ShellText s; | |
| 1618 char cQuote; | |
| 1619 char *zDiv = "("; | |
| 1620 int nRow = 0; | |
| 1621 | |
| 1622 zSql = sqlite3_mprintf("PRAGMA \"%w\".table_info=%Q;", | |
| 1623 zSchema ? zSchema : "main", zName); | |
| 1624 shell_check_oom(zSql); | |
| 1625 sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); | |
| 1626 sqlite3_free(zSql); | |
| 1627 initText(&s); | |
| 1628 if( zSchema ){ | |
| 1629 cQuote = quoteChar(zSchema); | |
| 1630 if( cQuote && sqlite3_stricmp(zSchema,"temp")==0 ) cQuote = 0; | |
| 1631 appendText(&s, zSchema, cQuote); | |
| 1632 appendText(&s, ".", 0); | |
| 1633 } | |
| 1634 cQuote = quoteChar(zName); | |
| 1635 appendText(&s, zName, cQuote); | |
| 1636 while( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 1637 const char *zCol = (const char*)sqlite3_column_text(pStmt, 1); | |
| 1638 nRow++; | |
| 1639 appendText(&s, zDiv, 0); | |
| 1640 zDiv = ","; | |
| 1641 if( zCol==0 ) zCol = ""; | |
| 1642 cQuote = quoteChar(zCol); | |
| 1643 appendText(&s, zCol, cQuote); | |
| 1644 } | |
| 1645 appendText(&s, ")", 0); | |
| 1646 sqlite3_finalize(pStmt); | |
| 1647 if( nRow==0 ){ | |
| 1648 freeText(&s); | |
| 1649 s.zTxt = 0; | |
| 1650 } | |
| 1651 return s.zTxt; | |
| 1652 } | |
| 1653 | |
| 1654 /* | |
| 1655 ** SQL function: strtod(X) | |
| 1656 ** | |
| 1657 ** Use the C-library strtod() function to convert string X into a double. | |
| 1658 ** Used for comparing the accuracy of SQLite's internal text-to-float conversion | |
| 1659 ** routines against the C-library. | |
| 1660 */ | |
| 1661 static void shellStrtod( | |
| 1662 sqlite3_context *pCtx, | |
| 1663 int nVal, | |
| 1664 sqlite3_value **apVal | |
| 1665 ){ | |
| 1666 char *z = (char*)sqlite3_value_text(apVal[0]); | |
| 1667 UNUSED_PARAMETER(nVal); | |
| 1668 if( z==0 ) return; | |
| 1669 sqlite3_result_double(pCtx, strtod(z,0)); | |
| 1670 } | |
| 1671 | |
| 1672 /* | |
| 1673 ** SQL function: dtostr(X) | |
| 1674 ** | |
| 1675 ** Use the C-library printf() function to convert real value X into a string. | |
| 1676 ** Used for comparing the accuracy of SQLite's internal float-to-text conversion | |
| 1677 ** routines against the C-library. | |
| 1678 */ | |
| 1679 static void shellDtostr( | |
| 1680 sqlite3_context *pCtx, | |
| 1681 int nVal, | |
| 1682 sqlite3_value **apVal | |
| 1683 ){ | |
| 1684 double r = sqlite3_value_double(apVal[0]); | |
| 1685 int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26; | |
| 1686 char z[400]; | |
| 1687 if( n<1 ) n = 1; | |
| 1688 if( n>350 ) n = 350; | |
| 1689 sqlite3_snprintf(sizeof(z), z, "%#+.*e", n, r); | |
| 1690 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); | |
| 1691 } | |
| 1692 | |
| 1693 /* | |
| 1694 ** SQL function: shell_add_schema(S,X) | |
| 1695 ** | |
| 1696 ** Add the schema name X to the CREATE statement in S and return the result. | |
| 1697 ** Examples: | |
| 1698 ** | |
| 1699 ** CREATE TABLE t1(x) -> CREATE TABLE xyz.t1(x); | |
| 1700 ** | |
| 1701 ** Also works on | |
| 1702 ** | |
| 1703 ** CREATE INDEX | |
| 1704 ** CREATE UNIQUE INDEX | |
| 1705 ** CREATE VIEW | |
| 1706 ** CREATE TRIGGER | |
| 1707 ** CREATE VIRTUAL TABLE | |
| 1708 ** | |
| 1709 ** This UDF is used by the .schema command to insert the schema name of | |
| 1710 ** attached databases into the middle of the sqlite_schema.sql field. | |
| 1711 */ | |
| 1712 static void shellAddSchemaName( | |
| 1713 sqlite3_context *pCtx, | |
| 1714 int nVal, | |
| 1715 sqlite3_value **apVal | |
| 1716 ){ | |
| 1717 static const char *aPrefix[] = { | |
| 1718 "TABLE", | |
| 1719 "INDEX", | |
| 1720 "UNIQUE INDEX", | |
| 1721 "VIEW", | |
| 1722 "TRIGGER", | |
| 1723 "VIRTUAL TABLE" | |
| 1724 }; | |
| 1725 int i = 0; | |
| 1726 const char *zIn = (const char*)sqlite3_value_text(apVal[0]); | |
| 1727 const char *zSchema = (const char*)sqlite3_value_text(apVal[1]); | |
| 1728 const char *zName = (const char*)sqlite3_value_text(apVal[2]); | |
| 1729 sqlite3 *db = sqlite3_context_db_handle(pCtx); | |
| 1730 UNUSED_PARAMETER(nVal); | |
| 1731 if( zIn!=0 && cli_strncmp(zIn, "CREATE ", 7)==0 ){ | |
| 1732 for(i=0; i<ArraySize(aPrefix); i++){ | |
| 1733 int n = strlen30(aPrefix[i]); | |
| 1734 if( cli_strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){ | |
| 1735 char *z = 0; | |
| 1736 char *zFake = 0; | |
| 1737 if( zSchema ){ | |
| 1738 char cQuote = quoteChar(zSchema); | |
| 1739 if( cQuote && sqlite3_stricmp(zSchema,"temp")!=0 ){ | |
| 1740 z = sqlite3_mprintf("%.*s \"%w\".%s", n+7, zIn, zSchema, zIn+n+8); | |
| 1741 }else{ | |
| 1742 z = sqlite3_mprintf("%.*s %s.%s", n+7, zIn, zSchema, zIn+n+8); | |
| 1743 } | |
| 1744 } | |
| 1745 if( zName | |
| 1746 && aPrefix[i][0]=='V' | |
| 1747 && (zFake = shellFakeSchema(db, zSchema, zName))!=0 | |
| 1748 ){ | |
| 1749 if( z==0 ){ | |
| 1750 z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake); | |
| 1751 }else{ | |
| 1752 z = sqlite3_mprintf("%z\n/* %s */", z, zFake); | |
| 1753 } | |
| 1754 sqlite3_free(zFake); | |
| 1755 } | |
| 1756 if( z ){ | |
| 1757 sqlite3_result_text(pCtx, z, -1, sqlite3_free); | |
| 1758 return; | |
| 1759 } | |
| 1760 } | |
| 1761 } | |
| 1762 } | |
| 1763 sqlite3_result_value(pCtx, apVal[0]); | |
| 1764 } | |
| 1765 | |
| 1766 /* | |
| 1767 ** The source code for several run-time loadable extensions is inserted | |
| 1768 ** below by the ../tool/mkshellc.tcl script. Before processing that included | |
| 1769 ** code, we need to override some macros to make the included program code | |
| 1770 ** work here in the middle of this regular program. | |
| 1771 */ | |
| 1772 #define SQLITE_EXTENSION_INIT1 | |
| 1773 #define SQLITE_EXTENSION_INIT2(X) (void)(X) | |
| 1774 | |
| 1775 /************************* Begin ../ext/misc/windirent.h ******************/ | |
| 1776 /* | |
| 1777 ** 2025-06-05 | |
| 1778 ** | |
| 1779 ** The author disclaims copyright to this source code. In place of | |
| 1780 ** a legal notice, here is a blessing: | |
| 1781 ** | |
| 1782 ** May you do good and not evil. | |
| 1783 ** May you find forgiveness for yourself and forgive others. | |
| 1784 ** May you share freely, never taking more than you give. | |
| 1785 ** | |
| 1786 ************************************************************************* | |
| 1787 ** | |
| 1788 ** An implementation of opendir(), readdir(), and closedir() for Windows, | |
| 1789 ** based on the FindFirstFile(), FindNextFile(), and FindClose() APIs | |
| 1790 ** of Win32. | |
| 1791 ** | |
| 1792 ** #include this file inside any C-code module that needs to use | |
| 1793 ** opendir()/readdir()/closedir(). This file is a no-op on non-Windows | |
| 1794 ** machines. On Windows, static functions are defined that implement | |
| 1795 ** those standard interfaces. | |
| 1796 */ | |
| 1797 #if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H) | |
| 1798 #define SQLITE_WINDIRENT_H | |
| 1799 | |
| 1800 #ifndef WIN32_LEAN_AND_MEAN | |
| 1801 #define WIN32_LEAN_AND_MEAN | |
| 1802 #endif | |
| 1803 #include <windows.h> | |
| 1804 #include <io.h> | |
| 1805 #include <stdio.h> | |
| 1806 #include <stdlib.h> | |
| 1807 #include <errno.h> | |
| 1808 #include <limits.h> | |
| 1809 #include <sys/types.h> | |
| 1810 #include <sys/stat.h> | |
| 1811 #include <string.h> | |
| 1812 #ifndef FILENAME_MAX | |
| 1813 # define FILENAME_MAX (260) | |
| 1814 #endif | |
| 1815 #ifndef S_ISREG | |
| 1816 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) | |
| 1817 #endif | |
| 1818 #ifndef S_ISDIR | |
| 1819 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) | |
| 1820 #endif | |
| 1821 #ifndef S_ISLNK | |
| 1822 #define S_ISLNK(m) (0) | |
| 1823 #endif | |
| 1824 typedef unsigned short mode_t; | |
| 1825 | |
| 1826 /* The dirent object for Windows is abbreviated. The only field really | |
| 1827 ** usable by applications is d_name[]. | |
| 1828 */ | |
| 1829 struct dirent { | |
| 1830 int d_ino; /* Inode number (synthesized) */ | |
| 1831 unsigned d_attributes; /* File attributes */ | |
| 1832 char d_name[FILENAME_MAX]; /* Null-terminated filename */ | |
| 1833 }; | |
| 1834 | |
| 1835 /* The internals of DIR are opaque according to standards. So it | |
| 1836 ** does not matter what we put here. */ | |
| 1837 typedef struct DIR DIR; | |
| 1838 struct DIR { | |
| 1839 intptr_t d_handle; /* Handle for findfirst()/findnext() */ | |
| 1840 struct dirent cur; /* Current entry */ | |
| 1841 }; | |
| 1842 | |
| 1843 /* Ignore hidden and system files */ | |
| 1844 #define WindowsFileToIgnore(a) \ | |
| 1845 ((((a).attrib)&_A_HIDDEN) || (((a).attrib)&_A_SYSTEM)) | |
| 1846 | |
| 1847 /* | |
| 1848 ** Close a previously opened directory | |
| 1849 */ | |
| 1850 static int closedir(DIR *pDir){ | |
| 1851 int rc = 0; | |
| 1852 if( pDir==0 ){ | |
| 1853 return EINVAL; | |
| 1854 } | |
| 1855 if( pDir->d_handle!=0 && pDir->d_handle!=(-1) ){ | |
| 1856 rc = _findclose(pDir->d_handle); | |
| 1857 } | |
| 1858 sqlite3_free(pDir); | |
| 1859 return rc; | |
| 1860 } | |
| 1861 | |
| 1862 /* | |
| 1863 ** Open a new directory. The directory name should be UTF-8 encoded. | |
| 1864 ** appropriate translations happen automatically. | |
| 1865 */ | |
| 1866 static DIR *opendir(const char *zDirName){ | |
| 1867 DIR *pDir; | |
| 1868 wchar_t *b1; | |
| 1869 sqlite3_int64 sz; | |
| 1870 struct _wfinddata_t data; | |
| 1871 | |
| 1872 pDir = sqlite3_malloc64( sizeof(DIR) ); | |
| 1873 if( pDir==0 ) return 0; | |
| 1874 memset(pDir, 0, sizeof(DIR)); | |
| 1875 memset(&data, 0, sizeof(data)); | |
| 1876 sz = strlen(zDirName); | |
| 1877 b1 = sqlite3_malloc64( (sz+3)*sizeof(b1[0]) ); | |
| 1878 if( b1==0 ){ | |
| 1879 closedir(pDir); | |
| 1880 return NULL; | |
| 1881 } | |
| 1882 sz = MultiByteToWideChar(CP_UTF8, 0, zDirName, sz, b1, sz); | |
| 1883 b1[sz++] = '\\'; | |
| 1884 b1[sz++] = '*'; | |
| 1885 b1[sz] = 0; | |
| 1886 if( sz+1>sizeof(data.name)/sizeof(data.name[0]) ){ | |
| 1887 closedir(pDir); | |
| 1888 sqlite3_free(b1); | |
| 1889 return NULL; | |
| 1890 } | |
| 1891 memcpy(data.name, b1, (sz+1)*sizeof(b1[0])); | |
| 1892 sqlite3_free(b1); | |
| 1893 pDir->d_handle = _wfindfirst(data.name, &data); | |
| 1894 if( pDir->d_handle<0 ){ | |
| 1895 closedir(pDir); | |
| 1896 return NULL; | |
| 1897 } | |
| 1898 while( WindowsFileToIgnore(data) ){ | |
| 1899 memset(&data, 0, sizeof(data)); | |
| 1900 if( _wfindnext(pDir->d_handle, &data)==-1 ){ | |
| 1901 closedir(pDir); | |
| 1902 return NULL; | |
| 1903 } | |
| 1904 } | |
| 1905 pDir->cur.d_ino = 0; | |
| 1906 pDir->cur.d_attributes = data.attrib; | |
| 1907 WideCharToMultiByte(CP_UTF8, 0, data.name, -1, | |
| 1908 pDir->cur.d_name, FILENAME_MAX, 0, 0); | |
| 1909 return pDir; | |
| 1910 } | |
| 1911 | |
| 1912 /* | |
| 1913 ** Read the next entry from a directory. | |
| 1914 ** | |
| 1915 ** The returned struct-dirent object is managed by DIR. It is only | |
| 1916 ** valid until the next readdir() or closedir() call. Only the | |
| 1917 ** d_name[] field is meaningful. The d_name[] value has been | |
| 1918 ** translated into UTF8. | |
| 1919 */ | |
| 1920 static struct dirent *readdir(DIR *pDir){ | |
| 1921 struct _wfinddata_t data; | |
| 1922 if( pDir==0 ) return 0; | |
| 1923 if( (pDir->cur.d_ino++)==0 ){ | |
| 1924 return &pDir->cur; | |
| 1925 } | |
| 1926 do{ | |
| 1927 memset(&data, 0, sizeof(data)); | |
| 1928 if( _wfindnext(pDir->d_handle, &data)==-1 ){ | |
| 1929 return NULL; | |
| 1930 } | |
| 1931 }while( WindowsFileToIgnore(data) ); | |
| 1932 pDir->cur.d_attributes = data.attrib; | |
| 1933 WideCharToMultiByte(CP_UTF8, 0, data.name, -1, | |
| 1934 pDir->cur.d_name, FILENAME_MAX, 0, 0); | |
| 1935 return &pDir->cur; | |
| 1936 } | |
| 1937 | |
| 1938 #endif /* defined(_WIN32) && defined(_MSC_VER) */ | |
| 1939 | |
| 1940 /************************* End ../ext/misc/windirent.h ********************/ | |
| 1941 /************************* Begin ../ext/misc/memtrace.c ******************/ | |
| 1942 /* | |
| 1943 ** 2019-01-21 | |
| 1944 ** | |
| 1945 ** The author disclaims copyright to this source code. In place of | |
| 1946 ** a legal notice, here is a blessing: | |
| 1947 ** | |
| 1948 ** May you do good and not evil. | |
| 1949 ** May you find forgiveness for yourself and forgive others. | |
| 1950 ** May you share freely, never taking more than you give. | |
| 1951 ** | |
| 1952 ************************************************************************* | |
| 1953 ** | |
| 1954 ** This file implements an extension that uses the SQLITE_CONFIG_MALLOC | |
| 1955 ** mechanism to add a tracing layer on top of SQLite. If this extension | |
| 1956 ** is registered prior to sqlite3_initialize(), it will cause all memory | |
| 1957 ** allocation activities to be logged on standard output, or to some other | |
| 1958 ** FILE specified by the initializer. | |
| 1959 ** | |
| 1960 ** This file needs to be compiled into the application that uses it. | |
| 1961 ** | |
| 1962 ** This extension is used to implement the --memtrace option of the | |
| 1963 ** command-line shell. | |
| 1964 */ | |
| 1965 #include <assert.h> | |
| 1966 #include <string.h> | |
| 1967 #include <stdio.h> | |
| 1968 | |
| 1969 /* The original memory allocation routines */ | |
| 1970 static sqlite3_mem_methods memtraceBase; | |
| 1971 static FILE *memtraceOut; | |
| 1972 | |
| 1973 /* Methods that trace memory allocations */ | |
| 1974 static void *memtraceMalloc(int n){ | |
| 1975 if( memtraceOut ){ | |
| 1976 fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n", | |
| 1977 memtraceBase.xRoundup(n)); | |
| 1978 } | |
| 1979 return memtraceBase.xMalloc(n); | |
| 1980 } | |
| 1981 static void memtraceFree(void *p){ | |
| 1982 if( p==0 ) return; | |
| 1983 if( memtraceOut ){ | |
| 1984 fprintf(memtraceOut, "MEMTRACE: free %d bytes\n", memtraceBase.xSize(p)); | |
| 1985 } | |
| 1986 memtraceBase.xFree(p); | |
| 1987 } | |
| 1988 static void *memtraceRealloc(void *p, int n){ | |
| 1989 if( p==0 ) return memtraceMalloc(n); | |
| 1990 if( n==0 ){ | |
| 1991 memtraceFree(p); | |
| 1992 return 0; | |
| 1993 } | |
| 1994 if( memtraceOut ){ | |
| 1995 fprintf(memtraceOut, "MEMTRACE: resize %d -> %d bytes\n", | |
| 1996 memtraceBase.xSize(p), memtraceBase.xRoundup(n)); | |
| 1997 } | |
| 1998 return memtraceBase.xRealloc(p, n); | |
| 1999 } | |
| 2000 static int memtraceSize(void *p){ | |
| 2001 return memtraceBase.xSize(p); | |
| 2002 } | |
| 2003 static int memtraceRoundup(int n){ | |
| 2004 return memtraceBase.xRoundup(n); | |
| 2005 } | |
| 2006 static int memtraceInit(void *p){ | |
| 2007 return memtraceBase.xInit(p); | |
| 2008 } | |
| 2009 static void memtraceShutdown(void *p){ | |
| 2010 memtraceBase.xShutdown(p); | |
| 2011 } | |
| 2012 | |
| 2013 /* The substitute memory allocator */ | |
| 2014 static sqlite3_mem_methods ersaztMethods = { | |
| 2015 memtraceMalloc, | |
| 2016 memtraceFree, | |
| 2017 memtraceRealloc, | |
| 2018 memtraceSize, | |
| 2019 memtraceRoundup, | |
| 2020 memtraceInit, | |
| 2021 memtraceShutdown, | |
| 2022 0 | |
| 2023 }; | |
| 2024 | |
| 2025 /* Begin tracing memory allocations to out. */ | |
| 2026 int sqlite3MemTraceActivate(FILE *out){ | |
| 2027 int rc = SQLITE_OK; | |
| 2028 if( memtraceBase.xMalloc==0 ){ | |
| 2029 rc = sqlite3_config(SQLITE_CONFIG_GETMALLOC, &memtraceBase); | |
| 2030 if( rc==SQLITE_OK ){ | |
| 2031 rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &ersaztMethods); | |
| 2032 } | |
| 2033 } | |
| 2034 memtraceOut = out; | |
| 2035 return rc; | |
| 2036 } | |
| 2037 | |
| 2038 /* Deactivate memory tracing */ | |
| 2039 int sqlite3MemTraceDeactivate(void){ | |
| 2040 int rc = SQLITE_OK; | |
| 2041 if( memtraceBase.xMalloc!=0 ){ | |
| 2042 rc = sqlite3_config(SQLITE_CONFIG_MALLOC, &memtraceBase); | |
| 2043 if( rc==SQLITE_OK ){ | |
| 2044 memset(&memtraceBase, 0, sizeof(memtraceBase)); | |
| 2045 } | |
| 2046 } | |
| 2047 memtraceOut = 0; | |
| 2048 return rc; | |
| 2049 } | |
| 2050 | |
| 2051 /************************* End ../ext/misc/memtrace.c ********************/ | |
| 2052 /************************* Begin ../ext/misc/pcachetrace.c ******************/ | |
| 2053 /* | |
| 2054 ** 2023-06-21 | |
| 2055 ** | |
| 2056 ** The author disclaims copyright to this source code. In place of | |
| 2057 ** a legal notice, here is a blessing: | |
| 2058 ** | |
| 2059 ** May you do good and not evil. | |
| 2060 ** May you find forgiveness for yourself and forgive others. | |
| 2061 ** May you share freely, never taking more than you give. | |
| 2062 ** | |
| 2063 ************************************************************************* | |
| 2064 ** | |
| 2065 ** This file implements an extension that uses the SQLITE_CONFIG_PCACHE2 | |
| 2066 ** mechanism to add a tracing layer on top of pluggable page cache of | |
| 2067 ** SQLite. If this extension is registered prior to sqlite3_initialize(), | |
| 2068 ** it will cause all page cache activities to be logged on standard output, | |
| 2069 ** or to some other FILE specified by the initializer. | |
| 2070 ** | |
| 2071 ** This file needs to be compiled into the application that uses it. | |
| 2072 ** | |
| 2073 ** This extension is used to implement the --pcachetrace option of the | |
| 2074 ** command-line shell. | |
| 2075 */ | |
| 2076 #include <assert.h> | |
| 2077 #include <string.h> | |
| 2078 #include <stdio.h> | |
| 2079 | |
| 2080 /* The original page cache routines */ | |
| 2081 static sqlite3_pcache_methods2 pcacheBase; | |
| 2082 static FILE *pcachetraceOut; | |
| 2083 | |
| 2084 /* Methods that trace pcache activity */ | |
| 2085 static int pcachetraceInit(void *pArg){ | |
| 2086 int nRes; | |
| 2087 if( pcachetraceOut ){ | |
| 2088 fprintf(pcachetraceOut, "PCACHETRACE: xInit(%p)\n", pArg); | |
| 2089 } | |
| 2090 nRes = pcacheBase.xInit(pArg); | |
| 2091 if( pcachetraceOut ){ | |
| 2092 fprintf(pcachetraceOut, "PCACHETRACE: xInit(%p) -> %d\n", pArg, nRes); | |
| 2093 } | |
| 2094 return nRes; | |
| 2095 } | |
| 2096 static void pcachetraceShutdown(void *pArg){ | |
| 2097 if( pcachetraceOut ){ | |
| 2098 fprintf(pcachetraceOut, "PCACHETRACE: xShutdown(%p)\n", pArg); | |
| 2099 } | |
| 2100 pcacheBase.xShutdown(pArg); | |
| 2101 } | |
| 2102 static sqlite3_pcache *pcachetraceCreate(int szPage, int szExtra, int bPurge){ | |
| 2103 sqlite3_pcache *pRes; | |
| 2104 if( pcachetraceOut ){ | |
| 2105 fprintf(pcachetraceOut, "PCACHETRACE: xCreate(%d,%d,%d)\n", | |
| 2106 szPage, szExtra, bPurge); | |
| 2107 } | |
| 2108 pRes = pcacheBase.xCreate(szPage, szExtra, bPurge); | |
| 2109 if( pcachetraceOut ){ | |
| 2110 fprintf(pcachetraceOut, "PCACHETRACE: xCreate(%d,%d,%d) -> %p\n", | |
| 2111 szPage, szExtra, bPurge, pRes); | |
| 2112 } | |
| 2113 return pRes; | |
| 2114 } | |
| 2115 static void pcachetraceCachesize(sqlite3_pcache *p, int nCachesize){ | |
| 2116 if( pcachetraceOut ){ | |
| 2117 fprintf(pcachetraceOut, "PCACHETRACE: xCachesize(%p, %d)\n", p, nCachesize); | |
| 2118 } | |
| 2119 pcacheBase.xCachesize(p, nCachesize); | |
| 2120 } | |
| 2121 static int pcachetracePagecount(sqlite3_pcache *p){ | |
| 2122 int nRes; | |
| 2123 if( pcachetraceOut ){ | |
| 2124 fprintf(pcachetraceOut, "PCACHETRACE: xPagecount(%p)\n", p); | |
| 2125 } | |
| 2126 nRes = pcacheBase.xPagecount(p); | |
| 2127 if( pcachetraceOut ){ | |
| 2128 fprintf(pcachetraceOut, "PCACHETRACE: xPagecount(%p) -> %d\n", p, nRes); | |
| 2129 } | |
| 2130 return nRes; | |
| 2131 } | |
| 2132 static sqlite3_pcache_page *pcachetraceFetch( | |
| 2133 sqlite3_pcache *p, | |
| 2134 unsigned key, | |
| 2135 int crFg | |
| 2136 ){ | |
| 2137 sqlite3_pcache_page *pRes; | |
| 2138 if( pcachetraceOut ){ | |
| 2139 fprintf(pcachetraceOut, "PCACHETRACE: xFetch(%p,%u,%d)\n", p, key, crFg); | |
| 2140 } | |
| 2141 pRes = pcacheBase.xFetch(p, key, crFg); | |
| 2142 if( pcachetraceOut ){ | |
| 2143 fprintf(pcachetraceOut, "PCACHETRACE: xFetch(%p,%u,%d) -> %p\n", | |
| 2144 p, key, crFg, pRes); | |
| 2145 } | |
| 2146 return pRes; | |
| 2147 } | |
| 2148 static void pcachetraceUnpin( | |
| 2149 sqlite3_pcache *p, | |
| 2150 sqlite3_pcache_page *pPg, | |
| 2151 int bDiscard | |
| 2152 ){ | |
| 2153 if( pcachetraceOut ){ | |
| 2154 fprintf(pcachetraceOut, "PCACHETRACE: xUnpin(%p, %p, %d)\n", | |
| 2155 p, pPg, bDiscard); | |
| 2156 } | |
| 2157 pcacheBase.xUnpin(p, pPg, bDiscard); | |
| 2158 } | |
| 2159 static void pcachetraceRekey( | |
| 2160 sqlite3_pcache *p, | |
| 2161 sqlite3_pcache_page *pPg, | |
| 2162 unsigned oldKey, | |
| 2163 unsigned newKey | |
| 2164 ){ | |
| 2165 if( pcachetraceOut ){ | |
| 2166 fprintf(pcachetraceOut, "PCACHETRACE: xRekey(%p, %p, %u, %u)\n", | |
| 2167 p, pPg, oldKey, newKey); | |
| 2168 } | |
| 2169 pcacheBase.xRekey(p, pPg, oldKey, newKey); | |
| 2170 } | |
| 2171 static void pcachetraceTruncate(sqlite3_pcache *p, unsigned n){ | |
| 2172 if( pcachetraceOut ){ | |
| 2173 fprintf(pcachetraceOut, "PCACHETRACE: xTruncate(%p, %u)\n", p, n); | |
| 2174 } | |
| 2175 pcacheBase.xTruncate(p, n); | |
| 2176 } | |
| 2177 static void pcachetraceDestroy(sqlite3_pcache *p){ | |
| 2178 if( pcachetraceOut ){ | |
| 2179 fprintf(pcachetraceOut, "PCACHETRACE: xDestroy(%p)\n", p); | |
| 2180 } | |
| 2181 pcacheBase.xDestroy(p); | |
| 2182 } | |
| 2183 static void pcachetraceShrink(sqlite3_pcache *p){ | |
| 2184 if( pcachetraceOut ){ | |
| 2185 fprintf(pcachetraceOut, "PCACHETRACE: xShrink(%p)\n", p); | |
| 2186 } | |
| 2187 pcacheBase.xShrink(p); | |
| 2188 } | |
| 2189 | |
| 2190 /* The substitute pcache methods */ | |
| 2191 static sqlite3_pcache_methods2 ersaztPcacheMethods = { | |
| 2192 0, | |
| 2193 0, | |
| 2194 pcachetraceInit, | |
| 2195 pcachetraceShutdown, | |
| 2196 pcachetraceCreate, | |
| 2197 pcachetraceCachesize, | |
| 2198 pcachetracePagecount, | |
| 2199 pcachetraceFetch, | |
| 2200 pcachetraceUnpin, | |
| 2201 pcachetraceRekey, | |
| 2202 pcachetraceTruncate, | |
| 2203 pcachetraceDestroy, | |
| 2204 pcachetraceShrink | |
| 2205 }; | |
| 2206 | |
| 2207 /* Begin tracing memory allocations to out. */ | |
| 2208 int sqlite3PcacheTraceActivate(FILE *out){ | |
| 2209 int rc = SQLITE_OK; | |
| 2210 if( pcacheBase.xFetch==0 ){ | |
| 2211 rc = sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &pcacheBase); | |
| 2212 if( rc==SQLITE_OK ){ | |
| 2213 rc = sqlite3_config(SQLITE_CONFIG_PCACHE2, &ersaztPcacheMethods); | |
| 2214 } | |
| 2215 } | |
| 2216 pcachetraceOut = out; | |
| 2217 return rc; | |
| 2218 } | |
| 2219 | |
| 2220 /* Deactivate memory tracing */ | |
| 2221 int sqlite3PcacheTraceDeactivate(void){ | |
| 2222 int rc = SQLITE_OK; | |
| 2223 if( pcacheBase.xFetch!=0 ){ | |
| 2224 rc = sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcacheBase); | |
| 2225 if( rc==SQLITE_OK ){ | |
| 2226 memset(&pcacheBase, 0, sizeof(pcacheBase)); | |
| 2227 } | |
| 2228 } | |
| 2229 pcachetraceOut = 0; | |
| 2230 return rc; | |
| 2231 } | |
| 2232 | |
| 2233 /************************* End ../ext/misc/pcachetrace.c ********************/ | |
| 2234 /************************* Begin ../ext/misc/shathree.c ******************/ | |
| 2235 /* | |
| 2236 ** 2017-03-08 | |
| 2237 ** | |
| 2238 ** The author disclaims copyright to this source code. In place of | |
| 2239 ** a legal notice, here is a blessing: | |
| 2240 ** | |
| 2241 ** May you do good and not evil. | |
| 2242 ** May you find forgiveness for yourself and forgive others. | |
| 2243 ** May you share freely, never taking more than you give. | |
| 2244 ** | |
| 2245 ****************************************************************************** | |
| 2246 ** | |
| 2247 ** This SQLite extension implements functions that compute SHA3 hashes | |
| 2248 ** in the way described by the (U.S.) NIST FIPS 202 SHA-3 Standard. | |
| 2249 ** Three SQL functions are implemented: | |
| 2250 ** | |
| 2251 ** sha3(X,SIZE) | |
| 2252 ** sha3_agg(Y,SIZE) | |
| 2253 ** sha3_query(Z,SIZE) | |
| 2254 ** | |
| 2255 ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if | |
| 2256 ** X is NULL. If inputs X is text, the UTF-8 rendering of that text is | |
| 2257 ** used to compute the hash. If X is a BLOB, then the binary data of the | |
| 2258 ** blob is used to compute the hash. If X is an integer or real number, | |
| 2259 ** then that number if converted into UTF-8 text and the hash is computed | |
| 2260 ** over the text. | |
| 2261 ** | |
| 2262 ** The sha3_agg(Y) function computes the SHA3 hash of all Y inputs. Since | |
| 2263 ** order is important for the hash, it is recommended that the Y expression | |
| 2264 ** by followed by an ORDER BY clause to guarantee that the inputs occur | |
| 2265 ** in the desired order. | |
| 2266 ** | |
| 2267 ** The sha3_query(Y) function evaluates all queries in the SQL statements of Y | |
| 2268 ** and returns a hash of their results. | |
| 2269 ** | |
| 2270 ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm | |
| 2271 ** is used. If SIZE is included it must be one of the integers 224, 256, | |
| 2272 ** 384, or 512, to determine SHA3 hash variant that is computed. | |
| 2273 ** | |
| 2274 ** Because the sha3_agg() and sha3_query() functions compute a hash over | |
| 2275 ** multiple values, the values are encode to use include type information. | |
| 2276 ** | |
| 2277 ** In sha3_agg(), the sequence of bytes that gets hashed for each input | |
| 2278 ** Y depends on the datatype of Y: | |
| 2279 ** | |
| 2280 ** typeof(Y)='null' A single "N" is hashed. (One byte) | |
| 2281 ** | |
| 2282 ** typeof(Y)='integer' The data hash is the character "I" followed | |
| 2283 ** by an 8-byte big-endian binary of the | |
| 2284 ** 64-bit signed integer. (Nine bytes total.) | |
| 2285 ** | |
| 2286 ** typeof(Y)='real' The character "F" followed by an 8-byte | |
| 2287 ** big-ending binary of the double. (Nine | |
| 2288 ** bytes total.) | |
| 2289 ** | |
| 2290 ** typeof(Y)='text' The hash is over prefix "Tnnn:" followed | |
| 2291 ** by the UTF8 encoding of the text. The "nnn" | |
| 2292 ** in the prefix is the minimum-length decimal | |
| 2293 ** representation of the octet_length of the text. | |
| 2294 ** Notice the ":" at the end of the prefix, which | |
| 2295 ** is needed to separate the prefix from the | |
| 2296 ** content in cases where the content starts | |
| 2297 ** with a digit. | |
| 2298 ** | |
| 2299 ** typeof(Y)='blob' The hash is taken over prefix "Bnnn:" followed | |
| 2300 ** by the binary content of the blob. The "nnn" | |
| 2301 ** in the prefix is the minimum-length decimal | |
| 2302 ** representation of the byte-length of the blob. | |
| 2303 ** | |
| 2304 ** According to the rules above, all of the following SELECT statements | |
| 2305 ** should return TRUE: | |
| 2306 ** | |
| 2307 ** SELECT sha3(1) = sha3('1'); | |
| 2308 ** | |
| 2309 ** SELECT sha3('hello') = sha3(x'68656c6c6f'); | |
| 2310 ** | |
| 2311 ** WITH a(x) AS (VALUES('xyzzy')) | |
| 2312 ** SELECT sha3_agg(x) = sha3('T5:xyzzy') FROM a; | |
| 2313 ** | |
| 2314 ** WITH a(x) AS (VALUES(x'010203')) | |
| 2315 ** SELECT sha3_agg(x) = sha3(x'42333a010203') FROM a; | |
| 2316 ** | |
| 2317 ** WITH a(x) AS (VALUES(0x123456)) | |
| 2318 ** SELECT sha3_agg(x) = sha3(x'490000000000123456') FROM a; | |
| 2319 ** | |
| 2320 ** WITH a(x) AS (VALUES(100.015625)) | |
| 2321 ** SELECT sha3_agg(x) = sha3(x'464059010000000000') FROM a; | |
| 2322 ** | |
| 2323 ** WITH a(x) AS (VALUES(NULL)) | |
| 2324 ** SELECT sha3_agg(x) = sha3('N') FROM a; | |
| 2325 ** | |
| 2326 ** | |
| 2327 ** In sha3_query(), individual column values are encoded as with | |
| 2328 ** sha3_agg(), but with the addition that a single "R" character is | |
| 2329 ** inserted at the start of each row. | |
| 2330 ** | |
| 2331 ** Note that sha3_agg() hashes rows for which Y is NULL. Add a FILTER | |
| 2332 ** clause if NULL rows should be excluded: | |
| 2333 ** | |
| 2334 ** SELECT sha3_agg(x ORDER BY rowid) FILTER(WHERE x NOT NULL) FROM t1; | |
| 2335 */ | |
| 2336 /* #include "sqlite3ext.h" */ | |
| 2337 SQLITE_EXTENSION_INIT1 | |
| 2338 #include <assert.h> | |
| 2339 #include <string.h> | |
| 2340 #include <stdarg.h> | |
| 2341 | |
| 2342 #ifndef SQLITE_AMALGAMATION | |
| 2343 /* typedef sqlite3_uint64 u64; */ | |
| 2344 #endif /* SQLITE_AMALGAMATION */ | |
| 2345 | |
| 2346 /****************************************************************************** | |
| 2347 ** The Hash Engine | |
| 2348 */ | |
| 2349 /* | |
| 2350 ** Macros to determine whether the machine is big or little endian, | |
| 2351 ** and whether or not that determination is run-time or compile-time. | |
| 2352 ** | |
| 2353 ** For best performance, an attempt is made to guess at the byte-order | |
| 2354 ** using C-preprocessor macros. If that is unsuccessful, or if | |
| 2355 ** -DSHA3_BYTEORDER=0 is set, then byte-order is determined | |
| 2356 ** at run-time. | |
| 2357 */ | |
| 2358 #ifndef SHA3_BYTEORDER | |
| 2359 # if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ | |
| 2360 defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ | |
| 2361 defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ | |
| 2362 defined(__arm__) | |
| 2363 # define SHA3_BYTEORDER 1234 | |
| 2364 # elif defined(sparc) || defined(__ppc__) | |
| 2365 # define SHA3_BYTEORDER 4321 | |
| 2366 # else | |
| 2367 # define SHA3_BYTEORDER 0 | |
| 2368 # endif | |
| 2369 #endif | |
| 2370 | |
| 2371 | |
| 2372 /* | |
| 2373 ** State structure for a SHA3 hash in progress | |
| 2374 */ | |
| 2375 typedef struct SHA3Context SHA3Context; | |
| 2376 struct SHA3Context { | |
| 2377 union { | |
| 2378 u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ | |
| 2379 unsigned char x[1600]; /* ... or 1600 bytes */ | |
| 2380 } u; | |
| 2381 unsigned nRate; /* Bytes of input accepted per Keccak iteration */ | |
| 2382 unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ | |
| 2383 unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ | |
| 2384 unsigned iSize; /* 224, 256, 358, or 512 */ | |
| 2385 }; | |
| 2386 | |
| 2387 /* | |
| 2388 ** A single step of the Keccak mixing function for a 1600-bit state | |
| 2389 */ | |
| 2390 static void KeccakF1600Step(SHA3Context *p){ | |
| 2391 int i; | |
| 2392 u64 b0, b1, b2, b3, b4; | |
| 2393 u64 c0, c1, c2, c3, c4; | |
| 2394 u64 d0, d1, d2, d3, d4; | |
| 2395 static const u64 RC[] = { | |
| 2396 0x0000000000000001ULL, 0x0000000000008082ULL, | |
| 2397 0x800000000000808aULL, 0x8000000080008000ULL, | |
| 2398 0x000000000000808bULL, 0x0000000080000001ULL, | |
| 2399 0x8000000080008081ULL, 0x8000000000008009ULL, | |
| 2400 0x000000000000008aULL, 0x0000000000000088ULL, | |
| 2401 0x0000000080008009ULL, 0x000000008000000aULL, | |
| 2402 0x000000008000808bULL, 0x800000000000008bULL, | |
| 2403 0x8000000000008089ULL, 0x8000000000008003ULL, | |
| 2404 0x8000000000008002ULL, 0x8000000000000080ULL, | |
| 2405 0x000000000000800aULL, 0x800000008000000aULL, | |
| 2406 0x8000000080008081ULL, 0x8000000000008080ULL, | |
| 2407 0x0000000080000001ULL, 0x8000000080008008ULL | |
| 2408 }; | |
| 2409 # define a00 (p->u.s[0]) | |
| 2410 # define a01 (p->u.s[1]) | |
| 2411 # define a02 (p->u.s[2]) | |
| 2412 # define a03 (p->u.s[3]) | |
| 2413 # define a04 (p->u.s[4]) | |
| 2414 # define a10 (p->u.s[5]) | |
| 2415 # define a11 (p->u.s[6]) | |
| 2416 # define a12 (p->u.s[7]) | |
| 2417 # define a13 (p->u.s[8]) | |
| 2418 # define a14 (p->u.s[9]) | |
| 2419 # define a20 (p->u.s[10]) | |
| 2420 # define a21 (p->u.s[11]) | |
| 2421 # define a22 (p->u.s[12]) | |
| 2422 # define a23 (p->u.s[13]) | |
| 2423 # define a24 (p->u.s[14]) | |
| 2424 # define a30 (p->u.s[15]) | |
| 2425 # define a31 (p->u.s[16]) | |
| 2426 # define a32 (p->u.s[17]) | |
| 2427 # define a33 (p->u.s[18]) | |
| 2428 # define a34 (p->u.s[19]) | |
| 2429 # define a40 (p->u.s[20]) | |
| 2430 # define a41 (p->u.s[21]) | |
| 2431 # define a42 (p->u.s[22]) | |
| 2432 # define a43 (p->u.s[23]) | |
| 2433 # define a44 (p->u.s[24]) | |
| 2434 # define ROL64(a,x) ((a<<x)|(a>>(64-x))) | |
| 2435 | |
| 2436 for(i=0; i<24; i+=4){ | |
| 2437 c0 = a00^a10^a20^a30^a40; | |
| 2438 c1 = a01^a11^a21^a31^a41; | |
| 2439 c2 = a02^a12^a22^a32^a42; | |
| 2440 c3 = a03^a13^a23^a33^a43; | |
| 2441 c4 = a04^a14^a24^a34^a44; | |
| 2442 d0 = c4^ROL64(c1, 1); | |
| 2443 d1 = c0^ROL64(c2, 1); | |
| 2444 d2 = c1^ROL64(c3, 1); | |
| 2445 d3 = c2^ROL64(c4, 1); | |
| 2446 d4 = c3^ROL64(c0, 1); | |
| 2447 | |
| 2448 b0 = (a00^d0); | |
| 2449 b1 = ROL64((a11^d1), 44); | |
| 2450 b2 = ROL64((a22^d2), 43); | |
| 2451 b3 = ROL64((a33^d3), 21); | |
| 2452 b4 = ROL64((a44^d4), 14); | |
| 2453 a00 = b0 ^((~b1)& b2 ); | |
| 2454 a00 ^= RC[i]; | |
| 2455 a11 = b1 ^((~b2)& b3 ); | |
| 2456 a22 = b2 ^((~b3)& b4 ); | |
| 2457 a33 = b3 ^((~b4)& b0 ); | |
| 2458 a44 = b4 ^((~b0)& b1 ); | |
| 2459 | |
| 2460 b2 = ROL64((a20^d0), 3); | |
| 2461 b3 = ROL64((a31^d1), 45); | |
| 2462 b4 = ROL64((a42^d2), 61); | |
| 2463 b0 = ROL64((a03^d3), 28); | |
| 2464 b1 = ROL64((a14^d4), 20); | |
| 2465 a20 = b0 ^((~b1)& b2 ); | |
| 2466 a31 = b1 ^((~b2)& b3 ); | |
| 2467 a42 = b2 ^((~b3)& b4 ); | |
| 2468 a03 = b3 ^((~b4)& b0 ); | |
| 2469 a14 = b4 ^((~b0)& b1 ); | |
| 2470 | |
| 2471 b4 = ROL64((a40^d0), 18); | |
| 2472 b0 = ROL64((a01^d1), 1); | |
| 2473 b1 = ROL64((a12^d2), 6); | |
| 2474 b2 = ROL64((a23^d3), 25); | |
| 2475 b3 = ROL64((a34^d4), 8); | |
| 2476 a40 = b0 ^((~b1)& b2 ); | |
| 2477 a01 = b1 ^((~b2)& b3 ); | |
| 2478 a12 = b2 ^((~b3)& b4 ); | |
| 2479 a23 = b3 ^((~b4)& b0 ); | |
| 2480 a34 = b4 ^((~b0)& b1 ); | |
| 2481 | |
| 2482 b1 = ROL64((a10^d0), 36); | |
| 2483 b2 = ROL64((a21^d1), 10); | |
| 2484 b3 = ROL64((a32^d2), 15); | |
| 2485 b4 = ROL64((a43^d3), 56); | |
| 2486 b0 = ROL64((a04^d4), 27); | |
| 2487 a10 = b0 ^((~b1)& b2 ); | |
| 2488 a21 = b1 ^((~b2)& b3 ); | |
| 2489 a32 = b2 ^((~b3)& b4 ); | |
| 2490 a43 = b3 ^((~b4)& b0 ); | |
| 2491 a04 = b4 ^((~b0)& b1 ); | |
| 2492 | |
| 2493 b3 = ROL64((a30^d0), 41); | |
| 2494 b4 = ROL64((a41^d1), 2); | |
| 2495 b0 = ROL64((a02^d2), 62); | |
| 2496 b1 = ROL64((a13^d3), 55); | |
| 2497 b2 = ROL64((a24^d4), 39); | |
| 2498 a30 = b0 ^((~b1)& b2 ); | |
| 2499 a41 = b1 ^((~b2)& b3 ); | |
| 2500 a02 = b2 ^((~b3)& b4 ); | |
| 2501 a13 = b3 ^((~b4)& b0 ); | |
| 2502 a24 = b4 ^((~b0)& b1 ); | |
| 2503 | |
| 2504 c0 = a00^a20^a40^a10^a30; | |
| 2505 c1 = a11^a31^a01^a21^a41; | |
| 2506 c2 = a22^a42^a12^a32^a02; | |
| 2507 c3 = a33^a03^a23^a43^a13; | |
| 2508 c4 = a44^a14^a34^a04^a24; | |
| 2509 d0 = c4^ROL64(c1, 1); | |
| 2510 d1 = c0^ROL64(c2, 1); | |
| 2511 d2 = c1^ROL64(c3, 1); | |
| 2512 d3 = c2^ROL64(c4, 1); | |
| 2513 d4 = c3^ROL64(c0, 1); | |
| 2514 | |
| 2515 b0 = (a00^d0); | |
| 2516 b1 = ROL64((a31^d1), 44); | |
| 2517 b2 = ROL64((a12^d2), 43); | |
| 2518 b3 = ROL64((a43^d3), 21); | |
| 2519 b4 = ROL64((a24^d4), 14); | |
| 2520 a00 = b0 ^((~b1)& b2 ); | |
| 2521 a00 ^= RC[i+1]; | |
| 2522 a31 = b1 ^((~b2)& b3 ); | |
| 2523 a12 = b2 ^((~b3)& b4 ); | |
| 2524 a43 = b3 ^((~b4)& b0 ); | |
| 2525 a24 = b4 ^((~b0)& b1 ); | |
| 2526 | |
| 2527 b2 = ROL64((a40^d0), 3); | |
| 2528 b3 = ROL64((a21^d1), 45); | |
| 2529 b4 = ROL64((a02^d2), 61); | |
| 2530 b0 = ROL64((a33^d3), 28); | |
| 2531 b1 = ROL64((a14^d4), 20); | |
| 2532 a40 = b0 ^((~b1)& b2 ); | |
| 2533 a21 = b1 ^((~b2)& b3 ); | |
| 2534 a02 = b2 ^((~b3)& b4 ); | |
| 2535 a33 = b3 ^((~b4)& b0 ); | |
| 2536 a14 = b4 ^((~b0)& b1 ); | |
| 2537 | |
| 2538 b4 = ROL64((a30^d0), 18); | |
| 2539 b0 = ROL64((a11^d1), 1); | |
| 2540 b1 = ROL64((a42^d2), 6); | |
| 2541 b2 = ROL64((a23^d3), 25); | |
| 2542 b3 = ROL64((a04^d4), 8); | |
| 2543 a30 = b0 ^((~b1)& b2 ); | |
| 2544 a11 = b1 ^((~b2)& b3 ); | |
| 2545 a42 = b2 ^((~b3)& b4 ); | |
| 2546 a23 = b3 ^((~b4)& b0 ); | |
| 2547 a04 = b4 ^((~b0)& b1 ); | |
| 2548 | |
| 2549 b1 = ROL64((a20^d0), 36); | |
| 2550 b2 = ROL64((a01^d1), 10); | |
| 2551 b3 = ROL64((a32^d2), 15); | |
| 2552 b4 = ROL64((a13^d3), 56); | |
| 2553 b0 = ROL64((a44^d4), 27); | |
| 2554 a20 = b0 ^((~b1)& b2 ); | |
| 2555 a01 = b1 ^((~b2)& b3 ); | |
| 2556 a32 = b2 ^((~b3)& b4 ); | |
| 2557 a13 = b3 ^((~b4)& b0 ); | |
| 2558 a44 = b4 ^((~b0)& b1 ); | |
| 2559 | |
| 2560 b3 = ROL64((a10^d0), 41); | |
| 2561 b4 = ROL64((a41^d1), 2); | |
| 2562 b0 = ROL64((a22^d2), 62); | |
| 2563 b1 = ROL64((a03^d3), 55); | |
| 2564 b2 = ROL64((a34^d4), 39); | |
| 2565 a10 = b0 ^((~b1)& b2 ); | |
| 2566 a41 = b1 ^((~b2)& b3 ); | |
| 2567 a22 = b2 ^((~b3)& b4 ); | |
| 2568 a03 = b3 ^((~b4)& b0 ); | |
| 2569 a34 = b4 ^((~b0)& b1 ); | |
| 2570 | |
| 2571 c0 = a00^a40^a30^a20^a10; | |
| 2572 c1 = a31^a21^a11^a01^a41; | |
| 2573 c2 = a12^a02^a42^a32^a22; | |
| 2574 c3 = a43^a33^a23^a13^a03; | |
| 2575 c4 = a24^a14^a04^a44^a34; | |
| 2576 d0 = c4^ROL64(c1, 1); | |
| 2577 d1 = c0^ROL64(c2, 1); | |
| 2578 d2 = c1^ROL64(c3, 1); | |
| 2579 d3 = c2^ROL64(c4, 1); | |
| 2580 d4 = c3^ROL64(c0, 1); | |
| 2581 | |
| 2582 b0 = (a00^d0); | |
| 2583 b1 = ROL64((a21^d1), 44); | |
| 2584 b2 = ROL64((a42^d2), 43); | |
| 2585 b3 = ROL64((a13^d3), 21); | |
| 2586 b4 = ROL64((a34^d4), 14); | |
| 2587 a00 = b0 ^((~b1)& b2 ); | |
| 2588 a00 ^= RC[i+2]; | |
| 2589 a21 = b1 ^((~b2)& b3 ); | |
| 2590 a42 = b2 ^((~b3)& b4 ); | |
| 2591 a13 = b3 ^((~b4)& b0 ); | |
| 2592 a34 = b4 ^((~b0)& b1 ); | |
| 2593 | |
| 2594 b2 = ROL64((a30^d0), 3); | |
| 2595 b3 = ROL64((a01^d1), 45); | |
| 2596 b4 = ROL64((a22^d2), 61); | |
| 2597 b0 = ROL64((a43^d3), 28); | |
| 2598 b1 = ROL64((a14^d4), 20); | |
| 2599 a30 = b0 ^((~b1)& b2 ); | |
| 2600 a01 = b1 ^((~b2)& b3 ); | |
| 2601 a22 = b2 ^((~b3)& b4 ); | |
| 2602 a43 = b3 ^((~b4)& b0 ); | |
| 2603 a14 = b4 ^((~b0)& b1 ); | |
| 2604 | |
| 2605 b4 = ROL64((a10^d0), 18); | |
| 2606 b0 = ROL64((a31^d1), 1); | |
| 2607 b1 = ROL64((a02^d2), 6); | |
| 2608 b2 = ROL64((a23^d3), 25); | |
| 2609 b3 = ROL64((a44^d4), 8); | |
| 2610 a10 = b0 ^((~b1)& b2 ); | |
| 2611 a31 = b1 ^((~b2)& b3 ); | |
| 2612 a02 = b2 ^((~b3)& b4 ); | |
| 2613 a23 = b3 ^((~b4)& b0 ); | |
| 2614 a44 = b4 ^((~b0)& b1 ); | |
| 2615 | |
| 2616 b1 = ROL64((a40^d0), 36); | |
| 2617 b2 = ROL64((a11^d1), 10); | |
| 2618 b3 = ROL64((a32^d2), 15); | |
| 2619 b4 = ROL64((a03^d3), 56); | |
| 2620 b0 = ROL64((a24^d4), 27); | |
| 2621 a40 = b0 ^((~b1)& b2 ); | |
| 2622 a11 = b1 ^((~b2)& b3 ); | |
| 2623 a32 = b2 ^((~b3)& b4 ); | |
| 2624 a03 = b3 ^((~b4)& b0 ); | |
| 2625 a24 = b4 ^((~b0)& b1 ); | |
| 2626 | |
| 2627 b3 = ROL64((a20^d0), 41); | |
| 2628 b4 = ROL64((a41^d1), 2); | |
| 2629 b0 = ROL64((a12^d2), 62); | |
| 2630 b1 = ROL64((a33^d3), 55); | |
| 2631 b2 = ROL64((a04^d4), 39); | |
| 2632 a20 = b0 ^((~b1)& b2 ); | |
| 2633 a41 = b1 ^((~b2)& b3 ); | |
| 2634 a12 = b2 ^((~b3)& b4 ); | |
| 2635 a33 = b3 ^((~b4)& b0 ); | |
| 2636 a04 = b4 ^((~b0)& b1 ); | |
| 2637 | |
| 2638 c0 = a00^a30^a10^a40^a20; | |
| 2639 c1 = a21^a01^a31^a11^a41; | |
| 2640 c2 = a42^a22^a02^a32^a12; | |
| 2641 c3 = a13^a43^a23^a03^a33; | |
| 2642 c4 = a34^a14^a44^a24^a04; | |
| 2643 d0 = c4^ROL64(c1, 1); | |
| 2644 d1 = c0^ROL64(c2, 1); | |
| 2645 d2 = c1^ROL64(c3, 1); | |
| 2646 d3 = c2^ROL64(c4, 1); | |
| 2647 d4 = c3^ROL64(c0, 1); | |
| 2648 | |
| 2649 b0 = (a00^d0); | |
| 2650 b1 = ROL64((a01^d1), 44); | |
| 2651 b2 = ROL64((a02^d2), 43); | |
| 2652 b3 = ROL64((a03^d3), 21); | |
| 2653 b4 = ROL64((a04^d4), 14); | |
| 2654 a00 = b0 ^((~b1)& b2 ); | |
| 2655 a00 ^= RC[i+3]; | |
| 2656 a01 = b1 ^((~b2)& b3 ); | |
| 2657 a02 = b2 ^((~b3)& b4 ); | |
| 2658 a03 = b3 ^((~b4)& b0 ); | |
| 2659 a04 = b4 ^((~b0)& b1 ); | |
| 2660 | |
| 2661 b2 = ROL64((a10^d0), 3); | |
| 2662 b3 = ROL64((a11^d1), 45); | |
| 2663 b4 = ROL64((a12^d2), 61); | |
| 2664 b0 = ROL64((a13^d3), 28); | |
| 2665 b1 = ROL64((a14^d4), 20); | |
| 2666 a10 = b0 ^((~b1)& b2 ); | |
| 2667 a11 = b1 ^((~b2)& b3 ); | |
| 2668 a12 = b2 ^((~b3)& b4 ); | |
| 2669 a13 = b3 ^((~b4)& b0 ); | |
| 2670 a14 = b4 ^((~b0)& b1 ); | |
| 2671 | |
| 2672 b4 = ROL64((a20^d0), 18); | |
| 2673 b0 = ROL64((a21^d1), 1); | |
| 2674 b1 = ROL64((a22^d2), 6); | |
| 2675 b2 = ROL64((a23^d3), 25); | |
| 2676 b3 = ROL64((a24^d4), 8); | |
| 2677 a20 = b0 ^((~b1)& b2 ); | |
| 2678 a21 = b1 ^((~b2)& b3 ); | |
| 2679 a22 = b2 ^((~b3)& b4 ); | |
| 2680 a23 = b3 ^((~b4)& b0 ); | |
| 2681 a24 = b4 ^((~b0)& b1 ); | |
| 2682 | |
| 2683 b1 = ROL64((a30^d0), 36); | |
| 2684 b2 = ROL64((a31^d1), 10); | |
| 2685 b3 = ROL64((a32^d2), 15); | |
| 2686 b4 = ROL64((a33^d3), 56); | |
| 2687 b0 = ROL64((a34^d4), 27); | |
| 2688 a30 = b0 ^((~b1)& b2 ); | |
| 2689 a31 = b1 ^((~b2)& b3 ); | |
| 2690 a32 = b2 ^((~b3)& b4 ); | |
| 2691 a33 = b3 ^((~b4)& b0 ); | |
| 2692 a34 = b4 ^((~b0)& b1 ); | |
| 2693 | |
| 2694 b3 = ROL64((a40^d0), 41); | |
| 2695 b4 = ROL64((a41^d1), 2); | |
| 2696 b0 = ROL64((a42^d2), 62); | |
| 2697 b1 = ROL64((a43^d3), 55); | |
| 2698 b2 = ROL64((a44^d4), 39); | |
| 2699 a40 = b0 ^((~b1)& b2 ); | |
| 2700 a41 = b1 ^((~b2)& b3 ); | |
| 2701 a42 = b2 ^((~b3)& b4 ); | |
| 2702 a43 = b3 ^((~b4)& b0 ); | |
| 2703 a44 = b4 ^((~b0)& b1 ); | |
| 2704 } | |
| 2705 } | |
| 2706 | |
| 2707 /* | |
| 2708 ** Initialize a new hash. iSize determines the size of the hash | |
| 2709 ** in bits and should be one of 224, 256, 384, or 512. Or iSize | |
| 2710 ** can be zero to use the default hash size of 256 bits. | |
| 2711 */ | |
| 2712 static void SHA3Init(SHA3Context *p, int iSize){ | |
| 2713 memset(p, 0, sizeof(*p)); | |
| 2714 p->iSize = iSize; | |
| 2715 if( iSize>=128 && iSize<=512 ){ | |
| 2716 p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; | |
| 2717 }else{ | |
| 2718 p->nRate = (1600 - 2*256)/8; | |
| 2719 } | |
| 2720 #if SHA3_BYTEORDER==1234 | |
| 2721 /* Known to be little-endian at compile-time. No-op */ | |
| 2722 #elif SHA3_BYTEORDER==4321 | |
| 2723 p->ixMask = 7; /* Big-endian */ | |
| 2724 #else | |
| 2725 { | |
| 2726 static unsigned int one = 1; | |
| 2727 if( 1==*(unsigned char*)&one ){ | |
| 2728 /* Little endian. No byte swapping. */ | |
| 2729 p->ixMask = 0; | |
| 2730 }else{ | |
| 2731 /* Big endian. Byte swap. */ | |
| 2732 p->ixMask = 7; | |
| 2733 } | |
| 2734 } | |
| 2735 #endif | |
| 2736 } | |
| 2737 | |
| 2738 /* | |
| 2739 ** Make consecutive calls to the SHA3Update function to add new content | |
| 2740 ** to the hash | |
| 2741 */ | |
| 2742 static void SHA3Update( | |
| 2743 SHA3Context *p, | |
| 2744 const unsigned char *aData, | |
| 2745 unsigned int nData | |
| 2746 ){ | |
| 2747 unsigned int i = 0; | |
| 2748 if( aData==0 ) return; | |
| 2749 #if SHA3_BYTEORDER==1234 | |
| 2750 if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){ | |
| 2751 for(; i+7<nData; i+=8){ | |
| 2752 p->u.s[p->nLoaded/8] ^= *(u64*)&aData[i]; | |
| 2753 p->nLoaded += 8; | |
| 2754 if( p->nLoaded>=p->nRate ){ | |
| 2755 KeccakF1600Step(p); | |
| 2756 p->nLoaded = 0; | |
| 2757 } | |
| 2758 } | |
| 2759 } | |
| 2760 #endif | |
| 2761 for(; i<nData; i++){ | |
| 2762 #if SHA3_BYTEORDER==1234 | |
| 2763 p->u.x[p->nLoaded] ^= aData[i]; | |
| 2764 #elif SHA3_BYTEORDER==4321 | |
| 2765 p->u.x[p->nLoaded^0x07] ^= aData[i]; | |
| 2766 #else | |
| 2767 p->u.x[p->nLoaded^p->ixMask] ^= aData[i]; | |
| 2768 #endif | |
| 2769 p->nLoaded++; | |
| 2770 if( p->nLoaded==p->nRate ){ | |
| 2771 KeccakF1600Step(p); | |
| 2772 p->nLoaded = 0; | |
| 2773 } | |
| 2774 } | |
| 2775 } | |
| 2776 | |
| 2777 /* | |
| 2778 ** After all content has been added, invoke SHA3Final() to compute | |
| 2779 ** the final hash. The function returns a pointer to the binary | |
| 2780 ** hash value. | |
| 2781 */ | |
| 2782 static unsigned char *SHA3Final(SHA3Context *p){ | |
| 2783 unsigned int i; | |
| 2784 if( p->nLoaded==p->nRate-1 ){ | |
| 2785 const unsigned char c1 = 0x86; | |
| 2786 SHA3Update(p, &c1, 1); | |
| 2787 }else{ | |
| 2788 const unsigned char c2 = 0x06; | |
| 2789 const unsigned char c3 = 0x80; | |
| 2790 SHA3Update(p, &c2, 1); | |
| 2791 p->nLoaded = p->nRate - 1; | |
| 2792 SHA3Update(p, &c3, 1); | |
| 2793 } | |
| 2794 for(i=0; i<p->nRate; i++){ | |
| 2795 p->u.x[i+p->nRate] = p->u.x[i^p->ixMask]; | |
| 2796 } | |
| 2797 return &p->u.x[p->nRate]; | |
| 2798 } | |
| 2799 /* End of the hashing logic | |
| 2800 *****************************************************************************/ | |
| 2801 | |
| 2802 /* | |
| 2803 ** Implementation of the sha3(X,SIZE) function. | |
| 2804 ** | |
| 2805 ** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default | |
| 2806 ** size is 256. If X is a BLOB, it is hashed as is. | |
| 2807 ** For all other non-NULL types of input, X is converted into a UTF-8 string | |
| 2808 ** and the string is hashed without the trailing 0x00 terminator. The hash | |
| 2809 ** of a NULL value is NULL. | |
| 2810 */ | |
| 2811 static void sha3Func( | |
| 2812 sqlite3_context *context, | |
| 2813 int argc, | |
| 2814 sqlite3_value **argv | |
| 2815 ){ | |
| 2816 SHA3Context cx; | |
| 2817 int eType = sqlite3_value_type(argv[0]); | |
| 2818 int nByte = sqlite3_value_bytes(argv[0]); | |
| 2819 int iSize; | |
| 2820 if( argc==1 ){ | |
| 2821 iSize = 256; | |
| 2822 }else{ | |
| 2823 iSize = sqlite3_value_int(argv[1]); | |
| 2824 if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ | |
| 2825 sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " | |
| 2826 "384 512", -1); | |
| 2827 return; | |
| 2828 } | |
| 2829 } | |
| 2830 if( eType==SQLITE_NULL ) return; | |
| 2831 SHA3Init(&cx, iSize); | |
| 2832 if( eType==SQLITE_BLOB ){ | |
| 2833 SHA3Update(&cx, sqlite3_value_blob(argv[0]), nByte); | |
| 2834 }else{ | |
| 2835 SHA3Update(&cx, sqlite3_value_text(argv[0]), nByte); | |
| 2836 } | |
| 2837 sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); | |
| 2838 } | |
| 2839 | |
| 2840 /* Compute a string using sqlite3_vsnprintf() with a maximum length | |
| 2841 ** of 50 bytes and add it to the hash. | |
| 2842 */ | |
| 2843 static void sha3_step_vformat( | |
| 2844 SHA3Context *p, /* Add content to this context */ | |
| 2845 const char *zFormat, | |
| 2846 ... | |
| 2847 ){ | |
| 2848 va_list ap; | |
| 2849 int n; | |
| 2850 char zBuf[50]; | |
| 2851 va_start(ap, zFormat); | |
| 2852 sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); | |
| 2853 va_end(ap); | |
| 2854 n = (int)strlen(zBuf); | |
| 2855 SHA3Update(p, (unsigned char*)zBuf, n); | |
| 2856 } | |
| 2857 | |
| 2858 /* | |
| 2859 ** Update a SHA3Context using a single sqlite3_value. | |
| 2860 */ | |
| 2861 static void sha3UpdateFromValue(SHA3Context *p, sqlite3_value *pVal){ | |
| 2862 switch( sqlite3_value_type(pVal) ){ | |
| 2863 case SQLITE_NULL: { | |
| 2864 SHA3Update(p, (const unsigned char*)"N",1); | |
| 2865 break; | |
| 2866 } | |
| 2867 case SQLITE_INTEGER: { | |
| 2868 sqlite3_uint64 u; | |
| 2869 int j; | |
| 2870 unsigned char x[9]; | |
| 2871 sqlite3_int64 v = sqlite3_value_int64(pVal); | |
| 2872 memcpy(&u, &v, 8); | |
| 2873 for(j=8; j>=1; j--){ | |
| 2874 x[j] = u & 0xff; | |
| 2875 u >>= 8; | |
| 2876 } | |
| 2877 x[0] = 'I'; | |
| 2878 SHA3Update(p, x, 9); | |
| 2879 break; | |
| 2880 } | |
| 2881 case SQLITE_FLOAT: { | |
| 2882 sqlite3_uint64 u; | |
| 2883 int j; | |
| 2884 unsigned char x[9]; | |
| 2885 double r = sqlite3_value_double(pVal); | |
| 2886 memcpy(&u, &r, 8); | |
| 2887 for(j=8; j>=1; j--){ | |
| 2888 x[j] = u & 0xff; | |
| 2889 u >>= 8; | |
| 2890 } | |
| 2891 x[0] = 'F'; | |
| 2892 SHA3Update(p,x,9); | |
| 2893 break; | |
| 2894 } | |
| 2895 case SQLITE_TEXT: { | |
| 2896 int n2 = sqlite3_value_bytes(pVal); | |
| 2897 const unsigned char *z2 = sqlite3_value_text(pVal); | |
| 2898 sha3_step_vformat(p,"T%d:",n2); | |
| 2899 SHA3Update(p, z2, n2); | |
| 2900 break; | |
| 2901 } | |
| 2902 case SQLITE_BLOB: { | |
| 2903 int n2 = sqlite3_value_bytes(pVal); | |
| 2904 const unsigned char *z2 = sqlite3_value_blob(pVal); | |
| 2905 sha3_step_vformat(p,"B%d:",n2); | |
| 2906 SHA3Update(p, z2, n2); | |
| 2907 break; | |
| 2908 } | |
| 2909 } | |
| 2910 } | |
| 2911 | |
| 2912 /* | |
| 2913 ** Implementation of the sha3_query(SQL,SIZE) function. | |
| 2914 ** | |
| 2915 ** This function compiles and runs the SQL statement(s) given in the | |
| 2916 ** argument. The results are hashed using a SIZE-bit SHA3. The default | |
| 2917 ** size is 256. | |
| 2918 ** | |
| 2919 ** The format of the byte stream that is hashed is summarized as follows: | |
| 2920 ** | |
| 2921 ** S<n>:<sql> | |
| 2922 ** R | |
| 2923 ** N | |
| 2924 ** I<int> | |
| 2925 ** F<ieee-float> | |
| 2926 ** B<size>:<bytes> | |
| 2927 ** T<size>:<text> | |
| 2928 ** | |
| 2929 ** <sql> is the original SQL text for each statement run and <n> is | |
| 2930 ** the size of that text. The SQL text is UTF-8. A single R character | |
| 2931 ** occurs before the start of each row. N means a NULL value. | |
| 2932 ** I mean an 8-byte little-endian integer <int>. F is a floating point | |
| 2933 ** number with an 8-byte little-endian IEEE floating point value <ieee-float>. | |
| 2934 ** B means blobs of <size> bytes. T means text rendered as <size> | |
| 2935 ** bytes of UTF-8. The <n> and <size> values are expressed as an ASCII | |
| 2936 ** text integers. | |
| 2937 ** | |
| 2938 ** For each SQL statement in the X input, there is one S segment. Each | |
| 2939 ** S segment is followed by zero or more R segments, one for each row in the | |
| 2940 ** result set. After each R, there are one or more N, I, F, B, or T segments, | |
| 2941 ** one for each column in the result set. Segments are concatentated directly | |
| 2942 ** with no delimiters of any kind. | |
| 2943 */ | |
| 2944 static void sha3QueryFunc( | |
| 2945 sqlite3_context *context, | |
| 2946 int argc, | |
| 2947 sqlite3_value **argv | |
| 2948 ){ | |
| 2949 sqlite3 *db = sqlite3_context_db_handle(context); | |
| 2950 const char *zSql = (const char*)sqlite3_value_text(argv[0]); | |
| 2951 sqlite3_stmt *pStmt = 0; | |
| 2952 int nCol; /* Number of columns in the result set */ | |
| 2953 int i; /* Loop counter */ | |
| 2954 int rc; | |
| 2955 int n; | |
| 2956 const char *z; | |
| 2957 SHA3Context cx; | |
| 2958 int iSize; | |
| 2959 | |
| 2960 if( argc==1 ){ | |
| 2961 iSize = 256; | |
| 2962 }else{ | |
| 2963 iSize = sqlite3_value_int(argv[1]); | |
| 2964 if( iSize!=224 && iSize!=256 && iSize!=384 && iSize!=512 ){ | |
| 2965 sqlite3_result_error(context, "SHA3 size should be one of: 224 256 " | |
| 2966 "384 512", -1); | |
| 2967 return; | |
| 2968 } | |
| 2969 } | |
| 2970 if( zSql==0 ) return; | |
| 2971 SHA3Init(&cx, iSize); | |
| 2972 while( zSql[0] ){ | |
| 2973 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); | |
| 2974 if( rc ){ | |
| 2975 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", | |
| 2976 zSql, sqlite3_errmsg(db)); | |
| 2977 sqlite3_finalize(pStmt); | |
| 2978 sqlite3_result_error(context, zMsg, -1); | |
| 2979 sqlite3_free(zMsg); | |
| 2980 return; | |
| 2981 } | |
| 2982 if( !sqlite3_stmt_readonly(pStmt) ){ | |
| 2983 char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); | |
| 2984 sqlite3_finalize(pStmt); | |
| 2985 sqlite3_result_error(context, zMsg, -1); | |
| 2986 sqlite3_free(zMsg); | |
| 2987 return; | |
| 2988 } | |
| 2989 nCol = sqlite3_column_count(pStmt); | |
| 2990 z = sqlite3_sql(pStmt); | |
| 2991 if( z ){ | |
| 2992 n = (int)strlen(z); | |
| 2993 sha3_step_vformat(&cx,"S%d:",n); | |
| 2994 SHA3Update(&cx,(unsigned char*)z,n); | |
| 2995 } | |
| 2996 | |
| 2997 /* Compute a hash over the result of the query */ | |
| 2998 while( SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 2999 SHA3Update(&cx,(const unsigned char*)"R",1); | |
| 3000 for(i=0; i<nCol; i++){ | |
| 3001 sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i)); | |
| 3002 } | |
| 3003 } | |
| 3004 sqlite3_finalize(pStmt); | |
| 3005 } | |
| 3006 sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); | |
| 3007 } | |
| 3008 | |
| 3009 /* | |
| 3010 ** xStep function for sha3_agg(). | |
| 3011 */ | |
| 3012 static void sha3AggStep( | |
| 3013 sqlite3_context *context, | |
| 3014 int argc, | |
| 3015 sqlite3_value **argv | |
| 3016 ){ | |
| 3017 SHA3Context *p; | |
| 3018 p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p)); | |
| 3019 if( p==0 ) return; | |
| 3020 if( p->nRate==0 ){ | |
| 3021 int sz = 256; | |
| 3022 if( argc==2 ){ | |
| 3023 sz = sqlite3_value_int(argv[1]); | |
| 3024 if( sz!=224 && sz!=384 && sz!=512 ){ | |
| 3025 sz = 256; | |
| 3026 } | |
| 3027 } | |
| 3028 SHA3Init(p, sz); | |
| 3029 } | |
| 3030 sha3UpdateFromValue(p, argv[0]); | |
| 3031 } | |
| 3032 | |
| 3033 | |
| 3034 /* | |
| 3035 ** xFinal function for sha3_agg(). | |
| 3036 */ | |
| 3037 static void sha3AggFinal(sqlite3_context *context){ | |
| 3038 SHA3Context *p; | |
| 3039 p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p)); | |
| 3040 if( p==0 ) return; | |
| 3041 if( p->iSize ){ | |
| 3042 sqlite3_result_blob(context, SHA3Final(p), p->iSize/8, SQLITE_TRANSIENT); | |
| 3043 } | |
| 3044 } | |
| 3045 | |
| 3046 | |
| 3047 | |
| 3048 #ifdef _WIN32 | |
| 3049 | |
| 3050 #endif | |
| 3051 int sqlite3_shathree_init( | |
| 3052 sqlite3 *db, | |
| 3053 char **pzErrMsg, | |
| 3054 const sqlite3_api_routines *pApi | |
| 3055 ){ | |
| 3056 int rc = SQLITE_OK; | |
| 3057 SQLITE_EXTENSION_INIT2(pApi); | |
| 3058 (void)pzErrMsg; /* Unused parameter */ | |
| 3059 rc = sqlite3_create_function(db, "sha3", 1, | |
| 3060 SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, | |
| 3061 0, sha3Func, 0, 0); | |
| 3062 if( rc==SQLITE_OK ){ | |
| 3063 rc = sqlite3_create_function(db, "sha3", 2, | |
| 3064 SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, | |
| 3065 0, sha3Func, 0, 0); | |
| 3066 } | |
| 3067 if( rc==SQLITE_OK ){ | |
| 3068 rc = sqlite3_create_function(db, "sha3_agg", 1, | |
| 3069 SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, | |
| 3070 0, 0, sha3AggStep, sha3AggFinal); | |
| 3071 } | |
| 3072 if( rc==SQLITE_OK ){ | |
| 3073 rc = sqlite3_create_function(db, "sha3_agg", 2, | |
| 3074 SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, | |
| 3075 0, 0, sha3AggStep, sha3AggFinal); | |
| 3076 } | |
| 3077 if( rc==SQLITE_OK ){ | |
| 3078 rc = sqlite3_create_function(db, "sha3_query", 1, | |
| 3079 SQLITE_UTF8 | SQLITE_DIRECTONLY, | |
| 3080 0, sha3QueryFunc, 0, 0); | |
| 3081 } | |
| 3082 if( rc==SQLITE_OK ){ | |
| 3083 rc = sqlite3_create_function(db, "sha3_query", 2, | |
| 3084 SQLITE_UTF8 | SQLITE_DIRECTONLY, | |
| 3085 0, sha3QueryFunc, 0, 0); | |
| 3086 } | |
| 3087 return rc; | |
| 3088 } | |
| 3089 | |
| 3090 /************************* End ../ext/misc/shathree.c ********************/ | |
| 3091 /************************* Begin ../ext/misc/sha1.c ******************/ | |
| 3092 /* | |
| 3093 ** 2017-01-27 | |
| 3094 ** | |
| 3095 ** The author disclaims copyright to this source code. In place of | |
| 3096 ** a legal notice, here is a blessing: | |
| 3097 ** | |
| 3098 ** May you do good and not evil. | |
| 3099 ** May you find forgiveness for yourself and forgive others. | |
| 3100 ** May you share freely, never taking more than you give. | |
| 3101 ** | |
| 3102 ****************************************************************************** | |
| 3103 ** | |
| 3104 ** This SQLite extension implements functions that compute SHA1 hashes. | |
| 3105 ** Two SQL functions are implemented: | |
| 3106 ** | |
| 3107 ** sha1(X) | |
| 3108 ** sha1_query(Y) | |
| 3109 ** | |
| 3110 ** The sha1(X) function computes the SHA1 hash of the input X, or NULL if | |
| 3111 ** X is NULL. | |
| 3112 ** | |
| 3113 ** The sha1_query(Y) function evalutes all queries in the SQL statements of Y | |
| 3114 ** and returns a hash of their results. | |
| 3115 */ | |
| 3116 /* #include "sqlite3ext.h" */ | |
| 3117 SQLITE_EXTENSION_INIT1 | |
| 3118 #include <assert.h> | |
| 3119 #include <string.h> | |
| 3120 #include <stdarg.h> | |
| 3121 | |
| 3122 /****************************************************************************** | |
| 3123 ** The Hash Engine | |
| 3124 */ | |
| 3125 /* Context for the SHA1 hash */ | |
| 3126 typedef struct SHA1Context SHA1Context; | |
| 3127 struct SHA1Context { | |
| 3128 unsigned int state[5]; | |
| 3129 unsigned int count[2]; | |
| 3130 unsigned char buffer[64]; | |
| 3131 }; | |
| 3132 | |
| 3133 #define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) | |
| 3134 #define rol(x,k) SHA_ROT(x,k,32-(k)) | |
| 3135 #define ror(x,k) SHA_ROT(x,32-(k),k) | |
| 3136 | |
| 3137 #define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ | |
| 3138 |(rol(block[i],8)&0x00FF00FF)) | |
| 3139 #define blk0be(i) block[i] | |
| 3140 #define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ | |
| 3141 ^block[(i+2)&15]^block[i&15],1)) | |
| 3142 | |
| 3143 /* | |
| 3144 * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 | |
| 3145 * | |
| 3146 * Rl0() for little-endian and Rb0() for big-endian. Endianness is | |
| 3147 * determined at run-time. | |
| 3148 */ | |
| 3149 #define Rl0(v,w,x,y,z,i) \ | |
| 3150 z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); | |
| 3151 #define Rb0(v,w,x,y,z,i) \ | |
| 3152 z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); | |
| 3153 #define R1(v,w,x,y,z,i) \ | |
| 3154 z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); | |
| 3155 #define R2(v,w,x,y,z,i) \ | |
| 3156 z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); | |
| 3157 #define R3(v,w,x,y,z,i) \ | |
| 3158 z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); | |
| 3159 #define R4(v,w,x,y,z,i) \ | |
| 3160 z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); | |
| 3161 | |
| 3162 /* | |
| 3163 * Hash a single 512-bit block. This is the core of the algorithm. | |
| 3164 */ | |
| 3165 static void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){ | |
| 3166 unsigned int qq[5]; /* a, b, c, d, e; */ | |
| 3167 static int one = 1; | |
| 3168 unsigned int block[16]; | |
| 3169 memcpy(block, buffer, 64); | |
| 3170 memcpy(qq,state,5*sizeof(unsigned int)); | |
| 3171 | |
| 3172 #define a qq[0] | |
| 3173 #define b qq[1] | |
| 3174 #define c qq[2] | |
| 3175 #define d qq[3] | |
| 3176 #define e qq[4] | |
| 3177 | |
| 3178 /* Copy p->state[] to working vars */ | |
| 3179 /* | |
| 3180 a = state[0]; | |
| 3181 b = state[1]; | |
| 3182 c = state[2]; | |
| 3183 d = state[3]; | |
| 3184 e = state[4]; | |
| 3185 */ | |
| 3186 | |
| 3187 /* 4 rounds of 20 operations each. Loop unrolled. */ | |
| 3188 if( 1 == *(unsigned char*)&one ){ | |
| 3189 Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); | |
| 3190 Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); | |
| 3191 Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); | |
| 3192 Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); | |
| 3193 }else{ | |
| 3194 Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); | |
| 3195 Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); | |
| 3196 Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); | |
| 3197 Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); | |
| 3198 } | |
| 3199 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); | |
| 3200 R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); | |
| 3201 R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); | |
| 3202 R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); | |
| 3203 R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); | |
| 3204 R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); | |
| 3205 R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); | |
| 3206 R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); | |
| 3207 R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); | |
| 3208 R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); | |
| 3209 R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); | |
| 3210 R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); | |
| 3211 R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); | |
| 3212 R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); | |
| 3213 R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); | |
| 3214 R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); | |
| 3215 | |
| 3216 /* Add the working vars back into context.state[] */ | |
| 3217 state[0] += a; | |
| 3218 state[1] += b; | |
| 3219 state[2] += c; | |
| 3220 state[3] += d; | |
| 3221 state[4] += e; | |
| 3222 | |
| 3223 #undef a | |
| 3224 #undef b | |
| 3225 #undef c | |
| 3226 #undef d | |
| 3227 #undef e | |
| 3228 } | |
| 3229 | |
| 3230 | |
| 3231 /* Initialize a SHA1 context */ | |
| 3232 static void hash_init(SHA1Context *p){ | |
| 3233 /* SHA1 initialization constants */ | |
| 3234 p->state[0] = 0x67452301; | |
| 3235 p->state[1] = 0xEFCDAB89; | |
| 3236 p->state[2] = 0x98BADCFE; | |
| 3237 p->state[3] = 0x10325476; | |
| 3238 p->state[4] = 0xC3D2E1F0; | |
| 3239 p->count[0] = p->count[1] = 0; | |
| 3240 } | |
| 3241 | |
| 3242 /* Add new content to the SHA1 hash */ | |
| 3243 static void hash_step( | |
| 3244 SHA1Context *p, /* Add content to this context */ | |
| 3245 const unsigned char *data, /* Data to be added */ | |
| 3246 unsigned int len /* Number of bytes in data */ | |
| 3247 ){ | |
| 3248 unsigned int i, j; | |
| 3249 | |
| 3250 j = p->count[0]; | |
| 3251 if( (p->count[0] += len << 3) < j ){ | |
| 3252 p->count[1] += (len>>29)+1; | |
| 3253 } | |
| 3254 j = (j >> 3) & 63; | |
| 3255 if( (j + len) > 63 ){ | |
| 3256 (void)memcpy(&p->buffer[j], data, (i = 64-j)); | |
| 3257 SHA1Transform(p->state, p->buffer); | |
| 3258 for(; i + 63 < len; i += 64){ | |
| 3259 SHA1Transform(p->state, &data[i]); | |
| 3260 } | |
| 3261 j = 0; | |
| 3262 }else{ | |
| 3263 i = 0; | |
| 3264 } | |
| 3265 (void)memcpy(&p->buffer[j], &data[i], len - i); | |
| 3266 } | |
| 3267 | |
| 3268 /* Compute a string using sqlite3_vsnprintf() and hash it */ | |
| 3269 static void hash_step_vformat( | |
| 3270 SHA1Context *p, /* Add content to this context */ | |
| 3271 const char *zFormat, | |
| 3272 ... | |
| 3273 ){ | |
| 3274 va_list ap; | |
| 3275 int n; | |
| 3276 char zBuf[50]; | |
| 3277 va_start(ap, zFormat); | |
| 3278 sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); | |
| 3279 va_end(ap); | |
| 3280 n = (int)strlen(zBuf); | |
| 3281 hash_step(p, (unsigned char*)zBuf, n); | |
| 3282 } | |
| 3283 | |
| 3284 | |
| 3285 /* Add padding and compute the message digest. Render the | |
| 3286 ** message digest as lower-case hexadecimal and put it into | |
| 3287 ** zOut[]. zOut[] must be at least 41 bytes long. */ | |
| 3288 static void hash_finish( | |
| 3289 SHA1Context *p, /* The SHA1 context to finish and render */ | |
| 3290 char *zOut, /* Store hex or binary hash here */ | |
| 3291 int bAsBinary /* 1 for binary hash, 0 for hex hash */ | |
| 3292 ){ | |
| 3293 unsigned int i; | |
| 3294 unsigned char finalcount[8]; | |
| 3295 unsigned char digest[20]; | |
| 3296 static const char zEncode[] = "0123456789abcdef"; | |
| 3297 | |
| 3298 for (i = 0; i < 8; i++){ | |
| 3299 finalcount[i] = (unsigned char)((p->count[(i >= 4 ? 0 : 1)] | |
| 3300 >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ | |
| 3301 } | |
| 3302 hash_step(p, (const unsigned char *)"\200", 1); | |
| 3303 while ((p->count[0] & 504) != 448){ | |
| 3304 hash_step(p, (const unsigned char *)"\0", 1); | |
| 3305 } | |
| 3306 hash_step(p, finalcount, 8); /* Should cause a SHA1Transform() */ | |
| 3307 for (i = 0; i < 20; i++){ | |
| 3308 digest[i] = (unsigned char)((p->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); | |
| 3309 } | |
| 3310 if( bAsBinary ){ | |
| 3311 memcpy(zOut, digest, 20); | |
| 3312 }else{ | |
| 3313 for(i=0; i<20; i++){ | |
| 3314 zOut[i*2] = zEncode[(digest[i]>>4)&0xf]; | |
| 3315 zOut[i*2+1] = zEncode[digest[i] & 0xf]; | |
| 3316 } | |
| 3317 zOut[i*2]= 0; | |
| 3318 } | |
| 3319 } | |
| 3320 /* End of the hashing logic | |
| 3321 *****************************************************************************/ | |
| 3322 | |
| 3323 /* | |
| 3324 ** Implementation of the sha1(X) function. | |
| 3325 ** | |
| 3326 ** Return a lower-case hexadecimal rendering of the SHA1 hash of the | |
| 3327 ** argument X. If X is a BLOB, it is hashed as is. For all other | |
| 3328 ** types of input, X is converted into a UTF-8 string and the string | |
| 3329 ** is hash without the trailing 0x00 terminator. The hash of a NULL | |
| 3330 ** value is NULL. | |
| 3331 */ | |
| 3332 static void sha1Func( | |
| 3333 sqlite3_context *context, | |
| 3334 int argc, | |
| 3335 sqlite3_value **argv | |
| 3336 ){ | |
| 3337 SHA1Context cx; | |
| 3338 int eType = sqlite3_value_type(argv[0]); | |
| 3339 int nByte = sqlite3_value_bytes(argv[0]); | |
| 3340 char zOut[44]; | |
| 3341 | |
| 3342 assert( argc==1 ); | |
| 3343 if( eType==SQLITE_NULL ) return; | |
| 3344 hash_init(&cx); | |
| 3345 if( eType==SQLITE_BLOB ){ | |
| 3346 hash_step(&cx, sqlite3_value_blob(argv[0]), nByte); | |
| 3347 }else{ | |
| 3348 hash_step(&cx, sqlite3_value_text(argv[0]), nByte); | |
| 3349 } | |
| 3350 if( sqlite3_user_data(context)!=0 ){ | |
| 3351 hash_finish(&cx, zOut, 1); | |
| 3352 sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT); | |
| 3353 }else{ | |
| 3354 hash_finish(&cx, zOut, 0); | |
| 3355 sqlite3_result_blob(context, zOut, 40, SQLITE_TRANSIENT); | |
| 3356 } | |
| 3357 } | |
| 3358 | |
| 3359 /* | |
| 3360 ** Implementation of the sha1_query(SQL) function. | |
| 3361 ** | |
| 3362 ** This function compiles and runs the SQL statement(s) given in the | |
| 3363 ** argument. The results are hashed using SHA1 and that hash is returned. | |
| 3364 ** | |
| 3365 ** The original SQL text is included as part of the hash. | |
| 3366 ** | |
| 3367 ** The hash is not just a concatenation of the outputs. Each query | |
| 3368 ** is delimited and each row and value within the query is delimited, | |
| 3369 ** with all values being marked with their datatypes. | |
| 3370 */ | |
| 3371 static void sha1QueryFunc( | |
| 3372 sqlite3_context *context, | |
| 3373 int argc, | |
| 3374 sqlite3_value **argv | |
| 3375 ){ | |
| 3376 sqlite3 *db = sqlite3_context_db_handle(context); | |
| 3377 const char *zSql = (const char*)sqlite3_value_text(argv[0]); | |
| 3378 sqlite3_stmt *pStmt = 0; | |
| 3379 int nCol; /* Number of columns in the result set */ | |
| 3380 int i; /* Loop counter */ | |
| 3381 int rc; | |
| 3382 int n; | |
| 3383 const char *z; | |
| 3384 SHA1Context cx; | |
| 3385 char zOut[44]; | |
| 3386 | |
| 3387 assert( argc==1 ); | |
| 3388 if( zSql==0 ) return; | |
| 3389 hash_init(&cx); | |
| 3390 while( zSql[0] ){ | |
| 3391 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); | |
| 3392 if( rc ){ | |
| 3393 char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", | |
| 3394 zSql, sqlite3_errmsg(db)); | |
| 3395 sqlite3_finalize(pStmt); | |
| 3396 sqlite3_result_error(context, zMsg, -1); | |
| 3397 sqlite3_free(zMsg); | |
| 3398 return; | |
| 3399 } | |
| 3400 if( !sqlite3_stmt_readonly(pStmt) ){ | |
| 3401 char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); | |
| 3402 sqlite3_finalize(pStmt); | |
| 3403 sqlite3_result_error(context, zMsg, -1); | |
| 3404 sqlite3_free(zMsg); | |
| 3405 return; | |
| 3406 } | |
| 3407 nCol = sqlite3_column_count(pStmt); | |
| 3408 z = sqlite3_sql(pStmt); | |
| 3409 n = (int)strlen(z); | |
| 3410 hash_step_vformat(&cx,"S%d:",n); | |
| 3411 hash_step(&cx,(unsigned char*)z,n); | |
| 3412 | |
| 3413 /* Compute a hash over the result of the query */ | |
| 3414 while( SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 3415 hash_step(&cx,(const unsigned char*)"R",1); | |
| 3416 for(i=0; i<nCol; i++){ | |
| 3417 switch( sqlite3_column_type(pStmt,i) ){ | |
| 3418 case SQLITE_NULL: { | |
| 3419 hash_step(&cx, (const unsigned char*)"N",1); | |
| 3420 break; | |
| 3421 } | |
| 3422 case SQLITE_INTEGER: { | |
| 3423 sqlite3_uint64 u; | |
| 3424 int j; | |
| 3425 unsigned char x[9]; | |
| 3426 sqlite3_int64 v = sqlite3_column_int64(pStmt,i); | |
| 3427 memcpy(&u, &v, 8); | |
| 3428 for(j=8; j>=1; j--){ | |
| 3429 x[j] = u & 0xff; | |
| 3430 u >>= 8; | |
| 3431 } | |
| 3432 x[0] = 'I'; | |
| 3433 hash_step(&cx, x, 9); | |
| 3434 break; | |
| 3435 } | |
| 3436 case SQLITE_FLOAT: { | |
| 3437 sqlite3_uint64 u; | |
| 3438 int j; | |
| 3439 unsigned char x[9]; | |
| 3440 double r = sqlite3_column_double(pStmt,i); | |
| 3441 memcpy(&u, &r, 8); | |
| 3442 for(j=8; j>=1; j--){ | |
| 3443 x[j] = u & 0xff; | |
| 3444 u >>= 8; | |
| 3445 } | |
| 3446 x[0] = 'F'; | |
| 3447 hash_step(&cx,x,9); | |
| 3448 break; | |
| 3449 } | |
| 3450 case SQLITE_TEXT: { | |
| 3451 int n2 = sqlite3_column_bytes(pStmt, i); | |
| 3452 const unsigned char *z2 = sqlite3_column_text(pStmt, i); | |
| 3453 hash_step_vformat(&cx,"T%d:",n2); | |
| 3454 hash_step(&cx, z2, n2); | |
| 3455 break; | |
| 3456 } | |
| 3457 case SQLITE_BLOB: { | |
| 3458 int n2 = sqlite3_column_bytes(pStmt, i); | |
| 3459 const unsigned char *z2 = sqlite3_column_blob(pStmt, i); | |
| 3460 hash_step_vformat(&cx,"B%d:",n2); | |
| 3461 hash_step(&cx, z2, n2); | |
| 3462 break; | |
| 3463 } | |
| 3464 } | |
| 3465 } | |
| 3466 } | |
| 3467 sqlite3_finalize(pStmt); | |
| 3468 } | |
| 3469 hash_finish(&cx, zOut, 0); | |
| 3470 sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT); | |
| 3471 } | |
| 3472 | |
| 3473 | |
| 3474 #ifdef _WIN32 | |
| 3475 | |
| 3476 #endif | |
| 3477 int sqlite3_sha_init( | |
| 3478 sqlite3 *db, | |
| 3479 char **pzErrMsg, | |
| 3480 const sqlite3_api_routines *pApi | |
| 3481 ){ | |
| 3482 int rc = SQLITE_OK; | |
| 3483 static int one = 1; | |
| 3484 SQLITE_EXTENSION_INIT2(pApi); | |
| 3485 (void)pzErrMsg; /* Unused parameter */ | |
| 3486 rc = sqlite3_create_function(db, "sha1", 1, | |
| 3487 SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, | |
| 3488 0, sha1Func, 0, 0); | |
| 3489 if( rc==SQLITE_OK ){ | |
| 3490 rc = sqlite3_create_function(db, "sha1b", 1, | |
| 3491 SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, | |
| 3492 (void*)&one, sha1Func, 0, 0); | |
| 3493 } | |
| 3494 if( rc==SQLITE_OK ){ | |
| 3495 rc = sqlite3_create_function(db, "sha1_query", 1, | |
| 3496 SQLITE_UTF8|SQLITE_DIRECTONLY, 0, | |
| 3497 sha1QueryFunc, 0, 0); | |
| 3498 } | |
| 3499 return rc; | |
| 3500 } | |
| 3501 | |
| 3502 /************************* End ../ext/misc/sha1.c ********************/ | |
| 3503 /************************* Begin ../ext/misc/uint.c ******************/ | |
| 3504 /* | |
| 3505 ** 2020-04-14 | |
| 3506 ** | |
| 3507 ** The author disclaims copyright to this source code. In place of | |
| 3508 ** a legal notice, here is a blessing: | |
| 3509 ** | |
| 3510 ** May you do good and not evil. | |
| 3511 ** May you find forgiveness for yourself and forgive others. | |
| 3512 ** May you share freely, never taking more than you give. | |
| 3513 ** | |
| 3514 ****************************************************************************** | |
| 3515 ** | |
| 3516 ** This SQLite extension implements the UINT collating sequence. | |
| 3517 ** | |
| 3518 ** UINT works like BINARY for text, except that embedded strings | |
| 3519 ** of digits compare in numeric order. | |
| 3520 ** | |
| 3521 ** * Leading zeros are handled properly, in the sense that | |
| 3522 ** they do not mess of the magnitude comparison of embedded | |
| 3523 ** strings of digits. "x00123y" is equal to "x123y". | |
| 3524 ** | |
| 3525 ** * Only unsigned integers are recognized. Plus and minus | |
| 3526 ** signs are ignored. Decimal points and exponential notation | |
| 3527 ** are ignored. | |
| 3528 ** | |
| 3529 ** * Embedded integers can be of arbitrary length. Comparison | |
| 3530 ** is *not* limited integers that can be expressed as a | |
| 3531 ** 64-bit machine integer. | |
| 3532 */ | |
| 3533 /* #include "sqlite3ext.h" */ | |
| 3534 SQLITE_EXTENSION_INIT1 | |
| 3535 #include <assert.h> | |
| 3536 #include <string.h> | |
| 3537 #include <ctype.h> | |
| 3538 | |
| 3539 /* | |
| 3540 ** Compare text in lexicographic order, except strings of digits | |
| 3541 ** compare in numeric order. | |
| 3542 */ | |
| 3543 static int uintCollFunc( | |
| 3544 void *notUsed, | |
| 3545 int nKey1, const void *pKey1, | |
| 3546 int nKey2, const void *pKey2 | |
| 3547 ){ | |
| 3548 const unsigned char *zA = (const unsigned char*)pKey1; | |
| 3549 const unsigned char *zB = (const unsigned char*)pKey2; | |
| 3550 int i=0, j=0, x; | |
| 3551 (void)notUsed; | |
| 3552 while( i<nKey1 && j<nKey2 ){ | |
| 3553 x = zA[i] - zB[j]; | |
| 3554 if( isdigit(zA[i]) ){ | |
| 3555 int k; | |
| 3556 if( !isdigit(zB[j]) ) return x; | |
| 3557 while( i<nKey1 && zA[i]=='0' ){ i++; } | |
| 3558 while( j<nKey2 && zB[j]=='0' ){ j++; } | |
| 3559 k = 0; | |
| 3560 while( i+k<nKey1 && isdigit(zA[i+k]) | |
| 3561 && j+k<nKey2 && isdigit(zB[j+k]) ){ | |
| 3562 k++; | |
| 3563 } | |
| 3564 if( i+k<nKey1 && isdigit(zA[i+k]) ){ | |
| 3565 return +1; | |
| 3566 }else if( j+k<nKey2 && isdigit(zB[j+k]) ){ | |
| 3567 return -1; | |
| 3568 }else{ | |
| 3569 x = memcmp(zA+i, zB+j, k); | |
| 3570 if( x ) return x; | |
| 3571 i += k; | |
| 3572 j += k; | |
| 3573 } | |
| 3574 }else if( x ){ | |
| 3575 return x; | |
| 3576 }else{ | |
| 3577 i++; | |
| 3578 j++; | |
| 3579 } | |
| 3580 } | |
| 3581 return (nKey1 - i) - (nKey2 - j); | |
| 3582 } | |
| 3583 | |
| 3584 #ifdef _WIN32 | |
| 3585 | |
| 3586 #endif | |
| 3587 int sqlite3_uint_init( | |
| 3588 sqlite3 *db, | |
| 3589 char **pzErrMsg, | |
| 3590 const sqlite3_api_routines *pApi | |
| 3591 ){ | |
| 3592 SQLITE_EXTENSION_INIT2(pApi); | |
| 3593 (void)pzErrMsg; /* Unused parameter */ | |
| 3594 return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc); | |
| 3595 } | |
| 3596 | |
| 3597 /************************* End ../ext/misc/uint.c ********************/ | |
| 3598 /************************* Begin ../ext/misc/decimal.c ******************/ | |
| 3599 /* | |
| 3600 ** 2020-06-22 | |
| 3601 ** | |
| 3602 ** The author disclaims copyright to this source code. In place of | |
| 3603 ** a legal notice, here is a blessing: | |
| 3604 ** | |
| 3605 ** May you do good and not evil. | |
| 3606 ** May you find forgiveness for yourself and forgive others. | |
| 3607 ** May you share freely, never taking more than you give. | |
| 3608 ** | |
| 3609 ****************************************************************************** | |
| 3610 ** | |
| 3611 ** Routines to implement arbitrary-precision decimal math. | |
| 3612 ** | |
| 3613 ** The focus here is on simplicity and correctness, not performance. | |
| 3614 */ | |
| 3615 /* #include "sqlite3ext.h" */ | |
| 3616 SQLITE_EXTENSION_INIT1 | |
| 3617 #include <assert.h> | |
| 3618 #include <string.h> | |
| 3619 #include <ctype.h> | |
| 3620 #include <stdlib.h> | |
| 3621 | |
| 3622 /* Mark a function parameter as unused, to suppress nuisance compiler | |
| 3623 ** warnings. */ | |
| 3624 #ifndef UNUSED_PARAMETER | |
| 3625 # define UNUSED_PARAMETER(X) (void)(X) | |
| 3626 #endif | |
| 3627 | |
| 3628 #ifndef IsSpace | |
| 3629 #define IsSpace(X) isspace((unsigned char)X) | |
| 3630 #endif | |
| 3631 | |
| 3632 /* A decimal object */ | |
| 3633 typedef struct Decimal Decimal; | |
| 3634 struct Decimal { | |
| 3635 char sign; /* 0 for positive, 1 for negative */ | |
| 3636 char oom; /* True if an OOM is encountered */ | |
| 3637 char isNull; /* True if holds a NULL rather than a number */ | |
| 3638 char isInit; /* True upon initialization */ | |
| 3639 int nDigit; /* Total number of digits */ | |
| 3640 int nFrac; /* Number of digits to the right of the decimal point */ | |
| 3641 signed char *a; /* Array of digits. Most significant first. */ | |
| 3642 }; | |
| 3643 | |
| 3644 /* | |
| 3645 ** Release memory held by a Decimal, but do not free the object itself. | |
| 3646 */ | |
| 3647 static void decimal_clear(Decimal *p){ | |
| 3648 sqlite3_free(p->a); | |
| 3649 } | |
| 3650 | |
| 3651 /* | |
| 3652 ** Destroy a Decimal object | |
| 3653 */ | |
| 3654 static void decimal_free(Decimal *p){ | |
| 3655 if( p ){ | |
| 3656 decimal_clear(p); | |
| 3657 sqlite3_free(p); | |
| 3658 } | |
| 3659 } | |
| 3660 | |
| 3661 /* | |
| 3662 ** Allocate a new Decimal object initialized to the text in zIn[]. | |
| 3663 ** Return NULL if any kind of error occurs. | |
| 3664 */ | |
| 3665 static Decimal *decimalNewFromText(const char *zIn, int n){ | |
| 3666 Decimal *p = 0; | |
| 3667 int i; | |
| 3668 int iExp = 0; | |
| 3669 | |
| 3670 p = sqlite3_malloc( sizeof(*p) ); | |
| 3671 if( p==0 ) goto new_from_text_failed; | |
| 3672 p->sign = 0; | |
| 3673 p->oom = 0; | |
| 3674 p->isInit = 1; | |
| 3675 p->isNull = 0; | |
| 3676 p->nDigit = 0; | |
| 3677 p->nFrac = 0; | |
| 3678 p->a = sqlite3_malloc64( n+1 ); | |
| 3679 if( p->a==0 ) goto new_from_text_failed; | |
| 3680 for(i=0; IsSpace(zIn[i]); i++){} | |
| 3681 if( zIn[i]=='-' ){ | |
| 3682 p->sign = 1; | |
| 3683 i++; | |
| 3684 }else if( zIn[i]=='+' ){ | |
| 3685 i++; | |
| 3686 } | |
| 3687 while( i<n && zIn[i]=='0' ) i++; | |
| 3688 while( i<n ){ | |
| 3689 char c = zIn[i]; | |
| 3690 if( c>='0' && c<='9' ){ | |
| 3691 p->a[p->nDigit++] = c - '0'; | |
| 3692 }else if( c=='.' ){ | |
| 3693 p->nFrac = p->nDigit + 1; | |
| 3694 }else if( c=='e' || c=='E' ){ | |
| 3695 int j = i+1; | |
| 3696 int neg = 0; | |
| 3697 if( j>=n ) break; | |
| 3698 if( zIn[j]=='-' ){ | |
| 3699 neg = 1; | |
| 3700 j++; | |
| 3701 }else if( zIn[j]=='+' ){ | |
| 3702 j++; | |
| 3703 } | |
| 3704 while( j<n && iExp<1000000 ){ | |
| 3705 if( zIn[j]>='0' && zIn[j]<='9' ){ | |
| 3706 iExp = iExp*10 + zIn[j] - '0'; | |
| 3707 } | |
| 3708 j++; | |
| 3709 } | |
| 3710 if( neg ) iExp = -iExp; | |
| 3711 break; | |
| 3712 } | |
| 3713 i++; | |
| 3714 } | |
| 3715 if( p->nFrac ){ | |
| 3716 p->nFrac = p->nDigit - (p->nFrac - 1); | |
| 3717 } | |
| 3718 if( iExp>0 ){ | |
| 3719 if( p->nFrac>0 ){ | |
| 3720 if( iExp<=p->nFrac ){ | |
| 3721 p->nFrac -= iExp; | |
| 3722 iExp = 0; | |
| 3723 }else{ | |
| 3724 iExp -= p->nFrac; | |
| 3725 p->nFrac = 0; | |
| 3726 } | |
| 3727 } | |
| 3728 if( iExp>0 ){ | |
| 3729 p->a = sqlite3_realloc64(p->a, (sqlite3_int64)p->nDigit | |
| 3730 + (sqlite3_int64)iExp + 1 ); | |
| 3731 if( p->a==0 ) goto new_from_text_failed; | |
| 3732 memset(p->a+p->nDigit, 0, iExp); | |
| 3733 p->nDigit += iExp; | |
| 3734 } | |
| 3735 }else if( iExp<0 ){ | |
| 3736 int nExtra; | |
| 3737 iExp = -iExp; | |
| 3738 nExtra = p->nDigit - p->nFrac - 1; | |
| 3739 if( nExtra ){ | |
| 3740 if( nExtra>=iExp ){ | |
| 3741 p->nFrac += iExp; | |
| 3742 iExp = 0; | |
| 3743 }else{ | |
| 3744 iExp -= nExtra; | |
| 3745 p->nFrac = p->nDigit - 1; | |
| 3746 } | |
| 3747 } | |
| 3748 if( iExp>0 ){ | |
| 3749 p->a = sqlite3_realloc64(p->a, (sqlite3_int64)p->nDigit | |
| 3750 + (sqlite3_int64)iExp + 1 ); | |
| 3751 if( p->a==0 ) goto new_from_text_failed; | |
| 3752 memmove(p->a+iExp, p->a, p->nDigit); | |
| 3753 memset(p->a, 0, iExp); | |
| 3754 p->nDigit += iExp; | |
| 3755 p->nFrac += iExp; | |
| 3756 } | |
| 3757 } | |
| 3758 if( p->sign ){ | |
| 3759 for(i=0; i<p->nDigit && p->a[i]==0; i++){} | |
| 3760 if( i>=p->nDigit ) p->sign = 0; | |
| 3761 } | |
| 3762 return p; | |
| 3763 | |
| 3764 new_from_text_failed: | |
| 3765 if( p ){ | |
| 3766 if( p->a ) sqlite3_free(p->a); | |
| 3767 sqlite3_free(p); | |
| 3768 } | |
| 3769 return 0; | |
| 3770 } | |
| 3771 | |
| 3772 /* Forward reference */ | |
| 3773 static Decimal *decimalFromDouble(double); | |
| 3774 | |
| 3775 /* | |
| 3776 ** Allocate a new Decimal object from an sqlite3_value. Return a pointer | |
| 3777 ** to the new object, or NULL if there is an error. If the pCtx argument | |
| 3778 ** is not NULL, then errors are reported on it as well. | |
| 3779 ** | |
| 3780 ** If the pIn argument is SQLITE_TEXT or SQLITE_INTEGER, it is converted | |
| 3781 ** directly into a Decimal. For SQLITE_FLOAT or for SQLITE_BLOB of length | |
| 3782 ** 8 bytes, the resulting double value is expanded into its decimal equivalent. | |
| 3783 ** If pIn is NULL or if it is a BLOB that is not exactly 8 bytes in length, | |
| 3784 ** then NULL is returned. | |
| 3785 */ | |
| 3786 static Decimal *decimal_new( | |
| 3787 sqlite3_context *pCtx, /* Report error here, if not null */ | |
| 3788 sqlite3_value *pIn, /* Construct the decimal object from this */ | |
| 3789 int bTextOnly /* Always interpret pIn as text if true */ | |
| 3790 ){ | |
| 3791 Decimal *p = 0; | |
| 3792 int eType = sqlite3_value_type(pIn); | |
| 3793 if( bTextOnly && (eType==SQLITE_FLOAT || eType==SQLITE_BLOB) ){ | |
| 3794 eType = SQLITE_TEXT; | |
| 3795 } | |
| 3796 switch( eType ){ | |
| 3797 case SQLITE_TEXT: | |
| 3798 case SQLITE_INTEGER: { | |
| 3799 const char *zIn = (const char*)sqlite3_value_text(pIn); | |
| 3800 int n = sqlite3_value_bytes(pIn); | |
| 3801 p = decimalNewFromText(zIn, n); | |
| 3802 if( p==0 ) goto new_failed; | |
| 3803 break; | |
| 3804 } | |
| 3805 | |
| 3806 case SQLITE_FLOAT: { | |
| 3807 p = decimalFromDouble(sqlite3_value_double(pIn)); | |
| 3808 break; | |
| 3809 } | |
| 3810 | |
| 3811 case SQLITE_BLOB: { | |
| 3812 const unsigned char *x; | |
| 3813 unsigned int i; | |
| 3814 sqlite3_uint64 v = 0; | |
| 3815 double r; | |
| 3816 | |
| 3817 if( sqlite3_value_bytes(pIn)!=sizeof(r) ) break; | |
| 3818 x = sqlite3_value_blob(pIn); | |
| 3819 for(i=0; i<sizeof(r); i++){ | |
| 3820 v = (v<<8) | x[i]; | |
| 3821 } | |
| 3822 memcpy(&r, &v, sizeof(r)); | |
| 3823 p = decimalFromDouble(r); | |
| 3824 break; | |
| 3825 } | |
| 3826 | |
| 3827 case SQLITE_NULL: { | |
| 3828 break; | |
| 3829 } | |
| 3830 } | |
| 3831 return p; | |
| 3832 | |
| 3833 new_failed: | |
| 3834 if( pCtx ) sqlite3_result_error_nomem(pCtx); | |
| 3835 sqlite3_free(p); | |
| 3836 return 0; | |
| 3837 } | |
| 3838 | |
| 3839 /* | |
| 3840 ** Make the given Decimal the result. | |
| 3841 */ | |
| 3842 static void decimal_result(sqlite3_context *pCtx, Decimal *p){ | |
| 3843 char *z; | |
| 3844 int i, j; | |
| 3845 int n; | |
| 3846 if( p==0 || p->oom ){ | |
| 3847 sqlite3_result_error_nomem(pCtx); | |
| 3848 return; | |
| 3849 } | |
| 3850 if( p->isNull ){ | |
| 3851 sqlite3_result_null(pCtx); | |
| 3852 return; | |
| 3853 } | |
| 3854 z = sqlite3_malloc64( (sqlite3_int64)p->nDigit+4 ); | |
| 3855 if( z==0 ){ | |
| 3856 sqlite3_result_error_nomem(pCtx); | |
| 3857 return; | |
| 3858 } | |
| 3859 i = 0; | |
| 3860 if( p->nDigit==0 || (p->nDigit==1 && p->a[0]==0) ){ | |
| 3861 p->sign = 0; | |
| 3862 } | |
| 3863 if( p->sign ){ | |
| 3864 z[0] = '-'; | |
| 3865 i = 1; | |
| 3866 } | |
| 3867 n = p->nDigit - p->nFrac; | |
| 3868 if( n<=0 ){ | |
| 3869 z[i++] = '0'; | |
| 3870 } | |
| 3871 j = 0; | |
| 3872 while( n>1 && p->a[j]==0 ){ | |
| 3873 j++; | |
| 3874 n--; | |
| 3875 } | |
| 3876 while( n>0 ){ | |
| 3877 z[i++] = p->a[j] + '0'; | |
| 3878 j++; | |
| 3879 n--; | |
| 3880 } | |
| 3881 if( p->nFrac ){ | |
| 3882 z[i++] = '.'; | |
| 3883 do{ | |
| 3884 z[i++] = p->a[j] + '0'; | |
| 3885 j++; | |
| 3886 }while( j<p->nDigit ); | |
| 3887 } | |
| 3888 z[i] = 0; | |
| 3889 sqlite3_result_text(pCtx, z, i, sqlite3_free); | |
| 3890 } | |
| 3891 | |
| 3892 /* | |
| 3893 ** Make the given Decimal the result in an format similar to '%+#e'. | |
| 3894 ** In other words, show exponential notation with leading and trailing | |
| 3895 ** zeros omitted. | |
| 3896 */ | |
| 3897 static void decimal_result_sci(sqlite3_context *pCtx, Decimal *p){ | |
| 3898 char *z; /* The output buffer */ | |
| 3899 int i; /* Loop counter */ | |
| 3900 int nZero; /* Number of leading zeros */ | |
| 3901 int nDigit; /* Number of digits not counting trailing zeros */ | |
| 3902 int nFrac; /* Digits to the right of the decimal point */ | |
| 3903 int exp; /* Exponent value */ | |
| 3904 signed char zero; /* Zero value */ | |
| 3905 signed char *a; /* Array of digits */ | |
| 3906 | |
| 3907 if( p==0 || p->oom ){ | |
| 3908 sqlite3_result_error_nomem(pCtx); | |
| 3909 return; | |
| 3910 } | |
| 3911 if( p->isNull ){ | |
| 3912 sqlite3_result_null(pCtx); | |
| 3913 return; | |
| 3914 } | |
| 3915 for(nDigit=p->nDigit; nDigit>0 && p->a[nDigit-1]==0; nDigit--){} | |
| 3916 for(nZero=0; nZero<nDigit && p->a[nZero]==0; nZero++){} | |
| 3917 nFrac = p->nFrac + (nDigit - p->nDigit); | |
| 3918 nDigit -= nZero; | |
| 3919 z = sqlite3_malloc64( (sqlite3_int64)nDigit+20 ); | |
| 3920 if( z==0 ){ | |
| 3921 sqlite3_result_error_nomem(pCtx); | |
| 3922 return; | |
| 3923 } | |
| 3924 if( nDigit==0 ){ | |
| 3925 zero = 0; | |
| 3926 a = &zero; | |
| 3927 nDigit = 1; | |
| 3928 nFrac = 0; | |
| 3929 }else{ | |
| 3930 a = &p->a[nZero]; | |
| 3931 } | |
| 3932 if( p->sign && nDigit>0 ){ | |
| 3933 z[0] = '-'; | |
| 3934 }else{ | |
| 3935 z[0] = '+'; | |
| 3936 } | |
| 3937 z[1] = a[0]+'0'; | |
| 3938 z[2] = '.'; | |
| 3939 if( nDigit==1 ){ | |
| 3940 z[3] = '0'; | |
| 3941 i = 4; | |
| 3942 }else{ | |
| 3943 for(i=1; i<nDigit; i++){ | |
| 3944 z[2+i] = a[i]+'0'; | |
| 3945 } | |
| 3946 i = nDigit+2; | |
| 3947 } | |
| 3948 exp = nDigit - nFrac - 1; | |
| 3949 sqlite3_snprintf(nDigit+20-i, &z[i], "e%+03d", exp); | |
| 3950 sqlite3_result_text(pCtx, z, -1, sqlite3_free); | |
| 3951 } | |
| 3952 | |
| 3953 /* | |
| 3954 ** Compare to Decimal objects. Return negative, 0, or positive if the | |
| 3955 ** first object is less than, equal to, or greater than the second. | |
| 3956 ** | |
| 3957 ** Preconditions for this routine: | |
| 3958 ** | |
| 3959 ** pA!=0 | |
| 3960 ** pA->isNull==0 | |
| 3961 ** pB!=0 | |
| 3962 ** pB->isNull==0 | |
| 3963 */ | |
| 3964 static int decimal_cmp(Decimal *pA, Decimal *pB){ | |
| 3965 int nASig, nBSig, rc, n; | |
| 3966 while( pA->nFrac>0 && pA->a[pA->nDigit-1]==0 ){ | |
| 3967 pA->nDigit--; | |
| 3968 pA->nFrac--; | |
| 3969 } | |
| 3970 while( pB->nFrac>0 && pB->a[pB->nDigit-1]==0 ){ | |
| 3971 pB->nDigit--; | |
| 3972 pB->nFrac--; | |
| 3973 } | |
| 3974 if( pA->sign!=pB->sign ){ | |
| 3975 return pA->sign ? -1 : +1; | |
| 3976 } | |
| 3977 if( pA->sign ){ | |
| 3978 Decimal *pTemp = pA; | |
| 3979 pA = pB; | |
| 3980 pB = pTemp; | |
| 3981 } | |
| 3982 nASig = pA->nDigit - pA->nFrac; | |
| 3983 nBSig = pB->nDigit - pB->nFrac; | |
| 3984 if( nASig!=nBSig ){ | |
| 3985 return nASig - nBSig; | |
| 3986 } | |
| 3987 n = pA->nDigit; | |
| 3988 if( n>pB->nDigit ) n = pB->nDigit; | |
| 3989 rc = memcmp(pA->a, pB->a, n); | |
| 3990 if( rc==0 ){ | |
| 3991 rc = pA->nDigit - pB->nDigit; | |
| 3992 } | |
| 3993 return rc; | |
| 3994 } | |
| 3995 | |
| 3996 /* | |
| 3997 ** SQL Function: decimal_cmp(X, Y) | |
| 3998 ** | |
| 3999 ** Return negative, zero, or positive if X is less then, equal to, or | |
| 4000 ** greater than Y. | |
| 4001 */ | |
| 4002 static void decimalCmpFunc( | |
| 4003 sqlite3_context *context, | |
| 4004 int argc, | |
| 4005 sqlite3_value **argv | |
| 4006 ){ | |
| 4007 Decimal *pA = 0, *pB = 0; | |
| 4008 int rc; | |
| 4009 | |
| 4010 UNUSED_PARAMETER(argc); | |
| 4011 pA = decimal_new(context, argv[0], 1); | |
| 4012 if( pA==0 || pA->isNull ) goto cmp_done; | |
| 4013 pB = decimal_new(context, argv[1], 1); | |
| 4014 if( pB==0 || pB->isNull ) goto cmp_done; | |
| 4015 rc = decimal_cmp(pA, pB); | |
| 4016 if( rc<0 ) rc = -1; | |
| 4017 else if( rc>0 ) rc = +1; | |
| 4018 sqlite3_result_int(context, rc); | |
| 4019 cmp_done: | |
| 4020 decimal_free(pA); | |
| 4021 decimal_free(pB); | |
| 4022 } | |
| 4023 | |
| 4024 /* | |
| 4025 ** Expand the Decimal so that it has a least nDigit digits and nFrac | |
| 4026 ** digits to the right of the decimal point. | |
| 4027 */ | |
| 4028 static void decimal_expand(Decimal *p, int nDigit, int nFrac){ | |
| 4029 int nAddSig; | |
| 4030 int nAddFrac; | |
| 4031 if( p==0 ) return; | |
| 4032 nAddFrac = nFrac - p->nFrac; | |
| 4033 nAddSig = (nDigit - p->nDigit) - nAddFrac; | |
| 4034 if( nAddFrac==0 && nAddSig==0 ) return; | |
| 4035 p->a = sqlite3_realloc64(p->a, nDigit+1); | |
| 4036 if( p->a==0 ){ | |
| 4037 p->oom = 1; | |
| 4038 return; | |
| 4039 } | |
| 4040 if( nAddSig ){ | |
| 4041 memmove(p->a+nAddSig, p->a, p->nDigit); | |
| 4042 memset(p->a, 0, nAddSig); | |
| 4043 p->nDigit += nAddSig; | |
| 4044 } | |
| 4045 if( nAddFrac ){ | |
| 4046 memset(p->a+p->nDigit, 0, nAddFrac); | |
| 4047 p->nDigit += nAddFrac; | |
| 4048 p->nFrac += nAddFrac; | |
| 4049 } | |
| 4050 } | |
| 4051 | |
| 4052 /* | |
| 4053 ** Add the value pB into pA. A := A + B. | |
| 4054 ** | |
| 4055 ** Both pA and pB might become denormalized by this routine. | |
| 4056 */ | |
| 4057 static void decimal_add(Decimal *pA, Decimal *pB){ | |
| 4058 int nSig, nFrac, nDigit; | |
| 4059 int i, rc; | |
| 4060 if( pA==0 ){ | |
| 4061 return; | |
| 4062 } | |
| 4063 if( pA->oom || pB==0 || pB->oom ){ | |
| 4064 pA->oom = 1; | |
| 4065 return; | |
| 4066 } | |
| 4067 if( pA->isNull || pB->isNull ){ | |
| 4068 pA->isNull = 1; | |
| 4069 return; | |
| 4070 } | |
| 4071 nSig = pA->nDigit - pA->nFrac; | |
| 4072 if( nSig && pA->a[0]==0 ) nSig--; | |
| 4073 if( nSig<pB->nDigit-pB->nFrac ){ | |
| 4074 nSig = pB->nDigit - pB->nFrac; | |
| 4075 } | |
| 4076 nFrac = pA->nFrac; | |
| 4077 if( nFrac<pB->nFrac ) nFrac = pB->nFrac; | |
| 4078 nDigit = nSig + nFrac + 1; | |
| 4079 decimal_expand(pA, nDigit, nFrac); | |
| 4080 decimal_expand(pB, nDigit, nFrac); | |
| 4081 if( pA->oom || pB->oom ){ | |
| 4082 pA->oom = 1; | |
| 4083 }else{ | |
| 4084 if( pA->sign==pB->sign ){ | |
| 4085 int carry = 0; | |
| 4086 for(i=nDigit-1; i>=0; i--){ | |
| 4087 int x = pA->a[i] + pB->a[i] + carry; | |
| 4088 if( x>=10 ){ | |
| 4089 carry = 1; | |
| 4090 pA->a[i] = x - 10; | |
| 4091 }else{ | |
| 4092 carry = 0; | |
| 4093 pA->a[i] = x; | |
| 4094 } | |
| 4095 } | |
| 4096 }else{ | |
| 4097 signed char *aA, *aB; | |
| 4098 int borrow = 0; | |
| 4099 rc = memcmp(pA->a, pB->a, nDigit); | |
| 4100 if( rc<0 ){ | |
| 4101 aA = pB->a; | |
| 4102 aB = pA->a; | |
| 4103 pA->sign = !pA->sign; | |
| 4104 }else{ | |
| 4105 aA = pA->a; | |
| 4106 aB = pB->a; | |
| 4107 } | |
| 4108 for(i=nDigit-1; i>=0; i--){ | |
| 4109 int x = aA[i] - aB[i] - borrow; | |
| 4110 if( x<0 ){ | |
| 4111 pA->a[i] = x+10; | |
| 4112 borrow = 1; | |
| 4113 }else{ | |
| 4114 pA->a[i] = x; | |
| 4115 borrow = 0; | |
| 4116 } | |
| 4117 } | |
| 4118 } | |
| 4119 } | |
| 4120 } | |
| 4121 | |
| 4122 /* | |
| 4123 ** Multiply A by B. A := A * B | |
| 4124 ** | |
| 4125 ** All significant digits after the decimal point are retained. | |
| 4126 ** Trailing zeros after the decimal point are omitted as long as | |
| 4127 ** the number of digits after the decimal point is no less than | |
| 4128 ** either the number of digits in either input. | |
| 4129 */ | |
| 4130 static void decimalMul(Decimal *pA, Decimal *pB){ | |
| 4131 signed char *acc = 0; | |
| 4132 int i, j, k; | |
| 4133 int minFrac; | |
| 4134 | |
| 4135 if( pA==0 || pA->oom || pA->isNull | |
| 4136 || pB==0 || pB->oom || pB->isNull | |
| 4137 ){ | |
| 4138 goto mul_end; | |
| 4139 } | |
| 4140 acc = sqlite3_malloc64( (sqlite3_int64)pA->nDigit + | |
| 4141 (sqlite3_int64)pB->nDigit + 2 ); | |
| 4142 if( acc==0 ){ | |
| 4143 pA->oom = 1; | |
| 4144 goto mul_end; | |
| 4145 } | |
| 4146 memset(acc, 0, pA->nDigit + pB->nDigit + 2); | |
| 4147 minFrac = pA->nFrac; | |
| 4148 if( pB->nFrac<minFrac ) minFrac = pB->nFrac; | |
| 4149 for(i=pA->nDigit-1; i>=0; i--){ | |
| 4150 signed char f = pA->a[i]; | |
| 4151 int carry = 0, x; | |
| 4152 for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){ | |
| 4153 x = acc[k] + f*pB->a[j] + carry; | |
| 4154 acc[k] = x%10; | |
| 4155 carry = x/10; | |
| 4156 } | |
| 4157 x = acc[k] + carry; | |
| 4158 acc[k] = x%10; | |
| 4159 acc[k-1] += x/10; | |
| 4160 } | |
| 4161 sqlite3_free(pA->a); | |
| 4162 pA->a = acc; | |
| 4163 acc = 0; | |
| 4164 pA->nDigit += pB->nDigit + 2; | |
| 4165 pA->nFrac += pB->nFrac; | |
| 4166 pA->sign ^= pB->sign; | |
| 4167 while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){ | |
| 4168 pA->nFrac--; | |
| 4169 pA->nDigit--; | |
| 4170 } | |
| 4171 | |
| 4172 mul_end: | |
| 4173 sqlite3_free(acc); | |
| 4174 } | |
| 4175 | |
| 4176 /* | |
| 4177 ** Create a new Decimal object that contains an integer power of 2. | |
| 4178 */ | |
| 4179 static Decimal *decimalPow2(int N){ | |
| 4180 Decimal *pA = 0; /* The result to be returned */ | |
| 4181 Decimal *pX = 0; /* Multiplier */ | |
| 4182 if( N<-20000 || N>20000 ) goto pow2_fault; | |
| 4183 pA = decimalNewFromText("1.0", 3); | |
| 4184 if( pA==0 || pA->oom ) goto pow2_fault; | |
| 4185 if( N==0 ) return pA; | |
| 4186 if( N>0 ){ | |
| 4187 pX = decimalNewFromText("2.0", 3); | |
| 4188 }else{ | |
| 4189 N = -N; | |
| 4190 pX = decimalNewFromText("0.5", 3); | |
| 4191 } | |
| 4192 if( pX==0 || pX->oom ) goto pow2_fault; | |
| 4193 while( 1 /* Exit by break */ ){ | |
| 4194 if( N & 1 ){ | |
| 4195 decimalMul(pA, pX); | |
| 4196 if( pA->oom ) goto pow2_fault; | |
| 4197 } | |
| 4198 N >>= 1; | |
| 4199 if( N==0 ) break; | |
| 4200 decimalMul(pX, pX); | |
| 4201 } | |
| 4202 decimal_free(pX); | |
| 4203 return pA; | |
| 4204 | |
| 4205 pow2_fault: | |
| 4206 decimal_free(pA); | |
| 4207 decimal_free(pX); | |
| 4208 return 0; | |
| 4209 } | |
| 4210 | |
| 4211 /* | |
| 4212 ** Use an IEEE754 binary64 ("double") to generate a new Decimal object. | |
| 4213 */ | |
| 4214 static Decimal *decimalFromDouble(double r){ | |
| 4215 sqlite3_int64 m, a; | |
| 4216 int e; | |
| 4217 int isNeg; | |
| 4218 Decimal *pA; | |
| 4219 Decimal *pX; | |
| 4220 char zNum[100]; | |
| 4221 if( r<0.0 ){ | |
| 4222 isNeg = 1; | |
| 4223 r = -r; | |
| 4224 }else{ | |
| 4225 isNeg = 0; | |
| 4226 } | |
| 4227 memcpy(&a,&r,sizeof(a)); | |
| 4228 if( a==0 || a==(sqlite3_int64)0x8000000000000000LL){ | |
| 4229 e = 0; | |
| 4230 m = 0; | |
| 4231 }else{ | |
| 4232 e = a>>52; | |
| 4233 m = a & ((((sqlite3_int64)1)<<52)-1); | |
| 4234 if( e==0 ){ | |
| 4235 m <<= 1; | |
| 4236 }else{ | |
| 4237 m |= ((sqlite3_int64)1)<<52; | |
| 4238 } | |
| 4239 while( e<1075 && m>0 && (m&1)==0 ){ | |
| 4240 m >>= 1; | |
| 4241 e++; | |
| 4242 } | |
| 4243 if( isNeg ) m = -m; | |
| 4244 e = e - 1075; | |
| 4245 if( e>971 ){ | |
| 4246 return 0; /* A NaN or an Infinity */ | |
| 4247 } | |
| 4248 } | |
| 4249 | |
| 4250 /* At this point m is the integer significand and e is the exponent */ | |
| 4251 sqlite3_snprintf(sizeof(zNum), zNum, "%lld", m); | |
| 4252 pA = decimalNewFromText(zNum, (int)strlen(zNum)); | |
| 4253 pX = decimalPow2(e); | |
| 4254 decimalMul(pA, pX); | |
| 4255 decimal_free(pX); | |
| 4256 return pA; | |
| 4257 } | |
| 4258 | |
| 4259 /* | |
| 4260 ** SQL Function: decimal(X) | |
| 4261 ** OR: decimal_exp(X) | |
| 4262 ** | |
| 4263 ** Convert input X into decimal and then back into text. | |
| 4264 ** | |
| 4265 ** If X is originally a float, then a full decimal expansion of that floating | |
| 4266 ** point value is done. Or if X is an 8-byte blob, it is interpreted | |
| 4267 ** as a float and similarly expanded. | |
| 4268 ** | |
| 4269 ** The decimal_exp(X) function returns the result in exponential notation. | |
| 4270 ** decimal(X) returns a complete decimal, without the e+NNN at the end. | |
| 4271 */ | |
| 4272 static void decimalFunc( | |
| 4273 sqlite3_context *context, | |
| 4274 int argc, | |
| 4275 sqlite3_value **argv | |
| 4276 ){ | |
| 4277 Decimal *p = decimal_new(context, argv[0], 0); | |
| 4278 UNUSED_PARAMETER(argc); | |
| 4279 if( p ){ | |
| 4280 if( sqlite3_user_data(context)!=0 ){ | |
| 4281 decimal_result_sci(context, p); | |
| 4282 }else{ | |
| 4283 decimal_result(context, p); | |
| 4284 } | |
| 4285 decimal_free(p); | |
| 4286 } | |
| 4287 } | |
| 4288 | |
| 4289 /* | |
| 4290 ** Compare text in decimal order. | |
| 4291 */ | |
| 4292 static int decimalCollFunc( | |
| 4293 void *notUsed, | |
| 4294 int nKey1, const void *pKey1, | |
| 4295 int nKey2, const void *pKey2 | |
| 4296 ){ | |
| 4297 const unsigned char *zA = (const unsigned char*)pKey1; | |
| 4298 const unsigned char *zB = (const unsigned char*)pKey2; | |
| 4299 Decimal *pA = decimalNewFromText((const char*)zA, nKey1); | |
| 4300 Decimal *pB = decimalNewFromText((const char*)zB, nKey2); | |
| 4301 int rc; | |
| 4302 UNUSED_PARAMETER(notUsed); | |
| 4303 if( pA==0 || pB==0 ){ | |
| 4304 rc = 0; | |
| 4305 }else{ | |
| 4306 rc = decimal_cmp(pA, pB); | |
| 4307 } | |
| 4308 decimal_free(pA); | |
| 4309 decimal_free(pB); | |
| 4310 return rc; | |
| 4311 } | |
| 4312 | |
| 4313 | |
| 4314 /* | |
| 4315 ** SQL Function: decimal_add(X, Y) | |
| 4316 ** decimal_sub(X, Y) | |
| 4317 ** | |
| 4318 ** Return the sum or difference of X and Y. | |
| 4319 */ | |
| 4320 static void decimalAddFunc( | |
| 4321 sqlite3_context *context, | |
| 4322 int argc, | |
| 4323 sqlite3_value **argv | |
| 4324 ){ | |
| 4325 Decimal *pA = decimal_new(context, argv[0], 1); | |
| 4326 Decimal *pB = decimal_new(context, argv[1], 1); | |
| 4327 UNUSED_PARAMETER(argc); | |
| 4328 decimal_add(pA, pB); | |
| 4329 decimal_result(context, pA); | |
| 4330 decimal_free(pA); | |
| 4331 decimal_free(pB); | |
| 4332 } | |
| 4333 static void decimalSubFunc( | |
| 4334 sqlite3_context *context, | |
| 4335 int argc, | |
| 4336 sqlite3_value **argv | |
| 4337 ){ | |
| 4338 Decimal *pA = decimal_new(context, argv[0], 1); | |
| 4339 Decimal *pB = decimal_new(context, argv[1], 1); | |
| 4340 UNUSED_PARAMETER(argc); | |
| 4341 if( pB ){ | |
| 4342 pB->sign = !pB->sign; | |
| 4343 decimal_add(pA, pB); | |
| 4344 decimal_result(context, pA); | |
| 4345 } | |
| 4346 decimal_free(pA); | |
| 4347 decimal_free(pB); | |
| 4348 } | |
| 4349 | |
| 4350 /* Aggregate function: decimal_sum(X) | |
| 4351 ** | |
| 4352 ** Works like sum() except that it uses decimal arithmetic for unlimited | |
| 4353 ** precision. | |
| 4354 */ | |
| 4355 static void decimalSumStep( | |
| 4356 sqlite3_context *context, | |
| 4357 int argc, | |
| 4358 sqlite3_value **argv | |
| 4359 ){ | |
| 4360 Decimal *p; | |
| 4361 Decimal *pArg; | |
| 4362 UNUSED_PARAMETER(argc); | |
| 4363 p = sqlite3_aggregate_context(context, sizeof(*p)); | |
| 4364 if( p==0 ) return; | |
| 4365 if( !p->isInit ){ | |
| 4366 p->isInit = 1; | |
| 4367 p->a = sqlite3_malloc(2); | |
| 4368 if( p->a==0 ){ | |
| 4369 p->oom = 1; | |
| 4370 }else{ | |
| 4371 p->a[0] = 0; | |
| 4372 } | |
| 4373 p->nDigit = 1; | |
| 4374 p->nFrac = 0; | |
| 4375 } | |
| 4376 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; | |
| 4377 pArg = decimal_new(context, argv[0], 1); | |
| 4378 decimal_add(p, pArg); | |
| 4379 decimal_free(pArg); | |
| 4380 } | |
| 4381 static void decimalSumInverse( | |
| 4382 sqlite3_context *context, | |
| 4383 int argc, | |
| 4384 sqlite3_value **argv | |
| 4385 ){ | |
| 4386 Decimal *p; | |
| 4387 Decimal *pArg; | |
| 4388 UNUSED_PARAMETER(argc); | |
| 4389 p = sqlite3_aggregate_context(context, sizeof(*p)); | |
| 4390 if( p==0 ) return; | |
| 4391 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; | |
| 4392 pArg = decimal_new(context, argv[0], 1); | |
| 4393 if( pArg ) pArg->sign = !pArg->sign; | |
| 4394 decimal_add(p, pArg); | |
| 4395 decimal_free(pArg); | |
| 4396 } | |
| 4397 static void decimalSumValue(sqlite3_context *context){ | |
| 4398 Decimal *p = sqlite3_aggregate_context(context, 0); | |
| 4399 if( p==0 ) return; | |
| 4400 decimal_result(context, p); | |
| 4401 } | |
| 4402 static void decimalSumFinalize(sqlite3_context *context){ | |
| 4403 Decimal *p = sqlite3_aggregate_context(context, 0); | |
| 4404 if( p==0 ) return; | |
| 4405 decimal_result(context, p); | |
| 4406 decimal_clear(p); | |
| 4407 } | |
| 4408 | |
| 4409 /* | |
| 4410 ** SQL Function: decimal_mul(X, Y) | |
| 4411 ** | |
| 4412 ** Return the product of X and Y. | |
| 4413 */ | |
| 4414 static void decimalMulFunc( | |
| 4415 sqlite3_context *context, | |
| 4416 int argc, | |
| 4417 sqlite3_value **argv | |
| 4418 ){ | |
| 4419 Decimal *pA = decimal_new(context, argv[0], 1); | |
| 4420 Decimal *pB = decimal_new(context, argv[1], 1); | |
| 4421 UNUSED_PARAMETER(argc); | |
| 4422 if( pA==0 || pA->oom || pA->isNull | |
| 4423 || pB==0 || pB->oom || pB->isNull | |
| 4424 ){ | |
| 4425 goto mul_end; | |
| 4426 } | |
| 4427 decimalMul(pA, pB); | |
| 4428 if( pA->oom ){ | |
| 4429 goto mul_end; | |
| 4430 } | |
| 4431 decimal_result(context, pA); | |
| 4432 | |
| 4433 mul_end: | |
| 4434 decimal_free(pA); | |
| 4435 decimal_free(pB); | |
| 4436 } | |
| 4437 | |
| 4438 /* | |
| 4439 ** SQL Function: decimal_pow2(N) | |
| 4440 ** | |
| 4441 ** Return the N-th power of 2. N must be an integer. | |
| 4442 */ | |
| 4443 static void decimalPow2Func( | |
| 4444 sqlite3_context *context, | |
| 4445 int argc, | |
| 4446 sqlite3_value **argv | |
| 4447 ){ | |
| 4448 UNUSED_PARAMETER(argc); | |
| 4449 if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){ | |
| 4450 Decimal *pA = decimalPow2(sqlite3_value_int(argv[0])); | |
| 4451 decimal_result_sci(context, pA); | |
| 4452 decimal_free(pA); | |
| 4453 } | |
| 4454 } | |
| 4455 | |
| 4456 #ifdef _WIN32 | |
| 4457 | |
| 4458 #endif | |
| 4459 int sqlite3_decimal_init( | |
| 4460 sqlite3 *db, | |
| 4461 char **pzErrMsg, | |
| 4462 const sqlite3_api_routines *pApi | |
| 4463 ){ | |
| 4464 int rc = SQLITE_OK; | |
| 4465 static const struct { | |
| 4466 const char *zFuncName; | |
| 4467 int nArg; | |
| 4468 int iArg; | |
| 4469 void (*xFunc)(sqlite3_context*,int,sqlite3_value**); | |
| 4470 } aFunc[] = { | |
| 4471 { "decimal", 1, 0, decimalFunc }, | |
| 4472 { "decimal_exp", 1, 1, decimalFunc }, | |
| 4473 { "decimal_cmp", 2, 0, decimalCmpFunc }, | |
| 4474 { "decimal_add", 2, 0, decimalAddFunc }, | |
| 4475 { "decimal_sub", 2, 0, decimalSubFunc }, | |
| 4476 { "decimal_mul", 2, 0, decimalMulFunc }, | |
| 4477 { "decimal_pow2", 1, 0, decimalPow2Func }, | |
| 4478 }; | |
| 4479 unsigned int i; | |
| 4480 (void)pzErrMsg; /* Unused parameter */ | |
| 4481 | |
| 4482 SQLITE_EXTENSION_INIT2(pApi); | |
| 4483 | |
| 4484 for(i=0; i<(int)(sizeof(aFunc)/sizeof(aFunc[0])) && rc==SQLITE_OK; i++){ | |
| 4485 rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg, | |
| 4486 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, | |
| 4487 aFunc[i].iArg ? db : 0, aFunc[i].xFunc, 0, 0); | |
| 4488 } | |
| 4489 if( rc==SQLITE_OK ){ | |
| 4490 rc = sqlite3_create_window_function(db, "decimal_sum", 1, | |
| 4491 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0, | |
| 4492 decimalSumStep, decimalSumFinalize, | |
| 4493 decimalSumValue, decimalSumInverse, 0); | |
| 4494 } | |
| 4495 if( rc==SQLITE_OK ){ | |
| 4496 rc = sqlite3_create_collation(db, "decimal", SQLITE_UTF8, | |
| 4497 0, decimalCollFunc); | |
| 4498 } | |
| 4499 return rc; | |
| 4500 } | |
| 4501 | |
| 4502 /************************* End ../ext/misc/decimal.c ********************/ | |
| 4503 #undef sqlite3_base_init | |
| 4504 #define sqlite3_base_init sqlite3_base64_init | |
| 4505 /************************* Begin ../ext/misc/base64.c ******************/ | |
| 4506 /* | |
| 4507 ** 2022-11-18 | |
| 4508 ** | |
| 4509 ** The author disclaims copyright to this source code. In place of | |
| 4510 ** a legal notice, here is a blessing: | |
| 4511 ** | |
| 4512 ** May you do good and not evil. | |
| 4513 ** May you find forgiveness for yourself and forgive others. | |
| 4514 ** May you share freely, never taking more than you give. | |
| 4515 ** | |
| 4516 ************************************************************************* | |
| 4517 ** | |
| 4518 ** This is a SQLite extension for converting in either direction | |
| 4519 ** between a (binary) blob and base64 text. Base64 can transit a | |
| 4520 ** sane USASCII channel unmolested. It also plays nicely in CSV or | |
| 4521 ** written as TCL brace-enclosed literals or SQL string literals, | |
| 4522 ** and can be used unmodified in XML-like documents. | |
| 4523 ** | |
| 4524 ** This is an independent implementation of conversions specified in | |
| 4525 ** RFC 4648, done on the above date by the author (Larry Brasfield) | |
| 4526 ** who thereby has the right to put this into the public domain. | |
| 4527 ** | |
| 4528 ** The conversions meet RFC 4648 requirements, provided that this | |
| 4529 ** C source specifies that line-feeds are included in the encoded | |
| 4530 ** data to limit visible line lengths to 72 characters and to | |
| 4531 ** terminate any encoded blob having non-zero length. | |
| 4532 ** | |
| 4533 ** Length limitations are not imposed except that the runtime | |
| 4534 ** SQLite string or blob length limits are respected. Otherwise, | |
| 4535 ** any length binary sequence can be represented and recovered. | |
| 4536 ** Generated base64 sequences, with their line-feeds included, | |
| 4537 ** can be concatenated; the result converted back to binary will | |
| 4538 ** be the concatenation of the represented binary sequences. | |
| 4539 ** | |
| 4540 ** This SQLite3 extension creates a function, base64(x), which | |
| 4541 ** either: converts text x containing base64 to a returned blob; | |
| 4542 ** or converts a blob x to returned text containing base64. An | |
| 4543 ** error will be thrown for other input argument types. | |
| 4544 ** | |
| 4545 ** This code relies on UTF-8 encoding only with respect to the | |
| 4546 ** meaning of the first 128 (7-bit) codes matching that of USASCII. | |
| 4547 ** It will fail miserably if somehow made to try to convert EBCDIC. | |
| 4548 ** Because it is table-driven, it could be enhanced to handle that, | |
| 4549 ** but the world and SQLite have moved on from that anachronism. | |
| 4550 ** | |
| 4551 ** To build the extension: | |
| 4552 ** Set shell variable SQDIR=<your favorite SQLite checkout directory> | |
| 4553 ** *Nix: gcc -O2 -shared -I$SQDIR -fPIC -o base64.so base64.c | |
| 4554 ** OSX: gcc -O2 -dynamiclib -fPIC -I$SQDIR -o base64.dylib base64.c | |
| 4555 ** Win32: gcc -O2 -shared -I%SQDIR% -o base64.dll base64.c | |
| 4556 ** Win32: cl /Os -I%SQDIR% base64.c -link -dll -out:base64.dll | |
| 4557 */ | |
| 4558 | |
| 4559 #include <assert.h> | |
| 4560 | |
| 4561 /* #include "sqlite3ext.h" */ | |
| 4562 | |
| 4563 #ifndef deliberate_fall_through | |
| 4564 /* Quiet some compilers about some of our intentional code. */ | |
| 4565 # if GCC_VERSION>=7000000 | |
| 4566 # define deliberate_fall_through __attribute__((fallthrough)); | |
| 4567 # else | |
| 4568 # define deliberate_fall_through | |
| 4569 # endif | |
| 4570 #endif | |
| 4571 | |
| 4572 SQLITE_EXTENSION_INIT1; | |
| 4573 | |
| 4574 #define PC 0x80 /* pad character */ | |
| 4575 #define WS 0x81 /* whitespace */ | |
| 4576 #define ND 0x82 /* Not above or digit-value */ | |
| 4577 #define PAD_CHAR '=' | |
| 4578 | |
| 4579 #ifndef U8_TYPEDEF | |
| 4580 /* typedef unsigned char u8; */ | |
| 4581 #define U8_TYPEDEF | |
| 4582 #endif | |
| 4583 | |
| 4584 /* Decoding table, ASCII (7-bit) value to base 64 digit value or other */ | |
| 4585 static const u8 b64DigitValues[128] = { | |
| 4586 /* HT LF VT FF CR */ | |
| 4587 ND,ND,ND,ND, ND,ND,ND,ND, ND,WS,WS,WS, WS,WS,ND,ND, | |
| 4588 /* US */ | |
| 4589 ND,ND,ND,ND, ND,ND,ND,ND, ND,ND,ND,ND, ND,ND,ND,ND, | |
| 4590 /*sp + / */ | |
| 4591 WS,ND,ND,ND, ND,ND,ND,ND, ND,ND,ND,62, ND,ND,ND,63, | |
| 4592 /* 0 1 5 9 = */ | |
| 4593 52,53,54,55, 56,57,58,59, 60,61,ND,ND, ND,PC,ND,ND, | |
| 4594 /* A O */ | |
| 4595 ND, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, | |
| 4596 /* P Z */ | |
| 4597 15,16,17,18, 19,20,21,22, 23,24,25,ND, ND,ND,ND,ND, | |
| 4598 /* a o */ | |
| 4599 ND,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, | |
| 4600 /* p z */ | |
| 4601 41,42,43,44, 45,46,47,48, 49,50,51,ND, ND,ND,ND,ND | |
| 4602 }; | |
| 4603 | |
| 4604 static const char b64Numerals[64+1] | |
| 4605 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
| 4606 | |
| 4607 #define BX_DV_PROTO(c) \ | |
| 4608 ((((u8)(c))<0x80)? (u8)(b64DigitValues[(u8)(c)]) : 0x80) | |
| 4609 #define IS_BX_DIGIT(bdp) (((u8)(bdp))<0x80) | |
| 4610 #define IS_BX_WS(bdp) ((bdp)==WS) | |
| 4611 #define IS_BX_PAD(bdp) ((bdp)==PC) | |
| 4612 #define BX_NUMERAL(dv) (b64Numerals[(u8)(dv)]) | |
| 4613 /* Width of base64 lines. Should be an integer multiple of 4. */ | |
| 4614 #define B64_DARK_MAX 72 | |
| 4615 | |
| 4616 /* Encode a byte buffer into base64 text with linefeeds appended to limit | |
| 4617 ** encoded group lengths to B64_DARK_MAX or to terminate the last group. | |
| 4618 */ | |
| 4619 static char* toBase64( u8 *pIn, int nbIn, char *pOut ){ | |
| 4620 int nCol = 0; | |
| 4621 while( nbIn >= 3 ){ | |
| 4622 /* Do the bit-shuffle, exploiting unsigned input to avoid masking. */ | |
| 4623 pOut[0] = BX_NUMERAL(pIn[0]>>2); | |
| 4624 pOut[1] = BX_NUMERAL(((pIn[0]<<4)|(pIn[1]>>4))&0x3f); | |
| 4625 pOut[2] = BX_NUMERAL(((pIn[1]&0xf)<<2)|(pIn[2]>>6)); | |
| 4626 pOut[3] = BX_NUMERAL(pIn[2]&0x3f); | |
| 4627 pOut += 4; | |
| 4628 nbIn -= 3; | |
| 4629 pIn += 3; | |
| 4630 if( (nCol += 4)>=B64_DARK_MAX || nbIn<=0 ){ | |
| 4631 *pOut++ = '\n'; | |
| 4632 nCol = 0; | |
| 4633 } | |
| 4634 } | |
| 4635 if( nbIn > 0 ){ | |
| 4636 signed char nco = nbIn+1; | |
| 4637 int nbe; | |
| 4638 unsigned long qv = *pIn++; | |
| 4639 for( nbe=1; nbe<3; ++nbe ){ | |
| 4640 qv <<= 8; | |
| 4641 if( nbe<nbIn ) qv |= *pIn++; | |
| 4642 } | |
| 4643 for( nbe=3; nbe>=0; --nbe ){ | |
| 4644 char ce = (nbe<nco)? BX_NUMERAL((u8)(qv & 0x3f)) : PAD_CHAR; | |
| 4645 qv >>= 6; | |
| 4646 pOut[nbe] = ce; | |
| 4647 } | |
| 4648 pOut += 4; | |
| 4649 *pOut++ = '\n'; | |
| 4650 } | |
| 4651 *pOut = 0; | |
| 4652 return pOut; | |
| 4653 } | |
| 4654 | |
| 4655 /* Skip over text which is not base64 numeral(s). */ | |
| 4656 static char * skipNonB64( char *s, int nc ){ | |
| 4657 char c; | |
| 4658 while( nc-- > 0 && (c = *s) && !IS_BX_DIGIT(BX_DV_PROTO(c)) ) ++s; | |
| 4659 return s; | |
| 4660 } | |
| 4661 | |
| 4662 /* Decode base64 text into a byte buffer. */ | |
| 4663 static u8* fromBase64( char *pIn, int ncIn, u8 *pOut ){ | |
| 4664 if( ncIn>0 && pIn[ncIn-1]=='\n' ) --ncIn; | |
| 4665 while( ncIn>0 && *pIn!=PAD_CHAR ){ | |
| 4666 static signed char nboi[] = { 0, 0, 1, 2, 3 }; | |
| 4667 char *pUse = skipNonB64(pIn, ncIn); | |
| 4668 unsigned long qv = 0L; | |
| 4669 int nti, nbo, nac; | |
| 4670 ncIn -= (pUse - pIn); | |
| 4671 pIn = pUse; | |
| 4672 nti = (ncIn>4)? 4 : ncIn; | |
| 4673 ncIn -= nti; | |
| 4674 nbo = nboi[nti]; | |
| 4675 if( nbo==0 ) break; | |
| 4676 for( nac=0; nac<4; ++nac ){ | |
| 4677 char c = (nac<nti)? *pIn++ : b64Numerals[0]; | |
| 4678 u8 bdp = BX_DV_PROTO(c); | |
| 4679 switch( bdp ){ | |
| 4680 case ND: | |
| 4681 /* Treat dark non-digits as pad, but they terminate decode too. */ | |
| 4682 ncIn = 0; | |
| 4683 deliberate_fall_through; /* FALLTHRU */ | |
| 4684 case WS: | |
| 4685 /* Treat whitespace as pad and terminate this group.*/ | |
| 4686 nti = nac; | |
| 4687 deliberate_fall_through; /* FALLTHRU */ | |
| 4688 case PC: | |
| 4689 bdp = 0; | |
| 4690 --nbo; | |
| 4691 deliberate_fall_through; /* FALLTHRU */ | |
| 4692 default: /* bdp is the digit value. */ | |
| 4693 qv = qv<<6 | bdp; | |
| 4694 break; | |
| 4695 } | |
| 4696 } | |
| 4697 switch( nbo ){ | |
| 4698 case 3: | |
| 4699 pOut[2] = (qv) & 0xff; | |
| 4700 deliberate_fall_through; /* FALLTHRU */ | |
| 4701 case 2: | |
| 4702 pOut[1] = (qv>>8) & 0xff; | |
| 4703 deliberate_fall_through; /* FALLTHRU */ | |
| 4704 case 1: | |
| 4705 pOut[0] = (qv>>16) & 0xff; | |
| 4706 break; | |
| 4707 } | |
| 4708 pOut += nbo; | |
| 4709 } | |
| 4710 return pOut; | |
| 4711 } | |
| 4712 | |
| 4713 /* This function does the work for the SQLite base64(x) UDF. */ | |
| 4714 static void base64(sqlite3_context *context, int na, sqlite3_value *av[]){ | |
| 4715 sqlite3_int64 nb; | |
| 4716 sqlite3_int64 nv = sqlite3_value_bytes(av[0]); | |
| 4717 sqlite3_int64 nc; | |
| 4718 int nvMax = sqlite3_limit(sqlite3_context_db_handle(context), | |
| 4719 SQLITE_LIMIT_LENGTH, -1); | |
| 4720 char *cBuf; | |
| 4721 u8 *bBuf; | |
| 4722 assert(na==1); | |
| 4723 switch( sqlite3_value_type(av[0]) ){ | |
| 4724 case SQLITE_BLOB: | |
| 4725 nb = nv; | |
| 4726 nc = 4*((nv+2)/3); /* quads needed */ | |
| 4727 nc += (nc+(B64_DARK_MAX-1))/B64_DARK_MAX + 1; /* LFs and a 0-terminator */ | |
| 4728 if( nvMax < nc ){ | |
| 4729 sqlite3_result_error(context, "blob expanded to base64 too big", -1); | |
| 4730 return; | |
| 4731 } | |
| 4732 bBuf = (u8*)sqlite3_value_blob(av[0]); | |
| 4733 if( !bBuf ){ | |
| 4734 if( SQLITE_NOMEM==sqlite3_errcode(sqlite3_context_db_handle(context)) ){ | |
| 4735 goto memFail; | |
| 4736 } | |
| 4737 sqlite3_result_text(context,"",-1,SQLITE_STATIC); | |
| 4738 break; | |
| 4739 } | |
| 4740 cBuf = sqlite3_malloc(nc); | |
| 4741 if( !cBuf ) goto memFail; | |
| 4742 nc = (int)(toBase64(bBuf, nb, cBuf) - cBuf); | |
| 4743 sqlite3_result_text(context, cBuf, nc, sqlite3_free); | |
| 4744 break; | |
| 4745 case SQLITE_TEXT: | |
| 4746 nc = nv; | |
| 4747 nb = 3*((nv+3)/4); /* may overestimate due to LF and padding */ | |
| 4748 if( nvMax < nb ){ | |
| 4749 sqlite3_result_error(context, "blob from base64 may be too big", -1); | |
| 4750 return; | |
| 4751 }else if( nb<1 ){ | |
| 4752 nb = 1; | |
| 4753 } | |
| 4754 cBuf = (char *)sqlite3_value_text(av[0]); | |
| 4755 if( !cBuf ){ | |
| 4756 if( SQLITE_NOMEM==sqlite3_errcode(sqlite3_context_db_handle(context)) ){ | |
| 4757 goto memFail; | |
| 4758 } | |
| 4759 sqlite3_result_zeroblob(context, 0); | |
| 4760 break; | |
| 4761 } | |
| 4762 bBuf = sqlite3_malloc(nb); | |
| 4763 if( !bBuf ) goto memFail; | |
| 4764 nb = (int)(fromBase64(cBuf, nc, bBuf) - bBuf); | |
| 4765 sqlite3_result_blob(context, bBuf, nb, sqlite3_free); | |
| 4766 break; | |
| 4767 default: | |
| 4768 sqlite3_result_error(context, "base64 accepts only blob or text", -1); | |
| 4769 return; | |
| 4770 } | |
| 4771 return; | |
| 4772 memFail: | |
| 4773 sqlite3_result_error(context, "base64 OOM", -1); | |
| 4774 } | |
| 4775 | |
| 4776 /* | |
| 4777 ** Establish linkage to running SQLite library. | |
| 4778 */ | |
| 4779 #ifndef SQLITE_SHELL_EXTFUNCS | |
| 4780 #ifdef _WIN32 | |
| 4781 | |
| 4782 #endif | |
| 4783 int sqlite3_base_init | |
| 4784 #else | |
| 4785 static int sqlite3_base64_init | |
| 4786 #endif | |
| 4787 (sqlite3 *db, char **pzErr, const sqlite3_api_routines *pApi){ | |
| 4788 SQLITE_EXTENSION_INIT2(pApi); | |
| 4789 (void)pzErr; | |
| 4790 return sqlite3_create_function | |
| 4791 (db, "base64", 1, | |
| 4792 SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|SQLITE_DIRECTONLY|SQLITE_UTF8, | |
| 4793 0, base64, 0, 0); | |
| 4794 } | |
| 4795 | |
| 4796 /* | |
| 4797 ** Define some macros to allow this extension to be built into the shell | |
| 4798 ** conveniently, in conjunction with use of SQLITE_SHELL_EXTFUNCS. This | |
| 4799 ** allows shell.c, as distributed, to have this extension built in. | |
| 4800 */ | |
| 4801 #define BASE64_INIT(db) sqlite3_base64_init(db, 0, 0) | |
| 4802 #define BASE64_EXPOSE(db, pzErr) /* Not needed, ..._init() does this. */ | |
| 4803 | |
| 4804 /************************* End ../ext/misc/base64.c ********************/ | |
| 4805 #undef sqlite3_base_init | |
| 4806 #define sqlite3_base_init sqlite3_base85_init | |
| 4807 #define OMIT_BASE85_CHECKER | |
| 4808 /************************* Begin ../ext/misc/base85.c ******************/ | |
| 4809 /* | |
| 4810 ** 2022-11-16 | |
| 4811 ** | |
| 4812 ** The author disclaims copyright to this source code. In place of | |
| 4813 ** a legal notice, here is a blessing: | |
| 4814 ** | |
| 4815 ** May you do good and not evil. | |
| 4816 ** May you find forgiveness for yourself and forgive others. | |
| 4817 ** May you share freely, never taking more than you give. | |
| 4818 ** | |
| 4819 ************************************************************************* | |
| 4820 ** | |
| 4821 ** This is a utility for converting binary to base85 or vice-versa. | |
| 4822 ** It can be built as a standalone program or an SQLite3 extension. | |
| 4823 ** | |
| 4824 ** Much like base64 representations, base85 can be sent through a | |
| 4825 ** sane USASCII channel unmolested. It also plays nicely in CSV or | |
| 4826 ** written as TCL brace-enclosed literals or SQL string literals. | |
| 4827 ** It is not suited for unmodified use in XML-like documents. | |
| 4828 ** | |
| 4829 ** The encoding used resembles Ascii85, but was devised by the author | |
| 4830 ** (Larry Brasfield) before Mozilla, Adobe, ZMODEM or other Ascii85 | |
| 4831 ** variant sources existed, in the 1984 timeframe on a VAX mainframe. | |
| 4832 ** Further, this is an independent implementation of a base85 system. | |
| 4833 ** Hence, the author has rightfully put this into the public domain. | |
| 4834 ** | |
| 4835 ** Base85 numerals are taken from the set of 7-bit USASCII codes, | |
| 4836 ** excluding control characters and Space ! " ' ( ) { | } ~ Del | |
| 4837 ** in code order representing digit values 0 to 84 (base 10.) | |
| 4838 ** | |
| 4839 ** Groups of 4 bytes, interpreted as big-endian 32-bit values, | |
| 4840 ** are represented as 5-digit base85 numbers with MS to LS digit | |
| 4841 ** order. Groups of 1-3 bytes are represented with 2-4 digits, | |
| 4842 ** still big-endian but 8-24 bit values. (Using big-endian yields | |
| 4843 ** the simplest transition to byte groups smaller than 4 bytes. | |
| 4844 ** These byte groups can also be considered base-256 numbers.) | |
| 4845 ** Groups of 0 bytes are represented with 0 digits and vice-versa. | |
| 4846 ** No pad characters are used; Encoded base85 numeral sequence | |
| 4847 ** (aka "group") length maps 1-to-1 to the decoded binary length. | |
| 4848 ** | |
| 4849 ** Any character not in the base85 numeral set delimits groups. | |
| 4850 ** When base85 is streamed or stored in containers of indefinite | |
| 4851 ** size, newline is used to separate it into sub-sequences of no | |
| 4852 ** more than 80 digits so that fgets() can be used to read it. | |
| 4853 ** | |
| 4854 ** Length limitations are not imposed except that the runtime | |
| 4855 ** SQLite string or blob length limits are respected. Otherwise, | |
| 4856 ** any length binary sequence can be represented and recovered. | |
| 4857 ** Base85 sequences can be concatenated by separating them with | |
| 4858 ** a non-base85 character; the conversion to binary will then | |
| 4859 ** be the concatenation of the represented binary sequences. | |
| 4860 | |
| 4861 ** The standalone program either converts base85 on stdin to create | |
| 4862 ** a binary file or converts a binary file to base85 on stdout. | |
| 4863 ** Read or make it blurt its help for invocation details. | |
| 4864 ** | |
| 4865 ** The SQLite3 extension creates a function, base85(x), which will | |
| 4866 ** either convert text base85 to a blob or a blob to text base85 | |
| 4867 ** and return the result (or throw an error for other types.) | |
| 4868 ** Unless built with OMIT_BASE85_CHECKER defined, it also creates a | |
| 4869 ** function, is_base85(t), which returns 1 iff the text t contains | |
| 4870 ** nothing other than base85 numerals and whitespace, or 0 otherwise. | |
| 4871 ** | |
| 4872 ** To build the extension: | |
| 4873 ** Set shell variable SQDIR=<your favorite SQLite checkout directory> | |
| 4874 ** and variable OPTS to -DOMIT_BASE85_CHECKER if is_base85() unwanted. | |
| 4875 ** *Nix: gcc -O2 -shared -I$SQDIR $OPTS -fPIC -o base85.so base85.c | |
| 4876 ** OSX: gcc -O2 -dynamiclib -fPIC -I$SQDIR $OPTS -o base85.dylib base85.c | |
| 4877 ** Win32: gcc -O2 -shared -I%SQDIR% %OPTS% -o base85.dll base85.c | |
| 4878 ** Win32: cl /Os -I%SQDIR% %OPTS% base85.c -link -dll -out:base85.dll | |
| 4879 ** | |
| 4880 ** To build the standalone program, define PP symbol BASE85_STANDALONE. Eg. | |
| 4881 ** *Nix or OSX: gcc -O2 -DBASE85_STANDALONE base85.c -o base85 | |
| 4882 ** Win32: gcc -O2 -DBASE85_STANDALONE -o base85.exe base85.c | |
| 4883 ** Win32: cl /Os /MD -DBASE85_STANDALONE base85.c | |
| 4884 */ | |
| 4885 | |
| 4886 #include <stdio.h> | |
| 4887 #include <memory.h> | |
| 4888 #include <string.h> | |
| 4889 #include <assert.h> | |
| 4890 #ifndef OMIT_BASE85_CHECKER | |
| 4891 # include <ctype.h> | |
| 4892 #endif | |
| 4893 | |
| 4894 #ifndef BASE85_STANDALONE | |
| 4895 | |
| 4896 /* # include "sqlite3ext.h" */ | |
| 4897 | |
| 4898 SQLITE_EXTENSION_INIT1; | |
| 4899 | |
| 4900 #else | |
| 4901 | |
| 4902 # ifdef _WIN32 | |
| 4903 # include <io.h> | |
| 4904 # include <fcntl.h> | |
| 4905 # else | |
| 4906 # define setmode(fd,m) | |
| 4907 # endif | |
| 4908 | |
| 4909 static char *zHelp = | |
| 4910 "Usage: base85 <dirFlag> <binFile>\n" | |
| 4911 " <dirFlag> is either -r to read or -w to write <binFile>,\n" | |
| 4912 " content to be converted to/from base85 on stdout/stdin.\n" | |
| 4913 " <binFile> names a binary file to be rendered or created.\n" | |
| 4914 " Or, the name '-' refers to the stdin or stdout stream.\n" | |
| 4915 ; | |
| 4916 | |
| 4917 static void sayHelp(){ | |
| 4918 printf("%s", zHelp); | |
| 4919 } | |
| 4920 #endif | |
| 4921 | |
| 4922 #ifndef U8_TYPEDEF | |
| 4923 /* typedef unsigned char u8; */ | |
| 4924 #define U8_TYPEDEF | |
| 4925 #endif | |
| 4926 | |
| 4927 /* Classify c according to interval within USASCII set w.r.t. base85 | |
| 4928 * Values of 1 and 3 are base85 numerals. Values of 0, 2, or 4 are not. | |
| 4929 */ | |
| 4930 #define B85_CLASS( c ) (((c)>='#')+((c)>'&')+((c)>='*')+((c)>'z')) | |
| 4931 | |
| 4932 /* Provide digitValue to b85Numeral offset as a function of above class. */ | |
| 4933 static u8 b85_cOffset[] = { 0, '#', 0, '*'-4, 0 }; | |
| 4934 #define B85_DNOS( c ) b85_cOffset[B85_CLASS(c)] | |
| 4935 | |
| 4936 /* Say whether c is a base85 numeral. */ | |
| 4937 #define IS_B85( c ) (B85_CLASS(c) & 1) | |
| 4938 | |
| 4939 #if 0 /* Not used, */ | |
| 4940 static u8 base85DigitValue( char c ){ | |
| 4941 u8 dv = (u8)(c - '#'); | |
| 4942 if( dv>87 ) return 0xff; | |
| 4943 return (dv > 3)? dv-3 : dv; | |
| 4944 } | |
| 4945 #endif | |
| 4946 | |
| 4947 /* Width of base64 lines. Should be an integer multiple of 5. */ | |
| 4948 #define B85_DARK_MAX 80 | |
| 4949 | |
| 4950 | |
| 4951 static char * skipNonB85( char *s, int nc ){ | |
| 4952 char c; | |
| 4953 while( nc-- > 0 && (c = *s) && !IS_B85(c) ) ++s; | |
| 4954 return s; | |
| 4955 } | |
| 4956 | |
| 4957 /* Convert small integer, known to be in 0..84 inclusive, to base85 numeral. | |
| 4958 * Do not use the macro form with argument expression having a side-effect.*/ | |
| 4959 #if 0 | |
| 4960 static char base85Numeral( u8 b ){ | |
| 4961 return (b < 4)? (char)(b + '#') : (char)(b - 4 + '*'); | |
| 4962 } | |
| 4963 #else | |
| 4964 # define base85Numeral( dn )\ | |
| 4965 ((char)(((dn) < 4)? (char)((dn) + '#') : (char)((dn) - 4 + '*'))) | |
| 4966 #endif | |
| 4967 | |
| 4968 static char *putcs(char *pc, char *s){ | |
| 4969 char c; | |
| 4970 while( (c = *s++)!=0 ) *pc++ = c; | |
| 4971 return pc; | |
| 4972 } | |
| 4973 | |
| 4974 /* Encode a byte buffer into base85 text. If pSep!=0, it's a C string | |
| 4975 ** to be appended to encoded groups to limit their length to B85_DARK_MAX | |
| 4976 ** or to terminate the last group (to aid concatenation.) | |
| 4977 */ | |
| 4978 static char* toBase85( u8 *pIn, int nbIn, char *pOut, char *pSep ){ | |
| 4979 int nCol = 0; | |
| 4980 while( nbIn >= 4 ){ | |
| 4981 int nco = 5; | |
| 4982 unsigned long qbv = (((unsigned long)pIn[0])<<24) | | |
| 4983 (pIn[1]<<16) | (pIn[2]<<8) | pIn[3]; | |
| 4984 while( nco > 0 ){ | |
| 4985 unsigned nqv = (unsigned)(qbv/85UL); | |
| 4986 unsigned char dv = qbv - 85UL*nqv; | |
| 4987 qbv = nqv; | |
| 4988 pOut[--nco] = base85Numeral(dv); | |
| 4989 } | |
| 4990 nbIn -= 4; | |
| 4991 pIn += 4; | |
| 4992 pOut += 5; | |
| 4993 if( pSep && (nCol += 5)>=B85_DARK_MAX ){ | |
| 4994 pOut = putcs(pOut, pSep); | |
| 4995 nCol = 0; | |
| 4996 } | |
| 4997 } | |
| 4998 if( nbIn > 0 ){ | |
| 4999 int nco = nbIn + 1; | |
| 5000 unsigned long qv = *pIn++; | |
| 5001 int nbe = 1; | |
| 5002 while( nbe++ < nbIn ){ | |
| 5003 qv = (qv<<8) | *pIn++; | |
| 5004 } | |
| 5005 nCol += nco; | |
| 5006 while( nco > 0 ){ | |
| 5007 u8 dv = (u8)(qv % 85); | |
| 5008 qv /= 85; | |
| 5009 pOut[--nco] = base85Numeral(dv); | |
| 5010 } | |
| 5011 pOut += (nbIn+1); | |
| 5012 } | |
| 5013 if( pSep && nCol>0 ) pOut = putcs(pOut, pSep); | |
| 5014 *pOut = 0; | |
| 5015 return pOut; | |
| 5016 } | |
| 5017 | |
| 5018 /* Decode base85 text into a byte buffer. */ | |
| 5019 static u8* fromBase85( char *pIn, int ncIn, u8 *pOut ){ | |
| 5020 if( ncIn>0 && pIn[ncIn-1]=='\n' ) --ncIn; | |
| 5021 while( ncIn>0 ){ | |
| 5022 static signed char nboi[] = { 0, 0, 1, 2, 3, 4 }; | |
| 5023 char *pUse = skipNonB85(pIn, ncIn); | |
| 5024 unsigned long qv = 0L; | |
| 5025 int nti, nbo; | |
| 5026 ncIn -= (pUse - pIn); | |
| 5027 pIn = pUse; | |
| 5028 nti = (ncIn>5)? 5 : ncIn; | |
| 5029 nbo = nboi[nti]; | |
| 5030 if( nbo==0 ) break; | |
| 5031 while( nti>0 ){ | |
| 5032 char c = *pIn++; | |
| 5033 u8 cdo = B85_DNOS(c); | |
| 5034 --ncIn; | |
| 5035 if( cdo==0 ) break; | |
| 5036 qv = 85 * qv + (c - cdo); | |
| 5037 --nti; | |
| 5038 } | |
| 5039 nbo -= nti; /* Adjust for early (non-digit) end of group. */ | |
| 5040 switch( nbo ){ | |
| 5041 case 4: | |
| 5042 *pOut++ = (qv >> 24)&0xff; | |
| 5043 /* FALLTHRU */ | |
| 5044 case 3: | |
| 5045 *pOut++ = (qv >> 16)&0xff; | |
| 5046 /* FALLTHRU */ | |
| 5047 case 2: | |
| 5048 *pOut++ = (qv >> 8)&0xff; | |
| 5049 /* FALLTHRU */ | |
| 5050 case 1: | |
| 5051 *pOut++ = qv&0xff; | |
| 5052 /* FALLTHRU */ | |
| 5053 case 0: | |
| 5054 break; | |
| 5055 } | |
| 5056 } | |
| 5057 return pOut; | |
| 5058 } | |
| 5059 | |
| 5060 #ifndef OMIT_BASE85_CHECKER | |
| 5061 /* Say whether input char sequence is all (base85 and/or whitespace).*/ | |
| 5062 static int allBase85( char *p, int len ){ | |
| 5063 char c; | |
| 5064 while( len-- > 0 && (c = *p++) != 0 ){ | |
| 5065 if( !IS_B85(c) && !isspace(c) ) return 0; | |
| 5066 } | |
| 5067 return 1; | |
| 5068 } | |
| 5069 #endif | |
| 5070 | |
| 5071 #ifndef BASE85_STANDALONE | |
| 5072 | |
| 5073 # ifndef OMIT_BASE85_CHECKER | |
| 5074 /* This function does the work for the SQLite is_base85(t) UDF. */ | |
| 5075 static void is_base85(sqlite3_context *context, int na, sqlite3_value *av[]){ | |
| 5076 assert(na==1); | |
| 5077 switch( sqlite3_value_type(av[0]) ){ | |
| 5078 case SQLITE_TEXT: | |
| 5079 { | |
| 5080 int rv = allBase85( (char *)sqlite3_value_text(av[0]), | |
| 5081 sqlite3_value_bytes(av[0]) ); | |
| 5082 sqlite3_result_int(context, rv); | |
| 5083 } | |
| 5084 break; | |
| 5085 case SQLITE_NULL: | |
| 5086 sqlite3_result_null(context); | |
| 5087 break; | |
| 5088 default: | |
| 5089 sqlite3_result_error(context, "is_base85 accepts only text or NULL", -1); | |
| 5090 return; | |
| 5091 } | |
| 5092 } | |
| 5093 # endif | |
| 5094 | |
| 5095 /* This function does the work for the SQLite base85(x) UDF. */ | |
| 5096 static void base85(sqlite3_context *context, int na, sqlite3_value *av[]){ | |
| 5097 sqlite3_int64 nb, nc, nv = sqlite3_value_bytes(av[0]); | |
| 5098 int nvMax = sqlite3_limit(sqlite3_context_db_handle(context), | |
| 5099 SQLITE_LIMIT_LENGTH, -1); | |
| 5100 char *cBuf; | |
| 5101 u8 *bBuf; | |
| 5102 assert(na==1); | |
| 5103 switch( sqlite3_value_type(av[0]) ){ | |
| 5104 case SQLITE_BLOB: | |
| 5105 nb = nv; | |
| 5106 /* ulongs tail newlines tailenc+nul*/ | |
| 5107 nc = 5*(nv/4) + nv%4 + nv/64+1 + 2; | |
| 5108 if( nvMax < nc ){ | |
| 5109 sqlite3_result_error(context, "blob expanded to base85 too big", -1); | |
| 5110 return; | |
| 5111 } | |
| 5112 bBuf = (u8*)sqlite3_value_blob(av[0]); | |
| 5113 if( !bBuf ){ | |
| 5114 if( SQLITE_NOMEM==sqlite3_errcode(sqlite3_context_db_handle(context)) ){ | |
| 5115 goto memFail; | |
| 5116 } | |
| 5117 sqlite3_result_text(context,"",-1,SQLITE_STATIC); | |
| 5118 break; | |
| 5119 } | |
| 5120 cBuf = sqlite3_malloc(nc); | |
| 5121 if( !cBuf ) goto memFail; | |
| 5122 nc = (int)(toBase85(bBuf, nb, cBuf, "\n") - cBuf); | |
| 5123 sqlite3_result_text(context, cBuf, nc, sqlite3_free); | |
| 5124 break; | |
| 5125 case SQLITE_TEXT: | |
| 5126 nc = nv; | |
| 5127 nb = 4*(nv/5) + nv%5; /* may overestimate */ | |
| 5128 if( nvMax < nb ){ | |
| 5129 sqlite3_result_error(context, "blob from base85 may be too big", -1); | |
| 5130 return; | |
| 5131 }else if( nb<1 ){ | |
| 5132 nb = 1; | |
| 5133 } | |
| 5134 cBuf = (char *)sqlite3_value_text(av[0]); | |
| 5135 if( !cBuf ){ | |
| 5136 if( SQLITE_NOMEM==sqlite3_errcode(sqlite3_context_db_handle(context)) ){ | |
| 5137 goto memFail; | |
| 5138 } | |
| 5139 sqlite3_result_zeroblob(context, 0); | |
| 5140 break; | |
| 5141 } | |
| 5142 bBuf = sqlite3_malloc(nb); | |
| 5143 if( !bBuf ) goto memFail; | |
| 5144 nb = (int)(fromBase85(cBuf, nc, bBuf) - bBuf); | |
| 5145 sqlite3_result_blob(context, bBuf, nb, sqlite3_free); | |
| 5146 break; | |
| 5147 default: | |
| 5148 sqlite3_result_error(context, "base85 accepts only blob or text.", -1); | |
| 5149 return; | |
| 5150 } | |
| 5151 return; | |
| 5152 memFail: | |
| 5153 sqlite3_result_error(context, "base85 OOM", -1); | |
| 5154 } | |
| 5155 | |
| 5156 /* | |
| 5157 ** Establish linkage to running SQLite library. | |
| 5158 */ | |
| 5159 #ifndef SQLITE_SHELL_EXTFUNCS | |
| 5160 #ifdef _WIN32 | |
| 5161 | |
| 5162 #endif | |
| 5163 int sqlite3_base_init | |
| 5164 #else | |
| 5165 static int sqlite3_base85_init | |
| 5166 #endif | |
| 5167 (sqlite3 *db, char **pzErr, const sqlite3_api_routines *pApi){ | |
| 5168 SQLITE_EXTENSION_INIT2(pApi); | |
| 5169 (void)pzErr; | |
| 5170 # ifndef OMIT_BASE85_CHECKER | |
| 5171 { | |
| 5172 int rc = sqlite3_create_function | |
| 5173 (db, "is_base85", 1, | |
| 5174 SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|SQLITE_UTF8, | |
| 5175 0, is_base85, 0, 0); | |
| 5176 if( rc!=SQLITE_OK ) return rc; | |
| 5177 } | |
| 5178 # endif | |
| 5179 return sqlite3_create_function | |
| 5180 (db, "base85", 1, | |
| 5181 SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|SQLITE_DIRECTONLY|SQLITE_UTF8, | |
| 5182 0, base85, 0, 0); | |
| 5183 } | |
| 5184 | |
| 5185 /* | |
| 5186 ** Define some macros to allow this extension to be built into the shell | |
| 5187 ** conveniently, in conjunction with use of SQLITE_SHELL_EXTFUNCS. This | |
| 5188 ** allows shell.c, as distributed, to have this extension built in. | |
| 5189 */ | |
| 5190 # define BASE85_INIT(db) sqlite3_base85_init(db, 0, 0) | |
| 5191 # define BASE85_EXPOSE(db, pzErr) /* Not needed, ..._init() does this. */ | |
| 5192 | |
| 5193 #else /* standalone program */ | |
| 5194 | |
| 5195 int main(int na, char *av[]){ | |
| 5196 int cin; | |
| 5197 int rc = 0; | |
| 5198 u8 bBuf[4*(B85_DARK_MAX/5)]; | |
| 5199 char cBuf[5*(sizeof(bBuf)/4)+2]; | |
| 5200 size_t nio; | |
| 5201 # ifndef OMIT_BASE85_CHECKER | |
| 5202 int b85Clean = 1; | |
| 5203 # endif | |
| 5204 char rw; | |
| 5205 FILE *fb = 0, *foc = 0; | |
| 5206 char fmode[3] = "xb"; | |
| 5207 if( na < 3 || av[1][0]!='-' || (rw = av[1][1])==0 || (rw!='r' && rw!='w') ){ | |
| 5208 sayHelp(); | |
| 5209 return 0; | |
| 5210 } | |
| 5211 fmode[0] = rw; | |
| 5212 if( av[2][0]=='-' && av[2][1]==0 ){ | |
| 5213 switch( rw ){ | |
| 5214 case 'r': | |
| 5215 fb = stdin; | |
| 5216 setmode(fileno(stdin), O_BINARY); | |
| 5217 break; | |
| 5218 case 'w': | |
| 5219 fb = stdout; | |
| 5220 setmode(fileno(stdout), O_BINARY); | |
| 5221 break; | |
| 5222 } | |
| 5223 }else{ | |
| 5224 fb = fopen(av[2], fmode); | |
| 5225 foc = fb; | |
| 5226 } | |
| 5227 if( !fb ){ | |
| 5228 fprintf(stderr, "Cannot open %s for %c\n", av[2], rw); | |
| 5229 rc = 1; | |
| 5230 }else{ | |
| 5231 switch( rw ){ | |
| 5232 case 'r': | |
| 5233 while( (nio = fread( bBuf, 1, sizeof(bBuf), fb))>0 ){ | |
| 5234 toBase85( bBuf, (int)nio, cBuf, 0 ); | |
| 5235 fprintf(stdout, "%s\n", cBuf); | |
| 5236 } | |
| 5237 break; | |
| 5238 case 'w': | |
| 5239 while( 0 != fgets(cBuf, sizeof(cBuf), stdin) ){ | |
| 5240 int nc = strlen(cBuf); | |
| 5241 size_t nbo = fromBase85( cBuf, nc, bBuf ) - bBuf; | |
| 5242 if( 1 != fwrite(bBuf, nbo, 1, fb) ) rc = 1; | |
| 5243 # ifndef OMIT_BASE85_CHECKER | |
| 5244 b85Clean &= allBase85( cBuf, nc ); | |
| 5245 # endif | |
| 5246 } | |
| 5247 break; | |
| 5248 default: | |
| 5249 sayHelp(); | |
| 5250 rc = 1; | |
| 5251 } | |
| 5252 if( foc ) fclose(foc); | |
| 5253 } | |
| 5254 # ifndef OMIT_BASE85_CHECKER | |
| 5255 if( !b85Clean ){ | |
| 5256 fprintf(stderr, "Base85 input had non-base85 dark or control content.\n"); | |
| 5257 } | |
| 5258 # endif | |
| 5259 return rc; | |
| 5260 } | |
| 5261 | |
| 5262 #endif | |
| 5263 | |
| 5264 /************************* End ../ext/misc/base85.c ********************/ | |
| 5265 /************************* Begin ../ext/misc/ieee754.c ******************/ | |
| 5266 /* | |
| 5267 ** 2013-04-17 | |
| 5268 ** | |
| 5269 ** The author disclaims copyright to this source code. In place of | |
| 5270 ** a legal notice, here is a blessing: | |
| 5271 ** | |
| 5272 ** May you do good and not evil. | |
| 5273 ** May you find forgiveness for yourself and forgive others. | |
| 5274 ** May you share freely, never taking more than you give. | |
| 5275 ** | |
| 5276 ****************************************************************************** | |
| 5277 ** | |
| 5278 ** This SQLite extension implements functions for the exact display | |
| 5279 ** and input of IEEE754 Binary64 floating-point numbers. | |
| 5280 ** | |
| 5281 ** ieee754(X) | |
| 5282 ** ieee754(Y,Z) | |
| 5283 ** | |
| 5284 ** In the first form, the value X should be a floating-point number. | |
| 5285 ** The function will return a string of the form 'ieee754(Y,Z)' where | |
| 5286 ** Y and Z are integers such that X==Y*pow(2,Z). | |
| 5287 ** | |
| 5288 ** In the second form, Y and Z are integers which are the mantissa and | |
| 5289 ** base-2 exponent of a new floating point number. The function returns | |
| 5290 ** a floating-point value equal to Y*pow(2,Z). | |
| 5291 ** | |
| 5292 ** Examples: | |
| 5293 ** | |
| 5294 ** ieee754(2.0) -> 'ieee754(2,0)' | |
| 5295 ** ieee754(45.25) -> 'ieee754(181,-2)' | |
| 5296 ** ieee754(2, 0) -> 2.0 | |
| 5297 ** ieee754(181, -2) -> 45.25 | |
| 5298 ** | |
| 5299 ** Two additional functions break apart the one-argument ieee754() | |
| 5300 ** result into separate integer values: | |
| 5301 ** | |
| 5302 ** ieee754_mantissa(45.25) -> 181 | |
| 5303 ** ieee754_exponent(45.25) -> -2 | |
| 5304 ** | |
| 5305 ** These functions convert binary64 numbers into blobs and back again. | |
| 5306 ** | |
| 5307 ** ieee754_from_blob(x'3ff0000000000000') -> 1.0 | |
| 5308 ** ieee754_to_blob(1.0) -> x'3ff0000000000000' | |
| 5309 ** | |
| 5310 ** In all single-argument functions, if the argument is an 8-byte blob | |
| 5311 ** then that blob is interpreted as a big-endian binary64 value. | |
| 5312 ** | |
| 5313 ** | |
| 5314 ** EXACT DECIMAL REPRESENTATION OF BINARY64 VALUES | |
| 5315 ** ----------------------------------------------- | |
| 5316 ** | |
| 5317 ** This extension in combination with the separate 'decimal' extension | |
| 5318 ** can be used to compute the exact decimal representation of binary64 | |
| 5319 ** values. To begin, first compute a table of exponent values: | |
| 5320 ** | |
| 5321 ** CREATE TABLE pow2(x INTEGER PRIMARY KEY, v TEXT); | |
| 5322 ** WITH RECURSIVE c(x,v) AS ( | |
| 5323 ** VALUES(0,'1') | |
| 5324 ** UNION ALL | |
| 5325 ** SELECT x+1, decimal_mul(v,'2') FROM c WHERE x+1<=971 | |
| 5326 ** ) INSERT INTO pow2(x,v) SELECT x, v FROM c; | |
| 5327 ** WITH RECURSIVE c(x,v) AS ( | |
| 5328 ** VALUES(-1,'0.5') | |
| 5329 ** UNION ALL | |
| 5330 ** SELECT x-1, decimal_mul(v,'0.5') FROM c WHERE x-1>=-1075 | |
| 5331 ** ) INSERT INTO pow2(x,v) SELECT x, v FROM c; | |
| 5332 ** | |
| 5333 ** Then, to compute the exact decimal representation of a floating | |
| 5334 ** point value (the value 47.49 is used in the example) do: | |
| 5335 ** | |
| 5336 ** WITH c(n) AS (VALUES(47.49)) | |
| 5337 ** ---------------^^^^^---- Replace with whatever you want | |
| 5338 ** SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v) | |
| 5339 ** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n); | |
| 5340 ** | |
| 5341 ** Here is a query to show various boundry values for the binary64 | |
| 5342 ** number format: | |
| 5343 ** | |
| 5344 ** WITH c(name,bin) AS (VALUES | |
| 5345 ** ('minimum positive value', x'0000000000000001'), | |
| 5346 ** ('maximum subnormal value', x'000fffffffffffff'), | |
| 5347 ** ('minimum positive normal value', x'0010000000000000'), | |
| 5348 ** ('maximum value', x'7fefffffffffffff')) | |
| 5349 ** SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v) | |
| 5350 ** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin); | |
| 5351 ** | |
| 5352 */ | |
| 5353 /* #include "sqlite3ext.h" */ | |
| 5354 SQLITE_EXTENSION_INIT1 | |
| 5355 #include <assert.h> | |
| 5356 #include <string.h> | |
| 5357 | |
| 5358 /* Mark a function parameter as unused, to suppress nuisance compiler | |
| 5359 ** warnings. */ | |
| 5360 #ifndef UNUSED_PARAMETER | |
| 5361 # define UNUSED_PARAMETER(X) (void)(X) | |
| 5362 #endif | |
| 5363 | |
| 5364 /* | |
| 5365 ** Implementation of the ieee754() function | |
| 5366 */ | |
| 5367 static void ieee754func( | |
| 5368 sqlite3_context *context, | |
| 5369 int argc, | |
| 5370 sqlite3_value **argv | |
| 5371 ){ | |
| 5372 if( argc==1 ){ | |
| 5373 sqlite3_int64 m, a; | |
| 5374 double r; | |
| 5375 int e; | |
| 5376 int isNeg; | |
| 5377 char zResult[100]; | |
| 5378 assert( sizeof(m)==sizeof(r) ); | |
| 5379 if( sqlite3_value_type(argv[0])==SQLITE_BLOB | |
| 5380 && sqlite3_value_bytes(argv[0])==sizeof(r) | |
| 5381 ){ | |
| 5382 const unsigned char *x = sqlite3_value_blob(argv[0]); | |
| 5383 unsigned int i; | |
| 5384 sqlite3_uint64 v = 0; | |
| 5385 for(i=0; i<sizeof(r); i++){ | |
| 5386 v = (v<<8) | x[i]; | |
| 5387 } | |
| 5388 memcpy(&r, &v, sizeof(r)); | |
| 5389 }else{ | |
| 5390 r = sqlite3_value_double(argv[0]); | |
| 5391 } | |
| 5392 if( r<0.0 ){ | |
| 5393 isNeg = 1; | |
| 5394 r = -r; | |
| 5395 }else{ | |
| 5396 isNeg = 0; | |
| 5397 } | |
| 5398 memcpy(&a,&r,sizeof(a)); | |
| 5399 if( a==0 ){ | |
| 5400 e = 0; | |
| 5401 m = 0; | |
| 5402 }else if( a==(sqlite3_int64)0x8000000000000000LL ){ | |
| 5403 e = -1996; | |
| 5404 m = -1; | |
| 5405 }else{ | |
| 5406 e = a>>52; | |
| 5407 m = a & ((((sqlite3_int64)1)<<52)-1); | |
| 5408 if( e==0 ){ | |
| 5409 m <<= 1; | |
| 5410 }else{ | |
| 5411 m |= ((sqlite3_int64)1)<<52; | |
| 5412 } | |
| 5413 while( e<1075 && m>0 && (m&1)==0 ){ | |
| 5414 m >>= 1; | |
| 5415 e++; | |
| 5416 } | |
| 5417 if( isNeg ) m = -m; | |
| 5418 } | |
| 5419 switch( *(int*)sqlite3_user_data(context) ){ | |
| 5420 case 0: | |
| 5421 sqlite3_snprintf(sizeof(zResult), zResult, "ieee754(%lld,%d)", | |
| 5422 m, e-1075); | |
| 5423 sqlite3_result_text(context, zResult, -1, SQLITE_TRANSIENT); | |
| 5424 break; | |
| 5425 case 1: | |
| 5426 sqlite3_result_int64(context, m); | |
| 5427 break; | |
| 5428 case 2: | |
| 5429 sqlite3_result_int(context, e-1075); | |
| 5430 break; | |
| 5431 } | |
| 5432 }else{ | |
| 5433 sqlite3_int64 m, e, a; | |
| 5434 double r; | |
| 5435 int isNeg = 0; | |
| 5436 m = sqlite3_value_int64(argv[0]); | |
| 5437 e = sqlite3_value_int64(argv[1]); | |
| 5438 | |
| 5439 /* Limit the range of e. Ticket 22dea1cfdb9151e4 2021-03-02 */ | |
| 5440 if( e>10000 ){ | |
| 5441 e = 10000; | |
| 5442 }else if( e<-10000 ){ | |
| 5443 e = -10000; | |
| 5444 } | |
| 5445 | |
| 5446 if( m<0 ){ | |
| 5447 isNeg = 1; | |
| 5448 m = -m; | |
| 5449 if( m<0 ) return; | |
| 5450 }else if( m==0 && e>-1000 && e<1000 ){ | |
| 5451 sqlite3_result_double(context, 0.0); | |
| 5452 return; | |
| 5453 } | |
| 5454 while( (m>>32)&0xffe00000 ){ | |
| 5455 m >>= 1; | |
| 5456 e++; | |
| 5457 } | |
| 5458 while( m!=0 && ((m>>32)&0xfff00000)==0 ){ | |
| 5459 m <<= 1; | |
| 5460 e--; | |
| 5461 } | |
| 5462 e += 1075; | |
| 5463 if( e<=0 ){ | |
| 5464 /* Subnormal */ | |
| 5465 if( 1-e >= 64 ){ | |
| 5466 m = 0; | |
| 5467 }else{ | |
| 5468 m >>= 1-e; | |
| 5469 } | |
| 5470 e = 0; | |
| 5471 }else if( e>0x7ff ){ | |
| 5472 e = 0x7ff; | |
| 5473 } | |
| 5474 a = m & ((((sqlite3_int64)1)<<52)-1); | |
| 5475 a |= e<<52; | |
| 5476 if( isNeg ) a |= ((sqlite3_uint64)1)<<63; | |
| 5477 memcpy(&r, &a, sizeof(r)); | |
| 5478 sqlite3_result_double(context, r); | |
| 5479 } | |
| 5480 } | |
| 5481 | |
| 5482 /* | |
| 5483 ** Functions to convert between blobs and floats. | |
| 5484 */ | |
| 5485 static void ieee754func_from_blob( | |
| 5486 sqlite3_context *context, | |
| 5487 int argc, | |
| 5488 sqlite3_value **argv | |
| 5489 ){ | |
| 5490 UNUSED_PARAMETER(argc); | |
| 5491 if( sqlite3_value_type(argv[0])==SQLITE_BLOB | |
| 5492 && sqlite3_value_bytes(argv[0])==sizeof(double) | |
| 5493 ){ | |
| 5494 double r; | |
| 5495 const unsigned char *x = sqlite3_value_blob(argv[0]); | |
| 5496 unsigned int i; | |
| 5497 sqlite3_uint64 v = 0; | |
| 5498 for(i=0; i<sizeof(r); i++){ | |
| 5499 v = (v<<8) | x[i]; | |
| 5500 } | |
| 5501 memcpy(&r, &v, sizeof(r)); | |
| 5502 sqlite3_result_double(context, r); | |
| 5503 } | |
| 5504 } | |
| 5505 static void ieee754func_to_blob( | |
| 5506 sqlite3_context *context, | |
| 5507 int argc, | |
| 5508 sqlite3_value **argv | |
| 5509 ){ | |
| 5510 UNUSED_PARAMETER(argc); | |
| 5511 if( sqlite3_value_type(argv[0])==SQLITE_FLOAT | |
| 5512 || sqlite3_value_type(argv[0])==SQLITE_INTEGER | |
| 5513 ){ | |
| 5514 double r = sqlite3_value_double(argv[0]); | |
| 5515 sqlite3_uint64 v; | |
| 5516 unsigned char a[sizeof(r)]; | |
| 5517 unsigned int i; | |
| 5518 memcpy(&v, &r, sizeof(r)); | |
| 5519 for(i=1; i<=sizeof(r); i++){ | |
| 5520 a[sizeof(r)-i] = v&0xff; | |
| 5521 v >>= 8; | |
| 5522 } | |
| 5523 sqlite3_result_blob(context, a, sizeof(r), SQLITE_TRANSIENT); | |
| 5524 } | |
| 5525 } | |
| 5526 | |
| 5527 /* | |
| 5528 ** SQL Function: ieee754_inc(r,N) | |
| 5529 ** | |
| 5530 ** Move the floating point value r by N quantums and return the new | |
| 5531 ** values. | |
| 5532 ** | |
| 5533 ** Behind the scenes: this routine merely casts r into a 64-bit unsigned | |
| 5534 ** integer, adds N, then casts the value back into float. | |
| 5535 ** | |
| 5536 ** Example: To find the smallest positive number: | |
| 5537 ** | |
| 5538 ** SELECT ieee754_inc(0.0,+1); | |
| 5539 */ | |
| 5540 static void ieee754inc( | |
| 5541 sqlite3_context *context, | |
| 5542 int argc, | |
| 5543 sqlite3_value **argv | |
| 5544 ){ | |
| 5545 double r; | |
| 5546 sqlite3_int64 N; | |
| 5547 sqlite3_uint64 m1, m2; | |
| 5548 double r2; | |
| 5549 UNUSED_PARAMETER(argc); | |
| 5550 r = sqlite3_value_double(argv[0]); | |
| 5551 N = sqlite3_value_int64(argv[1]); | |
| 5552 memcpy(&m1, &r, 8); | |
| 5553 m2 = m1 + N; | |
| 5554 memcpy(&r2, &m2, 8); | |
| 5555 sqlite3_result_double(context, r2); | |
| 5556 } | |
| 5557 | |
| 5558 | |
| 5559 #ifdef _WIN32 | |
| 5560 | |
| 5561 #endif | |
| 5562 int sqlite3_ieee_init( | |
| 5563 sqlite3 *db, | |
| 5564 char **pzErrMsg, | |
| 5565 const sqlite3_api_routines *pApi | |
| 5566 ){ | |
| 5567 static const struct { | |
| 5568 char *zFName; | |
| 5569 int nArg; | |
| 5570 int iAux; | |
| 5571 void (*xFunc)(sqlite3_context*,int,sqlite3_value**); | |
| 5572 } aFunc[] = { | |
| 5573 { "ieee754", 1, 0, ieee754func }, | |
| 5574 { "ieee754", 2, 0, ieee754func }, | |
| 5575 { "ieee754_mantissa", 1, 1, ieee754func }, | |
| 5576 { "ieee754_exponent", 1, 2, ieee754func }, | |
| 5577 { "ieee754_to_blob", 1, 0, ieee754func_to_blob }, | |
| 5578 { "ieee754_from_blob", 1, 0, ieee754func_from_blob }, | |
| 5579 { "ieee754_inc", 2, 0, ieee754inc }, | |
| 5580 }; | |
| 5581 unsigned int i; | |
| 5582 int rc = SQLITE_OK; | |
| 5583 SQLITE_EXTENSION_INIT2(pApi); | |
| 5584 (void)pzErrMsg; /* Unused parameter */ | |
| 5585 for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){ | |
| 5586 rc = sqlite3_create_function(db, aFunc[i].zFName, aFunc[i].nArg, | |
| 5587 SQLITE_UTF8|SQLITE_INNOCUOUS, | |
| 5588 (void*)&aFunc[i].iAux, | |
| 5589 aFunc[i].xFunc, 0, 0); | |
| 5590 } | |
| 5591 return rc; | |
| 5592 } | |
| 5593 | |
| 5594 /************************* End ../ext/misc/ieee754.c ********************/ | |
| 5595 /************************* Begin ../ext/misc/series.c ******************/ | |
| 5596 /* | |
| 5597 ** 2015-08-18, 2023-04-28 | |
| 5598 ** | |
| 5599 ** The author disclaims copyright to this source code. In place of | |
| 5600 ** a legal notice, here is a blessing: | |
| 5601 ** | |
| 5602 ** May you do good and not evil. | |
| 5603 ** May you find forgiveness for yourself and forgive others. | |
| 5604 ** May you share freely, never taking more than you give. | |
| 5605 ** | |
| 5606 ************************************************************************* | |
| 5607 ** | |
| 5608 ** This file demonstrates how to create a table-valued-function using | |
| 5609 ** a virtual table. This demo implements the generate_series() function | |
| 5610 ** which gives the same results as the eponymous function in PostgreSQL, | |
| 5611 ** within the limitation that its arguments are signed 64-bit integers. | |
| 5612 ** | |
| 5613 ** Considering its equivalents to generate_series(start,stop,step): A | |
| 5614 ** value V[n] sequence is produced for integer n ascending from 0 where | |
| 5615 ** ( V[n] == start + n * step && sgn(V[n] - stop) * sgn(step) >= 0 ) | |
| 5616 ** for each produced value (independent of production time ordering.) | |
| 5617 ** | |
| 5618 ** All parameters must be either integer or convertable to integer. | |
| 5619 ** The start parameter is required. | |
| 5620 ** The stop parameter defaults to (1<<32)-1 (aka 4294967295 or 0xffffffff) | |
| 5621 ** The step parameter defaults to 1 and 0 is treated as 1. | |
| 5622 ** | |
| 5623 ** Examples: | |
| 5624 ** | |
| 5625 ** SELECT * FROM generate_series(0,100,5); | |
| 5626 ** | |
| 5627 ** The query above returns integers from 0 through 100 counting by steps | |
| 5628 ** of 5. In other words, 0, 5, 10, 15, ..., 90, 95, 100. There are a total | |
| 5629 ** of 21 rows. | |
| 5630 ** | |
| 5631 ** SELECT * FROM generate_series(0,100); | |
| 5632 ** | |
| 5633 ** Integers from 0 through 100 with a step size of 1. 101 rows. | |
| 5634 ** | |
| 5635 ** SELECT * FROM generate_series(20) LIMIT 10; | |
| 5636 ** | |
| 5637 ** Integers 20 through 29. 10 rows. | |
| 5638 ** | |
| 5639 ** SELECT * FROM generate_series(0,-100,-5); | |
| 5640 ** | |
| 5641 ** Integers 0 -5 -10 ... -100. 21 rows. | |
| 5642 ** | |
| 5643 ** SELECT * FROM generate_series(0,-1); | |
| 5644 ** | |
| 5645 ** Empty sequence. | |
| 5646 ** | |
| 5647 ** HOW IT WORKS | |
| 5648 ** | |
| 5649 ** The generate_series "function" is really a virtual table with the | |
| 5650 ** following schema: | |
| 5651 ** | |
| 5652 ** CREATE TABLE generate_series( | |
| 5653 ** value, | |
| 5654 ** start HIDDEN, | |
| 5655 ** stop HIDDEN, | |
| 5656 ** step HIDDEN | |
| 5657 ** ); | |
| 5658 ** | |
| 5659 ** The virtual table also has a rowid which is an alias for the value. | |
| 5660 ** | |
| 5661 ** Function arguments in queries against this virtual table are translated | |
| 5662 ** into equality constraints against successive hidden columns. In other | |
| 5663 ** words, the following pairs of queries are equivalent to each other: | |
| 5664 ** | |
| 5665 ** SELECT * FROM generate_series(0,100,5); | |
| 5666 ** SELECT * FROM generate_series WHERE start=0 AND stop=100 AND step=5; | |
| 5667 ** | |
| 5668 ** SELECT * FROM generate_series(0,100); | |
| 5669 ** SELECT * FROM generate_series WHERE start=0 AND stop=100; | |
| 5670 ** | |
| 5671 ** SELECT * FROM generate_series(20) LIMIT 10; | |
| 5672 ** SELECT * FROM generate_series WHERE start=20 LIMIT 10; | |
| 5673 ** | |
| 5674 ** The generate_series virtual table implementation leaves the xCreate method | |
| 5675 ** set to NULL. This means that it is not possible to do a CREATE VIRTUAL | |
| 5676 ** TABLE command with "generate_series" as the USING argument. Instead, there | |
| 5677 ** is a single generate_series virtual table that is always available without | |
| 5678 ** having to be created first. | |
| 5679 ** | |
| 5680 ** The xBestIndex method looks for equality constraints against the hidden | |
| 5681 ** start, stop, and step columns, and if present, it uses those constraints | |
| 5682 ** to bound the sequence of generated values. If the equality constraints | |
| 5683 ** are missing, it uses 0 for start, 4294967295 for stop, and 1 for step. | |
| 5684 ** xBestIndex returns a small cost when both start and stop are available, | |
| 5685 ** and a very large cost if either start or stop are unavailable. This | |
| 5686 ** encourages the query planner to order joins such that the bounds of the | |
| 5687 ** series are well-defined. | |
| 5688 ** | |
| 5689 ** Update on 2024-08-22: | |
| 5690 ** xBestIndex now also looks for equality and inequality constraints against | |
| 5691 ** the value column and uses those constraints as additional bounds against | |
| 5692 ** the sequence range. Thus, a query like this: | |
| 5693 ** | |
| 5694 ** SELECT value FROM generate_series($SA,$EA) | |
| 5695 ** WHERE value BETWEEN $SB AND $EB; | |
| 5696 ** | |
| 5697 ** Is logically the same as: | |
| 5698 ** | |
| 5699 ** SELECT value FROM generate_series(max($SA,$SB),min($EA,$EB)); | |
| 5700 ** | |
| 5701 ** Constraints on the value column can server as substitutes for constraints | |
| 5702 ** on the hidden start and stop columns. So, the following two queries | |
| 5703 ** are equivalent: | |
| 5704 ** | |
| 5705 ** SELECT value FROM generate_series($S,$E); | |
| 5706 ** SELECT value FROM generate_series WHERE value BETWEEN $S and $E; | |
| 5707 ** | |
| 5708 */ | |
| 5709 /* #include "sqlite3ext.h" */ | |
| 5710 SQLITE_EXTENSION_INIT1 | |
| 5711 #include <assert.h> | |
| 5712 #include <string.h> | |
| 5713 #include <limits.h> | |
| 5714 #include <math.h> | |
| 5715 | |
| 5716 #ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 5717 | |
| 5718 /* series_cursor is a subclass of sqlite3_vtab_cursor which will | |
| 5719 ** serve as the underlying representation of a cursor that scans | |
| 5720 ** over rows of the result. | |
| 5721 ** | |
| 5722 ** iOBase, iOTerm, and iOStep are the original values of the | |
| 5723 ** start=, stop=, and step= constraints on the query. These are | |
| 5724 ** the values reported by the start, stop, and step columns of the | |
| 5725 ** virtual table. | |
| 5726 ** | |
| 5727 ** iBase, iTerm, iStep, and bDescp are the actual values used to generate | |
| 5728 ** the sequence. These might be different from the iOxxxx values. | |
| 5729 ** For example in | |
| 5730 ** | |
| 5731 ** SELECT value FROM generate_series(1,11,2) | |
| 5732 ** WHERE value BETWEEN 4 AND 8; | |
| 5733 ** | |
| 5734 ** The iOBase is 1, but the iBase is 5. iOTerm is 11 but iTerm is 7. | |
| 5735 ** Another example: | |
| 5736 ** | |
| 5737 ** SELECT value FROM generate_series(1,15,3) ORDER BY value DESC; | |
| 5738 ** | |
| 5739 ** The cursor initialization for the above query is: | |
| 5740 ** | |
| 5741 ** iOBase = 1 iBase = 13 | |
| 5742 ** iOTerm = 15 iTerm = 1 | |
| 5743 ** iOStep = 3 iStep = 3 bDesc = 1 | |
| 5744 ** | |
| 5745 ** The actual step size is unsigned so that can have a value of | |
| 5746 ** +9223372036854775808 which is needed for querys like this: | |
| 5747 ** | |
| 5748 ** SELECT value | |
| 5749 ** FROM generate_series(9223372036854775807, | |
| 5750 ** -9223372036854775808, | |
| 5751 ** -9223372036854775808) | |
| 5752 ** ORDER BY value ASC; | |
| 5753 ** | |
| 5754 ** The setup for the previous query will be: | |
| 5755 ** | |
| 5756 ** iOBase = 9223372036854775807 iBase = -1 | |
| 5757 ** iOTerm = -9223372036854775808 iTerm = 9223372036854775807 | |
| 5758 ** iOStep = -9223372036854775808 iStep = 9223372036854775808 bDesc = 0 | |
| 5759 */ | |
| 5760 /* typedef unsigned char u8; */ | |
| 5761 typedef struct series_cursor series_cursor; | |
| 5762 struct series_cursor { | |
| 5763 sqlite3_vtab_cursor base; /* Base class - must be first */ | |
| 5764 sqlite3_int64 iOBase; /* Original starting value ("start") */ | |
| 5765 sqlite3_int64 iOTerm; /* Original terminal value ("stop") */ | |
| 5766 sqlite3_int64 iOStep; /* Original step value */ | |
| 5767 sqlite3_int64 iBase; /* Starting value to actually use */ | |
| 5768 sqlite3_int64 iTerm; /* Terminal value to actually use */ | |
| 5769 sqlite3_uint64 iStep; /* The step size */ | |
| 5770 sqlite3_int64 iValue; /* Current value */ | |
| 5771 u8 bDesc; /* iStep is really negative */ | |
| 5772 u8 bDone; /* True if stepped past last element */ | |
| 5773 }; | |
| 5774 | |
| 5775 /* | |
| 5776 ** Computed the difference between two 64-bit signed integers using a | |
| 5777 ** convoluted computation designed to work around the silly restriction | |
| 5778 ** against signed integer overflow in C. | |
| 5779 */ | |
| 5780 static sqlite3_uint64 span64(sqlite3_int64 a, sqlite3_int64 b){ | |
| 5781 assert( a>=b ); | |
| 5782 return (*(sqlite3_uint64*)&a) - (*(sqlite3_uint64*)&b); | |
| 5783 } | |
| 5784 | |
| 5785 /* | |
| 5786 ** Add or substract an unsigned 64-bit integer from a signed 64-bit integer | |
| 5787 ** and return the new signed 64-bit integer. | |
| 5788 */ | |
| 5789 static sqlite3_int64 add64(sqlite3_int64 a, sqlite3_uint64 b){ | |
| 5790 sqlite3_uint64 x = *(sqlite3_uint64*)&a; | |
| 5791 x += b; | |
| 5792 return *(sqlite3_int64*)&x; | |
| 5793 } | |
| 5794 static sqlite3_int64 sub64(sqlite3_int64 a, sqlite3_uint64 b){ | |
| 5795 sqlite3_uint64 x = *(sqlite3_uint64*)&a; | |
| 5796 x -= b; | |
| 5797 return *(sqlite3_int64*)&x; | |
| 5798 } | |
| 5799 | |
| 5800 /* | |
| 5801 ** The seriesConnect() method is invoked to create a new | |
| 5802 ** series_vtab that describes the generate_series virtual table. | |
| 5803 ** | |
| 5804 ** Think of this routine as the constructor for series_vtab objects. | |
| 5805 ** | |
| 5806 ** All this routine needs to do is: | |
| 5807 ** | |
| 5808 ** (1) Allocate the series_vtab object and initialize all fields. | |
| 5809 ** | |
| 5810 ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the | |
| 5811 ** result set of queries against generate_series will look like. | |
| 5812 */ | |
| 5813 static int seriesConnect( | |
| 5814 sqlite3 *db, | |
| 5815 void *pUnused, | |
| 5816 int argcUnused, const char *const*argvUnused, | |
| 5817 sqlite3_vtab **ppVtab, | |
| 5818 char **pzErrUnused | |
| 5819 ){ | |
| 5820 sqlite3_vtab *pNew; | |
| 5821 int rc; | |
| 5822 | |
| 5823 /* Column numbers */ | |
| 5824 #define SERIES_COLUMN_ROWID (-1) | |
| 5825 #define SERIES_COLUMN_VALUE 0 | |
| 5826 #define SERIES_COLUMN_START 1 | |
| 5827 #define SERIES_COLUMN_STOP 2 | |
| 5828 #define SERIES_COLUMN_STEP 3 | |
| 5829 | |
| 5830 (void)pUnused; | |
| 5831 (void)argcUnused; | |
| 5832 (void)argvUnused; | |
| 5833 (void)pzErrUnused; | |
| 5834 rc = sqlite3_declare_vtab(db, | |
| 5835 "CREATE TABLE x(value,start hidden,stop hidden,step hidden)"); | |
| 5836 if( rc==SQLITE_OK ){ | |
| 5837 pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); | |
| 5838 if( pNew==0 ) return SQLITE_NOMEM; | |
| 5839 memset(pNew, 0, sizeof(*pNew)); | |
| 5840 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); | |
| 5841 } | |
| 5842 return rc; | |
| 5843 } | |
| 5844 | |
| 5845 /* | |
| 5846 ** This method is the destructor for series_cursor objects. | |
| 5847 */ | |
| 5848 static int seriesDisconnect(sqlite3_vtab *pVtab){ | |
| 5849 sqlite3_free(pVtab); | |
| 5850 return SQLITE_OK; | |
| 5851 } | |
| 5852 | |
| 5853 /* | |
| 5854 ** Constructor for a new series_cursor object. | |
| 5855 */ | |
| 5856 static int seriesOpen(sqlite3_vtab *pUnused, sqlite3_vtab_cursor **ppCursor){ | |
| 5857 series_cursor *pCur; | |
| 5858 (void)pUnused; | |
| 5859 pCur = sqlite3_malloc( sizeof(*pCur) ); | |
| 5860 if( pCur==0 ) return SQLITE_NOMEM; | |
| 5861 memset(pCur, 0, sizeof(*pCur)); | |
| 5862 *ppCursor = &pCur->base; | |
| 5863 return SQLITE_OK; | |
| 5864 } | |
| 5865 | |
| 5866 /* | |
| 5867 ** Destructor for a series_cursor. | |
| 5868 */ | |
| 5869 static int seriesClose(sqlite3_vtab_cursor *cur){ | |
| 5870 sqlite3_free(cur); | |
| 5871 return SQLITE_OK; | |
| 5872 } | |
| 5873 | |
| 5874 | |
| 5875 /* | |
| 5876 ** Advance a series_cursor to its next row of output. | |
| 5877 */ | |
| 5878 static int seriesNext(sqlite3_vtab_cursor *cur){ | |
| 5879 series_cursor *pCur = (series_cursor*)cur; | |
| 5880 if( pCur->iValue==pCur->iTerm ){ | |
| 5881 pCur->bDone = 1; | |
| 5882 }else if( pCur->bDesc ){ | |
| 5883 pCur->iValue = sub64(pCur->iValue, pCur->iStep); | |
| 5884 assert( pCur->iValue>=pCur->iTerm ); | |
| 5885 }else{ | |
| 5886 pCur->iValue = add64(pCur->iValue, pCur->iStep); | |
| 5887 assert( pCur->iValue<=pCur->iTerm ); | |
| 5888 } | |
| 5889 return SQLITE_OK; | |
| 5890 } | |
| 5891 | |
| 5892 /* | |
| 5893 ** Return values of columns for the row at which the series_cursor | |
| 5894 ** is currently pointing. | |
| 5895 */ | |
| 5896 static int seriesColumn( | |
| 5897 sqlite3_vtab_cursor *cur, /* The cursor */ | |
| 5898 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ | |
| 5899 int i /* Which column to return */ | |
| 5900 ){ | |
| 5901 series_cursor *pCur = (series_cursor*)cur; | |
| 5902 sqlite3_int64 x = 0; | |
| 5903 switch( i ){ | |
| 5904 case SERIES_COLUMN_START: x = pCur->iOBase; break; | |
| 5905 case SERIES_COLUMN_STOP: x = pCur->iOTerm; break; | |
| 5906 case SERIES_COLUMN_STEP: x = pCur->iOStep; break; | |
| 5907 default: x = pCur->iValue; break; | |
| 5908 } | |
| 5909 sqlite3_result_int64(ctx, x); | |
| 5910 return SQLITE_OK; | |
| 5911 } | |
| 5912 | |
| 5913 #ifndef LARGEST_UINT64 | |
| 5914 #define LARGEST_INT64 ((sqlite3_int64)0x7fffffffffffffffLL) | |
| 5915 #define LARGEST_UINT64 ((sqlite3_uint64)0xffffffffffffffffULL) | |
| 5916 #define SMALLEST_INT64 ((sqlite3_int64)0x8000000000000000LL) | |
| 5917 #endif | |
| 5918 | |
| 5919 /* | |
| 5920 ** The rowid is the same as the value. | |
| 5921 */ | |
| 5922 static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ | |
| 5923 series_cursor *pCur = (series_cursor*)cur; | |
| 5924 *pRowid = pCur->iValue; | |
| 5925 return SQLITE_OK; | |
| 5926 } | |
| 5927 | |
| 5928 /* | |
| 5929 ** Return TRUE if the cursor has been moved off of the last | |
| 5930 ** row of output. | |
| 5931 */ | |
| 5932 static int seriesEof(sqlite3_vtab_cursor *cur){ | |
| 5933 series_cursor *pCur = (series_cursor*)cur; | |
| 5934 return pCur->bDone; | |
| 5935 } | |
| 5936 | |
| 5937 /* True to cause run-time checking of the start=, stop=, and/or step= | |
| 5938 ** parameters. The only reason to do this is for testing the | |
| 5939 ** constraint checking logic for virtual tables in the SQLite core. | |
| 5940 */ | |
| 5941 #ifndef SQLITE_SERIES_CONSTRAINT_VERIFY | |
| 5942 # define SQLITE_SERIES_CONSTRAINT_VERIFY 0 | |
| 5943 #endif | |
| 5944 | |
| 5945 /* | |
| 5946 ** Return the number of steps between pCur->iBase and pCur->iTerm if | |
| 5947 ** the step width is pCur->iStep. | |
| 5948 */ | |
| 5949 static sqlite3_uint64 seriesSteps(series_cursor *pCur){ | |
| 5950 if( pCur->bDesc ){ | |
| 5951 assert( pCur->iBase >= pCur->iTerm ); | |
| 5952 return span64(pCur->iBase, pCur->iTerm)/pCur->iStep; | |
| 5953 }else{ | |
| 5954 assert( pCur->iBase <= pCur->iTerm ); | |
| 5955 return span64(pCur->iTerm, pCur->iBase)/pCur->iStep; | |
| 5956 } | |
| 5957 } | |
| 5958 | |
| 5959 #if defined(SQLITE_ENABLE_MATH_FUNCTIONS) || defined(_WIN32) | |
| 5960 /* | |
| 5961 ** Case 1 (the most common case): | |
| 5962 ** The standard math library is available so use ceil() and floor() from there. | |
| 5963 */ | |
| 5964 static double seriesCeil(double r){ return ceil(r); } | |
| 5965 static double seriesFloor(double r){ return floor(r); } | |
| 5966 #elif defined(__GNUC__) && !defined(SQLITE_DISABLE_INTRINSIC) | |
| 5967 /* | |
| 5968 ** Case 2 (2nd most common): Use GCC/Clang builtins | |
| 5969 */ | |
| 5970 static double seriesCeil(double r){ return __builtin_ceil(r); } | |
| 5971 static double seriesFloor(double r){ return __builtin_floor(r); } | |
| 5972 #else | |
| 5973 /* | |
| 5974 ** Case 3 (rarely happens): Use home-grown ceil() and floor() routines. | |
| 5975 */ | |
| 5976 static double seriesCeil(double r){ | |
| 5977 sqlite3_int64 x; | |
| 5978 if( r!=r ) return r; | |
| 5979 if( r<=(-4503599627370496.0) ) return r; | |
| 5980 if( r>=(+4503599627370496.0) ) return r; | |
| 5981 x = (sqlite3_int64)r; | |
| 5982 if( r==(double)x ) return r; | |
| 5983 if( r>(double)x ) x++; | |
| 5984 return (double)x; | |
| 5985 } | |
| 5986 static double seriesFloor(double r){ | |
| 5987 sqlite3_int64 x; | |
| 5988 if( r!=r ) return r; | |
| 5989 if( r<=(-4503599627370496.0) ) return r; | |
| 5990 if( r>=(+4503599627370496.0) ) return r; | |
| 5991 x = (sqlite3_int64)r; | |
| 5992 if( r==(double)x ) return r; | |
| 5993 if( r<(double)x ) x--; | |
| 5994 return (double)x; | |
| 5995 } | |
| 5996 #endif | |
| 5997 | |
| 5998 /* | |
| 5999 ** This method is called to "rewind" the series_cursor object back | |
| 6000 ** to the first row of output. This method is always called at least | |
| 6001 ** once prior to any call to seriesColumn() or seriesRowid() or | |
| 6002 ** seriesEof(). | |
| 6003 ** | |
| 6004 ** The query plan selected by seriesBestIndex is passed in the idxNum | |
| 6005 ** parameter. (idxStr is not used in this implementation.) idxNum | |
| 6006 ** is a bitmask showing which constraints are available: | |
| 6007 ** | |
| 6008 ** 0x0001: start=VALUE | |
| 6009 ** 0x0002: stop=VALUE | |
| 6010 ** 0x0004: step=VALUE | |
| 6011 ** 0x0008: descending order | |
| 6012 ** 0x0010: ascending order | |
| 6013 ** 0x0020: LIMIT VALUE | |
| 6014 ** 0x0040: OFFSET VALUE | |
| 6015 ** 0x0080: value=VALUE | |
| 6016 ** 0x0100: value>=VALUE | |
| 6017 ** 0x0200: value>VALUE | |
| 6018 ** 0x1000: value<=VALUE | |
| 6019 ** 0x2000: value<VALUE | |
| 6020 ** | |
| 6021 ** This routine should initialize the cursor and position it so that it | |
| 6022 ** is pointing at the first row, or pointing off the end of the table | |
| 6023 ** (so that seriesEof() will return true) if the table is empty. | |
| 6024 */ | |
| 6025 static int seriesFilter( | |
| 6026 sqlite3_vtab_cursor *pVtabCursor, | |
| 6027 int idxNum, const char *idxStrUnused, | |
| 6028 int argc, sqlite3_value **argv | |
| 6029 ){ | |
| 6030 series_cursor *pCur = (series_cursor *)pVtabCursor; | |
| 6031 int iArg = 0; /* Arguments used so far */ | |
| 6032 int i; /* Loop counter */ | |
| 6033 sqlite3_int64 iMin = SMALLEST_INT64; /* Smallest allowed output value */ | |
| 6034 sqlite3_int64 iMax = LARGEST_INT64; /* Largest allowed output value */ | |
| 6035 sqlite3_int64 iLimit = 0; /* if >0, the value of the LIMIT */ | |
| 6036 sqlite3_int64 iOffset = 0; /* if >0, the value of the OFFSET */ | |
| 6037 | |
| 6038 (void)idxStrUnused; | |
| 6039 | |
| 6040 /* If any constraints have a NULL value, then return no rows. | |
| 6041 ** See ticket https://sqlite.org/src/info/fac496b61722daf2 | |
| 6042 */ | |
| 6043 for(i=0; i<argc; i++){ | |
| 6044 if( sqlite3_value_type(argv[i])==SQLITE_NULL ){ | |
| 6045 goto series_no_rows; | |
| 6046 } | |
| 6047 } | |
| 6048 | |
| 6049 /* Capture the three HIDDEN parameters to the virtual table and insert | |
| 6050 ** default values for any parameters that are omitted. | |
| 6051 */ | |
| 6052 if( idxNum & 0x01 ){ | |
| 6053 pCur->iOBase = sqlite3_value_int64(argv[iArg++]); | |
| 6054 }else{ | |
| 6055 pCur->iOBase = 0; | |
| 6056 } | |
| 6057 if( idxNum & 0x02 ){ | |
| 6058 pCur->iOTerm = sqlite3_value_int64(argv[iArg++]); | |
| 6059 }else{ | |
| 6060 pCur->iOTerm = 0xffffffff; | |
| 6061 } | |
| 6062 if( idxNum & 0x04 ){ | |
| 6063 pCur->iOStep = sqlite3_value_int64(argv[iArg++]); | |
| 6064 if( pCur->iOStep==0 ) pCur->iOStep = 1; | |
| 6065 }else{ | |
| 6066 pCur->iOStep = 1; | |
| 6067 } | |
| 6068 | |
| 6069 /* If there are constraints on the value column but there are | |
| 6070 ** no constraints on the start, stop, and step columns, then | |
| 6071 ** initialize the default range to be the entire range of 64-bit signed | |
| 6072 ** integers. This range will contracted by the value column constraints | |
| 6073 ** further below. | |
| 6074 */ | |
| 6075 if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){ | |
| 6076 pCur->iOBase = SMALLEST_INT64; | |
| 6077 } | |
| 6078 if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){ | |
| 6079 pCur->iOTerm = LARGEST_INT64; | |
| 6080 } | |
| 6081 pCur->iBase = pCur->iOBase; | |
| 6082 pCur->iTerm = pCur->iOTerm; | |
| 6083 if( pCur->iOStep>0 ){ | |
| 6084 pCur->iStep = pCur->iOStep; | |
| 6085 }else if( pCur->iOStep>SMALLEST_INT64 ){ | |
| 6086 pCur->iStep = -pCur->iOStep; | |
| 6087 }else{ | |
| 6088 pCur->iStep = LARGEST_INT64; | |
| 6089 pCur->iStep++; | |
| 6090 } | |
| 6091 pCur->bDesc = pCur->iOStep<0; | |
| 6092 if( pCur->bDesc==0 && pCur->iBase>pCur->iTerm ){ | |
| 6093 goto series_no_rows; | |
| 6094 } | |
| 6095 if( pCur->bDesc!=0 && pCur->iBase<pCur->iTerm ){ | |
| 6096 goto series_no_rows; | |
| 6097 } | |
| 6098 | |
| 6099 /* Extract the LIMIT and OFFSET values, but do not apply them yet. | |
| 6100 ** The range must first be constrained by the limits on value. | |
| 6101 */ | |
| 6102 if( idxNum & 0x20 ){ | |
| 6103 iLimit = sqlite3_value_int64(argv[iArg++]); | |
| 6104 if( idxNum & 0x40 ){ | |
| 6105 iOffset = sqlite3_value_int64(argv[iArg++]); | |
| 6106 } | |
| 6107 } | |
| 6108 | |
| 6109 /* Narrow the range of iMin and iMax (the minimum and maximum outputs) | |
| 6110 ** based on equality and inequality constraints on the "value" column. | |
| 6111 */ | |
| 6112 if( idxNum & 0x3380 ){ | |
| 6113 if( idxNum & 0x0080 ){ /* value=X */ | |
| 6114 if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ | |
| 6115 double r = sqlite3_value_double(argv[iArg++]); | |
| 6116 if( r==seriesCeil(r) | |
| 6117 && r>=(double)SMALLEST_INT64 | |
| 6118 && r<=(double)LARGEST_INT64 | |
| 6119 ){ | |
| 6120 iMin = iMax = (sqlite3_int64)r; | |
| 6121 }else{ | |
| 6122 goto series_no_rows; | |
| 6123 } | |
| 6124 }else{ | |
| 6125 iMin = iMax = sqlite3_value_int64(argv[iArg++]); | |
| 6126 } | |
| 6127 }else{ | |
| 6128 if( idxNum & 0x0300 ){ /* value>X or value>=X */ | |
| 6129 if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ | |
| 6130 double r = sqlite3_value_double(argv[iArg++]); | |
| 6131 if( r<(double)SMALLEST_INT64 ){ | |
| 6132 iMin = SMALLEST_INT64; | |
| 6133 }else if( (idxNum & 0x0200)!=0 && r==seriesCeil(r) ){ | |
| 6134 iMin = (sqlite3_int64)seriesCeil(r+1.0); | |
| 6135 }else{ | |
| 6136 iMin = (sqlite3_int64)seriesCeil(r); | |
| 6137 } | |
| 6138 }else{ | |
| 6139 iMin = sqlite3_value_int64(argv[iArg++]); | |
| 6140 if( (idxNum & 0x0200)!=0 ){ | |
| 6141 if( iMin==LARGEST_INT64 ){ | |
| 6142 goto series_no_rows; | |
| 6143 }else{ | |
| 6144 iMin++; | |
| 6145 } | |
| 6146 } | |
| 6147 } | |
| 6148 } | |
| 6149 if( idxNum & 0x3000 ){ /* value<X or value<=X */ | |
| 6150 if( sqlite3_value_numeric_type(argv[iArg])==SQLITE_FLOAT ){ | |
| 6151 double r = sqlite3_value_double(argv[iArg++]); | |
| 6152 if( r>(double)LARGEST_INT64 ){ | |
| 6153 iMax = LARGEST_INT64; | |
| 6154 }else if( (idxNum & 0x2000)!=0 && r==seriesFloor(r) ){ | |
| 6155 iMax = (sqlite3_int64)(r-1.0); | |
| 6156 }else{ | |
| 6157 iMax = (sqlite3_int64)seriesFloor(r); | |
| 6158 } | |
| 6159 }else{ | |
| 6160 iMax = sqlite3_value_int64(argv[iArg++]); | |
| 6161 if( idxNum & 0x2000 ){ | |
| 6162 if( iMax==SMALLEST_INT64 ){ | |
| 6163 goto series_no_rows; | |
| 6164 }else{ | |
| 6165 iMax--; | |
| 6166 } | |
| 6167 } | |
| 6168 } | |
| 6169 } | |
| 6170 if( iMin>iMax ){ | |
| 6171 goto series_no_rows; | |
| 6172 } | |
| 6173 } | |
| 6174 | |
| 6175 /* Try to reduce the range of values to be generated based on | |
| 6176 ** constraints on the "value" column. | |
| 6177 */ | |
| 6178 if( pCur->bDesc==0 ){ | |
| 6179 if( pCur->iBase<iMin ){ | |
| 6180 sqlite3_uint64 span = span64(iMin,pCur->iBase); | |
| 6181 pCur->iBase = add64(pCur->iBase, (span/pCur->iStep)*pCur->iStep); | |
| 6182 if( pCur->iBase<iMin ){ | |
| 6183 if( pCur->iBase > sub64(LARGEST_INT64, pCur->iStep) ){ | |
| 6184 goto series_no_rows; | |
| 6185 } | |
| 6186 pCur->iBase = add64(pCur->iBase, pCur->iStep); | |
| 6187 } | |
| 6188 } | |
| 6189 if( pCur->iTerm>iMax ){ | |
| 6190 pCur->iTerm = iMax; | |
| 6191 } | |
| 6192 }else{ | |
| 6193 if( pCur->iBase>iMax ){ | |
| 6194 sqlite3_uint64 span = span64(pCur->iBase,iMax); | |
| 6195 pCur->iBase = sub64(pCur->iBase, (span/pCur->iStep)*pCur->iStep); | |
| 6196 if( pCur->iBase>iMax ){ | |
| 6197 if( pCur->iBase < add64(SMALLEST_INT64, pCur->iStep) ){ | |
| 6198 goto series_no_rows; | |
| 6199 } | |
| 6200 pCur->iBase = sub64(pCur->iBase, pCur->iStep); | |
| 6201 } | |
| 6202 } | |
| 6203 if( pCur->iTerm<iMin ){ | |
| 6204 pCur->iTerm = iMin; | |
| 6205 } | |
| 6206 } | |
| 6207 } | |
| 6208 | |
| 6209 /* Adjust iTerm so that it is exactly the last value of the series. | |
| 6210 */ | |
| 6211 if( pCur->bDesc==0 ){ | |
| 6212 if( pCur->iBase>pCur->iTerm ){ | |
| 6213 goto series_no_rows; | |
| 6214 } | |
| 6215 pCur->iTerm = sub64(pCur->iTerm, | |
| 6216 span64(pCur->iTerm,pCur->iBase) % pCur->iStep); | |
| 6217 }else{ | |
| 6218 if( pCur->iBase<pCur->iTerm ){ | |
| 6219 goto series_no_rows; | |
| 6220 } | |
| 6221 pCur->iTerm = add64(pCur->iTerm, | |
| 6222 span64(pCur->iBase,pCur->iTerm) % pCur->iStep); | |
| 6223 } | |
| 6224 | |
| 6225 /* Transform the series generator to output values in the requested | |
| 6226 ** order. | |
| 6227 */ | |
| 6228 if( ((idxNum & 0x0008)!=0 && pCur->bDesc==0) | |
| 6229 || ((idxNum & 0x0010)!=0 && pCur->bDesc!=0) | |
| 6230 ){ | |
| 6231 sqlite3_int64 tmp = pCur->iBase; | |
| 6232 pCur->iBase = pCur->iTerm; | |
| 6233 pCur->iTerm = tmp; | |
| 6234 pCur->bDesc = !pCur->bDesc; | |
| 6235 } | |
| 6236 | |
| 6237 /* Apply LIMIT and OFFSET constraints, if any */ | |
| 6238 assert( pCur->iStep!=0 ); | |
| 6239 if( idxNum & 0x20 ){ | |
| 6240 if( iOffset>0 ){ | |
| 6241 if( seriesSteps(pCur) < (sqlite3_uint64)iOffset ){ | |
| 6242 goto series_no_rows; | |
| 6243 }else if( pCur->bDesc ){ | |
| 6244 pCur->iBase = sub64(pCur->iBase, pCur->iStep*iOffset); | |
| 6245 }else{ | |
| 6246 pCur->iBase = add64(pCur->iBase, pCur->iStep*iOffset); | |
| 6247 } | |
| 6248 } | |
| 6249 if( iLimit>=0 && seriesSteps(pCur) > (sqlite3_uint64)iLimit ){ | |
| 6250 pCur->iTerm = add64(pCur->iBase, (iLimit - 1)*pCur->iStep); | |
| 6251 } | |
| 6252 } | |
| 6253 pCur->iValue = pCur->iBase; | |
| 6254 pCur->bDone = 0; | |
| 6255 return SQLITE_OK; | |
| 6256 | |
| 6257 series_no_rows: | |
| 6258 pCur->iBase = 0; | |
| 6259 pCur->iTerm = 0; | |
| 6260 pCur->iStep = 1; | |
| 6261 pCur->bDesc = 0; | |
| 6262 pCur->bDone = 1; | |
| 6263 return SQLITE_OK; | |
| 6264 } | |
| 6265 | |
| 6266 /* | |
| 6267 ** SQLite will invoke this method one or more times while planning a query | |
| 6268 ** that uses the generate_series virtual table. This routine needs to create | |
| 6269 ** a query plan for each invocation and compute an estimated cost for that | |
| 6270 ** plan. | |
| 6271 ** | |
| 6272 ** In this implementation idxNum is used to represent the | |
| 6273 ** query plan. idxStr is unused. | |
| 6274 ** | |
| 6275 ** The query plan is represented by bits in idxNum: | |
| 6276 ** | |
| 6277 ** 0x0001 start = $num | |
| 6278 ** 0x0002 stop = $num | |
| 6279 ** 0x0004 step = $num | |
| 6280 ** 0x0008 output is in descending order | |
| 6281 ** 0x0010 output is in ascending order | |
| 6282 ** 0x0020 LIMIT $num | |
| 6283 ** 0x0040 OFFSET $num | |
| 6284 ** 0x0080 value = $num | |
| 6285 ** 0x0100 value >= $num | |
| 6286 ** 0x0200 value > $num | |
| 6287 ** 0x1000 value <= $num | |
| 6288 ** 0x2000 value < $num | |
| 6289 ** | |
| 6290 ** Only one of 0x0100 or 0x0200 will be returned. Similarly, only | |
| 6291 ** one of 0x1000 or 0x2000 will be returned. If the 0x0080 is set, then | |
| 6292 ** none of the 0xff00 bits will be set. | |
| 6293 ** | |
| 6294 ** The order of parameters passed to xFilter is as follows: | |
| 6295 ** | |
| 6296 ** * The argument to start= if bit 0x0001 is in the idxNum mask | |
| 6297 ** * The argument to stop= if bit 0x0002 is in the idxNum mask | |
| 6298 ** * The argument to step= if bit 0x0004 is in the idxNum mask | |
| 6299 ** * The argument to LIMIT if bit 0x0020 is in the idxNum mask | |
| 6300 ** * The argument to OFFSET if bit 0x0040 is in the idxNum mask | |
| 6301 ** * The argument to value=, or value>= or value> if any of | |
| 6302 ** bits 0x0380 are in the idxNum mask | |
| 6303 ** * The argument to value<= or value< if either of bits 0x3000 | |
| 6304 ** are in the mask | |
| 6305 ** | |
| 6306 */ | |
| 6307 static int seriesBestIndex( | |
| 6308 sqlite3_vtab *pVTab, | |
| 6309 sqlite3_index_info *pIdxInfo | |
| 6310 ){ | |
| 6311 int i, j; /* Loop over constraints */ | |
| 6312 int idxNum = 0; /* The query plan bitmask */ | |
| 6313 #ifndef ZERO_ARGUMENT_GENERATE_SERIES | |
| 6314 int bStartSeen = 0; /* EQ constraint seen on the START column */ | |
| 6315 #endif | |
| 6316 int unusableMask = 0; /* Mask of unusable constraints */ | |
| 6317 int nArg = 0; /* Number of arguments that seriesFilter() expects */ | |
| 6318 int aIdx[7]; /* Constraints on start, stop, step, LIMIT, OFFSET, | |
| 6319 ** and value. aIdx[5] covers value=, value>=, and | |
| 6320 ** value>, aIdx[6] covers value<= and value< */ | |
| 6321 const struct sqlite3_index_constraint *pConstraint; | |
| 6322 | |
| 6323 /* This implementation assumes that the start, stop, and step columns | |
| 6324 ** are the last three columns in the virtual table. */ | |
| 6325 assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 ); | |
| 6326 assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 ); | |
| 6327 | |
| 6328 aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = aIdx[5] = aIdx[6] = -1; | |
| 6329 pConstraint = pIdxInfo->aConstraint; | |
| 6330 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ | |
| 6331 int iCol; /* 0 for start, 1 for stop, 2 for step */ | |
| 6332 int iMask; /* bitmask for those column */ | |
| 6333 int op = pConstraint->op; | |
| 6334 if( op>=SQLITE_INDEX_CONSTRAINT_LIMIT | |
| 6335 && op<=SQLITE_INDEX_CONSTRAINT_OFFSET | |
| 6336 ){ | |
| 6337 if( pConstraint->usable==0 ){ | |
| 6338 /* do nothing */ | |
| 6339 }else if( op==SQLITE_INDEX_CONSTRAINT_LIMIT ){ | |
| 6340 aIdx[3] = i; | |
| 6341 idxNum |= 0x20; | |
| 6342 }else{ | |
| 6343 assert( op==SQLITE_INDEX_CONSTRAINT_OFFSET ); | |
| 6344 aIdx[4] = i; | |
| 6345 idxNum |= 0x40; | |
| 6346 } | |
| 6347 continue; | |
| 6348 } | |
| 6349 if( pConstraint->iColumn<SERIES_COLUMN_START ){ | |
| 6350 if( (pConstraint->iColumn==SERIES_COLUMN_VALUE || | |
| 6351 pConstraint->iColumn==SERIES_COLUMN_ROWID) | |
| 6352 && pConstraint->usable | |
| 6353 ){ | |
| 6354 switch( op ){ | |
| 6355 case SQLITE_INDEX_CONSTRAINT_EQ: | |
| 6356 case SQLITE_INDEX_CONSTRAINT_IS: { | |
| 6357 idxNum |= 0x0080; | |
| 6358 idxNum &= ~0x3300; | |
| 6359 aIdx[5] = i; | |
| 6360 aIdx[6] = -1; | |
| 6361 #ifndef ZERO_ARGUMENT_GENERATE_SERIES | |
| 6362 bStartSeen = 1; | |
| 6363 #endif | |
| 6364 break; | |
| 6365 } | |
| 6366 case SQLITE_INDEX_CONSTRAINT_GE: { | |
| 6367 if( idxNum & 0x0080 ) break; | |
| 6368 idxNum |= 0x0100; | |
| 6369 idxNum &= ~0x0200; | |
| 6370 aIdx[5] = i; | |
| 6371 #ifndef ZERO_ARGUMENT_GENERATE_SERIES | |
| 6372 bStartSeen = 1; | |
| 6373 #endif | |
| 6374 break; | |
| 6375 } | |
| 6376 case SQLITE_INDEX_CONSTRAINT_GT: { | |
| 6377 if( idxNum & 0x0080 ) break; | |
| 6378 idxNum |= 0x0200; | |
| 6379 idxNum &= ~0x0100; | |
| 6380 aIdx[5] = i; | |
| 6381 #ifndef ZERO_ARGUMENT_GENERATE_SERIES | |
| 6382 bStartSeen = 1; | |
| 6383 #endif | |
| 6384 break; | |
| 6385 } | |
| 6386 case SQLITE_INDEX_CONSTRAINT_LE: { | |
| 6387 if( idxNum & 0x0080 ) break; | |
| 6388 idxNum |= 0x1000; | |
| 6389 idxNum &= ~0x2000; | |
| 6390 aIdx[6] = i; | |
| 6391 break; | |
| 6392 } | |
| 6393 case SQLITE_INDEX_CONSTRAINT_LT: { | |
| 6394 if( idxNum & 0x0080 ) break; | |
| 6395 idxNum |= 0x2000; | |
| 6396 idxNum &= ~0x1000; | |
| 6397 aIdx[6] = i; | |
| 6398 break; | |
| 6399 } | |
| 6400 } | |
| 6401 } | |
| 6402 continue; | |
| 6403 } | |
| 6404 iCol = pConstraint->iColumn - SERIES_COLUMN_START; | |
| 6405 assert( iCol>=0 && iCol<=2 ); | |
| 6406 iMask = 1 << iCol; | |
| 6407 #ifndef ZERO_ARGUMENT_GENERATE_SERIES | |
| 6408 if( iCol==0 && op==SQLITE_INDEX_CONSTRAINT_EQ ){ | |
| 6409 bStartSeen = 1; | |
| 6410 } | |
| 6411 #endif | |
| 6412 if( pConstraint->usable==0 ){ | |
| 6413 unusableMask |= iMask; | |
| 6414 continue; | |
| 6415 }else if( op==SQLITE_INDEX_CONSTRAINT_EQ ){ | |
| 6416 idxNum |= iMask; | |
| 6417 aIdx[iCol] = i; | |
| 6418 } | |
| 6419 } | |
| 6420 if( aIdx[3]==0 ){ | |
| 6421 /* Ignore OFFSET if LIMIT is omitted */ | |
| 6422 idxNum &= ~0x60; | |
| 6423 aIdx[4] = 0; | |
| 6424 } | |
| 6425 for(i=0; i<7; i++){ | |
| 6426 if( (j = aIdx[i])>=0 ){ | |
| 6427 pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg; | |
| 6428 pIdxInfo->aConstraintUsage[j].omit = | |
| 6429 !SQLITE_SERIES_CONSTRAINT_VERIFY || i>=3; | |
| 6430 } | |
| 6431 } | |
| 6432 /* The current generate_column() implementation requires at least one | |
| 6433 ** argument (the START value). Legacy versions assumed START=0 if the | |
| 6434 ** first argument was omitted. Compile with -DZERO_ARGUMENT_GENERATE_SERIES | |
| 6435 ** to obtain the legacy behavior */ | |
| 6436 #ifndef ZERO_ARGUMENT_GENERATE_SERIES | |
| 6437 if( !bStartSeen ){ | |
| 6438 sqlite3_free(pVTab->zErrMsg); | |
| 6439 pVTab->zErrMsg = sqlite3_mprintf( | |
| 6440 "first argument to \"generate_series()\" missing or unusable"); | |
| 6441 return SQLITE_ERROR; | |
| 6442 } | |
| 6443 #endif | |
| 6444 if( (unusableMask & ~idxNum)!=0 ){ | |
| 6445 /* The start, stop, and step columns are inputs. Therefore if there | |
| 6446 ** are unusable constraints on any of start, stop, or step then | |
| 6447 ** this plan is unusable */ | |
| 6448 return SQLITE_CONSTRAINT; | |
| 6449 } | |
| 6450 if( (idxNum & 0x03)==0x03 ){ | |
| 6451 /* Both start= and stop= boundaries are available. This is the | |
| 6452 ** the preferred case */ | |
| 6453 pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); | |
| 6454 pIdxInfo->estimatedRows = 1000; | |
| 6455 if( pIdxInfo->nOrderBy>=1 && pIdxInfo->aOrderBy[0].iColumn==0 ){ | |
| 6456 if( pIdxInfo->aOrderBy[0].desc ){ | |
| 6457 idxNum |= 0x08; | |
| 6458 }else{ | |
| 6459 idxNum |= 0x10; | |
| 6460 } | |
| 6461 pIdxInfo->orderByConsumed = 1; | |
| 6462 } | |
| 6463 }else if( (idxNum & 0x21)==0x21 ){ | |
| 6464 /* We have start= and LIMIT */ | |
| 6465 pIdxInfo->estimatedRows = 2500; | |
| 6466 }else{ | |
| 6467 /* If either boundary is missing, we have to generate a huge span | |
| 6468 ** of numbers. Make this case very expensive so that the query | |
| 6469 ** planner will work hard to avoid it. */ | |
| 6470 pIdxInfo->estimatedRows = 2147483647; | |
| 6471 } | |
| 6472 pIdxInfo->idxNum = idxNum; | |
| 6473 #ifdef SQLITE_INDEX_SCAN_HEX | |
| 6474 pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_HEX; | |
| 6475 #endif | |
| 6476 return SQLITE_OK; | |
| 6477 } | |
| 6478 | |
| 6479 /* | |
| 6480 ** This following structure defines all the methods for the | |
| 6481 ** generate_series virtual table. | |
| 6482 */ | |
| 6483 static sqlite3_module seriesModule = { | |
| 6484 0, /* iVersion */ | |
| 6485 0, /* xCreate */ | |
| 6486 seriesConnect, /* xConnect */ | |
| 6487 seriesBestIndex, /* xBestIndex */ | |
| 6488 seriesDisconnect, /* xDisconnect */ | |
| 6489 0, /* xDestroy */ | |
| 6490 seriesOpen, /* xOpen - open a cursor */ | |
| 6491 seriesClose, /* xClose - close a cursor */ | |
| 6492 seriesFilter, /* xFilter - configure scan constraints */ | |
| 6493 seriesNext, /* xNext - advance a cursor */ | |
| 6494 seriesEof, /* xEof - check for end of scan */ | |
| 6495 seriesColumn, /* xColumn - read data */ | |
| 6496 seriesRowid, /* xRowid - read data */ | |
| 6497 0, /* xUpdate */ | |
| 6498 0, /* xBegin */ | |
| 6499 0, /* xSync */ | |
| 6500 0, /* xCommit */ | |
| 6501 0, /* xRollback */ | |
| 6502 0, /* xFindMethod */ | |
| 6503 0, /* xRename */ | |
| 6504 0, /* xSavepoint */ | |
| 6505 0, /* xRelease */ | |
| 6506 0, /* xRollbackTo */ | |
| 6507 0, /* xShadowName */ | |
| 6508 0 /* xIntegrity */ | |
| 6509 }; | |
| 6510 | |
| 6511 #endif /* SQLITE_OMIT_VIRTUALTABLE */ | |
| 6512 | |
| 6513 #ifdef _WIN32 | |
| 6514 | |
| 6515 #endif | |
| 6516 int sqlite3_series_init( | |
| 6517 sqlite3 *db, | |
| 6518 char **pzErrMsg, | |
| 6519 const sqlite3_api_routines *pApi | |
| 6520 ){ | |
| 6521 int rc = SQLITE_OK; | |
| 6522 SQLITE_EXTENSION_INIT2(pApi); | |
| 6523 #ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 6524 if( sqlite3_libversion_number()<3008012 && pzErrMsg!=0 ){ | |
| 6525 *pzErrMsg = sqlite3_mprintf( | |
| 6526 "generate_series() requires SQLite 3.8.12 or later"); | |
| 6527 return SQLITE_ERROR; | |
| 6528 } | |
| 6529 rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0); | |
| 6530 #endif | |
| 6531 return rc; | |
| 6532 } | |
| 6533 | |
| 6534 /************************* End ../ext/misc/series.c ********************/ | |
| 6535 /************************* Begin ../ext/misc/regexp.c ******************/ | |
| 6536 /* | |
| 6537 ** 2012-11-13 | |
| 6538 ** | |
| 6539 ** The author disclaims copyright to this source code. In place of | |
| 6540 ** a legal notice, here is a blessing: | |
| 6541 ** | |
| 6542 ** May you do good and not evil. | |
| 6543 ** May you find forgiveness for yourself and forgive others. | |
| 6544 ** May you share freely, never taking more than you give. | |
| 6545 ** | |
| 6546 ****************************************************************************** | |
| 6547 ** | |
| 6548 ** The code in this file implements a compact but reasonably | |
| 6549 ** efficient regular-expression matcher for posix extended regular | |
| 6550 ** expressions against UTF8 text. | |
| 6551 ** | |
| 6552 ** This file is an SQLite extension. It registers a single function | |
| 6553 ** named "regexp(A,B)" where A is the regular expression and B is the | |
| 6554 ** string to be matched. By registering this function, SQLite will also | |
| 6555 ** then implement the "B regexp A" operator. Note that with the function | |
| 6556 ** the regular expression comes first, but with the operator it comes | |
| 6557 ** second. | |
| 6558 ** | |
| 6559 ** The following regular expression syntax is supported: | |
| 6560 ** | |
| 6561 ** X* zero or more occurrences of X | |
| 6562 ** X+ one or more occurrences of X | |
| 6563 ** X? zero or one occurrences of X | |
| 6564 ** X{p,q} between p and q occurrences of X | |
| 6565 ** (X) match X | |
| 6566 ** X|Y X or Y | |
| 6567 ** ^X X occurring at the beginning of the string | |
| 6568 ** X$ X occurring at the end of the string | |
| 6569 ** . Match any single character | |
| 6570 ** \c Character c where c is one of \{}()[]|*+?. | |
| 6571 ** \c C-language escapes for c in afnrtv. ex: \t or \n | |
| 6572 ** \uXXXX Where XXXX is exactly 4 hex digits, unicode value XXXX | |
| 6573 ** \xXX Where XX is exactly 2 hex digits, unicode value XX | |
| 6574 ** [abc] Any single character from the set abc | |
| 6575 ** [^abc] Any single character not in the set abc | |
| 6576 ** [a-z] Any single character in the range a-z | |
| 6577 ** [^a-z] Any single character not in the range a-z | |
| 6578 ** \b Word boundary | |
| 6579 ** \w Word character. [A-Za-z0-9_] | |
| 6580 ** \W Non-word character | |
| 6581 ** \d Digit | |
| 6582 ** \D Non-digit | |
| 6583 ** \s Whitespace character | |
| 6584 ** \S Non-whitespace character | |
| 6585 ** | |
| 6586 ** A nondeterministic finite automaton (NFA) is used for matching, so the | |
| 6587 ** performance is bounded by O(N*M) where N is the size of the regular | |
| 6588 ** expression and M is the size of the input string. The matcher never | |
| 6589 ** exhibits exponential behavior. Note that the X{p,q} operator expands | |
| 6590 ** to p copies of X following by q-p copies of X? and that the size of the | |
| 6591 ** regular expression in the O(N*M) performance bound is computed after | |
| 6592 ** this expansion. | |
| 6593 ** | |
| 6594 ** To help prevent DoS attacks, the maximum size of the NFA is restricted. | |
| 6595 */ | |
| 6596 #include <string.h> | |
| 6597 #include <stdlib.h> | |
| 6598 /* #include "sqlite3ext.h" */ | |
| 6599 SQLITE_EXTENSION_INIT1 | |
| 6600 | |
| 6601 /* | |
| 6602 ** The following #defines change the names of some functions implemented in | |
| 6603 ** this file to prevent name collisions with C-library functions of the | |
| 6604 ** same name. | |
| 6605 */ | |
| 6606 #define re_match sqlite3re_match | |
| 6607 #define re_compile sqlite3re_compile | |
| 6608 #define re_free sqlite3re_free | |
| 6609 | |
| 6610 /* The end-of-input character */ | |
| 6611 #define RE_EOF 0 /* End of input */ | |
| 6612 #define RE_START 0xfffffff /* Start of input - larger than an UTF-8 */ | |
| 6613 | |
| 6614 /* The NFA is implemented as sequence of opcodes taken from the following | |
| 6615 ** set. Each opcode has a single integer argument. | |
| 6616 */ | |
| 6617 #define RE_OP_MATCH 1 /* Match the one character in the argument */ | |
| 6618 #define RE_OP_ANY 2 /* Match any one character. (Implements ".") */ | |
| 6619 #define RE_OP_ANYSTAR 3 /* Special optimized version of .* */ | |
| 6620 #define RE_OP_FORK 4 /* Continue to both next and opcode at iArg */ | |
| 6621 #define RE_OP_GOTO 5 /* Jump to opcode at iArg */ | |
| 6622 #define RE_OP_ACCEPT 6 /* Halt and indicate a successful match */ | |
| 6623 #define RE_OP_CC_INC 7 /* Beginning of a [...] character class */ | |
| 6624 #define RE_OP_CC_EXC 8 /* Beginning of a [^...] character class */ | |
| 6625 #define RE_OP_CC_VALUE 9 /* Single value in a character class */ | |
| 6626 #define RE_OP_CC_RANGE 10 /* Range of values in a character class */ | |
| 6627 #define RE_OP_WORD 11 /* Perl word character [A-Za-z0-9_] */ | |
| 6628 #define RE_OP_NOTWORD 12 /* Not a perl word character */ | |
| 6629 #define RE_OP_DIGIT 13 /* digit: [0-9] */ | |
| 6630 #define RE_OP_NOTDIGIT 14 /* Not a digit */ | |
| 6631 #define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */ | |
| 6632 #define RE_OP_NOTSPACE 16 /* Not a digit */ | |
| 6633 #define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */ | |
| 6634 #define RE_OP_ATSTART 18 /* Currently at the start of the string */ | |
| 6635 | |
| 6636 /* Each opcode is a "state" in the NFA */ | |
| 6637 typedef unsigned short ReStateNumber; | |
| 6638 | |
| 6639 /* Because this is an NFA and not a DFA, multiple states can be active at | |
| 6640 ** once. An instance of the following object records all active states in | |
| 6641 ** the NFA. The implementation is optimized for the common case where the | |
| 6642 ** number of actives states is small. | |
| 6643 */ | |
| 6644 typedef struct ReStateSet { | |
| 6645 unsigned nState; /* Number of current states */ | |
| 6646 ReStateNumber *aState; /* Current states */ | |
| 6647 } ReStateSet; | |
| 6648 | |
| 6649 /* An input string read one character at a time. | |
| 6650 */ | |
| 6651 typedef struct ReInput ReInput; | |
| 6652 struct ReInput { | |
| 6653 const unsigned char *z; /* All text */ | |
| 6654 int i; /* Next byte to read */ | |
| 6655 int mx; /* EOF when i>=mx */ | |
| 6656 }; | |
| 6657 | |
| 6658 /* A compiled NFA (or an NFA that is in the process of being compiled) is | |
| 6659 ** an instance of the following object. | |
| 6660 */ | |
| 6661 typedef struct ReCompiled ReCompiled; | |
| 6662 struct ReCompiled { | |
| 6663 ReInput sIn; /* Regular expression text */ | |
| 6664 const char *zErr; /* Error message to return */ | |
| 6665 char *aOp; /* Operators for the virtual machine */ | |
| 6666 int *aArg; /* Arguments to each operator */ | |
| 6667 unsigned (*xNextChar)(ReInput*); /* Next character function */ | |
| 6668 unsigned char zInit[12]; /* Initial text to match */ | |
| 6669 int nInit; /* Number of bytes in zInit */ | |
| 6670 unsigned nState; /* Number of entries in aOp[] and aArg[] */ | |
| 6671 unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */ | |
| 6672 unsigned mxAlloc; /* Complexity limit */ | |
| 6673 }; | |
| 6674 | |
| 6675 /* Add a state to the given state set if it is not already there */ | |
| 6676 static void re_add_state(ReStateSet *pSet, int newState){ | |
| 6677 unsigned i; | |
| 6678 for(i=0; i<pSet->nState; i++) if( pSet->aState[i]==newState ) return; | |
| 6679 pSet->aState[pSet->nState++] = (ReStateNumber)newState; | |
| 6680 } | |
| 6681 | |
| 6682 /* Extract the next unicode character from *pzIn and return it. Advance | |
| 6683 ** *pzIn to the first byte past the end of the character returned. To | |
| 6684 ** be clear: this routine converts utf8 to unicode. This routine is | |
| 6685 ** optimized for the common case where the next character is a single byte. | |
| 6686 */ | |
| 6687 static unsigned re_next_char(ReInput *p){ | |
| 6688 unsigned c; | |
| 6689 if( p->i>=p->mx ) return 0; | |
| 6690 c = p->z[p->i++]; | |
| 6691 if( c>=0x80 ){ | |
| 6692 if( (c&0xe0)==0xc0 && p->i<p->mx && (p->z[p->i]&0xc0)==0x80 ){ | |
| 6693 c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f); | |
| 6694 if( c<0x80 ) c = 0xfffd; | |
| 6695 }else if( (c&0xf0)==0xe0 && p->i+1<p->mx && (p->z[p->i]&0xc0)==0x80 | |
| 6696 && (p->z[p->i+1]&0xc0)==0x80 ){ | |
| 6697 c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f); | |
| 6698 p->i += 2; | |
| 6699 if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd; | |
| 6700 }else if( (c&0xf8)==0xf0 && p->i+2<p->mx && (p->z[p->i]&0xc0)==0x80 | |
| 6701 && (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){ | |
| 6702 c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6) | |
| 6703 | (p->z[p->i+2]&0x3f); | |
| 6704 p->i += 3; | |
| 6705 if( c<=0xffff || c>0x10ffff ) c = 0xfffd; | |
| 6706 }else{ | |
| 6707 c = 0xfffd; | |
| 6708 } | |
| 6709 } | |
| 6710 return c; | |
| 6711 } | |
| 6712 static unsigned re_next_char_nocase(ReInput *p){ | |
| 6713 unsigned c = re_next_char(p); | |
| 6714 if( c>='A' && c<='Z' ) c += 'a' - 'A'; | |
| 6715 return c; | |
| 6716 } | |
| 6717 | |
| 6718 /* Return true if c is a perl "word" character: [A-Za-z0-9_] */ | |
| 6719 static int re_word_char(int c){ | |
| 6720 return (c>='0' && c<='9') || (c>='a' && c<='z') | |
| 6721 || (c>='A' && c<='Z') || c=='_'; | |
| 6722 } | |
| 6723 | |
| 6724 /* Return true if c is a "digit" character: [0-9] */ | |
| 6725 static int re_digit_char(int c){ | |
| 6726 return (c>='0' && c<='9'); | |
| 6727 } | |
| 6728 | |
| 6729 /* Return true if c is a perl "space" character: [ \t\r\n\v\f] */ | |
| 6730 static int re_space_char(int c){ | |
| 6731 return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f'; | |
| 6732 } | |
| 6733 | |
| 6734 /* Run a compiled regular expression on the zero-terminated input | |
| 6735 ** string zIn[]. Return true on a match and false if there is no match. | |
| 6736 */ | |
| 6737 static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){ | |
| 6738 ReStateSet aStateSet[2], *pThis, *pNext; | |
| 6739 ReStateNumber aSpace[100]; | |
| 6740 ReStateNumber *pToFree; | |
| 6741 unsigned int i = 0; | |
| 6742 unsigned int iSwap = 0; | |
| 6743 int c = RE_START; | |
| 6744 int cPrev = 0; | |
| 6745 int rc = 0; | |
| 6746 ReInput in; | |
| 6747 | |
| 6748 in.z = zIn; | |
| 6749 in.i = 0; | |
| 6750 in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn); | |
| 6751 | |
| 6752 /* Look for the initial prefix match, if there is one. */ | |
| 6753 if( pRe->nInit ){ | |
| 6754 unsigned char x = pRe->zInit[0]; | |
| 6755 while( in.i+pRe->nInit<=in.mx | |
| 6756 && (zIn[in.i]!=x || | |
| 6757 strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0) | |
| 6758 ){ | |
| 6759 in.i++; | |
| 6760 } | |
| 6761 if( in.i+pRe->nInit>in.mx ) return 0; | |
| 6762 c = RE_START-1; | |
| 6763 } | |
| 6764 | |
| 6765 if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){ | |
| 6766 pToFree = 0; | |
| 6767 aStateSet[0].aState = aSpace; | |
| 6768 }else{ | |
| 6769 pToFree = sqlite3_malloc64( sizeof(ReStateNumber)*2*pRe->nState ); | |
| 6770 if( pToFree==0 ) return -1; | |
| 6771 aStateSet[0].aState = pToFree; | |
| 6772 } | |
| 6773 aStateSet[1].aState = &aStateSet[0].aState[pRe->nState]; | |
| 6774 pNext = &aStateSet[1]; | |
| 6775 pNext->nState = 0; | |
| 6776 re_add_state(pNext, 0); | |
| 6777 while( c!=RE_EOF && pNext->nState>0 ){ | |
| 6778 cPrev = c; | |
| 6779 c = pRe->xNextChar(&in); | |
| 6780 pThis = pNext; | |
| 6781 pNext = &aStateSet[iSwap]; | |
| 6782 iSwap = 1 - iSwap; | |
| 6783 pNext->nState = 0; | |
| 6784 for(i=0; i<pThis->nState; i++){ | |
| 6785 int x = pThis->aState[i]; | |
| 6786 switch( pRe->aOp[x] ){ | |
| 6787 case RE_OP_MATCH: { | |
| 6788 if( pRe->aArg[x]==c ) re_add_state(pNext, x+1); | |
| 6789 break; | |
| 6790 } | |
| 6791 case RE_OP_ATSTART: { | |
| 6792 if( cPrev==RE_START ) re_add_state(pThis, x+1); | |
| 6793 break; | |
| 6794 } | |
| 6795 case RE_OP_ANY: { | |
| 6796 if( c!=0 ) re_add_state(pNext, x+1); | |
| 6797 break; | |
| 6798 } | |
| 6799 case RE_OP_WORD: { | |
| 6800 if( re_word_char(c) ) re_add_state(pNext, x+1); | |
| 6801 break; | |
| 6802 } | |
| 6803 case RE_OP_NOTWORD: { | |
| 6804 if( !re_word_char(c) && c!=0 ) re_add_state(pNext, x+1); | |
| 6805 break; | |
| 6806 } | |
| 6807 case RE_OP_DIGIT: { | |
| 6808 if( re_digit_char(c) ) re_add_state(pNext, x+1); | |
| 6809 break; | |
| 6810 } | |
| 6811 case RE_OP_NOTDIGIT: { | |
| 6812 if( !re_digit_char(c) && c!=0 ) re_add_state(pNext, x+1); | |
| 6813 break; | |
| 6814 } | |
| 6815 case RE_OP_SPACE: { | |
| 6816 if( re_space_char(c) ) re_add_state(pNext, x+1); | |
| 6817 break; | |
| 6818 } | |
| 6819 case RE_OP_NOTSPACE: { | |
| 6820 if( !re_space_char(c) && c!=0 ) re_add_state(pNext, x+1); | |
| 6821 break; | |
| 6822 } | |
| 6823 case RE_OP_BOUNDARY: { | |
| 6824 if( re_word_char(c)!=re_word_char(cPrev) ) re_add_state(pThis, x+1); | |
| 6825 break; | |
| 6826 } | |
| 6827 case RE_OP_ANYSTAR: { | |
| 6828 re_add_state(pNext, x); | |
| 6829 re_add_state(pThis, x+1); | |
| 6830 break; | |
| 6831 } | |
| 6832 case RE_OP_FORK: { | |
| 6833 re_add_state(pThis, x+pRe->aArg[x]); | |
| 6834 re_add_state(pThis, x+1); | |
| 6835 break; | |
| 6836 } | |
| 6837 case RE_OP_GOTO: { | |
| 6838 re_add_state(pThis, x+pRe->aArg[x]); | |
| 6839 break; | |
| 6840 } | |
| 6841 case RE_OP_ACCEPT: { | |
| 6842 rc = 1; | |
| 6843 goto re_match_end; | |
| 6844 } | |
| 6845 case RE_OP_CC_EXC: { | |
| 6846 if( c==0 ) break; | |
| 6847 /* fall-through */ goto re_op_cc_inc; | |
| 6848 } | |
| 6849 case RE_OP_CC_INC: re_op_cc_inc: { | |
| 6850 int j = 1; | |
| 6851 int n = pRe->aArg[x]; | |
| 6852 int hit = 0; | |
| 6853 for(j=1; j>0 && j<n; j++){ | |
| 6854 if( pRe->aOp[x+j]==RE_OP_CC_VALUE ){ | |
| 6855 if( pRe->aArg[x+j]==c ){ | |
| 6856 hit = 1; | |
| 6857 j = -1; | |
| 6858 } | |
| 6859 }else{ | |
| 6860 if( pRe->aArg[x+j]<=c && pRe->aArg[x+j+1]>=c ){ | |
| 6861 hit = 1; | |
| 6862 j = -1; | |
| 6863 }else{ | |
| 6864 j++; | |
| 6865 } | |
| 6866 } | |
| 6867 } | |
| 6868 if( pRe->aOp[x]==RE_OP_CC_EXC ) hit = !hit; | |
| 6869 if( hit ) re_add_state(pNext, x+n); | |
| 6870 break; | |
| 6871 } | |
| 6872 } | |
| 6873 } | |
| 6874 } | |
| 6875 for(i=0; i<pNext->nState; i++){ | |
| 6876 int x = pNext->aState[i]; | |
| 6877 while( pRe->aOp[x]==RE_OP_GOTO ) x += pRe->aArg[x]; | |
| 6878 if( pRe->aOp[x]==RE_OP_ACCEPT ){ rc = 1; break; } | |
| 6879 } | |
| 6880 re_match_end: | |
| 6881 sqlite3_free(pToFree); | |
| 6882 return rc; | |
| 6883 } | |
| 6884 | |
| 6885 /* Resize the opcode and argument arrays for an RE under construction. | |
| 6886 */ | |
| 6887 static int re_resize(ReCompiled *p, unsigned int N){ | |
| 6888 char *aOp; | |
| 6889 int *aArg; | |
| 6890 if( N>p->mxAlloc ){ p->zErr = "REGEXP pattern too big"; return 1; } | |
| 6891 aOp = sqlite3_realloc64(p->aOp, N*sizeof(p->aOp[0])); | |
| 6892 if( aOp==0 ){ p->zErr = "out of memory"; return 1; } | |
| 6893 p->aOp = aOp; | |
| 6894 aArg = sqlite3_realloc64(p->aArg, N*sizeof(p->aArg[0])); | |
| 6895 if( aArg==0 ){ p->zErr = "out of memory"; return 1; } | |
| 6896 p->aArg = aArg; | |
| 6897 p->nAlloc = N; | |
| 6898 return 0; | |
| 6899 } | |
| 6900 | |
| 6901 /* Insert a new opcode and argument into an RE under construction. The | |
| 6902 ** insertion point is just prior to existing opcode iBefore. | |
| 6903 */ | |
| 6904 static int re_insert(ReCompiled *p, int iBefore, int op, int arg){ | |
| 6905 int i; | |
| 6906 if( p->nAlloc<=p->nState && re_resize(p, p->nAlloc*2) ) return 0; | |
| 6907 for(i=p->nState; i>iBefore; i--){ | |
| 6908 p->aOp[i] = p->aOp[i-1]; | |
| 6909 p->aArg[i] = p->aArg[i-1]; | |
| 6910 } | |
| 6911 p->nState++; | |
| 6912 p->aOp[iBefore] = (char)op; | |
| 6913 p->aArg[iBefore] = arg; | |
| 6914 return iBefore; | |
| 6915 } | |
| 6916 | |
| 6917 /* Append a new opcode and argument to the end of the RE under construction. | |
| 6918 */ | |
| 6919 static int re_append(ReCompiled *p, int op, int arg){ | |
| 6920 return re_insert(p, p->nState, op, arg); | |
| 6921 } | |
| 6922 | |
| 6923 /* Make a copy of N opcodes starting at iStart onto the end of the RE | |
| 6924 ** under construction. | |
| 6925 */ | |
| 6926 static void re_copy(ReCompiled *p, int iStart, unsigned int N){ | |
| 6927 if( p->nState+N>=p->nAlloc && re_resize(p, p->nAlloc*2+N) ) return; | |
| 6928 memcpy(&p->aOp[p->nState], &p->aOp[iStart], N*sizeof(p->aOp[0])); | |
| 6929 memcpy(&p->aArg[p->nState], &p->aArg[iStart], N*sizeof(p->aArg[0])); | |
| 6930 p->nState += N; | |
| 6931 } | |
| 6932 | |
| 6933 /* Return true if c is a hexadecimal digit character: [0-9a-fA-F] | |
| 6934 ** If c is a hex digit, also set *pV = (*pV)*16 + valueof(c). If | |
| 6935 ** c is not a hex digit *pV is unchanged. | |
| 6936 */ | |
| 6937 static int re_hex(int c, int *pV){ | |
| 6938 if( c>='0' && c<='9' ){ | |
| 6939 c -= '0'; | |
| 6940 }else if( c>='a' && c<='f' ){ | |
| 6941 c -= 'a' - 10; | |
| 6942 }else if( c>='A' && c<='F' ){ | |
| 6943 c -= 'A' - 10; | |
| 6944 }else{ | |
| 6945 return 0; | |
| 6946 } | |
| 6947 *pV = (*pV)*16 + (c & 0xff); | |
| 6948 return 1; | |
| 6949 } | |
| 6950 | |
| 6951 /* A backslash character has been seen, read the next character and | |
| 6952 ** return its interpretation. | |
| 6953 */ | |
| 6954 static unsigned re_esc_char(ReCompiled *p){ | |
| 6955 static const char zEsc[] = "afnrtv\\()*.+?[$^{|}]"; | |
| 6956 static const char zTrans[] = "\a\f\n\r\t\v"; | |
| 6957 int i, v = 0; | |
| 6958 char c; | |
| 6959 if( p->sIn.i>=p->sIn.mx ) return 0; | |
| 6960 c = p->sIn.z[p->sIn.i]; | |
| 6961 if( c=='u' && p->sIn.i+4<p->sIn.mx ){ | |
| 6962 const unsigned char *zIn = p->sIn.z + p->sIn.i; | |
| 6963 if( re_hex(zIn[1],&v) | |
| 6964 && re_hex(zIn[2],&v) | |
| 6965 && re_hex(zIn[3],&v) | |
| 6966 && re_hex(zIn[4],&v) | |
| 6967 ){ | |
| 6968 p->sIn.i += 5; | |
| 6969 return v; | |
| 6970 } | |
| 6971 } | |
| 6972 if( c=='x' && p->sIn.i+2<p->sIn.mx ){ | |
| 6973 const unsigned char *zIn = p->sIn.z + p->sIn.i; | |
| 6974 if( re_hex(zIn[1],&v) | |
| 6975 && re_hex(zIn[2],&v) | |
| 6976 ){ | |
| 6977 p->sIn.i += 3; | |
| 6978 return v; | |
| 6979 } | |
| 6980 } | |
| 6981 for(i=0; zEsc[i] && zEsc[i]!=c; i++){} | |
| 6982 if( zEsc[i] ){ | |
| 6983 if( i<6 ) c = zTrans[i]; | |
| 6984 p->sIn.i++; | |
| 6985 }else{ | |
| 6986 p->zErr = "unknown \\ escape"; | |
| 6987 } | |
| 6988 return c; | |
| 6989 } | |
| 6990 | |
| 6991 /* Forward declaration */ | |
| 6992 static const char *re_subcompile_string(ReCompiled*); | |
| 6993 | |
| 6994 /* Peek at the next byte of input */ | |
| 6995 static unsigned char rePeek(ReCompiled *p){ | |
| 6996 return p->sIn.i<p->sIn.mx ? p->sIn.z[p->sIn.i] : 0; | |
| 6997 } | |
| 6998 | |
| 6999 /* Compile RE text into a sequence of opcodes. Continue up to the | |
| 7000 ** first unmatched ")" character, then return. If an error is found, | |
| 7001 ** return a pointer to the error message string. | |
| 7002 */ | |
| 7003 static const char *re_subcompile_re(ReCompiled *p){ | |
| 7004 const char *zErr; | |
| 7005 int iStart, iEnd, iGoto; | |
| 7006 iStart = p->nState; | |
| 7007 zErr = re_subcompile_string(p); | |
| 7008 if( zErr ) return zErr; | |
| 7009 while( rePeek(p)=='|' ){ | |
| 7010 iEnd = p->nState; | |
| 7011 re_insert(p, iStart, RE_OP_FORK, iEnd + 2 - iStart); | |
| 7012 iGoto = re_append(p, RE_OP_GOTO, 0); | |
| 7013 p->sIn.i++; | |
| 7014 zErr = re_subcompile_string(p); | |
| 7015 if( zErr ) return zErr; | |
| 7016 p->aArg[iGoto] = p->nState - iGoto; | |
| 7017 } | |
| 7018 return 0; | |
| 7019 } | |
| 7020 | |
| 7021 /* Compile an element of regular expression text (anything that can be | |
| 7022 ** an operand to the "|" operator). Return NULL on success or a pointer | |
| 7023 ** to the error message if there is a problem. | |
| 7024 */ | |
| 7025 static const char *re_subcompile_string(ReCompiled *p){ | |
| 7026 int iPrev = -1; | |
| 7027 int iStart; | |
| 7028 unsigned c; | |
| 7029 const char *zErr; | |
| 7030 while( (c = p->xNextChar(&p->sIn))!=0 ){ | |
| 7031 iStart = p->nState; | |
| 7032 switch( c ){ | |
| 7033 case '|': | |
| 7034 case ')': { | |
| 7035 p->sIn.i--; | |
| 7036 return 0; | |
| 7037 } | |
| 7038 case '(': { | |
| 7039 zErr = re_subcompile_re(p); | |
| 7040 if( zErr ) return zErr; | |
| 7041 if( rePeek(p)!=')' ) return "unmatched '('"; | |
| 7042 p->sIn.i++; | |
| 7043 break; | |
| 7044 } | |
| 7045 case '.': { | |
| 7046 if( rePeek(p)=='*' ){ | |
| 7047 re_append(p, RE_OP_ANYSTAR, 0); | |
| 7048 p->sIn.i++; | |
| 7049 }else{ | |
| 7050 re_append(p, RE_OP_ANY, 0); | |
| 7051 } | |
| 7052 break; | |
| 7053 } | |
| 7054 case '*': { | |
| 7055 if( iPrev<0 ) return "'*' without operand"; | |
| 7056 re_insert(p, iPrev, RE_OP_GOTO, p->nState - iPrev + 1); | |
| 7057 re_append(p, RE_OP_FORK, iPrev - p->nState + 1); | |
| 7058 break; | |
| 7059 } | |
| 7060 case '+': { | |
| 7061 if( iPrev<0 ) return "'+' without operand"; | |
| 7062 re_append(p, RE_OP_FORK, iPrev - p->nState); | |
| 7063 break; | |
| 7064 } | |
| 7065 case '?': { | |
| 7066 if( iPrev<0 ) return "'?' without operand"; | |
| 7067 re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1); | |
| 7068 break; | |
| 7069 } | |
| 7070 case '$': { | |
| 7071 re_append(p, RE_OP_MATCH, RE_EOF); | |
| 7072 break; | |
| 7073 } | |
| 7074 case '^': { | |
| 7075 re_append(p, RE_OP_ATSTART, 0); | |
| 7076 break; | |
| 7077 } | |
| 7078 case '{': { | |
| 7079 unsigned int m = 0, n = 0; | |
| 7080 unsigned int sz, j; | |
| 7081 if( iPrev<0 ) return "'{m,n}' without operand"; | |
| 7082 while( (c=rePeek(p))>='0' && c<='9' ){ | |
| 7083 m = m*10 + c - '0'; | |
| 7084 if( m*2>p->mxAlloc ) return "REGEXP pattern too big"; | |
| 7085 p->sIn.i++; | |
| 7086 } | |
| 7087 n = m; | |
| 7088 if( c==',' ){ | |
| 7089 p->sIn.i++; | |
| 7090 n = 0; | |
| 7091 while( (c=rePeek(p))>='0' && c<='9' ){ | |
| 7092 n = n*10 + c-'0'; | |
| 7093 if( n*2>p->mxAlloc ) return "REGEXP pattern too big"; | |
| 7094 p->sIn.i++; | |
| 7095 } | |
| 7096 } | |
| 7097 if( c!='}' ) return "unmatched '{'"; | |
| 7098 if( n<m ) return "n less than m in '{m,n}'"; | |
| 7099 p->sIn.i++; | |
| 7100 sz = p->nState - iPrev; | |
| 7101 if( m==0 ){ | |
| 7102 if( n==0 ) return "both m and n are zero in '{m,n}'"; | |
| 7103 re_insert(p, iPrev, RE_OP_FORK, sz+1); | |
| 7104 iPrev++; | |
| 7105 n--; | |
| 7106 }else{ | |
| 7107 for(j=1; j<m; j++) re_copy(p, iPrev, sz); | |
| 7108 } | |
| 7109 for(j=m; j<n; j++){ | |
| 7110 re_append(p, RE_OP_FORK, sz+1); | |
| 7111 re_copy(p, iPrev, sz); | |
| 7112 } | |
| 7113 if( n==0 && m>0 ){ | |
| 7114 re_append(p, RE_OP_FORK, -(int)sz); | |
| 7115 } | |
| 7116 break; | |
| 7117 } | |
| 7118 case '[': { | |
| 7119 unsigned int iFirst = p->nState; | |
| 7120 if( rePeek(p)=='^' ){ | |
| 7121 re_append(p, RE_OP_CC_EXC, 0); | |
| 7122 p->sIn.i++; | |
| 7123 }else{ | |
| 7124 re_append(p, RE_OP_CC_INC, 0); | |
| 7125 } | |
| 7126 while( (c = p->xNextChar(&p->sIn))!=0 ){ | |
| 7127 if( c=='[' && rePeek(p)==':' ){ | |
| 7128 return "POSIX character classes not supported"; | |
| 7129 } | |
| 7130 if( c=='\\' ) c = re_esc_char(p); | |
| 7131 if( rePeek(p)=='-' ){ | |
| 7132 re_append(p, RE_OP_CC_RANGE, c); | |
| 7133 p->sIn.i++; | |
| 7134 c = p->xNextChar(&p->sIn); | |
| 7135 if( c=='\\' ) c = re_esc_char(p); | |
| 7136 re_append(p, RE_OP_CC_RANGE, c); | |
| 7137 }else{ | |
| 7138 re_append(p, RE_OP_CC_VALUE, c); | |
| 7139 } | |
| 7140 if( rePeek(p)==']' ){ p->sIn.i++; break; } | |
| 7141 } | |
| 7142 if( c==0 ) return "unclosed '['"; | |
| 7143 if( p->nState>iFirst ) p->aArg[iFirst] = p->nState - iFirst; | |
| 7144 break; | |
| 7145 } | |
| 7146 case '\\': { | |
| 7147 int specialOp = 0; | |
| 7148 switch( rePeek(p) ){ | |
| 7149 case 'b': specialOp = RE_OP_BOUNDARY; break; | |
| 7150 case 'd': specialOp = RE_OP_DIGIT; break; | |
| 7151 case 'D': specialOp = RE_OP_NOTDIGIT; break; | |
| 7152 case 's': specialOp = RE_OP_SPACE; break; | |
| 7153 case 'S': specialOp = RE_OP_NOTSPACE; break; | |
| 7154 case 'w': specialOp = RE_OP_WORD; break; | |
| 7155 case 'W': specialOp = RE_OP_NOTWORD; break; | |
| 7156 } | |
| 7157 if( specialOp ){ | |
| 7158 p->sIn.i++; | |
| 7159 re_append(p, specialOp, 0); | |
| 7160 }else{ | |
| 7161 c = re_esc_char(p); | |
| 7162 re_append(p, RE_OP_MATCH, c); | |
| 7163 } | |
| 7164 break; | |
| 7165 } | |
| 7166 default: { | |
| 7167 re_append(p, RE_OP_MATCH, c); | |
| 7168 break; | |
| 7169 } | |
| 7170 } | |
| 7171 iPrev = iStart; | |
| 7172 } | |
| 7173 return 0; | |
| 7174 } | |
| 7175 | |
| 7176 /* Free and reclaim all the memory used by a previously compiled | |
| 7177 ** regular expression. Applications should invoke this routine once | |
| 7178 ** for every call to re_compile() to avoid memory leaks. | |
| 7179 */ | |
| 7180 static void re_free(ReCompiled *pRe){ | |
| 7181 if( pRe ){ | |
| 7182 sqlite3_free(pRe->aOp); | |
| 7183 sqlite3_free(pRe->aArg); | |
| 7184 sqlite3_free(pRe); | |
| 7185 } | |
| 7186 } | |
| 7187 | |
| 7188 /* | |
| 7189 ** Version of re_free() that accepts a pointer of type (void*). Required | |
| 7190 ** to satisfy sanitizers when the re_free() function is called via a | |
| 7191 ** function pointer. | |
| 7192 */ | |
| 7193 static void re_free_voidptr(void *p){ | |
| 7194 re_free((ReCompiled*)p); | |
| 7195 } | |
| 7196 | |
| 7197 /* | |
| 7198 ** Compile a textual regular expression in zIn[] into a compiled regular | |
| 7199 ** expression suitable for us by re_match() and return a pointer to the | |
| 7200 ** compiled regular expression in *ppRe. Return NULL on success or an | |
| 7201 ** error message if something goes wrong. | |
| 7202 */ | |
| 7203 static const char *re_compile( | |
| 7204 ReCompiled **ppRe, /* OUT: write compiled NFA here */ | |
| 7205 const char *zIn, /* Input regular expression */ | |
| 7206 int mxRe, /* Complexity limit */ | |
| 7207 int noCase /* True for caseless comparisons */ | |
| 7208 ){ | |
| 7209 ReCompiled *pRe; | |
| 7210 const char *zErr; | |
| 7211 int i, j; | |
| 7212 | |
| 7213 *ppRe = 0; | |
| 7214 pRe = sqlite3_malloc( sizeof(*pRe) ); | |
| 7215 if( pRe==0 ){ | |
| 7216 return "out of memory"; | |
| 7217 } | |
| 7218 memset(pRe, 0, sizeof(*pRe)); | |
| 7219 pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char; | |
| 7220 pRe->mxAlloc = mxRe; | |
| 7221 if( re_resize(pRe, 30) ){ | |
| 7222 zErr = pRe->zErr; | |
| 7223 re_free(pRe); | |
| 7224 return zErr; | |
| 7225 } | |
| 7226 if( zIn[0]=='^' ){ | |
| 7227 zIn++; | |
| 7228 }else{ | |
| 7229 re_append(pRe, RE_OP_ANYSTAR, 0); | |
| 7230 } | |
| 7231 pRe->sIn.z = (unsigned char*)zIn; | |
| 7232 pRe->sIn.i = 0; | |
| 7233 pRe->sIn.mx = (int)strlen(zIn); | |
| 7234 zErr = re_subcompile_re(pRe); | |
| 7235 if( zErr ){ | |
| 7236 re_free(pRe); | |
| 7237 return zErr; | |
| 7238 } | |
| 7239 if( pRe->sIn.i>=pRe->sIn.mx ){ | |
| 7240 re_append(pRe, RE_OP_ACCEPT, 0); | |
| 7241 *ppRe = pRe; | |
| 7242 }else{ | |
| 7243 re_free(pRe); | |
| 7244 return "unrecognized character"; | |
| 7245 } | |
| 7246 | |
| 7247 /* The following is a performance optimization. If the regex begins with | |
| 7248 ** ".*" (if the input regex lacks an initial "^") and afterwards there are | |
| 7249 ** one or more matching characters, enter those matching characters into | |
| 7250 ** zInit[]. The re_match() routine can then search ahead in the input | |
| 7251 ** string looking for the initial match without having to run the whole | |
| 7252 ** regex engine over the string. Do not worry about trying to match | |
| 7253 ** unicode characters beyond plane 0 - those are very rare and this is | |
| 7254 ** just an optimization. */ | |
| 7255 if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){ | |
| 7256 for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){ | |
| 7257 unsigned x = pRe->aArg[i]; | |
| 7258 if( x<=0x7f ){ | |
| 7259 pRe->zInit[j++] = (unsigned char)x; | |
| 7260 }else if( x<=0x7ff ){ | |
| 7261 pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6)); | |
| 7262 pRe->zInit[j++] = 0x80 | (x&0x3f); | |
| 7263 }else if( x<=0xffff ){ | |
| 7264 pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12)); | |
| 7265 pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f); | |
| 7266 pRe->zInit[j++] = 0x80 | (x&0x3f); | |
| 7267 }else{ | |
| 7268 break; | |
| 7269 } | |
| 7270 } | |
| 7271 if( j>0 && pRe->zInit[j-1]==0 ) j--; | |
| 7272 pRe->nInit = j; | |
| 7273 } | |
| 7274 return pRe->zErr; | |
| 7275 } | |
| 7276 | |
| 7277 /* | |
| 7278 ** Compute a reasonable limit on the length of the REGEXP NFA. | |
| 7279 */ | |
| 7280 static int re_maxlen(sqlite3_context *context){ | |
| 7281 sqlite3 *db = sqlite3_context_db_handle(context); | |
| 7282 return 75 + sqlite3_limit(db, SQLITE_LIMIT_LIKE_PATTERN_LENGTH,-1)/2; | |
| 7283 } | |
| 7284 | |
| 7285 /* | |
| 7286 ** Implementation of the regexp() SQL function. This function implements | |
| 7287 ** the build-in REGEXP operator. The first argument to the function is the | |
| 7288 ** pattern and the second argument is the string. So, the SQL statements: | |
| 7289 ** | |
| 7290 ** A REGEXP B | |
| 7291 ** | |
| 7292 ** is implemented as regexp(B,A). | |
| 7293 */ | |
| 7294 static void re_sql_func( | |
| 7295 sqlite3_context *context, | |
| 7296 int argc, | |
| 7297 sqlite3_value **argv | |
| 7298 ){ | |
| 7299 ReCompiled *pRe; /* Compiled regular expression */ | |
| 7300 const char *zPattern; /* The regular expression */ | |
| 7301 const unsigned char *zStr;/* String being searched */ | |
| 7302 const char *zErr; /* Compile error message */ | |
| 7303 int setAux = 0; /* True to invoke sqlite3_set_auxdata() */ | |
| 7304 | |
| 7305 (void)argc; /* Unused */ | |
| 7306 pRe = sqlite3_get_auxdata(context, 0); | |
| 7307 if( pRe==0 ){ | |
| 7308 zPattern = (const char*)sqlite3_value_text(argv[0]); | |
| 7309 if( zPattern==0 ) return; | |
| 7310 zErr = re_compile(&pRe, zPattern, re_maxlen(context), | |
| 7311 sqlite3_user_data(context)!=0); | |
| 7312 if( zErr ){ | |
| 7313 re_free(pRe); | |
| 7314 sqlite3_result_error(context, zErr, -1); | |
| 7315 return; | |
| 7316 } | |
| 7317 if( pRe==0 ){ | |
| 7318 sqlite3_result_error_nomem(context); | |
| 7319 return; | |
| 7320 } | |
| 7321 setAux = 1; | |
| 7322 } | |
| 7323 zStr = (const unsigned char*)sqlite3_value_text(argv[1]); | |
| 7324 if( zStr!=0 ){ | |
| 7325 sqlite3_result_int(context, re_match(pRe, zStr, -1)); | |
| 7326 } | |
| 7327 if( setAux ){ | |
| 7328 sqlite3_set_auxdata(context, 0, pRe, re_free_voidptr); | |
| 7329 } | |
| 7330 } | |
| 7331 | |
| 7332 #if defined(SQLITE_DEBUG) | |
| 7333 /* | |
| 7334 ** This function is used for testing and debugging only. It is only available | |
| 7335 ** if the SQLITE_DEBUG compile-time option is used. | |
| 7336 ** | |
| 7337 ** Compile a regular expression and then convert the compiled expression into | |
| 7338 ** text and return that text. | |
| 7339 */ | |
| 7340 static void re_bytecode_func( | |
| 7341 sqlite3_context *context, | |
| 7342 int argc, | |
| 7343 sqlite3_value **argv | |
| 7344 ){ | |
| 7345 const char *zPattern; | |
| 7346 const char *zErr; | |
| 7347 ReCompiled *pRe; | |
| 7348 sqlite3_str *pStr; | |
| 7349 int i; | |
| 7350 int n; | |
| 7351 char *z; | |
| 7352 (void)argc; | |
| 7353 static const char *ReOpName[] = { | |
| 7354 "EOF", | |
| 7355 "MATCH", | |
| 7356 "ANY", | |
| 7357 "ANYSTAR", | |
| 7358 "FORK", | |
| 7359 "GOTO", | |
| 7360 "ACCEPT", | |
| 7361 "CC_INC", | |
| 7362 "CC_EXC", | |
| 7363 "CC_VALUE", | |
| 7364 "CC_RANGE", | |
| 7365 "WORD", | |
| 7366 "NOTWORD", | |
| 7367 "DIGIT", | |
| 7368 "NOTDIGIT", | |
| 7369 "SPACE", | |
| 7370 "NOTSPACE", | |
| 7371 "BOUNDARY", | |
| 7372 "ATSTART", | |
| 7373 }; | |
| 7374 | |
| 7375 zPattern = (const char*)sqlite3_value_text(argv[0]); | |
| 7376 if( zPattern==0 ) return; | |
| 7377 zErr = re_compile(&pRe, zPattern, re_maxlen(context), | |
| 7378 sqlite3_user_data(context)!=0); | |
| 7379 if( zErr ){ | |
| 7380 re_free(pRe); | |
| 7381 sqlite3_result_error(context, zErr, -1); | |
| 7382 return; | |
| 7383 } | |
| 7384 if( pRe==0 ){ | |
| 7385 sqlite3_result_error_nomem(context); | |
| 7386 return; | |
| 7387 } | |
| 7388 pStr = sqlite3_str_new(0); | |
| 7389 if( pStr==0 ) goto re_bytecode_func_err; | |
| 7390 if( pRe->nInit>0 ){ | |
| 7391 sqlite3_str_appendf(pStr, "INIT "); | |
| 7392 for(i=0; i<pRe->nInit; i++){ | |
| 7393 sqlite3_str_appendf(pStr, "%02x", pRe->zInit[i]); | |
| 7394 } | |
| 7395 sqlite3_str_appendf(pStr, "\n"); | |
| 7396 } | |
| 7397 for(i=0; (unsigned)i<pRe->nState; i++){ | |
| 7398 sqlite3_str_appendf(pStr, "%-8s %4d\n", | |
| 7399 ReOpName[(unsigned char)pRe->aOp[i]], pRe->aArg[i]); | |
| 7400 } | |
| 7401 n = sqlite3_str_length(pStr); | |
| 7402 z = sqlite3_str_finish(pStr); | |
| 7403 if( n==0 ){ | |
| 7404 sqlite3_free(z); | |
| 7405 }else{ | |
| 7406 sqlite3_result_text(context, z, n-1, sqlite3_free); | |
| 7407 } | |
| 7408 | |
| 7409 re_bytecode_func_err: | |
| 7410 re_free(pRe); | |
| 7411 } | |
| 7412 | |
| 7413 #endif /* SQLITE_DEBUG */ | |
| 7414 | |
| 7415 | |
| 7416 /* | |
| 7417 ** Invoke this routine to register the regexp() function with the | |
| 7418 ** SQLite database connection. | |
| 7419 */ | |
| 7420 #ifdef _WIN32 | |
| 7421 | |
| 7422 #endif | |
| 7423 int sqlite3_regexp_init( | |
| 7424 sqlite3 *db, | |
| 7425 char **pzErrMsg, | |
| 7426 const sqlite3_api_routines *pApi | |
| 7427 ){ | |
| 7428 int rc = SQLITE_OK; | |
| 7429 SQLITE_EXTENSION_INIT2(pApi); | |
| 7430 (void)pzErrMsg; /* Unused */ | |
| 7431 rc = sqlite3_create_function(db, "regexp", 2, | |
| 7432 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, | |
| 7433 0, re_sql_func, 0, 0); | |
| 7434 if( rc==SQLITE_OK ){ | |
| 7435 /* The regexpi(PATTERN,STRING) function is a case-insensitive version | |
| 7436 ** of regexp(PATTERN,STRING). */ | |
| 7437 rc = sqlite3_create_function(db, "regexpi", 2, | |
| 7438 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, | |
| 7439 (void*)db, re_sql_func, 0, 0); | |
| 7440 #if defined(SQLITE_DEBUG) | |
| 7441 if( rc==SQLITE_OK ){ | |
| 7442 rc = sqlite3_create_function(db, "regexp_bytecode", 1, | |
| 7443 SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, | |
| 7444 0, re_bytecode_func, 0, 0); | |
| 7445 } | |
| 7446 #endif /* SQLITE_DEBUG */ | |
| 7447 } | |
| 7448 return rc; | |
| 7449 } | |
| 7450 | |
| 7451 /************************* End ../ext/misc/regexp.c ********************/ | |
| 7452 #ifndef SQLITE_SHELL_FIDDLE | |
| 7453 /************************* Begin ../ext/misc/fileio.c ******************/ | |
| 7454 /* | |
| 7455 ** 2014-06-13 | |
| 7456 ** | |
| 7457 ** The author disclaims copyright to this source code. In place of | |
| 7458 ** a legal notice, here is a blessing: | |
| 7459 ** | |
| 7460 ** May you do good and not evil. | |
| 7461 ** May you find forgiveness for yourself and forgive others. | |
| 7462 ** May you share freely, never taking more than you give. | |
| 7463 ** | |
| 7464 ****************************************************************************** | |
| 7465 ** | |
| 7466 ** This SQLite extension implements SQL functions readfile() and | |
| 7467 ** writefile(), and eponymous virtual type "fsdir". | |
| 7468 ** | |
| 7469 ** WRITEFILE(FILE, DATA [, MODE [, MTIME]]): | |
| 7470 ** | |
| 7471 ** If neither of the optional arguments is present, then this UDF | |
| 7472 ** function writes blob DATA to file FILE. If successful, the number | |
| 7473 ** of bytes written is returned. If an error occurs, NULL is returned. | |
| 7474 ** | |
| 7475 ** If the first option argument - MODE - is present, then it must | |
| 7476 ** be passed an integer value that corresponds to a POSIX mode | |
| 7477 ** value (file type + permissions, as returned in the stat.st_mode | |
| 7478 ** field by the stat() system call). Three types of files may | |
| 7479 ** be written/created: | |
| 7480 ** | |
| 7481 ** regular files: (mode & 0170000)==0100000 | |
| 7482 ** symbolic links: (mode & 0170000)==0120000 | |
| 7483 ** directories: (mode & 0170000)==0040000 | |
| 7484 ** | |
| 7485 ** For a directory, the DATA is ignored. For a symbolic link, it is | |
| 7486 ** interpreted as text and used as the target of the link. For a | |
| 7487 ** regular file, it is interpreted as a blob and written into the | |
| 7488 ** named file. Regardless of the type of file, its permissions are | |
| 7489 ** set to (mode & 0777) before returning. | |
| 7490 ** | |
| 7491 ** If the optional MTIME argument is present, then it is interpreted | |
| 7492 ** as an integer - the number of seconds since the unix epoch. The | |
| 7493 ** modification-time of the target file is set to this value before | |
| 7494 ** returning. | |
| 7495 ** | |
| 7496 ** If five or more arguments are passed to this function and an | |
| 7497 ** error is encountered, an exception is raised. | |
| 7498 ** | |
| 7499 ** READFILE(FILE): | |
| 7500 ** | |
| 7501 ** Read and return the contents of file FILE (type blob) from disk. | |
| 7502 ** | |
| 7503 ** FSDIR: | |
| 7504 ** | |
| 7505 ** Used as follows: | |
| 7506 ** | |
| 7507 ** SELECT * FROM fsdir($path [, $dir]); | |
| 7508 ** | |
| 7509 ** Parameter $path is an absolute or relative pathname. If the file that it | |
| 7510 ** refers to does not exist, it is an error. If the path refers to a regular | |
| 7511 ** file or symbolic link, it returns a single row. Or, if the path refers | |
| 7512 ** to a directory, it returns one row for the directory, and one row for each | |
| 7513 ** file within the hierarchy rooted at $path. | |
| 7514 ** | |
| 7515 ** Each row has the following columns: | |
| 7516 ** | |
| 7517 ** name: Path to file or directory (text value). | |
| 7518 ** mode: Value of stat.st_mode for directory entry (an integer). | |
| 7519 ** mtime: Value of stat.st_mtime for directory entry (an integer). | |
| 7520 ** data: For a regular file, a blob containing the file data. For a | |
| 7521 ** symlink, a text value containing the text of the link. For a | |
| 7522 ** directory, NULL. | |
| 7523 ** level: Directory hierarchy level. Topmost is 1. | |
| 7524 ** | |
| 7525 ** If a non-NULL value is specified for the optional $dir parameter and | |
| 7526 ** $path is a relative path, then $path is interpreted relative to $dir. | |
| 7527 ** And the paths returned in the "name" column of the table are also | |
| 7528 ** relative to directory $dir. | |
| 7529 ** | |
| 7530 ** Notes on building this extension for Windows: | |
| 7531 ** Unless linked statically with the SQLite library, a preprocessor | |
| 7532 ** symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone | |
| 7533 ** DLL form of this extension for WIN32. See its use below for details. | |
| 7534 */ | |
| 7535 /* #include "sqlite3ext.h" */ | |
| 7536 SQLITE_EXTENSION_INIT1 | |
| 7537 #include <stdio.h> | |
| 7538 #include <string.h> | |
| 7539 #include <assert.h> | |
| 7540 | |
| 7541 #include <sys/types.h> | |
| 7542 #include <sys/stat.h> | |
| 7543 #include <fcntl.h> | |
| 7544 #if !defined(_WIN32) && !defined(WIN32) | |
| 7545 # include <unistd.h> | |
| 7546 # include <dirent.h> | |
| 7547 # include <utime.h> | |
| 7548 # include <sys/time.h> | |
| 7549 # define STRUCT_STAT struct stat | |
| 7550 #else | |
| 7551 /* # include "windirent.h" */ | |
| 7552 # include <direct.h> | |
| 7553 # define STRUCT_STAT struct _stat | |
| 7554 # define chmod(path,mode) fileio_chmod(path,mode) | |
| 7555 # define mkdir(path,mode) fileio_mkdir(path) | |
| 7556 #endif | |
| 7557 #include <time.h> | |
| 7558 #include <errno.h> | |
| 7559 | |
| 7560 /* When used as part of the CLI, the sqlite3_stdio.h module will have | |
| 7561 ** been included before this one. In that case use the sqlite3_stdio.h | |
| 7562 ** #defines. If not, create our own for fopen(). | |
| 7563 */ | |
| 7564 #ifndef _SQLITE3_STDIO_H_ | |
| 7565 # define sqlite3_fopen fopen | |
| 7566 #endif | |
| 7567 | |
| 7568 /* | |
| 7569 ** Structure of the fsdir() table-valued function | |
| 7570 */ | |
| 7571 /* 0 1 2 3 4 5 6 */ | |
| 7572 #define FSDIR_SCHEMA "(name,mode,mtime,data,level,path HIDDEN,dir HIDDEN)" | |
| 7573 | |
| 7574 #define FSDIR_COLUMN_NAME 0 /* Name of the file */ | |
| 7575 #define FSDIR_COLUMN_MODE 1 /* Access mode */ | |
| 7576 #define FSDIR_COLUMN_MTIME 2 /* Last modification time */ | |
| 7577 #define FSDIR_COLUMN_DATA 3 /* File content */ | |
| 7578 #define FSDIR_COLUMN_LEVEL 4 /* Level. Topmost is 1 */ | |
| 7579 #define FSDIR_COLUMN_PATH 5 /* Path to top of search */ | |
| 7580 #define FSDIR_COLUMN_DIR 6 /* Path is relative to this directory */ | |
| 7581 | |
| 7582 /* | |
| 7583 ** UTF8 chmod() function for Windows | |
| 7584 */ | |
| 7585 #if defined(_WIN32) || defined(WIN32) | |
| 7586 static int fileio_chmod(const char *zPath, int pmode){ | |
| 7587 sqlite3_int64 sz = strlen(zPath); | |
| 7588 wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) ); | |
| 7589 int rc; | |
| 7590 if( b1==0 ) return -1; | |
| 7591 sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz); | |
| 7592 b1[sz] = 0; | |
| 7593 rc = _wchmod(b1, pmode); | |
| 7594 sqlite3_free(b1); | |
| 7595 return rc; | |
| 7596 } | |
| 7597 #endif | |
| 7598 | |
| 7599 /* | |
| 7600 ** UTF8 mkdir() function for Windows | |
| 7601 */ | |
| 7602 #if defined(_WIN32) || defined(WIN32) | |
| 7603 static int fileio_mkdir(const char *zPath){ | |
| 7604 sqlite3_int64 sz = strlen(zPath); | |
| 7605 wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) ); | |
| 7606 int rc; | |
| 7607 if( b1==0 ) return -1; | |
| 7608 sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz); | |
| 7609 b1[sz] = 0; | |
| 7610 rc = _wmkdir(b1); | |
| 7611 sqlite3_free(b1); | |
| 7612 return rc; | |
| 7613 } | |
| 7614 #endif | |
| 7615 | |
| 7616 | |
| 7617 /* | |
| 7618 ** Set the result stored by context ctx to a blob containing the | |
| 7619 ** contents of file zName. Or, leave the result unchanged (NULL) | |
| 7620 ** if the file does not exist or is unreadable. | |
| 7621 ** | |
| 7622 ** If the file exceeds the SQLite blob size limit, through an | |
| 7623 ** SQLITE_TOOBIG error. | |
| 7624 ** | |
| 7625 ** Throw an SQLITE_IOERR if there are difficulties pulling the file | |
| 7626 ** off of disk. | |
| 7627 */ | |
| 7628 static void readFileContents(sqlite3_context *ctx, const char *zName){ | |
| 7629 FILE *in; | |
| 7630 sqlite3_int64 nIn; | |
| 7631 void *pBuf; | |
| 7632 sqlite3 *db; | |
| 7633 int mxBlob; | |
| 7634 | |
| 7635 in = sqlite3_fopen(zName, "rb"); | |
| 7636 if( in==0 ){ | |
| 7637 /* File does not exist or is unreadable. Leave the result set to NULL. */ | |
| 7638 return; | |
| 7639 } | |
| 7640 fseek(in, 0, SEEK_END); | |
| 7641 nIn = ftell(in); | |
| 7642 rewind(in); | |
| 7643 db = sqlite3_context_db_handle(ctx); | |
| 7644 mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1); | |
| 7645 if( nIn>mxBlob ){ | |
| 7646 sqlite3_result_error_code(ctx, SQLITE_TOOBIG); | |
| 7647 fclose(in); | |
| 7648 return; | |
| 7649 } | |
| 7650 pBuf = sqlite3_malloc64( nIn ? nIn : 1 ); | |
| 7651 if( pBuf==0 ){ | |
| 7652 sqlite3_result_error_nomem(ctx); | |
| 7653 fclose(in); | |
| 7654 return; | |
| 7655 } | |
| 7656 if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){ | |
| 7657 sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free); | |
| 7658 }else{ | |
| 7659 sqlite3_result_error_code(ctx, SQLITE_IOERR); | |
| 7660 sqlite3_free(pBuf); | |
| 7661 } | |
| 7662 fclose(in); | |
| 7663 } | |
| 7664 | |
| 7665 /* | |
| 7666 ** Implementation of the "readfile(X)" SQL function. The entire content | |
| 7667 ** of the file named X is read and returned as a BLOB. NULL is returned | |
| 7668 ** if the file does not exist or is unreadable. | |
| 7669 */ | |
| 7670 static void readfileFunc( | |
| 7671 sqlite3_context *context, | |
| 7672 int argc, | |
| 7673 sqlite3_value **argv | |
| 7674 ){ | |
| 7675 const char *zName; | |
| 7676 (void)(argc); /* Unused parameter */ | |
| 7677 zName = (const char*)sqlite3_value_text(argv[0]); | |
| 7678 if( zName==0 ) return; | |
| 7679 readFileContents(context, zName); | |
| 7680 } | |
| 7681 | |
| 7682 /* | |
| 7683 ** Set the error message contained in context ctx to the results of | |
| 7684 ** vprintf(zFmt, ...). | |
| 7685 */ | |
| 7686 static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){ | |
| 7687 char *zMsg = 0; | |
| 7688 va_list ap; | |
| 7689 va_start(ap, zFmt); | |
| 7690 zMsg = sqlite3_vmprintf(zFmt, ap); | |
| 7691 sqlite3_result_error(ctx, zMsg, -1); | |
| 7692 sqlite3_free(zMsg); | |
| 7693 va_end(ap); | |
| 7694 } | |
| 7695 | |
| 7696 #if defined(_WIN32) | |
| 7697 /* | |
| 7698 ** This function is designed to convert a Win32 FILETIME structure into the | |
| 7699 ** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC). | |
| 7700 */ | |
| 7701 static sqlite3_uint64 fileTimeToUnixTime( | |
| 7702 LPFILETIME pFileTime | |
| 7703 ){ | |
| 7704 SYSTEMTIME epochSystemTime; | |
| 7705 ULARGE_INTEGER epochIntervals; | |
| 7706 FILETIME epochFileTime; | |
| 7707 ULARGE_INTEGER fileIntervals; | |
| 7708 | |
| 7709 memset(&epochSystemTime, 0, sizeof(SYSTEMTIME)); | |
| 7710 epochSystemTime.wYear = 1970; | |
| 7711 epochSystemTime.wMonth = 1; | |
| 7712 epochSystemTime.wDay = 1; | |
| 7713 SystemTimeToFileTime(&epochSystemTime, &epochFileTime); | |
| 7714 epochIntervals.LowPart = epochFileTime.dwLowDateTime; | |
| 7715 epochIntervals.HighPart = epochFileTime.dwHighDateTime; | |
| 7716 | |
| 7717 fileIntervals.LowPart = pFileTime->dwLowDateTime; | |
| 7718 fileIntervals.HighPart = pFileTime->dwHighDateTime; | |
| 7719 | |
| 7720 return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000; | |
| 7721 } | |
| 7722 | |
| 7723 | |
| 7724 #if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32)) | |
| 7725 # /* To allow a standalone DLL, use this next replacement function: */ | |
| 7726 # undef sqlite3_win32_utf8_to_unicode | |
| 7727 # define sqlite3_win32_utf8_to_unicode utf8_to_utf16 | |
| 7728 # | |
| 7729 LPWSTR utf8_to_utf16(const char *z){ | |
| 7730 int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0); | |
| 7731 LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR)); | |
| 7732 if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) ) | |
| 7733 return rv; | |
| 7734 sqlite3_free(rv); | |
| 7735 return 0; | |
| 7736 } | |
| 7737 #endif | |
| 7738 | |
| 7739 /* | |
| 7740 ** This function attempts to normalize the time values found in the stat() | |
| 7741 ** buffer to UTC. This is necessary on Win32, where the runtime library | |
| 7742 ** appears to return these values as local times. | |
| 7743 */ | |
| 7744 static void statTimesToUtc( | |
| 7745 const char *zPath, | |
| 7746 STRUCT_STAT *pStatBuf | |
| 7747 ){ | |
| 7748 HANDLE hFindFile; | |
| 7749 WIN32_FIND_DATAW fd; | |
| 7750 LPWSTR zUnicodeName; | |
| 7751 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); | |
| 7752 zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath); | |
| 7753 if( zUnicodeName ){ | |
| 7754 memset(&fd, 0, sizeof(WIN32_FIND_DATAW)); | |
| 7755 hFindFile = FindFirstFileW(zUnicodeName, &fd); | |
| 7756 if( hFindFile!=NULL ){ | |
| 7757 pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime); | |
| 7758 pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime); | |
| 7759 pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime); | |
| 7760 FindClose(hFindFile); | |
| 7761 } | |
| 7762 sqlite3_free(zUnicodeName); | |
| 7763 } | |
| 7764 } | |
| 7765 #endif | |
| 7766 | |
| 7767 /* | |
| 7768 ** This function is used in place of stat(). On Windows, special handling | |
| 7769 ** is required in order for the included time to be returned as UTC. On all | |
| 7770 ** other systems, this function simply calls stat(). | |
| 7771 */ | |
| 7772 static int fileStat( | |
| 7773 const char *zPath, | |
| 7774 STRUCT_STAT *pStatBuf | |
| 7775 ){ | |
| 7776 #if defined(_WIN32) | |
| 7777 sqlite3_int64 sz = strlen(zPath); | |
| 7778 wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) ); | |
| 7779 int rc; | |
| 7780 if( b1==0 ) return 1; | |
| 7781 sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz); | |
| 7782 b1[sz] = 0; | |
| 7783 rc = _wstat(b1, pStatBuf); | |
| 7784 if( rc==0 ) statTimesToUtc(zPath, pStatBuf); | |
| 7785 sqlite3_free(b1); | |
| 7786 return rc; | |
| 7787 #else | |
| 7788 return stat(zPath, pStatBuf); | |
| 7789 #endif | |
| 7790 } | |
| 7791 | |
| 7792 /* | |
| 7793 ** This function is used in place of lstat(). On Windows, special handling | |
| 7794 ** is required in order for the included time to be returned as UTC. On all | |
| 7795 ** other systems, this function simply calls lstat(). | |
| 7796 */ | |
| 7797 static int fileLinkStat( | |
| 7798 const char *zPath, | |
| 7799 STRUCT_STAT *pStatBuf | |
| 7800 ){ | |
| 7801 #if defined(_WIN32) | |
| 7802 return fileStat(zPath, pStatBuf); | |
| 7803 #else | |
| 7804 return lstat(zPath, pStatBuf); | |
| 7805 #endif | |
| 7806 } | |
| 7807 | |
| 7808 /* | |
| 7809 ** Argument zFile is the name of a file that will be created and/or written | |
| 7810 ** by SQL function writefile(). This function ensures that the directory | |
| 7811 ** zFile will be written to exists, creating it if required. The permissions | |
| 7812 ** for any path components created by this function are set in accordance | |
| 7813 ** with the current umask. | |
| 7814 ** | |
| 7815 ** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise, | |
| 7816 ** SQLITE_OK is returned if the directory is successfully created, or | |
| 7817 ** SQLITE_ERROR otherwise. | |
| 7818 */ | |
| 7819 static int makeDirectory( | |
| 7820 const char *zFile | |
| 7821 ){ | |
| 7822 char *zCopy = sqlite3_mprintf("%s", zFile); | |
| 7823 int rc = SQLITE_OK; | |
| 7824 | |
| 7825 if( zCopy==0 ){ | |
| 7826 rc = SQLITE_NOMEM; | |
| 7827 }else{ | |
| 7828 int nCopy = (int)strlen(zCopy); | |
| 7829 int i = 1; | |
| 7830 | |
| 7831 while( rc==SQLITE_OK ){ | |
| 7832 STRUCT_STAT sStat; | |
| 7833 int rc2; | |
| 7834 | |
| 7835 for(; zCopy[i]!='/' && i<nCopy; i++); | |
| 7836 if( i==nCopy ) break; | |
| 7837 zCopy[i] = '\0'; | |
| 7838 | |
| 7839 rc2 = fileStat(zCopy, &sStat); | |
| 7840 if( rc2!=0 ){ | |
| 7841 if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR; | |
| 7842 }else{ | |
| 7843 if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR; | |
| 7844 } | |
| 7845 zCopy[i] = '/'; | |
| 7846 i++; | |
| 7847 } | |
| 7848 | |
| 7849 sqlite3_free(zCopy); | |
| 7850 } | |
| 7851 | |
| 7852 return rc; | |
| 7853 } | |
| 7854 | |
| 7855 /* | |
| 7856 ** This function does the work for the writefile() UDF. Refer to | |
| 7857 ** header comments at the top of this file for details. | |
| 7858 */ | |
| 7859 static int writeFile( | |
| 7860 sqlite3_context *pCtx, /* Context to return bytes written in */ | |
| 7861 const char *zFile, /* File to write */ | |
| 7862 sqlite3_value *pData, /* Data to write */ | |
| 7863 mode_t mode, /* MODE parameter passed to writefile() */ | |
| 7864 sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */ | |
| 7865 ){ | |
| 7866 if( zFile==0 ) return 1; | |
| 7867 #if !defined(_WIN32) && !defined(WIN32) | |
| 7868 if( S_ISLNK(mode) ){ | |
| 7869 const char *zTo = (const char*)sqlite3_value_text(pData); | |
| 7870 if( zTo==0 ) return 1; | |
| 7871 unlink(zFile); | |
| 7872 if( symlink(zTo, zFile)<0 ) return 1; | |
| 7873 }else | |
| 7874 #endif | |
| 7875 { | |
| 7876 if( S_ISDIR(mode) ){ | |
| 7877 if( mkdir(zFile, mode) ){ | |
| 7878 /* The mkdir() call to create the directory failed. This might not | |
| 7879 ** be an error though - if there is already a directory at the same | |
| 7880 ** path and either the permissions already match or can be changed | |
| 7881 ** to do so using chmod(), it is not an error. */ | |
| 7882 STRUCT_STAT sStat; | |
| 7883 if( errno!=EEXIST | |
| 7884 || 0!=fileStat(zFile, &sStat) | |
| 7885 || !S_ISDIR(sStat.st_mode) | |
| 7886 || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777)) | |
| 7887 ){ | |
| 7888 return 1; | |
| 7889 } | |
| 7890 } | |
| 7891 }else{ | |
| 7892 sqlite3_int64 nWrite = 0; | |
| 7893 const char *z; | |
| 7894 int rc = 0; | |
| 7895 FILE *out = sqlite3_fopen(zFile, "wb"); | |
| 7896 if( out==0 ) return 1; | |
| 7897 z = (const char*)sqlite3_value_blob(pData); | |
| 7898 if( z ){ | |
| 7899 sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out); | |
| 7900 nWrite = sqlite3_value_bytes(pData); | |
| 7901 if( nWrite!=n ){ | |
| 7902 rc = 1; | |
| 7903 } | |
| 7904 } | |
| 7905 fclose(out); | |
| 7906 if( rc==0 && mode && chmod(zFile, mode & 0777) ){ | |
| 7907 rc = 1; | |
| 7908 } | |
| 7909 if( rc ) return 2; | |
| 7910 sqlite3_result_int64(pCtx, nWrite); | |
| 7911 } | |
| 7912 } | |
| 7913 | |
| 7914 if( mtime>=0 ){ | |
| 7915 #if defined(_WIN32) | |
| 7916 #if !SQLITE_OS_WINRT | |
| 7917 /* Windows */ | |
| 7918 FILETIME lastAccess; | |
| 7919 FILETIME lastWrite; | |
| 7920 SYSTEMTIME currentTime; | |
| 7921 LONGLONG intervals; | |
| 7922 HANDLE hFile; | |
| 7923 LPWSTR zUnicodeName; | |
| 7924 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); | |
| 7925 | |
| 7926 GetSystemTime(¤tTime); | |
| 7927 SystemTimeToFileTime(¤tTime, &lastAccess); | |
| 7928 intervals = (mtime*10000000) + 116444736000000000; | |
| 7929 lastWrite.dwLowDateTime = (DWORD)intervals; | |
| 7930 lastWrite.dwHighDateTime = intervals >> 32; | |
| 7931 zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile); | |
| 7932 if( zUnicodeName==0 ){ | |
| 7933 return 1; | |
| 7934 } | |
| 7935 hFile = CreateFileW( | |
| 7936 zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, | |
| 7937 FILE_FLAG_BACKUP_SEMANTICS, NULL | |
| 7938 ); | |
| 7939 sqlite3_free(zUnicodeName); | |
| 7940 if( hFile!=INVALID_HANDLE_VALUE ){ | |
| 7941 BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite); | |
| 7942 CloseHandle(hFile); | |
| 7943 return !bResult; | |
| 7944 }else{ | |
| 7945 return 1; | |
| 7946 } | |
| 7947 #endif | |
| 7948 #elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */ | |
| 7949 /* Recent unix */ | |
| 7950 struct timespec times[2]; | |
| 7951 times[0].tv_nsec = times[1].tv_nsec = 0; | |
| 7952 times[0].tv_sec = time(0); | |
| 7953 times[1].tv_sec = mtime; | |
| 7954 if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){ | |
| 7955 return 1; | |
| 7956 } | |
| 7957 #else | |
| 7958 /* Legacy unix. | |
| 7959 ** | |
| 7960 ** Do not use utimes() on a symbolic link - it sees through the link and | |
| 7961 ** modifies the timestamps on the target. Or fails if the target does | |
| 7962 ** not exist. */ | |
| 7963 if( 0==S_ISLNK(mode) ){ | |
| 7964 struct timeval times[2]; | |
| 7965 times[0].tv_usec = times[1].tv_usec = 0; | |
| 7966 times[0].tv_sec = time(0); | |
| 7967 times[1].tv_sec = mtime; | |
| 7968 if( utimes(zFile, times) ){ | |
| 7969 return 1; | |
| 7970 } | |
| 7971 } | |
| 7972 #endif | |
| 7973 } | |
| 7974 | |
| 7975 return 0; | |
| 7976 } | |
| 7977 | |
| 7978 /* | |
| 7979 ** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function. | |
| 7980 ** Refer to header comments at the top of this file for details. | |
| 7981 */ | |
| 7982 static void writefileFunc( | |
| 7983 sqlite3_context *context, | |
| 7984 int argc, | |
| 7985 sqlite3_value **argv | |
| 7986 ){ | |
| 7987 const char *zFile; | |
| 7988 mode_t mode = 0; | |
| 7989 int res; | |
| 7990 sqlite3_int64 mtime = -1; | |
| 7991 | |
| 7992 if( argc<2 || argc>4 ){ | |
| 7993 sqlite3_result_error(context, | |
| 7994 "wrong number of arguments to function writefile()", -1 | |
| 7995 ); | |
| 7996 return; | |
| 7997 } | |
| 7998 | |
| 7999 zFile = (const char*)sqlite3_value_text(argv[0]); | |
| 8000 if( zFile==0 ) return; | |
| 8001 if( argc>=3 ){ | |
| 8002 mode = (mode_t)sqlite3_value_int(argv[2]); | |
| 8003 } | |
| 8004 if( argc==4 ){ | |
| 8005 mtime = sqlite3_value_int64(argv[3]); | |
| 8006 } | |
| 8007 | |
| 8008 res = writeFile(context, zFile, argv[1], mode, mtime); | |
| 8009 if( res==1 && errno==ENOENT ){ | |
| 8010 if( makeDirectory(zFile)==SQLITE_OK ){ | |
| 8011 res = writeFile(context, zFile, argv[1], mode, mtime); | |
| 8012 } | |
| 8013 } | |
| 8014 | |
| 8015 if( argc>2 && res!=0 ){ | |
| 8016 if( S_ISLNK(mode) ){ | |
| 8017 ctxErrorMsg(context, "failed to create symlink: %s", zFile); | |
| 8018 }else if( S_ISDIR(mode) ){ | |
| 8019 ctxErrorMsg(context, "failed to create directory: %s", zFile); | |
| 8020 }else{ | |
| 8021 ctxErrorMsg(context, "failed to write file: %s", zFile); | |
| 8022 } | |
| 8023 } | |
| 8024 } | |
| 8025 | |
| 8026 /* | |
| 8027 ** SQL function: lsmode(MODE) | |
| 8028 ** | |
| 8029 ** Given a numberic st_mode from stat(), convert it into a human-readable | |
| 8030 ** text string in the style of "ls -l". | |
| 8031 */ | |
| 8032 static void lsModeFunc( | |
| 8033 sqlite3_context *context, | |
| 8034 int argc, | |
| 8035 sqlite3_value **argv | |
| 8036 ){ | |
| 8037 int i; | |
| 8038 int iMode = sqlite3_value_int(argv[0]); | |
| 8039 char z[16]; | |
| 8040 (void)argc; | |
| 8041 if( S_ISLNK(iMode) ){ | |
| 8042 z[0] = 'l'; | |
| 8043 }else if( S_ISREG(iMode) ){ | |
| 8044 z[0] = '-'; | |
| 8045 }else if( S_ISDIR(iMode) ){ | |
| 8046 z[0] = 'd'; | |
| 8047 }else{ | |
| 8048 z[0] = '?'; | |
| 8049 } | |
| 8050 for(i=0; i<3; i++){ | |
| 8051 int m = (iMode >> ((2-i)*3)); | |
| 8052 char *a = &z[1 + i*3]; | |
| 8053 a[0] = (m & 0x4) ? 'r' : '-'; | |
| 8054 a[1] = (m & 0x2) ? 'w' : '-'; | |
| 8055 a[2] = (m & 0x1) ? 'x' : '-'; | |
| 8056 } | |
| 8057 z[10] = '\0'; | |
| 8058 sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT); | |
| 8059 } | |
| 8060 | |
| 8061 #ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 8062 | |
| 8063 /* | |
| 8064 ** Cursor type for recursively iterating through a directory structure. | |
| 8065 */ | |
| 8066 typedef struct fsdir_cursor fsdir_cursor; | |
| 8067 typedef struct FsdirLevel FsdirLevel; | |
| 8068 | |
| 8069 struct FsdirLevel { | |
| 8070 DIR *pDir; /* From opendir() */ | |
| 8071 char *zDir; /* Name of directory (nul-terminated) */ | |
| 8072 }; | |
| 8073 | |
| 8074 struct fsdir_cursor { | |
| 8075 sqlite3_vtab_cursor base; /* Base class - must be first */ | |
| 8076 | |
| 8077 int nLvl; /* Number of entries in aLvl[] array */ | |
| 8078 int mxLvl; /* Maximum level */ | |
| 8079 int iLvl; /* Index of current entry */ | |
| 8080 FsdirLevel *aLvl; /* Hierarchy of directories being traversed */ | |
| 8081 | |
| 8082 const char *zBase; | |
| 8083 int nBase; | |
| 8084 | |
| 8085 STRUCT_STAT sStat; /* Current lstat() results */ | |
| 8086 char *zPath; /* Path to current entry */ | |
| 8087 sqlite3_int64 iRowid; /* Current rowid */ | |
| 8088 }; | |
| 8089 | |
| 8090 typedef struct fsdir_tab fsdir_tab; | |
| 8091 struct fsdir_tab { | |
| 8092 sqlite3_vtab base; /* Base class - must be first */ | |
| 8093 }; | |
| 8094 | |
| 8095 /* | |
| 8096 ** Construct a new fsdir virtual table object. | |
| 8097 */ | |
| 8098 static int fsdirConnect( | |
| 8099 sqlite3 *db, | |
| 8100 void *pAux, | |
| 8101 int argc, const char *const*argv, | |
| 8102 sqlite3_vtab **ppVtab, | |
| 8103 char **pzErr | |
| 8104 ){ | |
| 8105 fsdir_tab *pNew = 0; | |
| 8106 int rc; | |
| 8107 (void)pAux; | |
| 8108 (void)argc; | |
| 8109 (void)argv; | |
| 8110 (void)pzErr; | |
| 8111 rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA); | |
| 8112 if( rc==SQLITE_OK ){ | |
| 8113 pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) ); | |
| 8114 if( pNew==0 ) return SQLITE_NOMEM; | |
| 8115 memset(pNew, 0, sizeof(*pNew)); | |
| 8116 sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); | |
| 8117 } | |
| 8118 *ppVtab = (sqlite3_vtab*)pNew; | |
| 8119 return rc; | |
| 8120 } | |
| 8121 | |
| 8122 /* | |
| 8123 ** This method is the destructor for fsdir vtab objects. | |
| 8124 */ | |
| 8125 static int fsdirDisconnect(sqlite3_vtab *pVtab){ | |
| 8126 sqlite3_free(pVtab); | |
| 8127 return SQLITE_OK; | |
| 8128 } | |
| 8129 | |
| 8130 /* | |
| 8131 ** Constructor for a new fsdir_cursor object. | |
| 8132 */ | |
| 8133 static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ | |
| 8134 fsdir_cursor *pCur; | |
| 8135 (void)p; | |
| 8136 pCur = sqlite3_malloc( sizeof(*pCur) ); | |
| 8137 if( pCur==0 ) return SQLITE_NOMEM; | |
| 8138 memset(pCur, 0, sizeof(*pCur)); | |
| 8139 pCur->iLvl = -1; | |
| 8140 *ppCursor = &pCur->base; | |
| 8141 return SQLITE_OK; | |
| 8142 } | |
| 8143 | |
| 8144 /* | |
| 8145 ** Reset a cursor back to the state it was in when first returned | |
| 8146 ** by fsdirOpen(). | |
| 8147 */ | |
| 8148 static void fsdirResetCursor(fsdir_cursor *pCur){ | |
| 8149 int i; | |
| 8150 for(i=0; i<=pCur->iLvl; i++){ | |
| 8151 FsdirLevel *pLvl = &pCur->aLvl[i]; | |
| 8152 if( pLvl->pDir ) closedir(pLvl->pDir); | |
| 8153 sqlite3_free(pLvl->zDir); | |
| 8154 } | |
| 8155 sqlite3_free(pCur->zPath); | |
| 8156 sqlite3_free(pCur->aLvl); | |
| 8157 pCur->aLvl = 0; | |
| 8158 pCur->zPath = 0; | |
| 8159 pCur->zBase = 0; | |
| 8160 pCur->nBase = 0; | |
| 8161 pCur->nLvl = 0; | |
| 8162 pCur->iLvl = -1; | |
| 8163 pCur->iRowid = 1; | |
| 8164 } | |
| 8165 | |
| 8166 /* | |
| 8167 ** Destructor for an fsdir_cursor. | |
| 8168 */ | |
| 8169 static int fsdirClose(sqlite3_vtab_cursor *cur){ | |
| 8170 fsdir_cursor *pCur = (fsdir_cursor*)cur; | |
| 8171 | |
| 8172 fsdirResetCursor(pCur); | |
| 8173 sqlite3_free(pCur); | |
| 8174 return SQLITE_OK; | |
| 8175 } | |
| 8176 | |
| 8177 /* | |
| 8178 ** Set the error message for the virtual table associated with cursor | |
| 8179 ** pCur to the results of vprintf(zFmt, ...). | |
| 8180 */ | |
| 8181 static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){ | |
| 8182 va_list ap; | |
| 8183 va_start(ap, zFmt); | |
| 8184 pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); | |
| 8185 va_end(ap); | |
| 8186 } | |
| 8187 | |
| 8188 | |
| 8189 /* | |
| 8190 ** Advance an fsdir_cursor to its next row of output. | |
| 8191 */ | |
| 8192 static int fsdirNext(sqlite3_vtab_cursor *cur){ | |
| 8193 fsdir_cursor *pCur = (fsdir_cursor*)cur; | |
| 8194 mode_t m = pCur->sStat.st_mode; | |
| 8195 | |
| 8196 pCur->iRowid++; | |
| 8197 if( S_ISDIR(m) && pCur->iLvl+3<pCur->mxLvl ){ | |
| 8198 /* Descend into this directory */ | |
| 8199 int iNew = pCur->iLvl + 1; | |
| 8200 FsdirLevel *pLvl; | |
| 8201 if( iNew>=pCur->nLvl ){ | |
| 8202 int nNew = iNew+1; | |
| 8203 sqlite3_int64 nByte = nNew*sizeof(FsdirLevel); | |
| 8204 FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte); | |
| 8205 if( aNew==0 ) return SQLITE_NOMEM; | |
| 8206 memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl)); | |
| 8207 pCur->aLvl = aNew; | |
| 8208 pCur->nLvl = nNew; | |
| 8209 } | |
| 8210 pCur->iLvl = iNew; | |
| 8211 pLvl = &pCur->aLvl[iNew]; | |
| 8212 | |
| 8213 pLvl->zDir = pCur->zPath; | |
| 8214 pCur->zPath = 0; | |
| 8215 pLvl->pDir = opendir(pLvl->zDir); | |
| 8216 if( pLvl->pDir==0 ){ | |
| 8217 fsdirSetErrmsg(pCur, "cannot read directory: %s", pLvl->zDir); | |
| 8218 return SQLITE_ERROR; | |
| 8219 } | |
| 8220 } | |
| 8221 | |
| 8222 while( pCur->iLvl>=0 ){ | |
| 8223 FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl]; | |
| 8224 struct dirent *pEntry = readdir(pLvl->pDir); | |
| 8225 if( pEntry ){ | |
| 8226 if( pEntry->d_name[0]=='.' ){ | |
| 8227 if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue; | |
| 8228 if( pEntry->d_name[1]=='\0' ) continue; | |
| 8229 } | |
| 8230 sqlite3_free(pCur->zPath); | |
| 8231 pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name); | |
| 8232 if( pCur->zPath==0 ) return SQLITE_NOMEM; | |
| 8233 if( fileLinkStat(pCur->zPath, &pCur->sStat) ){ | |
| 8234 fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath); | |
| 8235 return SQLITE_ERROR; | |
| 8236 } | |
| 8237 return SQLITE_OK; | |
| 8238 } | |
| 8239 closedir(pLvl->pDir); | |
| 8240 sqlite3_free(pLvl->zDir); | |
| 8241 pLvl->pDir = 0; | |
| 8242 pLvl->zDir = 0; | |
| 8243 pCur->iLvl--; | |
| 8244 } | |
| 8245 | |
| 8246 /* EOF */ | |
| 8247 sqlite3_free(pCur->zPath); | |
| 8248 pCur->zPath = 0; | |
| 8249 return SQLITE_OK; | |
| 8250 } | |
| 8251 | |
| 8252 /* | |
| 8253 ** Return values of columns for the row at which the series_cursor | |
| 8254 ** is currently pointing. | |
| 8255 */ | |
| 8256 static int fsdirColumn( | |
| 8257 sqlite3_vtab_cursor *cur, /* The cursor */ | |
| 8258 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ | |
| 8259 int i /* Which column to return */ | |
| 8260 ){ | |
| 8261 fsdir_cursor *pCur = (fsdir_cursor*)cur; | |
| 8262 switch( i ){ | |
| 8263 case FSDIR_COLUMN_NAME: { | |
| 8264 sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT); | |
| 8265 break; | |
| 8266 } | |
| 8267 | |
| 8268 case FSDIR_COLUMN_MODE: | |
| 8269 sqlite3_result_int64(ctx, pCur->sStat.st_mode); | |
| 8270 break; | |
| 8271 | |
| 8272 case FSDIR_COLUMN_MTIME: | |
| 8273 sqlite3_result_int64(ctx, pCur->sStat.st_mtime); | |
| 8274 break; | |
| 8275 | |
| 8276 case FSDIR_COLUMN_DATA: { | |
| 8277 mode_t m = pCur->sStat.st_mode; | |
| 8278 if( S_ISDIR(m) ){ | |
| 8279 sqlite3_result_null(ctx); | |
| 8280 #if !defined(_WIN32) && !defined(WIN32) | |
| 8281 }else if( S_ISLNK(m) ){ | |
| 8282 char aStatic[64]; | |
| 8283 char *aBuf = aStatic; | |
| 8284 sqlite3_int64 nBuf = 64; | |
| 8285 int n; | |
| 8286 | |
| 8287 while( 1 ){ | |
| 8288 n = readlink(pCur->zPath, aBuf, nBuf); | |
| 8289 if( n<nBuf ) break; | |
| 8290 if( aBuf!=aStatic ) sqlite3_free(aBuf); | |
| 8291 nBuf = nBuf*2; | |
| 8292 aBuf = sqlite3_malloc64(nBuf); | |
| 8293 if( aBuf==0 ){ | |
| 8294 sqlite3_result_error_nomem(ctx); | |
| 8295 return SQLITE_NOMEM; | |
| 8296 } | |
| 8297 } | |
| 8298 | |
| 8299 sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT); | |
| 8300 if( aBuf!=aStatic ) sqlite3_free(aBuf); | |
| 8301 #endif | |
| 8302 }else{ | |
| 8303 readFileContents(ctx, pCur->zPath); | |
| 8304 } | |
| 8305 break; | |
| 8306 } | |
| 8307 case FSDIR_COLUMN_LEVEL: | |
| 8308 sqlite3_result_int(ctx, pCur->iLvl+2); | |
| 8309 break; | |
| 8310 case FSDIR_COLUMN_PATH: | |
| 8311 default: { | |
| 8312 /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters. | |
| 8313 ** always return their values as NULL */ | |
| 8314 break; | |
| 8315 } | |
| 8316 } | |
| 8317 return SQLITE_OK; | |
| 8318 } | |
| 8319 | |
| 8320 /* | |
| 8321 ** Return the rowid for the current row. In this implementation, the | |
| 8322 ** first row returned is assigned rowid value 1, and each subsequent | |
| 8323 ** row a value 1 more than that of the previous. | |
| 8324 */ | |
| 8325 static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ | |
| 8326 fsdir_cursor *pCur = (fsdir_cursor*)cur; | |
| 8327 *pRowid = pCur->iRowid; | |
| 8328 return SQLITE_OK; | |
| 8329 } | |
| 8330 | |
| 8331 /* | |
| 8332 ** Return TRUE if the cursor has been moved off of the last | |
| 8333 ** row of output. | |
| 8334 */ | |
| 8335 static int fsdirEof(sqlite3_vtab_cursor *cur){ | |
| 8336 fsdir_cursor *pCur = (fsdir_cursor*)cur; | |
| 8337 return (pCur->zPath==0); | |
| 8338 } | |
| 8339 | |
| 8340 /* | |
| 8341 ** xFilter callback. | |
| 8342 ** | |
| 8343 ** idxNum bit Meaning | |
| 8344 ** 0x01 PATH=N | |
| 8345 ** 0x02 DIR=N | |
| 8346 ** 0x04 LEVEL<N | |
| 8347 ** 0x08 LEVEL<=N | |
| 8348 */ | |
| 8349 static int fsdirFilter( | |
| 8350 sqlite3_vtab_cursor *cur, | |
| 8351 int idxNum, const char *idxStr, | |
| 8352 int argc, sqlite3_value **argv | |
| 8353 ){ | |
| 8354 const char *zDir = 0; | |
| 8355 fsdir_cursor *pCur = (fsdir_cursor*)cur; | |
| 8356 int i; | |
| 8357 (void)idxStr; | |
| 8358 fsdirResetCursor(pCur); | |
| 8359 | |
| 8360 if( idxNum==0 ){ | |
| 8361 fsdirSetErrmsg(pCur, "table function fsdir requires an argument"); | |
| 8362 return SQLITE_ERROR; | |
| 8363 } | |
| 8364 | |
| 8365 assert( (idxNum & 0x01)!=0 && argc>0 ); | |
| 8366 zDir = (const char*)sqlite3_value_text(argv[0]); | |
| 8367 if( zDir==0 ){ | |
| 8368 fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument"); | |
| 8369 return SQLITE_ERROR; | |
| 8370 } | |
| 8371 i = 1; | |
| 8372 if( (idxNum & 0x02)!=0 ){ | |
| 8373 assert( argc>i ); | |
| 8374 pCur->zBase = (const char*)sqlite3_value_text(argv[i++]); | |
| 8375 } | |
| 8376 if( (idxNum & 0x0c)!=0 ){ | |
| 8377 assert( argc>i ); | |
| 8378 pCur->mxLvl = sqlite3_value_int(argv[i++]); | |
| 8379 if( idxNum & 0x08 ) pCur->mxLvl++; | |
| 8380 if( pCur->mxLvl<=0 ) pCur->mxLvl = 1000000000; | |
| 8381 }else{ | |
| 8382 pCur->mxLvl = 1000000000; | |
| 8383 } | |
| 8384 if( pCur->zBase ){ | |
| 8385 pCur->nBase = (int)strlen(pCur->zBase)+1; | |
| 8386 pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir); | |
| 8387 }else{ | |
| 8388 pCur->zPath = sqlite3_mprintf("%s", zDir); | |
| 8389 } | |
| 8390 | |
| 8391 if( pCur->zPath==0 ){ | |
| 8392 return SQLITE_NOMEM; | |
| 8393 } | |
| 8394 if( fileLinkStat(pCur->zPath, &pCur->sStat) ){ | |
| 8395 fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath); | |
| 8396 return SQLITE_ERROR; | |
| 8397 } | |
| 8398 | |
| 8399 return SQLITE_OK; | |
| 8400 } | |
| 8401 | |
| 8402 /* | |
| 8403 ** SQLite will invoke this method one or more times while planning a query | |
| 8404 ** that uses the generate_series virtual table. This routine needs to create | |
| 8405 ** a query plan for each invocation and compute an estimated cost for that | |
| 8406 ** plan. | |
| 8407 ** | |
| 8408 ** In this implementation idxNum is used to represent the | |
| 8409 ** query plan. idxStr is unused. | |
| 8410 ** | |
| 8411 ** The query plan is represented by bits in idxNum: | |
| 8412 ** | |
| 8413 ** 0x01 The path value is supplied by argv[0] | |
| 8414 ** 0x02 dir is in argv[1] | |
| 8415 ** 0x04 maxdepth is in argv[1] or [2] | |
| 8416 */ | |
| 8417 static int fsdirBestIndex( | |
| 8418 sqlite3_vtab *tab, | |
| 8419 sqlite3_index_info *pIdxInfo | |
| 8420 ){ | |
| 8421 int i; /* Loop over constraints */ | |
| 8422 int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */ | |
| 8423 int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */ | |
| 8424 int idxLevel = -1; /* Index in pIdxInfo->aConstraint of LEVEL< or <= */ | |
| 8425 int idxLevelEQ = 0; /* 0x08 for LEVEL<= or LEVEL=. 0x04 for LEVEL< */ | |
| 8426 int omitLevel = 0; /* omit the LEVEL constraint */ | |
| 8427 int seenPath = 0; /* True if an unusable PATH= constraint is seen */ | |
| 8428 int seenDir = 0; /* True if an unusable DIR= constraint is seen */ | |
| 8429 const struct sqlite3_index_constraint *pConstraint; | |
| 8430 | |
| 8431 (void)tab; | |
| 8432 pConstraint = pIdxInfo->aConstraint; | |
| 8433 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ | |
| 8434 if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ | |
| 8435 switch( pConstraint->iColumn ){ | |
| 8436 case FSDIR_COLUMN_PATH: { | |
| 8437 if( pConstraint->usable ){ | |
| 8438 idxPath = i; | |
| 8439 seenPath = 0; | |
| 8440 }else if( idxPath<0 ){ | |
| 8441 seenPath = 1; | |
| 8442 } | |
| 8443 break; | |
| 8444 } | |
| 8445 case FSDIR_COLUMN_DIR: { | |
| 8446 if( pConstraint->usable ){ | |
| 8447 idxDir = i; | |
| 8448 seenDir = 0; | |
| 8449 }else if( idxDir<0 ){ | |
| 8450 seenDir = 1; | |
| 8451 } | |
| 8452 break; | |
| 8453 } | |
| 8454 case FSDIR_COLUMN_LEVEL: { | |
| 8455 if( pConstraint->usable && idxLevel<0 ){ | |
| 8456 idxLevel = i; | |
| 8457 idxLevelEQ = 0x08; | |
| 8458 omitLevel = 0; | |
| 8459 } | |
| 8460 break; | |
| 8461 } | |
| 8462 } | |
| 8463 }else | |
| 8464 if( pConstraint->iColumn==FSDIR_COLUMN_LEVEL | |
| 8465 && pConstraint->usable | |
| 8466 && idxLevel<0 | |
| 8467 ){ | |
| 8468 if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE ){ | |
| 8469 idxLevel = i; | |
| 8470 idxLevelEQ = 0x08; | |
| 8471 omitLevel = 1; | |
| 8472 }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT ){ | |
| 8473 idxLevel = i; | |
| 8474 idxLevelEQ = 0x04; | |
| 8475 omitLevel = 1; | |
| 8476 } | |
| 8477 } | |
| 8478 } | |
| 8479 if( seenPath || seenDir ){ | |
| 8480 /* If input parameters are unusable, disallow this plan */ | |
| 8481 return SQLITE_CONSTRAINT; | |
| 8482 } | |
| 8483 | |
| 8484 if( idxPath<0 ){ | |
| 8485 pIdxInfo->idxNum = 0; | |
| 8486 /* The pIdxInfo->estimatedCost should have been initialized to a huge | |
| 8487 ** number. Leave it unchanged. */ | |
| 8488 pIdxInfo->estimatedRows = 0x7fffffff; | |
| 8489 }else{ | |
| 8490 pIdxInfo->aConstraintUsage[idxPath].omit = 1; | |
| 8491 pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1; | |
| 8492 pIdxInfo->idxNum = 0x01; | |
| 8493 pIdxInfo->estimatedCost = 1.0e9; | |
| 8494 i = 2; | |
| 8495 if( idxDir>=0 ){ | |
| 8496 pIdxInfo->aConstraintUsage[idxDir].omit = 1; | |
| 8497 pIdxInfo->aConstraintUsage[idxDir].argvIndex = i++; | |
| 8498 pIdxInfo->idxNum |= 0x02; | |
| 8499 pIdxInfo->estimatedCost /= 1.0e4; | |
| 8500 } | |
| 8501 if( idxLevel>=0 ){ | |
| 8502 pIdxInfo->aConstraintUsage[idxLevel].omit = omitLevel; | |
| 8503 pIdxInfo->aConstraintUsage[idxLevel].argvIndex = i++; | |
| 8504 pIdxInfo->idxNum |= idxLevelEQ; | |
| 8505 pIdxInfo->estimatedCost /= 1.0e4; | |
| 8506 } | |
| 8507 } | |
| 8508 | |
| 8509 return SQLITE_OK; | |
| 8510 } | |
| 8511 | |
| 8512 /* | |
| 8513 ** Register the "fsdir" virtual table. | |
| 8514 */ | |
| 8515 static int fsdirRegister(sqlite3 *db){ | |
| 8516 static sqlite3_module fsdirModule = { | |
| 8517 0, /* iVersion */ | |
| 8518 0, /* xCreate */ | |
| 8519 fsdirConnect, /* xConnect */ | |
| 8520 fsdirBestIndex, /* xBestIndex */ | |
| 8521 fsdirDisconnect, /* xDisconnect */ | |
| 8522 0, /* xDestroy */ | |
| 8523 fsdirOpen, /* xOpen - open a cursor */ | |
| 8524 fsdirClose, /* xClose - close a cursor */ | |
| 8525 fsdirFilter, /* xFilter - configure scan constraints */ | |
| 8526 fsdirNext, /* xNext - advance a cursor */ | |
| 8527 fsdirEof, /* xEof - check for end of scan */ | |
| 8528 fsdirColumn, /* xColumn - read data */ | |
| 8529 fsdirRowid, /* xRowid - read data */ | |
| 8530 0, /* xUpdate */ | |
| 8531 0, /* xBegin */ | |
| 8532 0, /* xSync */ | |
| 8533 0, /* xCommit */ | |
| 8534 0, /* xRollback */ | |
| 8535 0, /* xFindMethod */ | |
| 8536 0, /* xRename */ | |
| 8537 0, /* xSavepoint */ | |
| 8538 0, /* xRelease */ | |
| 8539 0, /* xRollbackTo */ | |
| 8540 0, /* xShadowName */ | |
| 8541 0 /* xIntegrity */ | |
| 8542 }; | |
| 8543 | |
| 8544 int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0); | |
| 8545 return rc; | |
| 8546 } | |
| 8547 #else /* SQLITE_OMIT_VIRTUALTABLE */ | |
| 8548 # define fsdirRegister(x) SQLITE_OK | |
| 8549 #endif | |
| 8550 | |
| 8551 #ifdef _WIN32 | |
| 8552 | |
| 8553 #endif | |
| 8554 int sqlite3_fileio_init( | |
| 8555 sqlite3 *db, | |
| 8556 char **pzErrMsg, | |
| 8557 const sqlite3_api_routines *pApi | |
| 8558 ){ | |
| 8559 int rc = SQLITE_OK; | |
| 8560 SQLITE_EXTENSION_INIT2(pApi); | |
| 8561 (void)pzErrMsg; /* Unused parameter */ | |
| 8562 rc = sqlite3_create_function(db, "readfile", 1, | |
| 8563 SQLITE_UTF8|SQLITE_DIRECTONLY, 0, | |
| 8564 readfileFunc, 0, 0); | |
| 8565 if( rc==SQLITE_OK ){ | |
| 8566 rc = sqlite3_create_function(db, "writefile", -1, | |
| 8567 SQLITE_UTF8|SQLITE_DIRECTONLY, 0, | |
| 8568 writefileFunc, 0, 0); | |
| 8569 } | |
| 8570 if( rc==SQLITE_OK ){ | |
| 8571 rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0, | |
| 8572 lsModeFunc, 0, 0); | |
| 8573 } | |
| 8574 if( rc==SQLITE_OK ){ | |
| 8575 rc = fsdirRegister(db); | |
| 8576 } | |
| 8577 return rc; | |
| 8578 } | |
| 8579 | |
| 8580 #if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32)) | |
| 8581 /* To allow a standalone DLL, make test_windirent.c use the same | |
| 8582 * redefined SQLite API calls as the above extension code does. | |
| 8583 * Just pull in this .c to accomplish this. As a beneficial side | |
| 8584 * effect, this extension becomes a single translation unit. */ | |
| 8585 # include "test_windirent.c" | |
| 8586 #endif | |
| 8587 | |
| 8588 /************************* End ../ext/misc/fileio.c ********************/ | |
| 8589 /************************* Begin ../ext/misc/completion.c ******************/ | |
| 8590 /* | |
| 8591 ** 2017-07-10 | |
| 8592 ** | |
| 8593 ** The author disclaims copyright to this source code. In place of | |
| 8594 ** a legal notice, here is a blessing: | |
| 8595 ** | |
| 8596 ** May you do good and not evil. | |
| 8597 ** May you find forgiveness for yourself and forgive others. | |
| 8598 ** May you share freely, never taking more than you give. | |
| 8599 ** | |
| 8600 ************************************************************************* | |
| 8601 ** | |
| 8602 ** This file implements an eponymous virtual table that returns suggested | |
| 8603 ** completions for a partial SQL input. | |
| 8604 ** | |
| 8605 ** Suggested usage: | |
| 8606 ** | |
| 8607 ** SELECT DISTINCT candidate COLLATE nocase | |
| 8608 ** FROM completion($prefix,$wholeline) | |
| 8609 ** ORDER BY 1; | |
| 8610 ** | |
| 8611 ** The two query parameters are optional. $prefix is the text of the | |
| 8612 ** current word being typed and that is to be completed. $wholeline is | |
| 8613 ** the complete input line, used for context. | |
| 8614 ** | |
| 8615 ** The raw completion() table might return the same candidate multiple | |
| 8616 ** times, for example if the same column name is used to two or more | |
| 8617 ** tables. And the candidates are returned in an arbitrary order. Hence, | |
| 8618 ** the DISTINCT and ORDER BY are recommended. | |
| 8619 ** | |
| 8620 ** This virtual table operates at the speed of human typing, and so there | |
| 8621 ** is no attempt to make it fast. Even a slow implementation will be much | |
| 8622 ** faster than any human can type. | |
| 8623 ** | |
| 8624 */ | |
| 8625 /* #include "sqlite3ext.h" */ | |
| 8626 SQLITE_EXTENSION_INIT1 | |
| 8627 #include <assert.h> | |
| 8628 #include <string.h> | |
| 8629 #include <ctype.h> | |
| 8630 | |
| 8631 #ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 8632 | |
| 8633 #ifndef IsAlnum | |
| 8634 #define IsAlnum(X) isalnum((unsigned char)X) | |
| 8635 #endif | |
| 8636 | |
| 8637 | |
| 8638 /* completion_vtab is a subclass of sqlite3_vtab which will | |
| 8639 ** serve as the underlying representation of a completion virtual table | |
| 8640 */ | |
| 8641 typedef struct completion_vtab completion_vtab; | |
| 8642 struct completion_vtab { | |
| 8643 sqlite3_vtab base; /* Base class - must be first */ | |
| 8644 sqlite3 *db; /* Database connection for this completion vtab */ | |
| 8645 }; | |
| 8646 | |
| 8647 /* completion_cursor is a subclass of sqlite3_vtab_cursor which will | |
| 8648 ** serve as the underlying representation of a cursor that scans | |
| 8649 ** over rows of the result | |
| 8650 */ | |
| 8651 typedef struct completion_cursor completion_cursor; | |
| 8652 struct completion_cursor { | |
| 8653 sqlite3_vtab_cursor base; /* Base class - must be first */ | |
| 8654 sqlite3 *db; /* Database connection for this cursor */ | |
| 8655 int nPrefix, nLine; /* Number of bytes in zPrefix and zLine */ | |
| 8656 char *zPrefix; /* The prefix for the word we want to complete */ | |
| 8657 char *zLine; /* The whole that we want to complete */ | |
| 8658 const char *zCurrentRow; /* Current output row */ | |
| 8659 int szRow; /* Length of the zCurrentRow string */ | |
| 8660 sqlite3_stmt *pStmt; /* Current statement */ | |
| 8661 sqlite3_int64 iRowid; /* The rowid */ | |
| 8662 int ePhase; /* Current phase */ | |
| 8663 int j; /* inter-phase counter */ | |
| 8664 }; | |
| 8665 | |
| 8666 /* Values for ePhase: | |
| 8667 */ | |
| 8668 #define COMPLETION_FIRST_PHASE 1 | |
| 8669 #define COMPLETION_KEYWORDS 1 | |
| 8670 #define COMPLETION_PRAGMAS 2 | |
| 8671 #define COMPLETION_FUNCTIONS 3 | |
| 8672 #define COMPLETION_COLLATIONS 4 | |
| 8673 #define COMPLETION_INDEXES 5 | |
| 8674 #define COMPLETION_TRIGGERS 6 | |
| 8675 #define COMPLETION_DATABASES 7 | |
| 8676 #define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */ | |
| 8677 #define COMPLETION_COLUMNS 9 | |
| 8678 #define COMPLETION_MODULES 10 | |
| 8679 #define COMPLETION_EOF 11 | |
| 8680 | |
| 8681 /* | |
| 8682 ** The completionConnect() method is invoked to create a new | |
| 8683 ** completion_vtab that describes the completion virtual table. | |
| 8684 ** | |
| 8685 ** Think of this routine as the constructor for completion_vtab objects. | |
| 8686 ** | |
| 8687 ** All this routine needs to do is: | |
| 8688 ** | |
| 8689 ** (1) Allocate the completion_vtab object and initialize all fields. | |
| 8690 ** | |
| 8691 ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the | |
| 8692 ** result set of queries against completion will look like. | |
| 8693 */ | |
| 8694 static int completionConnect( | |
| 8695 sqlite3 *db, | |
| 8696 void *pAux, | |
| 8697 int argc, const char *const*argv, | |
| 8698 sqlite3_vtab **ppVtab, | |
| 8699 char **pzErr | |
| 8700 ){ | |
| 8701 completion_vtab *pNew; | |
| 8702 int rc; | |
| 8703 | |
| 8704 (void)(pAux); /* Unused parameter */ | |
| 8705 (void)(argc); /* Unused parameter */ | |
| 8706 (void)(argv); /* Unused parameter */ | |
| 8707 (void)(pzErr); /* Unused parameter */ | |
| 8708 | |
| 8709 /* Column numbers */ | |
| 8710 #define COMPLETION_COLUMN_CANDIDATE 0 /* Suggested completion of the input */ | |
| 8711 #define COMPLETION_COLUMN_PREFIX 1 /* Prefix of the word to be completed */ | |
| 8712 #define COMPLETION_COLUMN_WHOLELINE 2 /* Entire line seen so far */ | |
| 8713 #define COMPLETION_COLUMN_PHASE 3 /* ePhase - used for debugging only */ | |
| 8714 | |
| 8715 sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); | |
| 8716 rc = sqlite3_declare_vtab(db, | |
| 8717 "CREATE TABLE x(" | |
| 8718 " candidate TEXT," | |
| 8719 " prefix TEXT HIDDEN," | |
| 8720 " wholeline TEXT HIDDEN," | |
| 8721 " phase INT HIDDEN" /* Used for debugging only */ | |
| 8722 ")"); | |
| 8723 if( rc==SQLITE_OK ){ | |
| 8724 pNew = sqlite3_malloc( sizeof(*pNew) ); | |
| 8725 *ppVtab = (sqlite3_vtab*)pNew; | |
| 8726 if( pNew==0 ) return SQLITE_NOMEM; | |
| 8727 memset(pNew, 0, sizeof(*pNew)); | |
| 8728 pNew->db = db; | |
| 8729 } | |
| 8730 return rc; | |
| 8731 } | |
| 8732 | |
| 8733 /* | |
| 8734 ** This method is the destructor for completion_cursor objects. | |
| 8735 */ | |
| 8736 static int completionDisconnect(sqlite3_vtab *pVtab){ | |
| 8737 sqlite3_free(pVtab); | |
| 8738 return SQLITE_OK; | |
| 8739 } | |
| 8740 | |
| 8741 /* | |
| 8742 ** Constructor for a new completion_cursor object. | |
| 8743 */ | |
| 8744 static int completionOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ | |
| 8745 completion_cursor *pCur; | |
| 8746 pCur = sqlite3_malloc( sizeof(*pCur) ); | |
| 8747 if( pCur==0 ) return SQLITE_NOMEM; | |
| 8748 memset(pCur, 0, sizeof(*pCur)); | |
| 8749 pCur->db = ((completion_vtab*)p)->db; | |
| 8750 *ppCursor = &pCur->base; | |
| 8751 return SQLITE_OK; | |
| 8752 } | |
| 8753 | |
| 8754 /* | |
| 8755 ** Reset the completion_cursor. | |
| 8756 */ | |
| 8757 static void completionCursorReset(completion_cursor *pCur){ | |
| 8758 sqlite3_free(pCur->zPrefix); pCur->zPrefix = 0; pCur->nPrefix = 0; | |
| 8759 sqlite3_free(pCur->zLine); pCur->zLine = 0; pCur->nLine = 0; | |
| 8760 sqlite3_finalize(pCur->pStmt); pCur->pStmt = 0; | |
| 8761 pCur->j = 0; | |
| 8762 } | |
| 8763 | |
| 8764 /* | |
| 8765 ** Destructor for a completion_cursor. | |
| 8766 */ | |
| 8767 static int completionClose(sqlite3_vtab_cursor *cur){ | |
| 8768 completionCursorReset((completion_cursor*)cur); | |
| 8769 sqlite3_free(cur); | |
| 8770 return SQLITE_OK; | |
| 8771 } | |
| 8772 | |
| 8773 /* | |
| 8774 ** Advance a completion_cursor to its next row of output. | |
| 8775 ** | |
| 8776 ** The ->ePhase, ->j, and ->pStmt fields of the completion_cursor object | |
| 8777 ** record the current state of the scan. This routine sets ->zCurrentRow | |
| 8778 ** to the current row of output and then returns. If no more rows remain, | |
| 8779 ** then ->ePhase is set to COMPLETION_EOF which will signal the virtual | |
| 8780 ** table that has reached the end of its scan. | |
| 8781 ** | |
| 8782 ** The current implementation just lists potential identifiers and | |
| 8783 ** keywords and filters them by zPrefix. Future enhancements should | |
| 8784 ** take zLine into account to try to restrict the set of identifiers and | |
| 8785 ** keywords based on what would be legal at the current point of input. | |
| 8786 */ | |
| 8787 static int completionNext(sqlite3_vtab_cursor *cur){ | |
| 8788 completion_cursor *pCur = (completion_cursor*)cur; | |
| 8789 int eNextPhase = 0; /* Next phase to try if current phase reaches end */ | |
| 8790 int iCol = -1; /* If >=0, step pCur->pStmt and use the i-th column */ | |
| 8791 pCur->iRowid++; | |
| 8792 while( pCur->ePhase!=COMPLETION_EOF ){ | |
| 8793 switch( pCur->ePhase ){ | |
| 8794 case COMPLETION_KEYWORDS: { | |
| 8795 if( pCur->j >= sqlite3_keyword_count() ){ | |
| 8796 pCur->zCurrentRow = 0; | |
| 8797 pCur->ePhase = COMPLETION_DATABASES; | |
| 8798 }else{ | |
| 8799 sqlite3_keyword_name(pCur->j++, &pCur->zCurrentRow, &pCur->szRow); | |
| 8800 } | |
| 8801 iCol = -1; | |
| 8802 break; | |
| 8803 } | |
| 8804 case COMPLETION_DATABASES: { | |
| 8805 if( pCur->pStmt==0 ){ | |
| 8806 sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, | |
| 8807 &pCur->pStmt, 0); | |
| 8808 } | |
| 8809 iCol = 1; | |
| 8810 eNextPhase = COMPLETION_TABLES; | |
| 8811 break; | |
| 8812 } | |
| 8813 case COMPLETION_TABLES: { | |
| 8814 if( pCur->pStmt==0 ){ | |
| 8815 sqlite3_stmt *pS2; | |
| 8816 char *zSql = 0; | |
| 8817 const char *zSep = ""; | |
| 8818 sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0); | |
| 8819 while( sqlite3_step(pS2)==SQLITE_ROW ){ | |
| 8820 const char *zDb = (const char*)sqlite3_column_text(pS2, 1); | |
| 8821 zSql = sqlite3_mprintf( | |
| 8822 "%z%s" | |
| 8823 "SELECT name FROM \"%w\".sqlite_schema", | |
| 8824 zSql, zSep, zDb | |
| 8825 ); | |
| 8826 if( zSql==0 ) return SQLITE_NOMEM; | |
| 8827 zSep = " UNION "; | |
| 8828 } | |
| 8829 sqlite3_finalize(pS2); | |
| 8830 sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); | |
| 8831 sqlite3_free(zSql); | |
| 8832 } | |
| 8833 iCol = 0; | |
| 8834 eNextPhase = COMPLETION_COLUMNS; | |
| 8835 break; | |
| 8836 } | |
| 8837 case COMPLETION_COLUMNS: { | |
| 8838 if( pCur->pStmt==0 ){ | |
| 8839 sqlite3_stmt *pS2; | |
| 8840 char *zSql = 0; | |
| 8841 const char *zSep = ""; | |
| 8842 sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0); | |
| 8843 while( sqlite3_step(pS2)==SQLITE_ROW ){ | |
| 8844 const char *zDb = (const char*)sqlite3_column_text(pS2, 1); | |
| 8845 zSql = sqlite3_mprintf( | |
| 8846 "%z%s" | |
| 8847 "SELECT pti.name FROM \"%w\".sqlite_schema AS sm" | |
| 8848 " JOIN pragma_table_xinfo(sm.name,%Q) AS pti" | |
| 8849 " WHERE sm.type='table'", | |
| 8850 zSql, zSep, zDb, zDb | |
| 8851 ); | |
| 8852 if( zSql==0 ) return SQLITE_NOMEM; | |
| 8853 zSep = " UNION "; | |
| 8854 } | |
| 8855 sqlite3_finalize(pS2); | |
| 8856 sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0); | |
| 8857 sqlite3_free(zSql); | |
| 8858 } | |
| 8859 iCol = 0; | |
| 8860 eNextPhase = COMPLETION_EOF; | |
| 8861 break; | |
| 8862 } | |
| 8863 } | |
| 8864 if( iCol<0 ){ | |
| 8865 /* This case is when the phase presets zCurrentRow */ | |
| 8866 if( pCur->zCurrentRow==0 ) continue; | |
| 8867 }else{ | |
| 8868 if( sqlite3_step(pCur->pStmt)==SQLITE_ROW ){ | |
| 8869 /* Extract the next row of content */ | |
| 8870 pCur->zCurrentRow = (const char*)sqlite3_column_text(pCur->pStmt, iCol); | |
| 8871 pCur->szRow = sqlite3_column_bytes(pCur->pStmt, iCol); | |
| 8872 }else{ | |
| 8873 /* When all rows are finished, advance to the next phase */ | |
| 8874 sqlite3_finalize(pCur->pStmt); | |
| 8875 pCur->pStmt = 0; | |
| 8876 pCur->ePhase = eNextPhase; | |
| 8877 continue; | |
| 8878 } | |
| 8879 } | |
| 8880 if( pCur->nPrefix==0 ) break; | |
| 8881 if( pCur->nPrefix<=pCur->szRow | |
| 8882 && sqlite3_strnicmp(pCur->zPrefix, pCur->zCurrentRow, pCur->nPrefix)==0 | |
| 8883 ){ | |
| 8884 break; | |
| 8885 } | |
| 8886 } | |
| 8887 | |
| 8888 return SQLITE_OK; | |
| 8889 } | |
| 8890 | |
| 8891 /* | |
| 8892 ** Return values of columns for the row at which the completion_cursor | |
| 8893 ** is currently pointing. | |
| 8894 */ | |
| 8895 static int completionColumn( | |
| 8896 sqlite3_vtab_cursor *cur, /* The cursor */ | |
| 8897 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ | |
| 8898 int i /* Which column to return */ | |
| 8899 ){ | |
| 8900 completion_cursor *pCur = (completion_cursor*)cur; | |
| 8901 switch( i ){ | |
| 8902 case COMPLETION_COLUMN_CANDIDATE: { | |
| 8903 sqlite3_result_text(ctx, pCur->zCurrentRow, pCur->szRow,SQLITE_TRANSIENT); | |
| 8904 break; | |
| 8905 } | |
| 8906 case COMPLETION_COLUMN_PREFIX: { | |
| 8907 sqlite3_result_text(ctx, pCur->zPrefix, -1, SQLITE_TRANSIENT); | |
| 8908 break; | |
| 8909 } | |
| 8910 case COMPLETION_COLUMN_WHOLELINE: { | |
| 8911 sqlite3_result_text(ctx, pCur->zLine, -1, SQLITE_TRANSIENT); | |
| 8912 break; | |
| 8913 } | |
| 8914 case COMPLETION_COLUMN_PHASE: { | |
| 8915 sqlite3_result_int(ctx, pCur->ePhase); | |
| 8916 break; | |
| 8917 } | |
| 8918 } | |
| 8919 return SQLITE_OK; | |
| 8920 } | |
| 8921 | |
| 8922 /* | |
| 8923 ** Return the rowid for the current row. In this implementation, the | |
| 8924 ** rowid is the same as the output value. | |
| 8925 */ | |
| 8926 static int completionRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ | |
| 8927 completion_cursor *pCur = (completion_cursor*)cur; | |
| 8928 *pRowid = pCur->iRowid; | |
| 8929 return SQLITE_OK; | |
| 8930 } | |
| 8931 | |
| 8932 /* | |
| 8933 ** Return TRUE if the cursor has been moved off of the last | |
| 8934 ** row of output. | |
| 8935 */ | |
| 8936 static int completionEof(sqlite3_vtab_cursor *cur){ | |
| 8937 completion_cursor *pCur = (completion_cursor*)cur; | |
| 8938 return pCur->ePhase >= COMPLETION_EOF; | |
| 8939 } | |
| 8940 | |
| 8941 /* | |
| 8942 ** This method is called to "rewind" the completion_cursor object back | |
| 8943 ** to the first row of output. This method is always called at least | |
| 8944 ** once prior to any call to completionColumn() or completionRowid() or | |
| 8945 ** completionEof(). | |
| 8946 */ | |
| 8947 static int completionFilter( | |
| 8948 sqlite3_vtab_cursor *pVtabCursor, | |
| 8949 int idxNum, const char *idxStr, | |
| 8950 int argc, sqlite3_value **argv | |
| 8951 ){ | |
| 8952 completion_cursor *pCur = (completion_cursor *)pVtabCursor; | |
| 8953 int iArg = 0; | |
| 8954 (void)(idxStr); /* Unused parameter */ | |
| 8955 (void)(argc); /* Unused parameter */ | |
| 8956 completionCursorReset(pCur); | |
| 8957 if( idxNum & 1 ){ | |
| 8958 pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); | |
| 8959 if( pCur->nPrefix>0 ){ | |
| 8960 pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); | |
| 8961 if( pCur->zPrefix==0 ) return SQLITE_NOMEM; | |
| 8962 pCur->nPrefix = (int)strlen(pCur->zPrefix); | |
| 8963 } | |
| 8964 iArg = 1; | |
| 8965 } | |
| 8966 if( idxNum & 2 ){ | |
| 8967 pCur->nLine = sqlite3_value_bytes(argv[iArg]); | |
| 8968 if( pCur->nLine>0 ){ | |
| 8969 pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); | |
| 8970 if( pCur->zLine==0 ) return SQLITE_NOMEM; | |
| 8971 pCur->nLine = (int)strlen(pCur->zLine); | |
| 8972 } | |
| 8973 } | |
| 8974 if( pCur->zLine!=0 && pCur->zPrefix==0 ){ | |
| 8975 int i = pCur->nLine; | |
| 8976 while( i>0 && (IsAlnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){ | |
| 8977 i--; | |
| 8978 } | |
| 8979 pCur->nPrefix = pCur->nLine - i; | |
| 8980 if( pCur->nPrefix>0 ){ | |
| 8981 pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i); | |
| 8982 if( pCur->zPrefix==0 ) return SQLITE_NOMEM; | |
| 8983 pCur->nPrefix = (int)strlen(pCur->zPrefix); | |
| 8984 } | |
| 8985 } | |
| 8986 pCur->iRowid = 0; | |
| 8987 pCur->ePhase = COMPLETION_FIRST_PHASE; | |
| 8988 return completionNext(pVtabCursor); | |
| 8989 } | |
| 8990 | |
| 8991 /* | |
| 8992 ** SQLite will invoke this method one or more times while planning a query | |
| 8993 ** that uses the completion virtual table. This routine needs to create | |
| 8994 ** a query plan for each invocation and compute an estimated cost for that | |
| 8995 ** plan. | |
| 8996 ** | |
| 8997 ** There are two hidden parameters that act as arguments to the table-valued | |
| 8998 ** function: "prefix" and "wholeline". Bit 0 of idxNum is set if "prefix" | |
| 8999 ** is available and bit 1 is set if "wholeline" is available. | |
| 9000 */ | |
| 9001 static int completionBestIndex( | |
| 9002 sqlite3_vtab *tab, | |
| 9003 sqlite3_index_info *pIdxInfo | |
| 9004 ){ | |
| 9005 int i; /* Loop over constraints */ | |
| 9006 int idxNum = 0; /* The query plan bitmask */ | |
| 9007 int prefixIdx = -1; /* Index of the start= constraint, or -1 if none */ | |
| 9008 int wholelineIdx = -1; /* Index of the stop= constraint, or -1 if none */ | |
| 9009 int nArg = 0; /* Number of arguments that completeFilter() expects */ | |
| 9010 const struct sqlite3_index_constraint *pConstraint; | |
| 9011 | |
| 9012 (void)(tab); /* Unused parameter */ | |
| 9013 pConstraint = pIdxInfo->aConstraint; | |
| 9014 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){ | |
| 9015 if( pConstraint->usable==0 ) continue; | |
| 9016 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; | |
| 9017 switch( pConstraint->iColumn ){ | |
| 9018 case COMPLETION_COLUMN_PREFIX: | |
| 9019 prefixIdx = i; | |
| 9020 idxNum |= 1; | |
| 9021 break; | |
| 9022 case COMPLETION_COLUMN_WHOLELINE: | |
| 9023 wholelineIdx = i; | |
| 9024 idxNum |= 2; | |
| 9025 break; | |
| 9026 } | |
| 9027 } | |
| 9028 if( prefixIdx>=0 ){ | |
| 9029 pIdxInfo->aConstraintUsage[prefixIdx].argvIndex = ++nArg; | |
| 9030 pIdxInfo->aConstraintUsage[prefixIdx].omit = 1; | |
| 9031 } | |
| 9032 if( wholelineIdx>=0 ){ | |
| 9033 pIdxInfo->aConstraintUsage[wholelineIdx].argvIndex = ++nArg; | |
| 9034 pIdxInfo->aConstraintUsage[wholelineIdx].omit = 1; | |
| 9035 } | |
| 9036 pIdxInfo->idxNum = idxNum; | |
| 9037 pIdxInfo->estimatedCost = (double)5000 - 1000*nArg; | |
| 9038 pIdxInfo->estimatedRows = 500 - 100*nArg; | |
| 9039 return SQLITE_OK; | |
| 9040 } | |
| 9041 | |
| 9042 /* | |
| 9043 ** This following structure defines all the methods for the | |
| 9044 ** completion virtual table. | |
| 9045 */ | |
| 9046 static sqlite3_module completionModule = { | |
| 9047 0, /* iVersion */ | |
| 9048 0, /* xCreate */ | |
| 9049 completionConnect, /* xConnect */ | |
| 9050 completionBestIndex, /* xBestIndex */ | |
| 9051 completionDisconnect, /* xDisconnect */ | |
| 9052 0, /* xDestroy */ | |
| 9053 completionOpen, /* xOpen - open a cursor */ | |
| 9054 completionClose, /* xClose - close a cursor */ | |
| 9055 completionFilter, /* xFilter - configure scan constraints */ | |
| 9056 completionNext, /* xNext - advance a cursor */ | |
| 9057 completionEof, /* xEof - check for end of scan */ | |
| 9058 completionColumn, /* xColumn - read data */ | |
| 9059 completionRowid, /* xRowid - read data */ | |
| 9060 0, /* xUpdate */ | |
| 9061 0, /* xBegin */ | |
| 9062 0, /* xSync */ | |
| 9063 0, /* xCommit */ | |
| 9064 0, /* xRollback */ | |
| 9065 0, /* xFindMethod */ | |
| 9066 0, /* xRename */ | |
| 9067 0, /* xSavepoint */ | |
| 9068 0, /* xRelease */ | |
| 9069 0, /* xRollbackTo */ | |
| 9070 0, /* xShadowName */ | |
| 9071 0 /* xIntegrity */ | |
| 9072 }; | |
| 9073 | |
| 9074 #endif /* SQLITE_OMIT_VIRTUALTABLE */ | |
| 9075 | |
| 9076 int sqlite3CompletionVtabInit(sqlite3 *db){ | |
| 9077 int rc = SQLITE_OK; | |
| 9078 #ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 9079 rc = sqlite3_create_module(db, "completion", &completionModule, 0); | |
| 9080 #endif | |
| 9081 return rc; | |
| 9082 } | |
| 9083 | |
| 9084 #ifdef _WIN32 | |
| 9085 | |
| 9086 #endif | |
| 9087 int sqlite3_completion_init( | |
| 9088 sqlite3 *db, | |
| 9089 char **pzErrMsg, | |
| 9090 const sqlite3_api_routines *pApi | |
| 9091 ){ | |
| 9092 int rc = SQLITE_OK; | |
| 9093 SQLITE_EXTENSION_INIT2(pApi); | |
| 9094 (void)(pzErrMsg); /* Unused parameter */ | |
| 9095 #ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 9096 rc = sqlite3CompletionVtabInit(db); | |
| 9097 #endif | |
| 9098 return rc; | |
| 9099 } | |
| 9100 | |
| 9101 /************************* End ../ext/misc/completion.c ********************/ | |
| 9102 /************************* Begin ../ext/misc/appendvfs.c ******************/ | |
| 9103 /* | |
| 9104 ** 2017-10-20 | |
| 9105 ** | |
| 9106 ** The author disclaims copyright to this source code. In place of | |
| 9107 ** a legal notice, here is a blessing: | |
| 9108 ** | |
| 9109 ** May you do good and not evil. | |
| 9110 ** May you find forgiveness for yourself and forgive others. | |
| 9111 ** May you share freely, never taking more than you give. | |
| 9112 ** | |
| 9113 ****************************************************************************** | |
| 9114 ** | |
| 9115 ** This file implements a VFS shim that allows an SQLite database to be | |
| 9116 ** appended onto the end of some other file, such as an executable. | |
| 9117 ** | |
| 9118 ** A special record must appear at the end of the file that identifies the | |
| 9119 ** file as an appended database and provides the offset to the first page | |
| 9120 ** of the exposed content. (Or, it is the length of the content prefix.) | |
| 9121 ** For best performance page 1 should be located at a disk page boundary, | |
| 9122 ** though that is not required. | |
| 9123 ** | |
| 9124 ** When opening a database using this VFS, the connection might treat | |
| 9125 ** the file as an ordinary SQLite database, or it might treat it as a | |
| 9126 ** database appended onto some other file. The decision is made by | |
| 9127 ** applying the following rules in order: | |
| 9128 ** | |
| 9129 ** (1) An empty file is an ordinary database. | |
| 9130 ** | |
| 9131 ** (2) If the file ends with the appendvfs trailer string | |
| 9132 ** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database. | |
| 9133 ** | |
| 9134 ** (3) If the file begins with the standard SQLite prefix string | |
| 9135 ** "SQLite format 3", that file is an ordinary database. | |
| 9136 ** | |
| 9137 ** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is | |
| 9138 ** set, then a new database is appended to the already existing file. | |
| 9139 ** | |
| 9140 ** (5) Otherwise, SQLITE_CANTOPEN is returned. | |
| 9141 ** | |
| 9142 ** To avoid unnecessary complications with the PENDING_BYTE, the size of | |
| 9143 ** the file containing the database is limited to 1GiB. (1073741824 bytes) | |
| 9144 ** This VFS will not read or write past the 1GiB mark. This restriction | |
| 9145 ** might be lifted in future versions. For now, if you need a larger | |
| 9146 ** database, then keep it in a separate file. | |
| 9147 ** | |
| 9148 ** If the file being opened is a plain database (not an appended one), then | |
| 9149 ** this shim is a pass-through into the default underlying VFS. (rule 3) | |
| 9150 **/ | |
| 9151 /* #include "sqlite3ext.h" */ | |
| 9152 SQLITE_EXTENSION_INIT1 | |
| 9153 #include <string.h> | |
| 9154 #include <assert.h> | |
| 9155 | |
| 9156 /* The append mark at the end of the database is: | |
| 9157 ** | |
| 9158 ** Start-Of-SQLite3-NNNNNNNN | |
| 9159 ** 123456789 123456789 12345 | |
| 9160 ** | |
| 9161 ** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is | |
| 9162 ** the offset to page 1, and also the length of the prefix content. | |
| 9163 */ | |
| 9164 #define APND_MARK_PREFIX "Start-Of-SQLite3-" | |
| 9165 #define APND_MARK_PREFIX_SZ 17 | |
| 9166 #define APND_MARK_FOS_SZ 8 | |
| 9167 #define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ) | |
| 9168 | |
| 9169 /* | |
| 9170 ** Maximum size of the combined prefix + database + append-mark. This | |
| 9171 ** must be less than 0x40000000 to avoid locking issues on Windows. | |
| 9172 */ | |
| 9173 #define APND_MAX_SIZE (0x40000000) | |
| 9174 | |
| 9175 /* | |
| 9176 ** Try to align the database to an even multiple of APND_ROUNDUP bytes. | |
| 9177 */ | |
| 9178 #ifndef APND_ROUNDUP | |
| 9179 #define APND_ROUNDUP 4096 | |
| 9180 #endif | |
| 9181 #define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1)) | |
| 9182 #define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK) | |
| 9183 | |
| 9184 /* | |
| 9185 ** Forward declaration of objects used by this utility | |
| 9186 */ | |
| 9187 typedef struct sqlite3_vfs ApndVfs; | |
| 9188 typedef struct ApndFile ApndFile; | |
| 9189 | |
| 9190 /* Access to a lower-level VFS that (might) implement dynamic loading, | |
| 9191 ** access to randomness, etc. | |
| 9192 */ | |
| 9193 #define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) | |
| 9194 #define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1)) | |
| 9195 | |
| 9196 /* An open appendvfs file | |
| 9197 ** | |
| 9198 ** An instance of this structure describes the appended database file. | |
| 9199 ** A separate sqlite3_file object is always appended. The appended | |
| 9200 ** sqlite3_file object (which can be accessed using ORIGFILE()) describes | |
| 9201 ** the entire file, including the prefix, the database, and the | |
| 9202 ** append-mark. | |
| 9203 ** | |
| 9204 ** The structure of an AppendVFS database is like this: | |
| 9205 ** | |
| 9206 ** +-------------+---------+----------+-------------+ | |
| 9207 ** | prefix-file | padding | database | append-mark | | |
| 9208 ** +-------------+---------+----------+-------------+ | |
| 9209 ** ^ ^ | |
| 9210 ** | | | |
| 9211 ** iPgOne iMark | |
| 9212 ** | |
| 9213 ** | |
| 9214 ** "prefix file" - file onto which the database has been appended. | |
| 9215 ** "padding" - zero or more bytes inserted so that "database" | |
| 9216 ** starts on an APND_ROUNDUP boundary | |
| 9217 ** "database" - The SQLite database file | |
| 9218 ** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates | |
| 9219 ** the offset from the start of prefix-file to the start | |
| 9220 ** of "database". | |
| 9221 ** | |
| 9222 ** The size of the database is iMark - iPgOne. | |
| 9223 ** | |
| 9224 ** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value | |
| 9225 ** of iPgOne stored as a big-ending 64-bit integer. | |
| 9226 ** | |
| 9227 ** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE). | |
| 9228 ** Or, iMark is -1 to indicate that it has not yet been written. | |
| 9229 */ | |
| 9230 struct ApndFile { | |
| 9231 sqlite3_file base; /* Subclass. MUST BE FIRST! */ | |
| 9232 sqlite3_int64 iPgOne; /* Offset to the start of the database */ | |
| 9233 sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */ | |
| 9234 /* Always followed by another sqlite3_file that describes the whole file */ | |
| 9235 }; | |
| 9236 | |
| 9237 /* | |
| 9238 ** Methods for ApndFile | |
| 9239 */ | |
| 9240 static int apndClose(sqlite3_file*); | |
| 9241 static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); | |
| 9242 static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); | |
| 9243 static int apndTruncate(sqlite3_file*, sqlite3_int64 size); | |
| 9244 static int apndSync(sqlite3_file*, int flags); | |
| 9245 static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize); | |
| 9246 static int apndLock(sqlite3_file*, int); | |
| 9247 static int apndUnlock(sqlite3_file*, int); | |
| 9248 static int apndCheckReservedLock(sqlite3_file*, int *pResOut); | |
| 9249 static int apndFileControl(sqlite3_file*, int op, void *pArg); | |
| 9250 static int apndSectorSize(sqlite3_file*); | |
| 9251 static int apndDeviceCharacteristics(sqlite3_file*); | |
| 9252 static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**); | |
| 9253 static int apndShmLock(sqlite3_file*, int offset, int n, int flags); | |
| 9254 static void apndShmBarrier(sqlite3_file*); | |
| 9255 static int apndShmUnmap(sqlite3_file*, int deleteFlag); | |
| 9256 static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); | |
| 9257 static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); | |
| 9258 | |
| 9259 /* | |
| 9260 ** Methods for ApndVfs | |
| 9261 */ | |
| 9262 static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); | |
| 9263 static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir); | |
| 9264 static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *); | |
| 9265 static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); | |
| 9266 static void *apndDlOpen(sqlite3_vfs*, const char *zFilename); | |
| 9267 static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg); | |
| 9268 static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); | |
| 9269 static void apndDlClose(sqlite3_vfs*, void*); | |
| 9270 static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut); | |
| 9271 static int apndSleep(sqlite3_vfs*, int microseconds); | |
| 9272 static int apndCurrentTime(sqlite3_vfs*, double*); | |
| 9273 static int apndGetLastError(sqlite3_vfs*, int, char *); | |
| 9274 static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); | |
| 9275 static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr); | |
| 9276 static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z); | |
| 9277 static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName); | |
| 9278 | |
| 9279 static sqlite3_vfs apnd_vfs = { | |
| 9280 3, /* iVersion (set when registered) */ | |
| 9281 0, /* szOsFile (set when registered) */ | |
| 9282 1024, /* mxPathname */ | |
| 9283 0, /* pNext */ | |
| 9284 "apndvfs", /* zName */ | |
| 9285 0, /* pAppData (set when registered) */ | |
| 9286 apndOpen, /* xOpen */ | |
| 9287 apndDelete, /* xDelete */ | |
| 9288 apndAccess, /* xAccess */ | |
| 9289 apndFullPathname, /* xFullPathname */ | |
| 9290 apndDlOpen, /* xDlOpen */ | |
| 9291 apndDlError, /* xDlError */ | |
| 9292 apndDlSym, /* xDlSym */ | |
| 9293 apndDlClose, /* xDlClose */ | |
| 9294 apndRandomness, /* xRandomness */ | |
| 9295 apndSleep, /* xSleep */ | |
| 9296 apndCurrentTime, /* xCurrentTime */ | |
| 9297 apndGetLastError, /* xGetLastError */ | |
| 9298 apndCurrentTimeInt64, /* xCurrentTimeInt64 */ | |
| 9299 apndSetSystemCall, /* xSetSystemCall */ | |
| 9300 apndGetSystemCall, /* xGetSystemCall */ | |
| 9301 apndNextSystemCall /* xNextSystemCall */ | |
| 9302 }; | |
| 9303 | |
| 9304 static const sqlite3_io_methods apnd_io_methods = { | |
| 9305 3, /* iVersion */ | |
| 9306 apndClose, /* xClose */ | |
| 9307 apndRead, /* xRead */ | |
| 9308 apndWrite, /* xWrite */ | |
| 9309 apndTruncate, /* xTruncate */ | |
| 9310 apndSync, /* xSync */ | |
| 9311 apndFileSize, /* xFileSize */ | |
| 9312 apndLock, /* xLock */ | |
| 9313 apndUnlock, /* xUnlock */ | |
| 9314 apndCheckReservedLock, /* xCheckReservedLock */ | |
| 9315 apndFileControl, /* xFileControl */ | |
| 9316 apndSectorSize, /* xSectorSize */ | |
| 9317 apndDeviceCharacteristics, /* xDeviceCharacteristics */ | |
| 9318 apndShmMap, /* xShmMap */ | |
| 9319 apndShmLock, /* xShmLock */ | |
| 9320 apndShmBarrier, /* xShmBarrier */ | |
| 9321 apndShmUnmap, /* xShmUnmap */ | |
| 9322 apndFetch, /* xFetch */ | |
| 9323 apndUnfetch /* xUnfetch */ | |
| 9324 }; | |
| 9325 | |
| 9326 /* | |
| 9327 ** Close an apnd-file. | |
| 9328 */ | |
| 9329 static int apndClose(sqlite3_file *pFile){ | |
| 9330 pFile = ORIGFILE(pFile); | |
| 9331 return pFile->pMethods->xClose(pFile); | |
| 9332 } | |
| 9333 | |
| 9334 /* | |
| 9335 ** Read data from an apnd-file. | |
| 9336 */ | |
| 9337 static int apndRead( | |
| 9338 sqlite3_file *pFile, | |
| 9339 void *zBuf, | |
| 9340 int iAmt, | |
| 9341 sqlite_int64 iOfst | |
| 9342 ){ | |
| 9343 ApndFile *paf = (ApndFile *)pFile; | |
| 9344 pFile = ORIGFILE(pFile); | |
| 9345 return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst); | |
| 9346 } | |
| 9347 | |
| 9348 /* | |
| 9349 ** Add the append-mark onto what should become the end of the file. | |
| 9350 * If and only if this succeeds, internal ApndFile.iMark is updated. | |
| 9351 * Parameter iWriteEnd is the appendvfs-relative offset of the new mark. | |
| 9352 */ | |
| 9353 static int apndWriteMark( | |
| 9354 ApndFile *paf, | |
| 9355 sqlite3_file *pFile, | |
| 9356 sqlite_int64 iWriteEnd | |
| 9357 ){ | |
| 9358 sqlite_int64 iPgOne = paf->iPgOne; | |
| 9359 unsigned char a[APND_MARK_SIZE]; | |
| 9360 int i = APND_MARK_FOS_SZ; | |
| 9361 int rc; | |
| 9362 assert(pFile == ORIGFILE(paf)); | |
| 9363 memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ); | |
| 9364 while( --i >= 0 ){ | |
| 9365 a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff); | |
| 9366 iPgOne >>= 8; | |
| 9367 } | |
| 9368 iWriteEnd += paf->iPgOne; | |
| 9369 if( SQLITE_OK==(rc = pFile->pMethods->xWrite | |
| 9370 (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){ | |
| 9371 paf->iMark = iWriteEnd; | |
| 9372 } | |
| 9373 return rc; | |
| 9374 } | |
| 9375 | |
| 9376 /* | |
| 9377 ** Write data to an apnd-file. | |
| 9378 */ | |
| 9379 static int apndWrite( | |
| 9380 sqlite3_file *pFile, | |
| 9381 const void *zBuf, | |
| 9382 int iAmt, | |
| 9383 sqlite_int64 iOfst | |
| 9384 ){ | |
| 9385 ApndFile *paf = (ApndFile *)pFile; | |
| 9386 sqlite_int64 iWriteEnd = iOfst + iAmt; | |
| 9387 if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL; | |
| 9388 pFile = ORIGFILE(pFile); | |
| 9389 /* If append-mark is absent or will be overwritten, write it. */ | |
| 9390 if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){ | |
| 9391 int rc = apndWriteMark(paf, pFile, iWriteEnd); | |
| 9392 if( SQLITE_OK!=rc ) return rc; | |
| 9393 } | |
| 9394 return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst); | |
| 9395 } | |
| 9396 | |
| 9397 /* | |
| 9398 ** Truncate an apnd-file. | |
| 9399 */ | |
| 9400 static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){ | |
| 9401 ApndFile *paf = (ApndFile *)pFile; | |
| 9402 pFile = ORIGFILE(pFile); | |
| 9403 /* The append mark goes out first so truncate failure does not lose it. */ | |
| 9404 if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR; | |
| 9405 /* Truncate underlying file just past append mark */ | |
| 9406 return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE); | |
| 9407 } | |
| 9408 | |
| 9409 /* | |
| 9410 ** Sync an apnd-file. | |
| 9411 */ | |
| 9412 static int apndSync(sqlite3_file *pFile, int flags){ | |
| 9413 pFile = ORIGFILE(pFile); | |
| 9414 return pFile->pMethods->xSync(pFile, flags); | |
| 9415 } | |
| 9416 | |
| 9417 /* | |
| 9418 ** Return the current file-size of an apnd-file. | |
| 9419 ** If the append mark is not yet there, the file-size is 0. | |
| 9420 */ | |
| 9421 static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ | |
| 9422 ApndFile *paf = (ApndFile *)pFile; | |
| 9423 *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0; | |
| 9424 return SQLITE_OK; | |
| 9425 } | |
| 9426 | |
| 9427 /* | |
| 9428 ** Lock an apnd-file. | |
| 9429 */ | |
| 9430 static int apndLock(sqlite3_file *pFile, int eLock){ | |
| 9431 pFile = ORIGFILE(pFile); | |
| 9432 return pFile->pMethods->xLock(pFile, eLock); | |
| 9433 } | |
| 9434 | |
| 9435 /* | |
| 9436 ** Unlock an apnd-file. | |
| 9437 */ | |
| 9438 static int apndUnlock(sqlite3_file *pFile, int eLock){ | |
| 9439 pFile = ORIGFILE(pFile); | |
| 9440 return pFile->pMethods->xUnlock(pFile, eLock); | |
| 9441 } | |
| 9442 | |
| 9443 /* | |
| 9444 ** Check if another file-handle holds a RESERVED lock on an apnd-file. | |
| 9445 */ | |
| 9446 static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){ | |
| 9447 pFile = ORIGFILE(pFile); | |
| 9448 return pFile->pMethods->xCheckReservedLock(pFile, pResOut); | |
| 9449 } | |
| 9450 | |
| 9451 /* | |
| 9452 ** File control method. For custom operations on an apnd-file. | |
| 9453 */ | |
| 9454 static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){ | |
| 9455 ApndFile *paf = (ApndFile *)pFile; | |
| 9456 int rc; | |
| 9457 pFile = ORIGFILE(pFile); | |
| 9458 if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne; | |
| 9459 rc = pFile->pMethods->xFileControl(pFile, op, pArg); | |
| 9460 if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ | |
| 9461 *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg); | |
| 9462 } | |
| 9463 return rc; | |
| 9464 } | |
| 9465 | |
| 9466 /* | |
| 9467 ** Return the sector-size in bytes for an apnd-file. | |
| 9468 */ | |
| 9469 static int apndSectorSize(sqlite3_file *pFile){ | |
| 9470 pFile = ORIGFILE(pFile); | |
| 9471 return pFile->pMethods->xSectorSize(pFile); | |
| 9472 } | |
| 9473 | |
| 9474 /* | |
| 9475 ** Return the device characteristic flags supported by an apnd-file. | |
| 9476 */ | |
| 9477 static int apndDeviceCharacteristics(sqlite3_file *pFile){ | |
| 9478 pFile = ORIGFILE(pFile); | |
| 9479 return pFile->pMethods->xDeviceCharacteristics(pFile); | |
| 9480 } | |
| 9481 | |
| 9482 /* Create a shared memory file mapping */ | |
| 9483 static int apndShmMap( | |
| 9484 sqlite3_file *pFile, | |
| 9485 int iPg, | |
| 9486 int pgsz, | |
| 9487 int bExtend, | |
| 9488 void volatile **pp | |
| 9489 ){ | |
| 9490 pFile = ORIGFILE(pFile); | |
| 9491 return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp); | |
| 9492 } | |
| 9493 | |
| 9494 /* Perform locking on a shared-memory segment */ | |
| 9495 static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){ | |
| 9496 pFile = ORIGFILE(pFile); | |
| 9497 return pFile->pMethods->xShmLock(pFile,offset,n,flags); | |
| 9498 } | |
| 9499 | |
| 9500 /* Memory barrier operation on shared memory */ | |
| 9501 static void apndShmBarrier(sqlite3_file *pFile){ | |
| 9502 pFile = ORIGFILE(pFile); | |
| 9503 pFile->pMethods->xShmBarrier(pFile); | |
| 9504 } | |
| 9505 | |
| 9506 /* Unmap a shared memory segment */ | |
| 9507 static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){ | |
| 9508 pFile = ORIGFILE(pFile); | |
| 9509 return pFile->pMethods->xShmUnmap(pFile,deleteFlag); | |
| 9510 } | |
| 9511 | |
| 9512 /* Fetch a page of a memory-mapped file */ | |
| 9513 static int apndFetch( | |
| 9514 sqlite3_file *pFile, | |
| 9515 sqlite3_int64 iOfst, | |
| 9516 int iAmt, | |
| 9517 void **pp | |
| 9518 ){ | |
| 9519 ApndFile *p = (ApndFile *)pFile; | |
| 9520 if( p->iMark < 0 || iOfst+iAmt > p->iMark ){ | |
| 9521 return SQLITE_IOERR; /* Cannot read what is not yet there. */ | |
| 9522 } | |
| 9523 pFile = ORIGFILE(pFile); | |
| 9524 return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp); | |
| 9525 } | |
| 9526 | |
| 9527 /* Release a memory-mapped page */ | |
| 9528 static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ | |
| 9529 ApndFile *p = (ApndFile *)pFile; | |
| 9530 pFile = ORIGFILE(pFile); | |
| 9531 return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage); | |
| 9532 } | |
| 9533 | |
| 9534 /* | |
| 9535 ** Try to read the append-mark off the end of a file. Return the | |
| 9536 ** start of the appended database if the append-mark is present. | |
| 9537 ** If there is no valid append-mark, return -1; | |
| 9538 ** | |
| 9539 ** An append-mark is only valid if the NNNNNNNN start-of-database offset | |
| 9540 ** indicates that the appended database contains at least one page. The | |
| 9541 ** start-of-database value must be a multiple of 512. | |
| 9542 */ | |
| 9543 static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){ | |
| 9544 int rc, i; | |
| 9545 sqlite3_int64 iMark; | |
| 9546 int msbs = 8 * (APND_MARK_FOS_SZ-1); | |
| 9547 unsigned char a[APND_MARK_SIZE]; | |
| 9548 | |
| 9549 if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1; | |
| 9550 rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE); | |
| 9551 if( rc ) return -1; | |
| 9552 if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1; | |
| 9553 iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs; | |
| 9554 for(i=1; i<8; i++){ | |
| 9555 msbs -= 8; | |
| 9556 iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs; | |
| 9557 } | |
| 9558 if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1; | |
| 9559 if( iMark & 0x1ff ) return -1; | |
| 9560 return iMark; | |
| 9561 } | |
| 9562 | |
| 9563 static const char apvfsSqliteHdr[] = "SQLite format 3"; | |
| 9564 /* | |
| 9565 ** Check to see if the file is an appendvfs SQLite database file. | |
| 9566 ** Return true iff it is such. Parameter sz is the file's size. | |
| 9567 */ | |
| 9568 static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){ | |
| 9569 int rc; | |
| 9570 char zHdr[16]; | |
| 9571 sqlite3_int64 iMark = apndReadMark(sz, pFile); | |
| 9572 if( iMark>=0 ){ | |
| 9573 /* If file has the correct end-marker, the expected odd size, and the | |
| 9574 ** SQLite DB type marker where the end-marker puts it, then it | |
| 9575 ** is an appendvfs database. | |
| 9576 */ | |
| 9577 rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark); | |
| 9578 if( SQLITE_OK==rc | |
| 9579 && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0 | |
| 9580 && (sz & 0x1ff) == APND_MARK_SIZE | |
| 9581 && sz>=512+APND_MARK_SIZE | |
| 9582 ){ | |
| 9583 return 1; /* It's an appendvfs database */ | |
| 9584 } | |
| 9585 } | |
| 9586 return 0; | |
| 9587 } | |
| 9588 | |
| 9589 /* | |
| 9590 ** Check to see if the file is an ordinary SQLite database file. | |
| 9591 ** Return true iff so. Parameter sz is the file's size. | |
| 9592 */ | |
| 9593 static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){ | |
| 9594 char zHdr[16]; | |
| 9595 if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */ | |
| 9596 || (sz & 0x1ff) != 0 | |
| 9597 || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0) | |
| 9598 || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0 | |
| 9599 ){ | |
| 9600 return 0; | |
| 9601 }else{ | |
| 9602 return 1; | |
| 9603 } | |
| 9604 } | |
| 9605 | |
| 9606 /* | |
| 9607 ** Open an apnd file handle. | |
| 9608 */ | |
| 9609 static int apndOpen( | |
| 9610 sqlite3_vfs *pApndVfs, | |
| 9611 const char *zName, | |
| 9612 sqlite3_file *pFile, | |
| 9613 int flags, | |
| 9614 int *pOutFlags | |
| 9615 ){ | |
| 9616 ApndFile *pApndFile = (ApndFile*)pFile; | |
| 9617 sqlite3_file *pBaseFile = ORIGFILE(pFile); | |
| 9618 sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs); | |
| 9619 int rc; | |
| 9620 sqlite3_int64 sz = 0; | |
| 9621 if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ | |
| 9622 /* The appendvfs is not to be used for transient or temporary databases. | |
| 9623 ** Just use the base VFS open to initialize the given file object and | |
| 9624 ** open the underlying file. (Appendvfs is then unused for this file.) | |
| 9625 */ | |
| 9626 return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags); | |
| 9627 } | |
| 9628 memset(pApndFile, 0, sizeof(ApndFile)); | |
| 9629 pFile->pMethods = &apnd_io_methods; | |
| 9630 pApndFile->iMark = -1; /* Append mark not yet written */ | |
| 9631 | |
| 9632 rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags); | |
| 9633 if( rc==SQLITE_OK ){ | |
| 9634 rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz); | |
| 9635 if( rc ){ | |
| 9636 pBaseFile->pMethods->xClose(pBaseFile); | |
| 9637 } | |
| 9638 } | |
| 9639 if( rc ){ | |
| 9640 pFile->pMethods = 0; | |
| 9641 return rc; | |
| 9642 } | |
| 9643 if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){ | |
| 9644 /* The file being opened appears to be just an ordinary DB. Copy | |
| 9645 ** the base dispatch-table so this instance mimics the base VFS. | |
| 9646 */ | |
| 9647 memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile); | |
| 9648 return SQLITE_OK; | |
| 9649 } | |
| 9650 pApndFile->iPgOne = apndReadMark(sz, pFile); | |
| 9651 if( pApndFile->iPgOne>=0 ){ | |
| 9652 pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */ | |
| 9653 return SQLITE_OK; | |
| 9654 } | |
| 9655 if( (flags & SQLITE_OPEN_CREATE)==0 ){ | |
| 9656 pBaseFile->pMethods->xClose(pBaseFile); | |
| 9657 rc = SQLITE_CANTOPEN; | |
| 9658 pFile->pMethods = 0; | |
| 9659 }else{ | |
| 9660 /* Round newly added appendvfs location to #define'd page boundary. | |
| 9661 ** Note that nothing has yet been written to the underlying file. | |
| 9662 ** The append mark will be written along with first content write. | |
| 9663 ** Until then, paf->iMark value indicates it is not yet written. | |
| 9664 */ | |
| 9665 pApndFile->iPgOne = APND_START_ROUNDUP(sz); | |
| 9666 } | |
| 9667 return rc; | |
| 9668 } | |
| 9669 | |
| 9670 /* | |
| 9671 ** Delete an apnd file. | |
| 9672 ** For an appendvfs, this could mean delete the appendvfs portion, | |
| 9673 ** leaving the appendee as it was before it gained an appendvfs. | |
| 9674 ** For now, this code deletes the underlying file too. | |
| 9675 */ | |
| 9676 static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ | |
| 9677 return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync); | |
| 9678 } | |
| 9679 | |
| 9680 /* | |
| 9681 ** All other VFS methods are pass-thrus. | |
| 9682 */ | |
| 9683 static int apndAccess( | |
| 9684 sqlite3_vfs *pVfs, | |
| 9685 const char *zPath, | |
| 9686 int flags, | |
| 9687 int *pResOut | |
| 9688 ){ | |
| 9689 return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut); | |
| 9690 } | |
| 9691 static int apndFullPathname( | |
| 9692 sqlite3_vfs *pVfs, | |
| 9693 const char *zPath, | |
| 9694 int nOut, | |
| 9695 char *zOut | |
| 9696 ){ | |
| 9697 return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut); | |
| 9698 } | |
| 9699 static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){ | |
| 9700 return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); | |
| 9701 } | |
| 9702 static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ | |
| 9703 ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); | |
| 9704 } | |
| 9705 static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ | |
| 9706 return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); | |
| 9707 } | |
| 9708 static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){ | |
| 9709 ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); | |
| 9710 } | |
| 9711 static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ | |
| 9712 return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); | |
| 9713 } | |
| 9714 static int apndSleep(sqlite3_vfs *pVfs, int nMicro){ | |
| 9715 return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); | |
| 9716 } | |
| 9717 static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ | |
| 9718 return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); | |
| 9719 } | |
| 9720 static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){ | |
| 9721 return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); | |
| 9722 } | |
| 9723 static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ | |
| 9724 return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); | |
| 9725 } | |
| 9726 static int apndSetSystemCall( | |
| 9727 sqlite3_vfs *pVfs, | |
| 9728 const char *zName, | |
| 9729 sqlite3_syscall_ptr pCall | |
| 9730 ){ | |
| 9731 return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall); | |
| 9732 } | |
| 9733 static sqlite3_syscall_ptr apndGetSystemCall( | |
| 9734 sqlite3_vfs *pVfs, | |
| 9735 const char *zName | |
| 9736 ){ | |
| 9737 return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName); | |
| 9738 } | |
| 9739 static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){ | |
| 9740 return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName); | |
| 9741 } | |
| 9742 | |
| 9743 | |
| 9744 #ifdef _WIN32 | |
| 9745 | |
| 9746 #endif | |
| 9747 /* | |
| 9748 ** This routine is called when the extension is loaded. | |
| 9749 ** Register the new VFS. | |
| 9750 */ | |
| 9751 int sqlite3_appendvfs_init( | |
| 9752 sqlite3 *db, | |
| 9753 char **pzErrMsg, | |
| 9754 const sqlite3_api_routines *pApi | |
| 9755 ){ | |
| 9756 int rc = SQLITE_OK; | |
| 9757 sqlite3_vfs *pOrig; | |
| 9758 SQLITE_EXTENSION_INIT2(pApi); | |
| 9759 (void)pzErrMsg; | |
| 9760 (void)db; | |
| 9761 pOrig = sqlite3_vfs_find(0); | |
| 9762 if( pOrig==0 ) return SQLITE_ERROR; | |
| 9763 apnd_vfs.iVersion = pOrig->iVersion; | |
| 9764 apnd_vfs.pAppData = pOrig; | |
| 9765 apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile); | |
| 9766 rc = sqlite3_vfs_register(&apnd_vfs, 0); | |
| 9767 #ifdef APPENDVFS_TEST | |
| 9768 if( rc==SQLITE_OK ){ | |
| 9769 rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister); | |
| 9770 } | |
| 9771 #endif | |
| 9772 if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY; | |
| 9773 return rc; | |
| 9774 } | |
| 9775 | |
| 9776 /************************* End ../ext/misc/appendvfs.c ********************/ | |
| 9777 #endif | |
| 9778 #ifdef SQLITE_HAVE_ZLIB | |
| 9779 /************************* Begin ../ext/misc/zipfile.c ******************/ | |
| 9780 /* | |
| 9781 ** 2017-12-26 | |
| 9782 ** | |
| 9783 ** The author disclaims copyright to this source code. In place of | |
| 9784 ** a legal notice, here is a blessing: | |
| 9785 ** | |
| 9786 ** May you do good and not evil. | |
| 9787 ** May you find forgiveness for yourself and forgive others. | |
| 9788 ** May you share freely, never taking more than you give. | |
| 9789 ** | |
| 9790 ****************************************************************************** | |
| 9791 ** | |
| 9792 ** This file implements a virtual table for reading and writing ZIP archive | |
| 9793 ** files. | |
| 9794 ** | |
| 9795 ** Usage example: | |
| 9796 ** | |
| 9797 ** SELECT name, sz, datetime(mtime,'unixepoch') FROM zipfile($filename); | |
| 9798 ** | |
| 9799 ** Current limitations: | |
| 9800 ** | |
| 9801 ** * No support for encryption | |
| 9802 ** * No support for ZIP archives spanning multiple files | |
| 9803 ** * No support for zip64 extensions | |
| 9804 ** * Only the "inflate/deflate" (zlib) compression method is supported | |
| 9805 */ | |
| 9806 /* #include "sqlite3ext.h" */ | |
| 9807 SQLITE_EXTENSION_INIT1 | |
| 9808 #include <stdio.h> | |
| 9809 #include <string.h> | |
| 9810 #include <assert.h> | |
| 9811 #ifndef SQLITE_NO_STDINT | |
| 9812 # include <stdint.h> | |
| 9813 #endif | |
| 9814 | |
| 9815 #include <zlib.h> | |
| 9816 | |
| 9817 /* When used as part of the CLI, the sqlite3_stdio.h module will have | |
| 9818 ** been included before this one. In that case use the sqlite3_stdio.h | |
| 9819 ** #defines. If not, create our own for fopen(). | |
| 9820 */ | |
| 9821 #ifndef _SQLITE3_STDIO_H_ | |
| 9822 # define sqlite3_fopen fopen | |
| 9823 #endif | |
| 9824 | |
| 9825 #ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 9826 | |
| 9827 #ifndef SQLITE_AMALGAMATION | |
| 9828 | |
| 9829 #ifndef UINT32_TYPE | |
| 9830 # ifdef HAVE_UINT32_T | |
| 9831 # define UINT32_TYPE uint32_t | |
| 9832 # else | |
| 9833 # define UINT32_TYPE unsigned int | |
| 9834 # endif | |
| 9835 #endif | |
| 9836 #ifndef UINT16_TYPE | |
| 9837 # ifdef HAVE_UINT16_T | |
| 9838 # define UINT16_TYPE uint16_t | |
| 9839 # else | |
| 9840 # define UINT16_TYPE unsigned short int | |
| 9841 # endif | |
| 9842 #endif | |
| 9843 /* typedef sqlite3_int64 i64; */ | |
| 9844 /* typedef unsigned char u8; */ | |
| 9845 /* typedef UINT32_TYPE u32; // 4-byte unsigned integer // */ | |
| 9846 /* typedef UINT16_TYPE u16; // 2-byte unsigned integer // */ | |
| 9847 #define MIN(a,b) ((a)<(b) ? (a) : (b)) | |
| 9848 | |
| 9849 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) | |
| 9850 # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 | |
| 9851 #endif | |
| 9852 #if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) | |
| 9853 # define ALWAYS(X) (1) | |
| 9854 # define NEVER(X) (0) | |
| 9855 #elif !defined(NDEBUG) | |
| 9856 # define ALWAYS(X) ((X)?1:(assert(0),0)) | |
| 9857 # define NEVER(X) ((X)?(assert(0),1):0) | |
| 9858 #else | |
| 9859 # define ALWAYS(X) (X) | |
| 9860 # define NEVER(X) (X) | |
| 9861 #endif | |
| 9862 | |
| 9863 #endif /* SQLITE_AMALGAMATION */ | |
| 9864 | |
| 9865 /* | |
| 9866 ** Definitions for mode bitmasks S_IFDIR, S_IFREG and S_IFLNK. | |
| 9867 ** | |
| 9868 ** In some ways it would be better to obtain these values from system | |
| 9869 ** header files. But, the dependency is undesirable and (a) these | |
| 9870 ** have been stable for decades, (b) the values are part of POSIX and | |
| 9871 ** are also made explicit in [man stat], and (c) are part of the | |
| 9872 ** file format for zip archives. | |
| 9873 */ | |
| 9874 #ifndef S_IFDIR | |
| 9875 # define S_IFDIR 0040000 | |
| 9876 #endif | |
| 9877 #ifndef S_IFREG | |
| 9878 # define S_IFREG 0100000 | |
| 9879 #endif | |
| 9880 #ifndef S_IFLNK | |
| 9881 # define S_IFLNK 0120000 | |
| 9882 #endif | |
| 9883 | |
| 9884 static const char ZIPFILE_SCHEMA[] = | |
| 9885 "CREATE TABLE y(" | |
| 9886 "name PRIMARY KEY," /* 0: Name of file in zip archive */ | |
| 9887 "mode," /* 1: POSIX mode for file */ | |
| 9888 "mtime," /* 2: Last modification time (secs since 1970)*/ | |
| 9889 "sz," /* 3: Size of object */ | |
| 9890 "rawdata," /* 4: Raw data */ | |
| 9891 "data," /* 5: Uncompressed data */ | |
| 9892 "method," /* 6: Compression method (integer) */ | |
| 9893 "z HIDDEN" /* 7: Name of zip file */ | |
| 9894 ") WITHOUT ROWID;"; | |
| 9895 | |
| 9896 #define ZIPFILE_F_COLUMN_IDX 7 /* Index of column "file" in the above */ | |
| 9897 #define ZIPFILE_MX_NAME (250) /* Windows limitation on filename size */ | |
| 9898 | |
| 9899 /* | |
| 9900 ** The buffer should be large enough to contain 3 65536 byte strings - the | |
| 9901 ** filename, the extra field and the file comment. | |
| 9902 */ | |
| 9903 #define ZIPFILE_BUFFER_SIZE (200*1024) | |
| 9904 | |
| 9905 | |
| 9906 /* | |
| 9907 ** Magic numbers used to read and write zip files. | |
| 9908 ** | |
| 9909 ** ZIPFILE_NEWENTRY_MADEBY: | |
| 9910 ** Use this value for the "version-made-by" field in new zip file | |
| 9911 ** entries. The upper byte indicates "unix", and the lower byte | |
| 9912 ** indicates that the zip file matches pkzip specification 3.0. | |
| 9913 ** This is what info-zip seems to do. | |
| 9914 ** | |
| 9915 ** ZIPFILE_NEWENTRY_REQUIRED: | |
| 9916 ** Value for "version-required-to-extract" field of new entries. | |
| 9917 ** Version 2.0 is required to support folders and deflate compression. | |
| 9918 ** | |
| 9919 ** ZIPFILE_NEWENTRY_FLAGS: | |
| 9920 ** Value for "general-purpose-bit-flags" field of new entries. Bit | |
| 9921 ** 11 means "utf-8 filename and comment". | |
| 9922 ** | |
| 9923 ** ZIPFILE_SIGNATURE_CDS: | |
| 9924 ** First 4 bytes of a valid CDS record. | |
| 9925 ** | |
| 9926 ** ZIPFILE_SIGNATURE_LFH: | |
| 9927 ** First 4 bytes of a valid LFH record. | |
| 9928 ** | |
| 9929 ** ZIPFILE_SIGNATURE_EOCD | |
| 9930 ** First 4 bytes of a valid EOCD record. | |
| 9931 */ | |
| 9932 #define ZIPFILE_EXTRA_TIMESTAMP 0x5455 | |
| 9933 #define ZIPFILE_NEWENTRY_MADEBY ((3<<8) + 30) | |
| 9934 #define ZIPFILE_NEWENTRY_REQUIRED 20 | |
| 9935 #define ZIPFILE_NEWENTRY_FLAGS 0x800 | |
| 9936 #define ZIPFILE_SIGNATURE_CDS 0x02014b50 | |
| 9937 #define ZIPFILE_SIGNATURE_LFH 0x04034b50 | |
| 9938 #define ZIPFILE_SIGNATURE_EOCD 0x06054b50 | |
| 9939 | |
| 9940 /* | |
| 9941 ** The sizes of the fixed-size part of each of the three main data | |
| 9942 ** structures in a zip archive. | |
| 9943 */ | |
| 9944 #define ZIPFILE_LFH_FIXED_SZ 30 | |
| 9945 #define ZIPFILE_EOCD_FIXED_SZ 22 | |
| 9946 #define ZIPFILE_CDS_FIXED_SZ 46 | |
| 9947 | |
| 9948 /* | |
| 9949 *** 4.3.16 End of central directory record: | |
| 9950 *** | |
| 9951 *** end of central dir signature 4 bytes (0x06054b50) | |
| 9952 *** number of this disk 2 bytes | |
| 9953 *** number of the disk with the | |
| 9954 *** start of the central directory 2 bytes | |
| 9955 *** total number of entries in the | |
| 9956 *** central directory on this disk 2 bytes | |
| 9957 *** total number of entries in | |
| 9958 *** the central directory 2 bytes | |
| 9959 *** size of the central directory 4 bytes | |
| 9960 *** offset of start of central | |
| 9961 *** directory with respect to | |
| 9962 *** the starting disk number 4 bytes | |
| 9963 *** .ZIP file comment length 2 bytes | |
| 9964 *** .ZIP file comment (variable size) | |
| 9965 */ | |
| 9966 typedef struct ZipfileEOCD ZipfileEOCD; | |
| 9967 struct ZipfileEOCD { | |
| 9968 u16 iDisk; | |
| 9969 u16 iFirstDisk; | |
| 9970 u16 nEntry; | |
| 9971 u16 nEntryTotal; | |
| 9972 u32 nSize; | |
| 9973 u32 iOffset; | |
| 9974 }; | |
| 9975 | |
| 9976 /* | |
| 9977 *** 4.3.12 Central directory structure: | |
| 9978 *** | |
| 9979 *** ... | |
| 9980 *** | |
| 9981 *** central file header signature 4 bytes (0x02014b50) | |
| 9982 *** version made by 2 bytes | |
| 9983 *** version needed to extract 2 bytes | |
| 9984 *** general purpose bit flag 2 bytes | |
| 9985 *** compression method 2 bytes | |
| 9986 *** last mod file time 2 bytes | |
| 9987 *** last mod file date 2 bytes | |
| 9988 *** crc-32 4 bytes | |
| 9989 *** compressed size 4 bytes | |
| 9990 *** uncompressed size 4 bytes | |
| 9991 *** file name length 2 bytes | |
| 9992 *** extra field length 2 bytes | |
| 9993 *** file comment length 2 bytes | |
| 9994 *** disk number start 2 bytes | |
| 9995 *** internal file attributes 2 bytes | |
| 9996 *** external file attributes 4 bytes | |
| 9997 *** relative offset of local header 4 bytes | |
| 9998 */ | |
| 9999 typedef struct ZipfileCDS ZipfileCDS; | |
| 10000 struct ZipfileCDS { | |
| 10001 u16 iVersionMadeBy; | |
| 10002 u16 iVersionExtract; | |
| 10003 u16 flags; | |
| 10004 u16 iCompression; | |
| 10005 u16 mTime; | |
| 10006 u16 mDate; | |
| 10007 u32 crc32; | |
| 10008 u32 szCompressed; | |
| 10009 u32 szUncompressed; | |
| 10010 u16 nFile; | |
| 10011 u16 nExtra; | |
| 10012 u16 nComment; | |
| 10013 u16 iDiskStart; | |
| 10014 u16 iInternalAttr; | |
| 10015 u32 iExternalAttr; | |
| 10016 u32 iOffset; | |
| 10017 char *zFile; /* Filename (sqlite3_malloc()) */ | |
| 10018 }; | |
| 10019 | |
| 10020 /* | |
| 10021 *** 4.3.7 Local file header: | |
| 10022 *** | |
| 10023 *** local file header signature 4 bytes (0x04034b50) | |
| 10024 *** version needed to extract 2 bytes | |
| 10025 *** general purpose bit flag 2 bytes | |
| 10026 *** compression method 2 bytes | |
| 10027 *** last mod file time 2 bytes | |
| 10028 *** last mod file date 2 bytes | |
| 10029 *** crc-32 4 bytes | |
| 10030 *** compressed size 4 bytes | |
| 10031 *** uncompressed size 4 bytes | |
| 10032 *** file name length 2 bytes | |
| 10033 *** extra field length 2 bytes | |
| 10034 *** | |
| 10035 */ | |
| 10036 typedef struct ZipfileLFH ZipfileLFH; | |
| 10037 struct ZipfileLFH { | |
| 10038 u16 iVersionExtract; | |
| 10039 u16 flags; | |
| 10040 u16 iCompression; | |
| 10041 u16 mTime; | |
| 10042 u16 mDate; | |
| 10043 u32 crc32; | |
| 10044 u32 szCompressed; | |
| 10045 u32 szUncompressed; | |
| 10046 u16 nFile; | |
| 10047 u16 nExtra; | |
| 10048 }; | |
| 10049 | |
| 10050 typedef struct ZipfileEntry ZipfileEntry; | |
| 10051 struct ZipfileEntry { | |
| 10052 ZipfileCDS cds; /* Parsed CDS record */ | |
| 10053 u32 mUnixTime; /* Modification time, in UNIX format */ | |
| 10054 u8 *aExtra; /* cds.nExtra+cds.nComment bytes of extra data */ | |
| 10055 i64 iDataOff; /* Offset to data in file (if aData==0) */ | |
| 10056 u8 *aData; /* cds.szCompressed bytes of compressed data */ | |
| 10057 ZipfileEntry *pNext; /* Next element in in-memory CDS */ | |
| 10058 }; | |
| 10059 | |
| 10060 /* | |
| 10061 ** Cursor type for zipfile tables. | |
| 10062 */ | |
| 10063 typedef struct ZipfileCsr ZipfileCsr; | |
| 10064 struct ZipfileCsr { | |
| 10065 sqlite3_vtab_cursor base; /* Base class - must be first */ | |
| 10066 i64 iId; /* Cursor ID */ | |
| 10067 u8 bEof; /* True when at EOF */ | |
| 10068 u8 bNoop; /* If next xNext() call is no-op */ | |
| 10069 | |
| 10070 /* Used outside of write transactions */ | |
| 10071 FILE *pFile; /* Zip file */ | |
| 10072 i64 iNextOff; /* Offset of next record in central directory */ | |
| 10073 ZipfileEOCD eocd; /* Parse of central directory record */ | |
| 10074 | |
| 10075 ZipfileEntry *pFreeEntry; /* Free this list when cursor is closed or reset */ | |
| 10076 ZipfileEntry *pCurrent; /* Current entry */ | |
| 10077 ZipfileCsr *pCsrNext; /* Next cursor on same virtual table */ | |
| 10078 }; | |
| 10079 | |
| 10080 typedef struct ZipfileTab ZipfileTab; | |
| 10081 struct ZipfileTab { | |
| 10082 sqlite3_vtab base; /* Base class - must be first */ | |
| 10083 char *zFile; /* Zip file this table accesses (may be NULL) */ | |
| 10084 sqlite3 *db; /* Host database connection */ | |
| 10085 u8 *aBuffer; /* Temporary buffer used for various tasks */ | |
| 10086 | |
| 10087 ZipfileCsr *pCsrList; /* List of cursors */ | |
| 10088 i64 iNextCsrid; | |
| 10089 | |
| 10090 /* The following are used by write transactions only */ | |
| 10091 ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */ | |
| 10092 ZipfileEntry *pLastEntry; /* Last element in pFirstEntry list */ | |
| 10093 FILE *pWriteFd; /* File handle open on zip archive */ | |
| 10094 i64 szCurrent; /* Current size of zip archive */ | |
| 10095 i64 szOrig; /* Size of archive at start of transaction */ | |
| 10096 }; | |
| 10097 | |
| 10098 /* | |
| 10099 ** Set the error message contained in context ctx to the results of | |
| 10100 ** vprintf(zFmt, ...). | |
| 10101 */ | |
| 10102 static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){ | |
| 10103 char *zMsg = 0; | |
| 10104 va_list ap; | |
| 10105 va_start(ap, zFmt); | |
| 10106 zMsg = sqlite3_vmprintf(zFmt, ap); | |
| 10107 sqlite3_result_error(ctx, zMsg, -1); | |
| 10108 sqlite3_free(zMsg); | |
| 10109 va_end(ap); | |
| 10110 } | |
| 10111 | |
| 10112 /* | |
| 10113 ** If string zIn is quoted, dequote it in place. Otherwise, if the string | |
| 10114 ** is not quoted, do nothing. | |
| 10115 */ | |
| 10116 static void zipfileDequote(char *zIn){ | |
| 10117 char q = zIn[0]; | |
| 10118 if( q=='"' || q=='\'' || q=='`' || q=='[' ){ | |
| 10119 int iIn = 1; | |
| 10120 int iOut = 0; | |
| 10121 if( q=='[' ) q = ']'; | |
| 10122 while( ALWAYS(zIn[iIn]) ){ | |
| 10123 char c = zIn[iIn++]; | |
| 10124 if( c==q && zIn[iIn++]!=q ) break; | |
| 10125 zIn[iOut++] = c; | |
| 10126 } | |
| 10127 zIn[iOut] = '\0'; | |
| 10128 } | |
| 10129 } | |
| 10130 | |
| 10131 /* | |
| 10132 ** Construct a new ZipfileTab virtual table object. | |
| 10133 ** | |
| 10134 ** argv[0] -> module name ("zipfile") | |
| 10135 ** argv[1] -> database name | |
| 10136 ** argv[2] -> table name | |
| 10137 ** argv[...] -> "column name" and other module argument fields. | |
| 10138 */ | |
| 10139 static int zipfileConnect( | |
| 10140 sqlite3 *db, | |
| 10141 void *pAux, | |
| 10142 int argc, const char *const*argv, | |
| 10143 sqlite3_vtab **ppVtab, | |
| 10144 char **pzErr | |
| 10145 ){ | |
| 10146 int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE; | |
| 10147 int nFile = 0; | |
| 10148 const char *zFile = 0; | |
| 10149 ZipfileTab *pNew = 0; | |
| 10150 int rc; | |
| 10151 (void)pAux; | |
| 10152 | |
| 10153 /* If the table name is not "zipfile", require that the argument be | |
| 10154 ** specified. This stops zipfile tables from being created as: | |
| 10155 ** | |
| 10156 ** CREATE VIRTUAL TABLE zzz USING zipfile(); | |
| 10157 ** | |
| 10158 ** It does not prevent: | |
| 10159 ** | |
| 10160 ** CREATE VIRTUAL TABLE zipfile USING zipfile(); | |
| 10161 */ | |
| 10162 assert( 0==sqlite3_stricmp(argv[0], "zipfile") ); | |
| 10163 if( (0!=sqlite3_stricmp(argv[2], "zipfile") && argc<4) || argc>4 ){ | |
| 10164 *pzErr = sqlite3_mprintf("zipfile constructor requires one argument"); | |
| 10165 return SQLITE_ERROR; | |
| 10166 } | |
| 10167 | |
| 10168 if( argc>3 ){ | |
| 10169 zFile = argv[3]; | |
| 10170 nFile = (int)strlen(zFile)+1; | |
| 10171 } | |
| 10172 | |
| 10173 rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA); | |
| 10174 if( rc==SQLITE_OK ){ | |
| 10175 pNew = (ZipfileTab*)sqlite3_malloc64((sqlite3_int64)nByte+nFile); | |
| 10176 if( pNew==0 ) return SQLITE_NOMEM; | |
| 10177 memset(pNew, 0, nByte+nFile); | |
| 10178 pNew->db = db; | |
| 10179 pNew->aBuffer = (u8*)&pNew[1]; | |
| 10180 if( zFile ){ | |
| 10181 pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE]; | |
| 10182 memcpy(pNew->zFile, zFile, nFile); | |
| 10183 zipfileDequote(pNew->zFile); | |
| 10184 } | |
| 10185 } | |
| 10186 sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); | |
| 10187 *ppVtab = (sqlite3_vtab*)pNew; | |
| 10188 return rc; | |
| 10189 } | |
| 10190 | |
| 10191 /* | |
| 10192 ** Free the ZipfileEntry structure indicated by the only argument. | |
| 10193 */ | |
| 10194 static void zipfileEntryFree(ZipfileEntry *p){ | |
| 10195 if( p ){ | |
| 10196 sqlite3_free(p->cds.zFile); | |
| 10197 sqlite3_free(p); | |
| 10198 } | |
| 10199 } | |
| 10200 | |
| 10201 /* | |
| 10202 ** Release resources that should be freed at the end of a write | |
| 10203 ** transaction. | |
| 10204 */ | |
| 10205 static void zipfileCleanupTransaction(ZipfileTab *pTab){ | |
| 10206 ZipfileEntry *pEntry; | |
| 10207 ZipfileEntry *pNext; | |
| 10208 | |
| 10209 if( pTab->pWriteFd ){ | |
| 10210 fclose(pTab->pWriteFd); | |
| 10211 pTab->pWriteFd = 0; | |
| 10212 } | |
| 10213 for(pEntry=pTab->pFirstEntry; pEntry; pEntry=pNext){ | |
| 10214 pNext = pEntry->pNext; | |
| 10215 zipfileEntryFree(pEntry); | |
| 10216 } | |
| 10217 pTab->pFirstEntry = 0; | |
| 10218 pTab->pLastEntry = 0; | |
| 10219 pTab->szCurrent = 0; | |
| 10220 pTab->szOrig = 0; | |
| 10221 } | |
| 10222 | |
| 10223 /* | |
| 10224 ** This method is the destructor for zipfile vtab objects. | |
| 10225 */ | |
| 10226 static int zipfileDisconnect(sqlite3_vtab *pVtab){ | |
| 10227 zipfileCleanupTransaction((ZipfileTab*)pVtab); | |
| 10228 sqlite3_free(pVtab); | |
| 10229 return SQLITE_OK; | |
| 10230 } | |
| 10231 | |
| 10232 /* | |
| 10233 ** Constructor for a new ZipfileCsr object. | |
| 10234 */ | |
| 10235 static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){ | |
| 10236 ZipfileTab *pTab = (ZipfileTab*)p; | |
| 10237 ZipfileCsr *pCsr; | |
| 10238 pCsr = sqlite3_malloc(sizeof(*pCsr)); | |
| 10239 *ppCsr = (sqlite3_vtab_cursor*)pCsr; | |
| 10240 if( pCsr==0 ){ | |
| 10241 return SQLITE_NOMEM; | |
| 10242 } | |
| 10243 memset(pCsr, 0, sizeof(*pCsr)); | |
| 10244 pCsr->iId = ++pTab->iNextCsrid; | |
| 10245 pCsr->pCsrNext = pTab->pCsrList; | |
| 10246 pTab->pCsrList = pCsr; | |
| 10247 return SQLITE_OK; | |
| 10248 } | |
| 10249 | |
| 10250 /* | |
| 10251 ** Reset a cursor back to the state it was in when first returned | |
| 10252 ** by zipfileOpen(). | |
| 10253 */ | |
| 10254 static void zipfileResetCursor(ZipfileCsr *pCsr){ | |
| 10255 ZipfileEntry *p; | |
| 10256 ZipfileEntry *pNext; | |
| 10257 | |
| 10258 pCsr->bEof = 0; | |
| 10259 if( pCsr->pFile ){ | |
| 10260 fclose(pCsr->pFile); | |
| 10261 pCsr->pFile = 0; | |
| 10262 zipfileEntryFree(pCsr->pCurrent); | |
| 10263 pCsr->pCurrent = 0; | |
| 10264 } | |
| 10265 | |
| 10266 for(p=pCsr->pFreeEntry; p; p=pNext){ | |
| 10267 pNext = p->pNext; | |
| 10268 zipfileEntryFree(p); | |
| 10269 } | |
| 10270 } | |
| 10271 | |
| 10272 /* | |
| 10273 ** Destructor for an ZipfileCsr. | |
| 10274 */ | |
| 10275 static int zipfileClose(sqlite3_vtab_cursor *cur){ | |
| 10276 ZipfileCsr *pCsr = (ZipfileCsr*)cur; | |
| 10277 ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab); | |
| 10278 ZipfileCsr **pp; | |
| 10279 zipfileResetCursor(pCsr); | |
| 10280 | |
| 10281 /* Remove this cursor from the ZipfileTab.pCsrList list. */ | |
| 10282 for(pp=&pTab->pCsrList; *pp!=pCsr; pp=&((*pp)->pCsrNext)); | |
| 10283 *pp = pCsr->pCsrNext; | |
| 10284 | |
| 10285 sqlite3_free(pCsr); | |
| 10286 return SQLITE_OK; | |
| 10287 } | |
| 10288 | |
| 10289 /* | |
| 10290 ** Set the error message for the virtual table associated with cursor | |
| 10291 ** pCsr to the results of vprintf(zFmt, ...). | |
| 10292 */ | |
| 10293 static void zipfileTableErr(ZipfileTab *pTab, const char *zFmt, ...){ | |
| 10294 va_list ap; | |
| 10295 va_start(ap, zFmt); | |
| 10296 sqlite3_free(pTab->base.zErrMsg); | |
| 10297 pTab->base.zErrMsg = sqlite3_vmprintf(zFmt, ap); | |
| 10298 va_end(ap); | |
| 10299 } | |
| 10300 static void zipfileCursorErr(ZipfileCsr *pCsr, const char *zFmt, ...){ | |
| 10301 va_list ap; | |
| 10302 va_start(ap, zFmt); | |
| 10303 sqlite3_free(pCsr->base.pVtab->zErrMsg); | |
| 10304 pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); | |
| 10305 va_end(ap); | |
| 10306 } | |
| 10307 | |
| 10308 /* | |
| 10309 ** Read nRead bytes of data from offset iOff of file pFile into buffer | |
| 10310 ** aRead[]. Return SQLITE_OK if successful, or an SQLite error code | |
| 10311 ** otherwise. | |
| 10312 ** | |
| 10313 ** If an error does occur, output variable (*pzErrmsg) may be set to point | |
| 10314 ** to an English language error message. It is the responsibility of the | |
| 10315 ** caller to eventually free this buffer using | |
| 10316 ** sqlite3_free(). | |
| 10317 */ | |
| 10318 static int zipfileReadData( | |
| 10319 FILE *pFile, /* Read from this file */ | |
| 10320 u8 *aRead, /* Read into this buffer */ | |
| 10321 int nRead, /* Number of bytes to read */ | |
| 10322 i64 iOff, /* Offset to read from */ | |
| 10323 char **pzErrmsg /* OUT: Error message (from sqlite3_malloc) */ | |
| 10324 ){ | |
| 10325 size_t n; | |
| 10326 fseek(pFile, (long)iOff, SEEK_SET); | |
| 10327 n = fread(aRead, 1, nRead, pFile); | |
| 10328 if( (int)n!=nRead ){ | |
| 10329 *pzErrmsg = sqlite3_mprintf("error in fread()"); | |
| 10330 return SQLITE_ERROR; | |
| 10331 } | |
| 10332 return SQLITE_OK; | |
| 10333 } | |
| 10334 | |
| 10335 static int zipfileAppendData( | |
| 10336 ZipfileTab *pTab, | |
| 10337 const u8 *aWrite, | |
| 10338 int nWrite | |
| 10339 ){ | |
| 10340 if( nWrite>0 ){ | |
| 10341 size_t n = nWrite; | |
| 10342 fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET); | |
| 10343 n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd); | |
| 10344 if( (int)n!=nWrite ){ | |
| 10345 pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()"); | |
| 10346 return SQLITE_ERROR; | |
| 10347 } | |
| 10348 pTab->szCurrent += nWrite; | |
| 10349 } | |
| 10350 return SQLITE_OK; | |
| 10351 } | |
| 10352 | |
| 10353 /* | |
| 10354 ** Read and return a 16-bit little-endian unsigned integer from buffer aBuf. | |
| 10355 */ | |
| 10356 static u16 zipfileGetU16(const u8 *aBuf){ | |
| 10357 return (aBuf[1] << 8) + aBuf[0]; | |
| 10358 } | |
| 10359 | |
| 10360 /* | |
| 10361 ** Read and return a 32-bit little-endian unsigned integer from buffer aBuf. | |
| 10362 */ | |
| 10363 static u32 zipfileGetU32(const u8 *aBuf){ | |
| 10364 if( aBuf==0 ) return 0; | |
| 10365 return ((u32)(aBuf[3]) << 24) | |
| 10366 + ((u32)(aBuf[2]) << 16) | |
| 10367 + ((u32)(aBuf[1]) << 8) | |
| 10368 + ((u32)(aBuf[0]) << 0); | |
| 10369 } | |
| 10370 | |
| 10371 /* | |
| 10372 ** Write a 16-bit little endiate integer into buffer aBuf. | |
| 10373 */ | |
| 10374 static void zipfilePutU16(u8 *aBuf, u16 val){ | |
| 10375 aBuf[0] = val & 0xFF; | |
| 10376 aBuf[1] = (val>>8) & 0xFF; | |
| 10377 } | |
| 10378 | |
| 10379 /* | |
| 10380 ** Write a 32-bit little endiate integer into buffer aBuf. | |
| 10381 */ | |
| 10382 static void zipfilePutU32(u8 *aBuf, u32 val){ | |
| 10383 aBuf[0] = val & 0xFF; | |
| 10384 aBuf[1] = (val>>8) & 0xFF; | |
| 10385 aBuf[2] = (val>>16) & 0xFF; | |
| 10386 aBuf[3] = (val>>24) & 0xFF; | |
| 10387 } | |
| 10388 | |
| 10389 #define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) ) | |
| 10390 #define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) ) | |
| 10391 | |
| 10392 #define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; } | |
| 10393 #define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; } | |
| 10394 | |
| 10395 /* | |
| 10396 ** Magic numbers used to read CDS records. | |
| 10397 */ | |
| 10398 #define ZIPFILE_CDS_NFILE_OFF 28 | |
| 10399 #define ZIPFILE_CDS_SZCOMPRESSED_OFF 20 | |
| 10400 | |
| 10401 /* | |
| 10402 ** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR | |
| 10403 ** if the record is not well-formed, or SQLITE_OK otherwise. | |
| 10404 */ | |
| 10405 static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){ | |
| 10406 u8 *aRead = aBuf; | |
| 10407 u32 sig = zipfileRead32(aRead); | |
| 10408 int rc = SQLITE_OK; | |
| 10409 if( sig!=ZIPFILE_SIGNATURE_CDS ){ | |
| 10410 rc = SQLITE_ERROR; | |
| 10411 }else{ | |
| 10412 pCDS->iVersionMadeBy = zipfileRead16(aRead); | |
| 10413 pCDS->iVersionExtract = zipfileRead16(aRead); | |
| 10414 pCDS->flags = zipfileRead16(aRead); | |
| 10415 pCDS->iCompression = zipfileRead16(aRead); | |
| 10416 pCDS->mTime = zipfileRead16(aRead); | |
| 10417 pCDS->mDate = zipfileRead16(aRead); | |
| 10418 pCDS->crc32 = zipfileRead32(aRead); | |
| 10419 pCDS->szCompressed = zipfileRead32(aRead); | |
| 10420 pCDS->szUncompressed = zipfileRead32(aRead); | |
| 10421 assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] ); | |
| 10422 pCDS->nFile = zipfileRead16(aRead); | |
| 10423 pCDS->nExtra = zipfileRead16(aRead); | |
| 10424 pCDS->nComment = zipfileRead16(aRead); | |
| 10425 pCDS->iDiskStart = zipfileRead16(aRead); | |
| 10426 pCDS->iInternalAttr = zipfileRead16(aRead); | |
| 10427 pCDS->iExternalAttr = zipfileRead32(aRead); | |
| 10428 pCDS->iOffset = zipfileRead32(aRead); | |
| 10429 assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] ); | |
| 10430 } | |
| 10431 | |
| 10432 return rc; | |
| 10433 } | |
| 10434 | |
| 10435 /* | |
| 10436 ** Decode the LFH record in buffer aBuf into (*pLFH). Return SQLITE_ERROR | |
| 10437 ** if the record is not well-formed, or SQLITE_OK otherwise. | |
| 10438 */ | |
| 10439 static int zipfileReadLFH( | |
| 10440 u8 *aBuffer, | |
| 10441 ZipfileLFH *pLFH | |
| 10442 ){ | |
| 10443 u8 *aRead = aBuffer; | |
| 10444 int rc = SQLITE_OK; | |
| 10445 | |
| 10446 u32 sig = zipfileRead32(aRead); | |
| 10447 if( sig!=ZIPFILE_SIGNATURE_LFH ){ | |
| 10448 rc = SQLITE_ERROR; | |
| 10449 }else{ | |
| 10450 pLFH->iVersionExtract = zipfileRead16(aRead); | |
| 10451 pLFH->flags = zipfileRead16(aRead); | |
| 10452 pLFH->iCompression = zipfileRead16(aRead); | |
| 10453 pLFH->mTime = zipfileRead16(aRead); | |
| 10454 pLFH->mDate = zipfileRead16(aRead); | |
| 10455 pLFH->crc32 = zipfileRead32(aRead); | |
| 10456 pLFH->szCompressed = zipfileRead32(aRead); | |
| 10457 pLFH->szUncompressed = zipfileRead32(aRead); | |
| 10458 pLFH->nFile = zipfileRead16(aRead); | |
| 10459 pLFH->nExtra = zipfileRead16(aRead); | |
| 10460 if( pLFH->nFile>ZIPFILE_MX_NAME ) rc = SQLITE_ERROR; | |
| 10461 } | |
| 10462 return rc; | |
| 10463 } | |
| 10464 | |
| 10465 | |
| 10466 /* | |
| 10467 ** Buffer aExtra (size nExtra bytes) contains zip archive "extra" fields. | |
| 10468 ** Scan through this buffer to find an "extra-timestamp" field. If one | |
| 10469 ** exists, extract the 32-bit modification-timestamp from it and store | |
| 10470 ** the value in output parameter *pmTime. | |
| 10471 ** | |
| 10472 ** Zero is returned if no extra-timestamp record could be found (and so | |
| 10473 ** *pmTime is left unchanged), or non-zero otherwise. | |
| 10474 ** | |
| 10475 ** The general format of an extra field is: | |
| 10476 ** | |
| 10477 ** Header ID 2 bytes | |
| 10478 ** Data Size 2 bytes | |
| 10479 ** Data N bytes | |
| 10480 */ | |
| 10481 static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){ | |
| 10482 int ret = 0; | |
| 10483 u8 *p = aExtra; | |
| 10484 u8 *pEnd = &aExtra[nExtra]; | |
| 10485 | |
| 10486 while( p<pEnd ){ | |
| 10487 u16 id = zipfileRead16(p); | |
| 10488 u16 nByte = zipfileRead16(p); | |
| 10489 | |
| 10490 switch( id ){ | |
| 10491 case ZIPFILE_EXTRA_TIMESTAMP: { | |
| 10492 u8 b = p[0]; | |
| 10493 if( b & 0x01 ){ /* 0x01 -> modtime is present */ | |
| 10494 *pmTime = zipfileGetU32(&p[1]); | |
| 10495 ret = 1; | |
| 10496 } | |
| 10497 break; | |
| 10498 } | |
| 10499 } | |
| 10500 | |
| 10501 p += nByte; | |
| 10502 } | |
| 10503 return ret; | |
| 10504 } | |
| 10505 | |
| 10506 /* | |
| 10507 ** Convert the standard MS-DOS timestamp stored in the mTime and mDate | |
| 10508 ** fields of the CDS structure passed as the only argument to a 32-bit | |
| 10509 ** UNIX seconds-since-the-epoch timestamp. Return the result. | |
| 10510 ** | |
| 10511 ** "Standard" MS-DOS time format: | |
| 10512 ** | |
| 10513 ** File modification time: | |
| 10514 ** Bits 00-04: seconds divided by 2 | |
| 10515 ** Bits 05-10: minute | |
| 10516 ** Bits 11-15: hour | |
| 10517 ** File modification date: | |
| 10518 ** Bits 00-04: day | |
| 10519 ** Bits 05-08: month (1-12) | |
| 10520 ** Bits 09-15: years from 1980 | |
| 10521 ** | |
| 10522 ** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx | |
| 10523 */ | |
| 10524 static u32 zipfileMtime(ZipfileCDS *pCDS){ | |
| 10525 int Y,M,D,X1,X2,A,B,sec,min,hr; | |
| 10526 i64 JDsec; | |
| 10527 Y = (1980 + ((pCDS->mDate >> 9) & 0x7F)); | |
| 10528 M = ((pCDS->mDate >> 5) & 0x0F); | |
| 10529 D = (pCDS->mDate & 0x1F); | |
| 10530 sec = (pCDS->mTime & 0x1F)*2; | |
| 10531 min = (pCDS->mTime >> 5) & 0x3F; | |
| 10532 hr = (pCDS->mTime >> 11) & 0x1F; | |
| 10533 if( M<=2 ){ | |
| 10534 Y--; | |
| 10535 M += 12; | |
| 10536 } | |
| 10537 X1 = 36525*(Y+4716)/100; | |
| 10538 X2 = 306001*(M+1)/10000; | |
| 10539 A = Y/100; | |
| 10540 B = 2 - A + (A/4); | |
| 10541 JDsec = (i64)((X1 + X2 + D + B - 1524.5)*86400) + hr*3600 + min*60 + sec; | |
| 10542 return (u32)(JDsec - (i64)24405875*(i64)8640); | |
| 10543 } | |
| 10544 | |
| 10545 /* | |
| 10546 ** The opposite of zipfileMtime(). This function populates the mTime and | |
| 10547 ** mDate fields of the CDS structure passed as the first argument according | |
| 10548 ** to the UNIX timestamp value passed as the second. | |
| 10549 */ | |
| 10550 static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){ | |
| 10551 /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */ | |
| 10552 i64 JD = (i64)2440588 + mUnixTime / (24*60*60); | |
| 10553 | |
| 10554 int A, B, C, D, E; | |
| 10555 int yr, mon, day; | |
| 10556 int hr, min, sec; | |
| 10557 | |
| 10558 A = (int)((JD - 1867216.25)/36524.25); | |
| 10559 A = (int)(JD + 1 + A - (A/4)); | |
| 10560 B = A + 1524; | |
| 10561 C = (int)((B - 122.1)/365.25); | |
| 10562 D = (36525*(C&32767))/100; | |
| 10563 E = (int)((B-D)/30.6001); | |
| 10564 | |
| 10565 day = B - D - (int)(30.6001*E); | |
| 10566 mon = (E<14 ? E-1 : E-13); | |
| 10567 yr = mon>2 ? C-4716 : C-4715; | |
| 10568 | |
| 10569 hr = (mUnixTime % (24*60*60)) / (60*60); | |
| 10570 min = (mUnixTime % (60*60)) / 60; | |
| 10571 sec = (mUnixTime % 60); | |
| 10572 | |
| 10573 if( yr>=1980 ){ | |
| 10574 pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9)); | |
| 10575 pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11)); | |
| 10576 }else{ | |
| 10577 pCds->mDate = pCds->mTime = 0; | |
| 10578 } | |
| 10579 | |
| 10580 assert( mUnixTime<315507600 | |
| 10581 || mUnixTime==zipfileMtime(pCds) | |
| 10582 || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) | |
| 10583 /* || (mUnixTime % 2) */ | |
| 10584 ); | |
| 10585 } | |
| 10586 | |
| 10587 /* | |
| 10588 ** Set (*pzErr) to point to a buffer from sqlite3_malloc() containing a | |
| 10589 ** generic corruption message and return SQLITE_CORRUPT; | |
| 10590 */ | |
| 10591 static int zipfileCorrupt(char **pzErr){ | |
| 10592 *pzErr = sqlite3_mprintf("zip archive is corrupt"); | |
| 10593 return SQLITE_CORRUPT; | |
| 10594 } | |
| 10595 | |
| 10596 /* | |
| 10597 ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in | |
| 10598 ** size) containing an entire zip archive image. Or, if aBlob is NULL, | |
| 10599 ** then pFile is a file-handle open on a zip file. In either case, this | |
| 10600 ** function creates a ZipfileEntry object based on the zip archive entry | |
| 10601 ** for which the CDS record is at offset iOff. | |
| 10602 ** | |
| 10603 ** If successful, SQLITE_OK is returned and (*ppEntry) set to point to | |
| 10604 ** the new object. Otherwise, an SQLite error code is returned and the | |
| 10605 ** final value of (*ppEntry) undefined. | |
| 10606 */ | |
| 10607 static int zipfileGetEntry( | |
| 10608 ZipfileTab *pTab, /* Store any error message here */ | |
| 10609 const u8 *aBlob, /* Pointer to in-memory file image */ | |
| 10610 int nBlob, /* Size of aBlob[] in bytes */ | |
| 10611 FILE *pFile, /* If aBlob==0, read from this file */ | |
| 10612 i64 iOff, /* Offset of CDS record */ | |
| 10613 ZipfileEntry **ppEntry /* OUT: Pointer to new object */ | |
| 10614 ){ | |
| 10615 u8 *aRead; | |
| 10616 char **pzErr = &pTab->base.zErrMsg; | |
| 10617 int rc = SQLITE_OK; | |
| 10618 | |
| 10619 if( aBlob==0 ){ | |
| 10620 aRead = pTab->aBuffer; | |
| 10621 rc = zipfileReadData(pFile, aRead, ZIPFILE_CDS_FIXED_SZ, iOff, pzErr); | |
| 10622 }else{ | |
| 10623 if( (iOff+ZIPFILE_CDS_FIXED_SZ)>nBlob ){ | |
| 10624 /* Not enough data for the CDS structure. Corruption. */ | |
| 10625 return zipfileCorrupt(pzErr); | |
| 10626 } | |
| 10627 aRead = (u8*)&aBlob[iOff]; | |
| 10628 } | |
| 10629 | |
| 10630 if( rc==SQLITE_OK ){ | |
| 10631 sqlite3_int64 nAlloc; | |
| 10632 ZipfileEntry *pNew; | |
| 10633 | |
| 10634 int nFile = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF]); | |
| 10635 int nExtra = zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+2]); | |
| 10636 nExtra += zipfileGetU16(&aRead[ZIPFILE_CDS_NFILE_OFF+4]); | |
| 10637 | |
| 10638 nAlloc = sizeof(ZipfileEntry) + nExtra; | |
| 10639 if( aBlob ){ | |
| 10640 nAlloc += zipfileGetU32(&aRead[ZIPFILE_CDS_SZCOMPRESSED_OFF]); | |
| 10641 } | |
| 10642 | |
| 10643 pNew = (ZipfileEntry*)sqlite3_malloc64(nAlloc); | |
| 10644 if( pNew==0 ){ | |
| 10645 rc = SQLITE_NOMEM; | |
| 10646 }else{ | |
| 10647 memset(pNew, 0, sizeof(ZipfileEntry)); | |
| 10648 rc = zipfileReadCDS(aRead, &pNew->cds); | |
| 10649 if( rc!=SQLITE_OK ){ | |
| 10650 *pzErr = sqlite3_mprintf("failed to read CDS at offset %lld", iOff); | |
| 10651 }else if( aBlob==0 ){ | |
| 10652 rc = zipfileReadData( | |
| 10653 pFile, aRead, nExtra+nFile, iOff+ZIPFILE_CDS_FIXED_SZ, pzErr | |
| 10654 ); | |
| 10655 }else{ | |
| 10656 aRead = (u8*)&aBlob[iOff + ZIPFILE_CDS_FIXED_SZ]; | |
| 10657 if( (iOff + ZIPFILE_CDS_FIXED_SZ + nFile + nExtra)>nBlob ){ | |
| 10658 rc = zipfileCorrupt(pzErr); | |
| 10659 } | |
| 10660 } | |
| 10661 } | |
| 10662 | |
| 10663 if( rc==SQLITE_OK ){ | |
| 10664 u32 *pt = &pNew->mUnixTime; | |
| 10665 pNew->cds.zFile = sqlite3_mprintf("%.*s", nFile, aRead); | |
| 10666 pNew->aExtra = (u8*)&pNew[1]; | |
| 10667 memcpy(pNew->aExtra, &aRead[nFile], nExtra); | |
| 10668 if( pNew->cds.zFile==0 ){ | |
| 10669 rc = SQLITE_NOMEM; | |
| 10670 }else if( 0==zipfileScanExtra(&aRead[nFile], pNew->cds.nExtra, pt) ){ | |
| 10671 pNew->mUnixTime = zipfileMtime(&pNew->cds); | |
| 10672 } | |
| 10673 } | |
| 10674 | |
| 10675 if( rc==SQLITE_OK ){ | |
| 10676 static const int szFix = ZIPFILE_LFH_FIXED_SZ; | |
| 10677 ZipfileLFH lfh; | |
| 10678 if( pFile ){ | |
| 10679 rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr); | |
| 10680 }else{ | |
| 10681 aRead = (u8*)&aBlob[pNew->cds.iOffset]; | |
| 10682 if( (pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ)>nBlob ){ | |
| 10683 rc = zipfileCorrupt(pzErr); | |
| 10684 } | |
| 10685 } | |
| 10686 | |
| 10687 if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh); | |
| 10688 if( rc==SQLITE_OK ){ | |
| 10689 pNew->iDataOff = pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ; | |
| 10690 pNew->iDataOff += lfh.nFile + lfh.nExtra; | |
| 10691 if( aBlob && pNew->cds.szCompressed ){ | |
| 10692 if( pNew->iDataOff + pNew->cds.szCompressed > nBlob ){ | |
| 10693 rc = zipfileCorrupt(pzErr); | |
| 10694 }else{ | |
| 10695 pNew->aData = &pNew->aExtra[nExtra]; | |
| 10696 memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed); | |
| 10697 } | |
| 10698 } | |
| 10699 }else{ | |
| 10700 *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", | |
| 10701 (int)pNew->cds.iOffset | |
| 10702 ); | |
| 10703 } | |
| 10704 } | |
| 10705 | |
| 10706 if( rc!=SQLITE_OK ){ | |
| 10707 zipfileEntryFree(pNew); | |
| 10708 }else{ | |
| 10709 *ppEntry = pNew; | |
| 10710 } | |
| 10711 } | |
| 10712 | |
| 10713 return rc; | |
| 10714 } | |
| 10715 | |
| 10716 /* | |
| 10717 ** Advance an ZipfileCsr to its next row of output. | |
| 10718 */ | |
| 10719 static int zipfileNext(sqlite3_vtab_cursor *cur){ | |
| 10720 ZipfileCsr *pCsr = (ZipfileCsr*)cur; | |
| 10721 int rc = SQLITE_OK; | |
| 10722 | |
| 10723 if( pCsr->pFile ){ | |
| 10724 i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize; | |
| 10725 zipfileEntryFree(pCsr->pCurrent); | |
| 10726 pCsr->pCurrent = 0; | |
| 10727 if( pCsr->iNextOff>=iEof ){ | |
| 10728 pCsr->bEof = 1; | |
| 10729 }else{ | |
| 10730 ZipfileEntry *p = 0; | |
| 10731 ZipfileTab *pTab = (ZipfileTab*)(cur->pVtab); | |
| 10732 rc = zipfileGetEntry(pTab, 0, 0, pCsr->pFile, pCsr->iNextOff, &p); | |
| 10733 if( rc==SQLITE_OK ){ | |
| 10734 pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ; | |
| 10735 pCsr->iNextOff += (int)p->cds.nExtra + p->cds.nFile + p->cds.nComment; | |
| 10736 } | |
| 10737 pCsr->pCurrent = p; | |
| 10738 } | |
| 10739 }else{ | |
| 10740 if( !pCsr->bNoop ){ | |
| 10741 pCsr->pCurrent = pCsr->pCurrent->pNext; | |
| 10742 } | |
| 10743 if( pCsr->pCurrent==0 ){ | |
| 10744 pCsr->bEof = 1; | |
| 10745 } | |
| 10746 } | |
| 10747 | |
| 10748 pCsr->bNoop = 0; | |
| 10749 return rc; | |
| 10750 } | |
| 10751 | |
| 10752 static void zipfileFree(void *p) { | |
| 10753 sqlite3_free(p); | |
| 10754 } | |
| 10755 | |
| 10756 /* | |
| 10757 ** Buffer aIn (size nIn bytes) contains compressed data. Uncompressed, the | |
| 10758 ** size is nOut bytes. This function uncompresses the data and sets the | |
| 10759 ** return value in context pCtx to the result (a blob). | |
| 10760 ** | |
| 10761 ** If an error occurs, an error code is left in pCtx instead. | |
| 10762 */ | |
| 10763 static void zipfileInflate( | |
| 10764 sqlite3_context *pCtx, /* Store result here */ | |
| 10765 const u8 *aIn, /* Compressed data */ | |
| 10766 int nIn, /* Size of buffer aIn[] in bytes */ | |
| 10767 int nOut /* Expected output size */ | |
| 10768 ){ | |
| 10769 u8 *aRes = sqlite3_malloc(nOut); | |
| 10770 if( aRes==0 ){ | |
| 10771 sqlite3_result_error_nomem(pCtx); | |
| 10772 }else{ | |
| 10773 int err; | |
| 10774 z_stream str; | |
| 10775 memset(&str, 0, sizeof(str)); | |
| 10776 | |
| 10777 str.next_in = (Byte*)aIn; | |
| 10778 str.avail_in = nIn; | |
| 10779 str.next_out = (Byte*)aRes; | |
| 10780 str.avail_out = nOut; | |
| 10781 | |
| 10782 err = inflateInit2(&str, -15); | |
| 10783 if( err!=Z_OK ){ | |
| 10784 zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err); | |
| 10785 }else{ | |
| 10786 err = inflate(&str, Z_NO_FLUSH); | |
| 10787 if( err!=Z_STREAM_END ){ | |
| 10788 zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err); | |
| 10789 }else{ | |
| 10790 sqlite3_result_blob(pCtx, aRes, nOut, zipfileFree); | |
| 10791 aRes = 0; | |
| 10792 } | |
| 10793 } | |
| 10794 sqlite3_free(aRes); | |
| 10795 inflateEnd(&str); | |
| 10796 } | |
| 10797 } | |
| 10798 | |
| 10799 /* | |
| 10800 ** Buffer aIn (size nIn bytes) contains uncompressed data. This function | |
| 10801 ** compresses it and sets (*ppOut) to point to a buffer containing the | |
| 10802 ** compressed data. The caller is responsible for eventually calling | |
| 10803 ** sqlite3_free() to release buffer (*ppOut). Before returning, (*pnOut) | |
| 10804 ** is set to the size of buffer (*ppOut) in bytes. | |
| 10805 ** | |
| 10806 ** If no error occurs, SQLITE_OK is returned. Otherwise, an SQLite error | |
| 10807 ** code is returned and an error message left in virtual-table handle | |
| 10808 ** pTab. The values of (*ppOut) and (*pnOut) are left unchanged in this | |
| 10809 ** case. | |
| 10810 */ | |
| 10811 static int zipfileDeflate( | |
| 10812 const u8 *aIn, int nIn, /* Input */ | |
| 10813 u8 **ppOut, int *pnOut, /* Output */ | |
| 10814 char **pzErr /* OUT: Error message */ | |
| 10815 ){ | |
| 10816 int rc = SQLITE_OK; | |
| 10817 sqlite3_int64 nAlloc; | |
| 10818 z_stream str; | |
| 10819 u8 *aOut; | |
| 10820 | |
| 10821 memset(&str, 0, sizeof(str)); | |
| 10822 str.next_in = (Bytef*)aIn; | |
| 10823 str.avail_in = nIn; | |
| 10824 deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); | |
| 10825 | |
| 10826 nAlloc = deflateBound(&str, nIn); | |
| 10827 aOut = (u8*)sqlite3_malloc64(nAlloc); | |
| 10828 if( aOut==0 ){ | |
| 10829 rc = SQLITE_NOMEM; | |
| 10830 }else{ | |
| 10831 int res; | |
| 10832 str.next_out = aOut; | |
| 10833 str.avail_out = nAlloc; | |
| 10834 res = deflate(&str, Z_FINISH); | |
| 10835 if( res==Z_STREAM_END ){ | |
| 10836 *ppOut = aOut; | |
| 10837 *pnOut = (int)str.total_out; | |
| 10838 }else{ | |
| 10839 sqlite3_free(aOut); | |
| 10840 *pzErr = sqlite3_mprintf("zipfile: deflate() error"); | |
| 10841 rc = SQLITE_ERROR; | |
| 10842 } | |
| 10843 deflateEnd(&str); | |
| 10844 } | |
| 10845 | |
| 10846 return rc; | |
| 10847 } | |
| 10848 | |
| 10849 | |
| 10850 /* | |
| 10851 ** Return values of columns for the row at which the series_cursor | |
| 10852 ** is currently pointing. | |
| 10853 */ | |
| 10854 static int zipfileColumn( | |
| 10855 sqlite3_vtab_cursor *cur, /* The cursor */ | |
| 10856 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ | |
| 10857 int i /* Which column to return */ | |
| 10858 ){ | |
| 10859 ZipfileCsr *pCsr = (ZipfileCsr*)cur; | |
| 10860 ZipfileCDS *pCDS = &pCsr->pCurrent->cds; | |
| 10861 int rc = SQLITE_OK; | |
| 10862 switch( i ){ | |
| 10863 case 0: /* name */ | |
| 10864 sqlite3_result_text(ctx, pCDS->zFile, -1, SQLITE_TRANSIENT); | |
| 10865 break; | |
| 10866 case 1: /* mode */ | |
| 10867 /* TODO: Whether or not the following is correct surely depends on | |
| 10868 ** the platform on which the archive was created. */ | |
| 10869 sqlite3_result_int(ctx, pCDS->iExternalAttr >> 16); | |
| 10870 break; | |
| 10871 case 2: { /* mtime */ | |
| 10872 sqlite3_result_int64(ctx, pCsr->pCurrent->mUnixTime); | |
| 10873 break; | |
| 10874 } | |
| 10875 case 3: { /* sz */ | |
| 10876 if( sqlite3_vtab_nochange(ctx)==0 ){ | |
| 10877 sqlite3_result_int64(ctx, pCDS->szUncompressed); | |
| 10878 } | |
| 10879 break; | |
| 10880 } | |
| 10881 case 4: /* rawdata */ | |
| 10882 if( sqlite3_vtab_nochange(ctx) ) break; | |
| 10883 case 5: { /* data */ | |
| 10884 if( i==4 || pCDS->iCompression==0 || pCDS->iCompression==8 ){ | |
| 10885 int sz = pCDS->szCompressed; | |
| 10886 int szFinal = pCDS->szUncompressed; | |
| 10887 if( szFinal>0 ){ | |
| 10888 u8 *aBuf; | |
| 10889 u8 *aFree = 0; | |
| 10890 if( pCsr->pCurrent->aData ){ | |
| 10891 aBuf = pCsr->pCurrent->aData; | |
| 10892 }else{ | |
| 10893 aBuf = aFree = sqlite3_malloc64(sz); | |
| 10894 if( aBuf==0 ){ | |
| 10895 rc = SQLITE_NOMEM; | |
| 10896 }else{ | |
| 10897 FILE *pFile = pCsr->pFile; | |
| 10898 if( pFile==0 ){ | |
| 10899 pFile = ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd; | |
| 10900 } | |
| 10901 rc = zipfileReadData(pFile, aBuf, sz, pCsr->pCurrent->iDataOff, | |
| 10902 &pCsr->base.pVtab->zErrMsg | |
| 10903 ); | |
| 10904 } | |
| 10905 } | |
| 10906 if( rc==SQLITE_OK ){ | |
| 10907 if( i==5 && pCDS->iCompression ){ | |
| 10908 zipfileInflate(ctx, aBuf, sz, szFinal); | |
| 10909 }else{ | |
| 10910 sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT); | |
| 10911 } | |
| 10912 } | |
| 10913 sqlite3_free(aFree); | |
| 10914 }else{ | |
| 10915 /* Figure out if this is a directory or a zero-sized file. Consider | |
| 10916 ** it to be a directory either if the mode suggests so, or if | |
| 10917 ** the final character in the name is '/'. */ | |
| 10918 u32 mode = pCDS->iExternalAttr >> 16; | |
| 10919 if( !(mode & S_IFDIR) | |
| 10920 && pCDS->nFile>=1 | |
| 10921 && pCDS->zFile[pCDS->nFile-1]!='/' | |
| 10922 ){ | |
| 10923 sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC); | |
| 10924 } | |
| 10925 } | |
| 10926 } | |
| 10927 break; | |
| 10928 } | |
| 10929 case 6: /* method */ | |
| 10930 sqlite3_result_int(ctx, pCDS->iCompression); | |
| 10931 break; | |
| 10932 default: /* z */ | |
| 10933 assert( i==7 ); | |
| 10934 sqlite3_result_int64(ctx, pCsr->iId); | |
| 10935 break; | |
| 10936 } | |
| 10937 | |
| 10938 return rc; | |
| 10939 } | |
| 10940 | |
| 10941 /* | |
| 10942 ** Return TRUE if the cursor is at EOF. | |
| 10943 */ | |
| 10944 static int zipfileEof(sqlite3_vtab_cursor *cur){ | |
| 10945 ZipfileCsr *pCsr = (ZipfileCsr*)cur; | |
| 10946 return pCsr->bEof; | |
| 10947 } | |
| 10948 | |
| 10949 /* | |
| 10950 ** If aBlob is not NULL, then it points to a buffer nBlob bytes in size | |
| 10951 ** containing an entire zip archive image. Or, if aBlob is NULL, then pFile | |
| 10952 ** is guaranteed to be a file-handle open on a zip file. | |
| 10953 ** | |
| 10954 ** This function attempts to locate the EOCD record within the zip archive | |
| 10955 ** and populate *pEOCD with the results of decoding it. SQLITE_OK is | |
| 10956 ** returned if successful. Otherwise, an SQLite error code is returned and | |
| 10957 ** an English language error message may be left in virtual-table pTab. | |
| 10958 */ | |
| 10959 static int zipfileReadEOCD( | |
| 10960 ZipfileTab *pTab, /* Return errors here */ | |
| 10961 const u8 *aBlob, /* Pointer to in-memory file image */ | |
| 10962 int nBlob, /* Size of aBlob[] in bytes */ | |
| 10963 FILE *pFile, /* Read from this file if aBlob==0 */ | |
| 10964 ZipfileEOCD *pEOCD /* Object to populate */ | |
| 10965 ){ | |
| 10966 u8 *aRead = pTab->aBuffer; /* Temporary buffer */ | |
| 10967 int nRead; /* Bytes to read from file */ | |
| 10968 int rc = SQLITE_OK; | |
| 10969 | |
| 10970 memset(pEOCD, 0, sizeof(ZipfileEOCD)); | |
| 10971 if( aBlob==0 ){ | |
| 10972 i64 iOff; /* Offset to read from */ | |
| 10973 i64 szFile; /* Total size of file in bytes */ | |
| 10974 fseek(pFile, 0, SEEK_END); | |
| 10975 szFile = (i64)ftell(pFile); | |
| 10976 if( szFile==0 ){ | |
| 10977 return SQLITE_OK; | |
| 10978 } | |
| 10979 nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE)); | |
| 10980 iOff = szFile - nRead; | |
| 10981 rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg); | |
| 10982 }else{ | |
| 10983 nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE)); | |
| 10984 aRead = (u8*)&aBlob[nBlob-nRead]; | |
| 10985 } | |
| 10986 | |
| 10987 if( rc==SQLITE_OK ){ | |
| 10988 int i; | |
| 10989 | |
| 10990 /* Scan backwards looking for the signature bytes */ | |
| 10991 for(i=nRead-20; i>=0; i--){ | |
| 10992 if( aRead[i]==0x50 && aRead[i+1]==0x4b | |
| 10993 && aRead[i+2]==0x05 && aRead[i+3]==0x06 | |
| 10994 ){ | |
| 10995 break; | |
| 10996 } | |
| 10997 } | |
| 10998 if( i<0 ){ | |
| 10999 pTab->base.zErrMsg = sqlite3_mprintf( | |
| 11000 "cannot find end of central directory record" | |
| 11001 ); | |
| 11002 return SQLITE_ERROR; | |
| 11003 } | |
| 11004 | |
| 11005 aRead += i+4; | |
| 11006 pEOCD->iDisk = zipfileRead16(aRead); | |
| 11007 pEOCD->iFirstDisk = zipfileRead16(aRead); | |
| 11008 pEOCD->nEntry = zipfileRead16(aRead); | |
| 11009 pEOCD->nEntryTotal = zipfileRead16(aRead); | |
| 11010 pEOCD->nSize = zipfileRead32(aRead); | |
| 11011 pEOCD->iOffset = zipfileRead32(aRead); | |
| 11012 } | |
| 11013 | |
| 11014 return rc; | |
| 11015 } | |
| 11016 | |
| 11017 /* | |
| 11018 ** Add object pNew to the linked list that begins at ZipfileTab.pFirstEntry | |
| 11019 ** and ends with pLastEntry. If argument pBefore is NULL, then pNew is added | |
| 11020 ** to the end of the list. Otherwise, it is added to the list immediately | |
| 11021 ** before pBefore (which is guaranteed to be a part of said list). | |
| 11022 */ | |
| 11023 static void zipfileAddEntry( | |
| 11024 ZipfileTab *pTab, | |
| 11025 ZipfileEntry *pBefore, | |
| 11026 ZipfileEntry *pNew | |
| 11027 ){ | |
| 11028 assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) ); | |
| 11029 assert( pNew->pNext==0 ); | |
| 11030 if( pBefore==0 ){ | |
| 11031 if( pTab->pFirstEntry==0 ){ | |
| 11032 pTab->pFirstEntry = pTab->pLastEntry = pNew; | |
| 11033 }else{ | |
| 11034 assert( pTab->pLastEntry->pNext==0 ); | |
| 11035 pTab->pLastEntry->pNext = pNew; | |
| 11036 pTab->pLastEntry = pNew; | |
| 11037 } | |
| 11038 }else{ | |
| 11039 ZipfileEntry **pp; | |
| 11040 for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext)); | |
| 11041 pNew->pNext = pBefore; | |
| 11042 *pp = pNew; | |
| 11043 } | |
| 11044 } | |
| 11045 | |
| 11046 static int zipfileLoadDirectory(ZipfileTab *pTab, const u8 *aBlob, int nBlob){ | |
| 11047 ZipfileEOCD eocd; | |
| 11048 int rc; | |
| 11049 int i; | |
| 11050 i64 iOff; | |
| 11051 | |
| 11052 rc = zipfileReadEOCD(pTab, aBlob, nBlob, pTab->pWriteFd, &eocd); | |
| 11053 iOff = eocd.iOffset; | |
| 11054 for(i=0; rc==SQLITE_OK && i<eocd.nEntry; i++){ | |
| 11055 ZipfileEntry *pNew = 0; | |
| 11056 rc = zipfileGetEntry(pTab, aBlob, nBlob, pTab->pWriteFd, iOff, &pNew); | |
| 11057 | |
| 11058 if( rc==SQLITE_OK ){ | |
| 11059 zipfileAddEntry(pTab, 0, pNew); | |
| 11060 iOff += ZIPFILE_CDS_FIXED_SZ; | |
| 11061 iOff += (int)pNew->cds.nExtra + pNew->cds.nFile + pNew->cds.nComment; | |
| 11062 } | |
| 11063 } | |
| 11064 return rc; | |
| 11065 } | |
| 11066 | |
| 11067 /* | |
| 11068 ** xFilter callback. | |
| 11069 */ | |
| 11070 static int zipfileFilter( | |
| 11071 sqlite3_vtab_cursor *cur, | |
| 11072 int idxNum, const char *idxStr, | |
| 11073 int argc, sqlite3_value **argv | |
| 11074 ){ | |
| 11075 ZipfileTab *pTab = (ZipfileTab*)cur->pVtab; | |
| 11076 ZipfileCsr *pCsr = (ZipfileCsr*)cur; | |
| 11077 const char *zFile = 0; /* Zip file to scan */ | |
| 11078 int rc = SQLITE_OK; /* Return Code */ | |
| 11079 int bInMemory = 0; /* True for an in-memory zipfile */ | |
| 11080 | |
| 11081 (void)idxStr; | |
| 11082 (void)argc; | |
| 11083 | |
| 11084 zipfileResetCursor(pCsr); | |
| 11085 | |
| 11086 if( pTab->zFile ){ | |
| 11087 zFile = pTab->zFile; | |
| 11088 }else if( idxNum==0 ){ | |
| 11089 zipfileCursorErr(pCsr, "zipfile() function requires an argument"); | |
| 11090 return SQLITE_ERROR; | |
| 11091 }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ | |
| 11092 static const u8 aEmptyBlob = 0; | |
| 11093 const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]); | |
| 11094 int nBlob = sqlite3_value_bytes(argv[0]); | |
| 11095 assert( pTab->pFirstEntry==0 ); | |
| 11096 if( aBlob==0 ){ | |
| 11097 aBlob = &aEmptyBlob; | |
| 11098 nBlob = 0; | |
| 11099 } | |
| 11100 rc = zipfileLoadDirectory(pTab, aBlob, nBlob); | |
| 11101 pCsr->pFreeEntry = pTab->pFirstEntry; | |
| 11102 pTab->pFirstEntry = pTab->pLastEntry = 0; | |
| 11103 if( rc!=SQLITE_OK ) return rc; | |
| 11104 bInMemory = 1; | |
| 11105 }else{ | |
| 11106 zFile = (const char*)sqlite3_value_text(argv[0]); | |
| 11107 } | |
| 11108 | |
| 11109 if( 0==pTab->pWriteFd && 0==bInMemory ){ | |
| 11110 pCsr->pFile = zFile ? sqlite3_fopen(zFile, "rb") : 0; | |
| 11111 if( pCsr->pFile==0 ){ | |
| 11112 zipfileCursorErr(pCsr, "cannot open file: %s", zFile); | |
| 11113 rc = SQLITE_ERROR; | |
| 11114 }else{ | |
| 11115 rc = zipfileReadEOCD(pTab, 0, 0, pCsr->pFile, &pCsr->eocd); | |
| 11116 if( rc==SQLITE_OK ){ | |
| 11117 if( pCsr->eocd.nEntry==0 ){ | |
| 11118 pCsr->bEof = 1; | |
| 11119 }else{ | |
| 11120 pCsr->iNextOff = pCsr->eocd.iOffset; | |
| 11121 rc = zipfileNext(cur); | |
| 11122 } | |
| 11123 } | |
| 11124 } | |
| 11125 }else{ | |
| 11126 pCsr->bNoop = 1; | |
| 11127 pCsr->pCurrent = pCsr->pFreeEntry ? pCsr->pFreeEntry : pTab->pFirstEntry; | |
| 11128 rc = zipfileNext(cur); | |
| 11129 } | |
| 11130 | |
| 11131 return rc; | |
| 11132 } | |
| 11133 | |
| 11134 /* | |
| 11135 ** xBestIndex callback. | |
| 11136 */ | |
| 11137 static int zipfileBestIndex( | |
| 11138 sqlite3_vtab *tab, | |
| 11139 sqlite3_index_info *pIdxInfo | |
| 11140 ){ | |
| 11141 int i; | |
| 11142 int idx = -1; | |
| 11143 int unusable = 0; | |
| 11144 (void)tab; | |
| 11145 | |
| 11146 for(i=0; i<pIdxInfo->nConstraint; i++){ | |
| 11147 const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; | |
| 11148 if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue; | |
| 11149 if( pCons->usable==0 ){ | |
| 11150 unusable = 1; | |
| 11151 }else if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ | |
| 11152 idx = i; | |
| 11153 } | |
| 11154 } | |
| 11155 pIdxInfo->estimatedCost = 1000.0; | |
| 11156 if( idx>=0 ){ | |
| 11157 pIdxInfo->aConstraintUsage[idx].argvIndex = 1; | |
| 11158 pIdxInfo->aConstraintUsage[idx].omit = 1; | |
| 11159 pIdxInfo->idxNum = 1; | |
| 11160 }else if( unusable ){ | |
| 11161 return SQLITE_CONSTRAINT; | |
| 11162 } | |
| 11163 return SQLITE_OK; | |
| 11164 } | |
| 11165 | |
| 11166 static ZipfileEntry *zipfileNewEntry(const char *zPath){ | |
| 11167 ZipfileEntry *pNew; | |
| 11168 pNew = sqlite3_malloc(sizeof(ZipfileEntry)); | |
| 11169 if( pNew ){ | |
| 11170 memset(pNew, 0, sizeof(ZipfileEntry)); | |
| 11171 pNew->cds.zFile = sqlite3_mprintf("%s", zPath); | |
| 11172 if( pNew->cds.zFile==0 ){ | |
| 11173 sqlite3_free(pNew); | |
| 11174 pNew = 0; | |
| 11175 } | |
| 11176 } | |
| 11177 return pNew; | |
| 11178 } | |
| 11179 | |
| 11180 static int zipfileSerializeLFH(ZipfileEntry *pEntry, u8 *aBuf){ | |
| 11181 ZipfileCDS *pCds = &pEntry->cds; | |
| 11182 u8 *a = aBuf; | |
| 11183 | |
| 11184 pCds->nExtra = 9; | |
| 11185 | |
| 11186 /* Write the LFH itself */ | |
| 11187 zipfileWrite32(a, ZIPFILE_SIGNATURE_LFH); | |
| 11188 zipfileWrite16(a, pCds->iVersionExtract); | |
| 11189 zipfileWrite16(a, pCds->flags); | |
| 11190 zipfileWrite16(a, pCds->iCompression); | |
| 11191 zipfileWrite16(a, pCds->mTime); | |
| 11192 zipfileWrite16(a, pCds->mDate); | |
| 11193 zipfileWrite32(a, pCds->crc32); | |
| 11194 zipfileWrite32(a, pCds->szCompressed); | |
| 11195 zipfileWrite32(a, pCds->szUncompressed); | |
| 11196 zipfileWrite16(a, (u16)pCds->nFile); | |
| 11197 zipfileWrite16(a, pCds->nExtra); | |
| 11198 assert( a==&aBuf[ZIPFILE_LFH_FIXED_SZ] ); | |
| 11199 | |
| 11200 /* Add the file name */ | |
| 11201 memcpy(a, pCds->zFile, (int)pCds->nFile); | |
| 11202 a += (int)pCds->nFile; | |
| 11203 | |
| 11204 /* The "extra" data */ | |
| 11205 zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP); | |
| 11206 zipfileWrite16(a, 5); | |
| 11207 *a++ = 0x01; | |
| 11208 zipfileWrite32(a, pEntry->mUnixTime); | |
| 11209 | |
| 11210 return a-aBuf; | |
| 11211 } | |
| 11212 | |
| 11213 static int zipfileAppendEntry( | |
| 11214 ZipfileTab *pTab, | |
| 11215 ZipfileEntry *pEntry, | |
| 11216 const u8 *pData, | |
| 11217 int nData | |
| 11218 ){ | |
| 11219 u8 *aBuf = pTab->aBuffer; | |
| 11220 int nBuf; | |
| 11221 int rc; | |
| 11222 | |
| 11223 nBuf = zipfileSerializeLFH(pEntry, aBuf); | |
| 11224 rc = zipfileAppendData(pTab, aBuf, nBuf); | |
| 11225 if( rc==SQLITE_OK ){ | |
| 11226 pEntry->iDataOff = pTab->szCurrent; | |
| 11227 rc = zipfileAppendData(pTab, pData, nData); | |
| 11228 } | |
| 11229 | |
| 11230 return rc; | |
| 11231 } | |
| 11232 | |
| 11233 static int zipfileGetMode( | |
| 11234 sqlite3_value *pVal, | |
| 11235 int bIsDir, /* If true, default to directory */ | |
| 11236 u32 *pMode, /* OUT: Mode value */ | |
| 11237 char **pzErr /* OUT: Error message */ | |
| 11238 ){ | |
| 11239 const char *z = (const char*)sqlite3_value_text(pVal); | |
| 11240 u32 mode = 0; | |
| 11241 if( z==0 ){ | |
| 11242 mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644)); | |
| 11243 }else if( z[0]>='0' && z[0]<='9' ){ | |
| 11244 mode = (unsigned int)sqlite3_value_int(pVal); | |
| 11245 }else{ | |
| 11246 const char zTemplate[11] = "-rwxrwxrwx"; | |
| 11247 int i; | |
| 11248 if( strlen(z)!=10 ) goto parse_error; | |
| 11249 switch( z[0] ){ | |
| 11250 case '-': mode |= S_IFREG; break; | |
| 11251 case 'd': mode |= S_IFDIR; break; | |
| 11252 case 'l': mode |= S_IFLNK; break; | |
| 11253 default: goto parse_error; | |
| 11254 } | |
| 11255 for(i=1; i<10; i++){ | |
| 11256 if( z[i]==zTemplate[i] ) mode |= 1 << (9-i); | |
| 11257 else if( z[i]!='-' ) goto parse_error; | |
| 11258 } | |
| 11259 } | |
| 11260 if( ((mode & S_IFDIR)==0)==bIsDir ){ | |
| 11261 /* The "mode" attribute is a directory, but data has been specified. | |
| 11262 ** Or vice-versa - no data but "mode" is a file or symlink. */ | |
| 11263 *pzErr = sqlite3_mprintf("zipfile: mode does not match data"); | |
| 11264 return SQLITE_CONSTRAINT; | |
| 11265 } | |
| 11266 *pMode = mode; | |
| 11267 return SQLITE_OK; | |
| 11268 | |
| 11269 parse_error: | |
| 11270 *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z); | |
| 11271 return SQLITE_ERROR; | |
| 11272 } | |
| 11273 | |
| 11274 /* | |
| 11275 ** Both (const char*) arguments point to nul-terminated strings. Argument | |
| 11276 ** nB is the value of strlen(zB). This function returns 0 if the strings are | |
| 11277 ** identical, ignoring any trailing '/' character in either path. */ | |
| 11278 static int zipfileComparePath(const char *zA, const char *zB, int nB){ | |
| 11279 int nA = (int)strlen(zA); | |
| 11280 if( nA>0 && zA[nA-1]=='/' ) nA--; | |
| 11281 if( nB>0 && zB[nB-1]=='/' ) nB--; | |
| 11282 if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0; | |
| 11283 return 1; | |
| 11284 } | |
| 11285 | |
| 11286 static int zipfileBegin(sqlite3_vtab *pVtab){ | |
| 11287 ZipfileTab *pTab = (ZipfileTab*)pVtab; | |
| 11288 int rc = SQLITE_OK; | |
| 11289 | |
| 11290 assert( pTab->pWriteFd==0 ); | |
| 11291 if( pTab->zFile==0 || pTab->zFile[0]==0 ){ | |
| 11292 pTab->base.zErrMsg = sqlite3_mprintf("zipfile: missing filename"); | |
| 11293 return SQLITE_ERROR; | |
| 11294 } | |
| 11295 | |
| 11296 /* Open a write fd on the file. Also load the entire central directory | |
| 11297 ** structure into memory. During the transaction any new file data is | |
| 11298 ** appended to the archive file, but the central directory is accumulated | |
| 11299 ** in main-memory until the transaction is committed. */ | |
| 11300 pTab->pWriteFd = sqlite3_fopen(pTab->zFile, "ab+"); | |
| 11301 if( pTab->pWriteFd==0 ){ | |
| 11302 pTab->base.zErrMsg = sqlite3_mprintf( | |
| 11303 "zipfile: failed to open file %s for writing", pTab->zFile | |
| 11304 ); | |
| 11305 rc = SQLITE_ERROR; | |
| 11306 }else{ | |
| 11307 fseek(pTab->pWriteFd, 0, SEEK_END); | |
| 11308 pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd); | |
| 11309 rc = zipfileLoadDirectory(pTab, 0, 0); | |
| 11310 } | |
| 11311 | |
| 11312 if( rc!=SQLITE_OK ){ | |
| 11313 zipfileCleanupTransaction(pTab); | |
| 11314 } | |
| 11315 | |
| 11316 return rc; | |
| 11317 } | |
| 11318 | |
| 11319 /* | |
| 11320 ** Return the current time as a 32-bit timestamp in UNIX epoch format (like | |
| 11321 ** time(2)). | |
| 11322 */ | |
| 11323 static u32 zipfileTime(void){ | |
| 11324 sqlite3_vfs *pVfs = sqlite3_vfs_find(0); | |
| 11325 u32 ret; | |
| 11326 if( pVfs==0 ) return 0; | |
| 11327 if( pVfs->iVersion>=2 && pVfs->xCurrentTimeInt64 ){ | |
| 11328 i64 ms; | |
| 11329 pVfs->xCurrentTimeInt64(pVfs, &ms); | |
| 11330 ret = (u32)((ms/1000) - ((i64)24405875 * 8640)); | |
| 11331 }else{ | |
| 11332 double day; | |
| 11333 pVfs->xCurrentTime(pVfs, &day); | |
| 11334 ret = (u32)((day - 2440587.5) * 86400); | |
| 11335 } | |
| 11336 return ret; | |
| 11337 } | |
| 11338 | |
| 11339 /* | |
| 11340 ** Return a 32-bit timestamp in UNIX epoch format. | |
| 11341 ** | |
| 11342 ** If the value passed as the only argument is either NULL or an SQL NULL, | |
| 11343 ** return the current time. Otherwise, return the value stored in (*pVal) | |
| 11344 ** cast to a 32-bit unsigned integer. | |
| 11345 */ | |
| 11346 static u32 zipfileGetTime(sqlite3_value *pVal){ | |
| 11347 if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){ | |
| 11348 return zipfileTime(); | |
| 11349 } | |
| 11350 return (u32)sqlite3_value_int64(pVal); | |
| 11351 } | |
| 11352 | |
| 11353 /* | |
| 11354 ** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry | |
| 11355 ** linked list. Remove it from the list and free the object. | |
| 11356 */ | |
| 11357 static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){ | |
| 11358 if( pOld ){ | |
| 11359 if( pTab->pFirstEntry==pOld ){ | |
| 11360 pTab->pFirstEntry = pOld->pNext; | |
| 11361 if( pTab->pLastEntry==pOld ) pTab->pLastEntry = 0; | |
| 11362 }else{ | |
| 11363 ZipfileEntry *p; | |
| 11364 for(p=pTab->pFirstEntry; p; p=p->pNext){ | |
| 11365 if( p->pNext==pOld ){ | |
| 11366 p->pNext = pOld->pNext; | |
| 11367 if( pTab->pLastEntry==pOld ) pTab->pLastEntry = p; | |
| 11368 break; | |
| 11369 } | |
| 11370 } | |
| 11371 } | |
| 11372 zipfileEntryFree(pOld); | |
| 11373 } | |
| 11374 } | |
| 11375 | |
| 11376 /* | |
| 11377 ** xUpdate method. | |
| 11378 */ | |
| 11379 static int zipfileUpdate( | |
| 11380 sqlite3_vtab *pVtab, | |
| 11381 int nVal, | |
| 11382 sqlite3_value **apVal, | |
| 11383 sqlite_int64 *pRowid | |
| 11384 ){ | |
| 11385 ZipfileTab *pTab = (ZipfileTab*)pVtab; | |
| 11386 int rc = SQLITE_OK; /* Return Code */ | |
| 11387 ZipfileEntry *pNew = 0; /* New in-memory CDS entry */ | |
| 11388 | |
| 11389 u32 mode = 0; /* Mode for new entry */ | |
| 11390 u32 mTime = 0; /* Modification time for new entry */ | |
| 11391 i64 sz = 0; /* Uncompressed size */ | |
| 11392 const char *zPath = 0; /* Path for new entry */ | |
| 11393 int nPath = 0; /* strlen(zPath) */ | |
| 11394 const u8 *pData = 0; /* Pointer to buffer containing content */ | |
| 11395 int nData = 0; /* Size of pData buffer in bytes */ | |
| 11396 int iMethod = 0; /* Compression method for new entry */ | |
| 11397 u8 *pFree = 0; /* Free this */ | |
| 11398 char *zFree = 0; /* Also free this */ | |
| 11399 ZipfileEntry *pOld = 0; | |
| 11400 ZipfileEntry *pOld2 = 0; | |
| 11401 int bUpdate = 0; /* True for an update that modifies "name" */ | |
| 11402 int bIsDir = 0; | |
| 11403 u32 iCrc32 = 0; | |
| 11404 | |
| 11405 (void)pRowid; | |
| 11406 | |
| 11407 if( pTab->pWriteFd==0 ){ | |
| 11408 rc = zipfileBegin(pVtab); | |
| 11409 if( rc!=SQLITE_OK ) return rc; | |
| 11410 } | |
| 11411 | |
| 11412 /* If this is a DELETE or UPDATE, find the archive entry to delete. */ | |
| 11413 if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ | |
| 11414 const char *zDelete = (const char*)sqlite3_value_text(apVal[0]); | |
| 11415 int nDelete = (int)strlen(zDelete); | |
| 11416 if( nVal>1 ){ | |
| 11417 const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]); | |
| 11418 if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){ | |
| 11419 bUpdate = 1; | |
| 11420 } | |
| 11421 } | |
| 11422 for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){ | |
| 11423 if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){ | |
| 11424 break; | |
| 11425 } | |
| 11426 assert( pOld->pNext ); | |
| 11427 } | |
| 11428 } | |
| 11429 | |
| 11430 if( nVal>1 ){ | |
| 11431 /* Check that "sz" and "rawdata" are both NULL: */ | |
| 11432 if( sqlite3_value_type(apVal[5])!=SQLITE_NULL ){ | |
| 11433 zipfileTableErr(pTab, "sz must be NULL"); | |
| 11434 rc = SQLITE_CONSTRAINT; | |
| 11435 } | |
| 11436 if( sqlite3_value_type(apVal[6])!=SQLITE_NULL ){ | |
| 11437 zipfileTableErr(pTab, "rawdata must be NULL"); | |
| 11438 rc = SQLITE_CONSTRAINT; | |
| 11439 } | |
| 11440 | |
| 11441 if( rc==SQLITE_OK ){ | |
| 11442 if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){ | |
| 11443 /* data=NULL. A directory */ | |
| 11444 bIsDir = 1; | |
| 11445 }else{ | |
| 11446 /* Value specified for "data", and possibly "method". This must be | |
| 11447 ** a regular file or a symlink. */ | |
| 11448 const u8 *aIn = sqlite3_value_blob(apVal[7]); | |
| 11449 int nIn = sqlite3_value_bytes(apVal[7]); | |
| 11450 int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL; | |
| 11451 | |
| 11452 iMethod = sqlite3_value_int(apVal[8]); | |
| 11453 sz = nIn; | |
| 11454 pData = aIn; | |
| 11455 nData = nIn; | |
| 11456 if( iMethod!=0 && iMethod!=8 ){ | |
| 11457 zipfileTableErr(pTab, "unknown compression method: %d", iMethod); | |
| 11458 rc = SQLITE_CONSTRAINT; | |
| 11459 }else{ | |
| 11460 if( bAuto || iMethod ){ | |
| 11461 int nCmp; | |
| 11462 rc = zipfileDeflate(aIn, nIn, &pFree, &nCmp, &pTab->base.zErrMsg); | |
| 11463 if( rc==SQLITE_OK ){ | |
| 11464 if( iMethod || nCmp<nIn ){ | |
| 11465 iMethod = 8; | |
| 11466 pData = pFree; | |
| 11467 nData = nCmp; | |
| 11468 } | |
| 11469 } | |
| 11470 } | |
| 11471 iCrc32 = crc32(0, aIn, nIn); | |
| 11472 } | |
| 11473 } | |
| 11474 } | |
| 11475 | |
| 11476 if( rc==SQLITE_OK ){ | |
| 11477 rc = zipfileGetMode(apVal[3], bIsDir, &mode, &pTab->base.zErrMsg); | |
| 11478 } | |
| 11479 | |
| 11480 if( rc==SQLITE_OK ){ | |
| 11481 zPath = (const char*)sqlite3_value_text(apVal[2]); | |
| 11482 if( zPath==0 ) zPath = ""; | |
| 11483 nPath = (int)strlen(zPath); | |
| 11484 if( nPath>ZIPFILE_MX_NAME ){ | |
| 11485 zipfileTableErr(pTab, "filename too long; max: %d bytes", | |
| 11486 ZIPFILE_MX_NAME); | |
| 11487 rc = SQLITE_CONSTRAINT; | |
| 11488 } | |
| 11489 mTime = zipfileGetTime(apVal[4]); | |
| 11490 } | |
| 11491 | |
| 11492 if( rc==SQLITE_OK && bIsDir ){ | |
| 11493 /* For a directory, check that the last character in the path is a | |
| 11494 ** '/'. This appears to be required for compatibility with info-zip | |
| 11495 ** (the unzip command on unix). It does not create directories | |
| 11496 ** otherwise. */ | |
| 11497 if( nPath<=0 || zPath[nPath-1]!='/' ){ | |
| 11498 zFree = sqlite3_mprintf("%s/", zPath); | |
| 11499 zPath = (const char*)zFree; | |
| 11500 if( zFree==0 ){ | |
| 11501 rc = SQLITE_NOMEM; | |
| 11502 nPath = 0; | |
| 11503 }else{ | |
| 11504 nPath = (int)strlen(zPath); | |
| 11505 } | |
| 11506 } | |
| 11507 } | |
| 11508 | |
| 11509 /* Check that we're not inserting a duplicate entry -OR- updating an | |
| 11510 ** entry with a path, thereby making it into a duplicate. */ | |
| 11511 if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){ | |
| 11512 ZipfileEntry *p; | |
| 11513 for(p=pTab->pFirstEntry; p; p=p->pNext){ | |
| 11514 if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){ | |
| 11515 switch( sqlite3_vtab_on_conflict(pTab->db) ){ | |
| 11516 case SQLITE_IGNORE: { | |
| 11517 goto zipfile_update_done; | |
| 11518 } | |
| 11519 case SQLITE_REPLACE: { | |
| 11520 pOld2 = p; | |
| 11521 break; | |
| 11522 } | |
| 11523 default: { | |
| 11524 zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath); | |
| 11525 rc = SQLITE_CONSTRAINT; | |
| 11526 break; | |
| 11527 } | |
| 11528 } | |
| 11529 break; | |
| 11530 } | |
| 11531 } | |
| 11532 } | |
| 11533 | |
| 11534 if( rc==SQLITE_OK ){ | |
| 11535 /* Create the new CDS record. */ | |
| 11536 pNew = zipfileNewEntry(zPath); | |
| 11537 if( pNew==0 ){ | |
| 11538 rc = SQLITE_NOMEM; | |
| 11539 }else{ | |
| 11540 pNew->cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY; | |
| 11541 pNew->cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED; | |
| 11542 pNew->cds.flags = ZIPFILE_NEWENTRY_FLAGS; | |
| 11543 pNew->cds.iCompression = (u16)iMethod; | |
| 11544 zipfileMtimeToDos(&pNew->cds, mTime); | |
| 11545 pNew->cds.crc32 = iCrc32; | |
| 11546 pNew->cds.szCompressed = nData; | |
| 11547 pNew->cds.szUncompressed = (u32)sz; | |
| 11548 pNew->cds.iExternalAttr = (mode<<16); | |
| 11549 pNew->cds.iOffset = (u32)pTab->szCurrent; | |
| 11550 pNew->cds.nFile = (u16)nPath; | |
| 11551 pNew->mUnixTime = (u32)mTime; | |
| 11552 rc = zipfileAppendEntry(pTab, pNew, pData, nData); | |
| 11553 zipfileAddEntry(pTab, pOld, pNew); | |
| 11554 } | |
| 11555 } | |
| 11556 } | |
| 11557 | |
| 11558 if( rc==SQLITE_OK && (pOld || pOld2) ){ | |
| 11559 ZipfileCsr *pCsr; | |
| 11560 for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){ | |
| 11561 if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){ | |
| 11562 pCsr->pCurrent = pCsr->pCurrent->pNext; | |
| 11563 pCsr->bNoop = 1; | |
| 11564 } | |
| 11565 } | |
| 11566 | |
| 11567 zipfileRemoveEntryFromList(pTab, pOld); | |
| 11568 zipfileRemoveEntryFromList(pTab, pOld2); | |
| 11569 } | |
| 11570 | |
| 11571 zipfile_update_done: | |
| 11572 sqlite3_free(pFree); | |
| 11573 sqlite3_free(zFree); | |
| 11574 return rc; | |
| 11575 } | |
| 11576 | |
| 11577 static int zipfileSerializeEOCD(ZipfileEOCD *p, u8 *aBuf){ | |
| 11578 u8 *a = aBuf; | |
| 11579 zipfileWrite32(a, ZIPFILE_SIGNATURE_EOCD); | |
| 11580 zipfileWrite16(a, p->iDisk); | |
| 11581 zipfileWrite16(a, p->iFirstDisk); | |
| 11582 zipfileWrite16(a, p->nEntry); | |
| 11583 zipfileWrite16(a, p->nEntryTotal); | |
| 11584 zipfileWrite32(a, p->nSize); | |
| 11585 zipfileWrite32(a, p->iOffset); | |
| 11586 zipfileWrite16(a, 0); /* Size of trailing comment in bytes*/ | |
| 11587 | |
| 11588 return a-aBuf; | |
| 11589 } | |
| 11590 | |
| 11591 static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){ | |
| 11592 int nBuf = zipfileSerializeEOCD(p, pTab->aBuffer); | |
| 11593 assert( nBuf==ZIPFILE_EOCD_FIXED_SZ ); | |
| 11594 return zipfileAppendData(pTab, pTab->aBuffer, nBuf); | |
| 11595 } | |
| 11596 | |
| 11597 /* | |
| 11598 ** Serialize the CDS structure into buffer aBuf[]. Return the number | |
| 11599 ** of bytes written. | |
| 11600 */ | |
| 11601 static int zipfileSerializeCDS(ZipfileEntry *pEntry, u8 *aBuf){ | |
| 11602 u8 *a = aBuf; | |
| 11603 ZipfileCDS *pCDS = &pEntry->cds; | |
| 11604 | |
| 11605 if( pEntry->aExtra==0 ){ | |
| 11606 pCDS->nExtra = 9; | |
| 11607 } | |
| 11608 | |
| 11609 zipfileWrite32(a, ZIPFILE_SIGNATURE_CDS); | |
| 11610 zipfileWrite16(a, pCDS->iVersionMadeBy); | |
| 11611 zipfileWrite16(a, pCDS->iVersionExtract); | |
| 11612 zipfileWrite16(a, pCDS->flags); | |
| 11613 zipfileWrite16(a, pCDS->iCompression); | |
| 11614 zipfileWrite16(a, pCDS->mTime); | |
| 11615 zipfileWrite16(a, pCDS->mDate); | |
| 11616 zipfileWrite32(a, pCDS->crc32); | |
| 11617 zipfileWrite32(a, pCDS->szCompressed); | |
| 11618 zipfileWrite32(a, pCDS->szUncompressed); | |
| 11619 assert( a==&aBuf[ZIPFILE_CDS_NFILE_OFF] ); | |
| 11620 zipfileWrite16(a, pCDS->nFile); | |
| 11621 zipfileWrite16(a, pCDS->nExtra); | |
| 11622 zipfileWrite16(a, pCDS->nComment); | |
| 11623 zipfileWrite16(a, pCDS->iDiskStart); | |
| 11624 zipfileWrite16(a, pCDS->iInternalAttr); | |
| 11625 zipfileWrite32(a, pCDS->iExternalAttr); | |
| 11626 zipfileWrite32(a, pCDS->iOffset); | |
| 11627 | |
| 11628 memcpy(a, pCDS->zFile, pCDS->nFile); | |
| 11629 a += pCDS->nFile; | |
| 11630 | |
| 11631 if( pEntry->aExtra ){ | |
| 11632 int n = (int)pCDS->nExtra + (int)pCDS->nComment; | |
| 11633 memcpy(a, pEntry->aExtra, n); | |
| 11634 a += n; | |
| 11635 }else{ | |
| 11636 assert( pCDS->nExtra==9 ); | |
| 11637 zipfileWrite16(a, ZIPFILE_EXTRA_TIMESTAMP); | |
| 11638 zipfileWrite16(a, 5); | |
| 11639 *a++ = 0x01; | |
| 11640 zipfileWrite32(a, pEntry->mUnixTime); | |
| 11641 } | |
| 11642 | |
| 11643 return a-aBuf; | |
| 11644 } | |
| 11645 | |
| 11646 static int zipfileCommit(sqlite3_vtab *pVtab){ | |
| 11647 ZipfileTab *pTab = (ZipfileTab*)pVtab; | |
| 11648 int rc = SQLITE_OK; | |
| 11649 if( pTab->pWriteFd ){ | |
| 11650 i64 iOffset = pTab->szCurrent; | |
| 11651 ZipfileEntry *p; | |
| 11652 ZipfileEOCD eocd; | |
| 11653 int nEntry = 0; | |
| 11654 | |
| 11655 /* Write out all entries */ | |
| 11656 for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){ | |
| 11657 int n = zipfileSerializeCDS(p, pTab->aBuffer); | |
| 11658 rc = zipfileAppendData(pTab, pTab->aBuffer, n); | |
| 11659 nEntry++; | |
| 11660 } | |
| 11661 | |
| 11662 /* Write out the EOCD record */ | |
| 11663 eocd.iDisk = 0; | |
| 11664 eocd.iFirstDisk = 0; | |
| 11665 eocd.nEntry = (u16)nEntry; | |
| 11666 eocd.nEntryTotal = (u16)nEntry; | |
| 11667 eocd.nSize = (u32)(pTab->szCurrent - iOffset); | |
| 11668 eocd.iOffset = (u32)iOffset; | |
| 11669 rc = zipfileAppendEOCD(pTab, &eocd); | |
| 11670 | |
| 11671 zipfileCleanupTransaction(pTab); | |
| 11672 } | |
| 11673 return rc; | |
| 11674 } | |
| 11675 | |
| 11676 static int zipfileRollback(sqlite3_vtab *pVtab){ | |
| 11677 return zipfileCommit(pVtab); | |
| 11678 } | |
| 11679 | |
| 11680 static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){ | |
| 11681 ZipfileCsr *pCsr; | |
| 11682 for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){ | |
| 11683 if( iId==pCsr->iId ) break; | |
| 11684 } | |
| 11685 return pCsr; | |
| 11686 } | |
| 11687 | |
| 11688 static void zipfileFunctionCds( | |
| 11689 sqlite3_context *context, | |
| 11690 int argc, | |
| 11691 sqlite3_value **argv | |
| 11692 ){ | |
| 11693 ZipfileCsr *pCsr; | |
| 11694 ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context); | |
| 11695 assert( argc>0 ); | |
| 11696 | |
| 11697 pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0])); | |
| 11698 if( pCsr ){ | |
| 11699 ZipfileCDS *p = &pCsr->pCurrent->cds; | |
| 11700 char *zRes = sqlite3_mprintf("{" | |
| 11701 "\"version-made-by\" : %u, " | |
| 11702 "\"version-to-extract\" : %u, " | |
| 11703 "\"flags\" : %u, " | |
| 11704 "\"compression\" : %u, " | |
| 11705 "\"time\" : %u, " | |
| 11706 "\"date\" : %u, " | |
| 11707 "\"crc32\" : %u, " | |
| 11708 "\"compressed-size\" : %u, " | |
| 11709 "\"uncompressed-size\" : %u, " | |
| 11710 "\"file-name-length\" : %u, " | |
| 11711 "\"extra-field-length\" : %u, " | |
| 11712 "\"file-comment-length\" : %u, " | |
| 11713 "\"disk-number-start\" : %u, " | |
| 11714 "\"internal-attr\" : %u, " | |
| 11715 "\"external-attr\" : %u, " | |
| 11716 "\"offset\" : %u }", | |
| 11717 (u32)p->iVersionMadeBy, (u32)p->iVersionExtract, | |
| 11718 (u32)p->flags, (u32)p->iCompression, | |
| 11719 (u32)p->mTime, (u32)p->mDate, | |
| 11720 (u32)p->crc32, (u32)p->szCompressed, | |
| 11721 (u32)p->szUncompressed, (u32)p->nFile, | |
| 11722 (u32)p->nExtra, (u32)p->nComment, | |
| 11723 (u32)p->iDiskStart, (u32)p->iInternalAttr, | |
| 11724 (u32)p->iExternalAttr, (u32)p->iOffset | |
| 11725 ); | |
| 11726 | |
| 11727 if( zRes==0 ){ | |
| 11728 sqlite3_result_error_nomem(context); | |
| 11729 }else{ | |
| 11730 sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT); | |
| 11731 sqlite3_free(zRes); | |
| 11732 } | |
| 11733 } | |
| 11734 } | |
| 11735 | |
| 11736 /* | |
| 11737 ** xFindFunction method. | |
| 11738 */ | |
| 11739 static int zipfileFindFunction( | |
| 11740 sqlite3_vtab *pVtab, /* Virtual table handle */ | |
| 11741 int nArg, /* Number of SQL function arguments */ | |
| 11742 const char *zName, /* Name of SQL function */ | |
| 11743 void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ | |
| 11744 void **ppArg /* OUT: User data for *pxFunc */ | |
| 11745 ){ | |
| 11746 (void)nArg; | |
| 11747 if( sqlite3_stricmp("zipfile_cds", zName)==0 ){ | |
| 11748 *pxFunc = zipfileFunctionCds; | |
| 11749 *ppArg = (void*)pVtab; | |
| 11750 return 1; | |
| 11751 } | |
| 11752 return 0; | |
| 11753 } | |
| 11754 | |
| 11755 typedef struct ZipfileBuffer ZipfileBuffer; | |
| 11756 struct ZipfileBuffer { | |
| 11757 u8 *a; /* Pointer to buffer */ | |
| 11758 int n; /* Size of buffer in bytes */ | |
| 11759 int nAlloc; /* Byte allocated at a[] */ | |
| 11760 }; | |
| 11761 | |
| 11762 typedef struct ZipfileCtx ZipfileCtx; | |
| 11763 struct ZipfileCtx { | |
| 11764 int nEntry; | |
| 11765 ZipfileBuffer body; | |
| 11766 ZipfileBuffer cds; | |
| 11767 }; | |
| 11768 | |
| 11769 static int zipfileBufferGrow(ZipfileBuffer *pBuf, int nByte){ | |
| 11770 if( pBuf->n+nByte>pBuf->nAlloc ){ | |
| 11771 u8 *aNew; | |
| 11772 sqlite3_int64 nNew = pBuf->n ? pBuf->n*2 : 512; | |
| 11773 int nReq = pBuf->n + nByte; | |
| 11774 | |
| 11775 while( nNew<nReq ) nNew = nNew*2; | |
| 11776 aNew = sqlite3_realloc64(pBuf->a, nNew); | |
| 11777 if( aNew==0 ) return SQLITE_NOMEM; | |
| 11778 pBuf->a = aNew; | |
| 11779 pBuf->nAlloc = (int)nNew; | |
| 11780 } | |
| 11781 return SQLITE_OK; | |
| 11782 } | |
| 11783 | |
| 11784 /* | |
| 11785 ** xStep() callback for the zipfile() aggregate. This can be called in | |
| 11786 ** any of the following ways: | |
| 11787 ** | |
| 11788 ** SELECT zipfile(name,data) ... | |
| 11789 ** SELECT zipfile(name,mode,mtime,data) ... | |
| 11790 ** SELECT zipfile(name,mode,mtime,data,method) ... | |
| 11791 */ | |
| 11792 static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ | |
| 11793 ZipfileCtx *p; /* Aggregate function context */ | |
| 11794 ZipfileEntry e; /* New entry to add to zip archive */ | |
| 11795 | |
| 11796 sqlite3_value *pName = 0; | |
| 11797 sqlite3_value *pMode = 0; | |
| 11798 sqlite3_value *pMtime = 0; | |
| 11799 sqlite3_value *pData = 0; | |
| 11800 sqlite3_value *pMethod = 0; | |
| 11801 | |
| 11802 int bIsDir = 0; | |
| 11803 u32 mode; | |
| 11804 int rc = SQLITE_OK; | |
| 11805 char *zErr = 0; | |
| 11806 | |
| 11807 int iMethod = -1; /* Compression method to use (0 or 8) */ | |
| 11808 | |
| 11809 const u8 *aData = 0; /* Possibly compressed data for new entry */ | |
| 11810 int nData = 0; /* Size of aData[] in bytes */ | |
| 11811 int szUncompressed = 0; /* Size of data before compression */ | |
| 11812 u8 *aFree = 0; /* Free this before returning */ | |
| 11813 u32 iCrc32 = 0; /* crc32 of uncompressed data */ | |
| 11814 | |
| 11815 char *zName = 0; /* Path (name) of new entry */ | |
| 11816 int nName = 0; /* Size of zName in bytes */ | |
| 11817 char *zFree = 0; /* Free this before returning */ | |
| 11818 int nByte; | |
| 11819 | |
| 11820 memset(&e, 0, sizeof(e)); | |
| 11821 p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx)); | |
| 11822 if( p==0 ) return; | |
| 11823 | |
| 11824 /* Martial the arguments into stack variables */ | |
| 11825 if( nVal!=2 && nVal!=4 && nVal!=5 ){ | |
| 11826 zErr = sqlite3_mprintf("wrong number of arguments to function zipfile()"); | |
| 11827 rc = SQLITE_ERROR; | |
| 11828 goto zipfile_step_out; | |
| 11829 } | |
| 11830 pName = apVal[0]; | |
| 11831 if( nVal==2 ){ | |
| 11832 pData = apVal[1]; | |
| 11833 }else{ | |
| 11834 pMode = apVal[1]; | |
| 11835 pMtime = apVal[2]; | |
| 11836 pData = apVal[3]; | |
| 11837 if( nVal==5 ){ | |
| 11838 pMethod = apVal[4]; | |
| 11839 } | |
| 11840 } | |
| 11841 | |
| 11842 /* Check that the 'name' parameter looks ok. */ | |
| 11843 zName = (char*)sqlite3_value_text(pName); | |
| 11844 nName = sqlite3_value_bytes(pName); | |
| 11845 if( zName==0 ){ | |
| 11846 zErr = sqlite3_mprintf("first argument to zipfile() must be non-NULL"); | |
| 11847 rc = SQLITE_ERROR; | |
| 11848 goto zipfile_step_out; | |
| 11849 } | |
| 11850 if( nName>ZIPFILE_MX_NAME ){ | |
| 11851 zErr = sqlite3_mprintf( | |
| 11852 "filename argument to zipfile() too big; max: %d bytes", | |
| 11853 ZIPFILE_MX_NAME); | |
| 11854 rc = SQLITE_ERROR; | |
| 11855 goto zipfile_step_out; | |
| 11856 } | |
| 11857 | |
| 11858 /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use | |
| 11859 ** deflate compression) or NULL (choose automatically). */ | |
| 11860 if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){ | |
| 11861 iMethod = (int)sqlite3_value_int64(pMethod); | |
| 11862 if( iMethod!=0 && iMethod!=8 ){ | |
| 11863 zErr = sqlite3_mprintf("illegal method value: %d", iMethod); | |
| 11864 rc = SQLITE_ERROR; | |
| 11865 goto zipfile_step_out; | |
| 11866 } | |
| 11867 } | |
| 11868 | |
| 11869 /* Now inspect the data. If this is NULL, then the new entry must be a | |
| 11870 ** directory. Otherwise, figure out whether or not the data should | |
| 11871 ** be deflated or simply stored in the zip archive. */ | |
| 11872 if( sqlite3_value_type(pData)==SQLITE_NULL ){ | |
| 11873 bIsDir = 1; | |
| 11874 iMethod = 0; | |
| 11875 }else{ | |
| 11876 aData = sqlite3_value_blob(pData); | |
| 11877 szUncompressed = nData = sqlite3_value_bytes(pData); | |
| 11878 iCrc32 = crc32(0, aData, nData); | |
| 11879 if( iMethod<0 || iMethod==8 ){ | |
| 11880 int nOut = 0; | |
| 11881 rc = zipfileDeflate(aData, nData, &aFree, &nOut, &zErr); | |
| 11882 if( rc!=SQLITE_OK ){ | |
| 11883 goto zipfile_step_out; | |
| 11884 } | |
| 11885 if( iMethod==8 || nOut<nData ){ | |
| 11886 aData = aFree; | |
| 11887 nData = nOut; | |
| 11888 iMethod = 8; | |
| 11889 }else{ | |
| 11890 iMethod = 0; | |
| 11891 } | |
| 11892 } | |
| 11893 } | |
| 11894 | |
| 11895 /* Decode the "mode" argument. */ | |
| 11896 rc = zipfileGetMode(pMode, bIsDir, &mode, &zErr); | |
| 11897 if( rc ) goto zipfile_step_out; | |
| 11898 | |
| 11899 /* Decode the "mtime" argument. */ | |
| 11900 e.mUnixTime = zipfileGetTime(pMtime); | |
| 11901 | |
| 11902 /* If this is a directory entry, ensure that there is exactly one '/' | |
| 11903 ** at the end of the path. Or, if this is not a directory and the path | |
| 11904 ** ends in '/' it is an error. */ | |
| 11905 if( bIsDir==0 ){ | |
| 11906 if( nName>0 && zName[nName-1]=='/' ){ | |
| 11907 zErr = sqlite3_mprintf("non-directory name must not end with /"); | |
| 11908 rc = SQLITE_ERROR; | |
| 11909 goto zipfile_step_out; | |
| 11910 } | |
| 11911 }else{ | |
| 11912 if( nName==0 || zName[nName-1]!='/' ){ | |
| 11913 zName = zFree = sqlite3_mprintf("%s/", zName); | |
| 11914 if( zName==0 ){ | |
| 11915 rc = SQLITE_NOMEM; | |
| 11916 goto zipfile_step_out; | |
| 11917 } | |
| 11918 nName = (int)strlen(zName); | |
| 11919 }else{ | |
| 11920 while( nName>1 && zName[nName-2]=='/' ) nName--; | |
| 11921 } | |
| 11922 } | |
| 11923 | |
| 11924 /* Assemble the ZipfileEntry object for the new zip archive entry */ | |
| 11925 e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY; | |
| 11926 e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED; | |
| 11927 e.cds.flags = ZIPFILE_NEWENTRY_FLAGS; | |
| 11928 e.cds.iCompression = (u16)iMethod; | |
| 11929 zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime); | |
| 11930 e.cds.crc32 = iCrc32; | |
| 11931 e.cds.szCompressed = nData; | |
| 11932 e.cds.szUncompressed = szUncompressed; | |
| 11933 e.cds.iExternalAttr = (mode<<16); | |
| 11934 e.cds.iOffset = p->body.n; | |
| 11935 e.cds.nFile = (u16)nName; | |
| 11936 e.cds.zFile = zName; | |
| 11937 | |
| 11938 /* Append the LFH to the body of the new archive */ | |
| 11939 nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9; | |
| 11940 if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out; | |
| 11941 p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]); | |
| 11942 | |
| 11943 /* Append the data to the body of the new archive */ | |
| 11944 if( nData>0 ){ | |
| 11945 if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out; | |
| 11946 memcpy(&p->body.a[p->body.n], aData, nData); | |
| 11947 p->body.n += nData; | |
| 11948 } | |
| 11949 | |
| 11950 /* Append the CDS record to the directory of the new archive */ | |
| 11951 nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9; | |
| 11952 if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out; | |
| 11953 p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]); | |
| 11954 | |
| 11955 /* Increment the count of entries in the archive */ | |
| 11956 p->nEntry++; | |
| 11957 | |
| 11958 zipfile_step_out: | |
| 11959 sqlite3_free(aFree); | |
| 11960 sqlite3_free(zFree); | |
| 11961 if( rc ){ | |
| 11962 if( zErr ){ | |
| 11963 sqlite3_result_error(pCtx, zErr, -1); | |
| 11964 }else{ | |
| 11965 sqlite3_result_error_code(pCtx, rc); | |
| 11966 } | |
| 11967 } | |
| 11968 sqlite3_free(zErr); | |
| 11969 } | |
| 11970 | |
| 11971 /* | |
| 11972 ** xFinalize() callback for zipfile aggregate function. | |
| 11973 */ | |
| 11974 static void zipfileFinal(sqlite3_context *pCtx){ | |
| 11975 ZipfileCtx *p; | |
| 11976 ZipfileEOCD eocd; | |
| 11977 sqlite3_int64 nZip; | |
| 11978 u8 *aZip; | |
| 11979 | |
| 11980 p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx)); | |
| 11981 if( p==0 ) return; | |
| 11982 if( p->nEntry>0 ){ | |
| 11983 memset(&eocd, 0, sizeof(eocd)); | |
| 11984 eocd.nEntry = (u16)p->nEntry; | |
| 11985 eocd.nEntryTotal = (u16)p->nEntry; | |
| 11986 eocd.nSize = p->cds.n; | |
| 11987 eocd.iOffset = p->body.n; | |
| 11988 | |
| 11989 nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ; | |
| 11990 aZip = (u8*)sqlite3_malloc64(nZip); | |
| 11991 if( aZip==0 ){ | |
| 11992 sqlite3_result_error_nomem(pCtx); | |
| 11993 }else{ | |
| 11994 memcpy(aZip, p->body.a, p->body.n); | |
| 11995 memcpy(&aZip[p->body.n], p->cds.a, p->cds.n); | |
| 11996 zipfileSerializeEOCD(&eocd, &aZip[p->body.n + p->cds.n]); | |
| 11997 sqlite3_result_blob(pCtx, aZip, (int)nZip, zipfileFree); | |
| 11998 } | |
| 11999 } | |
| 12000 | |
| 12001 sqlite3_free(p->body.a); | |
| 12002 sqlite3_free(p->cds.a); | |
| 12003 } | |
| 12004 | |
| 12005 | |
| 12006 /* | |
| 12007 ** Register the "zipfile" virtual table. | |
| 12008 */ | |
| 12009 static int zipfileRegister(sqlite3 *db){ | |
| 12010 static sqlite3_module zipfileModule = { | |
| 12011 1, /* iVersion */ | |
| 12012 zipfileConnect, /* xCreate */ | |
| 12013 zipfileConnect, /* xConnect */ | |
| 12014 zipfileBestIndex, /* xBestIndex */ | |
| 12015 zipfileDisconnect, /* xDisconnect */ | |
| 12016 zipfileDisconnect, /* xDestroy */ | |
| 12017 zipfileOpen, /* xOpen - open a cursor */ | |
| 12018 zipfileClose, /* xClose - close a cursor */ | |
| 12019 zipfileFilter, /* xFilter - configure scan constraints */ | |
| 12020 zipfileNext, /* xNext - advance a cursor */ | |
| 12021 zipfileEof, /* xEof - check for end of scan */ | |
| 12022 zipfileColumn, /* xColumn - read data */ | |
| 12023 0, /* xRowid - read data */ | |
| 12024 zipfileUpdate, /* xUpdate */ | |
| 12025 zipfileBegin, /* xBegin */ | |
| 12026 0, /* xSync */ | |
| 12027 zipfileCommit, /* xCommit */ | |
| 12028 zipfileRollback, /* xRollback */ | |
| 12029 zipfileFindFunction, /* xFindMethod */ | |
| 12030 0, /* xRename */ | |
| 12031 0, /* xSavepoint */ | |
| 12032 0, /* xRelease */ | |
| 12033 0, /* xRollback */ | |
| 12034 0, /* xShadowName */ | |
| 12035 0 /* xIntegrity */ | |
| 12036 }; | |
| 12037 | |
| 12038 int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0); | |
| 12039 if( rc==SQLITE_OK ) rc = sqlite3_overload_function(db, "zipfile_cds", -1); | |
| 12040 if( rc==SQLITE_OK ){ | |
| 12041 rc = sqlite3_create_function(db, "zipfile", -1, SQLITE_UTF8, 0, 0, | |
| 12042 zipfileStep, zipfileFinal | |
| 12043 ); | |
| 12044 } | |
| 12045 assert( sizeof(i64)==8 ); | |
| 12046 assert( sizeof(u32)==4 ); | |
| 12047 assert( sizeof(u16)==2 ); | |
| 12048 assert( sizeof(u8)==1 ); | |
| 12049 return rc; | |
| 12050 } | |
| 12051 #else /* SQLITE_OMIT_VIRTUALTABLE */ | |
| 12052 # define zipfileRegister(x) SQLITE_OK | |
| 12053 #endif | |
| 12054 | |
| 12055 #ifdef _WIN32 | |
| 12056 | |
| 12057 #endif | |
| 12058 int sqlite3_zipfile_init( | |
| 12059 sqlite3 *db, | |
| 12060 char **pzErrMsg, | |
| 12061 const sqlite3_api_routines *pApi | |
| 12062 ){ | |
| 12063 SQLITE_EXTENSION_INIT2(pApi); | |
| 12064 (void)pzErrMsg; /* Unused parameter */ | |
| 12065 return zipfileRegister(db); | |
| 12066 } | |
| 12067 | |
| 12068 /************************* End ../ext/misc/zipfile.c ********************/ | |
| 12069 /************************* Begin ../ext/misc/sqlar.c ******************/ | |
| 12070 /* | |
| 12071 ** 2017-12-17 | |
| 12072 ** | |
| 12073 ** The author disclaims copyright to this source code. In place of | |
| 12074 ** a legal notice, here is a blessing: | |
| 12075 ** | |
| 12076 ** May you do good and not evil. | |
| 12077 ** May you find forgiveness for yourself and forgive others. | |
| 12078 ** May you share freely, never taking more than you give. | |
| 12079 ** | |
| 12080 ****************************************************************************** | |
| 12081 ** | |
| 12082 ** Utility functions sqlar_compress() and sqlar_uncompress(). Useful | |
| 12083 ** for working with sqlar archives and used by the shell tool's built-in | |
| 12084 ** sqlar support. | |
| 12085 */ | |
| 12086 /* #include "sqlite3ext.h" */ | |
| 12087 SQLITE_EXTENSION_INIT1 | |
| 12088 #include <zlib.h> | |
| 12089 #include <assert.h> | |
| 12090 | |
| 12091 /* | |
| 12092 ** Implementation of the "sqlar_compress(X)" SQL function. | |
| 12093 ** | |
| 12094 ** If the type of X is SQLITE_BLOB, and compressing that blob using | |
| 12095 ** zlib utility function compress() yields a smaller blob, return the | |
| 12096 ** compressed blob. Otherwise, return a copy of X. | |
| 12097 ** | |
| 12098 ** SQLar uses the "zlib format" for compressed content. The zlib format | |
| 12099 ** contains a two-byte identification header and a four-byte checksum at | |
| 12100 ** the end. This is different from ZIP which uses the raw deflate format. | |
| 12101 ** | |
| 12102 ** Future enhancements to SQLar might add support for new compression formats. | |
| 12103 ** If so, those new formats will be identified by alternative headers in the | |
| 12104 ** compressed data. | |
| 12105 */ | |
| 12106 static void sqlarCompressFunc( | |
| 12107 sqlite3_context *context, | |
| 12108 int argc, | |
| 12109 sqlite3_value **argv | |
| 12110 ){ | |
| 12111 assert( argc==1 ); | |
| 12112 if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ | |
| 12113 const Bytef *pData = sqlite3_value_blob(argv[0]); | |
| 12114 uLong nData = sqlite3_value_bytes(argv[0]); | |
| 12115 uLongf nOut = compressBound(nData); | |
| 12116 Bytef *pOut; | |
| 12117 | |
| 12118 pOut = (Bytef*)sqlite3_malloc(nOut); | |
| 12119 if( pOut==0 ){ | |
| 12120 sqlite3_result_error_nomem(context); | |
| 12121 return; | |
| 12122 }else{ | |
| 12123 if( Z_OK!=compress(pOut, &nOut, pData, nData) ){ | |
| 12124 sqlite3_result_error(context, "error in compress()", -1); | |
| 12125 }else if( nOut<nData ){ | |
| 12126 sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT); | |
| 12127 }else{ | |
| 12128 sqlite3_result_value(context, argv[0]); | |
| 12129 } | |
| 12130 sqlite3_free(pOut); | |
| 12131 } | |
| 12132 }else{ | |
| 12133 sqlite3_result_value(context, argv[0]); | |
| 12134 } | |
| 12135 } | |
| 12136 | |
| 12137 /* | |
| 12138 ** Implementation of the "sqlar_uncompress(X,SZ)" SQL function | |
| 12139 ** | |
| 12140 ** Parameter SZ is interpreted as an integer. If it is less than or | |
| 12141 ** equal to zero, then this function returns a copy of X. Or, if | |
| 12142 ** SZ is equal to the size of X when interpreted as a blob, also | |
| 12143 ** return a copy of X. Otherwise, decompress blob X using zlib | |
| 12144 ** utility function uncompress() and return the results (another | |
| 12145 ** blob). | |
| 12146 */ | |
| 12147 static void sqlarUncompressFunc( | |
| 12148 sqlite3_context *context, | |
| 12149 int argc, | |
| 12150 sqlite3_value **argv | |
| 12151 ){ | |
| 12152 uLong nData; | |
| 12153 sqlite3_int64 sz; | |
| 12154 | |
| 12155 assert( argc==2 ); | |
| 12156 sz = sqlite3_value_int(argv[1]); | |
| 12157 | |
| 12158 if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){ | |
| 12159 sqlite3_result_value(context, argv[0]); | |
| 12160 }else{ | |
| 12161 uLongf szf = sz; | |
| 12162 const Bytef *pData= sqlite3_value_blob(argv[0]); | |
| 12163 Bytef *pOut = sqlite3_malloc(sz); | |
| 12164 if( pOut==0 ){ | |
| 12165 sqlite3_result_error_nomem(context); | |
| 12166 }else if( Z_OK!=uncompress(pOut, &szf, pData, nData) ){ | |
| 12167 sqlite3_result_error(context, "error in uncompress()", -1); | |
| 12168 }else{ | |
| 12169 sqlite3_result_blob(context, pOut, szf, SQLITE_TRANSIENT); | |
| 12170 } | |
| 12171 sqlite3_free(pOut); | |
| 12172 } | |
| 12173 } | |
| 12174 | |
| 12175 #ifdef _WIN32 | |
| 12176 | |
| 12177 #endif | |
| 12178 int sqlite3_sqlar_init( | |
| 12179 sqlite3 *db, | |
| 12180 char **pzErrMsg, | |
| 12181 const sqlite3_api_routines *pApi | |
| 12182 ){ | |
| 12183 int rc = SQLITE_OK; | |
| 12184 SQLITE_EXTENSION_INIT2(pApi); | |
| 12185 (void)pzErrMsg; /* Unused parameter */ | |
| 12186 rc = sqlite3_create_function(db, "sqlar_compress", 1, | |
| 12187 SQLITE_UTF8|SQLITE_INNOCUOUS, 0, | |
| 12188 sqlarCompressFunc, 0, 0); | |
| 12189 if( rc==SQLITE_OK ){ | |
| 12190 rc = sqlite3_create_function(db, "sqlar_uncompress", 2, | |
| 12191 SQLITE_UTF8|SQLITE_INNOCUOUS, 0, | |
| 12192 sqlarUncompressFunc, 0, 0); | |
| 12193 } | |
| 12194 return rc; | |
| 12195 } | |
| 12196 | |
| 12197 /************************* End ../ext/misc/sqlar.c ********************/ | |
| 12198 #endif | |
| 12199 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 12200 /************************* Begin ../ext/expert/sqlite3expert.h ******************/ | |
| 12201 /* | |
| 12202 ** 2017 April 07 | |
| 12203 ** | |
| 12204 ** The author disclaims copyright to this source code. In place of | |
| 12205 ** a legal notice, here is a blessing: | |
| 12206 ** | |
| 12207 ** May you do good and not evil. | |
| 12208 ** May you find forgiveness for yourself and forgive others. | |
| 12209 ** May you share freely, never taking more than you give. | |
| 12210 ** | |
| 12211 ************************************************************************* | |
| 12212 */ | |
| 12213 #if !defined(SQLITEEXPERT_H) | |
| 12214 #define SQLITEEXPERT_H 1 | |
| 12215 /* #include "sqlite3.h" */ | |
| 12216 | |
| 12217 typedef struct sqlite3expert sqlite3expert; | |
| 12218 | |
| 12219 /* | |
| 12220 ** Create a new sqlite3expert object. | |
| 12221 ** | |
| 12222 ** If successful, a pointer to the new object is returned and (*pzErr) set | |
| 12223 ** to NULL. Or, if an error occurs, NULL is returned and (*pzErr) set to | |
| 12224 ** an English-language error message. In this case it is the responsibility | |
| 12225 ** of the caller to eventually free the error message buffer using | |
| 12226 ** sqlite3_free(). | |
| 12227 */ | |
| 12228 sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErr); | |
| 12229 | |
| 12230 /* | |
| 12231 ** Configure an sqlite3expert object. | |
| 12232 ** | |
| 12233 ** EXPERT_CONFIG_SAMPLE: | |
| 12234 ** By default, sqlite3_expert_analyze() generates sqlite_stat1 data for | |
| 12235 ** each candidate index. This involves scanning and sorting the entire | |
| 12236 ** contents of each user database table once for each candidate index | |
| 12237 ** associated with the table. For large databases, this can be | |
| 12238 ** prohibitively slow. This option allows the sqlite3expert object to | |
| 12239 ** be configured so that sqlite_stat1 data is instead generated based on a | |
| 12240 ** subset of each table, or so that no sqlite_stat1 data is used at all. | |
| 12241 ** | |
| 12242 ** A single integer argument is passed to this option. If the value is less | |
| 12243 ** than or equal to zero, then no sqlite_stat1 data is generated or used by | |
| 12244 ** the analysis - indexes are recommended based on the database schema only. | |
| 12245 ** Or, if the value is 100 or greater, complete sqlite_stat1 data is | |
| 12246 ** generated for each candidate index (this is the default). Finally, if the | |
| 12247 ** value falls between 0 and 100, then it represents the percentage of user | |
| 12248 ** table rows that should be considered when generating sqlite_stat1 data. | |
| 12249 ** | |
| 12250 ** Examples: | |
| 12251 ** | |
| 12252 ** // Do not generate any sqlite_stat1 data | |
| 12253 ** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 0); | |
| 12254 ** | |
| 12255 ** // Generate sqlite_stat1 data based on 10% of the rows in each table. | |
| 12256 ** sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 10); | |
| 12257 */ | |
| 12258 int sqlite3_expert_config(sqlite3expert *p, int op, ...); | |
| 12259 | |
| 12260 #define EXPERT_CONFIG_SAMPLE 1 /* int */ | |
| 12261 | |
| 12262 /* | |
| 12263 ** Specify zero or more SQL statements to be included in the analysis. | |
| 12264 ** | |
| 12265 ** Buffer zSql must contain zero or more complete SQL statements. This | |
| 12266 ** function parses all statements contained in the buffer and adds them | |
| 12267 ** to the internal list of statements to analyze. If successful, SQLITE_OK | |
| 12268 ** is returned and (*pzErr) set to NULL. Or, if an error occurs - for example | |
| 12269 ** due to a error in the SQL - an SQLite error code is returned and (*pzErr) | |
| 12270 ** may be set to point to an English language error message. In this case | |
| 12271 ** the caller is responsible for eventually freeing the error message buffer | |
| 12272 ** using sqlite3_free(). | |
| 12273 ** | |
| 12274 ** If an error does occur while processing one of the statements in the | |
| 12275 ** buffer passed as the second argument, none of the statements in the | |
| 12276 ** buffer are added to the analysis. | |
| 12277 ** | |
| 12278 ** This function must be called before sqlite3_expert_analyze(). If a call | |
| 12279 ** to this function is made on an sqlite3expert object that has already | |
| 12280 ** been passed to sqlite3_expert_analyze() SQLITE_MISUSE is returned | |
| 12281 ** immediately and no statements are added to the analysis. | |
| 12282 */ | |
| 12283 int sqlite3_expert_sql( | |
| 12284 sqlite3expert *p, /* From a successful sqlite3_expert_new() */ | |
| 12285 const char *zSql, /* SQL statement(s) to add */ | |
| 12286 char **pzErr /* OUT: Error message (if any) */ | |
| 12287 ); | |
| 12288 | |
| 12289 | |
| 12290 /* | |
| 12291 ** This function is called after the sqlite3expert object has been configured | |
| 12292 ** with all SQL statements using sqlite3_expert_sql() to actually perform | |
| 12293 ** the analysis. Once this function has been called, it is not possible to | |
| 12294 ** add further SQL statements to the analysis. | |
| 12295 ** | |
| 12296 ** If successful, SQLITE_OK is returned and (*pzErr) is set to NULL. Or, if | |
| 12297 ** an error occurs, an SQLite error code is returned and (*pzErr) set to | |
| 12298 ** point to a buffer containing an English language error message. In this | |
| 12299 ** case it is the responsibility of the caller to eventually free the buffer | |
| 12300 ** using sqlite3_free(). | |
| 12301 ** | |
| 12302 ** If an error does occur within this function, the sqlite3expert object | |
| 12303 ** is no longer useful for any purpose. At that point it is no longer | |
| 12304 ** possible to add further SQL statements to the object or to re-attempt | |
| 12305 ** the analysis. The sqlite3expert object must still be freed using a call | |
| 12306 ** sqlite3_expert_destroy(). | |
| 12307 */ | |
| 12308 int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr); | |
| 12309 | |
| 12310 /* | |
| 12311 ** Return the total number of statements loaded using sqlite3_expert_sql(). | |
| 12312 ** The total number of SQL statements may be different from the total number | |
| 12313 ** to calls to sqlite3_expert_sql(). | |
| 12314 */ | |
| 12315 int sqlite3_expert_count(sqlite3expert*); | |
| 12316 | |
| 12317 /* | |
| 12318 ** Return a component of the report. | |
| 12319 ** | |
| 12320 ** This function is called after sqlite3_expert_analyze() to extract the | |
| 12321 ** results of the analysis. Each call to this function returns either a | |
| 12322 ** NULL pointer or a pointer to a buffer containing a nul-terminated string. | |
| 12323 ** The value passed as the third argument must be one of the EXPERT_REPORT_* | |
| 12324 ** #define constants defined below. | |
| 12325 ** | |
| 12326 ** For some EXPERT_REPORT_* parameters, the buffer returned contains | |
| 12327 ** information relating to a specific SQL statement. In these cases that | |
| 12328 ** SQL statement is identified by the value passed as the second argument. | |
| 12329 ** SQL statements are numbered from 0 in the order in which they are parsed. | |
| 12330 ** If an out-of-range value (less than zero or equal to or greater than the | |
| 12331 ** value returned by sqlite3_expert_count()) is passed as the second argument | |
| 12332 ** along with such an EXPERT_REPORT_* parameter, NULL is always returned. | |
| 12333 ** | |
| 12334 ** EXPERT_REPORT_SQL: | |
| 12335 ** Return the text of SQL statement iStmt. | |
| 12336 ** | |
| 12337 ** EXPERT_REPORT_INDEXES: | |
| 12338 ** Return a buffer containing the CREATE INDEX statements for all recommended | |
| 12339 ** indexes for statement iStmt. If there are no new recommeded indexes, NULL | |
| 12340 ** is returned. | |
| 12341 ** | |
| 12342 ** EXPERT_REPORT_PLAN: | |
| 12343 ** Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query | |
| 12344 ** iStmt after the proposed indexes have been added to the database schema. | |
| 12345 ** | |
| 12346 ** EXPERT_REPORT_CANDIDATES: | |
| 12347 ** Return a pointer to a buffer containing the CREATE INDEX statements | |
| 12348 ** for all indexes that were tested (for all SQL statements). The iStmt | |
| 12349 ** parameter is ignored for EXPERT_REPORT_CANDIDATES calls. | |
| 12350 */ | |
| 12351 const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport); | |
| 12352 | |
| 12353 /* | |
| 12354 ** Values for the third argument passed to sqlite3_expert_report(). | |
| 12355 */ | |
| 12356 #define EXPERT_REPORT_SQL 1 | |
| 12357 #define EXPERT_REPORT_INDEXES 2 | |
| 12358 #define EXPERT_REPORT_PLAN 3 | |
| 12359 #define EXPERT_REPORT_CANDIDATES 4 | |
| 12360 | |
| 12361 /* | |
| 12362 ** Free an (sqlite3expert*) handle and all associated resources. There | |
| 12363 ** should be one call to this function for each successful call to | |
| 12364 ** sqlite3-expert_new(). | |
| 12365 */ | |
| 12366 void sqlite3_expert_destroy(sqlite3expert*); | |
| 12367 | |
| 12368 #endif /* !defined(SQLITEEXPERT_H) */ | |
| 12369 | |
| 12370 /************************* End ../ext/expert/sqlite3expert.h ********************/ | |
| 12371 /************************* Begin ../ext/expert/sqlite3expert.c ******************/ | |
| 12372 /* | |
| 12373 ** 2017 April 09 | |
| 12374 ** | |
| 12375 ** The author disclaims copyright to this source code. In place of | |
| 12376 ** a legal notice, here is a blessing: | |
| 12377 ** | |
| 12378 ** May you do good and not evil. | |
| 12379 ** May you find forgiveness for yourself and forgive others. | |
| 12380 ** May you share freely, never taking more than you give. | |
| 12381 ** | |
| 12382 ************************************************************************* | |
| 12383 */ | |
| 12384 /* #include "sqlite3expert.h" */ | |
| 12385 #include <assert.h> | |
| 12386 #include <string.h> | |
| 12387 #include <stdio.h> | |
| 12388 | |
| 12389 #if !defined(SQLITE_AMALGAMATION) | |
| 12390 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) | |
| 12391 # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 | |
| 12392 #endif | |
| 12393 #if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) | |
| 12394 # define ALWAYS(X) (1) | |
| 12395 # define NEVER(X) (0) | |
| 12396 #elif !defined(NDEBUG) | |
| 12397 # define ALWAYS(X) ((X)?1:(assert(0),0)) | |
| 12398 # define NEVER(X) ((X)?(assert(0),1):0) | |
| 12399 #else | |
| 12400 # define ALWAYS(X) (X) | |
| 12401 # define NEVER(X) (X) | |
| 12402 #endif | |
| 12403 #endif /* !defined(SQLITE_AMALGAMATION) */ | |
| 12404 | |
| 12405 | |
| 12406 #ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 12407 | |
| 12408 /* typedef sqlite3_int64 i64; */ | |
| 12409 /* typedef sqlite3_uint64 u64; */ | |
| 12410 | |
| 12411 typedef struct IdxColumn IdxColumn; | |
| 12412 typedef struct IdxConstraint IdxConstraint; | |
| 12413 typedef struct IdxScan IdxScan; | |
| 12414 typedef struct IdxStatement IdxStatement; | |
| 12415 typedef struct IdxTable IdxTable; | |
| 12416 typedef struct IdxWrite IdxWrite; | |
| 12417 | |
| 12418 #define STRLEN (int)strlen | |
| 12419 | |
| 12420 /* | |
| 12421 ** A temp table name that we assume no user database will actually use. | |
| 12422 ** If this assumption proves incorrect triggers on the table with the | |
| 12423 ** conflicting name will be ignored. | |
| 12424 */ | |
| 12425 #define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776" | |
| 12426 | |
| 12427 /* | |
| 12428 ** A single constraint. Equivalent to either "col = ?" or "col < ?" (or | |
| 12429 ** any other type of single-ended range constraint on a column). | |
| 12430 ** | |
| 12431 ** pLink: | |
| 12432 ** Used to temporarily link IdxConstraint objects into lists while | |
| 12433 ** creating candidate indexes. | |
| 12434 */ | |
| 12435 struct IdxConstraint { | |
| 12436 char *zColl; /* Collation sequence */ | |
| 12437 int bRange; /* True for range, false for eq */ | |
| 12438 int iCol; /* Constrained table column */ | |
| 12439 int bFlag; /* Used by idxFindCompatible() */ | |
| 12440 int bDesc; /* True if ORDER BY <expr> DESC */ | |
| 12441 IdxConstraint *pNext; /* Next constraint in pEq or pRange list */ | |
| 12442 IdxConstraint *pLink; /* See above */ | |
| 12443 }; | |
| 12444 | |
| 12445 /* | |
| 12446 ** A single scan of a single table. | |
| 12447 */ | |
| 12448 struct IdxScan { | |
| 12449 IdxTable *pTab; /* Associated table object */ | |
| 12450 int iDb; /* Database containing table zTable */ | |
| 12451 i64 covering; /* Mask of columns required for cov. index */ | |
| 12452 IdxConstraint *pOrder; /* ORDER BY columns */ | |
| 12453 IdxConstraint *pEq; /* List of == constraints */ | |
| 12454 IdxConstraint *pRange; /* List of < constraints */ | |
| 12455 IdxScan *pNextScan; /* Next IdxScan object for same analysis */ | |
| 12456 }; | |
| 12457 | |
| 12458 /* | |
| 12459 ** Information regarding a single database table. Extracted from | |
| 12460 ** "PRAGMA table_info" by function idxGetTableInfo(). | |
| 12461 */ | |
| 12462 struct IdxColumn { | |
| 12463 char *zName; | |
| 12464 char *zColl; | |
| 12465 int iPk; | |
| 12466 }; | |
| 12467 struct IdxTable { | |
| 12468 int nCol; | |
| 12469 char *zName; /* Table name */ | |
| 12470 IdxColumn *aCol; | |
| 12471 IdxTable *pNext; /* Next table in linked list of all tables */ | |
| 12472 }; | |
| 12473 | |
| 12474 /* | |
| 12475 ** An object of the following type is created for each unique table/write-op | |
| 12476 ** seen. The objects are stored in a singly-linked list beginning at | |
| 12477 ** sqlite3expert.pWrite. | |
| 12478 */ | |
| 12479 struct IdxWrite { | |
| 12480 IdxTable *pTab; | |
| 12481 int eOp; /* SQLITE_UPDATE, DELETE or INSERT */ | |
| 12482 IdxWrite *pNext; | |
| 12483 }; | |
| 12484 | |
| 12485 /* | |
| 12486 ** Each statement being analyzed is represented by an instance of this | |
| 12487 ** structure. | |
| 12488 */ | |
| 12489 struct IdxStatement { | |
| 12490 int iId; /* Statement number */ | |
| 12491 char *zSql; /* SQL statement */ | |
| 12492 char *zIdx; /* Indexes */ | |
| 12493 char *zEQP; /* Plan */ | |
| 12494 IdxStatement *pNext; | |
| 12495 }; | |
| 12496 | |
| 12497 | |
| 12498 /* | |
| 12499 ** A hash table for storing strings. With space for a payload string | |
| 12500 ** with each entry. Methods are: | |
| 12501 ** | |
| 12502 ** idxHashInit() | |
| 12503 ** idxHashClear() | |
| 12504 ** idxHashAdd() | |
| 12505 ** idxHashSearch() | |
| 12506 */ | |
| 12507 #define IDX_HASH_SIZE 1023 | |
| 12508 typedef struct IdxHashEntry IdxHashEntry; | |
| 12509 typedef struct IdxHash IdxHash; | |
| 12510 struct IdxHashEntry { | |
| 12511 char *zKey; /* nul-terminated key */ | |
| 12512 char *zVal; /* nul-terminated value string */ | |
| 12513 char *zVal2; /* nul-terminated value string 2 */ | |
| 12514 IdxHashEntry *pHashNext; /* Next entry in same hash bucket */ | |
| 12515 IdxHashEntry *pNext; /* Next entry in hash */ | |
| 12516 }; | |
| 12517 struct IdxHash { | |
| 12518 IdxHashEntry *pFirst; | |
| 12519 IdxHashEntry *aHash[IDX_HASH_SIZE]; | |
| 12520 }; | |
| 12521 | |
| 12522 /* | |
| 12523 ** sqlite3expert object. | |
| 12524 */ | |
| 12525 struct sqlite3expert { | |
| 12526 int iSample; /* Percentage of tables to sample for stat1 */ | |
| 12527 sqlite3 *db; /* User database */ | |
| 12528 sqlite3 *dbm; /* In-memory db for this analysis */ | |
| 12529 sqlite3 *dbv; /* Vtab schema for this analysis */ | |
| 12530 IdxTable *pTable; /* List of all IdxTable objects */ | |
| 12531 IdxScan *pScan; /* List of scan objects */ | |
| 12532 IdxWrite *pWrite; /* List of write objects */ | |
| 12533 IdxStatement *pStatement; /* List of IdxStatement objects */ | |
| 12534 int bRun; /* True once analysis has run */ | |
| 12535 char **pzErrmsg; | |
| 12536 int rc; /* Error code from whereinfo hook */ | |
| 12537 IdxHash hIdx; /* Hash containing all candidate indexes */ | |
| 12538 char *zCandidates; /* For EXPERT_REPORT_CANDIDATES */ | |
| 12539 }; | |
| 12540 | |
| 12541 | |
| 12542 /* | |
| 12543 ** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc(). | |
| 12544 ** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL. | |
| 12545 */ | |
| 12546 static void *idxMalloc(int *pRc, i64 nByte){ | |
| 12547 void *pRet; | |
| 12548 assert( *pRc==SQLITE_OK ); | |
| 12549 assert( nByte>0 ); | |
| 12550 pRet = sqlite3_malloc64(nByte); | |
| 12551 if( pRet ){ | |
| 12552 memset(pRet, 0, nByte); | |
| 12553 }else{ | |
| 12554 *pRc = SQLITE_NOMEM; | |
| 12555 } | |
| 12556 return pRet; | |
| 12557 } | |
| 12558 | |
| 12559 /* | |
| 12560 ** Initialize an IdxHash hash table. | |
| 12561 */ | |
| 12562 static void idxHashInit(IdxHash *pHash){ | |
| 12563 memset(pHash, 0, sizeof(IdxHash)); | |
| 12564 } | |
| 12565 | |
| 12566 /* | |
| 12567 ** Reset an IdxHash hash table. | |
| 12568 */ | |
| 12569 static void idxHashClear(IdxHash *pHash){ | |
| 12570 int i; | |
| 12571 for(i=0; i<IDX_HASH_SIZE; i++){ | |
| 12572 IdxHashEntry *pEntry; | |
| 12573 IdxHashEntry *pNext; | |
| 12574 for(pEntry=pHash->aHash[i]; pEntry; pEntry=pNext){ | |
| 12575 pNext = pEntry->pHashNext; | |
| 12576 sqlite3_free(pEntry->zVal2); | |
| 12577 sqlite3_free(pEntry); | |
| 12578 } | |
| 12579 } | |
| 12580 memset(pHash, 0, sizeof(IdxHash)); | |
| 12581 } | |
| 12582 | |
| 12583 /* | |
| 12584 ** Return the index of the hash bucket that the string specified by the | |
| 12585 ** arguments to this function belongs. | |
| 12586 */ | |
| 12587 static int idxHashString(const char *z, int n){ | |
| 12588 unsigned int ret = 0; | |
| 12589 int i; | |
| 12590 for(i=0; i<n; i++){ | |
| 12591 ret += (ret<<3) + (unsigned char)(z[i]); | |
| 12592 } | |
| 12593 return (int)(ret % IDX_HASH_SIZE); | |
| 12594 } | |
| 12595 | |
| 12596 /* | |
| 12597 ** If zKey is already present in the hash table, return non-zero and do | |
| 12598 ** nothing. Otherwise, add an entry with key zKey and payload string zVal to | |
| 12599 ** the hash table passed as the second argument. | |
| 12600 */ | |
| 12601 static int idxHashAdd( | |
| 12602 int *pRc, | |
| 12603 IdxHash *pHash, | |
| 12604 const char *zKey, | |
| 12605 const char *zVal | |
| 12606 ){ | |
| 12607 int nKey = STRLEN(zKey); | |
| 12608 int iHash = idxHashString(zKey, nKey); | |
| 12609 int nVal = (zVal ? STRLEN(zVal) : 0); | |
| 12610 IdxHashEntry *pEntry; | |
| 12611 assert( iHash>=0 ); | |
| 12612 for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){ | |
| 12613 if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){ | |
| 12614 return 1; | |
| 12615 } | |
| 12616 } | |
| 12617 pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + (i64)nKey+1 + (i64)nVal+1); | |
| 12618 if( pEntry ){ | |
| 12619 pEntry->zKey = (char*)&pEntry[1]; | |
| 12620 memcpy(pEntry->zKey, zKey, nKey); | |
| 12621 if( zVal ){ | |
| 12622 pEntry->zVal = &pEntry->zKey[nKey+1]; | |
| 12623 memcpy(pEntry->zVal, zVal, nVal); | |
| 12624 } | |
| 12625 pEntry->pHashNext = pHash->aHash[iHash]; | |
| 12626 pHash->aHash[iHash] = pEntry; | |
| 12627 | |
| 12628 pEntry->pNext = pHash->pFirst; | |
| 12629 pHash->pFirst = pEntry; | |
| 12630 } | |
| 12631 return 0; | |
| 12632 } | |
| 12633 | |
| 12634 /* | |
| 12635 ** If zKey/nKey is present in the hash table, return a pointer to the | |
| 12636 ** hash-entry object. | |
| 12637 */ | |
| 12638 static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){ | |
| 12639 int iHash; | |
| 12640 IdxHashEntry *pEntry; | |
| 12641 if( nKey<0 ) nKey = STRLEN(zKey); | |
| 12642 iHash = idxHashString(zKey, nKey); | |
| 12643 assert( iHash>=0 ); | |
| 12644 for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){ | |
| 12645 if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){ | |
| 12646 return pEntry; | |
| 12647 } | |
| 12648 } | |
| 12649 return 0; | |
| 12650 } | |
| 12651 | |
| 12652 /* | |
| 12653 ** If the hash table contains an entry with a key equal to the string | |
| 12654 ** passed as the final two arguments to this function, return a pointer | |
| 12655 ** to the payload string. Otherwise, if zKey/nKey is not present in the | |
| 12656 ** hash table, return NULL. | |
| 12657 */ | |
| 12658 static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){ | |
| 12659 IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey); | |
| 12660 if( pEntry ) return pEntry->zVal; | |
| 12661 return 0; | |
| 12662 } | |
| 12663 | |
| 12664 /* | |
| 12665 ** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl | |
| 12666 ** variable to point to a copy of nul-terminated string zColl. | |
| 12667 */ | |
| 12668 static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){ | |
| 12669 IdxConstraint *pNew; | |
| 12670 int nColl = STRLEN(zColl); | |
| 12671 | |
| 12672 assert( *pRc==SQLITE_OK ); | |
| 12673 pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1); | |
| 12674 if( pNew ){ | |
| 12675 pNew->zColl = (char*)&pNew[1]; | |
| 12676 memcpy(pNew->zColl, zColl, nColl+1); | |
| 12677 } | |
| 12678 return pNew; | |
| 12679 } | |
| 12680 | |
| 12681 /* | |
| 12682 ** An error associated with database handle db has just occurred. Pass | |
| 12683 ** the error message to callback function xOut. | |
| 12684 */ | |
| 12685 static void idxDatabaseError( | |
| 12686 sqlite3 *db, /* Database handle */ | |
| 12687 char **pzErrmsg /* Write error here */ | |
| 12688 ){ | |
| 12689 *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); | |
| 12690 } | |
| 12691 | |
| 12692 /* | |
| 12693 ** Prepare an SQL statement. | |
| 12694 */ | |
| 12695 static int idxPrepareStmt( | |
| 12696 sqlite3 *db, /* Database handle to compile against */ | |
| 12697 sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ | |
| 12698 char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ | |
| 12699 const char *zSql /* SQL statement to compile */ | |
| 12700 ){ | |
| 12701 int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); | |
| 12702 if( rc!=SQLITE_OK ){ | |
| 12703 *ppStmt = 0; | |
| 12704 idxDatabaseError(db, pzErrmsg); | |
| 12705 } | |
| 12706 return rc; | |
| 12707 } | |
| 12708 | |
| 12709 /* | |
| 12710 ** Prepare an SQL statement using the results of a printf() formatting. | |
| 12711 */ | |
| 12712 static int idxPrintfPrepareStmt( | |
| 12713 sqlite3 *db, /* Database handle to compile against */ | |
| 12714 sqlite3_stmt **ppStmt, /* OUT: Compiled SQL statement */ | |
| 12715 char **pzErrmsg, /* OUT: sqlite3_malloc()ed error message */ | |
| 12716 const char *zFmt, /* printf() format of SQL statement */ | |
| 12717 ... /* Trailing printf() arguments */ | |
| 12718 ){ | |
| 12719 va_list ap; | |
| 12720 int rc; | |
| 12721 char *zSql; | |
| 12722 va_start(ap, zFmt); | |
| 12723 zSql = sqlite3_vmprintf(zFmt, ap); | |
| 12724 if( zSql==0 ){ | |
| 12725 rc = SQLITE_NOMEM; | |
| 12726 }else{ | |
| 12727 rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql); | |
| 12728 sqlite3_free(zSql); | |
| 12729 } | |
| 12730 va_end(ap); | |
| 12731 return rc; | |
| 12732 } | |
| 12733 | |
| 12734 | |
| 12735 /************************************************************************* | |
| 12736 ** Beginning of virtual table implementation. | |
| 12737 */ | |
| 12738 typedef struct ExpertVtab ExpertVtab; | |
| 12739 struct ExpertVtab { | |
| 12740 sqlite3_vtab base; | |
| 12741 IdxTable *pTab; | |
| 12742 sqlite3expert *pExpert; | |
| 12743 }; | |
| 12744 | |
| 12745 typedef struct ExpertCsr ExpertCsr; | |
| 12746 struct ExpertCsr { | |
| 12747 sqlite3_vtab_cursor base; | |
| 12748 sqlite3_stmt *pData; | |
| 12749 }; | |
| 12750 | |
| 12751 static char *expertDequote(const char *zIn){ | |
| 12752 i64 n = STRLEN(zIn); | |
| 12753 char *zRet = sqlite3_malloc64(n); | |
| 12754 | |
| 12755 assert( zIn[0]=='\'' ); | |
| 12756 assert( zIn[n-1]=='\'' ); | |
| 12757 | |
| 12758 if( zRet ){ | |
| 12759 i64 iOut = 0; | |
| 12760 i64 iIn = 0; | |
| 12761 for(iIn=1; iIn<(n-1); iIn++){ | |
| 12762 if( zIn[iIn]=='\'' ){ | |
| 12763 assert( zIn[iIn+1]=='\'' ); | |
| 12764 iIn++; | |
| 12765 } | |
| 12766 zRet[iOut++] = zIn[iIn]; | |
| 12767 } | |
| 12768 zRet[iOut] = '\0'; | |
| 12769 } | |
| 12770 | |
| 12771 return zRet; | |
| 12772 } | |
| 12773 | |
| 12774 /* | |
| 12775 ** This function is the implementation of both the xConnect and xCreate | |
| 12776 ** methods of the r-tree virtual table. | |
| 12777 ** | |
| 12778 ** argv[0] -> module name | |
| 12779 ** argv[1] -> database name | |
| 12780 ** argv[2] -> table name | |
| 12781 ** argv[...] -> column names... | |
| 12782 */ | |
| 12783 static int expertConnect( | |
| 12784 sqlite3 *db, | |
| 12785 void *pAux, | |
| 12786 int argc, const char *const*argv, | |
| 12787 sqlite3_vtab **ppVtab, | |
| 12788 char **pzErr | |
| 12789 ){ | |
| 12790 sqlite3expert *pExpert = (sqlite3expert*)pAux; | |
| 12791 ExpertVtab *p = 0; | |
| 12792 int rc; | |
| 12793 | |
| 12794 if( argc!=4 ){ | |
| 12795 *pzErr = sqlite3_mprintf("internal error!"); | |
| 12796 rc = SQLITE_ERROR; | |
| 12797 }else{ | |
| 12798 char *zCreateTable = expertDequote(argv[3]); | |
| 12799 if( zCreateTable ){ | |
| 12800 rc = sqlite3_declare_vtab(db, zCreateTable); | |
| 12801 if( rc==SQLITE_OK ){ | |
| 12802 p = idxMalloc(&rc, sizeof(ExpertVtab)); | |
| 12803 } | |
| 12804 if( rc==SQLITE_OK ){ | |
| 12805 p->pExpert = pExpert; | |
| 12806 p->pTab = pExpert->pTable; | |
| 12807 assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 ); | |
| 12808 } | |
| 12809 sqlite3_free(zCreateTable); | |
| 12810 }else{ | |
| 12811 rc = SQLITE_NOMEM; | |
| 12812 } | |
| 12813 } | |
| 12814 | |
| 12815 *ppVtab = (sqlite3_vtab*)p; | |
| 12816 return rc; | |
| 12817 } | |
| 12818 | |
| 12819 static int expertDisconnect(sqlite3_vtab *pVtab){ | |
| 12820 ExpertVtab *p = (ExpertVtab*)pVtab; | |
| 12821 sqlite3_free(p); | |
| 12822 return SQLITE_OK; | |
| 12823 } | |
| 12824 | |
| 12825 static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){ | |
| 12826 ExpertVtab *p = (ExpertVtab*)pVtab; | |
| 12827 int rc = SQLITE_OK; | |
| 12828 int n = 0; | |
| 12829 IdxScan *pScan; | |
| 12830 const int opmask = | |
| 12831 SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT | | |
| 12832 SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE | | |
| 12833 SQLITE_INDEX_CONSTRAINT_LE; | |
| 12834 | |
| 12835 pScan = idxMalloc(&rc, sizeof(IdxScan)); | |
| 12836 if( pScan ){ | |
| 12837 int i; | |
| 12838 | |
| 12839 /* Link the new scan object into the list */ | |
| 12840 pScan->pTab = p->pTab; | |
| 12841 pScan->pNextScan = p->pExpert->pScan; | |
| 12842 p->pExpert->pScan = pScan; | |
| 12843 | |
| 12844 /* Add the constraints to the IdxScan object */ | |
| 12845 for(i=0; i<pIdxInfo->nConstraint; i++){ | |
| 12846 struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i]; | |
| 12847 if( pCons->usable | |
| 12848 && pCons->iColumn>=0 | |
| 12849 && p->pTab->aCol[pCons->iColumn].iPk==0 | |
| 12850 && (pCons->op & opmask) | |
| 12851 ){ | |
| 12852 IdxConstraint *pNew; | |
| 12853 const char *zColl = sqlite3_vtab_collation(pIdxInfo, i); | |
| 12854 pNew = idxNewConstraint(&rc, zColl); | |
| 12855 if( pNew ){ | |
| 12856 pNew->iCol = pCons->iColumn; | |
| 12857 if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){ | |
| 12858 pNew->pNext = pScan->pEq; | |
| 12859 pScan->pEq = pNew; | |
| 12860 }else{ | |
| 12861 pNew->bRange = 1; | |
| 12862 pNew->pNext = pScan->pRange; | |
| 12863 pScan->pRange = pNew; | |
| 12864 } | |
| 12865 } | |
| 12866 n++; | |
| 12867 pIdxInfo->aConstraintUsage[i].argvIndex = n; | |
| 12868 } | |
| 12869 } | |
| 12870 | |
| 12871 /* Add the ORDER BY to the IdxScan object */ | |
| 12872 for(i=pIdxInfo->nOrderBy-1; i>=0; i--){ | |
| 12873 int iCol = pIdxInfo->aOrderBy[i].iColumn; | |
| 12874 if( iCol>=0 ){ | |
| 12875 IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl); | |
| 12876 if( pNew ){ | |
| 12877 pNew->iCol = iCol; | |
| 12878 pNew->bDesc = pIdxInfo->aOrderBy[i].desc; | |
| 12879 pNew->pNext = pScan->pOrder; | |
| 12880 pNew->pLink = pScan->pOrder; | |
| 12881 pScan->pOrder = pNew; | |
| 12882 n++; | |
| 12883 } | |
| 12884 } | |
| 12885 } | |
| 12886 } | |
| 12887 | |
| 12888 pIdxInfo->estimatedCost = 1000000.0 / (n+1); | |
| 12889 return rc; | |
| 12890 } | |
| 12891 | |
| 12892 static int expertUpdate( | |
| 12893 sqlite3_vtab *pVtab, | |
| 12894 int nData, | |
| 12895 sqlite3_value **azData, | |
| 12896 sqlite_int64 *pRowid | |
| 12897 ){ | |
| 12898 (void)pVtab; | |
| 12899 (void)nData; | |
| 12900 (void)azData; | |
| 12901 (void)pRowid; | |
| 12902 return SQLITE_OK; | |
| 12903 } | |
| 12904 | |
| 12905 /* | |
| 12906 ** Virtual table module xOpen method. | |
| 12907 */ | |
| 12908 static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ | |
| 12909 int rc = SQLITE_OK; | |
| 12910 ExpertCsr *pCsr; | |
| 12911 (void)pVTab; | |
| 12912 pCsr = idxMalloc(&rc, sizeof(ExpertCsr)); | |
| 12913 *ppCursor = (sqlite3_vtab_cursor*)pCsr; | |
| 12914 return rc; | |
| 12915 } | |
| 12916 | |
| 12917 /* | |
| 12918 ** Virtual table module xClose method. | |
| 12919 */ | |
| 12920 static int expertClose(sqlite3_vtab_cursor *cur){ | |
| 12921 ExpertCsr *pCsr = (ExpertCsr*)cur; | |
| 12922 sqlite3_finalize(pCsr->pData); | |
| 12923 sqlite3_free(pCsr); | |
| 12924 return SQLITE_OK; | |
| 12925 } | |
| 12926 | |
| 12927 /* | |
| 12928 ** Virtual table module xEof method. | |
| 12929 ** | |
| 12930 ** Return non-zero if the cursor does not currently point to a valid | |
| 12931 ** record (i.e if the scan has finished), or zero otherwise. | |
| 12932 */ | |
| 12933 static int expertEof(sqlite3_vtab_cursor *cur){ | |
| 12934 ExpertCsr *pCsr = (ExpertCsr*)cur; | |
| 12935 return pCsr->pData==0; | |
| 12936 } | |
| 12937 | |
| 12938 /* | |
| 12939 ** Virtual table module xNext method. | |
| 12940 */ | |
| 12941 static int expertNext(sqlite3_vtab_cursor *cur){ | |
| 12942 ExpertCsr *pCsr = (ExpertCsr*)cur; | |
| 12943 int rc = SQLITE_OK; | |
| 12944 | |
| 12945 assert( pCsr->pData ); | |
| 12946 rc = sqlite3_step(pCsr->pData); | |
| 12947 if( rc!=SQLITE_ROW ){ | |
| 12948 rc = sqlite3_finalize(pCsr->pData); | |
| 12949 pCsr->pData = 0; | |
| 12950 }else{ | |
| 12951 rc = SQLITE_OK; | |
| 12952 } | |
| 12953 | |
| 12954 return rc; | |
| 12955 } | |
| 12956 | |
| 12957 /* | |
| 12958 ** Virtual table module xRowid method. | |
| 12959 */ | |
| 12960 static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ | |
| 12961 (void)cur; | |
| 12962 *pRowid = 0; | |
| 12963 return SQLITE_OK; | |
| 12964 } | |
| 12965 | |
| 12966 /* | |
| 12967 ** Virtual table module xColumn method. | |
| 12968 */ | |
| 12969 static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ | |
| 12970 ExpertCsr *pCsr = (ExpertCsr*)cur; | |
| 12971 sqlite3_value *pVal; | |
| 12972 pVal = sqlite3_column_value(pCsr->pData, i); | |
| 12973 if( pVal ){ | |
| 12974 sqlite3_result_value(ctx, pVal); | |
| 12975 } | |
| 12976 return SQLITE_OK; | |
| 12977 } | |
| 12978 | |
| 12979 /* | |
| 12980 ** Virtual table module xFilter method. | |
| 12981 */ | |
| 12982 static int expertFilter( | |
| 12983 sqlite3_vtab_cursor *cur, | |
| 12984 int idxNum, const char *idxStr, | |
| 12985 int argc, sqlite3_value **argv | |
| 12986 ){ | |
| 12987 ExpertCsr *pCsr = (ExpertCsr*)cur; | |
| 12988 ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab); | |
| 12989 sqlite3expert *pExpert = pVtab->pExpert; | |
| 12990 int rc; | |
| 12991 | |
| 12992 (void)idxNum; | |
| 12993 (void)idxStr; | |
| 12994 (void)argc; | |
| 12995 (void)argv; | |
| 12996 rc = sqlite3_finalize(pCsr->pData); | |
| 12997 pCsr->pData = 0; | |
| 12998 if( rc==SQLITE_OK ){ | |
| 12999 rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg, | |
| 13000 "SELECT * FROM main.%Q WHERE sqlite_expert_sample()", pVtab->pTab->zName | |
| 13001 ); | |
| 13002 } | |
| 13003 | |
| 13004 if( rc==SQLITE_OK ){ | |
| 13005 rc = expertNext(cur); | |
| 13006 } | |
| 13007 return rc; | |
| 13008 } | |
| 13009 | |
| 13010 static int idxRegisterVtab(sqlite3expert *p){ | |
| 13011 static sqlite3_module expertModule = { | |
| 13012 2, /* iVersion */ | |
| 13013 expertConnect, /* xCreate - create a table */ | |
| 13014 expertConnect, /* xConnect - connect to an existing table */ | |
| 13015 expertBestIndex, /* xBestIndex - Determine search strategy */ | |
| 13016 expertDisconnect, /* xDisconnect - Disconnect from a table */ | |
| 13017 expertDisconnect, /* xDestroy - Drop a table */ | |
| 13018 expertOpen, /* xOpen - open a cursor */ | |
| 13019 expertClose, /* xClose - close a cursor */ | |
| 13020 expertFilter, /* xFilter - configure scan constraints */ | |
| 13021 expertNext, /* xNext - advance a cursor */ | |
| 13022 expertEof, /* xEof */ | |
| 13023 expertColumn, /* xColumn - read data */ | |
| 13024 expertRowid, /* xRowid - read data */ | |
| 13025 expertUpdate, /* xUpdate - write data */ | |
| 13026 0, /* xBegin - begin transaction */ | |
| 13027 0, /* xSync - sync transaction */ | |
| 13028 0, /* xCommit - commit transaction */ | |
| 13029 0, /* xRollback - rollback transaction */ | |
| 13030 0, /* xFindFunction - function overloading */ | |
| 13031 0, /* xRename - rename the table */ | |
| 13032 0, /* xSavepoint */ | |
| 13033 0, /* xRelease */ | |
| 13034 0, /* xRollbackTo */ | |
| 13035 0, /* xShadowName */ | |
| 13036 0, /* xIntegrity */ | |
| 13037 }; | |
| 13038 | |
| 13039 return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p); | |
| 13040 } | |
| 13041 /* | |
| 13042 ** End of virtual table implementation. | |
| 13043 *************************************************************************/ | |
| 13044 /* | |
| 13045 ** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function | |
| 13046 ** is called, set it to the return value of sqlite3_finalize() before | |
| 13047 ** returning. Otherwise, discard the sqlite3_finalize() return value. | |
| 13048 */ | |
| 13049 static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){ | |
| 13050 int rc = sqlite3_finalize(pStmt); | |
| 13051 if( *pRc==SQLITE_OK ) *pRc = rc; | |
| 13052 } | |
| 13053 | |
| 13054 /* | |
| 13055 ** Attempt to allocate an IdxTable structure corresponding to table zTab | |
| 13056 ** in the main database of connection db. If successful, set (*ppOut) to | |
| 13057 ** point to the new object and return SQLITE_OK. Otherwise, return an | |
| 13058 ** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be | |
| 13059 ** set to point to an error string. | |
| 13060 ** | |
| 13061 ** It is the responsibility of the caller to eventually free either the | |
| 13062 ** IdxTable object or error message using sqlite3_free(). | |
| 13063 */ | |
| 13064 static int idxGetTableInfo( | |
| 13065 sqlite3 *db, /* Database connection to read details from */ | |
| 13066 const char *zTab, /* Table name */ | |
| 13067 IdxTable **ppOut, /* OUT: New object (if successful) */ | |
| 13068 char **pzErrmsg /* OUT: Error message (if not) */ | |
| 13069 ){ | |
| 13070 sqlite3_stmt *p1 = 0; | |
| 13071 int nCol = 0; | |
| 13072 int nTab; | |
| 13073 i64 nByte; | |
| 13074 IdxTable *pNew = 0; | |
| 13075 int rc, rc2; | |
| 13076 char *pCsr = 0; | |
| 13077 int nPk = 0; | |
| 13078 | |
| 13079 *ppOut = 0; | |
| 13080 if( zTab==0 ) return SQLITE_ERROR; | |
| 13081 nTab = STRLEN(zTab); | |
| 13082 nByte = sizeof(IdxTable) + nTab + 1; | |
| 13083 rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab); | |
| 13084 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ | |
| 13085 const char *zCol = (const char*)sqlite3_column_text(p1, 1); | |
| 13086 const char *zColSeq = 0; | |
| 13087 if( zCol==0 ){ | |
| 13088 rc = SQLITE_ERROR; | |
| 13089 break; | |
| 13090 } | |
| 13091 nByte += 1 + STRLEN(zCol); | |
| 13092 rc = sqlite3_table_column_metadata( | |
| 13093 db, "main", zTab, zCol, 0, &zColSeq, 0, 0, 0 | |
| 13094 ); | |
| 13095 if( zColSeq==0 ) zColSeq = "binary"; | |
| 13096 nByte += 1 + STRLEN(zColSeq); | |
| 13097 nCol++; | |
| 13098 nPk += (sqlite3_column_int(p1, 5)>0); | |
| 13099 } | |
| 13100 rc2 = sqlite3_reset(p1); | |
| 13101 if( rc==SQLITE_OK ) rc = rc2; | |
| 13102 | |
| 13103 nByte += sizeof(IdxColumn) * nCol; | |
| 13104 if( rc==SQLITE_OK ){ | |
| 13105 pNew = idxMalloc(&rc, nByte); | |
| 13106 } | |
| 13107 if( rc==SQLITE_OK ){ | |
| 13108 pNew->aCol = (IdxColumn*)&pNew[1]; | |
| 13109 pNew->nCol = nCol; | |
| 13110 pCsr = (char*)&pNew->aCol[nCol]; | |
| 13111 } | |
| 13112 | |
| 13113 nCol = 0; | |
| 13114 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ | |
| 13115 const char *zCol = (const char*)sqlite3_column_text(p1, 1); | |
| 13116 const char *zColSeq = 0; | |
| 13117 int nCopy; | |
| 13118 if( zCol==0 ) continue; | |
| 13119 nCopy = STRLEN(zCol) + 1; | |
| 13120 pNew->aCol[nCol].zName = pCsr; | |
| 13121 pNew->aCol[nCol].iPk = (sqlite3_column_int(p1, 5)==1 && nPk==1); | |
| 13122 memcpy(pCsr, zCol, nCopy); | |
| 13123 pCsr += nCopy; | |
| 13124 | |
| 13125 rc = sqlite3_table_column_metadata( | |
| 13126 db, "main", zTab, zCol, 0, &zColSeq, 0, 0, 0 | |
| 13127 ); | |
| 13128 if( rc==SQLITE_OK ){ | |
| 13129 if( zColSeq==0 ) zColSeq = "binary"; | |
| 13130 nCopy = STRLEN(zColSeq) + 1; | |
| 13131 pNew->aCol[nCol].zColl = pCsr; | |
| 13132 memcpy(pCsr, zColSeq, nCopy); | |
| 13133 pCsr += nCopy; | |
| 13134 } | |
| 13135 | |
| 13136 nCol++; | |
| 13137 } | |
| 13138 idxFinalize(&rc, p1); | |
| 13139 | |
| 13140 if( rc!=SQLITE_OK ){ | |
| 13141 sqlite3_free(pNew); | |
| 13142 pNew = 0; | |
| 13143 }else if( ALWAYS(pNew!=0) ){ | |
| 13144 pNew->zName = pCsr; | |
| 13145 if( ALWAYS(pNew->zName!=0) ) memcpy(pNew->zName, zTab, nTab+1); | |
| 13146 } | |
| 13147 | |
| 13148 *ppOut = pNew; | |
| 13149 return rc; | |
| 13150 } | |
| 13151 | |
| 13152 /* | |
| 13153 ** This function is a no-op if *pRc is set to anything other than | |
| 13154 ** SQLITE_OK when it is called. | |
| 13155 ** | |
| 13156 ** If *pRc is initially set to SQLITE_OK, then the text specified by | |
| 13157 ** the printf() style arguments is appended to zIn and the result returned | |
| 13158 ** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on | |
| 13159 ** zIn before returning. | |
| 13160 */ | |
| 13161 static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){ | |
| 13162 va_list ap; | |
| 13163 char *zAppend = 0; | |
| 13164 char *zRet = 0; | |
| 13165 i64 nIn = zIn ? STRLEN(zIn) : 0; | |
| 13166 i64 nAppend = 0; | |
| 13167 va_start(ap, zFmt); | |
| 13168 if( *pRc==SQLITE_OK ){ | |
| 13169 zAppend = sqlite3_vmprintf(zFmt, ap); | |
| 13170 if( zAppend ){ | |
| 13171 nAppend = STRLEN(zAppend); | |
| 13172 zRet = (char*)sqlite3_malloc64(nIn + nAppend + 1); | |
| 13173 } | |
| 13174 if( zAppend && zRet ){ | |
| 13175 if( nIn ) memcpy(zRet, zIn, nIn); | |
| 13176 memcpy(&zRet[nIn], zAppend, nAppend+1); | |
| 13177 }else{ | |
| 13178 sqlite3_free(zRet); | |
| 13179 zRet = 0; | |
| 13180 *pRc = SQLITE_NOMEM; | |
| 13181 } | |
| 13182 sqlite3_free(zAppend); | |
| 13183 sqlite3_free(zIn); | |
| 13184 } | |
| 13185 va_end(ap); | |
| 13186 return zRet; | |
| 13187 } | |
| 13188 | |
| 13189 /* | |
| 13190 ** Return true if zId must be quoted in order to use it as an SQL | |
| 13191 ** identifier, or false otherwise. | |
| 13192 */ | |
| 13193 static int idxIdentifierRequiresQuotes(const char *zId){ | |
| 13194 int i; | |
| 13195 int nId = STRLEN(zId); | |
| 13196 | |
| 13197 if( sqlite3_keyword_check(zId, nId) ) return 1; | |
| 13198 | |
| 13199 for(i=0; zId[i]; i++){ | |
| 13200 if( !(zId[i]=='_') | |
| 13201 && !(zId[i]>='0' && zId[i]<='9') | |
| 13202 && !(zId[i]>='a' && zId[i]<='z') | |
| 13203 && !(zId[i]>='A' && zId[i]<='Z') | |
| 13204 ){ | |
| 13205 return 1; | |
| 13206 } | |
| 13207 } | |
| 13208 return 0; | |
| 13209 } | |
| 13210 | |
| 13211 /* | |
| 13212 ** This function appends an index column definition suitable for constraint | |
| 13213 ** pCons to the string passed as zIn and returns the result. | |
| 13214 */ | |
| 13215 static char *idxAppendColDefn( | |
| 13216 int *pRc, /* IN/OUT: Error code */ | |
| 13217 char *zIn, /* Column defn accumulated so far */ | |
| 13218 IdxTable *pTab, /* Table index will be created on */ | |
| 13219 IdxConstraint *pCons | |
| 13220 ){ | |
| 13221 char *zRet = zIn; | |
| 13222 IdxColumn *p = &pTab->aCol[pCons->iCol]; | |
| 13223 if( zRet ) zRet = idxAppendText(pRc, zRet, ", "); | |
| 13224 | |
| 13225 if( idxIdentifierRequiresQuotes(p->zName) ){ | |
| 13226 zRet = idxAppendText(pRc, zRet, "%Q", p->zName); | |
| 13227 }else{ | |
| 13228 zRet = idxAppendText(pRc, zRet, "%s", p->zName); | |
| 13229 } | |
| 13230 | |
| 13231 if( sqlite3_stricmp(p->zColl, pCons->zColl) ){ | |
| 13232 if( idxIdentifierRequiresQuotes(pCons->zColl) ){ | |
| 13233 zRet = idxAppendText(pRc, zRet, " COLLATE %Q", pCons->zColl); | |
| 13234 }else{ | |
| 13235 zRet = idxAppendText(pRc, zRet, " COLLATE %s", pCons->zColl); | |
| 13236 } | |
| 13237 } | |
| 13238 | |
| 13239 if( pCons->bDesc ){ | |
| 13240 zRet = idxAppendText(pRc, zRet, " DESC"); | |
| 13241 } | |
| 13242 return zRet; | |
| 13243 } | |
| 13244 | |
| 13245 /* | |
| 13246 ** Search database dbm for an index compatible with the one idxCreateFromCons() | |
| 13247 ** would create from arguments pScan, pEq and pTail. If no error occurs and | |
| 13248 ** such an index is found, return non-zero. Or, if no such index is found, | |
| 13249 ** return zero. | |
| 13250 ** | |
| 13251 ** If an error occurs, set *pRc to an SQLite error code and return zero. | |
| 13252 */ | |
| 13253 static int idxFindCompatible( | |
| 13254 int *pRc, /* OUT: Error code */ | |
| 13255 sqlite3* dbm, /* Database to search */ | |
| 13256 IdxScan *pScan, /* Scan for table to search for index on */ | |
| 13257 IdxConstraint *pEq, /* List of == constraints */ | |
| 13258 IdxConstraint *pTail /* List of range constraints */ | |
| 13259 ){ | |
| 13260 const char *zTbl = pScan->pTab->zName; | |
| 13261 sqlite3_stmt *pIdxList = 0; | |
| 13262 IdxConstraint *pIter; | |
| 13263 int nEq = 0; /* Number of elements in pEq */ | |
| 13264 int rc; | |
| 13265 | |
| 13266 /* Count the elements in list pEq */ | |
| 13267 for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++; | |
| 13268 | |
| 13269 rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl); | |
| 13270 while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){ | |
| 13271 int bMatch = 1; | |
| 13272 IdxConstraint *pT = pTail; | |
| 13273 sqlite3_stmt *pInfo = 0; | |
| 13274 const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1); | |
| 13275 if( zIdx==0 ) continue; | |
| 13276 | |
| 13277 /* Zero the IdxConstraint.bFlag values in the pEq list */ | |
| 13278 for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0; | |
| 13279 | |
| 13280 rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx); | |
| 13281 while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){ | |
| 13282 int iIdx = sqlite3_column_int(pInfo, 0); | |
| 13283 int iCol = sqlite3_column_int(pInfo, 1); | |
| 13284 const char *zColl = (const char*)sqlite3_column_text(pInfo, 4); | |
| 13285 | |
| 13286 if( iIdx<nEq ){ | |
| 13287 for(pIter=pEq; pIter; pIter=pIter->pLink){ | |
| 13288 if( pIter->bFlag ) continue; | |
| 13289 if( pIter->iCol!=iCol ) continue; | |
| 13290 if( sqlite3_stricmp(pIter->zColl, zColl) ) continue; | |
| 13291 pIter->bFlag = 1; | |
| 13292 break; | |
| 13293 } | |
| 13294 if( pIter==0 ){ | |
| 13295 bMatch = 0; | |
| 13296 break; | |
| 13297 } | |
| 13298 }else{ | |
| 13299 if( pT ){ | |
| 13300 if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){ | |
| 13301 bMatch = 0; | |
| 13302 break; | |
| 13303 } | |
| 13304 pT = pT->pLink; | |
| 13305 } | |
| 13306 } | |
| 13307 } | |
| 13308 idxFinalize(&rc, pInfo); | |
| 13309 | |
| 13310 if( rc==SQLITE_OK && bMatch ){ | |
| 13311 sqlite3_finalize(pIdxList); | |
| 13312 return 1; | |
| 13313 } | |
| 13314 } | |
| 13315 idxFinalize(&rc, pIdxList); | |
| 13316 | |
| 13317 *pRc = rc; | |
| 13318 return 0; | |
| 13319 } | |
| 13320 | |
| 13321 /* Callback for sqlite3_exec() with query with leading count(*) column. | |
| 13322 * The first argument is expected to be an int*, referent to be incremented | |
| 13323 * if that leading column is not exactly '0'. | |
| 13324 */ | |
| 13325 static int countNonzeros(void* pCount, int nc, | |
| 13326 char* azResults[], char* azColumns[]){ | |
| 13327 (void)azColumns; /* Suppress unused parameter warning */ | |
| 13328 if( nc>0 && (azResults[0][0]!='0' || azResults[0][1]!=0) ){ | |
| 13329 *((int *)pCount) += 1; | |
| 13330 } | |
| 13331 return 0; | |
| 13332 } | |
| 13333 | |
| 13334 static int idxCreateFromCons( | |
| 13335 sqlite3expert *p, | |
| 13336 IdxScan *pScan, | |
| 13337 IdxConstraint *pEq, | |
| 13338 IdxConstraint *pTail | |
| 13339 ){ | |
| 13340 sqlite3 *dbm = p->dbm; | |
| 13341 int rc = SQLITE_OK; | |
| 13342 if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){ | |
| 13343 IdxTable *pTab = pScan->pTab; | |
| 13344 char *zCols = 0; | |
| 13345 char *zIdx = 0; | |
| 13346 IdxConstraint *pCons; | |
| 13347 unsigned int h = 0; | |
| 13348 const char *zFmt; | |
| 13349 | |
| 13350 for(pCons=pEq; pCons; pCons=pCons->pLink){ | |
| 13351 zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); | |
| 13352 } | |
| 13353 for(pCons=pTail; pCons; pCons=pCons->pLink){ | |
| 13354 zCols = idxAppendColDefn(&rc, zCols, pTab, pCons); | |
| 13355 } | |
| 13356 | |
| 13357 if( rc==SQLITE_OK ){ | |
| 13358 /* Hash the list of columns to come up with a name for the index */ | |
| 13359 const char *zTable = pScan->pTab->zName; | |
| 13360 int quoteTable = idxIdentifierRequiresQuotes(zTable); | |
| 13361 char *zName = 0; /* Index name */ | |
| 13362 int collisions = 0; | |
| 13363 do{ | |
| 13364 int i; | |
| 13365 char *zFind; | |
| 13366 for(i=0; zCols[i]; i++){ | |
| 13367 h += ((h<<3) + zCols[i]); | |
| 13368 } | |
| 13369 sqlite3_free(zName); | |
| 13370 zName = sqlite3_mprintf("%s_idx_%08x", zTable, h); | |
| 13371 if( zName==0 ) break; | |
| 13372 /* Is is unique among table, view and index names? */ | |
| 13373 zFmt = "SELECT count(*) FROM sqlite_schema WHERE name=%Q" | |
| 13374 " AND type in ('index','table','view')"; | |
| 13375 zFind = sqlite3_mprintf(zFmt, zName); | |
| 13376 i = 0; | |
| 13377 rc = sqlite3_exec(dbm, zFind, countNonzeros, &i, 0); | |
| 13378 assert(rc==SQLITE_OK); | |
| 13379 sqlite3_free(zFind); | |
| 13380 if( i==0 ){ | |
| 13381 collisions = 0; | |
| 13382 break; | |
| 13383 } | |
| 13384 ++collisions; | |
| 13385 }while( collisions<50 && zName!=0 ); | |
| 13386 if( collisions ){ | |
| 13387 /* This return means "Gave up trying to find a unique index name." */ | |
| 13388 rc = SQLITE_BUSY_TIMEOUT; | |
| 13389 }else if( zName==0 ){ | |
| 13390 rc = SQLITE_NOMEM; | |
| 13391 }else{ | |
| 13392 if( quoteTable ){ | |
| 13393 zFmt = "CREATE INDEX \"%w\" ON \"%w\"(%s)"; | |
| 13394 }else{ | |
| 13395 zFmt = "CREATE INDEX %s ON %s(%s)"; | |
| 13396 } | |
| 13397 zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols); | |
| 13398 if( !zIdx ){ | |
| 13399 rc = SQLITE_NOMEM; | |
| 13400 }else{ | |
| 13401 rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg); | |
| 13402 if( rc!=SQLITE_OK ){ | |
| 13403 rc = SQLITE_BUSY_TIMEOUT; | |
| 13404 }else{ | |
| 13405 idxHashAdd(&rc, &p->hIdx, zName, zIdx); | |
| 13406 } | |
| 13407 } | |
| 13408 sqlite3_free(zName); | |
| 13409 sqlite3_free(zIdx); | |
| 13410 } | |
| 13411 } | |
| 13412 | |
| 13413 sqlite3_free(zCols); | |
| 13414 } | |
| 13415 return rc; | |
| 13416 } | |
| 13417 | |
| 13418 /* | |
| 13419 ** Return true if list pList (linked by IdxConstraint.pLink) contains | |
| 13420 ** a constraint compatible with *p. Otherwise return false. | |
| 13421 */ | |
| 13422 static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){ | |
| 13423 IdxConstraint *pCmp; | |
| 13424 for(pCmp=pList; pCmp; pCmp=pCmp->pLink){ | |
| 13425 if( p->iCol==pCmp->iCol ) return 1; | |
| 13426 } | |
| 13427 return 0; | |
| 13428 } | |
| 13429 | |
| 13430 static int idxCreateFromWhere( | |
| 13431 sqlite3expert *p, | |
| 13432 IdxScan *pScan, /* Create indexes for this scan */ | |
| 13433 IdxConstraint *pTail /* range/ORDER BY constraints for inclusion */ | |
| 13434 ){ | |
| 13435 IdxConstraint *p1 = 0; | |
| 13436 IdxConstraint *pCon; | |
| 13437 int rc; | |
| 13438 | |
| 13439 /* Gather up all the == constraints. */ | |
| 13440 for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){ | |
| 13441 if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){ | |
| 13442 pCon->pLink = p1; | |
| 13443 p1 = pCon; | |
| 13444 } | |
| 13445 } | |
| 13446 | |
| 13447 /* Create an index using the == constraints collected above. And the | |
| 13448 ** range constraint/ORDER BY terms passed in by the caller, if any. */ | |
| 13449 rc = idxCreateFromCons(p, pScan, p1, pTail); | |
| 13450 | |
| 13451 /* If no range/ORDER BY passed by the caller, create a version of the | |
| 13452 ** index for each range constraint. */ | |
| 13453 if( pTail==0 ){ | |
| 13454 for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){ | |
| 13455 assert( pCon->pLink==0 ); | |
| 13456 if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){ | |
| 13457 rc = idxCreateFromCons(p, pScan, p1, pCon); | |
| 13458 } | |
| 13459 } | |
| 13460 } | |
| 13461 | |
| 13462 return rc; | |
| 13463 } | |
| 13464 | |
| 13465 /* | |
| 13466 ** Create candidate indexes in database [dbm] based on the data in | |
| 13467 ** linked-list pScan. | |
| 13468 */ | |
| 13469 static int idxCreateCandidates(sqlite3expert *p){ | |
| 13470 int rc = SQLITE_OK; | |
| 13471 IdxScan *pIter; | |
| 13472 | |
| 13473 for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){ | |
| 13474 rc = idxCreateFromWhere(p, pIter, 0); | |
| 13475 if( rc==SQLITE_OK && pIter->pOrder ){ | |
| 13476 rc = idxCreateFromWhere(p, pIter, pIter->pOrder); | |
| 13477 } | |
| 13478 } | |
| 13479 | |
| 13480 return rc; | |
| 13481 } | |
| 13482 | |
| 13483 /* | |
| 13484 ** Free all elements of the linked list starting at pConstraint. | |
| 13485 */ | |
| 13486 static void idxConstraintFree(IdxConstraint *pConstraint){ | |
| 13487 IdxConstraint *pNext; | |
| 13488 IdxConstraint *p; | |
| 13489 | |
| 13490 for(p=pConstraint; p; p=pNext){ | |
| 13491 pNext = p->pNext; | |
| 13492 sqlite3_free(p); | |
| 13493 } | |
| 13494 } | |
| 13495 | |
| 13496 /* | |
| 13497 ** Free all elements of the linked list starting from pScan up until pLast | |
| 13498 ** (pLast is not freed). | |
| 13499 */ | |
| 13500 static void idxScanFree(IdxScan *pScan, IdxScan *pLast){ | |
| 13501 IdxScan *p; | |
| 13502 IdxScan *pNext; | |
| 13503 for(p=pScan; p!=pLast; p=pNext){ | |
| 13504 pNext = p->pNextScan; | |
| 13505 idxConstraintFree(p->pOrder); | |
| 13506 idxConstraintFree(p->pEq); | |
| 13507 idxConstraintFree(p->pRange); | |
| 13508 sqlite3_free(p); | |
| 13509 } | |
| 13510 } | |
| 13511 | |
| 13512 /* | |
| 13513 ** Free all elements of the linked list starting from pStatement up | |
| 13514 ** until pLast (pLast is not freed). | |
| 13515 */ | |
| 13516 static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){ | |
| 13517 IdxStatement *p; | |
| 13518 IdxStatement *pNext; | |
| 13519 for(p=pStatement; p!=pLast; p=pNext){ | |
| 13520 pNext = p->pNext; | |
| 13521 sqlite3_free(p->zEQP); | |
| 13522 sqlite3_free(p->zIdx); | |
| 13523 sqlite3_free(p); | |
| 13524 } | |
| 13525 } | |
| 13526 | |
| 13527 /* | |
| 13528 ** Free the linked list of IdxTable objects starting at pTab. | |
| 13529 */ | |
| 13530 static void idxTableFree(IdxTable *pTab){ | |
| 13531 IdxTable *pIter; | |
| 13532 IdxTable *pNext; | |
| 13533 for(pIter=pTab; pIter; pIter=pNext){ | |
| 13534 pNext = pIter->pNext; | |
| 13535 sqlite3_free(pIter); | |
| 13536 } | |
| 13537 } | |
| 13538 | |
| 13539 /* | |
| 13540 ** Free the linked list of IdxWrite objects starting at pTab. | |
| 13541 */ | |
| 13542 static void idxWriteFree(IdxWrite *pTab){ | |
| 13543 IdxWrite *pIter; | |
| 13544 IdxWrite *pNext; | |
| 13545 for(pIter=pTab; pIter; pIter=pNext){ | |
| 13546 pNext = pIter->pNext; | |
| 13547 sqlite3_free(pIter); | |
| 13548 } | |
| 13549 } | |
| 13550 | |
| 13551 | |
| 13552 | |
| 13553 /* | |
| 13554 ** This function is called after candidate indexes have been created. It | |
| 13555 ** runs all the queries to see which indexes they prefer, and populates | |
| 13556 ** IdxStatement.zIdx and IdxStatement.zEQP with the results. | |
| 13557 */ | |
| 13558 static int idxFindIndexes( | |
| 13559 sqlite3expert *p, | |
| 13560 char **pzErr /* OUT: Error message (sqlite3_malloc) */ | |
| 13561 ){ | |
| 13562 IdxStatement *pStmt; | |
| 13563 sqlite3 *dbm = p->dbm; | |
| 13564 int rc = SQLITE_OK; | |
| 13565 | |
| 13566 IdxHash hIdx; | |
| 13567 idxHashInit(&hIdx); | |
| 13568 | |
| 13569 for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){ | |
| 13570 IdxHashEntry *pEntry; | |
| 13571 sqlite3_stmt *pExplain = 0; | |
| 13572 idxHashClear(&hIdx); | |
| 13573 rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr, | |
| 13574 "EXPLAIN QUERY PLAN %s", pStmt->zSql | |
| 13575 ); | |
| 13576 while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){ | |
| 13577 /* int iId = sqlite3_column_int(pExplain, 0); */ | |
| 13578 /* int iParent = sqlite3_column_int(pExplain, 1); */ | |
| 13579 /* int iNotUsed = sqlite3_column_int(pExplain, 2); */ | |
| 13580 const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3); | |
| 13581 int nDetail; | |
| 13582 int i; | |
| 13583 | |
| 13584 if( !zDetail ) continue; | |
| 13585 nDetail = STRLEN(zDetail); | |
| 13586 | |
| 13587 for(i=0; i<nDetail; i++){ | |
| 13588 const char *zIdx = 0; | |
| 13589 if( i+13<nDetail && memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){ | |
| 13590 zIdx = &zDetail[i+13]; | |
| 13591 }else if( i+22<nDetail | |
| 13592 && memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 | |
| 13593 ){ | |
| 13594 zIdx = &zDetail[i+22]; | |
| 13595 } | |
| 13596 if( zIdx ){ | |
| 13597 const char *zSql; | |
| 13598 int nIdx = 0; | |
| 13599 while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){ | |
| 13600 nIdx++; | |
| 13601 } | |
| 13602 zSql = idxHashSearch(&p->hIdx, zIdx, nIdx); | |
| 13603 if( zSql ){ | |
| 13604 idxHashAdd(&rc, &hIdx, zSql, 0); | |
| 13605 if( rc ) goto find_indexes_out; | |
| 13606 } | |
| 13607 break; | |
| 13608 } | |
| 13609 } | |
| 13610 | |
| 13611 if( zDetail[0]!='-' ){ | |
| 13612 pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail); | |
| 13613 } | |
| 13614 } | |
| 13615 | |
| 13616 for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){ | |
| 13617 pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey); | |
| 13618 } | |
| 13619 | |
| 13620 idxFinalize(&rc, pExplain); | |
| 13621 } | |
| 13622 | |
| 13623 find_indexes_out: | |
| 13624 idxHashClear(&hIdx); | |
| 13625 return rc; | |
| 13626 } | |
| 13627 | |
| 13628 static int idxAuthCallback( | |
| 13629 void *pCtx, | |
| 13630 int eOp, | |
| 13631 const char *z3, | |
| 13632 const char *z4, | |
| 13633 const char *zDb, | |
| 13634 const char *zTrigger | |
| 13635 ){ | |
| 13636 int rc = SQLITE_OK; | |
| 13637 (void)z4; | |
| 13638 (void)zTrigger; | |
| 13639 if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){ | |
| 13640 if( sqlite3_stricmp(zDb, "main")==0 ){ | |
| 13641 sqlite3expert *p = (sqlite3expert*)pCtx; | |
| 13642 IdxTable *pTab; | |
| 13643 for(pTab=p->pTable; pTab; pTab=pTab->pNext){ | |
| 13644 if( 0==sqlite3_stricmp(z3, pTab->zName) ) break; | |
| 13645 } | |
| 13646 if( pTab ){ | |
| 13647 IdxWrite *pWrite; | |
| 13648 for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){ | |
| 13649 if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break; | |
| 13650 } | |
| 13651 if( pWrite==0 ){ | |
| 13652 pWrite = idxMalloc(&rc, sizeof(IdxWrite)); | |
| 13653 if( rc==SQLITE_OK ){ | |
| 13654 pWrite->pTab = pTab; | |
| 13655 pWrite->eOp = eOp; | |
| 13656 pWrite->pNext = p->pWrite; | |
| 13657 p->pWrite = pWrite; | |
| 13658 } | |
| 13659 } | |
| 13660 } | |
| 13661 } | |
| 13662 } | |
| 13663 return rc; | |
| 13664 } | |
| 13665 | |
| 13666 static int idxProcessOneTrigger( | |
| 13667 sqlite3expert *p, | |
| 13668 IdxWrite *pWrite, | |
| 13669 char **pzErr | |
| 13670 ){ | |
| 13671 static const char *zInt = UNIQUE_TABLE_NAME; | |
| 13672 static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME; | |
| 13673 IdxTable *pTab = pWrite->pTab; | |
| 13674 const char *zTab = pTab->zName; | |
| 13675 const char *zSql = | |
| 13676 "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_schema " | |
| 13677 "WHERE tbl_name = %Q AND type IN ('table', 'trigger') " | |
| 13678 "ORDER BY type;"; | |
| 13679 sqlite3_stmt *pSelect = 0; | |
| 13680 int rc = SQLITE_OK; | |
| 13681 char *zWrite = 0; | |
| 13682 | |
| 13683 /* Create the table and its triggers in the temp schema */ | |
| 13684 rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab); | |
| 13685 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){ | |
| 13686 const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0); | |
| 13687 if( zCreate==0 ) continue; | |
| 13688 rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr); | |
| 13689 } | |
| 13690 idxFinalize(&rc, pSelect); | |
| 13691 | |
| 13692 /* Rename the table in the temp schema to zInt */ | |
| 13693 if( rc==SQLITE_OK ){ | |
| 13694 char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q", zTab, zInt); | |
| 13695 if( z==0 ){ | |
| 13696 rc = SQLITE_NOMEM; | |
| 13697 }else{ | |
| 13698 rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr); | |
| 13699 sqlite3_free(z); | |
| 13700 } | |
| 13701 } | |
| 13702 | |
| 13703 switch( pWrite->eOp ){ | |
| 13704 case SQLITE_INSERT: { | |
| 13705 int i; | |
| 13706 zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(", zInt); | |
| 13707 for(i=0; i<pTab->nCol; i++){ | |
| 13708 zWrite = idxAppendText(&rc, zWrite, "%s?", i==0 ? "" : ", "); | |
| 13709 } | |
| 13710 zWrite = idxAppendText(&rc, zWrite, ")"); | |
| 13711 break; | |
| 13712 } | |
| 13713 case SQLITE_UPDATE: { | |
| 13714 int i; | |
| 13715 zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET ", zInt); | |
| 13716 for(i=0; i<pTab->nCol; i++){ | |
| 13717 zWrite = idxAppendText(&rc, zWrite, "%s%Q=?", i==0 ? "" : ", ", | |
| 13718 pTab->aCol[i].zName | |
| 13719 ); | |
| 13720 } | |
| 13721 break; | |
| 13722 } | |
| 13723 default: { | |
| 13724 assert( pWrite->eOp==SQLITE_DELETE ); | |
| 13725 if( rc==SQLITE_OK ){ | |
| 13726 zWrite = sqlite3_mprintf("DELETE FROM %Q", zInt); | |
| 13727 if( zWrite==0 ) rc = SQLITE_NOMEM; | |
| 13728 } | |
| 13729 } | |
| 13730 } | |
| 13731 | |
| 13732 if( rc==SQLITE_OK ){ | |
| 13733 sqlite3_stmt *pX = 0; | |
| 13734 rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0); | |
| 13735 idxFinalize(&rc, pX); | |
| 13736 if( rc!=SQLITE_OK ){ | |
| 13737 idxDatabaseError(p->dbv, pzErr); | |
| 13738 } | |
| 13739 } | |
| 13740 sqlite3_free(zWrite); | |
| 13741 | |
| 13742 if( rc==SQLITE_OK ){ | |
| 13743 rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr); | |
| 13744 } | |
| 13745 | |
| 13746 return rc; | |
| 13747 } | |
| 13748 | |
| 13749 static int idxProcessTriggers(sqlite3expert *p, char **pzErr){ | |
| 13750 int rc = SQLITE_OK; | |
| 13751 IdxWrite *pEnd = 0; | |
| 13752 IdxWrite *pFirst = p->pWrite; | |
| 13753 | |
| 13754 while( rc==SQLITE_OK && pFirst!=pEnd ){ | |
| 13755 IdxWrite *pIter; | |
| 13756 for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){ | |
| 13757 rc = idxProcessOneTrigger(p, pIter, pzErr); | |
| 13758 } | |
| 13759 pEnd = pFirst; | |
| 13760 pFirst = p->pWrite; | |
| 13761 } | |
| 13762 | |
| 13763 return rc; | |
| 13764 } | |
| 13765 | |
| 13766 /* | |
| 13767 ** This function tests if the schema of the main database of database handle | |
| 13768 ** db contains an object named zTab. Assuming no error occurs, output parameter | |
| 13769 ** (*pbContains) is set to true if zTab exists, or false if it does not. | |
| 13770 ** | |
| 13771 ** Or, if an error occurs, an SQLite error code is returned. The final value | |
| 13772 ** of (*pbContains) is undefined in this case. | |
| 13773 */ | |
| 13774 static int expertDbContainsObject( | |
| 13775 sqlite3 *db, | |
| 13776 const char *zTab, | |
| 13777 int *pbContains /* OUT: True if object exists */ | |
| 13778 ){ | |
| 13779 const char *zSql = "SELECT 1 FROM sqlite_schema WHERE name = ?"; | |
| 13780 sqlite3_stmt *pSql = 0; | |
| 13781 int rc = SQLITE_OK; | |
| 13782 int ret = 0; | |
| 13783 | |
| 13784 rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); | |
| 13785 if( rc==SQLITE_OK ){ | |
| 13786 sqlite3_bind_text(pSql, 1, zTab, -1, SQLITE_STATIC); | |
| 13787 if( SQLITE_ROW==sqlite3_step(pSql) ){ | |
| 13788 ret = 1; | |
| 13789 } | |
| 13790 rc = sqlite3_finalize(pSql); | |
| 13791 } | |
| 13792 | |
| 13793 *pbContains = ret; | |
| 13794 return rc; | |
| 13795 } | |
| 13796 | |
| 13797 /* | |
| 13798 ** Execute SQL command zSql using database handle db. If no error occurs, | |
| 13799 ** set (*pzErr) to NULL and return SQLITE_OK. | |
| 13800 ** | |
| 13801 ** If an error does occur, return an SQLite error code and set (*pzErr) to | |
| 13802 ** point to a buffer containing an English language error message. Except, | |
| 13803 ** if the error message begins with "no such module:", then ignore the | |
| 13804 ** error and return as if the SQL statement had succeeded. | |
| 13805 ** | |
| 13806 ** This is used to copy as much of the database schema as possible while | |
| 13807 ** ignoring any errors related to missing virtual table modules. | |
| 13808 */ | |
| 13809 static int expertSchemaSql(sqlite3 *db, const char *zSql, char **pzErr){ | |
| 13810 int rc = SQLITE_OK; | |
| 13811 char *zErr = 0; | |
| 13812 | |
| 13813 rc = sqlite3_exec(db, zSql, 0, 0, &zErr); | |
| 13814 if( rc!=SQLITE_OK && zErr ){ | |
| 13815 int nErr = STRLEN(zErr); | |
| 13816 if( nErr>=15 && memcmp(zErr, "no such module:", 15)==0 ){ | |
| 13817 sqlite3_free(zErr); | |
| 13818 rc = SQLITE_OK; | |
| 13819 zErr = 0; | |
| 13820 } | |
| 13821 } | |
| 13822 | |
| 13823 *pzErr = zErr; | |
| 13824 return rc; | |
| 13825 } | |
| 13826 | |
| 13827 static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){ | |
| 13828 int rc = idxRegisterVtab(p); | |
| 13829 sqlite3_stmt *pSchema = 0; | |
| 13830 | |
| 13831 /* For each table in the main db schema: | |
| 13832 ** | |
| 13833 ** 1) Add an entry to the p->pTable list, and | |
| 13834 ** 2) Create the equivalent virtual table in dbv. | |
| 13835 */ | |
| 13836 rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg, | |
| 13837 "SELECT type, name, sql, 1, " | |
| 13838 " substr(sql,1,14)=='create virtual' COLLATE nocase " | |
| 13839 "FROM sqlite_schema " | |
| 13840 "WHERE type IN ('table','view') AND " | |
| 13841 " substr(name,1,7)!='sqlite_' COLLATE nocase " | |
| 13842 " UNION ALL " | |
| 13843 "SELECT type, name, sql, 2, 0 FROM sqlite_schema " | |
| 13844 "WHERE type = 'trigger'" | |
| 13845 " AND tbl_name IN(SELECT name FROM sqlite_schema WHERE type = 'view') " | |
| 13846 "ORDER BY 4, 5 DESC, 1" | |
| 13847 ); | |
| 13848 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){ | |
| 13849 const char *zType = (const char*)sqlite3_column_text(pSchema, 0); | |
| 13850 const char *zName = (const char*)sqlite3_column_text(pSchema, 1); | |
| 13851 const char *zSql = (const char*)sqlite3_column_text(pSchema, 2); | |
| 13852 int bVirtual = sqlite3_column_int(pSchema, 4); | |
| 13853 int bExists = 0; | |
| 13854 | |
| 13855 if( zType==0 || zName==0 ) continue; | |
| 13856 rc = expertDbContainsObject(p->dbv, zName, &bExists); | |
| 13857 if( rc || bExists ) continue; | |
| 13858 | |
| 13859 if( zType[0]=='v' || zType[1]=='r' || bVirtual ){ | |
| 13860 /* A view. Or a trigger on a view. */ | |
| 13861 if( zSql ) rc = expertSchemaSql(p->dbv, zSql, pzErrmsg); | |
| 13862 }else{ | |
| 13863 IdxTable *pTab; | |
| 13864 rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg); | |
| 13865 if( rc==SQLITE_OK && ALWAYS(pTab!=0) ){ | |
| 13866 int i; | |
| 13867 char *zInner = 0; | |
| 13868 char *zOuter = 0; | |
| 13869 pTab->pNext = p->pTable; | |
| 13870 p->pTable = pTab; | |
| 13871 | |
| 13872 /* The statement the vtab will pass to sqlite3_declare_vtab() */ | |
| 13873 zInner = idxAppendText(&rc, 0, "CREATE TABLE x("); | |
| 13874 for(i=0; i<pTab->nCol; i++){ | |
| 13875 zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s", | |
| 13876 (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl | |
| 13877 ); | |
| 13878 } | |
| 13879 zInner = idxAppendText(&rc, zInner, ")"); | |
| 13880 | |
| 13881 /* The CVT statement to create the vtab */ | |
| 13882 zOuter = idxAppendText(&rc, 0, | |
| 13883 "CREATE VIRTUAL TABLE %Q USING expert(%Q)", zName, zInner | |
| 13884 ); | |
| 13885 if( rc==SQLITE_OK ){ | |
| 13886 rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg); | |
| 13887 } | |
| 13888 sqlite3_free(zInner); | |
| 13889 sqlite3_free(zOuter); | |
| 13890 } | |
| 13891 } | |
| 13892 } | |
| 13893 idxFinalize(&rc, pSchema); | |
| 13894 return rc; | |
| 13895 } | |
| 13896 | |
| 13897 struct IdxSampleCtx { | |
| 13898 int iTarget; | |
| 13899 double target; /* Target nRet/nRow value */ | |
| 13900 double nRow; /* Number of rows seen */ | |
| 13901 double nRet; /* Number of rows returned */ | |
| 13902 }; | |
| 13903 | |
| 13904 static void idxSampleFunc( | |
| 13905 sqlite3_context *pCtx, | |
| 13906 int argc, | |
| 13907 sqlite3_value **argv | |
| 13908 ){ | |
| 13909 struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx); | |
| 13910 int bRet; | |
| 13911 | |
| 13912 (void)argv; | |
| 13913 assert( argc==0 ); | |
| 13914 if( p->nRow==0.0 ){ | |
| 13915 bRet = 1; | |
| 13916 }else{ | |
| 13917 bRet = (p->nRet / p->nRow) <= p->target; | |
| 13918 if( bRet==0 ){ | |
| 13919 unsigned short rnd; | |
| 13920 sqlite3_randomness(2, (void*)&rnd); | |
| 13921 bRet = ((int)rnd % 100) <= p->iTarget; | |
| 13922 } | |
| 13923 } | |
| 13924 | |
| 13925 sqlite3_result_int(pCtx, bRet); | |
| 13926 p->nRow += 1.0; | |
| 13927 p->nRet += (double)bRet; | |
| 13928 } | |
| 13929 | |
| 13930 struct IdxRemCtx { | |
| 13931 int nSlot; | |
| 13932 struct IdxRemSlot { | |
| 13933 int eType; /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */ | |
| 13934 i64 iVal; /* SQLITE_INTEGER value */ | |
| 13935 double rVal; /* SQLITE_FLOAT value */ | |
| 13936 i64 nByte; /* Bytes of space allocated at z */ | |
| 13937 i64 n; /* Size of buffer z */ | |
| 13938 char *z; /* SQLITE_TEXT/BLOB value */ | |
| 13939 } aSlot[1]; | |
| 13940 }; | |
| 13941 | |
| 13942 /* | |
| 13943 ** Implementation of scalar function sqlite_expert_rem(). | |
| 13944 */ | |
| 13945 static void idxRemFunc( | |
| 13946 sqlite3_context *pCtx, | |
| 13947 int argc, | |
| 13948 sqlite3_value **argv | |
| 13949 ){ | |
| 13950 struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx); | |
| 13951 struct IdxRemSlot *pSlot; | |
| 13952 int iSlot; | |
| 13953 assert( argc==2 ); | |
| 13954 | |
| 13955 iSlot = sqlite3_value_int(argv[0]); | |
| 13956 assert( iSlot<p->nSlot ); | |
| 13957 pSlot = &p->aSlot[iSlot]; | |
| 13958 | |
| 13959 switch( pSlot->eType ){ | |
| 13960 case SQLITE_NULL: | |
| 13961 /* no-op */ | |
| 13962 break; | |
| 13963 | |
| 13964 case SQLITE_INTEGER: | |
| 13965 sqlite3_result_int64(pCtx, pSlot->iVal); | |
| 13966 break; | |
| 13967 | |
| 13968 case SQLITE_FLOAT: | |
| 13969 sqlite3_result_double(pCtx, pSlot->rVal); | |
| 13970 break; | |
| 13971 | |
| 13972 case SQLITE_BLOB: | |
| 13973 assert( pSlot->n <= 0x7fffffff ); | |
| 13974 sqlite3_result_blob(pCtx, pSlot->z, (int)pSlot->n, SQLITE_TRANSIENT); | |
| 13975 break; | |
| 13976 | |
| 13977 case SQLITE_TEXT: | |
| 13978 assert( pSlot->n <= 0x7fffffff ); | |
| 13979 sqlite3_result_text(pCtx, pSlot->z, (int)pSlot->n, SQLITE_TRANSIENT); | |
| 13980 break; | |
| 13981 } | |
| 13982 | |
| 13983 pSlot->eType = sqlite3_value_type(argv[1]); | |
| 13984 switch( pSlot->eType ){ | |
| 13985 case SQLITE_NULL: | |
| 13986 /* no-op */ | |
| 13987 break; | |
| 13988 | |
| 13989 case SQLITE_INTEGER: | |
| 13990 pSlot->iVal = sqlite3_value_int64(argv[1]); | |
| 13991 break; | |
| 13992 | |
| 13993 case SQLITE_FLOAT: | |
| 13994 pSlot->rVal = sqlite3_value_double(argv[1]); | |
| 13995 break; | |
| 13996 | |
| 13997 case SQLITE_BLOB: | |
| 13998 case SQLITE_TEXT: { | |
| 13999 i64 nByte = sqlite3_value_bytes(argv[1]); | |
| 14000 const void *pData = 0; | |
| 14001 if( nByte>pSlot->nByte ){ | |
| 14002 char *zNew = (char*)sqlite3_realloc64(pSlot->z, nByte*2); | |
| 14003 if( zNew==0 ){ | |
| 14004 sqlite3_result_error_nomem(pCtx); | |
| 14005 return; | |
| 14006 } | |
| 14007 pSlot->nByte = nByte*2; | |
| 14008 pSlot->z = zNew; | |
| 14009 } | |
| 14010 pSlot->n = nByte; | |
| 14011 if( pSlot->eType==SQLITE_BLOB ){ | |
| 14012 pData = sqlite3_value_blob(argv[1]); | |
| 14013 if( pData ) memcpy(pSlot->z, pData, nByte); | |
| 14014 }else{ | |
| 14015 pData = sqlite3_value_text(argv[1]); | |
| 14016 memcpy(pSlot->z, pData, nByte); | |
| 14017 } | |
| 14018 break; | |
| 14019 } | |
| 14020 } | |
| 14021 } | |
| 14022 | |
| 14023 static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){ | |
| 14024 int rc = SQLITE_OK; | |
| 14025 const char *zMax = | |
| 14026 "SELECT max(i.seqno) FROM " | |
| 14027 " sqlite_schema AS s, " | |
| 14028 " pragma_index_list(s.name) AS l, " | |
| 14029 " pragma_index_info(l.name) AS i " | |
| 14030 "WHERE s.type = 'table'"; | |
| 14031 sqlite3_stmt *pMax = 0; | |
| 14032 | |
| 14033 *pnMax = 0; | |
| 14034 rc = idxPrepareStmt(db, &pMax, pzErr, zMax); | |
| 14035 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ | |
| 14036 *pnMax = sqlite3_column_int(pMax, 0) + 1; | |
| 14037 } | |
| 14038 idxFinalize(&rc, pMax); | |
| 14039 | |
| 14040 return rc; | |
| 14041 } | |
| 14042 | |
| 14043 static int idxPopulateOneStat1( | |
| 14044 sqlite3expert *p, | |
| 14045 sqlite3_stmt *pIndexXInfo, | |
| 14046 sqlite3_stmt *pWriteStat, | |
| 14047 const char *zTab, | |
| 14048 const char *zIdx, | |
| 14049 char **pzErr | |
| 14050 ){ | |
| 14051 char *zCols = 0; | |
| 14052 char *zOrder = 0; | |
| 14053 char *zQuery = 0; | |
| 14054 int nCol = 0; | |
| 14055 int i; | |
| 14056 sqlite3_stmt *pQuery = 0; | |
| 14057 i64 *aStat = 0; | |
| 14058 int rc = SQLITE_OK; | |
| 14059 | |
| 14060 assert( p->iSample>0 ); | |
| 14061 | |
| 14062 /* Formulate the query text */ | |
| 14063 sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC); | |
| 14064 while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){ | |
| 14065 const char *zComma = zCols==0 ? "" : ", "; | |
| 14066 const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0); | |
| 14067 const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1); | |
| 14068 if( zName==0 ){ | |
| 14069 /* This index contains an expression. Ignore it. */ | |
| 14070 sqlite3_free(zCols); | |
| 14071 sqlite3_free(zOrder); | |
| 14072 return sqlite3_reset(pIndexXInfo); | |
| 14073 } | |
| 14074 zCols = idxAppendText(&rc, zCols, | |
| 14075 "%sx.%Q IS sqlite_expert_rem(%d, x.%Q) COLLATE %s", | |
| 14076 zComma, zName, nCol, zName, zColl | |
| 14077 ); | |
| 14078 zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol); | |
| 14079 } | |
| 14080 sqlite3_reset(pIndexXInfo); | |
| 14081 if( rc==SQLITE_OK ){ | |
| 14082 if( p->iSample==100 ){ | |
| 14083 zQuery = sqlite3_mprintf( | |
| 14084 "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder | |
| 14085 ); | |
| 14086 }else{ | |
| 14087 zQuery = sqlite3_mprintf( | |
| 14088 "SELECT %s FROM temp."UNIQUE_TABLE_NAME" x ORDER BY %s", zCols, zOrder | |
| 14089 ); | |
| 14090 } | |
| 14091 } | |
| 14092 sqlite3_free(zCols); | |
| 14093 sqlite3_free(zOrder); | |
| 14094 | |
| 14095 /* Formulate the query text */ | |
| 14096 if( rc==SQLITE_OK ){ | |
| 14097 sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); | |
| 14098 rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery); | |
| 14099 } | |
| 14100 sqlite3_free(zQuery); | |
| 14101 | |
| 14102 if( rc==SQLITE_OK ){ | |
| 14103 aStat = (i64*)idxMalloc(&rc, sizeof(i64)*(nCol+1)); | |
| 14104 } | |
| 14105 if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){ | |
| 14106 IdxHashEntry *pEntry; | |
| 14107 char *zStat = 0; | |
| 14108 for(i=0; i<=nCol; i++) aStat[i] = 1; | |
| 14109 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){ | |
| 14110 aStat[0]++; | |
| 14111 for(i=0; i<nCol; i++){ | |
| 14112 if( sqlite3_column_int(pQuery, i)==0 ) break; | |
| 14113 } | |
| 14114 for(/*no-op*/; i<nCol; i++){ | |
| 14115 aStat[i+1]++; | |
| 14116 } | |
| 14117 } | |
| 14118 | |
| 14119 if( rc==SQLITE_OK ){ | |
| 14120 i64 s0 = aStat[0]; | |
| 14121 zStat = sqlite3_mprintf("%lld", s0); | |
| 14122 if( zStat==0 ) rc = SQLITE_NOMEM; | |
| 14123 for(i=1; rc==SQLITE_OK && i<=nCol; i++){ | |
| 14124 zStat = idxAppendText(&rc, zStat, " %lld", (s0+aStat[i]/2) / aStat[i]); | |
| 14125 } | |
| 14126 } | |
| 14127 | |
| 14128 if( rc==SQLITE_OK ){ | |
| 14129 sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC); | |
| 14130 sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC); | |
| 14131 sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC); | |
| 14132 sqlite3_step(pWriteStat); | |
| 14133 rc = sqlite3_reset(pWriteStat); | |
| 14134 } | |
| 14135 | |
| 14136 pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx)); | |
| 14137 if( pEntry ){ | |
| 14138 assert( pEntry->zVal2==0 ); | |
| 14139 pEntry->zVal2 = zStat; | |
| 14140 }else{ | |
| 14141 sqlite3_free(zStat); | |
| 14142 } | |
| 14143 } | |
| 14144 sqlite3_free(aStat); | |
| 14145 idxFinalize(&rc, pQuery); | |
| 14146 | |
| 14147 return rc; | |
| 14148 } | |
| 14149 | |
| 14150 static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){ | |
| 14151 int rc; | |
| 14152 char *zSql; | |
| 14153 | |
| 14154 rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); | |
| 14155 if( rc!=SQLITE_OK ) return rc; | |
| 14156 | |
| 14157 zSql = sqlite3_mprintf( | |
| 14158 "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q", zTab | |
| 14159 ); | |
| 14160 if( zSql==0 ) return SQLITE_NOMEM; | |
| 14161 rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0); | |
| 14162 sqlite3_free(zSql); | |
| 14163 | |
| 14164 return rc; | |
| 14165 } | |
| 14166 | |
| 14167 /* | |
| 14168 ** This function is called as part of sqlite3_expert_analyze(). Candidate | |
| 14169 ** indexes have already been created in database sqlite3expert.dbm, this | |
| 14170 ** function populates sqlite_stat1 table in the same database. | |
| 14171 ** | |
| 14172 ** The stat1 data is generated by querying the | |
| 14173 */ | |
| 14174 static int idxPopulateStat1(sqlite3expert *p, char **pzErr){ | |
| 14175 int rc = SQLITE_OK; | |
| 14176 int nMax =0; | |
| 14177 struct IdxRemCtx *pCtx = 0; | |
| 14178 struct IdxSampleCtx samplectx; | |
| 14179 int i; | |
| 14180 i64 iPrev = -100000; | |
| 14181 sqlite3_stmt *pAllIndex = 0; | |
| 14182 sqlite3_stmt *pIndexXInfo = 0; | |
| 14183 sqlite3_stmt *pWrite = 0; | |
| 14184 | |
| 14185 const char *zAllIndex = | |
| 14186 "SELECT s.rowid, s.name, l.name FROM " | |
| 14187 " sqlite_schema AS s, " | |
| 14188 " pragma_index_list(s.name) AS l " | |
| 14189 "WHERE s.type = 'table'"; | |
| 14190 const char *zIndexXInfo = | |
| 14191 "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key"; | |
| 14192 const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)"; | |
| 14193 | |
| 14194 /* If iSample==0, no sqlite_stat1 data is required. */ | |
| 14195 if( p->iSample==0 ) return SQLITE_OK; | |
| 14196 | |
| 14197 rc = idxLargestIndex(p->dbm, &nMax, pzErr); | |
| 14198 if( nMax<=0 || rc!=SQLITE_OK ) return rc; | |
| 14199 | |
| 14200 rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0); | |
| 14201 | |
| 14202 if( rc==SQLITE_OK ){ | |
| 14203 i64 nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax); | |
| 14204 pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte); | |
| 14205 } | |
| 14206 | |
| 14207 if( rc==SQLITE_OK ){ | |
| 14208 sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv); | |
| 14209 rc = sqlite3_create_function(dbrem, "sqlite_expert_rem", | |
| 14210 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0 | |
| 14211 ); | |
| 14212 } | |
| 14213 if( rc==SQLITE_OK ){ | |
| 14214 rc = sqlite3_create_function(p->db, "sqlite_expert_sample", | |
| 14215 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0 | |
| 14216 ); | |
| 14217 } | |
| 14218 | |
| 14219 if( rc==SQLITE_OK ){ | |
| 14220 pCtx->nSlot = (i64)nMax+1; | |
| 14221 rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex); | |
| 14222 } | |
| 14223 if( rc==SQLITE_OK ){ | |
| 14224 rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo); | |
| 14225 } | |
| 14226 if( rc==SQLITE_OK ){ | |
| 14227 rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite); | |
| 14228 } | |
| 14229 | |
| 14230 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){ | |
| 14231 i64 iRowid = sqlite3_column_int64(pAllIndex, 0); | |
| 14232 const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1); | |
| 14233 const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2); | |
| 14234 if( zTab==0 || zIdx==0 ) continue; | |
| 14235 if( p->iSample<100 && iPrev!=iRowid ){ | |
| 14236 samplectx.target = (double)p->iSample / 100.0; | |
| 14237 samplectx.iTarget = p->iSample; | |
| 14238 samplectx.nRow = 0.0; | |
| 14239 samplectx.nRet = 0.0; | |
| 14240 rc = idxBuildSampleTable(p, zTab); | |
| 14241 if( rc!=SQLITE_OK ) break; | |
| 14242 } | |
| 14243 rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr); | |
| 14244 iPrev = iRowid; | |
| 14245 } | |
| 14246 if( rc==SQLITE_OK && p->iSample<100 ){ | |
| 14247 rc = sqlite3_exec(p->dbv, | |
| 14248 "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0 | |
| 14249 ); | |
| 14250 } | |
| 14251 | |
| 14252 idxFinalize(&rc, pAllIndex); | |
| 14253 idxFinalize(&rc, pIndexXInfo); | |
| 14254 idxFinalize(&rc, pWrite); | |
| 14255 | |
| 14256 if( pCtx ){ | |
| 14257 for(i=0; i<pCtx->nSlot; i++){ | |
| 14258 sqlite3_free(pCtx->aSlot[i].z); | |
| 14259 } | |
| 14260 sqlite3_free(pCtx); | |
| 14261 } | |
| 14262 | |
| 14263 if( rc==SQLITE_OK ){ | |
| 14264 rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_schema", 0, 0, 0); | |
| 14265 } | |
| 14266 | |
| 14267 sqlite3_create_function(p->db, "sqlite_expert_rem", 2, SQLITE_UTF8, 0,0,0,0); | |
| 14268 sqlite3_create_function(p->db, "sqlite_expert_sample", 0,SQLITE_UTF8,0,0,0,0); | |
| 14269 | |
| 14270 sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0); | |
| 14271 return rc; | |
| 14272 } | |
| 14273 | |
| 14274 /* | |
| 14275 ** Define and possibly pretend to use a useless collation sequence. | |
| 14276 ** This pretense allows expert to accept SQL using custom collations. | |
| 14277 */ | |
| 14278 int dummyCompare(void *up1, int up2, const void *up3, int up4, const void *up5){ | |
| 14279 (void)up1; | |
| 14280 (void)up2; | |
| 14281 (void)up3; | |
| 14282 (void)up4; | |
| 14283 (void)up5; | |
| 14284 assert(0); /* VDBE should never be run. */ | |
| 14285 return 0; | |
| 14286 } | |
| 14287 /* And a callback to register above upon actual need */ | |
| 14288 void useDummyCS(void *up1, sqlite3 *db, int etr, const char *zName){ | |
| 14289 (void)up1; | |
| 14290 sqlite3_create_collation_v2(db, zName, etr, 0, dummyCompare, 0); | |
| 14291 } | |
| 14292 | |
| 14293 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) \ | |
| 14294 && !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) | |
| 14295 /* | |
| 14296 ** dummy functions for no-op implementation of UDFs during expert's work | |
| 14297 */ | |
| 14298 void dummyUDF(sqlite3_context *up1, int up2, sqlite3_value **up3){ | |
| 14299 (void)up1; | |
| 14300 (void)up2; | |
| 14301 (void)up3; | |
| 14302 assert(0); /* VDBE should never be run. */ | |
| 14303 } | |
| 14304 void dummyUDFvalue(sqlite3_context *up1){ | |
| 14305 (void)up1; | |
| 14306 assert(0); /* VDBE should never be run. */ | |
| 14307 } | |
| 14308 | |
| 14309 /* | |
| 14310 ** Register UDFs from user database with another. | |
| 14311 */ | |
| 14312 int registerUDFs(sqlite3 *dbSrc, sqlite3 *dbDst){ | |
| 14313 sqlite3_stmt *pStmt; | |
| 14314 int rc = sqlite3_prepare_v2(dbSrc, | |
| 14315 "SELECT name,type,enc,narg,flags " | |
| 14316 "FROM pragma_function_list() " | |
| 14317 "WHERE builtin==0", -1, &pStmt, 0); | |
| 14318 if( rc==SQLITE_OK ){ | |
| 14319 while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ | |
| 14320 int nargs = sqlite3_column_int(pStmt,3); | |
| 14321 int flags = sqlite3_column_int(pStmt,4); | |
| 14322 const char *name = (char*)sqlite3_column_text(pStmt,0); | |
| 14323 const char *type = (char*)sqlite3_column_text(pStmt,1); | |
| 14324 const char *enc = (char*)sqlite3_column_text(pStmt,2); | |
| 14325 if( name==0 || type==0 || enc==0 ){ | |
| 14326 /* no-op. Only happens on OOM */ | |
| 14327 }else{ | |
| 14328 int ienc = SQLITE_UTF8; | |
| 14329 int rcf = SQLITE_ERROR; | |
| 14330 if( strcmp(enc,"utf16le")==0 ) ienc = SQLITE_UTF16LE; | |
| 14331 else if( strcmp(enc,"utf16be")==0 ) ienc = SQLITE_UTF16BE; | |
| 14332 ienc |= (flags & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY)); | |
| 14333 if( strcmp(type,"w")==0 ){ | |
| 14334 rcf = sqlite3_create_window_function(dbDst,name,nargs,ienc,0, | |
| 14335 dummyUDF,dummyUDFvalue,0,0,0); | |
| 14336 }else if( strcmp(type,"a")==0 ){ | |
| 14337 rcf = sqlite3_create_function(dbDst,name,nargs,ienc,0, | |
| 14338 0,dummyUDF,dummyUDFvalue); | |
| 14339 }else if( strcmp(type,"s")==0 ){ | |
| 14340 rcf = sqlite3_create_function(dbDst,name,nargs,ienc,0, | |
| 14341 dummyUDF,0,0); | |
| 14342 } | |
| 14343 if( rcf!=SQLITE_OK ){ | |
| 14344 rc = rcf; | |
| 14345 break; | |
| 14346 } | |
| 14347 } | |
| 14348 } | |
| 14349 sqlite3_finalize(pStmt); | |
| 14350 if( rc==SQLITE_DONE ) rc = SQLITE_OK; | |
| 14351 } | |
| 14352 return rc; | |
| 14353 } | |
| 14354 #endif | |
| 14355 | |
| 14356 /* | |
| 14357 ** Allocate a new sqlite3expert object. | |
| 14358 */ | |
| 14359 sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){ | |
| 14360 int rc = SQLITE_OK; | |
| 14361 sqlite3expert *pNew; | |
| 14362 | |
| 14363 pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert)); | |
| 14364 | |
| 14365 /* Open two in-memory databases to work with. The "vtab database" (dbv) | |
| 14366 ** will contain a virtual table corresponding to each real table in | |
| 14367 ** the user database schema, and a copy of each view. It is used to | |
| 14368 ** collect information regarding the WHERE, ORDER BY and other clauses | |
| 14369 ** of the user's query. | |
| 14370 */ | |
| 14371 if( rc==SQLITE_OK ){ | |
| 14372 pNew->db = db; | |
| 14373 pNew->iSample = 100; | |
| 14374 rc = sqlite3_open(":memory:", &pNew->dbv); | |
| 14375 } | |
| 14376 if( rc==SQLITE_OK ){ | |
| 14377 rc = sqlite3_open(":memory:", &pNew->dbm); | |
| 14378 if( rc==SQLITE_OK ){ | |
| 14379 sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0); | |
| 14380 } | |
| 14381 } | |
| 14382 | |
| 14383 /* Allow custom collations to be dealt with through prepare. */ | |
| 14384 if( rc==SQLITE_OK ) rc = sqlite3_collation_needed(pNew->dbm,0,useDummyCS); | |
| 14385 if( rc==SQLITE_OK ) rc = sqlite3_collation_needed(pNew->dbv,0,useDummyCS); | |
| 14386 | |
| 14387 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) \ | |
| 14388 && !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) | |
| 14389 /* Register UDFs from database [db] with [dbm] and [dbv]. */ | |
| 14390 if( rc==SQLITE_OK ){ | |
| 14391 rc = registerUDFs(pNew->db, pNew->dbm); | |
| 14392 } | |
| 14393 if( rc==SQLITE_OK ){ | |
| 14394 rc = registerUDFs(pNew->db, pNew->dbv); | |
| 14395 } | |
| 14396 #endif | |
| 14397 | |
| 14398 /* Copy the entire schema of database [db] into [dbm]. */ | |
| 14399 if( rc==SQLITE_OK ){ | |
| 14400 sqlite3_stmt *pSql = 0; | |
| 14401 rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, | |
| 14402 "SELECT sql, name, substr(sql,1,14)=='create virtual' COLLATE nocase" | |
| 14403 " FROM sqlite_schema WHERE substr(name,1,7)!='sqlite_' COLLATE nocase" | |
| 14404 " ORDER BY 3 DESC, rowid" | |
| 14405 ); | |
| 14406 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ | |
| 14407 const char *zSql = (const char*)sqlite3_column_text(pSql, 0); | |
| 14408 const char *zName = (const char*)sqlite3_column_text(pSql, 1); | |
| 14409 int bExists = 0; | |
| 14410 rc = expertDbContainsObject(pNew->dbm, zName, &bExists); | |
| 14411 if( rc==SQLITE_OK && zSql && bExists==0 ){ | |
| 14412 rc = expertSchemaSql(pNew->dbm, zSql, pzErrmsg); | |
| 14413 } | |
| 14414 } | |
| 14415 idxFinalize(&rc, pSql); | |
| 14416 } | |
| 14417 | |
| 14418 /* Create the vtab schema */ | |
| 14419 if( rc==SQLITE_OK ){ | |
| 14420 rc = idxCreateVtabSchema(pNew, pzErrmsg); | |
| 14421 } | |
| 14422 | |
| 14423 /* Register the auth callback with dbv */ | |
| 14424 if( rc==SQLITE_OK ){ | |
| 14425 sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew); | |
| 14426 } | |
| 14427 | |
| 14428 /* If an error has occurred, free the new object and return NULL. Otherwise, | |
| 14429 ** return the new sqlite3expert handle. */ | |
| 14430 if( rc!=SQLITE_OK ){ | |
| 14431 sqlite3_expert_destroy(pNew); | |
| 14432 pNew = 0; | |
| 14433 } | |
| 14434 return pNew; | |
| 14435 } | |
| 14436 | |
| 14437 /* | |
| 14438 ** Configure an sqlite3expert object. | |
| 14439 */ | |
| 14440 int sqlite3_expert_config(sqlite3expert *p, int op, ...){ | |
| 14441 int rc = SQLITE_OK; | |
| 14442 va_list ap; | |
| 14443 va_start(ap, op); | |
| 14444 switch( op ){ | |
| 14445 case EXPERT_CONFIG_SAMPLE: { | |
| 14446 int iVal = va_arg(ap, int); | |
| 14447 if( iVal<0 ) iVal = 0; | |
| 14448 if( iVal>100 ) iVal = 100; | |
| 14449 p->iSample = iVal; | |
| 14450 break; | |
| 14451 } | |
| 14452 default: | |
| 14453 rc = SQLITE_NOTFOUND; | |
| 14454 break; | |
| 14455 } | |
| 14456 | |
| 14457 va_end(ap); | |
| 14458 return rc; | |
| 14459 } | |
| 14460 | |
| 14461 /* | |
| 14462 ** Add an SQL statement to the analysis. | |
| 14463 */ | |
| 14464 int sqlite3_expert_sql( | |
| 14465 sqlite3expert *p, /* From sqlite3_expert_new() */ | |
| 14466 const char *zSql, /* SQL statement to add */ | |
| 14467 char **pzErr /* OUT: Error message (if any) */ | |
| 14468 ){ | |
| 14469 IdxScan *pScanOrig = p->pScan; | |
| 14470 IdxStatement *pStmtOrig = p->pStatement; | |
| 14471 int rc = SQLITE_OK; | |
| 14472 const char *zStmt = zSql; | |
| 14473 | |
| 14474 if( p->bRun ) return SQLITE_MISUSE; | |
| 14475 | |
| 14476 while( rc==SQLITE_OK && zStmt && zStmt[0] ){ | |
| 14477 sqlite3_stmt *pStmt = 0; | |
| 14478 /* Ensure that the provided statement compiles against user's DB. */ | |
| 14479 rc = idxPrepareStmt(p->db, &pStmt, pzErr, zStmt); | |
| 14480 if( rc!=SQLITE_OK ) break; | |
| 14481 sqlite3_finalize(pStmt); | |
| 14482 rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt); | |
| 14483 if( rc==SQLITE_OK ){ | |
| 14484 if( pStmt ){ | |
| 14485 IdxStatement *pNew; | |
| 14486 const char *z = sqlite3_sql(pStmt); | |
| 14487 i64 n = STRLEN(z); | |
| 14488 pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1); | |
| 14489 if( rc==SQLITE_OK ){ | |
| 14490 pNew->zSql = (char*)&pNew[1]; | |
| 14491 memcpy(pNew->zSql, z, n+1); | |
| 14492 pNew->pNext = p->pStatement; | |
| 14493 if( p->pStatement ) pNew->iId = p->pStatement->iId+1; | |
| 14494 p->pStatement = pNew; | |
| 14495 } | |
| 14496 sqlite3_finalize(pStmt); | |
| 14497 } | |
| 14498 }else{ | |
| 14499 idxDatabaseError(p->dbv, pzErr); | |
| 14500 } | |
| 14501 } | |
| 14502 | |
| 14503 if( rc!=SQLITE_OK ){ | |
| 14504 idxScanFree(p->pScan, pScanOrig); | |
| 14505 idxStatementFree(p->pStatement, pStmtOrig); | |
| 14506 p->pScan = pScanOrig; | |
| 14507 p->pStatement = pStmtOrig; | |
| 14508 } | |
| 14509 | |
| 14510 return rc; | |
| 14511 } | |
| 14512 | |
| 14513 int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){ | |
| 14514 int rc; | |
| 14515 IdxHashEntry *pEntry; | |
| 14516 | |
| 14517 /* Do trigger processing to collect any extra IdxScan structures */ | |
| 14518 rc = idxProcessTriggers(p, pzErr); | |
| 14519 | |
| 14520 /* Create candidate indexes within the in-memory database file */ | |
| 14521 if( rc==SQLITE_OK ){ | |
| 14522 rc = idxCreateCandidates(p); | |
| 14523 }else if ( rc==SQLITE_BUSY_TIMEOUT ){ | |
| 14524 if( pzErr ) | |
| 14525 *pzErr = sqlite3_mprintf("Cannot find a unique index name to propose."); | |
| 14526 return rc; | |
| 14527 } | |
| 14528 | |
| 14529 /* Generate the stat1 data */ | |
| 14530 if( rc==SQLITE_OK ){ | |
| 14531 rc = idxPopulateStat1(p, pzErr); | |
| 14532 } | |
| 14533 | |
| 14534 /* Formulate the EXPERT_REPORT_CANDIDATES text */ | |
| 14535 for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){ | |
| 14536 p->zCandidates = idxAppendText(&rc, p->zCandidates, | |
| 14537 "%s;%s%s\n", pEntry->zVal, | |
| 14538 pEntry->zVal2 ? " -- stat1: " : "", pEntry->zVal2 | |
| 14539 ); | |
| 14540 } | |
| 14541 | |
| 14542 /* Figure out which of the candidate indexes are preferred by the query | |
| 14543 ** planner and report the results to the user. */ | |
| 14544 if( rc==SQLITE_OK ){ | |
| 14545 rc = idxFindIndexes(p, pzErr); | |
| 14546 } | |
| 14547 | |
| 14548 if( rc==SQLITE_OK ){ | |
| 14549 p->bRun = 1; | |
| 14550 } | |
| 14551 return rc; | |
| 14552 } | |
| 14553 | |
| 14554 /* | |
| 14555 ** Return the total number of statements that have been added to this | |
| 14556 ** sqlite3expert using sqlite3_expert_sql(). | |
| 14557 */ | |
| 14558 int sqlite3_expert_count(sqlite3expert *p){ | |
| 14559 int nRet = 0; | |
| 14560 if( p->pStatement ) nRet = p->pStatement->iId+1; | |
| 14561 return nRet; | |
| 14562 } | |
| 14563 | |
| 14564 /* | |
| 14565 ** Return a component of the report. | |
| 14566 */ | |
| 14567 const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){ | |
| 14568 const char *zRet = 0; | |
| 14569 IdxStatement *pStmt; | |
| 14570 | |
| 14571 if( p->bRun==0 ) return 0; | |
| 14572 for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext); | |
| 14573 switch( eReport ){ | |
| 14574 case EXPERT_REPORT_SQL: | |
| 14575 if( pStmt ) zRet = pStmt->zSql; | |
| 14576 break; | |
| 14577 case EXPERT_REPORT_INDEXES: | |
| 14578 if( pStmt ) zRet = pStmt->zIdx; | |
| 14579 break; | |
| 14580 case EXPERT_REPORT_PLAN: | |
| 14581 if( pStmt ) zRet = pStmt->zEQP; | |
| 14582 break; | |
| 14583 case EXPERT_REPORT_CANDIDATES: | |
| 14584 zRet = p->zCandidates; | |
| 14585 break; | |
| 14586 } | |
| 14587 return zRet; | |
| 14588 } | |
| 14589 | |
| 14590 /* | |
| 14591 ** Free an sqlite3expert object. | |
| 14592 */ | |
| 14593 void sqlite3_expert_destroy(sqlite3expert *p){ | |
| 14594 if( p ){ | |
| 14595 sqlite3_close(p->dbm); | |
| 14596 sqlite3_close(p->dbv); | |
| 14597 idxScanFree(p->pScan, 0); | |
| 14598 idxStatementFree(p->pStatement, 0); | |
| 14599 idxTableFree(p->pTable); | |
| 14600 idxWriteFree(p->pWrite); | |
| 14601 idxHashClear(&p->hIdx); | |
| 14602 sqlite3_free(p->zCandidates); | |
| 14603 sqlite3_free(p); | |
| 14604 } | |
| 14605 } | |
| 14606 | |
| 14607 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ | |
| 14608 | |
| 14609 /************************* End ../ext/expert/sqlite3expert.c ********************/ | |
| 14610 #endif | |
| 14611 /************************* Begin ../ext/intck/sqlite3intck.h ******************/ | |
| 14612 /* | |
| 14613 ** 2024-02-08 | |
| 14614 ** | |
| 14615 ** The author disclaims copyright to this source code. In place of | |
| 14616 ** a legal notice, here is a blessing: | |
| 14617 ** | |
| 14618 ** May you do good and not evil. | |
| 14619 ** May you find forgiveness for yourself and forgive others. | |
| 14620 ** May you share freely, never taking more than you give. | |
| 14621 ** | |
| 14622 ************************************************************************* | |
| 14623 */ | |
| 14624 | |
| 14625 /* | |
| 14626 ** Incremental Integrity-Check Extension | |
| 14627 ** ------------------------------------- | |
| 14628 ** | |
| 14629 ** This module contains code to check whether or not an SQLite database | |
| 14630 ** is well-formed or corrupt. This is the same task as performed by SQLite's | |
| 14631 ** built-in "PRAGMA integrity_check" command. This module differs from | |
| 14632 ** "PRAGMA integrity_check" in that: | |
| 14633 ** | |
| 14634 ** + It is less thorough - this module does not detect certain types | |
| 14635 ** of corruption that are detected by the PRAGMA command. However, | |
| 14636 ** it does detect all kinds of corruption that are likely to cause | |
| 14637 ** errors in SQLite applications. | |
| 14638 ** | |
| 14639 ** + It is slower. Sometimes up to three times slower. | |
| 14640 ** | |
| 14641 ** + It allows integrity-check operations to be split into multiple | |
| 14642 ** transactions, so that the database does not need to be read-locked | |
| 14643 ** for the duration of the integrity-check. | |
| 14644 ** | |
| 14645 ** One way to use the API to run integrity-check on the "main" database | |
| 14646 ** of handle db is: | |
| 14647 ** | |
| 14648 ** int rc = SQLITE_OK; | |
| 14649 ** sqlite3_intck *p = 0; | |
| 14650 ** | |
| 14651 ** sqlite3_intck_open(db, "main", &p); | |
| 14652 ** while( SQLITE_OK==sqlite3_intck_step(p) ){ | |
| 14653 ** const char *zMsg = sqlite3_intck_message(p); | |
| 14654 ** if( zMsg ) printf("corruption: %s\n", zMsg); | |
| 14655 ** } | |
| 14656 ** rc = sqlite3_intck_error(p, &zErr); | |
| 14657 ** if( rc!=SQLITE_OK ){ | |
| 14658 ** printf("error occured (rc=%d), (errmsg=%s)\n", rc, zErr); | |
| 14659 ** } | |
| 14660 ** sqlite3_intck_close(p); | |
| 14661 ** | |
| 14662 ** Usually, the sqlite3_intck object opens a read transaction within the | |
| 14663 ** first call to sqlite3_intck_step() and holds it open until the | |
| 14664 ** integrity-check is complete. However, if sqlite3_intck_unlock() is | |
| 14665 ** called, the read transaction is ended and a new read transaction opened | |
| 14666 ** by the subsequent call to sqlite3_intck_step(). | |
| 14667 */ | |
| 14668 | |
| 14669 #ifndef _SQLITE_INTCK_H | |
| 14670 #define _SQLITE_INTCK_H | |
| 14671 | |
| 14672 /* #include "sqlite3.h" */ | |
| 14673 | |
| 14674 #ifdef __cplusplus | |
| 14675 extern "C" { | |
| 14676 #endif | |
| 14677 | |
| 14678 /* | |
| 14679 ** An ongoing incremental integrity-check operation is represented by an | |
| 14680 ** opaque pointer of the following type. | |
| 14681 */ | |
| 14682 typedef struct sqlite3_intck sqlite3_intck; | |
| 14683 | |
| 14684 /* | |
| 14685 ** Open a new incremental integrity-check object. If successful, populate | |
| 14686 ** output variable (*ppOut) with the new object handle and return SQLITE_OK. | |
| 14687 ** Or, if an error occurs, set (*ppOut) to NULL and return an SQLite error | |
| 14688 ** code (e.g. SQLITE_NOMEM). | |
| 14689 ** | |
| 14690 ** The integrity-check will be conducted on database zDb (which must be "main", | |
| 14691 ** "temp", or the name of an attached database) of database handle db. Once | |
| 14692 ** this function has been called successfully, the caller should not use | |
| 14693 ** database handle db until the integrity-check object has been destroyed | |
| 14694 ** using sqlite3_intck_close(). | |
| 14695 */ | |
| 14696 int sqlite3_intck_open( | |
| 14697 sqlite3 *db, /* Database handle */ | |
| 14698 const char *zDb, /* Database name ("main", "temp" etc.) */ | |
| 14699 sqlite3_intck **ppOut /* OUT: New sqlite3_intck handle */ | |
| 14700 ); | |
| 14701 | |
| 14702 /* | |
| 14703 ** Close and release all resources associated with a handle opened by an | |
| 14704 ** earlier call to sqlite3_intck_open(). The results of using an | |
| 14705 ** integrity-check handle after it has been passed to this function are | |
| 14706 ** undefined. | |
| 14707 */ | |
| 14708 void sqlite3_intck_close(sqlite3_intck *pCk); | |
| 14709 | |
| 14710 /* | |
| 14711 ** Do the next step of the integrity-check operation specified by the handle | |
| 14712 ** passed as the only argument. This function returns SQLITE_DONE if the | |
| 14713 ** integrity-check operation is finished, or an SQLite error code if | |
| 14714 ** an error occurs, or SQLITE_OK if no error occurs but the integrity-check | |
| 14715 ** is not finished. It is not considered an error if database corruption | |
| 14716 ** is encountered. | |
| 14717 ** | |
| 14718 ** Following a successful call to sqlite3_intck_step() (one that returns | |
| 14719 ** SQLITE_OK), sqlite3_intck_message() returns a non-NULL value if | |
| 14720 ** corruption was detected in the db. | |
| 14721 ** | |
| 14722 ** If an error occurs and a value other than SQLITE_OK or SQLITE_DONE is | |
| 14723 ** returned, then the integrity-check handle is placed in an error state. | |
| 14724 ** In this state all subsequent calls to sqlite3_intck_step() or | |
| 14725 ** sqlite3_intck_unlock() will immediately return the same error. The | |
| 14726 ** sqlite3_intck_error() method may be used to obtain an English language | |
| 14727 ** error message in this case. | |
| 14728 */ | |
| 14729 int sqlite3_intck_step(sqlite3_intck *pCk); | |
| 14730 | |
| 14731 /* | |
| 14732 ** If the previous call to sqlite3_intck_step() encountered corruption | |
| 14733 ** within the database, then this function returns a pointer to a buffer | |
| 14734 ** containing a nul-terminated string describing the corruption in | |
| 14735 ** English. If the previous call to sqlite3_intck_step() did not encounter | |
| 14736 ** corruption, or if there was no previous call, this function returns | |
| 14737 ** NULL. | |
| 14738 */ | |
| 14739 const char *sqlite3_intck_message(sqlite3_intck *pCk); | |
| 14740 | |
| 14741 /* | |
| 14742 ** Close any read-transaction opened by an earlier call to | |
| 14743 ** sqlite3_intck_step(). Any subsequent call to sqlite3_intck_step() will | |
| 14744 ** open a new transaction. Return SQLITE_OK if successful, or an SQLite error | |
| 14745 ** code otherwise. | |
| 14746 ** | |
| 14747 ** If an error occurs, then the integrity-check handle is placed in an error | |
| 14748 ** state. In this state all subsequent calls to sqlite3_intck_step() or | |
| 14749 ** sqlite3_intck_unlock() will immediately return the same error. The | |
| 14750 ** sqlite3_intck_error() method may be used to obtain an English language | |
| 14751 ** error message in this case. | |
| 14752 */ | |
| 14753 int sqlite3_intck_unlock(sqlite3_intck *pCk); | |
| 14754 | |
| 14755 /* | |
| 14756 ** If an error has occurred in an earlier call to sqlite3_intck_step() | |
| 14757 ** or sqlite3_intck_unlock(), then this method returns the associated | |
| 14758 ** SQLite error code. Additionally, if pzErr is not NULL, then (*pzErr) | |
| 14759 ** may be set to point to a nul-terminated string containing an English | |
| 14760 ** language error message. Or, if no error message is available, to | |
| 14761 ** NULL. | |
| 14762 ** | |
| 14763 ** If no error has occurred within sqlite3_intck_step() or | |
| 14764 ** sqlite_intck_unlock() calls on the handle passed as the first argument, | |
| 14765 ** then SQLITE_OK is returned and (*pzErr) set to NULL. | |
| 14766 */ | |
| 14767 int sqlite3_intck_error(sqlite3_intck *pCk, const char **pzErr); | |
| 14768 | |
| 14769 /* | |
| 14770 ** This API is used for testing only. It returns the full-text of an SQL | |
| 14771 ** statement used to test object zObj, which may be a table or index. | |
| 14772 ** The returned buffer is valid until the next call to either this function | |
| 14773 ** or sqlite3_intck_close() on the same sqlite3_intck handle. | |
| 14774 */ | |
| 14775 const char *sqlite3_intck_test_sql(sqlite3_intck *pCk, const char *zObj); | |
| 14776 | |
| 14777 | |
| 14778 #ifdef __cplusplus | |
| 14779 } /* end of the 'extern "C"' block */ | |
| 14780 #endif | |
| 14781 | |
| 14782 #endif /* ifndef _SQLITE_INTCK_H */ | |
| 14783 | |
| 14784 /************************* End ../ext/intck/sqlite3intck.h ********************/ | |
| 14785 /************************* Begin ../ext/intck/sqlite3intck.c ******************/ | |
| 14786 /* | |
| 14787 ** 2024-02-08 | |
| 14788 ** | |
| 14789 ** The author disclaims copyright to this source code. In place of | |
| 14790 ** a legal notice, here is a blessing: | |
| 14791 ** | |
| 14792 ** May you do good and not evil. | |
| 14793 ** May you find forgiveness for yourself and forgive others. | |
| 14794 ** May you share freely, never taking more than you give. | |
| 14795 ** | |
| 14796 ************************************************************************* | |
| 14797 */ | |
| 14798 | |
| 14799 /* #include "sqlite3intck.h" */ | |
| 14800 #include <string.h> | |
| 14801 #include <assert.h> | |
| 14802 | |
| 14803 #include <stdio.h> | |
| 14804 #include <stdlib.h> | |
| 14805 | |
| 14806 /* | |
| 14807 ** nKeyVal: | |
| 14808 ** The number of values that make up the 'key' for the current pCheck | |
| 14809 ** statement. | |
| 14810 ** | |
| 14811 ** rc: | |
| 14812 ** Error code returned by most recent sqlite3_intck_step() or | |
| 14813 ** sqlite3_intck_unlock() call. This is set to SQLITE_DONE when | |
| 14814 ** the integrity-check operation is finished. | |
| 14815 ** | |
| 14816 ** zErr: | |
| 14817 ** If the object has entered the error state, this is the error message. | |
| 14818 ** Is freed using sqlite3_free() when the object is deleted. | |
| 14819 ** | |
| 14820 ** zTestSql: | |
| 14821 ** The value returned by the most recent call to sqlite3_intck_testsql(). | |
| 14822 ** Each call to testsql() frees the previous zTestSql value (using | |
| 14823 ** sqlite3_free()) and replaces it with the new value it will return. | |
| 14824 */ | |
| 14825 struct sqlite3_intck { | |
| 14826 sqlite3 *db; | |
| 14827 const char *zDb; /* Copy of zDb parameter to _open() */ | |
| 14828 char *zObj; /* Current object. Or NULL. */ | |
| 14829 | |
| 14830 sqlite3_stmt *pCheck; /* Current check statement */ | |
| 14831 char *zKey; | |
| 14832 int nKeyVal; | |
| 14833 | |
| 14834 char *zMessage; | |
| 14835 int bCorruptSchema; | |
| 14836 | |
| 14837 int rc; /* Error code */ | |
| 14838 char *zErr; /* Error message */ | |
| 14839 char *zTestSql; /* Returned by sqlite3_intck_test_sql() */ | |
| 14840 }; | |
| 14841 | |
| 14842 | |
| 14843 /* | |
| 14844 ** Some error has occurred while using database p->db. Save the error message | |
| 14845 ** and error code currently held by the database handle in p->rc and p->zErr. | |
| 14846 */ | |
| 14847 static void intckSaveErrmsg(sqlite3_intck *p){ | |
| 14848 p->rc = sqlite3_errcode(p->db); | |
| 14849 sqlite3_free(p->zErr); | |
| 14850 p->zErr = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); | |
| 14851 } | |
| 14852 | |
| 14853 /* | |
| 14854 ** If the handle passed as the first argument is already in the error state, | |
| 14855 ** then this function is a no-op (returns NULL immediately). Otherwise, if an | |
| 14856 ** error occurs within this function, it leaves an error in said handle. | |
| 14857 ** | |
| 14858 ** Otherwise, this function attempts to prepare SQL statement zSql and | |
| 14859 ** return the resulting statement handle to the user. | |
| 14860 */ | |
| 14861 static sqlite3_stmt *intckPrepare(sqlite3_intck *p, const char *zSql){ | |
| 14862 sqlite3_stmt *pRet = 0; | |
| 14863 if( p->rc==SQLITE_OK ){ | |
| 14864 p->rc = sqlite3_prepare_v2(p->db, zSql, -1, &pRet, 0); | |
| 14865 if( p->rc!=SQLITE_OK ){ | |
| 14866 intckSaveErrmsg(p); | |
| 14867 assert( pRet==0 ); | |
| 14868 } | |
| 14869 } | |
| 14870 return pRet; | |
| 14871 } | |
| 14872 | |
| 14873 /* | |
| 14874 ** If the handle passed as the first argument is already in the error state, | |
| 14875 ** then this function is a no-op (returns NULL immediately). Otherwise, if an | |
| 14876 ** error occurs within this function, it leaves an error in said handle. | |
| 14877 ** | |
| 14878 ** Otherwise, this function treats argument zFmt as a printf() style format | |
| 14879 ** string. It formats it according to the trailing arguments and then | |
| 14880 ** attempts to prepare the results and return the resulting prepared | |
| 14881 ** statement. | |
| 14882 */ | |
| 14883 static sqlite3_stmt *intckPrepareFmt(sqlite3_intck *p, const char *zFmt, ...){ | |
| 14884 sqlite3_stmt *pRet = 0; | |
| 14885 va_list ap; | |
| 14886 char *zSql = 0; | |
| 14887 va_start(ap, zFmt); | |
| 14888 zSql = sqlite3_vmprintf(zFmt, ap); | |
| 14889 if( p->rc==SQLITE_OK && zSql==0 ){ | |
| 14890 p->rc = SQLITE_NOMEM; | |
| 14891 } | |
| 14892 pRet = intckPrepare(p, zSql); | |
| 14893 sqlite3_free(zSql); | |
| 14894 va_end(ap); | |
| 14895 return pRet; | |
| 14896 } | |
| 14897 | |
| 14898 /* | |
| 14899 ** Finalize SQL statement pStmt. If an error occurs and the handle passed | |
| 14900 ** as the first argument does not already contain an error, store the | |
| 14901 ** error in the handle. | |
| 14902 */ | |
| 14903 static void intckFinalize(sqlite3_intck *p, sqlite3_stmt *pStmt){ | |
| 14904 int rc = sqlite3_finalize(pStmt); | |
| 14905 if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){ | |
| 14906 intckSaveErrmsg(p); | |
| 14907 } | |
| 14908 } | |
| 14909 | |
| 14910 /* | |
| 14911 ** If there is already an error in handle p, return it. Otherwise, call | |
| 14912 ** sqlite3_step() on the statement handle and return that value. | |
| 14913 */ | |
| 14914 static int intckStep(sqlite3_intck *p, sqlite3_stmt *pStmt){ | |
| 14915 if( p->rc ) return p->rc; | |
| 14916 return sqlite3_step(pStmt); | |
| 14917 } | |
| 14918 | |
| 14919 /* | |
| 14920 ** Execute SQL statement zSql. There is no way to obtain any results | |
| 14921 ** returned by the statement. This function uses the sqlite3_intck error | |
| 14922 ** code convention. | |
| 14923 */ | |
| 14924 static void intckExec(sqlite3_intck *p, const char *zSql){ | |
| 14925 sqlite3_stmt *pStmt = 0; | |
| 14926 pStmt = intckPrepare(p, zSql); | |
| 14927 intckStep(p, pStmt); | |
| 14928 intckFinalize(p, pStmt); | |
| 14929 } | |
| 14930 | |
| 14931 /* | |
| 14932 ** A wrapper around sqlite3_mprintf() that uses the sqlite3_intck error | |
| 14933 ** code convention. | |
| 14934 */ | |
| 14935 static char *intckMprintf(sqlite3_intck *p, const char *zFmt, ...){ | |
| 14936 va_list ap; | |
| 14937 char *zRet = 0; | |
| 14938 va_start(ap, zFmt); | |
| 14939 zRet = sqlite3_vmprintf(zFmt, ap); | |
| 14940 if( p->rc==SQLITE_OK ){ | |
| 14941 if( zRet==0 ){ | |
| 14942 p->rc = SQLITE_NOMEM; | |
| 14943 } | |
| 14944 }else{ | |
| 14945 sqlite3_free(zRet); | |
| 14946 zRet = 0; | |
| 14947 } | |
| 14948 va_end(ap); | |
| 14949 return zRet; | |
| 14950 } | |
| 14951 | |
| 14952 /* | |
| 14953 ** This is used by sqlite3_intck_unlock() to save the vector key value | |
| 14954 ** required to restart the current pCheck query as a nul-terminated string | |
| 14955 ** in p->zKey. | |
| 14956 */ | |
| 14957 static void intckSaveKey(sqlite3_intck *p){ | |
| 14958 int ii; | |
| 14959 char *zSql = 0; | |
| 14960 sqlite3_stmt *pStmt = 0; | |
| 14961 sqlite3_stmt *pXinfo = 0; | |
| 14962 const char *zDir = 0; | |
| 14963 | |
| 14964 assert( p->pCheck ); | |
| 14965 assert( p->zKey==0 ); | |
| 14966 | |
| 14967 pXinfo = intckPrepareFmt(p, | |
| 14968 "SELECT group_concat(desc, '') FROM %Q.sqlite_schema s, " | |
| 14969 "pragma_index_xinfo(%Q, %Q) " | |
| 14970 "WHERE s.type='index' AND s.name=%Q", | |
| 14971 p->zDb, p->zObj, p->zDb, p->zObj | |
| 14972 ); | |
| 14973 if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXinfo) ){ | |
| 14974 zDir = (const char*)sqlite3_column_text(pXinfo, 0); | |
| 14975 } | |
| 14976 | |
| 14977 if( zDir==0 ){ | |
| 14978 /* Object is a table, not an index. This is the easy case,as there are | |
| 14979 ** no DESC columns or NULL values in a primary key. */ | |
| 14980 const char *zSep = "SELECT '(' || "; | |
| 14981 for(ii=0; ii<p->nKeyVal; ii++){ | |
| 14982 zSql = intckMprintf(p, "%z%squote(?)", zSql, zSep); | |
| 14983 zSep = " || ', ' || "; | |
| 14984 } | |
| 14985 zSql = intckMprintf(p, "%z || ')'", zSql); | |
| 14986 }else{ | |
| 14987 | |
| 14988 /* Object is an index. */ | |
| 14989 assert( p->nKeyVal>1 ); | |
| 14990 for(ii=p->nKeyVal; ii>0; ii--){ | |
| 14991 int bLastIsDesc = zDir[ii-1]=='1'; | |
| 14992 int bLastIsNull = sqlite3_column_type(p->pCheck, ii)==SQLITE_NULL; | |
| 14993 const char *zLast = sqlite3_column_name(p->pCheck, ii); | |
| 14994 char *zLhs = 0; | |
| 14995 char *zRhs = 0; | |
| 14996 char *zWhere = 0; | |
| 14997 | |
| 14998 if( bLastIsNull ){ | |
| 14999 if( bLastIsDesc ) continue; | |
| 15000 zWhere = intckMprintf(p, "'%s IS NOT NULL'", zLast); | |
| 15001 }else{ | |
| 15002 const char *zOp = bLastIsDesc ? "<" : ">"; | |
| 15003 zWhere = intckMprintf(p, "'%s %s ' || quote(?%d)", zLast, zOp, ii); | |
| 15004 } | |
| 15005 | |
| 15006 if( ii>1 ){ | |
| 15007 const char *zLhsSep = ""; | |
| 15008 const char *zRhsSep = ""; | |
| 15009 int jj; | |
| 15010 for(jj=0; jj<ii-1; jj++){ | |
| 15011 const char *zAlias = (const char*)sqlite3_column_name(p->pCheck,jj+1); | |
| 15012 zLhs = intckMprintf(p, "%z%s%s", zLhs, zLhsSep, zAlias); | |
| 15013 zRhs = intckMprintf(p, "%z%squote(?%d)", zRhs, zRhsSep, jj+1); | |
| 15014 zLhsSep = ","; | |
| 15015 zRhsSep = " || ',' || "; | |
| 15016 } | |
| 15017 | |
| 15018 zWhere = intckMprintf(p, | |
| 15019 "'(%z) IS (' || %z || ') AND ' || %z", | |
| 15020 zLhs, zRhs, zWhere); | |
| 15021 } | |
| 15022 zWhere = intckMprintf(p, "'WHERE ' || %z", zWhere); | |
| 15023 | |
| 15024 zSql = intckMprintf(p, "%z%s(quote( %z ) )", | |
| 15025 zSql, | |
| 15026 (zSql==0 ? "VALUES" : ",\n "), | |
| 15027 zWhere | |
| 15028 ); | |
| 15029 } | |
| 15030 zSql = intckMprintf(p, | |
| 15031 "WITH wc(q) AS (\n%z\n)" | |
| 15032 "SELECT 'VALUES' || group_concat('(' || q || ')', ',\n ') FROM wc" | |
| 15033 , zSql | |
| 15034 ); | |
| 15035 } | |
| 15036 | |
| 15037 pStmt = intckPrepare(p, zSql); | |
| 15038 if( p->rc==SQLITE_OK ){ | |
| 15039 for(ii=0; ii<p->nKeyVal; ii++){ | |
| 15040 sqlite3_bind_value(pStmt, ii+1, sqlite3_column_value(p->pCheck, ii+1)); | |
| 15041 } | |
| 15042 if( SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 15043 p->zKey = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0)); | |
| 15044 } | |
| 15045 intckFinalize(p, pStmt); | |
| 15046 } | |
| 15047 | |
| 15048 sqlite3_free(zSql); | |
| 15049 intckFinalize(p, pXinfo); | |
| 15050 } | |
| 15051 | |
| 15052 /* | |
| 15053 ** Find the next database object (table or index) to check. If successful, | |
| 15054 ** set sqlite3_intck.zObj to point to a nul-terminated buffer containing | |
| 15055 ** the object's name before returning. | |
| 15056 */ | |
| 15057 static void intckFindObject(sqlite3_intck *p){ | |
| 15058 sqlite3_stmt *pStmt = 0; | |
| 15059 char *zPrev = p->zObj; | |
| 15060 p->zObj = 0; | |
| 15061 | |
| 15062 assert( p->rc==SQLITE_OK ); | |
| 15063 assert( p->pCheck==0 ); | |
| 15064 | |
| 15065 pStmt = intckPrepareFmt(p, | |
| 15066 "WITH tables(table_name) AS (" | |
| 15067 " SELECT name" | |
| 15068 " FROM %Q.sqlite_schema WHERE (type='table' OR type='index') AND rootpage" | |
| 15069 " UNION ALL " | |
| 15070 " SELECT 'sqlite_schema'" | |
| 15071 ")" | |
| 15072 "SELECT table_name FROM tables " | |
| 15073 "WHERE ?1 IS NULL OR table_name%s?1 " | |
| 15074 "ORDER BY 1" | |
| 15075 , p->zDb, (p->zKey ? ">=" : ">") | |
| 15076 ); | |
| 15077 | |
| 15078 if( p->rc==SQLITE_OK ){ | |
| 15079 sqlite3_bind_text(pStmt, 1, zPrev, -1, SQLITE_TRANSIENT); | |
| 15080 if( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 15081 p->zObj = intckMprintf(p,"%s",(const char*)sqlite3_column_text(pStmt, 0)); | |
| 15082 } | |
| 15083 } | |
| 15084 intckFinalize(p, pStmt); | |
| 15085 | |
| 15086 /* If this is a new object, ensure the previous key value is cleared. */ | |
| 15087 if( sqlite3_stricmp(p->zObj, zPrev) ){ | |
| 15088 sqlite3_free(p->zKey); | |
| 15089 p->zKey = 0; | |
| 15090 } | |
| 15091 | |
| 15092 sqlite3_free(zPrev); | |
| 15093 } | |
| 15094 | |
| 15095 /* | |
| 15096 ** Return the size in bytes of the first token in nul-terminated buffer z. | |
| 15097 ** For the purposes of this call, a token is either: | |
| 15098 ** | |
| 15099 ** * a quoted SQL string, | |
| 15100 * * a contiguous series of ascii alphabet characters, or | |
| 15101 * * any other single byte. | |
| 15102 */ | |
| 15103 static int intckGetToken(const char *z){ | |
| 15104 char c = z[0]; | |
| 15105 int iRet = 1; | |
| 15106 if( c=='\'' || c=='"' || c=='`' ){ | |
| 15107 while( 1 ){ | |
| 15108 if( z[iRet]==c ){ | |
| 15109 iRet++; | |
| 15110 if( z[iRet]!=c ) break; | |
| 15111 } | |
| 15112 iRet++; | |
| 15113 } | |
| 15114 } | |
| 15115 else if( c=='[' ){ | |
| 15116 while( z[iRet++]!=']' && z[iRet] ); | |
| 15117 } | |
| 15118 else if( (c>='A' && c<='Z') || (c>='a' && c<='z') ){ | |
| 15119 while( (z[iRet]>='A' && z[iRet]<='Z') || (z[iRet]>='a' && z[iRet]<='z') ){ | |
| 15120 iRet++; | |
| 15121 } | |
| 15122 } | |
| 15123 | |
| 15124 return iRet; | |
| 15125 } | |
| 15126 | |
| 15127 /* | |
| 15128 ** Return true if argument c is an ascii whitespace character. | |
| 15129 */ | |
| 15130 static int intckIsSpace(char c){ | |
| 15131 return (c==' ' || c=='\t' || c=='\n' || c=='\r'); | |
| 15132 } | |
| 15133 | |
| 15134 /* | |
| 15135 ** Argument z points to the text of a CREATE INDEX statement. This function | |
| 15136 ** identifies the part of the text that contains either the index WHERE | |
| 15137 ** clause (if iCol<0) or the iCol'th column of the index. | |
| 15138 ** | |
| 15139 ** If (iCol<0), the identified fragment does not include the "WHERE" keyword, | |
| 15140 ** only the expression that follows it. If (iCol>=0) then the identified | |
| 15141 ** fragment does not include any trailing sort-order keywords - "ASC" or | |
| 15142 ** "DESC". | |
| 15143 ** | |
| 15144 ** If the CREATE INDEX statement does not contain the requested field or | |
| 15145 ** clause, NULL is returned and (*pnByte) is set to 0. Otherwise, a pointer to | |
| 15146 ** the identified fragment is returned and output parameter (*pnByte) set | |
| 15147 ** to its size in bytes. | |
| 15148 */ | |
| 15149 static const char *intckParseCreateIndex(const char *z, int iCol, int *pnByte){ | |
| 15150 int iOff = 0; | |
| 15151 int iThisCol = 0; | |
| 15152 int iStart = 0; | |
| 15153 int nOpen = 0; | |
| 15154 | |
| 15155 const char *zRet = 0; | |
| 15156 int nRet = 0; | |
| 15157 | |
| 15158 int iEndOfCol = 0; | |
| 15159 | |
| 15160 /* Skip forward until the first "(" token */ | |
| 15161 while( z[iOff]!='(' ){ | |
| 15162 iOff += intckGetToken(&z[iOff]); | |
| 15163 if( z[iOff]=='\0' ) return 0; | |
| 15164 } | |
| 15165 assert( z[iOff]=='(' ); | |
| 15166 | |
| 15167 nOpen = 1; | |
| 15168 iOff++; | |
| 15169 iStart = iOff; | |
| 15170 while( z[iOff] ){ | |
| 15171 const char *zToken = &z[iOff]; | |
| 15172 int nToken = 0; | |
| 15173 | |
| 15174 /* Check if this is the end of the current column - either a "," or ")" | |
| 15175 ** when nOpen==1. */ | |
| 15176 if( nOpen==1 ){ | |
| 15177 if( z[iOff]==',' || z[iOff]==')' ){ | |
| 15178 if( iCol==iThisCol ){ | |
| 15179 int iEnd = iEndOfCol ? iEndOfCol : iOff; | |
| 15180 nRet = (iEnd - iStart); | |
| 15181 zRet = &z[iStart]; | |
| 15182 break; | |
| 15183 } | |
| 15184 iStart = iOff+1; | |
| 15185 while( intckIsSpace(z[iStart]) ) iStart++; | |
| 15186 iThisCol++; | |
| 15187 } | |
| 15188 if( z[iOff]==')' ) break; | |
| 15189 } | |
| 15190 if( z[iOff]=='(' ) nOpen++; | |
| 15191 if( z[iOff]==')' ) nOpen--; | |
| 15192 nToken = intckGetToken(zToken); | |
| 15193 | |
| 15194 if( (nToken==3 && 0==sqlite3_strnicmp(zToken, "ASC", nToken)) | |
| 15195 || (nToken==4 && 0==sqlite3_strnicmp(zToken, "DESC", nToken)) | |
| 15196 ){ | |
| 15197 iEndOfCol = iOff; | |
| 15198 }else if( 0==intckIsSpace(zToken[0]) ){ | |
| 15199 iEndOfCol = 0; | |
| 15200 } | |
| 15201 | |
| 15202 iOff += nToken; | |
| 15203 } | |
| 15204 | |
| 15205 /* iStart is now the byte offset of 1 byte passed the final ')' in the | |
| 15206 ** CREATE INDEX statement. Try to find a WHERE clause to return. */ | |
| 15207 while( zRet==0 && z[iOff] ){ | |
| 15208 int n = intckGetToken(&z[iOff]); | |
| 15209 if( n==5 && 0==sqlite3_strnicmp(&z[iOff], "where", 5) ){ | |
| 15210 zRet = &z[iOff+5]; | |
| 15211 nRet = (int)strlen(zRet); | |
| 15212 } | |
| 15213 iOff += n; | |
| 15214 } | |
| 15215 | |
| 15216 /* Trim any whitespace from the start and end of the returned string. */ | |
| 15217 if( zRet ){ | |
| 15218 while( intckIsSpace(zRet[0]) ){ | |
| 15219 nRet--; | |
| 15220 zRet++; | |
| 15221 } | |
| 15222 while( nRet>0 && intckIsSpace(zRet[nRet-1]) ) nRet--; | |
| 15223 } | |
| 15224 | |
| 15225 *pnByte = nRet; | |
| 15226 return zRet; | |
| 15227 } | |
| 15228 | |
| 15229 /* | |
| 15230 ** User-defined SQL function wrapper for intckParseCreateIndex(): | |
| 15231 ** | |
| 15232 ** SELECT parse_create_index(<sql>, <icol>); | |
| 15233 */ | |
| 15234 static void intckParseCreateIndexFunc( | |
| 15235 sqlite3_context *pCtx, | |
| 15236 int nVal, | |
| 15237 sqlite3_value **apVal | |
| 15238 ){ | |
| 15239 const char *zSql = (const char*)sqlite3_value_text(apVal[0]); | |
| 15240 int idx = sqlite3_value_int(apVal[1]); | |
| 15241 const char *zRes = 0; | |
| 15242 int nRes = 0; | |
| 15243 | |
| 15244 assert( nVal==2 ); | |
| 15245 if( zSql ){ | |
| 15246 zRes = intckParseCreateIndex(zSql, idx, &nRes); | |
| 15247 } | |
| 15248 sqlite3_result_text(pCtx, zRes, nRes, SQLITE_TRANSIENT); | |
| 15249 } | |
| 15250 | |
| 15251 /* | |
| 15252 ** Return true if sqlite3_intck.db has automatic indexes enabled, false | |
| 15253 ** otherwise. | |
| 15254 */ | |
| 15255 static int intckGetAutoIndex(sqlite3_intck *p){ | |
| 15256 int bRet = 0; | |
| 15257 sqlite3_stmt *pStmt = 0; | |
| 15258 pStmt = intckPrepare(p, "PRAGMA automatic_index"); | |
| 15259 if( SQLITE_ROW==intckStep(p, pStmt) ){ | |
| 15260 bRet = sqlite3_column_int(pStmt, 0); | |
| 15261 } | |
| 15262 intckFinalize(p, pStmt); | |
| 15263 return bRet; | |
| 15264 } | |
| 15265 | |
| 15266 /* | |
| 15267 ** Return true if zObj is an index, or false otherwise. | |
| 15268 */ | |
| 15269 static int intckIsIndex(sqlite3_intck *p, const char *zObj){ | |
| 15270 int bRet = 0; | |
| 15271 sqlite3_stmt *pStmt = 0; | |
| 15272 pStmt = intckPrepareFmt(p, | |
| 15273 "SELECT 1 FROM %Q.sqlite_schema WHERE name=%Q AND type='index'", | |
| 15274 p->zDb, zObj | |
| 15275 ); | |
| 15276 if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 15277 bRet = 1; | |
| 15278 } | |
| 15279 intckFinalize(p, pStmt); | |
| 15280 return bRet; | |
| 15281 } | |
| 15282 | |
| 15283 /* | |
| 15284 ** Return a pointer to a nul-terminated buffer containing the SQL statement | |
| 15285 ** used to check database object zObj (a table or index) for corruption. | |
| 15286 ** If parameter zPrev is not NULL, then it must be a string containing the | |
| 15287 ** vector key required to restart the check where it left off last time. | |
| 15288 ** If pnKeyVal is not NULL, then (*pnKeyVal) is set to the number of | |
| 15289 ** columns in the vector key value for the specified object. | |
| 15290 ** | |
| 15291 ** This function uses the sqlite3_intck error code convention. | |
| 15292 */ | |
| 15293 static char *intckCheckObjectSql( | |
| 15294 sqlite3_intck *p, /* Integrity check object */ | |
| 15295 const char *zObj, /* Object (table or index) to scan */ | |
| 15296 const char *zPrev, /* Restart key vector, if any */ | |
| 15297 int *pnKeyVal /* OUT: Number of key-values for this scan */ | |
| 15298 ){ | |
| 15299 char *zRet = 0; | |
| 15300 sqlite3_stmt *pStmt = 0; | |
| 15301 int bAutoIndex = 0; | |
| 15302 int bIsIndex = 0; | |
| 15303 | |
| 15304 const char *zCommon = | |
| 15305 /* Relation without_rowid also contains just one row. Column "b" is | |
| 15306 ** set to true if the table being examined is a WITHOUT ROWID table, | |
| 15307 ** or false otherwise. */ | |
| 15308 ", without_rowid(b) AS (" | |
| 15309 " SELECT EXISTS (" | |
| 15310 " SELECT 1 FROM tabname, pragma_index_list(tab, db) AS l" | |
| 15311 " WHERE origin='pk' " | |
| 15312 " AND NOT EXISTS (SELECT 1 FROM sqlite_schema WHERE name=l.name)" | |
| 15313 " )" | |
| 15314 ")" | |
| 15315 "" | |
| 15316 /* Table idx_cols contains 1 row for each column in each index on the | |
| 15317 ** table being checked. Columns are: | |
| 15318 ** | |
| 15319 ** idx_name: Name of the index. | |
| 15320 ** idx_ispk: True if this index is the PK of a WITHOUT ROWID table. | |
| 15321 ** col_name: Name of indexed column, or NULL for index on expression. | |
| 15322 ** col_expr: Indexed expression, including COLLATE clause. | |
| 15323 ** col_alias: Alias used for column in 'intck_wrapper' table. | |
| 15324 */ | |
| 15325 ", idx_cols(idx_name, idx_ispk, col_name, col_expr, col_alias) AS (" | |
| 15326 " SELECT l.name, (l.origin=='pk' AND w.b), i.name, COALESCE((" | |
| 15327 " SELECT parse_create_index(sql, i.seqno) FROM " | |
| 15328 " sqlite_schema WHERE name = l.name" | |
| 15329 " ), format('\"%w\"', i.name) || ' COLLATE ' || quote(i.coll))," | |
| 15330 " 'c' || row_number() OVER ()" | |
| 15331 " FROM " | |
| 15332 " tabname t," | |
| 15333 " without_rowid w," | |
| 15334 " pragma_index_list(t.tab, t.db) l," | |
| 15335 " pragma_index_xinfo(l.name) i" | |
| 15336 " WHERE i.key" | |
| 15337 " UNION ALL" | |
| 15338 " SELECT '', 1, '_rowid_', '_rowid_', 'r1' FROM without_rowid WHERE b=0" | |
| 15339 ")" | |
| 15340 "" | |
| 15341 "" | |
| 15342 /* | |
| 15343 ** For a PK declared as "PRIMARY KEY(a, b) ... WITHOUT ROWID", where | |
| 15344 ** the intck_wrapper aliases of "a" and "b" are "c1" and "c2": | |
| 15345 ** | |
| 15346 ** o_pk: "o.c1, o.c2" | |
| 15347 ** i_pk: "i.'a', i.'b'" | |
| 15348 ** ... | |
| 15349 ** n_pk: 2 | |
| 15350 */ | |
| 15351 ", tabpk(db, tab, idx, o_pk, i_pk, q_pk, eq_pk, ps_pk, pk_pk, n_pk) AS (" | |
| 15352 " WITH pkfields(f, a) AS (" | |
| 15353 " SELECT i.col_name, i.col_alias FROM idx_cols i WHERE i.idx_ispk" | |
| 15354 " )" | |
| 15355 " SELECT t.db, t.tab, t.idx, " | |
| 15356 " group_concat(a, ', '), " | |
| 15357 " group_concat('i.'||quote(f), ', '), " | |
| 15358 " group_concat('quote(o.'||a||')', ' || '','' || '), " | |
| 15359 " format('(%s)==(%s)'," | |
| 15360 " group_concat('o.'||a, ', '), " | |
| 15361 " group_concat(format('\"%w\"', f), ', ')" | |
| 15362 " )," | |
| 15363 " group_concat('%s', ',')," | |
| 15364 " group_concat('quote('||a||')', ', '), " | |
| 15365 " count(*)" | |
| 15366 " FROM tabname t, pkfields" | |
| 15367 ")" | |
| 15368 "" | |
| 15369 ", idx(name, match_expr, partial, partial_alias, idx_ps, idx_idx) AS (" | |
| 15370 " SELECT idx_name," | |
| 15371 " format('(%s,%s) IS (%s,%s)', " | |
| 15372 " group_concat(i.col_expr, ', '), i_pk," | |
| 15373 " group_concat('o.'||i.col_alias, ', '), o_pk" | |
| 15374 " ), " | |
| 15375 " parse_create_index(" | |
| 15376 " (SELECT sql FROM sqlite_schema WHERE name=idx_name), -1" | |
| 15377 " )," | |
| 15378 " 'cond' || row_number() OVER ()" | |
| 15379 " , group_concat('%s', ',')" | |
| 15380 " , group_concat('quote('||i.col_alias||')', ', ')" | |
| 15381 " FROM tabpk t, " | |
| 15382 " without_rowid w," | |
| 15383 " idx_cols i" | |
| 15384 " WHERE i.idx_ispk==0 " | |
| 15385 " GROUP BY idx_name" | |
| 15386 ")" | |
| 15387 "" | |
| 15388 ", wrapper_with(s) AS (" | |
| 15389 " SELECT 'intck_wrapper AS (\n SELECT\n ' || (" | |
| 15390 " WITH f(a, b) AS (" | |
| 15391 " SELECT col_expr, col_alias FROM idx_cols" | |
| 15392 " UNION ALL " | |
| 15393 " SELECT partial, partial_alias FROM idx WHERE partial IS NOT NULL" | |
| 15394 " )" | |
| 15395 " SELECT group_concat(format('%s AS %s', a, b), ',\n ') FROM f" | |
| 15396 " )" | |
| 15397 " || format('\n FROM %Q.%Q ', t.db, t.tab)" | |
| 15398 /* If the object being checked is a table, append "NOT INDEXED". | |
| 15399 ** Otherwise, append "INDEXED BY <index>", and then, if the index | |
| 15400 ** is a partial index " WHERE <condition>". */ | |
| 15401 " || CASE WHEN t.idx IS NULL THEN " | |
| 15402 " 'NOT INDEXED'" | |
| 15403 " ELSE" | |
| 15404 " format('INDEXED BY %Q%s', t.idx, ' WHERE '||i.partial)" | |
| 15405 " END" | |
| 15406 " || '\n)'" | |
| 15407 " FROM tabname t LEFT JOIN idx i ON (i.name=t.idx)" | |
| 15408 ")" | |
| 15409 "" | |
| 15410 ; | |
| 15411 | |
| 15412 bAutoIndex = intckGetAutoIndex(p); | |
| 15413 if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 0"); | |
| 15414 | |
| 15415 bIsIndex = intckIsIndex(p, zObj); | |
| 15416 if( bIsIndex ){ | |
| 15417 pStmt = intckPrepareFmt(p, | |
| 15418 /* Table idxname contains a single row. The first column, "db", contains | |
| 15419 ** the name of the db containing the table (e.g. "main") and the second, | |
| 15420 ** "tab", the name of the table itself. */ | |
| 15421 "WITH tabname(db, tab, idx) AS (" | |
| 15422 " SELECT %Q, (SELECT tbl_name FROM %Q.sqlite_schema WHERE name=%Q), %Q " | |
| 15423 ")" | |
| 15424 "" | |
| 15425 ", whereclause(w_c) AS (%s)" | |
| 15426 "" | |
| 15427 "%s" /* zCommon */ | |
| 15428 "" | |
| 15429 ", case_statement(c) AS (" | |
| 15430 " SELECT " | |
| 15431 " 'CASE WHEN (' || group_concat(col_alias, ', ') || ', 1) IS (\n' " | |
| 15432 " || ' SELECT ' || group_concat(col_expr, ', ') || ', 1 FROM '" | |
| 15433 " || format('%%Q.%%Q NOT INDEXED WHERE %%s\n', t.db, t.tab, p.eq_pk)" | |
| 15434 " || ' )\n THEN NULL\n '" | |
| 15435 " || 'ELSE format(''surplus entry ('" | |
| 15436 " || group_concat('%%s', ',') || ',' || p.ps_pk" | |
| 15437 " || ') in index ' || t.idx || ''', ' " | |
| 15438 " || group_concat('quote('||i.col_alias||')', ', ') || ', ' || p.pk_pk" | |
| 15439 " || ')'" | |
| 15440 " || '\n END AS error_message'" | |
| 15441 " FROM tabname t, tabpk p, idx_cols i WHERE i.idx_name=t.idx" | |
| 15442 ")" | |
| 15443 "" | |
| 15444 ", thiskey(k, n) AS (" | |
| 15445 " SELECT group_concat(i.col_alias, ', ') || ', ' || p.o_pk, " | |
| 15446 " count(*) + p.n_pk " | |
| 15447 " FROM tabpk p, idx_cols i WHERE i.idx_name=p.idx" | |
| 15448 ")" | |
| 15449 "" | |
| 15450 ", main_select(m, n) AS (" | |
| 15451 " SELECT format(" | |
| 15452 " 'WITH %%s\n' ||" | |
| 15453 " ', idx_checker AS (\n' ||" | |
| 15454 " ' SELECT %%s,\n' ||" | |
| 15455 " ' %%s\n' || " | |
| 15456 " ' FROM intck_wrapper AS o\n' ||" | |
| 15457 " ')\n'," | |
| 15458 " ww.s, c, t.k" | |
| 15459 " ), t.n" | |
| 15460 " FROM case_statement, wrapper_with ww, thiskey t" | |
| 15461 ")" | |
| 15462 | |
| 15463 "SELECT m || " | |
| 15464 " group_concat('SELECT * FROM idx_checker ' || w_c, ' UNION ALL '), n" | |
| 15465 " FROM " | |
| 15466 "main_select, whereclause " | |
| 15467 , p->zDb, p->zDb, zObj, zObj | |
| 15468 , zPrev ? zPrev : "VALUES('')", zCommon | |
| 15469 ); | |
| 15470 }else{ | |
| 15471 pStmt = intckPrepareFmt(p, | |
| 15472 /* Table tabname contains a single row. The first column, "db", contains | |
| 15473 ** the name of the db containing the table (e.g. "main") and the second, | |
| 15474 ** "tab", the name of the table itself. */ | |
| 15475 "WITH tabname(db, tab, idx, prev) AS (SELECT %Q, %Q, NULL, %Q)" | |
| 15476 "" | |
| 15477 "%s" /* zCommon */ | |
| 15478 | |
| 15479 /* expr(e) contains one row for each index on table zObj. Value e | |
| 15480 ** is set to an expression that evaluates to NULL if the required | |
| 15481 ** entry is present in the index, or an error message otherwise. */ | |
| 15482 ", expr(e, p) AS (" | |
| 15483 " SELECT format('CASE WHEN EXISTS \n" | |
| 15484 " (SELECT 1 FROM %%Q.%%Q AS i INDEXED BY %%Q WHERE %%s%%s)\n" | |
| 15485 " THEN NULL\n" | |
| 15486 " ELSE format(''entry (%%s,%%s) missing from index %%s'', %%s, %%s)\n" | |
| 15487 " END\n'" | |
| 15488 " , t.db, t.tab, i.name, i.match_expr, ' AND (' || partial || ')'," | |
| 15489 " i.idx_ps, t.ps_pk, i.name, i.idx_idx, t.pk_pk)," | |
| 15490 " CASE WHEN partial IS NULL THEN NULL ELSE i.partial_alias END" | |
| 15491 " FROM tabpk t, idx i" | |
| 15492 ")" | |
| 15493 | |
| 15494 ", numbered(ii, cond, e) AS (" | |
| 15495 " SELECT 0, 'n.ii=0', 'NULL'" | |
| 15496 " UNION ALL " | |
| 15497 " SELECT row_number() OVER ()," | |
| 15498 " '(n.ii='||row_number() OVER ()||COALESCE(' AND '||p||')', ')'), e" | |
| 15499 " FROM expr" | |
| 15500 ")" | |
| 15501 | |
| 15502 ", counter_with(w) AS (" | |
| 15503 " SELECT 'WITH intck_counter(ii) AS (\n ' || " | |
| 15504 " group_concat('SELECT '||ii, ' UNION ALL\n ') " | |
| 15505 " || '\n)' FROM numbered" | |
| 15506 ")" | |
| 15507 "" | |
| 15508 ", case_statement(c) AS (" | |
| 15509 " SELECT 'CASE ' || " | |
| 15510 " group_concat(format('\n WHEN %%s THEN (%%s)', cond, e), '') ||" | |
| 15511 " '\nEND AS error_message'" | |
| 15512 " FROM numbered" | |
| 15513 ")" | |
| 15514 "" | |
| 15515 | |
| 15516 /* This table contains a single row consisting of a single value - | |
| 15517 ** the text of an SQL expression that may be used by the main SQL | |
| 15518 ** statement to output an SQL literal that can be used to resume | |
| 15519 ** the scan if it is suspended. e.g. for a rowid table, an expression | |
| 15520 ** like: | |
| 15521 ** | |
| 15522 ** format('(%d,%d)', _rowid_, n.ii) | |
| 15523 */ | |
| 15524 ", thiskey(k, n) AS (" | |
| 15525 " SELECT o_pk || ', ii', n_pk+1 FROM tabpk" | |
| 15526 ")" | |
| 15527 "" | |
| 15528 ", whereclause(w_c) AS (" | |
| 15529 " SELECT CASE WHEN prev!='' THEN " | |
| 15530 " '\nWHERE (' || o_pk ||', n.ii) > ' || prev" | |
| 15531 " ELSE ''" | |
| 15532 " END" | |
| 15533 " FROM tabpk, tabname" | |
| 15534 ")" | |
| 15535 "" | |
| 15536 ", main_select(m, n) AS (" | |
| 15537 " SELECT format(" | |
| 15538 " '%%s, %%s\nSELECT %%s,\n%%s\nFROM intck_wrapper AS o" | |
| 15539 ", intck_counter AS n%%s\nORDER BY %%s', " | |
| 15540 " w, ww.s, c, thiskey.k, whereclause.w_c, t.o_pk" | |
| 15541 " ), thiskey.n" | |
| 15542 " FROM case_statement, tabpk t, counter_with, " | |
| 15543 " wrapper_with ww, thiskey, whereclause" | |
| 15544 ")" | |
| 15545 | |
| 15546 "SELECT m, n FROM main_select", | |
| 15547 p->zDb, zObj, zPrev, zCommon | |
| 15548 ); | |
| 15549 } | |
| 15550 | |
| 15551 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 15552 zRet = intckMprintf(p, "%s", (const char*)sqlite3_column_text(pStmt, 0)); | |
| 15553 if( pnKeyVal ){ | |
| 15554 *pnKeyVal = sqlite3_column_int(pStmt, 1); | |
| 15555 } | |
| 15556 } | |
| 15557 intckFinalize(p, pStmt); | |
| 15558 | |
| 15559 if( bAutoIndex ) intckExec(p, "PRAGMA automatic_index = 1"); | |
| 15560 return zRet; | |
| 15561 } | |
| 15562 | |
| 15563 /* | |
| 15564 ** Open a new integrity-check object. | |
| 15565 */ | |
| 15566 int sqlite3_intck_open( | |
| 15567 sqlite3 *db, /* Database handle to operate on */ | |
| 15568 const char *zDbArg, /* "main", "temp" etc. */ | |
| 15569 sqlite3_intck **ppOut /* OUT: New integrity-check handle */ | |
| 15570 ){ | |
| 15571 sqlite3_intck *pNew = 0; | |
| 15572 int rc = SQLITE_OK; | |
| 15573 const char *zDb = zDbArg ? zDbArg : "main"; | |
| 15574 int nDb = (int)strlen(zDb); | |
| 15575 | |
| 15576 pNew = (sqlite3_intck*)sqlite3_malloc(sizeof(*pNew) + nDb + 1); | |
| 15577 if( pNew==0 ){ | |
| 15578 rc = SQLITE_NOMEM; | |
| 15579 }else{ | |
| 15580 memset(pNew, 0, sizeof(*pNew)); | |
| 15581 pNew->db = db; | |
| 15582 pNew->zDb = (const char*)&pNew[1]; | |
| 15583 memcpy(&pNew[1], zDb, nDb+1); | |
| 15584 rc = sqlite3_create_function(db, "parse_create_index", | |
| 15585 2, SQLITE_UTF8, 0, intckParseCreateIndexFunc, 0, 0 | |
| 15586 ); | |
| 15587 if( rc!=SQLITE_OK ){ | |
| 15588 sqlite3_intck_close(pNew); | |
| 15589 pNew = 0; | |
| 15590 } | |
| 15591 } | |
| 15592 | |
| 15593 *ppOut = pNew; | |
| 15594 return rc; | |
| 15595 } | |
| 15596 | |
| 15597 /* | |
| 15598 ** Free the integrity-check object. | |
| 15599 */ | |
| 15600 void sqlite3_intck_close(sqlite3_intck *p){ | |
| 15601 if( p ){ | |
| 15602 sqlite3_finalize(p->pCheck); | |
| 15603 sqlite3_create_function( | |
| 15604 p->db, "parse_create_index", 1, SQLITE_UTF8, 0, 0, 0, 0 | |
| 15605 ); | |
| 15606 sqlite3_free(p->zObj); | |
| 15607 sqlite3_free(p->zKey); | |
| 15608 sqlite3_free(p->zTestSql); | |
| 15609 sqlite3_free(p->zErr); | |
| 15610 sqlite3_free(p->zMessage); | |
| 15611 sqlite3_free(p); | |
| 15612 } | |
| 15613 } | |
| 15614 | |
| 15615 /* | |
| 15616 ** Step the integrity-check object. | |
| 15617 */ | |
| 15618 int sqlite3_intck_step(sqlite3_intck *p){ | |
| 15619 if( p->rc==SQLITE_OK ){ | |
| 15620 | |
| 15621 if( p->zMessage ){ | |
| 15622 sqlite3_free(p->zMessage); | |
| 15623 p->zMessage = 0; | |
| 15624 } | |
| 15625 | |
| 15626 if( p->bCorruptSchema ){ | |
| 15627 p->rc = SQLITE_DONE; | |
| 15628 }else | |
| 15629 if( p->pCheck==0 ){ | |
| 15630 intckFindObject(p); | |
| 15631 if( p->rc==SQLITE_OK ){ | |
| 15632 if( p->zObj ){ | |
| 15633 char *zSql = 0; | |
| 15634 zSql = intckCheckObjectSql(p, p->zObj, p->zKey, &p->nKeyVal); | |
| 15635 p->pCheck = intckPrepare(p, zSql); | |
| 15636 sqlite3_free(zSql); | |
| 15637 sqlite3_free(p->zKey); | |
| 15638 p->zKey = 0; | |
| 15639 }else{ | |
| 15640 p->rc = SQLITE_DONE; | |
| 15641 } | |
| 15642 }else if( p->rc==SQLITE_CORRUPT ){ | |
| 15643 p->rc = SQLITE_OK; | |
| 15644 p->zMessage = intckMprintf(p, "%s", | |
| 15645 "corruption found while reading database schema" | |
| 15646 ); | |
| 15647 p->bCorruptSchema = 1; | |
| 15648 } | |
| 15649 } | |
| 15650 | |
| 15651 if( p->pCheck ){ | |
| 15652 assert( p->rc==SQLITE_OK ); | |
| 15653 if( sqlite3_step(p->pCheck)==SQLITE_ROW ){ | |
| 15654 /* Normal case, do nothing. */ | |
| 15655 }else{ | |
| 15656 intckFinalize(p, p->pCheck); | |
| 15657 p->pCheck = 0; | |
| 15658 p->nKeyVal = 0; | |
| 15659 if( p->rc==SQLITE_CORRUPT ){ | |
| 15660 p->rc = SQLITE_OK; | |
| 15661 p->zMessage = intckMprintf(p, | |
| 15662 "corruption found while scanning database object %s", p->zObj | |
| 15663 ); | |
| 15664 } | |
| 15665 } | |
| 15666 } | |
| 15667 } | |
| 15668 | |
| 15669 return p->rc; | |
| 15670 } | |
| 15671 | |
| 15672 /* | |
| 15673 ** Return a message describing the corruption encountered by the most recent | |
| 15674 ** call to sqlite3_intck_step(), or NULL if no corruption was encountered. | |
| 15675 */ | |
| 15676 const char *sqlite3_intck_message(sqlite3_intck *p){ | |
| 15677 assert( p->pCheck==0 || p->zMessage==0 ); | |
| 15678 if( p->zMessage ){ | |
| 15679 return p->zMessage; | |
| 15680 } | |
| 15681 if( p->pCheck ){ | |
| 15682 return (const char*)sqlite3_column_text(p->pCheck, 0); | |
| 15683 } | |
| 15684 return 0; | |
| 15685 } | |
| 15686 | |
| 15687 /* | |
| 15688 ** Return the error code and message. | |
| 15689 */ | |
| 15690 int sqlite3_intck_error(sqlite3_intck *p, const char **pzErr){ | |
| 15691 if( pzErr ) *pzErr = p->zErr; | |
| 15692 return (p->rc==SQLITE_DONE ? SQLITE_OK : p->rc); | |
| 15693 } | |
| 15694 | |
| 15695 /* | |
| 15696 ** Close any read transaction the integrity-check object is holding open | |
| 15697 ** on the database. | |
| 15698 */ | |
| 15699 int sqlite3_intck_unlock(sqlite3_intck *p){ | |
| 15700 if( p->rc==SQLITE_OK && p->pCheck ){ | |
| 15701 assert( p->zKey==0 && p->nKeyVal>0 ); | |
| 15702 intckSaveKey(p); | |
| 15703 intckFinalize(p, p->pCheck); | |
| 15704 p->pCheck = 0; | |
| 15705 } | |
| 15706 return p->rc; | |
| 15707 } | |
| 15708 | |
| 15709 /* | |
| 15710 ** Return the SQL statement used to check object zObj. Or, if zObj is | |
| 15711 ** NULL, the current SQL statement. | |
| 15712 */ | |
| 15713 const char *sqlite3_intck_test_sql(sqlite3_intck *p, const char *zObj){ | |
| 15714 sqlite3_free(p->zTestSql); | |
| 15715 if( zObj ){ | |
| 15716 p->zTestSql = intckCheckObjectSql(p, zObj, 0, 0); | |
| 15717 }else{ | |
| 15718 if( p->zObj ){ | |
| 15719 p->zTestSql = intckCheckObjectSql(p, p->zObj, p->zKey, 0); | |
| 15720 }else{ | |
| 15721 sqlite3_free(p->zTestSql); | |
| 15722 p->zTestSql = 0; | |
| 15723 } | |
| 15724 } | |
| 15725 return p->zTestSql; | |
| 15726 } | |
| 15727 | |
| 15728 /************************* End ../ext/intck/sqlite3intck.c ********************/ | |
| 15729 /************************* Begin ../ext/misc/stmtrand.c ******************/ | |
| 15730 /* | |
| 15731 ** 2024-05-24 | |
| 15732 ** | |
| 15733 ** The author disclaims copyright to this source code. In place of | |
| 15734 ** a legal notice, here is a blessing: | |
| 15735 ** | |
| 15736 ** May you do good and not evil. | |
| 15737 ** May you find forgiveness for yourself and forgive others. | |
| 15738 ** May you share freely, never taking more than you give. | |
| 15739 ** | |
| 15740 ****************************************************************************** | |
| 15741 ** | |
| 15742 ** An SQL function that return pseudo-random non-negative integers. | |
| 15743 ** | |
| 15744 ** SELECT stmtrand(123); | |
| 15745 ** | |
| 15746 ** A special feature of this function is that the same sequence of random | |
| 15747 ** integers is returned for each invocation of the statement. This makes | |
| 15748 ** the results repeatable, and hence useful for testing. The argument is | |
| 15749 ** an integer which is the seed for the random number sequence. The seed | |
| 15750 ** is used by the first invocation of this function only and is ignored | |
| 15751 ** for all subsequent calls within the same statement. | |
| 15752 ** | |
| 15753 ** Resetting a statement (sqlite3_reset()) also resets the random number | |
| 15754 ** sequence. | |
| 15755 */ | |
| 15756 /* #include "sqlite3ext.h" */ | |
| 15757 SQLITE_EXTENSION_INIT1 | |
| 15758 #include <assert.h> | |
| 15759 #include <string.h> | |
| 15760 | |
| 15761 /* State of the pseudo-random number generator */ | |
| 15762 typedef struct Stmtrand { | |
| 15763 unsigned int x, y; | |
| 15764 } Stmtrand; | |
| 15765 | |
| 15766 /* auxdata key */ | |
| 15767 #define STMTRAND_KEY (-4418371) | |
| 15768 | |
| 15769 /* | |
| 15770 ** Function: stmtrand(SEED) | |
| 15771 ** | |
| 15772 ** Return a pseudo-random number. | |
| 15773 */ | |
| 15774 static void stmtrandFunc( | |
| 15775 sqlite3_context *context, | |
| 15776 int argc, | |
| 15777 sqlite3_value **argv | |
| 15778 ){ | |
| 15779 Stmtrand *p; | |
| 15780 | |
| 15781 p = (Stmtrand*)sqlite3_get_auxdata(context, STMTRAND_KEY); | |
| 15782 if( p==0 ){ | |
| 15783 unsigned int seed; | |
| 15784 p = sqlite3_malloc( sizeof(*p) ); | |
| 15785 if( p==0 ){ | |
| 15786 sqlite3_result_error_nomem(context); | |
| 15787 return; | |
| 15788 } | |
| 15789 if( argc>=1 ){ | |
| 15790 seed = (unsigned int)sqlite3_value_int(argv[0]); | |
| 15791 }else{ | |
| 15792 seed = 0; | |
| 15793 } | |
| 15794 p->x = seed | 1; | |
| 15795 p->y = seed; | |
| 15796 sqlite3_set_auxdata(context, STMTRAND_KEY, p, sqlite3_free); | |
| 15797 p = (Stmtrand*)sqlite3_get_auxdata(context, STMTRAND_KEY); | |
| 15798 if( p==0 ){ | |
| 15799 sqlite3_result_error_nomem(context); | |
| 15800 return; | |
| 15801 } | |
| 15802 } | |
| 15803 p->x = (p->x>>1) ^ ((1+~(p->x&1)) & 0xd0000001); | |
| 15804 p->y = p->y*1103515245 + 12345; | |
| 15805 sqlite3_result_int(context, (int)((p->x ^ p->y)&0x7fffffff)); | |
| 15806 } | |
| 15807 | |
| 15808 #ifdef _WIN32 | |
| 15809 | |
| 15810 #endif | |
| 15811 int sqlite3_stmtrand_init( | |
| 15812 sqlite3 *db, | |
| 15813 char **pzErrMsg, | |
| 15814 const sqlite3_api_routines *pApi | |
| 15815 ){ | |
| 15816 int rc = SQLITE_OK; | |
| 15817 SQLITE_EXTENSION_INIT2(pApi); | |
| 15818 (void)pzErrMsg; /* Unused parameter */ | |
| 15819 rc = sqlite3_create_function(db, "stmtrand", 1, SQLITE_UTF8, 0, | |
| 15820 stmtrandFunc, 0, 0); | |
| 15821 if( rc==SQLITE_OK ){ | |
| 15822 rc = sqlite3_create_function(db, "stmtrand", 0, SQLITE_UTF8, 0, | |
| 15823 stmtrandFunc, 0, 0); | |
| 15824 } | |
| 15825 return rc; | |
| 15826 } | |
| 15827 | |
| 15828 /************************* End ../ext/misc/stmtrand.c ********************/ | |
| 15829 /************************* Begin ../ext/misc/vfstrace.c ******************/ | |
| 15830 /* | |
| 15831 ** 2011 March 16 | |
| 15832 ** | |
| 15833 ** The author disclaims copyright to this source code. In place of | |
| 15834 ** a legal notice, here is a blessing: | |
| 15835 ** | |
| 15836 ** May you do good and not evil. | |
| 15837 ** May you find forgiveness for yourself and forgive others. | |
| 15838 ** May you share freely, never taking more than you give. | |
| 15839 ** | |
| 15840 ****************************************************************************** | |
| 15841 ** | |
| 15842 ** This file contains code implements a VFS shim that writes diagnostic | |
| 15843 ** output for each VFS call, similar to "strace". | |
| 15844 ** | |
| 15845 ** USAGE: | |
| 15846 ** | |
| 15847 ** This source file exports a single symbol which is the name of a | |
| 15848 ** function: | |
| 15849 ** | |
| 15850 ** int vfstrace_register( | |
| 15851 ** const char *zTraceName, // Name of the newly constructed VFS | |
| 15852 ** const char *zOldVfsName, // Name of the underlying VFS | |
| 15853 ** int (*xOut)(const char*,void*), // Output routine. ex: fputs | |
| 15854 ** void *pOutArg, // 2nd argument to xOut. ex: stderr | |
| 15855 ** int makeDefault // Make the new VFS the default | |
| 15856 ** ); | |
| 15857 ** | |
| 15858 ** Applications that want to trace their VFS usage must provide a callback | |
| 15859 ** function with this prototype: | |
| 15860 ** | |
| 15861 ** int traceOutput(const char *zMessage, void *pAppData); | |
| 15862 ** | |
| 15863 ** This function will "output" the trace messages, where "output" can | |
| 15864 ** mean different things to different applications. The traceOutput function | |
| 15865 ** for the command-line shell (see shell.c) is "fputs" from the standard | |
| 15866 ** library, which means that all trace output is written on the stream | |
| 15867 ** specified by the second argument. In the case of the command-line shell | |
| 15868 ** the second argument is stderr. Other applications might choose to output | |
| 15869 ** trace information to a file, over a socket, or write it into a buffer. | |
| 15870 ** | |
| 15871 ** The vfstrace_register() function creates a new "shim" VFS named by | |
| 15872 ** the zTraceName parameter. A "shim" VFS is an SQLite backend that does | |
| 15873 ** not really perform the duties of a true backend, but simply filters or | |
| 15874 ** interprets VFS calls before passing them off to another VFS which does | |
| 15875 ** the actual work. In this case the other VFS - the one that does the | |
| 15876 ** real work - is identified by the second parameter, zOldVfsName. If | |
| 15877 ** the 2nd parameter is NULL then the default VFS is used. The common | |
| 15878 ** case is for the 2nd parameter to be NULL. | |
| 15879 ** | |
| 15880 ** The third and fourth parameters are the pointer to the output function | |
| 15881 ** and the second argument to the output function. For the SQLite | |
| 15882 ** command-line shell, when the -vfstrace option is used, these parameters | |
| 15883 ** are fputs and stderr, respectively. | |
| 15884 ** | |
| 15885 ** The fifth argument is true (non-zero) to cause the newly created VFS | |
| 15886 ** to become the default VFS. The common case is for the fifth parameter | |
| 15887 ** to be true. | |
| 15888 ** | |
| 15889 ** The call to vfstrace_register() simply creates the shim VFS that does | |
| 15890 ** tracing. The application must also arrange to use the new VFS for | |
| 15891 ** all database connections that are created and for which tracing is | |
| 15892 ** desired. This can be done by specifying the trace VFS using URI filename | |
| 15893 ** notation, or by specifying the trace VFS as the 4th parameter to | |
| 15894 ** sqlite3_open_v2() or by making the trace VFS be the default (by setting | |
| 15895 ** the 5th parameter of vfstrace_register() to 1). | |
| 15896 ** | |
| 15897 ** | |
| 15898 ** ENABLING VFSTRACE IN A COMMAND-LINE SHELL | |
| 15899 ** | |
| 15900 ** The SQLite command line shell implemented by the shell.c source file | |
| 15901 ** can be used with this module. To compile in -vfstrace support, first | |
| 15902 ** gather this file (test_vfstrace.c), the shell source file (shell.c), | |
| 15903 ** and the SQLite amalgamation source files (sqlite3.c, sqlite3.h) into | |
| 15904 ** the working directory. Then compile using a command like the following: | |
| 15905 ** | |
| 15906 ** gcc -o sqlite3 -Os -I. -DSQLITE_ENABLE_VFSTRACE \ | |
| 15907 ** -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE \ | |
| 15908 ** -DHAVE_READLINE -DHAVE_USLEEP=1 \ | |
| 15909 ** shell.c test_vfstrace.c sqlite3.c -ldl -lreadline -lncurses | |
| 15910 ** | |
| 15911 ** The gcc command above works on Linux and provides (in addition to the | |
| 15912 ** -vfstrace option) support for FTS3 and FTS4, RTREE, and command-line | |
| 15913 ** editing using the readline library. The command-line shell does not | |
| 15914 ** use threads so we added -DSQLITE_THREADSAFE=0 just to make the code | |
| 15915 ** run a little faster. For compiling on a Mac, you'll probably need | |
| 15916 ** to omit the -DHAVE_READLINE, the -lreadline, and the -lncurses options. | |
| 15917 ** The compilation could be simplified to just this: | |
| 15918 ** | |
| 15919 ** gcc -DSQLITE_ENABLE_VFSTRACE \ | |
| 15920 ** shell.c test_vfstrace.c sqlite3.c -ldl -lpthread | |
| 15921 ** | |
| 15922 ** In this second example, all unnecessary options have been removed | |
| 15923 ** Note that since the code is now threadsafe, we had to add the -lpthread | |
| 15924 ** option to pull in the pthreads library. | |
| 15925 ** | |
| 15926 ** To cross-compile for windows using MinGW, a command like this might | |
| 15927 ** work: | |
| 15928 ** | |
| 15929 ** /opt/mingw/bin/i386-mingw32msvc-gcc -o sqlite3.exe -Os -I \ | |
| 15930 ** -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_VFSTRACE \ | |
| 15931 ** shell.c test_vfstrace.c sqlite3.c | |
| 15932 ** | |
| 15933 ** Similar compiler commands will work on different systems. The key | |
| 15934 ** invariants are (1) you must have -DSQLITE_ENABLE_VFSTRACE so that | |
| 15935 ** the shell.c source file will know to include the -vfstrace command-line | |
| 15936 ** option and (2) you must compile and link the three source files | |
| 15937 ** shell,c, test_vfstrace.c, and sqlite3.c. | |
| 15938 ** | |
| 15939 ** RUNTIME CONTROL OF VFSTRACE OUTPUT | |
| 15940 ** | |
| 15941 ** The application can use the "vfstrace" pragma to control which VFS | |
| 15942 ** APIs are traced. To disable all output: | |
| 15943 ** | |
| 15944 ** PRAGMA vfstrace('-all'); | |
| 15945 ** | |
| 15946 ** To enable all output (which is the default setting): | |
| 15947 ** | |
| 15948 ** PRAGMA vfstrace('+all'); | |
| 15949 ** | |
| 15950 ** Individual APIs can be enabled or disabled by name, with or without | |
| 15951 ** the initial "x" character. For example, to set up for tracing lock | |
| 15952 ** primitives only: | |
| 15953 ** | |
| 15954 ** PRAGMA vfstrace('-all, +Lock,Unlock,ShmLock'); | |
| 15955 ** | |
| 15956 ** The argument to the vfstrace pragma ignores capitalization and any | |
| 15957 ** characters other than alphabetics, '+', and '-'. | |
| 15958 */ | |
| 15959 #include <stdlib.h> | |
| 15960 #include <string.h> | |
| 15961 /* #include "sqlite3.h" */ | |
| 15962 | |
| 15963 /* | |
| 15964 ** An instance of this structure is attached to the each trace VFS to | |
| 15965 ** provide auxiliary information. | |
| 15966 */ | |
| 15967 typedef struct vfstrace_info vfstrace_info; | |
| 15968 struct vfstrace_info { | |
| 15969 sqlite3_vfs *pRootVfs; /* The underlying real VFS */ | |
| 15970 int (*xOut)(const char*, void*); /* Send output here */ | |
| 15971 unsigned int mTrace; /* Mask of interfaces to trace */ | |
| 15972 u8 bOn; /* Tracing on/off */ | |
| 15973 void *pOutArg; /* First argument to xOut */ | |
| 15974 const char *zVfsName; /* Name of this trace-VFS */ | |
| 15975 sqlite3_vfs *pTraceVfs; /* Pointer back to the trace VFS */ | |
| 15976 }; | |
| 15977 | |
| 15978 /* | |
| 15979 ** The sqlite3_file object for the trace VFS | |
| 15980 */ | |
| 15981 typedef struct vfstrace_file vfstrace_file; | |
| 15982 struct vfstrace_file { | |
| 15983 sqlite3_file base; /* Base class. Must be first */ | |
| 15984 vfstrace_info *pInfo; /* The trace-VFS to which this file belongs */ | |
| 15985 const char *zFName; /* Base name of the file */ | |
| 15986 sqlite3_file *pReal; /* The real underlying file */ | |
| 15987 }; | |
| 15988 | |
| 15989 /* | |
| 15990 ** Bit values for vfstrace_info.mTrace. | |
| 15991 */ | |
| 15992 #define VTR_CLOSE 0x00000001 | |
| 15993 #define VTR_READ 0x00000002 | |
| 15994 #define VTR_WRITE 0x00000004 | |
| 15995 #define VTR_TRUNC 0x00000008 | |
| 15996 #define VTR_SYNC 0x00000010 | |
| 15997 #define VTR_FSIZE 0x00000020 | |
| 15998 #define VTR_LOCK 0x00000040 | |
| 15999 #define VTR_UNLOCK 0x00000080 | |
| 16000 #define VTR_CRL 0x00000100 | |
| 16001 #define VTR_FCTRL 0x00000200 | |
| 16002 #define VTR_SECSZ 0x00000400 | |
| 16003 #define VTR_DEVCHAR 0x00000800 | |
| 16004 #define VTR_SHMLOCK 0x00001000 | |
| 16005 #define VTR_SHMMAP 0x00002000 | |
| 16006 #define VTR_SHMBAR 0x00004000 | |
| 16007 #define VTR_SHMUNMAP 0x00008000 | |
| 16008 #define VTR_OPEN 0x00010000 | |
| 16009 #define VTR_DELETE 0x00020000 | |
| 16010 #define VTR_ACCESS 0x00040000 | |
| 16011 #define VTR_FULLPATH 0x00080000 | |
| 16012 #define VTR_DLOPEN 0x00100000 | |
| 16013 #define VTR_DLERR 0x00200000 | |
| 16014 #define VTR_DLSYM 0x00400000 | |
| 16015 #define VTR_DLCLOSE 0x00800000 | |
| 16016 #define VTR_RAND 0x01000000 | |
| 16017 #define VTR_SLEEP 0x02000000 | |
| 16018 #define VTR_CURTIME 0x04000000 | |
| 16019 #define VTR_LASTERR 0x08000000 | |
| 16020 #define VTR_FETCH 0x10000000 /* Also coverse xUnfetch */ | |
| 16021 | |
| 16022 /* | |
| 16023 ** Method declarations for vfstrace_file. | |
| 16024 */ | |
| 16025 static int vfstraceClose(sqlite3_file*); | |
| 16026 static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); | |
| 16027 static int vfstraceWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64); | |
| 16028 static int vfstraceTruncate(sqlite3_file*, sqlite3_int64 size); | |
| 16029 static int vfstraceSync(sqlite3_file*, int flags); | |
| 16030 static int vfstraceFileSize(sqlite3_file*, sqlite3_int64 *pSize); | |
| 16031 static int vfstraceLock(sqlite3_file*, int); | |
| 16032 static int vfstraceUnlock(sqlite3_file*, int); | |
| 16033 static int vfstraceCheckReservedLock(sqlite3_file*, int *); | |
| 16034 static int vfstraceFileControl(sqlite3_file*, int op, void *pArg); | |
| 16035 static int vfstraceSectorSize(sqlite3_file*); | |
| 16036 static int vfstraceDeviceCharacteristics(sqlite3_file*); | |
| 16037 static int vfstraceShmLock(sqlite3_file*,int,int,int); | |
| 16038 static int vfstraceShmMap(sqlite3_file*,int,int,int, void volatile **); | |
| 16039 static void vfstraceShmBarrier(sqlite3_file*); | |
| 16040 static int vfstraceShmUnmap(sqlite3_file*,int); | |
| 16041 | |
| 16042 /* | |
| 16043 ** Method declarations for vfstrace_vfs. | |
| 16044 */ | |
| 16045 static int vfstraceOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); | |
| 16046 static int vfstraceDelete(sqlite3_vfs*, const char *zName, int syncDir); | |
| 16047 static int vfstraceAccess(sqlite3_vfs*, const char *zName, int flags, int *); | |
| 16048 static int vfstraceFullPathname(sqlite3_vfs*, const char *zName, int, char *); | |
| 16049 static void *vfstraceDlOpen(sqlite3_vfs*, const char *zFilename); | |
| 16050 static void vfstraceDlError(sqlite3_vfs*, int nByte, char *zErrMsg); | |
| 16051 static void (*vfstraceDlSym(sqlite3_vfs*,void*, const char *zSymbol))(void); | |
| 16052 static void vfstraceDlClose(sqlite3_vfs*, void*); | |
| 16053 static int vfstraceRandomness(sqlite3_vfs*, int nByte, char *zOut); | |
| 16054 static int vfstraceSleep(sqlite3_vfs*, int microseconds); | |
| 16055 static int vfstraceCurrentTime(sqlite3_vfs*, double*); | |
| 16056 static int vfstraceGetLastError(sqlite3_vfs*, int, char*); | |
| 16057 static int vfstraceCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); | |
| 16058 static int vfstraceSetSystemCall(sqlite3_vfs*,const char*, sqlite3_syscall_ptr); | |
| 16059 static sqlite3_syscall_ptr vfstraceGetSystemCall(sqlite3_vfs*, const char *); | |
| 16060 static const char *vfstraceNextSystemCall(sqlite3_vfs*, const char *zName); | |
| 16061 | |
| 16062 /* | |
| 16063 ** Return a pointer to the tail of the pathname. Examples: | |
| 16064 ** | |
| 16065 ** /home/drh/xyzzy.txt -> xyzzy.txt | |
| 16066 ** xyzzy.txt -> xyzzy.txt | |
| 16067 */ | |
| 16068 static const char *fileTail(const char *z){ | |
| 16069 size_t i; | |
| 16070 if( z==0 ) return 0; | |
| 16071 i = strlen(z)-1; | |
| 16072 while( i>0 && z[i-1]!='/' ){ i--; } | |
| 16073 return &z[i]; | |
| 16074 } | |
| 16075 | |
| 16076 /* | |
| 16077 ** Send trace output defined by zFormat and subsequent arguments. | |
| 16078 */ | |
| 16079 static void vfstrace_printf( | |
| 16080 vfstrace_info *pInfo, | |
| 16081 const char *zFormat, | |
| 16082 ... | |
| 16083 ){ | |
| 16084 va_list ap; | |
| 16085 char *zMsg; | |
| 16086 if( pInfo->bOn ){ | |
| 16087 va_start(ap, zFormat); | |
| 16088 zMsg = sqlite3_vmprintf(zFormat, ap); | |
| 16089 va_end(ap); | |
| 16090 pInfo->xOut(zMsg, pInfo->pOutArg); | |
| 16091 sqlite3_free(zMsg); | |
| 16092 } | |
| 16093 } | |
| 16094 | |
| 16095 /* | |
| 16096 ** Try to convert an error code into a symbolic name for that error code. | |
| 16097 */ | |
| 16098 static const char *vfstrace_errcode_name(int rc ){ | |
| 16099 const char *zVal = 0; | |
| 16100 switch( rc ){ | |
| 16101 case SQLITE_OK: zVal = "SQLITE_OK"; break; | |
| 16102 case SQLITE_INTERNAL: zVal = "SQLITE_INTERNAL"; break; | |
| 16103 case SQLITE_ERROR: zVal = "SQLITE_ERROR"; break; | |
| 16104 case SQLITE_PERM: zVal = "SQLITE_PERM"; break; | |
| 16105 case SQLITE_ABORT: zVal = "SQLITE_ABORT"; break; | |
| 16106 case SQLITE_BUSY: zVal = "SQLITE_BUSY"; break; | |
| 16107 case SQLITE_LOCKED: zVal = "SQLITE_LOCKED"; break; | |
| 16108 case SQLITE_NOMEM: zVal = "SQLITE_NOMEM"; break; | |
| 16109 case SQLITE_READONLY: zVal = "SQLITE_READONLY"; break; | |
| 16110 case SQLITE_INTERRUPT: zVal = "SQLITE_INTERRUPT"; break; | |
| 16111 case SQLITE_IOERR: zVal = "SQLITE_IOERR"; break; | |
| 16112 case SQLITE_CORRUPT: zVal = "SQLITE_CORRUPT"; break; | |
| 16113 case SQLITE_NOTFOUND: zVal = "SQLITE_NOTFOUND"; break; | |
| 16114 case SQLITE_FULL: zVal = "SQLITE_FULL"; break; | |
| 16115 case SQLITE_CANTOPEN: zVal = "SQLITE_CANTOPEN"; break; | |
| 16116 case SQLITE_PROTOCOL: zVal = "SQLITE_PROTOCOL"; break; | |
| 16117 case SQLITE_EMPTY: zVal = "SQLITE_EMPTY"; break; | |
| 16118 case SQLITE_SCHEMA: zVal = "SQLITE_SCHEMA"; break; | |
| 16119 case SQLITE_TOOBIG: zVal = "SQLITE_TOOBIG"; break; | |
| 16120 case SQLITE_CONSTRAINT: zVal = "SQLITE_CONSTRAINT"; break; | |
| 16121 case SQLITE_MISMATCH: zVal = "SQLITE_MISMATCH"; break; | |
| 16122 case SQLITE_MISUSE: zVal = "SQLITE_MISUSE"; break; | |
| 16123 case SQLITE_NOLFS: zVal = "SQLITE_NOLFS"; break; | |
| 16124 case SQLITE_IOERR_READ: zVal = "SQLITE_IOERR_READ"; break; | |
| 16125 case SQLITE_IOERR_SHORT_READ: zVal = "SQLITE_IOERR_SHORT_READ"; break; | |
| 16126 case SQLITE_IOERR_WRITE: zVal = "SQLITE_IOERR_WRITE"; break; | |
| 16127 case SQLITE_IOERR_FSYNC: zVal = "SQLITE_IOERR_FSYNC"; break; | |
| 16128 case SQLITE_IOERR_DIR_FSYNC: zVal = "SQLITE_IOERR_DIR_FSYNC"; break; | |
| 16129 case SQLITE_IOERR_TRUNCATE: zVal = "SQLITE_IOERR_TRUNCATE"; break; | |
| 16130 case SQLITE_IOERR_FSTAT: zVal = "SQLITE_IOERR_FSTAT"; break; | |
| 16131 case SQLITE_IOERR_UNLOCK: zVal = "SQLITE_IOERR_UNLOCK"; break; | |
| 16132 case SQLITE_IOERR_RDLOCK: zVal = "SQLITE_IOERR_RDLOCK"; break; | |
| 16133 case SQLITE_IOERR_DELETE: zVal = "SQLITE_IOERR_DELETE"; break; | |
| 16134 case SQLITE_IOERR_BLOCKED: zVal = "SQLITE_IOERR_BLOCKED"; break; | |
| 16135 case SQLITE_IOERR_NOMEM: zVal = "SQLITE_IOERR_NOMEM"; break; | |
| 16136 case SQLITE_IOERR_ACCESS: zVal = "SQLITE_IOERR_ACCESS"; break; | |
| 16137 case SQLITE_IOERR_CHECKRESERVEDLOCK: | |
| 16138 zVal = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; | |
| 16139 case SQLITE_IOERR_LOCK: zVal = "SQLITE_IOERR_LOCK"; break; | |
| 16140 case SQLITE_IOERR_CLOSE: zVal = "SQLITE_IOERR_CLOSE"; break; | |
| 16141 case SQLITE_IOERR_DIR_CLOSE: zVal = "SQLITE_IOERR_DIR_CLOSE"; break; | |
| 16142 case SQLITE_IOERR_SHMOPEN: zVal = "SQLITE_IOERR_SHMOPEN"; break; | |
| 16143 case SQLITE_IOERR_SHMSIZE: zVal = "SQLITE_IOERR_SHMSIZE"; break; | |
| 16144 case SQLITE_IOERR_SHMLOCK: zVal = "SQLITE_IOERR_SHMLOCK"; break; | |
| 16145 case SQLITE_IOERR_SHMMAP: zVal = "SQLITE_IOERR_SHMMAP"; break; | |
| 16146 case SQLITE_IOERR_SEEK: zVal = "SQLITE_IOERR_SEEK"; break; | |
| 16147 case SQLITE_IOERR_GETTEMPPATH: zVal = "SQLITE_IOERR_GETTEMPPATH"; break; | |
| 16148 case SQLITE_IOERR_CONVPATH: zVal = "SQLITE_IOERR_CONVPATH"; break; | |
| 16149 case SQLITE_READONLY_DBMOVED: zVal = "SQLITE_READONLY_DBMOVED"; break; | |
| 16150 case SQLITE_LOCKED_SHAREDCACHE: zVal = "SQLITE_LOCKED_SHAREDCACHE"; break; | |
| 16151 case SQLITE_BUSY_RECOVERY: zVal = "SQLITE_BUSY_RECOVERY"; break; | |
| 16152 case SQLITE_CANTOPEN_NOTEMPDIR: zVal = "SQLITE_CANTOPEN_NOTEMPDIR"; break; | |
| 16153 } | |
| 16154 return zVal; | |
| 16155 } | |
| 16156 | |
| 16157 /* | |
| 16158 ** Convert value rc into a string and print it using zFormat. zFormat | |
| 16159 ** should have exactly one %s | |
| 16160 */ | |
| 16161 static void vfstrace_print_errcode( | |
| 16162 vfstrace_info *pInfo, | |
| 16163 const char *zFormat, | |
| 16164 int rc | |
| 16165 ){ | |
| 16166 const char *zVal; | |
| 16167 char zBuf[50]; | |
| 16168 zVal = vfstrace_errcode_name(rc); | |
| 16169 if( zVal==0 ){ | |
| 16170 zVal = vfstrace_errcode_name(rc&0xff); | |
| 16171 if( zVal ){ | |
| 16172 sqlite3_snprintf(sizeof(zBuf), zBuf, "%s | 0x%x", zVal, rc&0xffff00); | |
| 16173 }else{ | |
| 16174 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d (0x%x)", rc, rc); | |
| 16175 } | |
| 16176 zVal = zBuf; | |
| 16177 } | |
| 16178 vfstrace_printf(pInfo, zFormat, zVal); | |
| 16179 } | |
| 16180 | |
| 16181 /* | |
| 16182 ** Append to a buffer. | |
| 16183 */ | |
| 16184 static void strappend(char *z, int *pI, const char *zAppend){ | |
| 16185 int i = *pI; | |
| 16186 while( zAppend[0] ){ z[i++] = *(zAppend++); } | |
| 16187 z[i] = 0; | |
| 16188 *pI = i; | |
| 16189 } | |
| 16190 | |
| 16191 /* | |
| 16192 ** Turn tracing output on or off according to mMask. | |
| 16193 */ | |
| 16194 static void vfstraceOnOff(vfstrace_info *pInfo, unsigned int mMask){ | |
| 16195 pInfo->bOn = (pInfo->mTrace & mMask)!=0; | |
| 16196 } | |
| 16197 | |
| 16198 /* | |
| 16199 ** Close an vfstrace-file. | |
| 16200 */ | |
| 16201 static int vfstraceClose(sqlite3_file *pFile){ | |
| 16202 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16203 vfstrace_info *pInfo = p->pInfo; | |
| 16204 int rc; | |
| 16205 vfstraceOnOff(pInfo, VTR_CLOSE); | |
| 16206 vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName); | |
| 16207 rc = p->pReal->pMethods->xClose(p->pReal); | |
| 16208 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16209 if( rc==SQLITE_OK ){ | |
| 16210 sqlite3_free((void*)p->base.pMethods); | |
| 16211 p->base.pMethods = 0; | |
| 16212 } | |
| 16213 return rc; | |
| 16214 } | |
| 16215 | |
| 16216 /* | |
| 16217 ** Read data from an vfstrace-file. | |
| 16218 */ | |
| 16219 static int vfstraceRead( | |
| 16220 sqlite3_file *pFile, | |
| 16221 void *zBuf, | |
| 16222 int iAmt, | |
| 16223 sqlite_int64 iOfst | |
| 16224 ){ | |
| 16225 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16226 vfstrace_info *pInfo = p->pInfo; | |
| 16227 int rc; | |
| 16228 vfstraceOnOff(pInfo, VTR_READ); | |
| 16229 vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)", | |
| 16230 pInfo->zVfsName, p->zFName, iAmt, iOfst); | |
| 16231 rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); | |
| 16232 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16233 return rc; | |
| 16234 } | |
| 16235 | |
| 16236 /* | |
| 16237 ** Write data to an vfstrace-file. | |
| 16238 */ | |
| 16239 static int vfstraceWrite( | |
| 16240 sqlite3_file *pFile, | |
| 16241 const void *zBuf, | |
| 16242 int iAmt, | |
| 16243 sqlite_int64 iOfst | |
| 16244 ){ | |
| 16245 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16246 vfstrace_info *pInfo = p->pInfo; | |
| 16247 int rc; | |
| 16248 vfstraceOnOff(pInfo, VTR_WRITE); | |
| 16249 vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)", | |
| 16250 pInfo->zVfsName, p->zFName, iAmt, iOfst); | |
| 16251 rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst); | |
| 16252 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16253 return rc; | |
| 16254 } | |
| 16255 | |
| 16256 /* | |
| 16257 ** Truncate an vfstrace-file. | |
| 16258 */ | |
| 16259 static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){ | |
| 16260 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16261 vfstrace_info *pInfo = p->pInfo; | |
| 16262 int rc; | |
| 16263 vfstraceOnOff(pInfo, VTR_TRUNC); | |
| 16264 vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName, | |
| 16265 size); | |
| 16266 rc = p->pReal->pMethods->xTruncate(p->pReal, size); | |
| 16267 vfstrace_printf(pInfo, " -> %d\n", rc); | |
| 16268 return rc; | |
| 16269 } | |
| 16270 | |
| 16271 /* | |
| 16272 ** Sync an vfstrace-file. | |
| 16273 */ | |
| 16274 static int vfstraceSync(sqlite3_file *pFile, int flags){ | |
| 16275 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16276 vfstrace_info *pInfo = p->pInfo; | |
| 16277 int rc; | |
| 16278 int i; | |
| 16279 char zBuf[100]; | |
| 16280 memcpy(zBuf, "|0", 3); | |
| 16281 i = 0; | |
| 16282 if( flags & SQLITE_SYNC_FULL ) strappend(zBuf, &i, "|FULL"); | |
| 16283 else if( flags & SQLITE_SYNC_NORMAL ) strappend(zBuf, &i, "|NORMAL"); | |
| 16284 if( flags & SQLITE_SYNC_DATAONLY ) strappend(zBuf, &i, "|DATAONLY"); | |
| 16285 if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){ | |
| 16286 sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags); | |
| 16287 } | |
| 16288 vfstraceOnOff(pInfo, VTR_SYNC); | |
| 16289 vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName, | |
| 16290 &zBuf[1]); | |
| 16291 rc = p->pReal->pMethods->xSync(p->pReal, flags); | |
| 16292 vfstrace_printf(pInfo, " -> %d\n", rc); | |
| 16293 return rc; | |
| 16294 } | |
| 16295 | |
| 16296 /* | |
| 16297 ** Return the current file-size of an vfstrace-file. | |
| 16298 */ | |
| 16299 static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ | |
| 16300 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16301 vfstrace_info *pInfo = p->pInfo; | |
| 16302 int rc; | |
| 16303 vfstraceOnOff(pInfo, VTR_FSIZE); | |
| 16304 vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName); | |
| 16305 rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); | |
| 16306 vfstrace_print_errcode(pInfo, " -> %s,", rc); | |
| 16307 vfstrace_printf(pInfo, " size=%lld\n", *pSize); | |
| 16308 return rc; | |
| 16309 } | |
| 16310 | |
| 16311 /* | |
| 16312 ** Return the name of a lock. | |
| 16313 */ | |
| 16314 static const char *lockName(int eLock){ | |
| 16315 const char *azLockNames[] = { | |
| 16316 "NONE", "SHARED", "RESERVED", "PENDING", "EXCLUSIVE" | |
| 16317 }; | |
| 16318 if( eLock<0 || eLock>=(int)(sizeof(azLockNames)/sizeof(azLockNames[0])) ){ | |
| 16319 return "???"; | |
| 16320 }else{ | |
| 16321 return azLockNames[eLock]; | |
| 16322 } | |
| 16323 } | |
| 16324 | |
| 16325 /* | |
| 16326 ** Lock an vfstrace-file. | |
| 16327 */ | |
| 16328 static int vfstraceLock(sqlite3_file *pFile, int eLock){ | |
| 16329 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16330 vfstrace_info *pInfo = p->pInfo; | |
| 16331 int rc; | |
| 16332 vfstraceOnOff(pInfo, VTR_LOCK); | |
| 16333 vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName, | |
| 16334 lockName(eLock)); | |
| 16335 rc = p->pReal->pMethods->xLock(p->pReal, eLock); | |
| 16336 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16337 return rc; | |
| 16338 } | |
| 16339 | |
| 16340 /* | |
| 16341 ** Unlock an vfstrace-file. | |
| 16342 */ | |
| 16343 static int vfstraceUnlock(sqlite3_file *pFile, int eLock){ | |
| 16344 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16345 vfstrace_info *pInfo = p->pInfo; | |
| 16346 int rc; | |
| 16347 vfstraceOnOff(pInfo, VTR_UNLOCK); | |
| 16348 vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName, | |
| 16349 lockName(eLock)); | |
| 16350 rc = p->pReal->pMethods->xUnlock(p->pReal, eLock); | |
| 16351 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16352 return rc; | |
| 16353 } | |
| 16354 | |
| 16355 /* | |
| 16356 ** Check if another file-handle holds a RESERVED lock on an vfstrace-file. | |
| 16357 */ | |
| 16358 static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){ | |
| 16359 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16360 vfstrace_info *pInfo = p->pInfo; | |
| 16361 int rc; | |
| 16362 vfstraceOnOff(pInfo, VTR_CRL); | |
| 16363 vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)", | |
| 16364 pInfo->zVfsName, p->zFName); | |
| 16365 rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut); | |
| 16366 vfstrace_print_errcode(pInfo, " -> %s", rc); | |
| 16367 vfstrace_printf(pInfo, ", out=%d\n", *pResOut); | |
| 16368 return rc; | |
| 16369 } | |
| 16370 | |
| 16371 /* | |
| 16372 ** File control method. For custom operations on an vfstrace-file. | |
| 16373 */ | |
| 16374 static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){ | |
| 16375 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16376 vfstrace_info *pInfo = p->pInfo; | |
| 16377 int rc; | |
| 16378 char zBuf[100]; | |
| 16379 char zBuf2[100]; | |
| 16380 char *zOp; | |
| 16381 char *zRVal = 0; | |
| 16382 vfstraceOnOff(pInfo, VTR_FCTRL); | |
| 16383 switch( op ){ | |
| 16384 case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break; | |
| 16385 case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break; | |
| 16386 case SQLITE_SET_LOCKPROXYFILE: zOp = "SET_LOCKPROXYFILE"; break; | |
| 16387 case SQLITE_LAST_ERRNO: zOp = "LAST_ERRNO"; break; | |
| 16388 case SQLITE_FCNTL_SIZE_HINT: { | |
| 16389 sqlite3_snprintf(sizeof(zBuf), zBuf, "SIZE_HINT,%lld", | |
| 16390 *(sqlite3_int64*)pArg); | |
| 16391 zOp = zBuf; | |
| 16392 break; | |
| 16393 } | |
| 16394 case SQLITE_FCNTL_CHUNK_SIZE: { | |
| 16395 sqlite3_snprintf(sizeof(zBuf), zBuf, "CHUNK_SIZE,%d", *(int*)pArg); | |
| 16396 zOp = zBuf; | |
| 16397 break; | |
| 16398 } | |
| 16399 case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER"; break; | |
| 16400 case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY"; break; | |
| 16401 case SQLITE_FCNTL_PERSIST_WAL: { | |
| 16402 sqlite3_snprintf(sizeof(zBuf), zBuf, "PERSIST_WAL,%d", *(int*)pArg); | |
| 16403 zOp = zBuf; | |
| 16404 break; | |
| 16405 } | |
| 16406 case SQLITE_FCNTL_OVERWRITE: zOp = "OVERWRITE"; break; | |
| 16407 case SQLITE_FCNTL_VFSNAME: zOp = "VFSNAME"; break; | |
| 16408 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break; | |
| 16409 case SQLITE_FCNTL_PRAGMA: { | |
| 16410 const char *const* a = (const char*const*)pArg; | |
| 16411 if( a[1] && strcmp(a[1],"vfstrace")==0 && a[2] ){ | |
| 16412 const u8 *zArg = (const u8*)a[2]; | |
| 16413 if( zArg[0]>='0' && zArg[0]<='9' ){ | |
| 16414 pInfo->mTrace = (sqlite3_uint64)strtoll(a[2], 0, 0); | |
| 16415 }else{ | |
| 16416 static const struct { | |
| 16417 const char *z; | |
| 16418 unsigned int m; | |
| 16419 } aKw[] = { | |
| 16420 { "all", 0xffffffff }, | |
| 16421 { "close", VTR_CLOSE }, | |
| 16422 { "read", VTR_READ }, | |
| 16423 { "write", VTR_WRITE }, | |
| 16424 { "truncate", VTR_TRUNC }, | |
| 16425 { "sync", VTR_SYNC }, | |
| 16426 { "filesize", VTR_FSIZE }, | |
| 16427 { "lock", VTR_LOCK }, | |
| 16428 { "unlock", VTR_UNLOCK }, | |
| 16429 { "checkreservedlock", VTR_CRL }, | |
| 16430 { "filecontrol", VTR_FCTRL }, | |
| 16431 { "sectorsize", VTR_SECSZ }, | |
| 16432 { "devicecharacteristics", VTR_DEVCHAR }, | |
| 16433 { "shmlock", VTR_SHMLOCK }, | |
| 16434 { "shmmap", VTR_SHMMAP }, | |
| 16435 { "shmummap", VTR_SHMUNMAP }, | |
| 16436 { "shmbarrier", VTR_SHMBAR }, | |
| 16437 { "open", VTR_OPEN }, | |
| 16438 { "delete", VTR_DELETE }, | |
| 16439 { "access", VTR_ACCESS }, | |
| 16440 { "fullpathname", VTR_FULLPATH }, | |
| 16441 { "dlopen", VTR_DLOPEN }, | |
| 16442 { "dlerror", VTR_DLERR }, | |
| 16443 { "dlsym", VTR_DLSYM }, | |
| 16444 { "dlclose", VTR_DLCLOSE }, | |
| 16445 { "randomness", VTR_RAND }, | |
| 16446 { "sleep", VTR_SLEEP }, | |
| 16447 { "currenttime", VTR_CURTIME }, | |
| 16448 { "currenttimeint64", VTR_CURTIME }, | |
| 16449 { "getlasterror", VTR_LASTERR }, | |
| 16450 { "fetch", VTR_FETCH }, | |
| 16451 }; | |
| 16452 int onOff = 1; | |
| 16453 while( zArg[0] ){ | |
| 16454 int jj, n; | |
| 16455 while( zArg[0]!=0 && zArg[0]!='-' && zArg[0]!='+' | |
| 16456 && !isalpha(zArg[0]) ) zArg++; | |
| 16457 if( zArg[0]==0 ) break; | |
| 16458 if( zArg[0]=='-' ){ | |
| 16459 onOff = 0; | |
| 16460 zArg++; | |
| 16461 }else if( zArg[0]=='+' ){ | |
| 16462 onOff = 1; | |
| 16463 zArg++; | |
| 16464 } | |
| 16465 while( !isalpha(zArg[0]) ){ | |
| 16466 if( zArg[0]==0 ) break; | |
| 16467 zArg++; | |
| 16468 } | |
| 16469 if( zArg[0]=='x' && isalpha(zArg[1]) ) zArg++; | |
| 16470 for(n=0; isalpha(zArg[n]); n++){} | |
| 16471 for(jj=0; jj<(int)(sizeof(aKw)/sizeof(aKw[0])); jj++){ | |
| 16472 if( sqlite3_strnicmp(aKw[jj].z,(const char*)zArg,n)==0 ){ | |
| 16473 if( onOff ){ | |
| 16474 pInfo->mTrace |= aKw[jj].m; | |
| 16475 }else{ | |
| 16476 pInfo->mTrace &= ~aKw[jj].m; | |
| 16477 } | |
| 16478 break; | |
| 16479 } | |
| 16480 } | |
| 16481 zArg += n; | |
| 16482 } | |
| 16483 } | |
| 16484 } | |
| 16485 sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]); | |
| 16486 zOp = zBuf; | |
| 16487 break; | |
| 16488 } | |
| 16489 case SQLITE_FCNTL_BUSYHANDLER: zOp = "BUSYHANDLER"; break; | |
| 16490 case SQLITE_FCNTL_TEMPFILENAME: zOp = "TEMPFILENAME"; break; | |
| 16491 case SQLITE_FCNTL_MMAP_SIZE: { | |
| 16492 sqlite3_int64 iMMap = *(sqlite3_int64*)pArg; | |
| 16493 sqlite3_snprintf(sizeof(zBuf), zBuf, "MMAP_SIZE,%lld",iMMap); | |
| 16494 zOp = zBuf; | |
| 16495 break; | |
| 16496 } | |
| 16497 case SQLITE_FCNTL_TRACE: zOp = "TRACE"; break; | |
| 16498 case SQLITE_FCNTL_HAS_MOVED: zOp = "HAS_MOVED"; break; | |
| 16499 case SQLITE_FCNTL_SYNC: zOp = "SYNC"; break; | |
| 16500 case SQLITE_FCNTL_COMMIT_PHASETWO: zOp = "COMMIT_PHASETWO"; break; | |
| 16501 case SQLITE_FCNTL_WIN32_SET_HANDLE: zOp = "WIN32_SET_HANDLE"; break; | |
| 16502 case SQLITE_FCNTL_WAL_BLOCK: zOp = "WAL_BLOCK"; break; | |
| 16503 case SQLITE_FCNTL_ZIPVFS: zOp = "ZIPVFS"; break; | |
| 16504 case SQLITE_FCNTL_RBU: zOp = "RBU"; break; | |
| 16505 case SQLITE_FCNTL_VFS_POINTER: zOp = "VFS_POINTER"; break; | |
| 16506 case SQLITE_FCNTL_JOURNAL_POINTER: zOp = "JOURNAL_POINTER"; break; | |
| 16507 case SQLITE_FCNTL_WIN32_GET_HANDLE: zOp = "WIN32_GET_HANDLE"; break; | |
| 16508 case SQLITE_FCNTL_PDB: zOp = "PDB"; break; | |
| 16509 case SQLITE_FCNTL_BEGIN_ATOMIC_WRITE: zOp = "BEGIN_ATOMIC_WRITE"; break; | |
| 16510 case SQLITE_FCNTL_COMMIT_ATOMIC_WRITE: zOp = "COMMIT_ATOMIC_WRITE"; break; | |
| 16511 case SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE: { | |
| 16512 zOp = "ROLLBACK_ATOMIC_WRITE"; | |
| 16513 break; | |
| 16514 } | |
| 16515 case SQLITE_FCNTL_LOCK_TIMEOUT: { | |
| 16516 sqlite3_snprintf(sizeof(zBuf), zBuf, "LOCK_TIMEOUT,%d", *(int*)pArg); | |
| 16517 zOp = zBuf; | |
| 16518 break; | |
| 16519 } | |
| 16520 case SQLITE_FCNTL_DATA_VERSION: zOp = "DATA_VERSION"; break; | |
| 16521 case SQLITE_FCNTL_SIZE_LIMIT: zOp = "SIZE_LIMIT"; break; | |
| 16522 case SQLITE_FCNTL_CKPT_DONE: zOp = "CKPT_DONE"; break; | |
| 16523 case SQLITE_FCNTL_RESERVE_BYTES: zOp = "RESERVED_BYTES"; break; | |
| 16524 case SQLITE_FCNTL_CKPT_START: zOp = "CKPT_START"; break; | |
| 16525 case SQLITE_FCNTL_EXTERNAL_READER: zOp = "EXTERNAL_READER"; break; | |
| 16526 case SQLITE_FCNTL_CKSM_FILE: zOp = "CKSM_FILE"; break; | |
| 16527 case SQLITE_FCNTL_RESET_CACHE: zOp = "RESET_CACHE"; break; | |
| 16528 case 0xca093fa0: zOp = "DB_UNCHANGED"; break; | |
| 16529 default: { | |
| 16530 sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op); | |
| 16531 zOp = zBuf; | |
| 16532 break; | |
| 16533 } | |
| 16534 } | |
| 16535 vfstrace_printf(pInfo, "%s.xFileControl(%s,%s)", | |
| 16536 pInfo->zVfsName, p->zFName, zOp); | |
| 16537 rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg); | |
| 16538 if( rc==SQLITE_OK ){ | |
| 16539 switch( op ){ | |
| 16540 case SQLITE_FCNTL_VFSNAME: { | |
| 16541 *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z", | |
| 16542 pInfo->zVfsName, *(char**)pArg); | |
| 16543 zRVal = *(char**)pArg; | |
| 16544 break; | |
| 16545 } | |
| 16546 case SQLITE_FCNTL_MMAP_SIZE: { | |
| 16547 sqlite3_snprintf(sizeof(zBuf2), zBuf2, "%lld", *(sqlite3_int64*)pArg); | |
| 16548 zRVal = zBuf2; | |
| 16549 break; | |
| 16550 } | |
| 16551 case SQLITE_FCNTL_HAS_MOVED: | |
| 16552 case SQLITE_FCNTL_PERSIST_WAL: { | |
| 16553 sqlite3_snprintf(sizeof(zBuf2), zBuf2, "%d", *(int*)pArg); | |
| 16554 zRVal = zBuf2; | |
| 16555 break; | |
| 16556 } | |
| 16557 case SQLITE_FCNTL_PRAGMA: | |
| 16558 case SQLITE_FCNTL_TEMPFILENAME: { | |
| 16559 zRVal = *(char**)pArg; | |
| 16560 break; | |
| 16561 } | |
| 16562 } | |
| 16563 } | |
| 16564 if( zRVal ){ | |
| 16565 vfstrace_print_errcode(pInfo, " -> %s", rc); | |
| 16566 vfstrace_printf(pInfo, ", %s\n", zRVal); | |
| 16567 }else{ | |
| 16568 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16569 } | |
| 16570 return rc; | |
| 16571 } | |
| 16572 | |
| 16573 /* | |
| 16574 ** Return the sector-size in bytes for an vfstrace-file. | |
| 16575 */ | |
| 16576 static int vfstraceSectorSize(sqlite3_file *pFile){ | |
| 16577 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16578 vfstrace_info *pInfo = p->pInfo; | |
| 16579 int rc; | |
| 16580 vfstraceOnOff(pInfo, VTR_SECSZ); | |
| 16581 vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName); | |
| 16582 rc = p->pReal->pMethods->xSectorSize(p->pReal); | |
| 16583 vfstrace_printf(pInfo, " -> %d\n", rc); | |
| 16584 return rc; | |
| 16585 } | |
| 16586 | |
| 16587 /* | |
| 16588 ** Return the device characteristic flags supported by an vfstrace-file. | |
| 16589 */ | |
| 16590 static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){ | |
| 16591 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16592 vfstrace_info *pInfo = p->pInfo; | |
| 16593 int rc; | |
| 16594 vfstraceOnOff(pInfo, VTR_DEVCHAR); | |
| 16595 vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)", | |
| 16596 pInfo->zVfsName, p->zFName); | |
| 16597 rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal); | |
| 16598 vfstrace_printf(pInfo, " -> 0x%08x\n", rc); | |
| 16599 return rc; | |
| 16600 } | |
| 16601 | |
| 16602 /* | |
| 16603 ** Shared-memory operations. | |
| 16604 */ | |
| 16605 static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ | |
| 16606 static const char *azLockName[] = { | |
| 16607 "WRITE", | |
| 16608 "CKPT", | |
| 16609 "RECOVER", | |
| 16610 "READ0", | |
| 16611 "READ1", | |
| 16612 "READ2", | |
| 16613 "READ3", | |
| 16614 "READ4", | |
| 16615 }; | |
| 16616 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16617 vfstrace_info *pInfo = p->pInfo; | |
| 16618 int rc; | |
| 16619 char zLck[100]; | |
| 16620 int i = 0; | |
| 16621 vfstraceOnOff(pInfo, VTR_SHMLOCK); | |
| 16622 memcpy(zLck, "|0", 3); | |
| 16623 if( flags & SQLITE_SHM_UNLOCK ) strappend(zLck, &i, "|UNLOCK"); | |
| 16624 if( flags & SQLITE_SHM_LOCK ) strappend(zLck, &i, "|LOCK"); | |
| 16625 if( flags & SQLITE_SHM_SHARED ) strappend(zLck, &i, "|SHARED"); | |
| 16626 if( flags & SQLITE_SHM_EXCLUSIVE ) strappend(zLck, &i, "|EXCLUSIVE"); | |
| 16627 if( flags & ~(0xf) ){ | |
| 16628 sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags); | |
| 16629 } | |
| 16630 if( ofst>=0 && ofst<(int)(sizeof(azLockName)/sizeof(azLockName[0])) ){ | |
| 16631 vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d(%s),n=%d,%s)", | |
| 16632 pInfo->zVfsName, p->zFName, ofst, azLockName[ofst], | |
| 16633 n, &zLck[1]); | |
| 16634 }else{ | |
| 16635 vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=5d,n=%d,%s)", | |
| 16636 pInfo->zVfsName, p->zFName, ofst, | |
| 16637 n, &zLck[1]); | |
| 16638 } | |
| 16639 rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags); | |
| 16640 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16641 return rc; | |
| 16642 } | |
| 16643 static int vfstraceShmMap( | |
| 16644 sqlite3_file *pFile, | |
| 16645 int iRegion, | |
| 16646 int szRegion, | |
| 16647 int isWrite, | |
| 16648 void volatile **pp | |
| 16649 ){ | |
| 16650 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16651 vfstrace_info *pInfo = p->pInfo; | |
| 16652 int rc; | |
| 16653 vfstraceOnOff(pInfo, VTR_SHMMAP); | |
| 16654 vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)", | |
| 16655 pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite); | |
| 16656 rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp); | |
| 16657 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16658 return rc; | |
| 16659 } | |
| 16660 static void vfstraceShmBarrier(sqlite3_file *pFile){ | |
| 16661 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16662 vfstrace_info *pInfo = p->pInfo; | |
| 16663 vfstraceOnOff(pInfo, VTR_SHMBAR); | |
| 16664 vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName); | |
| 16665 p->pReal->pMethods->xShmBarrier(p->pReal); | |
| 16666 } | |
| 16667 static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){ | |
| 16668 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16669 vfstrace_info *pInfo = p->pInfo; | |
| 16670 int rc; | |
| 16671 vfstraceOnOff(pInfo, VTR_SHMUNMAP); | |
| 16672 vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)", | |
| 16673 pInfo->zVfsName, p->zFName, delFlag); | |
| 16674 rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag); | |
| 16675 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16676 return rc; | |
| 16677 } | |
| 16678 static int vfstraceFetch(sqlite3_file *pFile, i64 iOff, int nAmt, void **pptr){ | |
| 16679 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16680 vfstrace_info *pInfo = p->pInfo; | |
| 16681 int rc; | |
| 16682 vfstraceOnOff(pInfo, VTR_FETCH); | |
| 16683 vfstrace_printf(pInfo, "%s.xFetch(%s,iOff=%lld,nAmt=%d,p=%p)", | |
| 16684 pInfo->zVfsName, p->zFName, iOff, nAmt, *pptr); | |
| 16685 rc = p->pReal->pMethods->xFetch(p->pReal, iOff, nAmt, pptr); | |
| 16686 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16687 return rc; | |
| 16688 } | |
| 16689 static int vfstraceUnfetch(sqlite3_file *pFile, i64 iOff, void *ptr){ | |
| 16690 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16691 vfstrace_info *pInfo = p->pInfo; | |
| 16692 int rc; | |
| 16693 vfstraceOnOff(pInfo, VTR_FETCH); | |
| 16694 vfstrace_printf(pInfo, "%s.xUnfetch(%s,iOff=%lld,p=%p)", | |
| 16695 pInfo->zVfsName, p->zFName, iOff, ptr); | |
| 16696 rc = p->pReal->pMethods->xUnfetch(p->pReal, iOff, ptr); | |
| 16697 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16698 return rc; | |
| 16699 } | |
| 16700 | |
| 16701 | |
| 16702 /* | |
| 16703 ** Open an vfstrace file handle. | |
| 16704 */ | |
| 16705 static int vfstraceOpen( | |
| 16706 sqlite3_vfs *pVfs, | |
| 16707 const char *zName, | |
| 16708 sqlite3_file *pFile, | |
| 16709 int flags, | |
| 16710 int *pOutFlags | |
| 16711 ){ | |
| 16712 int rc; | |
| 16713 vfstrace_file *p = (vfstrace_file *)pFile; | |
| 16714 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16715 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16716 p->pInfo = pInfo; | |
| 16717 p->zFName = zName ? fileTail(zName) : "<temp>"; | |
| 16718 p->pReal = (sqlite3_file *)&p[1]; | |
| 16719 rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags); | |
| 16720 vfstraceOnOff(pInfo, VTR_OPEN); | |
| 16721 vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)", | |
| 16722 pInfo->zVfsName, p->zFName, flags); | |
| 16723 if( p->pReal->pMethods ){ | |
| 16724 sqlite3_io_methods *pNew = sqlite3_malloc( sizeof(*pNew) ); | |
| 16725 const sqlite3_io_methods *pSub = p->pReal->pMethods; | |
| 16726 memset(pNew, 0, sizeof(*pNew)); | |
| 16727 pNew->iVersion = pSub->iVersion; | |
| 16728 pNew->xClose = vfstraceClose; | |
| 16729 pNew->xRead = vfstraceRead; | |
| 16730 pNew->xWrite = vfstraceWrite; | |
| 16731 pNew->xTruncate = vfstraceTruncate; | |
| 16732 pNew->xSync = vfstraceSync; | |
| 16733 pNew->xFileSize = vfstraceFileSize; | |
| 16734 pNew->xLock = vfstraceLock; | |
| 16735 pNew->xUnlock = vfstraceUnlock; | |
| 16736 pNew->xCheckReservedLock = vfstraceCheckReservedLock; | |
| 16737 pNew->xFileControl = vfstraceFileControl; | |
| 16738 pNew->xSectorSize = vfstraceSectorSize; | |
| 16739 pNew->xDeviceCharacteristics = vfstraceDeviceCharacteristics; | |
| 16740 if( pNew->iVersion>=2 ){ | |
| 16741 pNew->xShmMap = pSub->xShmMap ? vfstraceShmMap : 0; | |
| 16742 pNew->xShmLock = pSub->xShmLock ? vfstraceShmLock : 0; | |
| 16743 pNew->xShmBarrier = pSub->xShmBarrier ? vfstraceShmBarrier : 0; | |
| 16744 pNew->xShmUnmap = pSub->xShmUnmap ? vfstraceShmUnmap : 0; | |
| 16745 } | |
| 16746 if( pNew->iVersion>=3 ){ | |
| 16747 pNew->xFetch = pSub->xFetch ? vfstraceFetch : 0; | |
| 16748 pNew->xUnfetch = pSub->xUnfetch ? vfstraceUnfetch : 0; | |
| 16749 } | |
| 16750 pFile->pMethods = pNew; | |
| 16751 } | |
| 16752 vfstrace_print_errcode(pInfo, " -> %s", rc); | |
| 16753 if( pOutFlags ){ | |
| 16754 vfstrace_printf(pInfo, ", outFlags=0x%x\n", *pOutFlags); | |
| 16755 }else{ | |
| 16756 vfstrace_printf(pInfo, "\n"); | |
| 16757 } | |
| 16758 return rc; | |
| 16759 } | |
| 16760 | |
| 16761 /* | |
| 16762 ** Delete the file located at zPath. If the dirSync argument is true, | |
| 16763 ** ensure the file-system modifications are synced to disk before | |
| 16764 ** returning. | |
| 16765 */ | |
| 16766 static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ | |
| 16767 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16768 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16769 int rc; | |
| 16770 vfstraceOnOff(pInfo, VTR_DELETE); | |
| 16771 vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)", | |
| 16772 pInfo->zVfsName, zPath, dirSync); | |
| 16773 rc = pRoot->xDelete(pRoot, zPath, dirSync); | |
| 16774 vfstrace_print_errcode(pInfo, " -> %s\n", rc); | |
| 16775 return rc; | |
| 16776 } | |
| 16777 | |
| 16778 /* | |
| 16779 ** Test for access permissions. Return true if the requested permission | |
| 16780 ** is available, or false otherwise. | |
| 16781 */ | |
| 16782 static int vfstraceAccess( | |
| 16783 sqlite3_vfs *pVfs, | |
| 16784 const char *zPath, | |
| 16785 int flags, | |
| 16786 int *pResOut | |
| 16787 ){ | |
| 16788 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16789 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16790 int rc; | |
| 16791 vfstraceOnOff(pInfo, VTR_ACCESS); | |
| 16792 vfstrace_printf(pInfo, "%s.xAccess(\"%s\",%d)", | |
| 16793 pInfo->zVfsName, zPath, flags); | |
| 16794 rc = pRoot->xAccess(pRoot, zPath, flags, pResOut); | |
| 16795 vfstrace_print_errcode(pInfo, " -> %s", rc); | |
| 16796 vfstrace_printf(pInfo, ", out=%d\n", *pResOut); | |
| 16797 return rc; | |
| 16798 } | |
| 16799 | |
| 16800 /* | |
| 16801 ** Populate buffer zOut with the full canonical pathname corresponding | |
| 16802 ** to the pathname in zPath. zOut is guaranteed to point to a buffer | |
| 16803 ** of at least (DEVSYM_MAX_PATHNAME+1) bytes. | |
| 16804 */ | |
| 16805 static int vfstraceFullPathname( | |
| 16806 sqlite3_vfs *pVfs, | |
| 16807 const char *zPath, | |
| 16808 int nOut, | |
| 16809 char *zOut | |
| 16810 ){ | |
| 16811 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16812 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16813 int rc; | |
| 16814 vfstraceOnOff(pInfo, VTR_FULLPATH); | |
| 16815 vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")", | |
| 16816 pInfo->zVfsName, zPath); | |
| 16817 rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut); | |
| 16818 vfstrace_print_errcode(pInfo, " -> %s", rc); | |
| 16819 vfstrace_printf(pInfo, ", out=\"%.*s\"\n", nOut, zOut); | |
| 16820 return rc; | |
| 16821 } | |
| 16822 | |
| 16823 /* | |
| 16824 ** Open the dynamic library located at zPath and return a handle. | |
| 16825 */ | |
| 16826 static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){ | |
| 16827 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16828 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16829 vfstraceOnOff(pInfo, VTR_DLOPEN); | |
| 16830 vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath); | |
| 16831 return pRoot->xDlOpen(pRoot, zPath); | |
| 16832 } | |
| 16833 | |
| 16834 /* | |
| 16835 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable | |
| 16836 ** utf-8 string describing the most recent error encountered associated | |
| 16837 ** with dynamic libraries. | |
| 16838 */ | |
| 16839 static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ | |
| 16840 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16841 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16842 vfstraceOnOff(pInfo, VTR_DLERR); | |
| 16843 vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte); | |
| 16844 pRoot->xDlError(pRoot, nByte, zErrMsg); | |
| 16845 vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg); | |
| 16846 } | |
| 16847 | |
| 16848 /* | |
| 16849 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle. | |
| 16850 */ | |
| 16851 static void (*vfstraceDlSym(sqlite3_vfs *pVfs,void *p,const char *zSym))(void){ | |
| 16852 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16853 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16854 vfstrace_printf(pInfo, "%s.xDlSym(\"%s\")\n", pInfo->zVfsName, zSym); | |
| 16855 return pRoot->xDlSym(pRoot, p, zSym); | |
| 16856 } | |
| 16857 | |
| 16858 /* | |
| 16859 ** Close the dynamic library handle pHandle. | |
| 16860 */ | |
| 16861 static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){ | |
| 16862 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16863 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16864 vfstraceOnOff(pInfo, VTR_DLCLOSE); | |
| 16865 vfstrace_printf(pInfo, "%s.xDlClose()\n", pInfo->zVfsName); | |
| 16866 pRoot->xDlClose(pRoot, pHandle); | |
| 16867 } | |
| 16868 | |
| 16869 /* | |
| 16870 ** Populate the buffer pointed to by zBufOut with nByte bytes of | |
| 16871 ** random data. | |
| 16872 */ | |
| 16873 static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ | |
| 16874 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16875 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16876 vfstraceOnOff(pInfo, VTR_RAND); | |
| 16877 vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte); | |
| 16878 return pRoot->xRandomness(pRoot, nByte, zBufOut); | |
| 16879 } | |
| 16880 | |
| 16881 /* | |
| 16882 ** Sleep for nMicro microseconds. Return the number of microseconds | |
| 16883 ** actually slept. | |
| 16884 */ | |
| 16885 static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){ | |
| 16886 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16887 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16888 vfstraceOnOff(pInfo, VTR_SLEEP); | |
| 16889 vfstrace_printf(pInfo, "%s.xSleep(%d)\n", pInfo->zVfsName, nMicro); | |
| 16890 return pRoot->xSleep(pRoot, nMicro); | |
| 16891 } | |
| 16892 | |
| 16893 /* | |
| 16894 ** Return the current time as a Julian Day number in *pTimeOut. | |
| 16895 */ | |
| 16896 static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ | |
| 16897 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16898 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16899 int rc; | |
| 16900 vfstraceOnOff(pInfo, VTR_CURTIME); | |
| 16901 vfstrace_printf(pInfo, "%s.xCurrentTime()", pInfo->zVfsName); | |
| 16902 rc = pRoot->xCurrentTime(pRoot, pTimeOut); | |
| 16903 vfstrace_printf(pInfo, " -> %.17g\n", *pTimeOut); | |
| 16904 return rc; | |
| 16905 } | |
| 16906 static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ | |
| 16907 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16908 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16909 int rc; | |
| 16910 vfstraceOnOff(pInfo, VTR_CURTIME); | |
| 16911 vfstrace_printf(pInfo, "%s.xCurrentTimeInt64()", pInfo->zVfsName); | |
| 16912 rc = pRoot->xCurrentTimeInt64(pRoot, pTimeOut); | |
| 16913 vfstrace_printf(pInfo, " -> %lld\n", *pTimeOut); | |
| 16914 return rc; | |
| 16915 } | |
| 16916 | |
| 16917 /* | |
| 16918 ** Return the most recent error code and message | |
| 16919 */ | |
| 16920 static int vfstraceGetLastError(sqlite3_vfs *pVfs, int nErr, char *zErr){ | |
| 16921 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16922 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16923 int rc; | |
| 16924 vfstraceOnOff(pInfo, VTR_LASTERR); | |
| 16925 vfstrace_printf(pInfo, "%s.xGetLastError(%d,zBuf)", pInfo->zVfsName, nErr); | |
| 16926 if( nErr ) zErr[0] = 0; | |
| 16927 rc = pRoot->xGetLastError(pRoot, nErr, zErr); | |
| 16928 vfstrace_printf(pInfo, " -> zBuf[] = \"%s\", rc = %d\n", nErr?zErr:"", rc); | |
| 16929 return rc; | |
| 16930 } | |
| 16931 | |
| 16932 /* | |
| 16933 ** Override system calls. | |
| 16934 */ | |
| 16935 static int vfstraceSetSystemCall( | |
| 16936 sqlite3_vfs *pVfs, | |
| 16937 const char *zName, | |
| 16938 sqlite3_syscall_ptr pFunc | |
| 16939 ){ | |
| 16940 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16941 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16942 return pRoot->xSetSystemCall(pRoot, zName, pFunc); | |
| 16943 } | |
| 16944 static sqlite3_syscall_ptr vfstraceGetSystemCall( | |
| 16945 sqlite3_vfs *pVfs, | |
| 16946 const char *zName | |
| 16947 ){ | |
| 16948 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16949 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16950 return pRoot->xGetSystemCall(pRoot, zName); | |
| 16951 } | |
| 16952 static const char *vfstraceNextSystemCall(sqlite3_vfs *pVfs, const char *zName){ | |
| 16953 vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; | |
| 16954 sqlite3_vfs *pRoot = pInfo->pRootVfs; | |
| 16955 return pRoot->xNextSystemCall(pRoot, zName); | |
| 16956 } | |
| 16957 | |
| 16958 | |
| 16959 /* | |
| 16960 ** Clients invoke this routine to construct a new trace-vfs shim. | |
| 16961 ** | |
| 16962 ** Return SQLITE_OK on success. | |
| 16963 ** | |
| 16964 ** SQLITE_NOMEM is returned in the case of a memory allocation error. | |
| 16965 ** SQLITE_NOTFOUND is returned if zOldVfsName does not exist. | |
| 16966 */ | |
| 16967 int vfstrace_register( | |
| 16968 const char *zTraceName, /* Name of the newly constructed VFS */ | |
| 16969 const char *zOldVfsName, /* Name of the underlying VFS */ | |
| 16970 int (*xOut)(const char*,void*), /* Output routine. ex: fputs */ | |
| 16971 void *pOutArg, /* 2nd argument to xOut. ex: stderr */ | |
| 16972 int makeDefault /* True to make the new VFS the default */ | |
| 16973 ){ | |
| 16974 sqlite3_vfs *pNew; | |
| 16975 sqlite3_vfs *pRoot; | |
| 16976 vfstrace_info *pInfo; | |
| 16977 size_t nName; | |
| 16978 size_t nByte; | |
| 16979 | |
| 16980 pRoot = sqlite3_vfs_find(zOldVfsName); | |
| 16981 if( pRoot==0 ) return SQLITE_NOTFOUND; | |
| 16982 nName = strlen(zTraceName); | |
| 16983 nByte = sizeof(*pNew) + sizeof(*pInfo) + nName + 1; | |
| 16984 pNew = sqlite3_malloc64( nByte ); | |
| 16985 if( pNew==0 ) return SQLITE_NOMEM; | |
| 16986 memset(pNew, 0, nByte); | |
| 16987 pInfo = (vfstrace_info*)&pNew[1]; | |
| 16988 pNew->iVersion = pRoot->iVersion; | |
| 16989 pNew->szOsFile = pRoot->szOsFile + sizeof(vfstrace_file); | |
| 16990 pNew->mxPathname = pRoot->mxPathname; | |
| 16991 pNew->zName = (char*)&pInfo[1]; | |
| 16992 memcpy((char*)&pInfo[1], zTraceName, nName+1); | |
| 16993 pNew->pAppData = pInfo; | |
| 16994 pNew->xOpen = vfstraceOpen; | |
| 16995 pNew->xDelete = vfstraceDelete; | |
| 16996 pNew->xAccess = vfstraceAccess; | |
| 16997 pNew->xFullPathname = vfstraceFullPathname; | |
| 16998 pNew->xDlOpen = pRoot->xDlOpen==0 ? 0 : vfstraceDlOpen; | |
| 16999 pNew->xDlError = pRoot->xDlError==0 ? 0 : vfstraceDlError; | |
| 17000 pNew->xDlSym = pRoot->xDlSym==0 ? 0 : vfstraceDlSym; | |
| 17001 pNew->xDlClose = pRoot->xDlClose==0 ? 0 : vfstraceDlClose; | |
| 17002 pNew->xRandomness = vfstraceRandomness; | |
| 17003 pNew->xSleep = vfstraceSleep; | |
| 17004 pNew->xCurrentTime = vfstraceCurrentTime; | |
| 17005 pNew->xGetLastError = pRoot->xGetLastError==0 ? 0 : vfstraceGetLastError; | |
| 17006 if( pNew->iVersion>=2 ){ | |
| 17007 pNew->xCurrentTimeInt64 = pRoot->xCurrentTimeInt64==0 ? 0 : | |
| 17008 vfstraceCurrentTimeInt64; | |
| 17009 if( pNew->iVersion>=3 ){ | |
| 17010 pNew->xSetSystemCall = pRoot->xSetSystemCall==0 ? 0 : | |
| 17011 vfstraceSetSystemCall; | |
| 17012 pNew->xGetSystemCall = pRoot->xGetSystemCall==0 ? 0 : | |
| 17013 vfstraceGetSystemCall; | |
| 17014 pNew->xNextSystemCall = pRoot->xNextSystemCall==0 ? 0 : | |
| 17015 vfstraceNextSystemCall; | |
| 17016 } | |
| 17017 } | |
| 17018 pInfo->pRootVfs = pRoot; | |
| 17019 pInfo->xOut = xOut; | |
| 17020 pInfo->pOutArg = pOutArg; | |
| 17021 pInfo->zVfsName = pNew->zName; | |
| 17022 pInfo->pTraceVfs = pNew; | |
| 17023 pInfo->mTrace = 0xffffffff; | |
| 17024 pInfo->bOn = 1; | |
| 17025 vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n", | |
| 17026 pInfo->zVfsName, pRoot->zName); | |
| 17027 return sqlite3_vfs_register(pNew, makeDefault); | |
| 17028 } | |
| 17029 | |
| 17030 /* | |
| 17031 ** Look for the named VFS. If it is a TRACEVFS, then unregister it | |
| 17032 ** and delete it. | |
| 17033 */ | |
| 17034 void vfstrace_unregister(const char *zTraceName){ | |
| 17035 sqlite3_vfs *pVfs = sqlite3_vfs_find(zTraceName); | |
| 17036 if( pVfs==0 ) return; | |
| 17037 if( pVfs->xOpen!=vfstraceOpen ) return; | |
| 17038 sqlite3_vfs_unregister(pVfs); | |
| 17039 sqlite3_free(pVfs); | |
| 17040 } | |
| 17041 | |
| 17042 /************************* End ../ext/misc/vfstrace.c ********************/ | |
| 17043 | |
| 17044 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) | |
| 17045 #define SQLITE_SHELL_HAVE_RECOVER 1 | |
| 17046 #else | |
| 17047 #define SQLITE_SHELL_HAVE_RECOVER 0 | |
| 17048 #endif | |
| 17049 #if SQLITE_SHELL_HAVE_RECOVER | |
| 17050 /************************* Begin ../ext/recover/sqlite3recover.h ******************/ | |
| 17051 /* | |
| 17052 ** 2022-08-27 | |
| 17053 ** | |
| 17054 ** The author disclaims copyright to this source code. In place of | |
| 17055 ** a legal notice, here is a blessing: | |
| 17056 ** | |
| 17057 ** May you do good and not evil. | |
| 17058 ** May you find forgiveness for yourself and forgive others. | |
| 17059 ** May you share freely, never taking more than you give. | |
| 17060 ** | |
| 17061 ************************************************************************* | |
| 17062 ** | |
| 17063 ** This file contains the public interface to the "recover" extension - | |
| 17064 ** an SQLite extension designed to recover data from corrupted database | |
| 17065 ** files. | |
| 17066 */ | |
| 17067 | |
| 17068 /* | |
| 17069 ** OVERVIEW: | |
| 17070 ** | |
| 17071 ** To use the API to recover data from a corrupted database, an | |
| 17072 ** application: | |
| 17073 ** | |
| 17074 ** 1) Creates an sqlite3_recover handle by calling either | |
| 17075 ** sqlite3_recover_init() or sqlite3_recover_init_sql(). | |
| 17076 ** | |
| 17077 ** 2) Configures the new handle using one or more calls to | |
| 17078 ** sqlite3_recover_config(). | |
| 17079 ** | |
| 17080 ** 3) Executes the recovery by repeatedly calling sqlite3_recover_step() on | |
| 17081 ** the handle until it returns something other than SQLITE_OK. If it | |
| 17082 ** returns SQLITE_DONE, then the recovery operation completed without | |
| 17083 ** error. If it returns some other non-SQLITE_OK value, then an error | |
| 17084 ** has occurred. | |
| 17085 ** | |
| 17086 ** 4) Retrieves any error code and English language error message using the | |
| 17087 ** sqlite3_recover_errcode() and sqlite3_recover_errmsg() APIs, | |
| 17088 ** respectively. | |
| 17089 ** | |
| 17090 ** 5) Destroys the sqlite3_recover handle and frees all resources | |
| 17091 ** using sqlite3_recover_finish(). | |
| 17092 ** | |
| 17093 ** The application may abandon the recovery operation at any point | |
| 17094 ** before it is finished by passing the sqlite3_recover handle to | |
| 17095 ** sqlite3_recover_finish(). This is not an error, but the final state | |
| 17096 ** of the output database, or the results of running the partial script | |
| 17097 ** delivered to the SQL callback, are undefined. | |
| 17098 */ | |
| 17099 | |
| 17100 #ifndef _SQLITE_RECOVER_H | |
| 17101 #define _SQLITE_RECOVER_H | |
| 17102 | |
| 17103 /* #include "sqlite3.h" */ | |
| 17104 | |
| 17105 #ifdef __cplusplus | |
| 17106 extern "C" { | |
| 17107 #endif | |
| 17108 | |
| 17109 /* | |
| 17110 ** An instance of the sqlite3_recover object represents a recovery | |
| 17111 ** operation in progress. | |
| 17112 ** | |
| 17113 ** Constructors: | |
| 17114 ** | |
| 17115 ** sqlite3_recover_init() | |
| 17116 ** sqlite3_recover_init_sql() | |
| 17117 ** | |
| 17118 ** Destructor: | |
| 17119 ** | |
| 17120 ** sqlite3_recover_finish() | |
| 17121 ** | |
| 17122 ** Methods: | |
| 17123 ** | |
| 17124 ** sqlite3_recover_config() | |
| 17125 ** sqlite3_recover_errcode() | |
| 17126 ** sqlite3_recover_errmsg() | |
| 17127 ** sqlite3_recover_run() | |
| 17128 ** sqlite3_recover_step() | |
| 17129 */ | |
| 17130 typedef struct sqlite3_recover sqlite3_recover; | |
| 17131 | |
| 17132 /* | |
| 17133 ** These two APIs attempt to create and return a new sqlite3_recover object. | |
| 17134 ** In both cases the first two arguments identify the (possibly | |
| 17135 ** corrupt) database to recover data from. The first argument is an open | |
| 17136 ** database handle and the second the name of a database attached to that | |
| 17137 ** handle (i.e. "main", "temp" or the name of an attached database). | |
| 17138 ** | |
| 17139 ** If sqlite3_recover_init() is used to create the new sqlite3_recover | |
| 17140 ** handle, then data is recovered into a new database, identified by | |
| 17141 ** string parameter zUri. zUri may be an absolute or relative file path, | |
| 17142 ** or may be an SQLite URI. If the identified database file already exists, | |
| 17143 ** it is overwritten. | |
| 17144 ** | |
| 17145 ** If sqlite3_recover_init_sql() is invoked, then any recovered data will | |
| 17146 ** be returned to the user as a series of SQL statements. Executing these | |
| 17147 ** SQL statements results in the same database as would have been created | |
| 17148 ** had sqlite3_recover_init() been used. For each SQL statement in the | |
| 17149 ** output, the callback function passed as the third argument (xSql) is | |
| 17150 ** invoked once. The first parameter is a passed a copy of the fourth argument | |
| 17151 ** to this function (pCtx) as its first parameter, and a pointer to a | |
| 17152 ** nul-terminated buffer containing the SQL statement formated as UTF-8 as | |
| 17153 ** the second. If the xSql callback returns any value other than SQLITE_OK, | |
| 17154 ** then processing is immediately abandoned and the value returned used as | |
| 17155 ** the recover handle error code (see below). | |
| 17156 ** | |
| 17157 ** If an out-of-memory error occurs, NULL may be returned instead of | |
| 17158 ** a valid handle. In all other cases, it is the responsibility of the | |
| 17159 ** application to avoid resource leaks by ensuring that | |
| 17160 ** sqlite3_recover_finish() is called on all allocated handles. | |
| 17161 */ | |
| 17162 sqlite3_recover *sqlite3_recover_init( | |
| 17163 sqlite3* db, | |
| 17164 const char *zDb, | |
| 17165 const char *zUri | |
| 17166 ); | |
| 17167 sqlite3_recover *sqlite3_recover_init_sql( | |
| 17168 sqlite3* db, | |
| 17169 const char *zDb, | |
| 17170 int (*xSql)(void*, const char*), | |
| 17171 void *pCtx | |
| 17172 ); | |
| 17173 | |
| 17174 /* | |
| 17175 ** Configure an sqlite3_recover object that has just been created using | |
| 17176 ** sqlite3_recover_init() or sqlite3_recover_init_sql(). This function | |
| 17177 ** may only be called before the first call to sqlite3_recover_step() | |
| 17178 ** or sqlite3_recover_run() on the object. | |
| 17179 ** | |
| 17180 ** The second argument passed to this function must be one of the | |
| 17181 ** SQLITE_RECOVER_* symbols defined below. Valid values for the third argument | |
| 17182 ** depend on the specific SQLITE_RECOVER_* symbol in use. | |
| 17183 ** | |
| 17184 ** SQLITE_OK is returned if the configuration operation was successful, | |
| 17185 ** or an SQLite error code otherwise. | |
| 17186 */ | |
| 17187 int sqlite3_recover_config(sqlite3_recover*, int op, void *pArg); | |
| 17188 | |
| 17189 /* | |
| 17190 ** SQLITE_RECOVER_LOST_AND_FOUND: | |
| 17191 ** The pArg argument points to a string buffer containing the name | |
| 17192 ** of a "lost-and-found" table in the output database, or NULL. If | |
| 17193 ** the argument is non-NULL and the database contains seemingly | |
| 17194 ** valid pages that cannot be associated with any table in the | |
| 17195 ** recovered part of the schema, data is extracted from these | |
| 17196 ** pages to add to the lost-and-found table. | |
| 17197 ** | |
| 17198 ** SQLITE_RECOVER_FREELIST_CORRUPT: | |
| 17199 ** The pArg value must actually be a pointer to a value of type | |
| 17200 ** int containing value 0 or 1 cast as a (void*). If this option is set | |
| 17201 ** (argument is 1) and a lost-and-found table has been configured using | |
| 17202 ** SQLITE_RECOVER_LOST_AND_FOUND, then is assumed that the freelist is | |
| 17203 ** corrupt and an attempt is made to recover records from pages that | |
| 17204 ** appear to be linked into the freelist. Otherwise, pages on the freelist | |
| 17205 ** are ignored. Setting this option can recover more data from the | |
| 17206 ** database, but often ends up "recovering" deleted records. The default | |
| 17207 ** value is 0 (clear). | |
| 17208 ** | |
| 17209 ** SQLITE_RECOVER_ROWIDS: | |
| 17210 ** The pArg value must actually be a pointer to a value of type | |
| 17211 ** int containing value 0 or 1 cast as a (void*). If this option is set | |
| 17212 ** (argument is 1), then an attempt is made to recover rowid values | |
| 17213 ** that are not also INTEGER PRIMARY KEY values. If this option is | |
| 17214 ** clear, then new rowids are assigned to all recovered rows. The | |
| 17215 ** default value is 1 (set). | |
| 17216 ** | |
| 17217 ** SQLITE_RECOVER_SLOWINDEXES: | |
| 17218 ** The pArg value must actually be a pointer to a value of type | |
| 17219 ** int containing value 0 or 1 cast as a (void*). If this option is clear | |
| 17220 ** (argument is 0), then when creating an output database, the recover | |
| 17221 ** module creates and populates non-UNIQUE indexes right at the end of the | |
| 17222 ** recovery operation - after all recoverable data has been inserted | |
| 17223 ** into the new database. This is faster overall, but means that the | |
| 17224 ** final call to sqlite3_recover_step() for a recovery operation may | |
| 17225 ** be need to create a large number of indexes, which may be very slow. | |
| 17226 ** | |
| 17227 ** Or, if this option is set (argument is 1), then non-UNIQUE indexes | |
| 17228 ** are created in the output database before it is populated with | |
| 17229 ** recovered data. This is slower overall, but avoids the slow call | |
| 17230 ** to sqlite3_recover_step() at the end of the recovery operation. | |
| 17231 ** | |
| 17232 ** The default option value is 0. | |
| 17233 */ | |
| 17234 #define SQLITE_RECOVER_LOST_AND_FOUND 1 | |
| 17235 #define SQLITE_RECOVER_FREELIST_CORRUPT 2 | |
| 17236 #define SQLITE_RECOVER_ROWIDS 3 | |
| 17237 #define SQLITE_RECOVER_SLOWINDEXES 4 | |
| 17238 | |
| 17239 /* | |
| 17240 ** Perform a unit of work towards the recovery operation. This function | |
| 17241 ** must normally be called multiple times to complete database recovery. | |
| 17242 ** | |
| 17243 ** If no error occurs but the recovery operation is not completed, this | |
| 17244 ** function returns SQLITE_OK. If recovery has been completed successfully | |
| 17245 ** then SQLITE_DONE is returned. If an error has occurred, then an SQLite | |
| 17246 ** error code (e.g. SQLITE_IOERR or SQLITE_NOMEM) is returned. It is not | |
| 17247 ** considered an error if some or all of the data cannot be recovered | |
| 17248 ** due to database corruption. | |
| 17249 ** | |
| 17250 ** Once sqlite3_recover_step() has returned a value other than SQLITE_OK, | |
| 17251 ** all further such calls on the same recover handle are no-ops that return | |
| 17252 ** the same non-SQLITE_OK value. | |
| 17253 */ | |
| 17254 int sqlite3_recover_step(sqlite3_recover*); | |
| 17255 | |
| 17256 /* | |
| 17257 ** Run the recovery operation to completion. Return SQLITE_OK if successful, | |
| 17258 ** or an SQLite error code otherwise. Calling this function is the same | |
| 17259 ** as executing: | |
| 17260 ** | |
| 17261 ** while( SQLITE_OK==sqlite3_recover_step(p) ); | |
| 17262 ** return sqlite3_recover_errcode(p); | |
| 17263 */ | |
| 17264 int sqlite3_recover_run(sqlite3_recover*); | |
| 17265 | |
| 17266 /* | |
| 17267 ** If an error has been encountered during a prior call to | |
| 17268 ** sqlite3_recover_step(), then this function attempts to return a | |
| 17269 ** pointer to a buffer containing an English language explanation of | |
| 17270 ** the error. If no error message is available, or if an out-of memory | |
| 17271 ** error occurs while attempting to allocate a buffer in which to format | |
| 17272 ** the error message, NULL is returned. | |
| 17273 ** | |
| 17274 ** The returned buffer remains valid until the sqlite3_recover handle is | |
| 17275 ** destroyed using sqlite3_recover_finish(). | |
| 17276 */ | |
| 17277 const char *sqlite3_recover_errmsg(sqlite3_recover*); | |
| 17278 | |
| 17279 /* | |
| 17280 ** If this function is called on an sqlite3_recover handle after | |
| 17281 ** an error occurs, an SQLite error code is returned. Otherwise, SQLITE_OK. | |
| 17282 */ | |
| 17283 int sqlite3_recover_errcode(sqlite3_recover*); | |
| 17284 | |
| 17285 /* | |
| 17286 ** Clean up a recovery object created by a call to sqlite3_recover_init(). | |
| 17287 ** The results of using a recovery object with any API after it has been | |
| 17288 ** passed to this function are undefined. | |
| 17289 ** | |
| 17290 ** This function returns the same value as sqlite3_recover_errcode(). | |
| 17291 */ | |
| 17292 int sqlite3_recover_finish(sqlite3_recover*); | |
| 17293 | |
| 17294 | |
| 17295 #ifdef __cplusplus | |
| 17296 } /* end of the 'extern "C"' block */ | |
| 17297 #endif | |
| 17298 | |
| 17299 #endif /* ifndef _SQLITE_RECOVER_H */ | |
| 17300 | |
| 17301 /************************* End ../ext/recover/sqlite3recover.h ********************/ | |
| 17302 # ifndef SQLITE_HAVE_SQLITE3R | |
| 17303 /************************* Begin ../ext/recover/dbdata.c ******************/ | |
| 17304 /* | |
| 17305 ** 2019-04-17 | |
| 17306 ** | |
| 17307 ** The author disclaims copyright to this source code. In place of | |
| 17308 ** a legal notice, here is a blessing: | |
| 17309 ** | |
| 17310 ** May you do good and not evil. | |
| 17311 ** May you find forgiveness for yourself and forgive others. | |
| 17312 ** May you share freely, never taking more than you give. | |
| 17313 ** | |
| 17314 ****************************************************************************** | |
| 17315 ** | |
| 17316 ** This file contains an implementation of two eponymous virtual tables, | |
| 17317 ** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the | |
| 17318 ** "sqlite_dbpage" eponymous virtual table be available. | |
| 17319 ** | |
| 17320 ** SQLITE_DBDATA: | |
| 17321 ** sqlite_dbdata is used to extract data directly from a database b-tree | |
| 17322 ** page and its associated overflow pages, bypassing the b-tree layer. | |
| 17323 ** The table schema is equivalent to: | |
| 17324 ** | |
| 17325 ** CREATE TABLE sqlite_dbdata( | |
| 17326 ** pgno INTEGER, | |
| 17327 ** cell INTEGER, | |
| 17328 ** field INTEGER, | |
| 17329 ** value ANY, | |
| 17330 ** schema TEXT HIDDEN | |
| 17331 ** ); | |
| 17332 ** | |
| 17333 ** IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE | |
| 17334 ** FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND | |
| 17335 ** "schema". | |
| 17336 ** | |
| 17337 ** Each page of the database is inspected. If it cannot be interpreted as | |
| 17338 ** a b-tree page, or if it is a b-tree page containing 0 entries, the | |
| 17339 ** sqlite_dbdata table contains no rows for that page. Otherwise, the | |
| 17340 ** table contains one row for each field in the record associated with | |
| 17341 ** each cell on the page. For intkey b-trees, the key value is stored in | |
| 17342 ** field -1. | |
| 17343 ** | |
| 17344 ** For example, for the database: | |
| 17345 ** | |
| 17346 ** CREATE TABLE t1(a, b); -- root page is page 2 | |
| 17347 ** INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five'); | |
| 17348 ** INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten'); | |
| 17349 ** | |
| 17350 ** the sqlite_dbdata table contains, as well as from entries related to | |
| 17351 ** page 1, content equivalent to: | |
| 17352 ** | |
| 17353 ** INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES | |
| 17354 ** (2, 0, -1, 5 ), | |
| 17355 ** (2, 0, 0, 'v' ), | |
| 17356 ** (2, 0, 1, 'five'), | |
| 17357 ** (2, 1, -1, 10 ), | |
| 17358 ** (2, 1, 0, 'x' ), | |
| 17359 ** (2, 1, 1, 'ten' ); | |
| 17360 ** | |
| 17361 ** If database corruption is encountered, this module does not report an | |
| 17362 ** error. Instead, it attempts to extract as much data as possible and | |
| 17363 ** ignores the corruption. | |
| 17364 ** | |
| 17365 ** SQLITE_DBPTR: | |
| 17366 ** The sqlite_dbptr table has the following schema: | |
| 17367 ** | |
| 17368 ** CREATE TABLE sqlite_dbptr( | |
| 17369 ** pgno INTEGER, | |
| 17370 ** child INTEGER, | |
| 17371 ** schema TEXT HIDDEN | |
| 17372 ** ); | |
| 17373 ** | |
| 17374 ** It contains one entry for each b-tree pointer between a parent and | |
| 17375 ** child page in the database. | |
| 17376 */ | |
| 17377 | |
| 17378 #if !defined(SQLITEINT_H) | |
| 17379 /* #include "sqlite3.h" */ | |
| 17380 | |
| 17381 /* typedef unsigned char u8; */ | |
| 17382 /* typedef unsigned int u32; */ | |
| 17383 | |
| 17384 #endif | |
| 17385 #include <string.h> | |
| 17386 #include <assert.h> | |
| 17387 | |
| 17388 #ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 17389 | |
| 17390 #define DBDATA_PADDING_BYTES 100 | |
| 17391 | |
| 17392 typedef struct DbdataTable DbdataTable; | |
| 17393 typedef struct DbdataCursor DbdataCursor; | |
| 17394 typedef struct DbdataBuffer DbdataBuffer; | |
| 17395 | |
| 17396 /* | |
| 17397 ** Buffer type. | |
| 17398 */ | |
| 17399 struct DbdataBuffer { | |
| 17400 u8 *aBuf; | |
| 17401 sqlite3_int64 nBuf; | |
| 17402 }; | |
| 17403 | |
| 17404 /* Cursor object */ | |
| 17405 struct DbdataCursor { | |
| 17406 sqlite3_vtab_cursor base; /* Base class. Must be first */ | |
| 17407 sqlite3_stmt *pStmt; /* For fetching database pages */ | |
| 17408 | |
| 17409 int iPgno; /* Current page number */ | |
| 17410 u8 *aPage; /* Buffer containing page */ | |
| 17411 int nPage; /* Size of aPage[] in bytes */ | |
| 17412 int nCell; /* Number of cells on aPage[] */ | |
| 17413 int iCell; /* Current cell number */ | |
| 17414 int bOnePage; /* True to stop after one page */ | |
| 17415 int szDb; | |
| 17416 sqlite3_int64 iRowid; | |
| 17417 | |
| 17418 /* Only for the sqlite_dbdata table */ | |
| 17419 DbdataBuffer rec; | |
| 17420 sqlite3_int64 nRec; /* Size of pRec[] in bytes */ | |
| 17421 sqlite3_int64 nHdr; /* Size of header in bytes */ | |
| 17422 int iField; /* Current field number */ | |
| 17423 u8 *pHdrPtr; | |
| 17424 u8 *pPtr; | |
| 17425 u32 enc; /* Text encoding */ | |
| 17426 | |
| 17427 sqlite3_int64 iIntkey; /* Integer key value */ | |
| 17428 }; | |
| 17429 | |
| 17430 /* Table object */ | |
| 17431 struct DbdataTable { | |
| 17432 sqlite3_vtab base; /* Base class. Must be first */ | |
| 17433 sqlite3 *db; /* The database connection */ | |
| 17434 sqlite3_stmt *pStmt; /* For fetching database pages */ | |
| 17435 int bPtr; /* True for sqlite3_dbptr table */ | |
| 17436 }; | |
| 17437 | |
| 17438 /* Column and schema definitions for sqlite_dbdata */ | |
| 17439 #define DBDATA_COLUMN_PGNO 0 | |
| 17440 #define DBDATA_COLUMN_CELL 1 | |
| 17441 #define DBDATA_COLUMN_FIELD 2 | |
| 17442 #define DBDATA_COLUMN_VALUE 3 | |
| 17443 #define DBDATA_COLUMN_SCHEMA 4 | |
| 17444 #define DBDATA_SCHEMA \ | |
| 17445 "CREATE TABLE x(" \ | |
| 17446 " pgno INTEGER," \ | |
| 17447 " cell INTEGER," \ | |
| 17448 " field INTEGER," \ | |
| 17449 " value ANY," \ | |
| 17450 " schema TEXT HIDDEN" \ | |
| 17451 ")" | |
| 17452 | |
| 17453 /* Column and schema definitions for sqlite_dbptr */ | |
| 17454 #define DBPTR_COLUMN_PGNO 0 | |
| 17455 #define DBPTR_COLUMN_CHILD 1 | |
| 17456 #define DBPTR_COLUMN_SCHEMA 2 | |
| 17457 #define DBPTR_SCHEMA \ | |
| 17458 "CREATE TABLE x(" \ | |
| 17459 " pgno INTEGER," \ | |
| 17460 " child INTEGER," \ | |
| 17461 " schema TEXT HIDDEN" \ | |
| 17462 ")" | |
| 17463 | |
| 17464 /* | |
| 17465 ** Ensure the buffer passed as the first argument is at least nMin bytes | |
| 17466 ** in size. If an error occurs while attempting to resize the buffer, | |
| 17467 ** SQLITE_NOMEM is returned. Otherwise, SQLITE_OK. | |
| 17468 */ | |
| 17469 static int dbdataBufferSize(DbdataBuffer *pBuf, sqlite3_int64 nMin){ | |
| 17470 if( nMin>pBuf->nBuf ){ | |
| 17471 sqlite3_int64 nNew = nMin+16384; | |
| 17472 u8 *aNew = (u8*)sqlite3_realloc64(pBuf->aBuf, nNew); | |
| 17473 | |
| 17474 if( aNew==0 ) return SQLITE_NOMEM; | |
| 17475 pBuf->aBuf = aNew; | |
| 17476 pBuf->nBuf = nNew; | |
| 17477 } | |
| 17478 return SQLITE_OK; | |
| 17479 } | |
| 17480 | |
| 17481 /* | |
| 17482 ** Release the allocation managed by buffer pBuf. | |
| 17483 */ | |
| 17484 static void dbdataBufferFree(DbdataBuffer *pBuf){ | |
| 17485 sqlite3_free(pBuf->aBuf); | |
| 17486 memset(pBuf, 0, sizeof(*pBuf)); | |
| 17487 } | |
| 17488 | |
| 17489 /* | |
| 17490 ** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual | |
| 17491 ** table. | |
| 17492 */ | |
| 17493 static int dbdataConnect( | |
| 17494 sqlite3 *db, | |
| 17495 void *pAux, | |
| 17496 int argc, const char *const*argv, | |
| 17497 sqlite3_vtab **ppVtab, | |
| 17498 char **pzErr | |
| 17499 ){ | |
| 17500 DbdataTable *pTab = 0; | |
| 17501 int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA); | |
| 17502 | |
| 17503 (void)argc; | |
| 17504 (void)argv; | |
| 17505 (void)pzErr; | |
| 17506 sqlite3_vtab_config(db, SQLITE_VTAB_USES_ALL_SCHEMAS); | |
| 17507 if( rc==SQLITE_OK ){ | |
| 17508 pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable)); | |
| 17509 if( pTab==0 ){ | |
| 17510 rc = SQLITE_NOMEM; | |
| 17511 }else{ | |
| 17512 memset(pTab, 0, sizeof(DbdataTable)); | |
| 17513 pTab->db = db; | |
| 17514 pTab->bPtr = (pAux!=0); | |
| 17515 } | |
| 17516 } | |
| 17517 | |
| 17518 *ppVtab = (sqlite3_vtab*)pTab; | |
| 17519 return rc; | |
| 17520 } | |
| 17521 | |
| 17522 /* | |
| 17523 ** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table. | |
| 17524 */ | |
| 17525 static int dbdataDisconnect(sqlite3_vtab *pVtab){ | |
| 17526 DbdataTable *pTab = (DbdataTable*)pVtab; | |
| 17527 if( pTab ){ | |
| 17528 sqlite3_finalize(pTab->pStmt); | |
| 17529 sqlite3_free(pVtab); | |
| 17530 } | |
| 17531 return SQLITE_OK; | |
| 17532 } | |
| 17533 | |
| 17534 /* | |
| 17535 ** This function interprets two types of constraints: | |
| 17536 ** | |
| 17537 ** schema=? | |
| 17538 ** pgno=? | |
| 17539 ** | |
| 17540 ** If neither are present, idxNum is set to 0. If schema=? is present, | |
| 17541 ** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit | |
| 17542 ** in idxNum is set. | |
| 17543 ** | |
| 17544 ** If both parameters are present, schema is in position 0 and pgno in | |
| 17545 ** position 1. | |
| 17546 */ | |
| 17547 static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){ | |
| 17548 DbdataTable *pTab = (DbdataTable*)tab; | |
| 17549 int i; | |
| 17550 int iSchema = -1; | |
| 17551 int iPgno = -1; | |
| 17552 int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA); | |
| 17553 | |
| 17554 for(i=0; i<pIdx->nConstraint; i++){ | |
| 17555 struct sqlite3_index_constraint *p = &pIdx->aConstraint[i]; | |
| 17556 if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ | |
| 17557 if( p->iColumn==colSchema ){ | |
| 17558 if( p->usable==0 ) return SQLITE_CONSTRAINT; | |
| 17559 iSchema = i; | |
| 17560 } | |
| 17561 if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){ | |
| 17562 iPgno = i; | |
| 17563 } | |
| 17564 } | |
| 17565 } | |
| 17566 | |
| 17567 if( iSchema>=0 ){ | |
| 17568 pIdx->aConstraintUsage[iSchema].argvIndex = 1; | |
| 17569 pIdx->aConstraintUsage[iSchema].omit = 1; | |
| 17570 } | |
| 17571 if( iPgno>=0 ){ | |
| 17572 pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0); | |
| 17573 pIdx->aConstraintUsage[iPgno].omit = 1; | |
| 17574 pIdx->estimatedCost = 100; | |
| 17575 pIdx->estimatedRows = 50; | |
| 17576 | |
| 17577 if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){ | |
| 17578 int iCol = pIdx->aOrderBy[0].iColumn; | |
| 17579 if( pIdx->nOrderBy==1 ){ | |
| 17580 pIdx->orderByConsumed = (iCol==0 || iCol==1); | |
| 17581 }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){ | |
| 17582 pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1); | |
| 17583 } | |
| 17584 } | |
| 17585 | |
| 17586 }else{ | |
| 17587 pIdx->estimatedCost = 100000000; | |
| 17588 pIdx->estimatedRows = 1000000000; | |
| 17589 } | |
| 17590 pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00); | |
| 17591 return SQLITE_OK; | |
| 17592 } | |
| 17593 | |
| 17594 /* | |
| 17595 ** Open a new sqlite_dbdata or sqlite_dbptr cursor. | |
| 17596 */ | |
| 17597 static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ | |
| 17598 DbdataCursor *pCsr; | |
| 17599 | |
| 17600 pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor)); | |
| 17601 if( pCsr==0 ){ | |
| 17602 return SQLITE_NOMEM; | |
| 17603 }else{ | |
| 17604 memset(pCsr, 0, sizeof(DbdataCursor)); | |
| 17605 pCsr->base.pVtab = pVTab; | |
| 17606 } | |
| 17607 | |
| 17608 *ppCursor = (sqlite3_vtab_cursor *)pCsr; | |
| 17609 return SQLITE_OK; | |
| 17610 } | |
| 17611 | |
| 17612 /* | |
| 17613 ** Restore a cursor object to the state it was in when first allocated | |
| 17614 ** by dbdataOpen(). | |
| 17615 */ | |
| 17616 static void dbdataResetCursor(DbdataCursor *pCsr){ | |
| 17617 DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab); | |
| 17618 if( pTab->pStmt==0 ){ | |
| 17619 pTab->pStmt = pCsr->pStmt; | |
| 17620 }else{ | |
| 17621 sqlite3_finalize(pCsr->pStmt); | |
| 17622 } | |
| 17623 pCsr->pStmt = 0; | |
| 17624 pCsr->iPgno = 1; | |
| 17625 pCsr->iCell = 0; | |
| 17626 pCsr->iField = 0; | |
| 17627 pCsr->bOnePage = 0; | |
| 17628 sqlite3_free(pCsr->aPage); | |
| 17629 dbdataBufferFree(&pCsr->rec); | |
| 17630 pCsr->aPage = 0; | |
| 17631 pCsr->nRec = 0; | |
| 17632 } | |
| 17633 | |
| 17634 /* | |
| 17635 ** Close an sqlite_dbdata or sqlite_dbptr cursor. | |
| 17636 */ | |
| 17637 static int dbdataClose(sqlite3_vtab_cursor *pCursor){ | |
| 17638 DbdataCursor *pCsr = (DbdataCursor*)pCursor; | |
| 17639 dbdataResetCursor(pCsr); | |
| 17640 sqlite3_free(pCsr); | |
| 17641 return SQLITE_OK; | |
| 17642 } | |
| 17643 | |
| 17644 /* | |
| 17645 ** Utility methods to decode 16 and 32-bit big-endian unsigned integers. | |
| 17646 */ | |
| 17647 static u32 get_uint16(unsigned char *a){ | |
| 17648 return (a[0]<<8)|a[1]; | |
| 17649 } | |
| 17650 static u32 get_uint32(unsigned char *a){ | |
| 17651 return ((u32)a[0]<<24) | |
| 17652 | ((u32)a[1]<<16) | |
| 17653 | ((u32)a[2]<<8) | |
| 17654 | ((u32)a[3]); | |
| 17655 } | |
| 17656 | |
| 17657 /* | |
| 17658 ** Load page pgno from the database via the sqlite_dbpage virtual table. | |
| 17659 ** If successful, set (*ppPage) to point to a buffer containing the page | |
| 17660 ** data, (*pnPage) to the size of that buffer in bytes and return | |
| 17661 ** SQLITE_OK. In this case it is the responsibility of the caller to | |
| 17662 ** eventually free the buffer using sqlite3_free(). | |
| 17663 ** | |
| 17664 ** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and | |
| 17665 ** return an SQLite error code. | |
| 17666 */ | |
| 17667 static int dbdataLoadPage( | |
| 17668 DbdataCursor *pCsr, /* Cursor object */ | |
| 17669 u32 pgno, /* Page number of page to load */ | |
| 17670 u8 **ppPage, /* OUT: pointer to page buffer */ | |
| 17671 int *pnPage /* OUT: Size of (*ppPage) in bytes */ | |
| 17672 ){ | |
| 17673 int rc2; | |
| 17674 int rc = SQLITE_OK; | |
| 17675 sqlite3_stmt *pStmt = pCsr->pStmt; | |
| 17676 | |
| 17677 *ppPage = 0; | |
| 17678 *pnPage = 0; | |
| 17679 if( pgno>0 ){ | |
| 17680 sqlite3_bind_int64(pStmt, 2, pgno); | |
| 17681 if( SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 17682 int nCopy = sqlite3_column_bytes(pStmt, 0); | |
| 17683 if( nCopy>0 ){ | |
| 17684 u8 *pPage; | |
| 17685 pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES); | |
| 17686 if( pPage==0 ){ | |
| 17687 rc = SQLITE_NOMEM; | |
| 17688 }else{ | |
| 17689 const u8 *pCopy = sqlite3_column_blob(pStmt, 0); | |
| 17690 memcpy(pPage, pCopy, nCopy); | |
| 17691 memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES); | |
| 17692 } | |
| 17693 *ppPage = pPage; | |
| 17694 *pnPage = nCopy; | |
| 17695 } | |
| 17696 } | |
| 17697 rc2 = sqlite3_reset(pStmt); | |
| 17698 if( rc==SQLITE_OK ) rc = rc2; | |
| 17699 } | |
| 17700 | |
| 17701 return rc; | |
| 17702 } | |
| 17703 | |
| 17704 /* | |
| 17705 ** Read a varint. Put the value in *pVal and return the number of bytes. | |
| 17706 */ | |
| 17707 static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){ | |
| 17708 sqlite3_uint64 u = 0; | |
| 17709 int i; | |
| 17710 for(i=0; i<8; i++){ | |
| 17711 u = (u<<7) + (z[i]&0x7f); | |
| 17712 if( (z[i]&0x80)==0 ){ *pVal = (sqlite3_int64)u; return i+1; } | |
| 17713 } | |
| 17714 u = (u<<8) + (z[i]&0xff); | |
| 17715 *pVal = (sqlite3_int64)u; | |
| 17716 return 9; | |
| 17717 } | |
| 17718 | |
| 17719 /* | |
| 17720 ** Like dbdataGetVarint(), but set the output to 0 if it is less than 0 | |
| 17721 ** or greater than 0xFFFFFFFF. This can be used for all varints in an | |
| 17722 ** SQLite database except for key values in intkey tables. | |
| 17723 */ | |
| 17724 static int dbdataGetVarintU32(const u8 *z, sqlite3_int64 *pVal){ | |
| 17725 sqlite3_int64 val; | |
| 17726 int nRet = dbdataGetVarint(z, &val); | |
| 17727 if( val<0 || val>0xFFFFFFFF ) val = 0; | |
| 17728 *pVal = val; | |
| 17729 return nRet; | |
| 17730 } | |
| 17731 | |
| 17732 /* | |
| 17733 ** Return the number of bytes of space used by an SQLite value of type | |
| 17734 ** eType. | |
| 17735 */ | |
| 17736 static int dbdataValueBytes(int eType){ | |
| 17737 switch( eType ){ | |
| 17738 case 0: case 8: case 9: | |
| 17739 case 10: case 11: | |
| 17740 return 0; | |
| 17741 case 1: | |
| 17742 return 1; | |
| 17743 case 2: | |
| 17744 return 2; | |
| 17745 case 3: | |
| 17746 return 3; | |
| 17747 case 4: | |
| 17748 return 4; | |
| 17749 case 5: | |
| 17750 return 6; | |
| 17751 case 6: | |
| 17752 case 7: | |
| 17753 return 8; | |
| 17754 default: | |
| 17755 if( eType>0 ){ | |
| 17756 return ((eType-12) / 2); | |
| 17757 } | |
| 17758 return 0; | |
| 17759 } | |
| 17760 } | |
| 17761 | |
| 17762 /* | |
| 17763 ** Load a value of type eType from buffer pData and use it to set the | |
| 17764 ** result of context object pCtx. | |
| 17765 */ | |
| 17766 static void dbdataValue( | |
| 17767 sqlite3_context *pCtx, | |
| 17768 u32 enc, | |
| 17769 int eType, | |
| 17770 u8 *pData, | |
| 17771 sqlite3_int64 nData | |
| 17772 ){ | |
| 17773 if( eType>=0 ){ | |
| 17774 if( dbdataValueBytes(eType)<=nData ){ | |
| 17775 switch( eType ){ | |
| 17776 case 0: | |
| 17777 case 10: | |
| 17778 case 11: | |
| 17779 sqlite3_result_null(pCtx); | |
| 17780 break; | |
| 17781 | |
| 17782 case 8: | |
| 17783 sqlite3_result_int(pCtx, 0); | |
| 17784 break; | |
| 17785 case 9: | |
| 17786 sqlite3_result_int(pCtx, 1); | |
| 17787 break; | |
| 17788 | |
| 17789 case 1: case 2: case 3: case 4: case 5: case 6: case 7: { | |
| 17790 sqlite3_uint64 v = (signed char)pData[0]; | |
| 17791 pData++; | |
| 17792 switch( eType ){ | |
| 17793 case 7: | |
| 17794 case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; | |
| 17795 case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; | |
| 17796 case 4: v = (v<<8) + pData[0]; pData++; | |
| 17797 case 3: v = (v<<8) + pData[0]; pData++; | |
| 17798 case 2: v = (v<<8) + pData[0]; pData++; | |
| 17799 } | |
| 17800 | |
| 17801 if( eType==7 ){ | |
| 17802 double r; | |
| 17803 memcpy(&r, &v, sizeof(r)); | |
| 17804 sqlite3_result_double(pCtx, r); | |
| 17805 }else{ | |
| 17806 sqlite3_result_int64(pCtx, (sqlite3_int64)v); | |
| 17807 } | |
| 17808 break; | |
| 17809 } | |
| 17810 | |
| 17811 default: { | |
| 17812 int n = ((eType-12) / 2); | |
| 17813 if( eType % 2 ){ | |
| 17814 switch( enc ){ | |
| 17815 #ifndef SQLITE_OMIT_UTF16 | |
| 17816 case SQLITE_UTF16BE: | |
| 17817 sqlite3_result_text16be(pCtx, (void*)pData, n, SQLITE_TRANSIENT); | |
| 17818 break; | |
| 17819 case SQLITE_UTF16LE: | |
| 17820 sqlite3_result_text16le(pCtx, (void*)pData, n, SQLITE_TRANSIENT); | |
| 17821 break; | |
| 17822 #endif | |
| 17823 default: | |
| 17824 sqlite3_result_text(pCtx, (char*)pData, n, SQLITE_TRANSIENT); | |
| 17825 break; | |
| 17826 } | |
| 17827 }else{ | |
| 17828 sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); | |
| 17829 } | |
| 17830 } | |
| 17831 } | |
| 17832 }else{ | |
| 17833 if( eType==7 ){ | |
| 17834 sqlite3_result_double(pCtx, 0.0); | |
| 17835 }else if( eType<7 ){ | |
| 17836 sqlite3_result_int(pCtx, 0); | |
| 17837 }else if( eType%2 ){ | |
| 17838 sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); | |
| 17839 }else{ | |
| 17840 sqlite3_result_blob(pCtx, "", 0, SQLITE_STATIC); | |
| 17841 } | |
| 17842 } | |
| 17843 } | |
| 17844 } | |
| 17845 | |
| 17846 /* This macro is a copy of the MX_CELL() macro in the SQLite core. Given | |
| 17847 ** a page-size, it returns the maximum number of cells that may be present | |
| 17848 ** on the page. */ | |
| 17849 #define DBDATA_MX_CELL(pgsz) ((pgsz-8)/6) | |
| 17850 | |
| 17851 /* Maximum number of fields that may appear in a single record. This is | |
| 17852 ** the "hard-limit", according to comments in sqliteLimit.h. */ | |
| 17853 #define DBDATA_MX_FIELD 32676 | |
| 17854 | |
| 17855 /* | |
| 17856 ** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry. | |
| 17857 */ | |
| 17858 static int dbdataNext(sqlite3_vtab_cursor *pCursor){ | |
| 17859 DbdataCursor *pCsr = (DbdataCursor*)pCursor; | |
| 17860 DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; | |
| 17861 | |
| 17862 pCsr->iRowid++; | |
| 17863 while( 1 ){ | |
| 17864 int rc; | |
| 17865 int iOff = (pCsr->iPgno==1 ? 100 : 0); | |
| 17866 int bNextPage = 0; | |
| 17867 | |
| 17868 if( pCsr->aPage==0 ){ | |
| 17869 while( 1 ){ | |
| 17870 if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK; | |
| 17871 rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage); | |
| 17872 if( rc!=SQLITE_OK ) return rc; | |
| 17873 if( pCsr->aPage && pCsr->nPage>=256 ) break; | |
| 17874 sqlite3_free(pCsr->aPage); | |
| 17875 pCsr->aPage = 0; | |
| 17876 if( pCsr->bOnePage ) return SQLITE_OK; | |
| 17877 pCsr->iPgno++; | |
| 17878 } | |
| 17879 | |
| 17880 assert( iOff+3+2<=pCsr->nPage ); | |
| 17881 pCsr->iCell = pTab->bPtr ? -2 : 0; | |
| 17882 pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]); | |
| 17883 if( pCsr->nCell>DBDATA_MX_CELL(pCsr->nPage) ){ | |
| 17884 pCsr->nCell = DBDATA_MX_CELL(pCsr->nPage); | |
| 17885 } | |
| 17886 } | |
| 17887 | |
| 17888 if( pTab->bPtr ){ | |
| 17889 if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){ | |
| 17890 pCsr->iCell = pCsr->nCell; | |
| 17891 } | |
| 17892 pCsr->iCell++; | |
| 17893 if( pCsr->iCell>=pCsr->nCell ){ | |
| 17894 sqlite3_free(pCsr->aPage); | |
| 17895 pCsr->aPage = 0; | |
| 17896 if( pCsr->bOnePage ) return SQLITE_OK; | |
| 17897 pCsr->iPgno++; | |
| 17898 }else{ | |
| 17899 return SQLITE_OK; | |
| 17900 } | |
| 17901 }else{ | |
| 17902 /* If there is no record loaded, load it now. */ | |
| 17903 assert( pCsr->rec.aBuf!=0 || pCsr->nRec==0 ); | |
| 17904 if( pCsr->nRec==0 ){ | |
| 17905 int bHasRowid = 0; | |
| 17906 int nPointer = 0; | |
| 17907 sqlite3_int64 nPayload = 0; | |
| 17908 sqlite3_int64 nHdr = 0; | |
| 17909 int iHdr; | |
| 17910 int U, X; | |
| 17911 int nLocal; | |
| 17912 | |
| 17913 switch( pCsr->aPage[iOff] ){ | |
| 17914 case 0x02: | |
| 17915 nPointer = 4; | |
| 17916 break; | |
| 17917 case 0x0a: | |
| 17918 break; | |
| 17919 case 0x0d: | |
| 17920 bHasRowid = 1; | |
| 17921 break; | |
| 17922 default: | |
| 17923 /* This is not a b-tree page with records on it. Continue. */ | |
| 17924 pCsr->iCell = pCsr->nCell; | |
| 17925 break; | |
| 17926 } | |
| 17927 | |
| 17928 if( pCsr->iCell>=pCsr->nCell ){ | |
| 17929 bNextPage = 1; | |
| 17930 }else{ | |
| 17931 int iCellPtr = iOff + 8 + nPointer + pCsr->iCell*2; | |
| 17932 | |
| 17933 if( iCellPtr>pCsr->nPage ){ | |
| 17934 bNextPage = 1; | |
| 17935 }else{ | |
| 17936 iOff = get_uint16(&pCsr->aPage[iCellPtr]); | |
| 17937 } | |
| 17938 | |
| 17939 /* For an interior node cell, skip past the child-page number */ | |
| 17940 iOff += nPointer; | |
| 17941 | |
| 17942 /* Load the "byte of payload including overflow" field */ | |
| 17943 if( bNextPage || iOff>pCsr->nPage || iOff<=iCellPtr ){ | |
| 17944 bNextPage = 1; | |
| 17945 }else{ | |
| 17946 iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload); | |
| 17947 if( nPayload>0x7fffff00 ) nPayload &= 0x3fff; | |
| 17948 if( nPayload==0 ) nPayload = 1; | |
| 17949 } | |
| 17950 | |
| 17951 /* If this is a leaf intkey cell, load the rowid */ | |
| 17952 if( bHasRowid && !bNextPage && iOff<pCsr->nPage ){ | |
| 17953 iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey); | |
| 17954 } | |
| 17955 | |
| 17956 /* Figure out how much data to read from the local page */ | |
| 17957 U = pCsr->nPage; | |
| 17958 if( bHasRowid ){ | |
| 17959 X = U-35; | |
| 17960 }else{ | |
| 17961 X = ((U-12)*64/255)-23; | |
| 17962 } | |
| 17963 if( nPayload<=X ){ | |
| 17964 nLocal = nPayload; | |
| 17965 }else{ | |
| 17966 int M, K; | |
| 17967 M = ((U-12)*32/255)-23; | |
| 17968 K = M+((nPayload-M)%(U-4)); | |
| 17969 if( K<=X ){ | |
| 17970 nLocal = K; | |
| 17971 }else{ | |
| 17972 nLocal = M; | |
| 17973 } | |
| 17974 } | |
| 17975 | |
| 17976 if( bNextPage || nLocal+iOff>pCsr->nPage ){ | |
| 17977 bNextPage = 1; | |
| 17978 }else{ | |
| 17979 | |
| 17980 /* Allocate space for payload. And a bit more to catch small buffer | |
| 17981 ** overruns caused by attempting to read a varint or similar from | |
| 17982 ** near the end of a corrupt record. */ | |
| 17983 rc = dbdataBufferSize(&pCsr->rec, nPayload+DBDATA_PADDING_BYTES); | |
| 17984 if( rc!=SQLITE_OK ) return rc; | |
| 17985 assert( pCsr->rec.aBuf!=0 ); | |
| 17986 assert( nPayload!=0 ); | |
| 17987 | |
| 17988 /* Load the nLocal bytes of payload */ | |
| 17989 memcpy(pCsr->rec.aBuf, &pCsr->aPage[iOff], nLocal); | |
| 17990 iOff += nLocal; | |
| 17991 | |
| 17992 /* Load content from overflow pages */ | |
| 17993 if( nPayload>nLocal ){ | |
| 17994 sqlite3_int64 nRem = nPayload - nLocal; | |
| 17995 u32 pgnoOvfl = get_uint32(&pCsr->aPage[iOff]); | |
| 17996 while( nRem>0 ){ | |
| 17997 u8 *aOvfl = 0; | |
| 17998 int nOvfl = 0; | |
| 17999 int nCopy; | |
| 18000 rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl); | |
| 18001 assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage ); | |
| 18002 if( rc!=SQLITE_OK ) return rc; | |
| 18003 if( aOvfl==0 ) break; | |
| 18004 | |
| 18005 nCopy = U-4; | |
| 18006 if( nCopy>nRem ) nCopy = nRem; | |
| 18007 memcpy(&pCsr->rec.aBuf[nPayload-nRem], &aOvfl[4], nCopy); | |
| 18008 nRem -= nCopy; | |
| 18009 | |
| 18010 pgnoOvfl = get_uint32(aOvfl); | |
| 18011 sqlite3_free(aOvfl); | |
| 18012 } | |
| 18013 nPayload -= nRem; | |
| 18014 } | |
| 18015 memset(&pCsr->rec.aBuf[nPayload], 0, DBDATA_PADDING_BYTES); | |
| 18016 pCsr->nRec = nPayload; | |
| 18017 | |
| 18018 iHdr = dbdataGetVarintU32(pCsr->rec.aBuf, &nHdr); | |
| 18019 if( nHdr>nPayload ) nHdr = 0; | |
| 18020 pCsr->nHdr = nHdr; | |
| 18021 pCsr->pHdrPtr = &pCsr->rec.aBuf[iHdr]; | |
| 18022 pCsr->pPtr = &pCsr->rec.aBuf[pCsr->nHdr]; | |
| 18023 pCsr->iField = (bHasRowid ? -1 : 0); | |
| 18024 } | |
| 18025 } | |
| 18026 }else{ | |
| 18027 pCsr->iField++; | |
| 18028 if( pCsr->iField>0 ){ | |
| 18029 sqlite3_int64 iType; | |
| 18030 if( pCsr->pHdrPtr>=&pCsr->rec.aBuf[pCsr->nRec] | |
| 18031 || pCsr->iField>=DBDATA_MX_FIELD | |
| 18032 ){ | |
| 18033 bNextPage = 1; | |
| 18034 }else{ | |
| 18035 int szField = 0; | |
| 18036 pCsr->pHdrPtr += dbdataGetVarintU32(pCsr->pHdrPtr, &iType); | |
| 18037 szField = dbdataValueBytes(iType); | |
| 18038 if( (pCsr->nRec - (pCsr->pPtr - pCsr->rec.aBuf))<szField ){ | |
| 18039 pCsr->pPtr = &pCsr->rec.aBuf[pCsr->nRec]; | |
| 18040 }else{ | |
| 18041 pCsr->pPtr += szField; | |
| 18042 } | |
| 18043 } | |
| 18044 } | |
| 18045 } | |
| 18046 | |
| 18047 if( bNextPage ){ | |
| 18048 sqlite3_free(pCsr->aPage); | |
| 18049 pCsr->aPage = 0; | |
| 18050 pCsr->nRec = 0; | |
| 18051 if( pCsr->bOnePage ) return SQLITE_OK; | |
| 18052 pCsr->iPgno++; | |
| 18053 }else{ | |
| 18054 if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->rec.aBuf[pCsr->nHdr] ){ | |
| 18055 return SQLITE_OK; | |
| 18056 } | |
| 18057 | |
| 18058 /* Advance to the next cell. The next iteration of the loop will load | |
| 18059 ** the record and so on. */ | |
| 18060 pCsr->nRec = 0; | |
| 18061 pCsr->iCell++; | |
| 18062 } | |
| 18063 } | |
| 18064 } | |
| 18065 | |
| 18066 assert( !"can't get here" ); | |
| 18067 return SQLITE_OK; | |
| 18068 } | |
| 18069 | |
| 18070 /* | |
| 18071 ** Return true if the cursor is at EOF. | |
| 18072 */ | |
| 18073 static int dbdataEof(sqlite3_vtab_cursor *pCursor){ | |
| 18074 DbdataCursor *pCsr = (DbdataCursor*)pCursor; | |
| 18075 return pCsr->aPage==0; | |
| 18076 } | |
| 18077 | |
| 18078 /* | |
| 18079 ** Return true if nul-terminated string zSchema ends in "()". Or false | |
| 18080 ** otherwise. | |
| 18081 */ | |
| 18082 static int dbdataIsFunction(const char *zSchema){ | |
| 18083 size_t n = strlen(zSchema); | |
| 18084 if( n>2 && zSchema[n-2]=='(' && zSchema[n-1]==')' ){ | |
| 18085 return (int)n-2; | |
| 18086 } | |
| 18087 return 0; | |
| 18088 } | |
| 18089 | |
| 18090 /* | |
| 18091 ** Determine the size in pages of database zSchema (where zSchema is | |
| 18092 ** "main", "temp" or the name of an attached database) and set | |
| 18093 ** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise, | |
| 18094 ** an SQLite error code. | |
| 18095 */ | |
| 18096 static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){ | |
| 18097 DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab; | |
| 18098 char *zSql = 0; | |
| 18099 int rc, rc2; | |
| 18100 int nFunc = 0; | |
| 18101 sqlite3_stmt *pStmt = 0; | |
| 18102 | |
| 18103 if( (nFunc = dbdataIsFunction(zSchema))>0 ){ | |
| 18104 zSql = sqlite3_mprintf("SELECT %.*s(0)", nFunc, zSchema); | |
| 18105 }else{ | |
| 18106 zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema); | |
| 18107 } | |
| 18108 if( zSql==0 ) return SQLITE_NOMEM; | |
| 18109 | |
| 18110 rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0); | |
| 18111 sqlite3_free(zSql); | |
| 18112 if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 18113 pCsr->szDb = sqlite3_column_int(pStmt, 0); | |
| 18114 } | |
| 18115 rc2 = sqlite3_finalize(pStmt); | |
| 18116 if( rc==SQLITE_OK ) rc = rc2; | |
| 18117 return rc; | |
| 18118 } | |
| 18119 | |
| 18120 /* | |
| 18121 ** Attempt to figure out the encoding of the database by retrieving page 1 | |
| 18122 ** and inspecting the header field. If successful, set the pCsr->enc variable | |
| 18123 ** and return SQLITE_OK. Otherwise, return an SQLite error code. | |
| 18124 */ | |
| 18125 static int dbdataGetEncoding(DbdataCursor *pCsr){ | |
| 18126 int rc = SQLITE_OK; | |
| 18127 int nPg1 = 0; | |
| 18128 u8 *aPg1 = 0; | |
| 18129 rc = dbdataLoadPage(pCsr, 1, &aPg1, &nPg1); | |
| 18130 if( rc==SQLITE_OK && nPg1>=(56+4) ){ | |
| 18131 pCsr->enc = get_uint32(&aPg1[56]); | |
| 18132 } | |
| 18133 sqlite3_free(aPg1); | |
| 18134 return rc; | |
| 18135 } | |
| 18136 | |
| 18137 | |
| 18138 /* | |
| 18139 ** xFilter method for sqlite_dbdata and sqlite_dbptr. | |
| 18140 */ | |
| 18141 static int dbdataFilter( | |
| 18142 sqlite3_vtab_cursor *pCursor, | |
| 18143 int idxNum, const char *idxStr, | |
| 18144 int argc, sqlite3_value **argv | |
| 18145 ){ | |
| 18146 DbdataCursor *pCsr = (DbdataCursor*)pCursor; | |
| 18147 DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; | |
| 18148 int rc = SQLITE_OK; | |
| 18149 const char *zSchema = "main"; | |
| 18150 (void)idxStr; | |
| 18151 (void)argc; | |
| 18152 | |
| 18153 dbdataResetCursor(pCsr); | |
| 18154 assert( pCsr->iPgno==1 ); | |
| 18155 if( idxNum & 0x01 ){ | |
| 18156 zSchema = (const char*)sqlite3_value_text(argv[0]); | |
| 18157 if( zSchema==0 ) zSchema = ""; | |
| 18158 } | |
| 18159 if( idxNum & 0x02 ){ | |
| 18160 pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]); | |
| 18161 pCsr->bOnePage = 1; | |
| 18162 }else{ | |
| 18163 rc = dbdataDbsize(pCsr, zSchema); | |
| 18164 } | |
| 18165 | |
| 18166 if( rc==SQLITE_OK ){ | |
| 18167 int nFunc = 0; | |
| 18168 if( pTab->pStmt ){ | |
| 18169 pCsr->pStmt = pTab->pStmt; | |
| 18170 pTab->pStmt = 0; | |
| 18171 }else if( (nFunc = dbdataIsFunction(zSchema))>0 ){ | |
| 18172 char *zSql = sqlite3_mprintf("SELECT %.*s(?2)", nFunc, zSchema); | |
| 18173 if( zSql==0 ){ | |
| 18174 rc = SQLITE_NOMEM; | |
| 18175 }else{ | |
| 18176 rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0); | |
| 18177 sqlite3_free(zSql); | |
| 18178 } | |
| 18179 }else{ | |
| 18180 rc = sqlite3_prepare_v2(pTab->db, | |
| 18181 "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1, | |
| 18182 &pCsr->pStmt, 0 | |
| 18183 ); | |
| 18184 } | |
| 18185 } | |
| 18186 if( rc==SQLITE_OK ){ | |
| 18187 rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT); | |
| 18188 } | |
| 18189 | |
| 18190 /* Try to determine the encoding of the db by inspecting the header | |
| 18191 ** field on page 1. */ | |
| 18192 if( rc==SQLITE_OK ){ | |
| 18193 rc = dbdataGetEncoding(pCsr); | |
| 18194 } | |
| 18195 | |
| 18196 if( rc!=SQLITE_OK ){ | |
| 18197 pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); | |
| 18198 } | |
| 18199 | |
| 18200 if( rc==SQLITE_OK ){ | |
| 18201 rc = dbdataNext(pCursor); | |
| 18202 } | |
| 18203 return rc; | |
| 18204 } | |
| 18205 | |
| 18206 /* | |
| 18207 ** Return a column for the sqlite_dbdata or sqlite_dbptr table. | |
| 18208 */ | |
| 18209 static int dbdataColumn( | |
| 18210 sqlite3_vtab_cursor *pCursor, | |
| 18211 sqlite3_context *ctx, | |
| 18212 int i | |
| 18213 ){ | |
| 18214 DbdataCursor *pCsr = (DbdataCursor*)pCursor; | |
| 18215 DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; | |
| 18216 if( pTab->bPtr ){ | |
| 18217 switch( i ){ | |
| 18218 case DBPTR_COLUMN_PGNO: | |
| 18219 sqlite3_result_int64(ctx, pCsr->iPgno); | |
| 18220 break; | |
| 18221 case DBPTR_COLUMN_CHILD: { | |
| 18222 int iOff = pCsr->iPgno==1 ? 100 : 0; | |
| 18223 if( pCsr->iCell<0 ){ | |
| 18224 iOff += 8; | |
| 18225 }else{ | |
| 18226 iOff += 12 + pCsr->iCell*2; | |
| 18227 if( iOff>pCsr->nPage ) return SQLITE_OK; | |
| 18228 iOff = get_uint16(&pCsr->aPage[iOff]); | |
| 18229 } | |
| 18230 if( iOff<=pCsr->nPage ){ | |
| 18231 sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff])); | |
| 18232 } | |
| 18233 break; | |
| 18234 } | |
| 18235 } | |
| 18236 }else{ | |
| 18237 switch( i ){ | |
| 18238 case DBDATA_COLUMN_PGNO: | |
| 18239 sqlite3_result_int64(ctx, pCsr->iPgno); | |
| 18240 break; | |
| 18241 case DBDATA_COLUMN_CELL: | |
| 18242 sqlite3_result_int(ctx, pCsr->iCell); | |
| 18243 break; | |
| 18244 case DBDATA_COLUMN_FIELD: | |
| 18245 sqlite3_result_int(ctx, pCsr->iField); | |
| 18246 break; | |
| 18247 case DBDATA_COLUMN_VALUE: { | |
| 18248 if( pCsr->iField<0 ){ | |
| 18249 sqlite3_result_int64(ctx, pCsr->iIntkey); | |
| 18250 }else if( &pCsr->rec.aBuf[pCsr->nRec] >= pCsr->pPtr ){ | |
| 18251 sqlite3_int64 iType; | |
| 18252 dbdataGetVarintU32(pCsr->pHdrPtr, &iType); | |
| 18253 dbdataValue( | |
| 18254 ctx, pCsr->enc, iType, pCsr->pPtr, | |
| 18255 &pCsr->rec.aBuf[pCsr->nRec] - pCsr->pPtr | |
| 18256 ); | |
| 18257 } | |
| 18258 break; | |
| 18259 } | |
| 18260 } | |
| 18261 } | |
| 18262 return SQLITE_OK; | |
| 18263 } | |
| 18264 | |
| 18265 /* | |
| 18266 ** Return the rowid for an sqlite_dbdata or sqlite_dptr table. | |
| 18267 */ | |
| 18268 static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ | |
| 18269 DbdataCursor *pCsr = (DbdataCursor*)pCursor; | |
| 18270 *pRowid = pCsr->iRowid; | |
| 18271 return SQLITE_OK; | |
| 18272 } | |
| 18273 | |
| 18274 | |
| 18275 /* | |
| 18276 ** Invoke this routine to register the "sqlite_dbdata" virtual table module | |
| 18277 */ | |
| 18278 static int sqlite3DbdataRegister(sqlite3 *db){ | |
| 18279 static sqlite3_module dbdata_module = { | |
| 18280 0, /* iVersion */ | |
| 18281 0, /* xCreate */ | |
| 18282 dbdataConnect, /* xConnect */ | |
| 18283 dbdataBestIndex, /* xBestIndex */ | |
| 18284 dbdataDisconnect, /* xDisconnect */ | |
| 18285 0, /* xDestroy */ | |
| 18286 dbdataOpen, /* xOpen - open a cursor */ | |
| 18287 dbdataClose, /* xClose - close a cursor */ | |
| 18288 dbdataFilter, /* xFilter - configure scan constraints */ | |
| 18289 dbdataNext, /* xNext - advance a cursor */ | |
| 18290 dbdataEof, /* xEof - check for end of scan */ | |
| 18291 dbdataColumn, /* xColumn - read data */ | |
| 18292 dbdataRowid, /* xRowid - read data */ | |
| 18293 0, /* xUpdate */ | |
| 18294 0, /* xBegin */ | |
| 18295 0, /* xSync */ | |
| 18296 0, /* xCommit */ | |
| 18297 0, /* xRollback */ | |
| 18298 0, /* xFindMethod */ | |
| 18299 0, /* xRename */ | |
| 18300 0, /* xSavepoint */ | |
| 18301 0, /* xRelease */ | |
| 18302 0, /* xRollbackTo */ | |
| 18303 0, /* xShadowName */ | |
| 18304 0 /* xIntegrity */ | |
| 18305 }; | |
| 18306 | |
| 18307 int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0); | |
| 18308 if( rc==SQLITE_OK ){ | |
| 18309 rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1); | |
| 18310 } | |
| 18311 return rc; | |
| 18312 } | |
| 18313 | |
| 18314 #ifdef _WIN32 | |
| 18315 | |
| 18316 #endif | |
| 18317 int sqlite3_dbdata_init( | |
| 18318 sqlite3 *db, | |
| 18319 char **pzErrMsg, | |
| 18320 const sqlite3_api_routines *pApi | |
| 18321 ){ | |
| 18322 (void)pzErrMsg; | |
| 18323 return sqlite3DbdataRegister(db); | |
| 18324 } | |
| 18325 | |
| 18326 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ | |
| 18327 | |
| 18328 /************************* End ../ext/recover/dbdata.c ********************/ | |
| 18329 /************************* Begin ../ext/recover/sqlite3recover.c ******************/ | |
| 18330 /* | |
| 18331 ** 2022-08-27 | |
| 18332 ** | |
| 18333 ** The author disclaims copyright to this source code. In place of | |
| 18334 ** a legal notice, here is a blessing: | |
| 18335 ** | |
| 18336 ** May you do good and not evil. | |
| 18337 ** May you find forgiveness for yourself and forgive others. | |
| 18338 ** May you share freely, never taking more than you give. | |
| 18339 ** | |
| 18340 ************************************************************************* | |
| 18341 ** | |
| 18342 */ | |
| 18343 | |
| 18344 | |
| 18345 /* #include "sqlite3recover.h" */ | |
| 18346 #include <assert.h> | |
| 18347 #include <string.h> | |
| 18348 | |
| 18349 #ifndef SQLITE_OMIT_VIRTUALTABLE | |
| 18350 | |
| 18351 /* | |
| 18352 ** Declaration for public API function in file dbdata.c. This may be called | |
| 18353 ** with NULL as the final two arguments to register the sqlite_dbptr and | |
| 18354 ** sqlite_dbdata virtual tables with a database handle. | |
| 18355 */ | |
| 18356 #ifdef _WIN32 | |
| 18357 | |
| 18358 #endif | |
| 18359 int sqlite3_dbdata_init(sqlite3*, char**, const sqlite3_api_routines*); | |
| 18360 | |
| 18361 /* typedef unsigned int u32; */ | |
| 18362 /* typedef unsigned char u8; */ | |
| 18363 /* typedef sqlite3_int64 i64; */ | |
| 18364 | |
| 18365 /* | |
| 18366 ** Work around C99 "flex-array" syntax for pre-C99 compilers, so as | |
| 18367 ** to avoid complaints from -fsanitize=strict-bounds. | |
| 18368 */ | |
| 18369 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) | |
| 18370 # define FLEXARRAY | |
| 18371 #else | |
| 18372 # define FLEXARRAY 1 | |
| 18373 #endif | |
| 18374 | |
| 18375 typedef struct RecoverTable RecoverTable; | |
| 18376 typedef struct RecoverColumn RecoverColumn; | |
| 18377 | |
| 18378 /* | |
| 18379 ** When recovering rows of data that can be associated with table | |
| 18380 ** definitions recovered from the sqlite_schema table, each table is | |
| 18381 ** represented by an instance of the following object. | |
| 18382 ** | |
| 18383 ** iRoot: | |
| 18384 ** The root page in the original database. Not necessarily (and usually | |
| 18385 ** not) the same in the recovered database. | |
| 18386 ** | |
| 18387 ** zTab: | |
| 18388 ** Name of the table. | |
| 18389 ** | |
| 18390 ** nCol/aCol[]: | |
| 18391 ** aCol[] is an array of nCol columns. In the order in which they appear | |
| 18392 ** in the table. | |
| 18393 ** | |
| 18394 ** bIntkey: | |
| 18395 ** Set to true for intkey tables, false for WITHOUT ROWID. | |
| 18396 ** | |
| 18397 ** iRowidBind: | |
| 18398 ** Each column in the aCol[] array has associated with it the index of | |
| 18399 ** the bind parameter its values will be bound to in the INSERT statement | |
| 18400 ** used to construct the output database. If the table does has a rowid | |
| 18401 ** but not an INTEGER PRIMARY KEY column, then iRowidBind contains the | |
| 18402 ** index of the bind paramater to which the rowid value should be bound. | |
| 18403 ** Otherwise, it contains -1. If the table does contain an INTEGER PRIMARY | |
| 18404 ** KEY column, then the rowid value should be bound to the index associated | |
| 18405 ** with the column. | |
| 18406 ** | |
| 18407 ** pNext: | |
| 18408 ** All RecoverTable objects used by the recovery operation are allocated | |
| 18409 ** and populated as part of creating the recovered database schema in | |
| 18410 ** the output database, before any non-schema data are recovered. They | |
| 18411 ** are then stored in a singly-linked list linked by this variable beginning | |
| 18412 ** at sqlite3_recover.pTblList. | |
| 18413 */ | |
| 18414 struct RecoverTable { | |
| 18415 u32 iRoot; /* Root page in original database */ | |
| 18416 char *zTab; /* Name of table */ | |
| 18417 int nCol; /* Number of columns in table */ | |
| 18418 RecoverColumn *aCol; /* Array of columns */ | |
| 18419 int bIntkey; /* True for intkey, false for without rowid */ | |
| 18420 int iRowidBind; /* If >0, bind rowid to INSERT here */ | |
| 18421 RecoverTable *pNext; | |
| 18422 }; | |
| 18423 | |
| 18424 /* | |
| 18425 ** Each database column is represented by an instance of the following object | |
| 18426 ** stored in the RecoverTable.aCol[] array of the associated table. | |
| 18427 ** | |
| 18428 ** iField: | |
| 18429 ** The index of the associated field within database records. Or -1 if | |
| 18430 ** there is no associated field (e.g. for virtual generated columns). | |
| 18431 ** | |
| 18432 ** iBind: | |
| 18433 ** The bind index of the INSERT statement to bind this columns values | |
| 18434 ** to. Or 0 if there is no such index (iff (iField<0)). | |
| 18435 ** | |
| 18436 ** bIPK: | |
| 18437 ** True if this is the INTEGER PRIMARY KEY column. | |
| 18438 ** | |
| 18439 ** zCol: | |
| 18440 ** Name of column. | |
| 18441 ** | |
| 18442 ** eHidden: | |
| 18443 ** A RECOVER_EHIDDEN_* constant value (see below for interpretation of each). | |
| 18444 */ | |
| 18445 struct RecoverColumn { | |
| 18446 int iField; /* Field in record on disk */ | |
| 18447 int iBind; /* Binding to use in INSERT */ | |
| 18448 int bIPK; /* True for IPK column */ | |
| 18449 char *zCol; | |
| 18450 int eHidden; | |
| 18451 }; | |
| 18452 | |
| 18453 #define RECOVER_EHIDDEN_NONE 0 /* Normal database column */ | |
| 18454 #define RECOVER_EHIDDEN_HIDDEN 1 /* Column is __HIDDEN__ */ | |
| 18455 #define RECOVER_EHIDDEN_VIRTUAL 2 /* Virtual generated column */ | |
| 18456 #define RECOVER_EHIDDEN_STORED 3 /* Stored generated column */ | |
| 18457 | |
| 18458 /* | |
| 18459 ** Bitmap object used to track pages in the input database. Allocated | |
| 18460 ** and manipulated only by the following functions: | |
| 18461 ** | |
| 18462 ** recoverBitmapAlloc() | |
| 18463 ** recoverBitmapFree() | |
| 18464 ** recoverBitmapSet() | |
| 18465 ** recoverBitmapQuery() | |
| 18466 ** | |
| 18467 ** nPg: | |
| 18468 ** Largest page number that may be stored in the bitmap. The range | |
| 18469 ** of valid keys is 1 to nPg, inclusive. | |
| 18470 ** | |
| 18471 ** aElem[]: | |
| 18472 ** Array large enough to contain a bit for each key. For key value | |
| 18473 ** iKey, the associated bit is the bit (iKey%32) of aElem[iKey/32]. | |
| 18474 ** In other words, the following is true if bit iKey is set, or | |
| 18475 ** false if it is clear: | |
| 18476 ** | |
| 18477 ** (aElem[iKey/32] & (1 << (iKey%32))) ? 1 : 0 | |
| 18478 */ | |
| 18479 typedef struct RecoverBitmap RecoverBitmap; | |
| 18480 struct RecoverBitmap { | |
| 18481 i64 nPg; /* Size of bitmap */ | |
| 18482 u32 aElem[FLEXARRAY]; /* Array of 32-bit bitmasks */ | |
| 18483 }; | |
| 18484 | |
| 18485 /* Size in bytes of a RecoverBitmap object sufficient to cover 32 pages */ | |
| 18486 #define SZ_RECOVERBITMAP_32 (16) | |
| 18487 | |
| 18488 /* | |
| 18489 ** State variables (part of the sqlite3_recover structure) used while | |
| 18490 ** recovering data for tables identified in the recovered schema (state | |
| 18491 ** RECOVER_STATE_WRITING). | |
| 18492 */ | |
| 18493 typedef struct RecoverStateW1 RecoverStateW1; | |
| 18494 struct RecoverStateW1 { | |
| 18495 sqlite3_stmt *pTbls; | |
| 18496 sqlite3_stmt *pSel; | |
| 18497 sqlite3_stmt *pInsert; | |
| 18498 int nInsert; | |
| 18499 | |
| 18500 RecoverTable *pTab; /* Table currently being written */ | |
| 18501 int nMax; /* Max column count in any schema table */ | |
| 18502 sqlite3_value **apVal; /* Array of nMax values */ | |
| 18503 int nVal; /* Number of valid entries in apVal[] */ | |
| 18504 int bHaveRowid; | |
| 18505 i64 iRowid; | |
| 18506 i64 iPrevPage; | |
| 18507 int iPrevCell; | |
| 18508 }; | |
| 18509 | |
| 18510 /* | |
| 18511 ** State variables (part of the sqlite3_recover structure) used while | |
| 18512 ** recovering data destined for the lost and found table (states | |
| 18513 ** RECOVER_STATE_LOSTANDFOUND[123]). | |
| 18514 */ | |
| 18515 typedef struct RecoverStateLAF RecoverStateLAF; | |
| 18516 struct RecoverStateLAF { | |
| 18517 RecoverBitmap *pUsed; | |
| 18518 i64 nPg; /* Size of db in pages */ | |
| 18519 sqlite3_stmt *pAllAndParent; | |
| 18520 sqlite3_stmt *pMapInsert; | |
| 18521 sqlite3_stmt *pMaxField; | |
| 18522 sqlite3_stmt *pUsedPages; | |
| 18523 sqlite3_stmt *pFindRoot; | |
| 18524 sqlite3_stmt *pInsert; /* INSERT INTO lost_and_found ... */ | |
| 18525 sqlite3_stmt *pAllPage; | |
| 18526 sqlite3_stmt *pPageData; | |
| 18527 sqlite3_value **apVal; | |
| 18528 int nMaxField; | |
| 18529 }; | |
| 18530 | |
| 18531 /* | |
| 18532 ** Main recover handle structure. | |
| 18533 */ | |
| 18534 struct sqlite3_recover { | |
| 18535 /* Copies of sqlite3_recover_init[_sql]() parameters */ | |
| 18536 sqlite3 *dbIn; /* Input database */ | |
| 18537 char *zDb; /* Name of input db ("main" etc.) */ | |
| 18538 char *zUri; /* URI for output database */ | |
| 18539 void *pSqlCtx; /* SQL callback context */ | |
| 18540 int (*xSql)(void*,const char*); /* Pointer to SQL callback function */ | |
| 18541 | |
| 18542 /* Values configured by sqlite3_recover_config() */ | |
| 18543 char *zStateDb; /* State database to use (or NULL) */ | |
| 18544 char *zLostAndFound; /* Name of lost-and-found table (or NULL) */ | |
| 18545 int bFreelistCorrupt; /* SQLITE_RECOVER_FREELIST_CORRUPT setting */ | |
| 18546 int bRecoverRowid; /* SQLITE_RECOVER_ROWIDS setting */ | |
| 18547 int bSlowIndexes; /* SQLITE_RECOVER_SLOWINDEXES setting */ | |
| 18548 | |
| 18549 int pgsz; | |
| 18550 int detected_pgsz; | |
| 18551 int nReserve; | |
| 18552 u8 *pPage1Disk; | |
| 18553 u8 *pPage1Cache; | |
| 18554 | |
| 18555 /* Error code and error message */ | |
| 18556 int errCode; /* For sqlite3_recover_errcode() */ | |
| 18557 char *zErrMsg; /* For sqlite3_recover_errmsg() */ | |
| 18558 | |
| 18559 int eState; | |
| 18560 int bCloseTransaction; | |
| 18561 | |
| 18562 /* Variables used with eState==RECOVER_STATE_WRITING */ | |
| 18563 RecoverStateW1 w1; | |
| 18564 | |
| 18565 /* Variables used with states RECOVER_STATE_LOSTANDFOUND[123] */ | |
| 18566 RecoverStateLAF laf; | |
| 18567 | |
| 18568 /* Fields used within sqlite3_recover_run() */ | |
| 18569 sqlite3 *dbOut; /* Output database */ | |
| 18570 sqlite3_stmt *pGetPage; /* SELECT against input db sqlite_dbdata */ | |
| 18571 RecoverTable *pTblList; /* List of tables recovered from schema */ | |
| 18572 }; | |
| 18573 | |
| 18574 /* | |
| 18575 ** The various states in which an sqlite3_recover object may exist: | |
| 18576 ** | |
| 18577 ** RECOVER_STATE_INIT: | |
| 18578 ** The object is initially created in this state. sqlite3_recover_step() | |
| 18579 ** has yet to be called. This is the only state in which it is permitted | |
| 18580 ** to call sqlite3_recover_config(). | |
| 18581 ** | |
| 18582 ** RECOVER_STATE_WRITING: | |
| 18583 ** | |
| 18584 ** RECOVER_STATE_LOSTANDFOUND1: | |
| 18585 ** State to populate the bitmap of pages used by other tables or the | |
| 18586 ** database freelist. | |
| 18587 ** | |
| 18588 ** RECOVER_STATE_LOSTANDFOUND2: | |
| 18589 ** Populate the recovery.map table - used to figure out a "root" page | |
| 18590 ** for each lost page from in the database from which records are | |
| 18591 ** extracted. | |
| 18592 ** | |
| 18593 ** RECOVER_STATE_LOSTANDFOUND3: | |
| 18594 ** Populate the lost-and-found table itself. | |
| 18595 */ | |
| 18596 #define RECOVER_STATE_INIT 0 | |
| 18597 #define RECOVER_STATE_WRITING 1 | |
| 18598 #define RECOVER_STATE_LOSTANDFOUND1 2 | |
| 18599 #define RECOVER_STATE_LOSTANDFOUND2 3 | |
| 18600 #define RECOVER_STATE_LOSTANDFOUND3 4 | |
| 18601 #define RECOVER_STATE_SCHEMA2 5 | |
| 18602 #define RECOVER_STATE_DONE 6 | |
| 18603 | |
| 18604 | |
| 18605 /* | |
| 18606 ** Global variables used by this extension. | |
| 18607 */ | |
| 18608 typedef struct RecoverGlobal RecoverGlobal; | |
| 18609 struct RecoverGlobal { | |
| 18610 const sqlite3_io_methods *pMethods; | |
| 18611 sqlite3_recover *p; | |
| 18612 }; | |
| 18613 static RecoverGlobal recover_g; | |
| 18614 | |
| 18615 /* | |
| 18616 ** Use this static SQLite mutex to protect the globals during the | |
| 18617 ** first call to sqlite3_recover_step(). | |
| 18618 */ | |
| 18619 #define RECOVER_MUTEX_ID SQLITE_MUTEX_STATIC_APP2 | |
| 18620 | |
| 18621 | |
| 18622 /* | |
| 18623 ** Default value for SQLITE_RECOVER_ROWIDS (sqlite3_recover.bRecoverRowid). | |
| 18624 */ | |
| 18625 #define RECOVER_ROWID_DEFAULT 1 | |
| 18626 | |
| 18627 /* | |
| 18628 ** Mutex handling: | |
| 18629 ** | |
| 18630 ** recoverEnterMutex() - Enter the recovery mutex | |
| 18631 ** recoverLeaveMutex() - Leave the recovery mutex | |
| 18632 ** recoverAssertMutexHeld() - Assert that the recovery mutex is held | |
| 18633 */ | |
| 18634 #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0 | |
| 18635 # define recoverEnterMutex() | |
| 18636 # define recoverLeaveMutex() | |
| 18637 #else | |
| 18638 static void recoverEnterMutex(void){ | |
| 18639 sqlite3_mutex_enter(sqlite3_mutex_alloc(RECOVER_MUTEX_ID)); | |
| 18640 } | |
| 18641 static void recoverLeaveMutex(void){ | |
| 18642 sqlite3_mutex_leave(sqlite3_mutex_alloc(RECOVER_MUTEX_ID)); | |
| 18643 } | |
| 18644 #endif | |
| 18645 #if SQLITE_THREADSAFE+0>=1 && defined(SQLITE_DEBUG) | |
| 18646 static void recoverAssertMutexHeld(void){ | |
| 18647 assert( sqlite3_mutex_held(sqlite3_mutex_alloc(RECOVER_MUTEX_ID)) ); | |
| 18648 } | |
| 18649 #else | |
| 18650 # define recoverAssertMutexHeld() | |
| 18651 #endif | |
| 18652 | |
| 18653 | |
| 18654 /* | |
| 18655 ** Like strlen(). But handles NULL pointer arguments. | |
| 18656 */ | |
| 18657 static int recoverStrlen(const char *zStr){ | |
| 18658 if( zStr==0 ) return 0; | |
| 18659 return (int)(strlen(zStr)&0x7fffffff); | |
| 18660 } | |
| 18661 | |
| 18662 /* | |
| 18663 ** This function is a no-op if the recover handle passed as the first | |
| 18664 ** argument already contains an error (if p->errCode!=SQLITE_OK). | |
| 18665 ** | |
| 18666 ** Otherwise, an attempt is made to allocate, zero and return a buffer nByte | |
| 18667 ** bytes in size. If successful, a pointer to the new buffer is returned. Or, | |
| 18668 ** if an OOM error occurs, NULL is returned and the handle error code | |
| 18669 ** (p->errCode) set to SQLITE_NOMEM. | |
| 18670 */ | |
| 18671 static void *recoverMalloc(sqlite3_recover *p, i64 nByte){ | |
| 18672 void *pRet = 0; | |
| 18673 assert( nByte>0 ); | |
| 18674 if( p->errCode==SQLITE_OK ){ | |
| 18675 pRet = sqlite3_malloc64(nByte); | |
| 18676 if( pRet ){ | |
| 18677 memset(pRet, 0, nByte); | |
| 18678 }else{ | |
| 18679 p->errCode = SQLITE_NOMEM; | |
| 18680 } | |
| 18681 } | |
| 18682 return pRet; | |
| 18683 } | |
| 18684 | |
| 18685 /* | |
| 18686 ** Set the error code and error message for the recover handle passed as | |
| 18687 ** the first argument. The error code is set to the value of parameter | |
| 18688 ** errCode. | |
| 18689 ** | |
| 18690 ** Parameter zFmt must be a printf() style formatting string. The handle | |
| 18691 ** error message is set to the result of using any trailing arguments for | |
| 18692 ** parameter substitutions in the formatting string. | |
| 18693 ** | |
| 18694 ** For example: | |
| 18695 ** | |
| 18696 ** recoverError(p, SQLITE_ERROR, "no such table: %s", zTablename); | |
| 18697 */ | |
| 18698 static int recoverError( | |
| 18699 sqlite3_recover *p, | |
| 18700 int errCode, | |
| 18701 const char *zFmt, ... | |
| 18702 ){ | |
| 18703 char *z = 0; | |
| 18704 va_list ap; | |
| 18705 va_start(ap, zFmt); | |
| 18706 if( zFmt ){ | |
| 18707 z = sqlite3_vmprintf(zFmt, ap); | |
| 18708 } | |
| 18709 va_end(ap); | |
| 18710 sqlite3_free(p->zErrMsg); | |
| 18711 p->zErrMsg = z; | |
| 18712 p->errCode = errCode; | |
| 18713 return errCode; | |
| 18714 } | |
| 18715 | |
| 18716 | |
| 18717 /* | |
| 18718 ** This function is a no-op if p->errCode is initially other than SQLITE_OK. | |
| 18719 ** In this case it returns NULL. | |
| 18720 ** | |
| 18721 ** Otherwise, an attempt is made to allocate and return a bitmap object | |
| 18722 ** large enough to store a bit for all page numbers between 1 and nPg, | |
| 18723 ** inclusive. The bitmap is initially zeroed. | |
| 18724 */ | |
| 18725 static RecoverBitmap *recoverBitmapAlloc(sqlite3_recover *p, i64 nPg){ | |
| 18726 int nElem = (nPg+1+31) / 32; | |
| 18727 int nByte = SZ_RECOVERBITMAP_32 + nElem*sizeof(u32); | |
| 18728 RecoverBitmap *pRet = (RecoverBitmap*)recoverMalloc(p, nByte); | |
| 18729 | |
| 18730 if( pRet ){ | |
| 18731 pRet->nPg = nPg; | |
| 18732 } | |
| 18733 return pRet; | |
| 18734 } | |
| 18735 | |
| 18736 /* | |
| 18737 ** Free a bitmap object allocated by recoverBitmapAlloc(). | |
| 18738 */ | |
| 18739 static void recoverBitmapFree(RecoverBitmap *pMap){ | |
| 18740 sqlite3_free(pMap); | |
| 18741 } | |
| 18742 | |
| 18743 /* | |
| 18744 ** Set the bit associated with page iPg in bitvec pMap. | |
| 18745 */ | |
| 18746 static void recoverBitmapSet(RecoverBitmap *pMap, i64 iPg){ | |
| 18747 if( iPg<=pMap->nPg ){ | |
| 18748 int iElem = (iPg / 32); | |
| 18749 int iBit = (iPg % 32); | |
| 18750 pMap->aElem[iElem] |= (((u32)1) << iBit); | |
| 18751 } | |
| 18752 } | |
| 18753 | |
| 18754 /* | |
| 18755 ** Query bitmap object pMap for the state of the bit associated with page | |
| 18756 ** iPg. Return 1 if it is set, or 0 otherwise. | |
| 18757 */ | |
| 18758 static int recoverBitmapQuery(RecoverBitmap *pMap, i64 iPg){ | |
| 18759 int ret = 1; | |
| 18760 if( iPg<=pMap->nPg && iPg>0 ){ | |
| 18761 int iElem = (iPg / 32); | |
| 18762 int iBit = (iPg % 32); | |
| 18763 ret = (pMap->aElem[iElem] & (((u32)1) << iBit)) ? 1 : 0; | |
| 18764 } | |
| 18765 return ret; | |
| 18766 } | |
| 18767 | |
| 18768 /* | |
| 18769 ** Set the recover handle error to the error code and message returned by | |
| 18770 ** calling sqlite3_errcode() and sqlite3_errmsg(), respectively, on database | |
| 18771 ** handle db. | |
| 18772 */ | |
| 18773 static int recoverDbError(sqlite3_recover *p, sqlite3 *db){ | |
| 18774 return recoverError(p, sqlite3_errcode(db), "%s", sqlite3_errmsg(db)); | |
| 18775 } | |
| 18776 | |
| 18777 /* | |
| 18778 ** This function is a no-op if recover handle p already contains an error | |
| 18779 ** (if p->errCode!=SQLITE_OK). | |
| 18780 ** | |
| 18781 ** Otherwise, it attempts to prepare the SQL statement in zSql against | |
| 18782 ** database handle db. If successful, the statement handle is returned. | |
| 18783 ** Or, if an error occurs, NULL is returned and an error left in the | |
| 18784 ** recover handle. | |
| 18785 */ | |
| 18786 static sqlite3_stmt *recoverPrepare( | |
| 18787 sqlite3_recover *p, | |
| 18788 sqlite3 *db, | |
| 18789 const char *zSql | |
| 18790 ){ | |
| 18791 sqlite3_stmt *pStmt = 0; | |
| 18792 if( p->errCode==SQLITE_OK ){ | |
| 18793 if( sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) ){ | |
| 18794 recoverDbError(p, db); | |
| 18795 } | |
| 18796 } | |
| 18797 return pStmt; | |
| 18798 } | |
| 18799 | |
| 18800 /* | |
| 18801 ** This function is a no-op if recover handle p already contains an error | |
| 18802 ** (if p->errCode!=SQLITE_OK). | |
| 18803 ** | |
| 18804 ** Otherwise, argument zFmt is used as a printf() style format string, | |
| 18805 ** along with any trailing arguments, to create an SQL statement. This | |
| 18806 ** SQL statement is prepared against database handle db and, if successful, | |
| 18807 ** the statment handle returned. Or, if an error occurs - either during | |
| 18808 ** the printf() formatting or when preparing the resulting SQL - an | |
| 18809 ** error code and message are left in the recover handle. | |
| 18810 */ | |
| 18811 static sqlite3_stmt *recoverPreparePrintf( | |
| 18812 sqlite3_recover *p, | |
| 18813 sqlite3 *db, | |
| 18814 const char *zFmt, ... | |
| 18815 ){ | |
| 18816 sqlite3_stmt *pStmt = 0; | |
| 18817 if( p->errCode==SQLITE_OK ){ | |
| 18818 va_list ap; | |
| 18819 char *z; | |
| 18820 va_start(ap, zFmt); | |
| 18821 z = sqlite3_vmprintf(zFmt, ap); | |
| 18822 va_end(ap); | |
| 18823 if( z==0 ){ | |
| 18824 p->errCode = SQLITE_NOMEM; | |
| 18825 }else{ | |
| 18826 pStmt = recoverPrepare(p, db, z); | |
| 18827 sqlite3_free(z); | |
| 18828 } | |
| 18829 } | |
| 18830 return pStmt; | |
| 18831 } | |
| 18832 | |
| 18833 /* | |
| 18834 ** Reset SQLite statement handle pStmt. If the call to sqlite3_reset() | |
| 18835 ** indicates that an error occurred, and there is not already an error | |
| 18836 ** in the recover handle passed as the first argument, set the error | |
| 18837 ** code and error message appropriately. | |
| 18838 ** | |
| 18839 ** This function returns a copy of the statement handle pointer passed | |
| 18840 ** as the second argument. | |
| 18841 */ | |
| 18842 static sqlite3_stmt *recoverReset(sqlite3_recover *p, sqlite3_stmt *pStmt){ | |
| 18843 int rc = sqlite3_reset(pStmt); | |
| 18844 if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT && p->errCode==SQLITE_OK ){ | |
| 18845 recoverDbError(p, sqlite3_db_handle(pStmt)); | |
| 18846 } | |
| 18847 return pStmt; | |
| 18848 } | |
| 18849 | |
| 18850 /* | |
| 18851 ** Finalize SQLite statement handle pStmt. If the call to sqlite3_reset() | |
| 18852 ** indicates that an error occurred, and there is not already an error | |
| 18853 ** in the recover handle passed as the first argument, set the error | |
| 18854 ** code and error message appropriately. | |
| 18855 */ | |
| 18856 static void recoverFinalize(sqlite3_recover *p, sqlite3_stmt *pStmt){ | |
| 18857 sqlite3 *db = sqlite3_db_handle(pStmt); | |
| 18858 int rc = sqlite3_finalize(pStmt); | |
| 18859 if( rc!=SQLITE_OK && p->errCode==SQLITE_OK ){ | |
| 18860 recoverDbError(p, db); | |
| 18861 } | |
| 18862 } | |
| 18863 | |
| 18864 /* | |
| 18865 ** This function is a no-op if recover handle p already contains an error | |
| 18866 ** (if p->errCode!=SQLITE_OK). A copy of p->errCode is returned in this | |
| 18867 ** case. | |
| 18868 ** | |
| 18869 ** Otherwise, execute SQL script zSql. If successful, return SQLITE_OK. | |
| 18870 ** Or, if an error occurs, leave an error code and message in the recover | |
| 18871 ** handle and return a copy of the error code. | |
| 18872 */ | |
| 18873 static int recoverExec(sqlite3_recover *p, sqlite3 *db, const char *zSql){ | |
| 18874 if( p->errCode==SQLITE_OK ){ | |
| 18875 int rc = sqlite3_exec(db, zSql, 0, 0, 0); | |
| 18876 if( rc ){ | |
| 18877 recoverDbError(p, db); | |
| 18878 } | |
| 18879 } | |
| 18880 return p->errCode; | |
| 18881 } | |
| 18882 | |
| 18883 /* | |
| 18884 ** Bind the value pVal to parameter iBind of statement pStmt. Leave an | |
| 18885 ** error in the recover handle passed as the first argument if an error | |
| 18886 ** (e.g. an OOM) occurs. | |
| 18887 */ | |
| 18888 static void recoverBindValue( | |
| 18889 sqlite3_recover *p, | |
| 18890 sqlite3_stmt *pStmt, | |
| 18891 int iBind, | |
| 18892 sqlite3_value *pVal | |
| 18893 ){ | |
| 18894 if( p->errCode==SQLITE_OK ){ | |
| 18895 int rc = sqlite3_bind_value(pStmt, iBind, pVal); | |
| 18896 if( rc ) recoverError(p, rc, 0); | |
| 18897 } | |
| 18898 } | |
| 18899 | |
| 18900 /* | |
| 18901 ** This function is a no-op if recover handle p already contains an error | |
| 18902 ** (if p->errCode!=SQLITE_OK). NULL is returned in this case. | |
| 18903 ** | |
| 18904 ** Otherwise, an attempt is made to interpret zFmt as a printf() style | |
| 18905 ** formatting string and the result of using the trailing arguments for | |
| 18906 ** parameter substitution with it written into a buffer obtained from | |
| 18907 ** sqlite3_malloc(). If successful, a pointer to the buffer is returned. | |
| 18908 ** It is the responsibility of the caller to eventually free the buffer | |
| 18909 ** using sqlite3_free(). | |
| 18910 ** | |
| 18911 ** Or, if an error occurs, an error code and message is left in the recover | |
| 18912 ** handle and NULL returned. | |
| 18913 */ | |
| 18914 static char *recoverMPrintf(sqlite3_recover *p, const char *zFmt, ...){ | |
| 18915 va_list ap; | |
| 18916 char *z; | |
| 18917 va_start(ap, zFmt); | |
| 18918 z = sqlite3_vmprintf(zFmt, ap); | |
| 18919 va_end(ap); | |
| 18920 if( p->errCode==SQLITE_OK ){ | |
| 18921 if( z==0 ) p->errCode = SQLITE_NOMEM; | |
| 18922 }else{ | |
| 18923 sqlite3_free(z); | |
| 18924 z = 0; | |
| 18925 } | |
| 18926 return z; | |
| 18927 } | |
| 18928 | |
| 18929 /* | |
| 18930 ** This function is a no-op if recover handle p already contains an error | |
| 18931 ** (if p->errCode!=SQLITE_OK). Zero is returned in this case. | |
| 18932 ** | |
| 18933 ** Otherwise, execute "PRAGMA page_count" against the input database. If | |
| 18934 ** successful, return the integer result. Or, if an error occurs, leave an | |
| 18935 ** error code and error message in the sqlite3_recover handle and return | |
| 18936 ** zero. | |
| 18937 */ | |
| 18938 static i64 recoverPageCount(sqlite3_recover *p){ | |
| 18939 i64 nPg = 0; | |
| 18940 if( p->errCode==SQLITE_OK ){ | |
| 18941 sqlite3_stmt *pStmt = 0; | |
| 18942 pStmt = recoverPreparePrintf(p, p->dbIn, "PRAGMA %Q.page_count", p->zDb); | |
| 18943 if( pStmt ){ | |
| 18944 sqlite3_step(pStmt); | |
| 18945 nPg = sqlite3_column_int64(pStmt, 0); | |
| 18946 } | |
| 18947 recoverFinalize(p, pStmt); | |
| 18948 } | |
| 18949 return nPg; | |
| 18950 } | |
| 18951 | |
| 18952 /* | |
| 18953 ** Implementation of SQL scalar function "read_i32". The first argument to | |
| 18954 ** this function must be a blob. The second a non-negative integer. This | |
| 18955 ** function reads and returns a 32-bit big-endian integer from byte | |
| 18956 ** offset (4*<arg2>) of the blob. | |
| 18957 ** | |
| 18958 ** SELECT read_i32(<blob>, <idx>) | |
| 18959 */ | |
| 18960 static void recoverReadI32( | |
| 18961 sqlite3_context *context, | |
| 18962 int argc, | |
| 18963 sqlite3_value **argv | |
| 18964 ){ | |
| 18965 const unsigned char *pBlob; | |
| 18966 int nBlob; | |
| 18967 int iInt; | |
| 18968 | |
| 18969 assert( argc==2 ); | |
| 18970 nBlob = sqlite3_value_bytes(argv[0]); | |
| 18971 pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]); | |
| 18972 iInt = sqlite3_value_int(argv[1]) & 0xFFFF; | |
| 18973 | |
| 18974 if( (iInt+1)*4<=nBlob ){ | |
| 18975 const unsigned char *a = &pBlob[iInt*4]; | |
| 18976 i64 iVal = ((i64)a[0]<<24) | |
| 18977 + ((i64)a[1]<<16) | |
| 18978 + ((i64)a[2]<< 8) | |
| 18979 + ((i64)a[3]<< 0); | |
| 18980 sqlite3_result_int64(context, iVal); | |
| 18981 } | |
| 18982 } | |
| 18983 | |
| 18984 /* | |
| 18985 ** Implementation of SQL scalar function "page_is_used". This function | |
| 18986 ** is used as part of the procedure for locating orphan rows for the | |
| 18987 ** lost-and-found table, and it depends on those routines having populated | |
| 18988 ** the sqlite3_recover.laf.pUsed variable. | |
| 18989 ** | |
| 18990 ** The only argument to this function is a page-number. It returns true | |
| 18991 ** if the page has already been used somehow during data recovery, or false | |
| 18992 ** otherwise. | |
| 18993 ** | |
| 18994 ** SELECT page_is_used(<pgno>); | |
| 18995 */ | |
| 18996 static void recoverPageIsUsed( | |
| 18997 sqlite3_context *pCtx, | |
| 18998 int nArg, | |
| 18999 sqlite3_value **apArg | |
| 19000 ){ | |
| 19001 sqlite3_recover *p = (sqlite3_recover*)sqlite3_user_data(pCtx); | |
| 19002 i64 pgno = sqlite3_value_int64(apArg[0]); | |
| 19003 assert( nArg==1 ); | |
| 19004 sqlite3_result_int(pCtx, recoverBitmapQuery(p->laf.pUsed, pgno)); | |
| 19005 } | |
| 19006 | |
| 19007 /* | |
| 19008 ** The implementation of a user-defined SQL function invoked by the | |
| 19009 ** sqlite_dbdata and sqlite_dbptr virtual table modules to access pages | |
| 19010 ** of the database being recovered. | |
| 19011 ** | |
| 19012 ** This function always takes a single integer argument. If the argument | |
| 19013 ** is zero, then the value returned is the number of pages in the db being | |
| 19014 ** recovered. If the argument is greater than zero, it is a page number. | |
| 19015 ** The value returned in this case is an SQL blob containing the data for | |
| 19016 ** the identified page of the db being recovered. e.g. | |
| 19017 ** | |
| 19018 ** SELECT getpage(0); -- return number of pages in db | |
| 19019 ** SELECT getpage(4); -- return page 4 of db as a blob of data | |
| 19020 */ | |
| 19021 static void recoverGetPage( | |
| 19022 sqlite3_context *pCtx, | |
| 19023 int nArg, | |
| 19024 sqlite3_value **apArg | |
| 19025 ){ | |
| 19026 sqlite3_recover *p = (sqlite3_recover*)sqlite3_user_data(pCtx); | |
| 19027 i64 pgno = sqlite3_value_int64(apArg[0]); | |
| 19028 sqlite3_stmt *pStmt = 0; | |
| 19029 | |
| 19030 assert( nArg==1 ); | |
| 19031 if( pgno==0 ){ | |
| 19032 i64 nPg = recoverPageCount(p); | |
| 19033 sqlite3_result_int64(pCtx, nPg); | |
| 19034 return; | |
| 19035 }else{ | |
| 19036 if( p->pGetPage==0 ){ | |
| 19037 pStmt = p->pGetPage = recoverPreparePrintf( | |
| 19038 p, p->dbIn, "SELECT data FROM sqlite_dbpage(%Q) WHERE pgno=?", p->zDb | |
| 19039 ); | |
| 19040 }else if( p->errCode==SQLITE_OK ){ | |
| 19041 pStmt = p->pGetPage; | |
| 19042 } | |
| 19043 | |
| 19044 if( pStmt ){ | |
| 19045 sqlite3_bind_int64(pStmt, 1, pgno); | |
| 19046 if( SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 19047 const u8 *aPg; | |
| 19048 int nPg; | |
| 19049 assert( p->errCode==SQLITE_OK ); | |
| 19050 aPg = sqlite3_column_blob(pStmt, 0); | |
| 19051 nPg = sqlite3_column_bytes(pStmt, 0); | |
| 19052 if( pgno==1 && nPg==p->pgsz && 0==memcmp(p->pPage1Cache, aPg, nPg) ){ | |
| 19053 aPg = p->pPage1Disk; | |
| 19054 } | |
| 19055 sqlite3_result_blob(pCtx, aPg, nPg-p->nReserve, SQLITE_TRANSIENT); | |
| 19056 } | |
| 19057 recoverReset(p, pStmt); | |
| 19058 } | |
| 19059 } | |
| 19060 | |
| 19061 if( p->errCode ){ | |
| 19062 if( p->zErrMsg ) sqlite3_result_error(pCtx, p->zErrMsg, -1); | |
| 19063 sqlite3_result_error_code(pCtx, p->errCode); | |
| 19064 } | |
| 19065 } | |
| 19066 | |
| 19067 /* | |
| 19068 ** Find a string that is not found anywhere in z[]. Return a pointer | |
| 19069 ** to that string. | |
| 19070 ** | |
| 19071 ** Try to use zA and zB first. If both of those are already found in z[] | |
| 19072 ** then make up some string and store it in the buffer zBuf. | |
| 19073 */ | |
| 19074 static const char *recoverUnusedString( | |
| 19075 const char *z, /* Result must not appear anywhere in z */ | |
| 19076 const char *zA, const char *zB, /* Try these first */ | |
| 19077 char *zBuf /* Space to store a generated string */ | |
| 19078 ){ | |
| 19079 unsigned i = 0; | |
| 19080 if( strstr(z, zA)==0 ) return zA; | |
| 19081 if( strstr(z, zB)==0 ) return zB; | |
| 19082 do{ | |
| 19083 sqlite3_snprintf(20,zBuf,"(%s%u)", zA, i++); | |
| 19084 }while( strstr(z,zBuf)!=0 ); | |
| 19085 return zBuf; | |
| 19086 } | |
| 19087 | |
| 19088 /* | |
| 19089 ** Implementation of scalar SQL function "escape_crlf". The argument passed to | |
| 19090 ** this function is the output of built-in function quote(). If the first | |
| 19091 ** character of the input is "'", indicating that the value passed to quote() | |
| 19092 ** was a text value, then this function searches the input for "\n" and "\r" | |
| 19093 ** characters and adds a wrapper similar to the following: | |
| 19094 ** | |
| 19095 ** replace(replace(<input>, '\n', char(10), '\r', char(13)); | |
| 19096 ** | |
| 19097 ** Or, if the first character of the input is not "'", then a copy of the input | |
| 19098 ** is returned. | |
| 19099 */ | |
| 19100 static void recoverEscapeCrlf( | |
| 19101 sqlite3_context *context, | |
| 19102 int argc, | |
| 19103 sqlite3_value **argv | |
| 19104 ){ | |
| 19105 const char *zText = (const char*)sqlite3_value_text(argv[0]); | |
| 19106 (void)argc; | |
| 19107 if( zText && zText[0]=='\'' ){ | |
| 19108 int nText = sqlite3_value_bytes(argv[0]); | |
| 19109 int i; | |
| 19110 char zBuf1[20]; | |
| 19111 char zBuf2[20]; | |
| 19112 const char *zNL = 0; | |
| 19113 const char *zCR = 0; | |
| 19114 int nCR = 0; | |
| 19115 int nNL = 0; | |
| 19116 | |
| 19117 for(i=0; zText[i]; i++){ | |
| 19118 if( zNL==0 && zText[i]=='\n' ){ | |
| 19119 zNL = recoverUnusedString(zText, "\\n", "\\012", zBuf1); | |
| 19120 nNL = (int)strlen(zNL); | |
| 19121 } | |
| 19122 if( zCR==0 && zText[i]=='\r' ){ | |
| 19123 zCR = recoverUnusedString(zText, "\\r", "\\015", zBuf2); | |
| 19124 nCR = (int)strlen(zCR); | |
| 19125 } | |
| 19126 } | |
| 19127 | |
| 19128 if( zNL || zCR ){ | |
| 19129 int iOut = 0; | |
| 19130 i64 nMax = (nNL > nCR) ? nNL : nCR; | |
| 19131 i64 nAlloc = nMax * nText + (nMax+64)*2; | |
| 19132 char *zOut = (char*)sqlite3_malloc64(nAlloc); | |
| 19133 if( zOut==0 ){ | |
| 19134 sqlite3_result_error_nomem(context); | |
| 19135 return; | |
| 19136 } | |
| 19137 | |
| 19138 if( zNL && zCR ){ | |
| 19139 memcpy(&zOut[iOut], "replace(replace(", 16); | |
| 19140 iOut += 16; | |
| 19141 }else{ | |
| 19142 memcpy(&zOut[iOut], "replace(", 8); | |
| 19143 iOut += 8; | |
| 19144 } | |
| 19145 for(i=0; zText[i]; i++){ | |
| 19146 if( zText[i]=='\n' ){ | |
| 19147 memcpy(&zOut[iOut], zNL, nNL); | |
| 19148 iOut += nNL; | |
| 19149 }else if( zText[i]=='\r' ){ | |
| 19150 memcpy(&zOut[iOut], zCR, nCR); | |
| 19151 iOut += nCR; | |
| 19152 }else{ | |
| 19153 zOut[iOut] = zText[i]; | |
| 19154 iOut++; | |
| 19155 } | |
| 19156 } | |
| 19157 | |
| 19158 if( zNL ){ | |
| 19159 memcpy(&zOut[iOut], ",'", 2); iOut += 2; | |
| 19160 memcpy(&zOut[iOut], zNL, nNL); iOut += nNL; | |
| 19161 memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12; | |
| 19162 } | |
| 19163 if( zCR ){ | |
| 19164 memcpy(&zOut[iOut], ",'", 2); iOut += 2; | |
| 19165 memcpy(&zOut[iOut], zCR, nCR); iOut += nCR; | |
| 19166 memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12; | |
| 19167 } | |
| 19168 | |
| 19169 sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT); | |
| 19170 sqlite3_free(zOut); | |
| 19171 return; | |
| 19172 } | |
| 19173 } | |
| 19174 | |
| 19175 sqlite3_result_value(context, argv[0]); | |
| 19176 } | |
| 19177 | |
| 19178 /* | |
| 19179 ** This function is a no-op if recover handle p already contains an error | |
| 19180 ** (if p->errCode!=SQLITE_OK). A copy of the error code is returned in | |
| 19181 ** this case. | |
| 19182 ** | |
| 19183 ** Otherwise, attempt to populate temporary table "recovery.schema" with the | |
| 19184 ** parts of the database schema that can be extracted from the input database. | |
| 19185 ** | |
| 19186 ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code | |
| 19187 ** and error message are left in the recover handle and a copy of the | |
| 19188 ** error code returned. It is not considered an error if part of all of | |
| 19189 ** the database schema cannot be recovered due to corruption. | |
| 19190 */ | |
| 19191 static int recoverCacheSchema(sqlite3_recover *p){ | |
| 19192 return recoverExec(p, p->dbOut, | |
| 19193 "WITH RECURSIVE pages(p) AS (" | |
| 19194 " SELECT 1" | |
| 19195 " UNION" | |
| 19196 " SELECT child FROM sqlite_dbptr('getpage()'), pages WHERE pgno=p" | |
| 19197 ")" | |
| 19198 "INSERT INTO recovery.schema SELECT" | |
| 19199 " max(CASE WHEN field=0 THEN value ELSE NULL END)," | |
| 19200 " max(CASE WHEN field=1 THEN value ELSE NULL END)," | |
| 19201 " max(CASE WHEN field=2 THEN value ELSE NULL END)," | |
| 19202 " max(CASE WHEN field=3 THEN value ELSE NULL END)," | |
| 19203 " max(CASE WHEN field=4 THEN value ELSE NULL END)" | |
| 19204 "FROM sqlite_dbdata('getpage()') WHERE pgno IN (" | |
| 19205 " SELECT p FROM pages" | |
| 19206 ") GROUP BY pgno, cell" | |
| 19207 ); | |
| 19208 } | |
| 19209 | |
| 19210 /* | |
| 19211 ** If this recover handle is not in SQL callback mode (i.e. was not created | |
| 19212 ** using sqlite3_recover_init_sql()) of if an error has already occurred, | |
| 19213 ** this function is a no-op. Otherwise, issue a callback with SQL statement | |
| 19214 ** zSql as the parameter. | |
| 19215 ** | |
| 19216 ** If the callback returns non-zero, set the recover handle error code to | |
| 19217 ** the value returned (so that the caller will abandon processing). | |
| 19218 */ | |
| 19219 static void recoverSqlCallback(sqlite3_recover *p, const char *zSql){ | |
| 19220 if( p->errCode==SQLITE_OK && p->xSql ){ | |
| 19221 int res = p->xSql(p->pSqlCtx, zSql); | |
| 19222 if( res ){ | |
| 19223 recoverError(p, SQLITE_ERROR, "callback returned an error - %d", res); | |
| 19224 } | |
| 19225 } | |
| 19226 } | |
| 19227 | |
| 19228 /* | |
| 19229 ** Transfer the following settings from the input database to the output | |
| 19230 ** database: | |
| 19231 ** | |
| 19232 ** + page-size, | |
| 19233 ** + auto-vacuum settings, | |
| 19234 ** + database encoding, | |
| 19235 ** + user-version (PRAGMA user_version), and | |
| 19236 ** + application-id (PRAGMA application_id), and | |
| 19237 */ | |
| 19238 static void recoverTransferSettings(sqlite3_recover *p){ | |
| 19239 const char *aPragma[] = { | |
| 19240 "encoding", | |
| 19241 "page_size", | |
| 19242 "auto_vacuum", | |
| 19243 "user_version", | |
| 19244 "application_id" | |
| 19245 }; | |
| 19246 int ii; | |
| 19247 | |
| 19248 /* Truncate the output database to 0 pages in size. This is done by | |
| 19249 ** opening a new, empty, temp db, then using the backup API to clobber | |
| 19250 ** any existing output db with a copy of it. */ | |
| 19251 if( p->errCode==SQLITE_OK ){ | |
| 19252 sqlite3 *db2 = 0; | |
| 19253 int rc = sqlite3_open("", &db2); | |
| 19254 if( rc!=SQLITE_OK ){ | |
| 19255 recoverDbError(p, db2); | |
| 19256 return; | |
| 19257 } | |
| 19258 | |
| 19259 for(ii=0; ii<(int)(sizeof(aPragma)/sizeof(aPragma[0])); ii++){ | |
| 19260 const char *zPrag = aPragma[ii]; | |
| 19261 sqlite3_stmt *p1 = 0; | |
| 19262 p1 = recoverPreparePrintf(p, p->dbIn, "PRAGMA %Q.%s", p->zDb, zPrag); | |
| 19263 if( p->errCode==SQLITE_OK && sqlite3_step(p1)==SQLITE_ROW ){ | |
| 19264 const char *zArg = (const char*)sqlite3_column_text(p1, 0); | |
| 19265 char *z2 = recoverMPrintf(p, "PRAGMA %s = %Q", zPrag, zArg); | |
| 19266 recoverSqlCallback(p, z2); | |
| 19267 recoverExec(p, db2, z2); | |
| 19268 sqlite3_free(z2); | |
| 19269 if( zArg==0 ){ | |
| 19270 recoverError(p, SQLITE_NOMEM, 0); | |
| 19271 } | |
| 19272 } | |
| 19273 recoverFinalize(p, p1); | |
| 19274 } | |
| 19275 recoverExec(p, db2, "CREATE TABLE t1(a); DROP TABLE t1;"); | |
| 19276 | |
| 19277 if( p->errCode==SQLITE_OK ){ | |
| 19278 sqlite3 *db = p->dbOut; | |
| 19279 sqlite3_backup *pBackup = sqlite3_backup_init(db, "main", db2, "main"); | |
| 19280 if( pBackup ){ | |
| 19281 sqlite3_backup_step(pBackup, -1); | |
| 19282 p->errCode = sqlite3_backup_finish(pBackup); | |
| 19283 }else{ | |
| 19284 recoverDbError(p, db); | |
| 19285 } | |
| 19286 } | |
| 19287 | |
| 19288 sqlite3_close(db2); | |
| 19289 } | |
| 19290 } | |
| 19291 | |
| 19292 /* | |
| 19293 ** This function is a no-op if recover handle p already contains an error | |
| 19294 ** (if p->errCode!=SQLITE_OK). A copy of the error code is returned in | |
| 19295 ** this case. | |
| 19296 ** | |
| 19297 ** Otherwise, an attempt is made to open the output database, attach | |
| 19298 ** and create the schema of the temporary database used to store | |
| 19299 ** intermediate data, and to register all required user functions and | |
| 19300 ** virtual table modules with the output handle. | |
| 19301 ** | |
| 19302 ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code | |
| 19303 ** and error message are left in the recover handle and a copy of the | |
| 19304 ** error code returned. | |
| 19305 */ | |
| 19306 static int recoverOpenOutput(sqlite3_recover *p){ | |
| 19307 struct Func { | |
| 19308 const char *zName; | |
| 19309 int nArg; | |
| 19310 void (*xFunc)(sqlite3_context*,int,sqlite3_value **); | |
| 19311 } aFunc[] = { | |
| 19312 { "getpage", 1, recoverGetPage }, | |
| 19313 { "page_is_used", 1, recoverPageIsUsed }, | |
| 19314 { "read_i32", 2, recoverReadI32 }, | |
| 19315 { "escape_crlf", 1, recoverEscapeCrlf }, | |
| 19316 }; | |
| 19317 | |
| 19318 const int flags = SQLITE_OPEN_URI|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE; | |
| 19319 sqlite3 *db = 0; /* New database handle */ | |
| 19320 int ii; /* For iterating through aFunc[] */ | |
| 19321 | |
| 19322 assert( p->dbOut==0 ); | |
| 19323 | |
| 19324 if( sqlite3_open_v2(p->zUri, &db, flags, 0) ){ | |
| 19325 recoverDbError(p, db); | |
| 19326 } | |
| 19327 | |
| 19328 /* Register the sqlite_dbdata and sqlite_dbptr virtual table modules. | |
| 19329 ** These two are registered with the output database handle - this | |
| 19330 ** module depends on the input handle supporting the sqlite_dbpage | |
| 19331 ** virtual table only. */ | |
| 19332 if( p->errCode==SQLITE_OK ){ | |
| 19333 p->errCode = sqlite3_dbdata_init(db, 0, 0); | |
| 19334 } | |
| 19335 | |
| 19336 /* Register the custom user-functions with the output handle. */ | |
| 19337 for(ii=0; | |
| 19338 p->errCode==SQLITE_OK && ii<(int)(sizeof(aFunc)/sizeof(aFunc[0])); | |
| 19339 ii++){ | |
| 19340 p->errCode = sqlite3_create_function(db, aFunc[ii].zName, | |
| 19341 aFunc[ii].nArg, SQLITE_UTF8, (void*)p, aFunc[ii].xFunc, 0, 0 | |
| 19342 ); | |
| 19343 } | |
| 19344 | |
| 19345 p->dbOut = db; | |
| 19346 return p->errCode; | |
| 19347 } | |
| 19348 | |
| 19349 /* | |
| 19350 ** Attach the auxiliary database 'recovery' to the output database handle. | |
| 19351 ** This temporary database is used during the recovery process and then | |
| 19352 ** discarded. | |
| 19353 */ | |
| 19354 static void recoverOpenRecovery(sqlite3_recover *p){ | |
| 19355 char *zSql = recoverMPrintf(p, "ATTACH %Q AS recovery;", p->zStateDb); | |
| 19356 recoverExec(p, p->dbOut, zSql); | |
| 19357 recoverExec(p, p->dbOut, | |
| 19358 "PRAGMA writable_schema = 1;" | |
| 19359 "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, parent INT);" | |
| 19360 "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);" | |
| 19361 ); | |
| 19362 sqlite3_free(zSql); | |
| 19363 } | |
| 19364 | |
| 19365 | |
| 19366 /* | |
| 19367 ** This function is a no-op if recover handle p already contains an error | |
| 19368 ** (if p->errCode!=SQLITE_OK). | |
| 19369 ** | |
| 19370 ** Otherwise, argument zName must be the name of a table that has just been | |
| 19371 ** created in the output database. This function queries the output db | |
| 19372 ** for the schema of said table, and creates a RecoverTable object to | |
| 19373 ** store the schema in memory. The new RecoverTable object is linked into | |
| 19374 ** the list at sqlite3_recover.pTblList. | |
| 19375 ** | |
| 19376 ** Parameter iRoot must be the root page of table zName in the INPUT | |
| 19377 ** database. | |
| 19378 */ | |
| 19379 static void recoverAddTable( | |
| 19380 sqlite3_recover *p, | |
| 19381 const char *zName, /* Name of table created in output db */ | |
| 19382 i64 iRoot /* Root page of same table in INPUT db */ | |
| 19383 ){ | |
| 19384 sqlite3_stmt *pStmt = recoverPreparePrintf(p, p->dbOut, | |
| 19385 "PRAGMA table_xinfo(%Q)", zName | |
| 19386 ); | |
| 19387 | |
| 19388 if( pStmt ){ | |
| 19389 int iPk = -1; | |
| 19390 int iBind = 1; | |
| 19391 RecoverTable *pNew = 0; | |
| 19392 int nCol = 0; | |
| 19393 int nName = recoverStrlen(zName); | |
| 19394 int nByte = 0; | |
| 19395 while( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 19396 nCol++; | |
| 19397 nByte += (sqlite3_column_bytes(pStmt, 1)+1); | |
| 19398 } | |
| 19399 nByte += sizeof(RecoverTable) + nCol*sizeof(RecoverColumn) + nName+1; | |
| 19400 recoverReset(p, pStmt); | |
| 19401 | |
| 19402 pNew = recoverMalloc(p, nByte); | |
| 19403 if( pNew ){ | |
| 19404 int i = 0; | |
| 19405 int iField = 0; | |
| 19406 char *csr = 0; | |
| 19407 pNew->aCol = (RecoverColumn*)&pNew[1]; | |
| 19408 pNew->zTab = csr = (char*)&pNew->aCol[nCol]; | |
| 19409 pNew->nCol = nCol; | |
| 19410 pNew->iRoot = iRoot; | |
| 19411 memcpy(csr, zName, nName); | |
| 19412 csr += nName+1; | |
| 19413 | |
| 19414 for(i=0; sqlite3_step(pStmt)==SQLITE_ROW; i++){ | |
| 19415 int iPKF = sqlite3_column_int(pStmt, 5); | |
| 19416 int n = sqlite3_column_bytes(pStmt, 1); | |
| 19417 const char *z = (const char*)sqlite3_column_text(pStmt, 1); | |
| 19418 const char *zType = (const char*)sqlite3_column_text(pStmt, 2); | |
| 19419 int eHidden = sqlite3_column_int(pStmt, 6); | |
| 19420 | |
| 19421 if( iPk==-1 && iPKF==1 && !sqlite3_stricmp("integer", zType) ) iPk = i; | |
| 19422 if( iPKF>1 ) iPk = -2; | |
| 19423 pNew->aCol[i].zCol = csr; | |
| 19424 pNew->aCol[i].eHidden = eHidden; | |
| 19425 if( eHidden==RECOVER_EHIDDEN_VIRTUAL ){ | |
| 19426 pNew->aCol[i].iField = -1; | |
| 19427 }else{ | |
| 19428 pNew->aCol[i].iField = iField++; | |
| 19429 } | |
| 19430 if( eHidden!=RECOVER_EHIDDEN_VIRTUAL | |
| 19431 && eHidden!=RECOVER_EHIDDEN_STORED | |
| 19432 ){ | |
| 19433 pNew->aCol[i].iBind = iBind++; | |
| 19434 } | |
| 19435 memcpy(csr, z, n); | |
| 19436 csr += (n+1); | |
| 19437 } | |
| 19438 | |
| 19439 pNew->pNext = p->pTblList; | |
| 19440 p->pTblList = pNew; | |
| 19441 pNew->bIntkey = 1; | |
| 19442 } | |
| 19443 | |
| 19444 recoverFinalize(p, pStmt); | |
| 19445 | |
| 19446 pStmt = recoverPreparePrintf(p, p->dbOut, "PRAGMA index_xinfo(%Q)", zName); | |
| 19447 while( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 19448 int iField = sqlite3_column_int(pStmt, 0); | |
| 19449 int iCol = sqlite3_column_int(pStmt, 1); | |
| 19450 | |
| 19451 assert( iCol<pNew->nCol ); | |
| 19452 pNew->aCol[iCol].iField = iField; | |
| 19453 | |
| 19454 pNew->bIntkey = 0; | |
| 19455 iPk = -2; | |
| 19456 } | |
| 19457 recoverFinalize(p, pStmt); | |
| 19458 | |
| 19459 if( p->errCode==SQLITE_OK ){ | |
| 19460 if( iPk>=0 ){ | |
| 19461 pNew->aCol[iPk].bIPK = 1; | |
| 19462 }else if( pNew->bIntkey ){ | |
| 19463 pNew->iRowidBind = iBind++; | |
| 19464 } | |
| 19465 } | |
| 19466 } | |
| 19467 } | |
| 19468 | |
| 19469 /* | |
| 19470 ** This function is called after recoverCacheSchema() has cached those parts | |
| 19471 ** of the input database schema that could be recovered in temporary table | |
| 19472 ** "recovery.schema". This function creates in the output database copies | |
| 19473 ** of all parts of that schema that must be created before the tables can | |
| 19474 ** be populated. Specifically, this means: | |
| 19475 ** | |
| 19476 ** * all tables that are not VIRTUAL, and | |
| 19477 ** * UNIQUE indexes. | |
| 19478 ** | |
| 19479 ** If the recovery handle uses SQL callbacks, then callbacks containing | |
| 19480 ** the associated "CREATE TABLE" and "CREATE INDEX" statements are made. | |
| 19481 ** | |
| 19482 ** Additionally, records are added to the sqlite_schema table of the | |
| 19483 ** output database for any VIRTUAL tables. The CREATE VIRTUAL TABLE | |
| 19484 ** records are written directly to sqlite_schema, not actually executed. | |
| 19485 ** If the handle is in SQL callback mode, then callbacks are invoked | |
| 19486 ** with equivalent SQL statements. | |
| 19487 */ | |
| 19488 static int recoverWriteSchema1(sqlite3_recover *p){ | |
| 19489 sqlite3_stmt *pSelect = 0; | |
| 19490 sqlite3_stmt *pTblname = 0; | |
| 19491 | |
| 19492 pSelect = recoverPrepare(p, p->dbOut, | |
| 19493 "WITH dbschema(rootpage, name, sql, tbl, isVirtual, isIndex) AS (" | |
| 19494 " SELECT rootpage, name, sql, " | |
| 19495 " type='table', " | |
| 19496 " sql LIKE 'create virtual%'," | |
| 19497 " (type='index' AND (sql LIKE '%unique%' OR ?1))" | |
| 19498 " FROM recovery.schema" | |
| 19499 ")" | |
| 19500 "SELECT rootpage, tbl, isVirtual, name, sql" | |
| 19501 " FROM dbschema " | |
| 19502 " WHERE tbl OR isIndex" | |
| 19503 " ORDER BY tbl DESC, name=='sqlite_sequence' DESC" | |
| 19504 ); | |
| 19505 | |
| 19506 pTblname = recoverPrepare(p, p->dbOut, | |
| 19507 "SELECT name FROM sqlite_schema " | |
| 19508 "WHERE type='table' ORDER BY rowid DESC LIMIT 1" | |
| 19509 ); | |
| 19510 | |
| 19511 if( pSelect ){ | |
| 19512 sqlite3_bind_int(pSelect, 1, p->bSlowIndexes); | |
| 19513 while( sqlite3_step(pSelect)==SQLITE_ROW ){ | |
| 19514 i64 iRoot = sqlite3_column_int64(pSelect, 0); | |
| 19515 int bTable = sqlite3_column_int(pSelect, 1); | |
| 19516 int bVirtual = sqlite3_column_int(pSelect, 2); | |
| 19517 const char *zName = (const char*)sqlite3_column_text(pSelect, 3); | |
| 19518 const char *zSql = (const char*)sqlite3_column_text(pSelect, 4); | |
| 19519 char *zFree = 0; | |
| 19520 int rc = SQLITE_OK; | |
| 19521 | |
| 19522 if( bVirtual ){ | |
| 19523 zSql = (const char*)(zFree = recoverMPrintf(p, | |
| 19524 "INSERT INTO sqlite_schema VALUES('table', %Q, %Q, 0, %Q)", | |
| 19525 zName, zName, zSql | |
| 19526 )); | |
| 19527 } | |
| 19528 rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0); | |
| 19529 if( rc==SQLITE_OK ){ | |
| 19530 recoverSqlCallback(p, zSql); | |
| 19531 if( bTable && !bVirtual ){ | |
| 19532 if( SQLITE_ROW==sqlite3_step(pTblname) ){ | |
| 19533 const char *zTbl = (const char*)sqlite3_column_text(pTblname, 0); | |
| 19534 if( zTbl ) recoverAddTable(p, zTbl, iRoot); | |
| 19535 } | |
| 19536 recoverReset(p, pTblname); | |
| 19537 } | |
| 19538 }else if( rc!=SQLITE_ERROR ){ | |
| 19539 recoverDbError(p, p->dbOut); | |
| 19540 } | |
| 19541 sqlite3_free(zFree); | |
| 19542 } | |
| 19543 } | |
| 19544 recoverFinalize(p, pSelect); | |
| 19545 recoverFinalize(p, pTblname); | |
| 19546 | |
| 19547 return p->errCode; | |
| 19548 } | |
| 19549 | |
| 19550 /* | |
| 19551 ** This function is called after the output database has been populated. It | |
| 19552 ** adds all recovered schema elements that were not created in the output | |
| 19553 ** database by recoverWriteSchema1() - everything except for tables and | |
| 19554 ** UNIQUE indexes. Specifically: | |
| 19555 ** | |
| 19556 ** * views, | |
| 19557 ** * triggers, | |
| 19558 ** * non-UNIQUE indexes. | |
| 19559 ** | |
| 19560 ** If the recover handle is in SQL callback mode, then equivalent callbacks | |
| 19561 ** are issued to create the schema elements. | |
| 19562 */ | |
| 19563 static int recoverWriteSchema2(sqlite3_recover *p){ | |
| 19564 sqlite3_stmt *pSelect = 0; | |
| 19565 | |
| 19566 pSelect = recoverPrepare(p, p->dbOut, | |
| 19567 p->bSlowIndexes ? | |
| 19568 "SELECT rootpage, sql FROM recovery.schema " | |
| 19569 " WHERE type!='table' AND type!='index'" | |
| 19570 : | |
| 19571 "SELECT rootpage, sql FROM recovery.schema " | |
| 19572 " WHERE type!='table' AND (type!='index' OR sql NOT LIKE '%unique%')" | |
| 19573 ); | |
| 19574 | |
| 19575 if( pSelect ){ | |
| 19576 while( sqlite3_step(pSelect)==SQLITE_ROW ){ | |
| 19577 const char *zSql = (const char*)sqlite3_column_text(pSelect, 1); | |
| 19578 int rc = sqlite3_exec(p->dbOut, zSql, 0, 0, 0); | |
| 19579 if( rc==SQLITE_OK ){ | |
| 19580 recoverSqlCallback(p, zSql); | |
| 19581 }else if( rc!=SQLITE_ERROR ){ | |
| 19582 recoverDbError(p, p->dbOut); | |
| 19583 } | |
| 19584 } | |
| 19585 } | |
| 19586 recoverFinalize(p, pSelect); | |
| 19587 | |
| 19588 return p->errCode; | |
| 19589 } | |
| 19590 | |
| 19591 /* | |
| 19592 ** This function is a no-op if recover handle p already contains an error | |
| 19593 ** (if p->errCode!=SQLITE_OK). In this case it returns NULL. | |
| 19594 ** | |
| 19595 ** Otherwise, if the recover handle is configured to create an output | |
| 19596 ** database (was created by sqlite3_recover_init()), then this function | |
| 19597 ** prepares and returns an SQL statement to INSERT a new record into table | |
| 19598 ** pTab, assuming the first nField fields of a record extracted from disk | |
| 19599 ** are valid. | |
| 19600 ** | |
| 19601 ** For example, if table pTab is: | |
| 19602 ** | |
| 19603 ** CREATE TABLE name(a, b GENERATED ALWAYS AS (a+1) STORED, c, d, e); | |
| 19604 ** | |
| 19605 ** And nField is 4, then the SQL statement prepared and returned is: | |
| 19606 ** | |
| 19607 ** INSERT INTO (a, c, d) VALUES (?1, ?2, ?3); | |
| 19608 ** | |
| 19609 ** In this case even though 4 values were extracted from the input db, | |
| 19610 ** only 3 are written to the output, as the generated STORED column | |
| 19611 ** cannot be written. | |
| 19612 ** | |
| 19613 ** If the recover handle is in SQL callback mode, then the SQL statement | |
| 19614 ** prepared is such that evaluating it returns a single row containing | |
| 19615 ** a single text value - itself an SQL statement similar to the above, | |
| 19616 ** except with SQL literals in place of the variables. For example: | |
| 19617 ** | |
| 19618 ** SELECT 'INSERT INTO (a, c, d) VALUES (' | |
| 19619 ** || quote(?1) || ', ' | |
| 19620 ** || quote(?2) || ', ' | |
| 19621 ** || quote(?3) || ')'; | |
| 19622 ** | |
| 19623 ** In either case, it is the responsibility of the caller to eventually | |
| 19624 ** free the statement handle using sqlite3_finalize(). | |
| 19625 */ | |
| 19626 static sqlite3_stmt *recoverInsertStmt( | |
| 19627 sqlite3_recover *p, | |
| 19628 RecoverTable *pTab, | |
| 19629 int nField | |
| 19630 ){ | |
| 19631 sqlite3_stmt *pRet = 0; | |
| 19632 const char *zSep = ""; | |
| 19633 const char *zSqlSep = ""; | |
| 19634 char *zSql = 0; | |
| 19635 char *zFinal = 0; | |
| 19636 char *zBind = 0; | |
| 19637 int ii; | |
| 19638 int bSql = p->xSql ? 1 : 0; | |
| 19639 | |
| 19640 if( nField<=0 ) return 0; | |
| 19641 | |
| 19642 assert( nField<=pTab->nCol ); | |
| 19643 | |
| 19644 zSql = recoverMPrintf(p, "INSERT OR IGNORE INTO %Q(", pTab->zTab); | |
| 19645 | |
| 19646 if( pTab->iRowidBind ){ | |
| 19647 assert( pTab->bIntkey ); | |
| 19648 zSql = recoverMPrintf(p, "%z_rowid_", zSql); | |
| 19649 if( bSql ){ | |
| 19650 zBind = recoverMPrintf(p, "%zquote(?%d)", zBind, pTab->iRowidBind); | |
| 19651 }else{ | |
| 19652 zBind = recoverMPrintf(p, "%z?%d", zBind, pTab->iRowidBind); | |
| 19653 } | |
| 19654 zSqlSep = "||', '||"; | |
| 19655 zSep = ", "; | |
| 19656 } | |
| 19657 | |
| 19658 for(ii=0; ii<nField; ii++){ | |
| 19659 int eHidden = pTab->aCol[ii].eHidden; | |
| 19660 if( eHidden!=RECOVER_EHIDDEN_VIRTUAL | |
| 19661 && eHidden!=RECOVER_EHIDDEN_STORED | |
| 19662 ){ | |
| 19663 assert( pTab->aCol[ii].iField>=0 && pTab->aCol[ii].iBind>=1 ); | |
| 19664 zSql = recoverMPrintf(p, "%z%s%Q", zSql, zSep, pTab->aCol[ii].zCol); | |
| 19665 | |
| 19666 if( bSql ){ | |
| 19667 zBind = recoverMPrintf(p, | |
| 19668 "%z%sescape_crlf(quote(?%d))", zBind, zSqlSep, pTab->aCol[ii].iBind | |
| 19669 ); | |
| 19670 zSqlSep = "||', '||"; | |
| 19671 }else{ | |
| 19672 zBind = recoverMPrintf(p, "%z%s?%d", zBind, zSep, pTab->aCol[ii].iBind); | |
| 19673 } | |
| 19674 zSep = ", "; | |
| 19675 } | |
| 19676 } | |
| 19677 | |
| 19678 if( bSql ){ | |
| 19679 zFinal = recoverMPrintf(p, "SELECT %Q || ') VALUES (' || %s || ')'", | |
| 19680 zSql, zBind | |
| 19681 ); | |
| 19682 }else{ | |
| 19683 zFinal = recoverMPrintf(p, "%s) VALUES (%s)", zSql, zBind); | |
| 19684 } | |
| 19685 | |
| 19686 pRet = recoverPrepare(p, p->dbOut, zFinal); | |
| 19687 sqlite3_free(zSql); | |
| 19688 sqlite3_free(zBind); | |
| 19689 sqlite3_free(zFinal); | |
| 19690 | |
| 19691 return pRet; | |
| 19692 } | |
| 19693 | |
| 19694 | |
| 19695 /* | |
| 19696 ** Search the list of RecoverTable objects at p->pTblList for one that | |
| 19697 ** has root page iRoot in the input database. If such an object is found, | |
| 19698 ** return a pointer to it. Otherwise, return NULL. | |
| 19699 */ | |
| 19700 static RecoverTable *recoverFindTable(sqlite3_recover *p, u32 iRoot){ | |
| 19701 RecoverTable *pRet = 0; | |
| 19702 for(pRet=p->pTblList; pRet && pRet->iRoot!=iRoot; pRet=pRet->pNext); | |
| 19703 return pRet; | |
| 19704 } | |
| 19705 | |
| 19706 /* | |
| 19707 ** This function attempts to create a lost and found table within the | |
| 19708 ** output db. If successful, it returns a pointer to a buffer containing | |
| 19709 ** the name of the new table. It is the responsibility of the caller to | |
| 19710 ** eventually free this buffer using sqlite3_free(). | |
| 19711 ** | |
| 19712 ** If an error occurs, NULL is returned and an error code and error | |
| 19713 ** message left in the recover handle. | |
| 19714 */ | |
| 19715 static char *recoverLostAndFoundCreate( | |
| 19716 sqlite3_recover *p, /* Recover object */ | |
| 19717 int nField /* Number of column fields in new table */ | |
| 19718 ){ | |
| 19719 char *zTbl = 0; | |
| 19720 sqlite3_stmt *pProbe = 0; | |
| 19721 int ii = 0; | |
| 19722 | |
| 19723 pProbe = recoverPrepare(p, p->dbOut, | |
| 19724 "SELECT 1 FROM sqlite_schema WHERE name=?" | |
| 19725 ); | |
| 19726 for(ii=-1; zTbl==0 && p->errCode==SQLITE_OK && ii<1000; ii++){ | |
| 19727 int bFail = 0; | |
| 19728 if( ii<0 ){ | |
| 19729 zTbl = recoverMPrintf(p, "%s", p->zLostAndFound); | |
| 19730 }else{ | |
| 19731 zTbl = recoverMPrintf(p, "%s_%d", p->zLostAndFound, ii); | |
| 19732 } | |
| 19733 | |
| 19734 if( p->errCode==SQLITE_OK ){ | |
| 19735 sqlite3_bind_text(pProbe, 1, zTbl, -1, SQLITE_STATIC); | |
| 19736 if( SQLITE_ROW==sqlite3_step(pProbe) ){ | |
| 19737 bFail = 1; | |
| 19738 } | |
| 19739 recoverReset(p, pProbe); | |
| 19740 } | |
| 19741 | |
| 19742 if( bFail ){ | |
| 19743 sqlite3_clear_bindings(pProbe); | |
| 19744 sqlite3_free(zTbl); | |
| 19745 zTbl = 0; | |
| 19746 } | |
| 19747 } | |
| 19748 recoverFinalize(p, pProbe); | |
| 19749 | |
| 19750 if( zTbl ){ | |
| 19751 const char *zSep = 0; | |
| 19752 char *zField = 0; | |
| 19753 char *zSql = 0; | |
| 19754 | |
| 19755 zSep = "rootpgno INTEGER, pgno INTEGER, nfield INTEGER, id INTEGER, "; | |
| 19756 for(ii=0; p->errCode==SQLITE_OK && ii<nField; ii++){ | |
| 19757 zField = recoverMPrintf(p, "%z%sc%d", zField, zSep, ii); | |
| 19758 zSep = ", "; | |
| 19759 } | |
| 19760 | |
| 19761 zSql = recoverMPrintf(p, "CREATE TABLE %s(%s)", zTbl, zField); | |
| 19762 sqlite3_free(zField); | |
| 19763 | |
| 19764 recoverExec(p, p->dbOut, zSql); | |
| 19765 recoverSqlCallback(p, zSql); | |
| 19766 sqlite3_free(zSql); | |
| 19767 }else if( p->errCode==SQLITE_OK ){ | |
| 19768 recoverError( | |
| 19769 p, SQLITE_ERROR, "failed to create %s output table", p->zLostAndFound | |
| 19770 ); | |
| 19771 } | |
| 19772 | |
| 19773 return zTbl; | |
| 19774 } | |
| 19775 | |
| 19776 /* | |
| 19777 ** Synthesize and prepare an INSERT statement to write to the lost_and_found | |
| 19778 ** table in the output database. The name of the table is zTab, and it has | |
| 19779 ** nField c* fields. | |
| 19780 */ | |
| 19781 static sqlite3_stmt *recoverLostAndFoundInsert( | |
| 19782 sqlite3_recover *p, | |
| 19783 const char *zTab, | |
| 19784 int nField | |
| 19785 ){ | |
| 19786 int nTotal = nField + 4; | |
| 19787 int ii; | |
| 19788 char *zBind = 0; | |
| 19789 sqlite3_stmt *pRet = 0; | |
| 19790 | |
| 19791 if( p->xSql==0 ){ | |
| 19792 for(ii=0; ii<nTotal; ii++){ | |
| 19793 zBind = recoverMPrintf(p, "%z%s?", zBind, zBind?", ":"", ii); | |
| 19794 } | |
| 19795 pRet = recoverPreparePrintf( | |
| 19796 p, p->dbOut, "INSERT INTO %s VALUES(%s)", zTab, zBind | |
| 19797 ); | |
| 19798 }else{ | |
| 19799 const char *zSep = ""; | |
| 19800 for(ii=0; ii<nTotal; ii++){ | |
| 19801 zBind = recoverMPrintf(p, "%z%squote(?)", zBind, zSep); | |
| 19802 zSep = "|| ', ' ||"; | |
| 19803 } | |
| 19804 pRet = recoverPreparePrintf( | |
| 19805 p, p->dbOut, "SELECT 'INSERT INTO %s VALUES(' || %s || ')'", zTab, zBind | |
| 19806 ); | |
| 19807 } | |
| 19808 | |
| 19809 sqlite3_free(zBind); | |
| 19810 return pRet; | |
| 19811 } | |
| 19812 | |
| 19813 /* | |
| 19814 ** Input database page iPg contains data that will be written to the | |
| 19815 ** lost-and-found table of the output database. This function attempts | |
| 19816 ** to identify the root page of the tree that page iPg belonged to. | |
| 19817 ** If successful, it sets output variable (*piRoot) to the page number | |
| 19818 ** of the root page and returns SQLITE_OK. Otherwise, if an error occurs, | |
| 19819 ** an SQLite error code is returned and the final value of *piRoot | |
| 19820 ** undefined. | |
| 19821 */ | |
| 19822 static int recoverLostAndFoundFindRoot( | |
| 19823 sqlite3_recover *p, | |
| 19824 i64 iPg, | |
| 19825 i64 *piRoot | |
| 19826 ){ | |
| 19827 RecoverStateLAF *pLaf = &p->laf; | |
| 19828 | |
| 19829 if( pLaf->pFindRoot==0 ){ | |
| 19830 pLaf->pFindRoot = recoverPrepare(p, p->dbOut, | |
| 19831 "WITH RECURSIVE p(pgno) AS (" | |
| 19832 " SELECT ?" | |
| 19833 " UNION" | |
| 19834 " SELECT parent FROM recovery.map AS m, p WHERE m.pgno=p.pgno" | |
| 19835 ") " | |
| 19836 "SELECT p.pgno FROM p, recovery.map m WHERE m.pgno=p.pgno " | |
| 19837 " AND m.parent IS NULL" | |
| 19838 ); | |
| 19839 } | |
| 19840 if( p->errCode==SQLITE_OK ){ | |
| 19841 sqlite3_bind_int64(pLaf->pFindRoot, 1, iPg); | |
| 19842 if( sqlite3_step(pLaf->pFindRoot)==SQLITE_ROW ){ | |
| 19843 *piRoot = sqlite3_column_int64(pLaf->pFindRoot, 0); | |
| 19844 }else{ | |
| 19845 *piRoot = iPg; | |
| 19846 } | |
| 19847 recoverReset(p, pLaf->pFindRoot); | |
| 19848 } | |
| 19849 return p->errCode; | |
| 19850 } | |
| 19851 | |
| 19852 /* | |
| 19853 ** Recover data from page iPage of the input database and write it to | |
| 19854 ** the lost-and-found table in the output database. | |
| 19855 */ | |
| 19856 static void recoverLostAndFoundOnePage(sqlite3_recover *p, i64 iPage){ | |
| 19857 RecoverStateLAF *pLaf = &p->laf; | |
| 19858 sqlite3_value **apVal = pLaf->apVal; | |
| 19859 sqlite3_stmt *pPageData = pLaf->pPageData; | |
| 19860 sqlite3_stmt *pInsert = pLaf->pInsert; | |
| 19861 | |
| 19862 int nVal = -1; | |
| 19863 int iPrevCell = 0; | |
| 19864 i64 iRoot = 0; | |
| 19865 int bHaveRowid = 0; | |
| 19866 i64 iRowid = 0; | |
| 19867 int ii = 0; | |
| 19868 | |
| 19869 if( recoverLostAndFoundFindRoot(p, iPage, &iRoot) ) return; | |
| 19870 sqlite3_bind_int64(pPageData, 1, iPage); | |
| 19871 while( p->errCode==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPageData) ){ | |
| 19872 int iCell = sqlite3_column_int64(pPageData, 0); | |
| 19873 int iField = sqlite3_column_int64(pPageData, 1); | |
| 19874 | |
| 19875 if( iPrevCell!=iCell && nVal>=0 ){ | |
| 19876 /* Insert the new row */ | |
| 19877 sqlite3_bind_int64(pInsert, 1, iRoot); /* rootpgno */ | |
| 19878 sqlite3_bind_int64(pInsert, 2, iPage); /* pgno */ | |
| 19879 sqlite3_bind_int(pInsert, 3, nVal); /* nfield */ | |
| 19880 if( bHaveRowid ){ | |
| 19881 sqlite3_bind_int64(pInsert, 4, iRowid); /* id */ | |
| 19882 } | |
| 19883 for(ii=0; ii<nVal; ii++){ | |
| 19884 recoverBindValue(p, pInsert, 5+ii, apVal[ii]); | |
| 19885 } | |
| 19886 if( sqlite3_step(pInsert)==SQLITE_ROW ){ | |
| 19887 recoverSqlCallback(p, (const char*)sqlite3_column_text(pInsert, 0)); | |
| 19888 } | |
| 19889 recoverReset(p, pInsert); | |
| 19890 | |
| 19891 /* Discard the accumulated row data */ | |
| 19892 for(ii=0; ii<nVal; ii++){ | |
| 19893 sqlite3_value_free(apVal[ii]); | |
| 19894 apVal[ii] = 0; | |
| 19895 } | |
| 19896 sqlite3_clear_bindings(pInsert); | |
| 19897 bHaveRowid = 0; | |
| 19898 nVal = -1; | |
| 19899 } | |
| 19900 | |
| 19901 if( iCell<0 ) break; | |
| 19902 | |
| 19903 if( iField<0 ){ | |
| 19904 assert( nVal==-1 ); | |
| 19905 iRowid = sqlite3_column_int64(pPageData, 2); | |
| 19906 bHaveRowid = 1; | |
| 19907 nVal = 0; | |
| 19908 }else if( iField<pLaf->nMaxField ){ | |
| 19909 sqlite3_value *pVal = sqlite3_column_value(pPageData, 2); | |
| 19910 apVal[iField] = sqlite3_value_dup(pVal); | |
| 19911 assert( iField==nVal || (nVal==-1 && iField==0) ); | |
| 19912 nVal = iField+1; | |
| 19913 if( apVal[iField]==0 ){ | |
| 19914 recoverError(p, SQLITE_NOMEM, 0); | |
| 19915 } | |
| 19916 } | |
| 19917 | |
| 19918 iPrevCell = iCell; | |
| 19919 } | |
| 19920 recoverReset(p, pPageData); | |
| 19921 | |
| 19922 for(ii=0; ii<nVal; ii++){ | |
| 19923 sqlite3_value_free(apVal[ii]); | |
| 19924 apVal[ii] = 0; | |
| 19925 } | |
| 19926 } | |
| 19927 | |
| 19928 /* | |
| 19929 ** Perform one step (sqlite3_recover_step()) of work for the connection | |
| 19930 ** passed as the only argument, which is guaranteed to be in | |
| 19931 ** RECOVER_STATE_LOSTANDFOUND3 state - during which the lost-and-found | |
| 19932 ** table of the output database is populated with recovered data that can | |
| 19933 ** not be assigned to any recovered schema object. | |
| 19934 */ | |
| 19935 static int recoverLostAndFound3Step(sqlite3_recover *p){ | |
| 19936 RecoverStateLAF *pLaf = &p->laf; | |
| 19937 if( p->errCode==SQLITE_OK ){ | |
| 19938 if( pLaf->pInsert==0 ){ | |
| 19939 return SQLITE_DONE; | |
| 19940 }else{ | |
| 19941 if( p->errCode==SQLITE_OK ){ | |
| 19942 int res = sqlite3_step(pLaf->pAllPage); | |
| 19943 if( res==SQLITE_ROW ){ | |
| 19944 i64 iPage = sqlite3_column_int64(pLaf->pAllPage, 0); | |
| 19945 if( recoverBitmapQuery(pLaf->pUsed, iPage)==0 ){ | |
| 19946 recoverLostAndFoundOnePage(p, iPage); | |
| 19947 } | |
| 19948 }else{ | |
| 19949 recoverReset(p, pLaf->pAllPage); | |
| 19950 return SQLITE_DONE; | |
| 19951 } | |
| 19952 } | |
| 19953 } | |
| 19954 } | |
| 19955 return SQLITE_OK; | |
| 19956 } | |
| 19957 | |
| 19958 /* | |
| 19959 ** Initialize resources required in RECOVER_STATE_LOSTANDFOUND3 | |
| 19960 ** state - during which the lost-and-found table of the output database | |
| 19961 ** is populated with recovered data that can not be assigned to any | |
| 19962 ** recovered schema object. | |
| 19963 */ | |
| 19964 static void recoverLostAndFound3Init(sqlite3_recover *p){ | |
| 19965 RecoverStateLAF *pLaf = &p->laf; | |
| 19966 | |
| 19967 if( pLaf->nMaxField>0 ){ | |
| 19968 char *zTab = 0; /* Name of lost_and_found table */ | |
| 19969 | |
| 19970 zTab = recoverLostAndFoundCreate(p, pLaf->nMaxField); | |
| 19971 pLaf->pInsert = recoverLostAndFoundInsert(p, zTab, pLaf->nMaxField); | |
| 19972 sqlite3_free(zTab); | |
| 19973 | |
| 19974 pLaf->pAllPage = recoverPreparePrintf(p, p->dbOut, | |
| 19975 "WITH RECURSIVE seq(ii) AS (" | |
| 19976 " SELECT 1 UNION ALL SELECT ii+1 FROM seq WHERE ii<%lld" | |
| 19977 ")" | |
| 19978 "SELECT ii FROM seq" , p->laf.nPg | |
| 19979 ); | |
| 19980 pLaf->pPageData = recoverPrepare(p, p->dbOut, | |
| 19981 "SELECT cell, field, value " | |
| 19982 "FROM sqlite_dbdata('getpage()') d WHERE d.pgno=? " | |
| 19983 "UNION ALL " | |
| 19984 "SELECT -1, -1, -1" | |
| 19985 ); | |
| 19986 | |
| 19987 pLaf->apVal = (sqlite3_value**)recoverMalloc(p, | |
| 19988 pLaf->nMaxField*sizeof(sqlite3_value*) | |
| 19989 ); | |
| 19990 } | |
| 19991 } | |
| 19992 | |
| 19993 /* | |
| 19994 ** Initialize resources required in RECOVER_STATE_WRITING state - during which | |
| 19995 ** tables recovered from the schema of the input database are populated with | |
| 19996 ** recovered data. | |
| 19997 */ | |
| 19998 static int recoverWriteDataInit(sqlite3_recover *p){ | |
| 19999 RecoverStateW1 *p1 = &p->w1; | |
| 20000 RecoverTable *pTbl = 0; | |
| 20001 int nByte = 0; | |
| 20002 | |
| 20003 /* Figure out the maximum number of columns for any table in the schema */ | |
| 20004 assert( p1->nMax==0 ); | |
| 20005 for(pTbl=p->pTblList; pTbl; pTbl=pTbl->pNext){ | |
| 20006 if( pTbl->nCol>p1->nMax ) p1->nMax = pTbl->nCol; | |
| 20007 } | |
| 20008 | |
| 20009 /* Allocate an array of (sqlite3_value*) in which to accumulate the values | |
| 20010 ** that will be written to the output database in a single row. */ | |
| 20011 nByte = sizeof(sqlite3_value*) * (p1->nMax+1); | |
| 20012 p1->apVal = (sqlite3_value**)recoverMalloc(p, nByte); | |
| 20013 if( p1->apVal==0 ) return p->errCode; | |
| 20014 | |
| 20015 /* Prepare the SELECT to loop through schema tables (pTbls) and the SELECT | |
| 20016 ** to loop through cells that appear to belong to a single table (pSel). */ | |
| 20017 p1->pTbls = recoverPrepare(p, p->dbOut, | |
| 20018 "SELECT rootpage FROM recovery.schema " | |
| 20019 " WHERE type='table' AND (sql NOT LIKE 'create virtual%')" | |
| 20020 " ORDER BY (tbl_name='sqlite_sequence') ASC" | |
| 20021 ); | |
| 20022 p1->pSel = recoverPrepare(p, p->dbOut, | |
| 20023 "WITH RECURSIVE pages(page) AS (" | |
| 20024 " SELECT ?1" | |
| 20025 " UNION" | |
| 20026 " SELECT child FROM sqlite_dbptr('getpage()'), pages " | |
| 20027 " WHERE pgno=page" | |
| 20028 ") " | |
| 20029 "SELECT page, cell, field, value " | |
| 20030 "FROM sqlite_dbdata('getpage()') d, pages p WHERE p.page=d.pgno " | |
| 20031 "UNION ALL " | |
| 20032 "SELECT 0, 0, 0, 0" | |
| 20033 ); | |
| 20034 | |
| 20035 return p->errCode; | |
| 20036 } | |
| 20037 | |
| 20038 /* | |
| 20039 ** Clean up resources allocated by recoverWriteDataInit() (stuff in | |
| 20040 ** sqlite3_recover.w1). | |
| 20041 */ | |
| 20042 static void recoverWriteDataCleanup(sqlite3_recover *p){ | |
| 20043 RecoverStateW1 *p1 = &p->w1; | |
| 20044 int ii; | |
| 20045 for(ii=0; ii<p1->nVal; ii++){ | |
| 20046 sqlite3_value_free(p1->apVal[ii]); | |
| 20047 } | |
| 20048 sqlite3_free(p1->apVal); | |
| 20049 recoverFinalize(p, p1->pInsert); | |
| 20050 recoverFinalize(p, p1->pTbls); | |
| 20051 recoverFinalize(p, p1->pSel); | |
| 20052 memset(p1, 0, sizeof(*p1)); | |
| 20053 } | |
| 20054 | |
| 20055 /* | |
| 20056 ** Perform one step (sqlite3_recover_step()) of work for the connection | |
| 20057 ** passed as the only argument, which is guaranteed to be in | |
| 20058 ** RECOVER_STATE_WRITING state - during which tables recovered from the | |
| 20059 ** schema of the input database are populated with recovered data. | |
| 20060 */ | |
| 20061 static int recoverWriteDataStep(sqlite3_recover *p){ | |
| 20062 RecoverStateW1 *p1 = &p->w1; | |
| 20063 sqlite3_stmt *pSel = p1->pSel; | |
| 20064 sqlite3_value **apVal = p1->apVal; | |
| 20065 | |
| 20066 if( p->errCode==SQLITE_OK && p1->pTab==0 ){ | |
| 20067 if( sqlite3_step(p1->pTbls)==SQLITE_ROW ){ | |
| 20068 i64 iRoot = sqlite3_column_int64(p1->pTbls, 0); | |
| 20069 p1->pTab = recoverFindTable(p, iRoot); | |
| 20070 | |
| 20071 recoverFinalize(p, p1->pInsert); | |
| 20072 p1->pInsert = 0; | |
| 20073 | |
| 20074 /* If this table is unknown, return early. The caller will invoke this | |
| 20075 ** function again and it will move on to the next table. */ | |
| 20076 if( p1->pTab==0 ) return p->errCode; | |
| 20077 | |
| 20078 /* If this is the sqlite_sequence table, delete any rows added by | |
| 20079 ** earlier INSERT statements on tables with AUTOINCREMENT primary | |
| 20080 ** keys before recovering its contents. The p1->pTbls SELECT statement | |
| 20081 ** is rigged to deliver "sqlite_sequence" last of all, so we don't | |
| 20082 ** worry about it being modified after it is recovered. */ | |
| 20083 if( sqlite3_stricmp("sqlite_sequence", p1->pTab->zTab)==0 ){ | |
| 20084 recoverExec(p, p->dbOut, "DELETE FROM sqlite_sequence"); | |
| 20085 recoverSqlCallback(p, "DELETE FROM sqlite_sequence"); | |
| 20086 } | |
| 20087 | |
| 20088 /* Bind the root page of this table within the original database to | |
| 20089 ** SELECT statement p1->pSel. The SELECT statement will then iterate | |
| 20090 ** through cells that look like they belong to table pTab. */ | |
| 20091 sqlite3_bind_int64(pSel, 1, iRoot); | |
| 20092 | |
| 20093 p1->nVal = 0; | |
| 20094 p1->bHaveRowid = 0; | |
| 20095 p1->iPrevPage = -1; | |
| 20096 p1->iPrevCell = -1; | |
| 20097 }else{ | |
| 20098 return SQLITE_DONE; | |
| 20099 } | |
| 20100 } | |
| 20101 assert( p->errCode!=SQLITE_OK || p1->pTab ); | |
| 20102 | |
| 20103 if( p->errCode==SQLITE_OK && sqlite3_step(pSel)==SQLITE_ROW ){ | |
| 20104 RecoverTable *pTab = p1->pTab; | |
| 20105 | |
| 20106 i64 iPage = sqlite3_column_int64(pSel, 0); | |
| 20107 int iCell = sqlite3_column_int(pSel, 1); | |
| 20108 int iField = sqlite3_column_int(pSel, 2); | |
| 20109 sqlite3_value *pVal = sqlite3_column_value(pSel, 3); | |
| 20110 int bNewCell = (p1->iPrevPage!=iPage || p1->iPrevCell!=iCell); | |
| 20111 | |
| 20112 assert( bNewCell==0 || (iField==-1 || iField==0) ); | |
| 20113 assert( bNewCell || iField==p1->nVal || p1->nVal==pTab->nCol ); | |
| 20114 | |
| 20115 if( bNewCell ){ | |
| 20116 int ii = 0; | |
| 20117 if( p1->nVal>=0 ){ | |
| 20118 if( p1->pInsert==0 || p1->nVal!=p1->nInsert ){ | |
| 20119 recoverFinalize(p, p1->pInsert); | |
| 20120 p1->pInsert = recoverInsertStmt(p, pTab, p1->nVal); | |
| 20121 p1->nInsert = p1->nVal; | |
| 20122 } | |
| 20123 if( p1->nVal>0 ){ | |
| 20124 sqlite3_stmt *pInsert = p1->pInsert; | |
| 20125 for(ii=0; ii<pTab->nCol; ii++){ | |
| 20126 RecoverColumn *pCol = &pTab->aCol[ii]; | |
| 20127 int iBind = pCol->iBind; | |
| 20128 if( iBind>0 ){ | |
| 20129 if( pCol->bIPK ){ | |
| 20130 sqlite3_bind_int64(pInsert, iBind, p1->iRowid); | |
| 20131 }else if( pCol->iField<p1->nVal ){ | |
| 20132 recoverBindValue(p, pInsert, iBind, apVal[pCol->iField]); | |
| 20133 } | |
| 20134 } | |
| 20135 } | |
| 20136 if( p->bRecoverRowid && pTab->iRowidBind>0 && p1->bHaveRowid ){ | |
| 20137 sqlite3_bind_int64(pInsert, pTab->iRowidBind, p1->iRowid); | |
| 20138 } | |
| 20139 if( SQLITE_ROW==sqlite3_step(pInsert) ){ | |
| 20140 const char *z = (const char*)sqlite3_column_text(pInsert, 0); | |
| 20141 recoverSqlCallback(p, z); | |
| 20142 } | |
| 20143 recoverReset(p, pInsert); | |
| 20144 assert( p->errCode || pInsert ); | |
| 20145 if( pInsert ) sqlite3_clear_bindings(pInsert); | |
| 20146 } | |
| 20147 } | |
| 20148 | |
| 20149 for(ii=0; ii<p1->nVal; ii++){ | |
| 20150 sqlite3_value_free(apVal[ii]); | |
| 20151 apVal[ii] = 0; | |
| 20152 } | |
| 20153 p1->nVal = -1; | |
| 20154 p1->bHaveRowid = 0; | |
| 20155 } | |
| 20156 | |
| 20157 if( iPage!=0 ){ | |
| 20158 if( iField<0 ){ | |
| 20159 p1->iRowid = sqlite3_column_int64(pSel, 3); | |
| 20160 assert( p1->nVal==-1 ); | |
| 20161 p1->nVal = 0; | |
| 20162 p1->bHaveRowid = 1; | |
| 20163 }else if( iField<pTab->nCol ){ | |
| 20164 assert( apVal[iField]==0 ); | |
| 20165 apVal[iField] = sqlite3_value_dup( pVal ); | |
| 20166 if( apVal[iField]==0 ){ | |
| 20167 recoverError(p, SQLITE_NOMEM, 0); | |
| 20168 } | |
| 20169 p1->nVal = iField+1; | |
| 20170 }else if( pTab->nCol==0 ){ | |
| 20171 p1->nVal = pTab->nCol; | |
| 20172 } | |
| 20173 p1->iPrevCell = iCell; | |
| 20174 p1->iPrevPage = iPage; | |
| 20175 } | |
| 20176 }else{ | |
| 20177 recoverReset(p, pSel); | |
| 20178 p1->pTab = 0; | |
| 20179 } | |
| 20180 | |
| 20181 return p->errCode; | |
| 20182 } | |
| 20183 | |
| 20184 /* | |
| 20185 ** Initialize resources required by sqlite3_recover_step() in | |
| 20186 ** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not | |
| 20187 ** already allocated to a recovered schema element is determined. | |
| 20188 */ | |
| 20189 static void recoverLostAndFound1Init(sqlite3_recover *p){ | |
| 20190 RecoverStateLAF *pLaf = &p->laf; | |
| 20191 sqlite3_stmt *pStmt = 0; | |
| 20192 | |
| 20193 assert( p->laf.pUsed==0 ); | |
| 20194 pLaf->nPg = recoverPageCount(p); | |
| 20195 pLaf->pUsed = recoverBitmapAlloc(p, pLaf->nPg); | |
| 20196 | |
| 20197 /* Prepare a statement to iterate through all pages that are part of any tree | |
| 20198 ** in the recoverable part of the input database schema to the bitmap. And, | |
| 20199 ** if !p->bFreelistCorrupt, add all pages that appear to be part of the | |
| 20200 ** freelist. */ | |
| 20201 pStmt = recoverPrepare( | |
| 20202 p, p->dbOut, | |
| 20203 "WITH trunk(pgno) AS (" | |
| 20204 " SELECT read_i32(getpage(1), 8) AS x WHERE x>0" | |
| 20205 " UNION" | |
| 20206 " SELECT read_i32(getpage(trunk.pgno), 0) AS x FROM trunk WHERE x>0" | |
| 20207 ")," | |
| 20208 "trunkdata(pgno, data) AS (" | |
| 20209 " SELECT pgno, getpage(pgno) FROM trunk" | |
| 20210 ")," | |
| 20211 "freelist(data, n, freepgno) AS (" | |
| 20212 " SELECT data, min(16384, read_i32(data, 1)-1), pgno FROM trunkdata" | |
| 20213 " UNION ALL" | |
| 20214 " SELECT data, n-1, read_i32(data, 2+n) FROM freelist WHERE n>=0" | |
| 20215 ")," | |
| 20216 "" | |
| 20217 "roots(r) AS (" | |
| 20218 " SELECT 1 UNION ALL" | |
| 20219 " SELECT rootpage FROM recovery.schema WHERE rootpage>0" | |
| 20220 ")," | |
| 20221 "used(page) AS (" | |
| 20222 " SELECT r FROM roots" | |
| 20223 " UNION" | |
| 20224 " SELECT child FROM sqlite_dbptr('getpage()'), used " | |
| 20225 " WHERE pgno=page" | |
| 20226 ") " | |
| 20227 "SELECT page FROM used" | |
| 20228 " UNION ALL " | |
| 20229 "SELECT freepgno FROM freelist WHERE NOT ?" | |
| 20230 ); | |
| 20231 if( pStmt ) sqlite3_bind_int(pStmt, 1, p->bFreelistCorrupt); | |
| 20232 pLaf->pUsedPages = pStmt; | |
| 20233 } | |
| 20234 | |
| 20235 /* | |
| 20236 ** Perform one step (sqlite3_recover_step()) of work for the connection | |
| 20237 ** passed as the only argument, which is guaranteed to be in | |
| 20238 ** RECOVER_STATE_LOSTANDFOUND1 state - during which the set of pages not | |
| 20239 ** already allocated to a recovered schema element is determined. | |
| 20240 */ | |
| 20241 static int recoverLostAndFound1Step(sqlite3_recover *p){ | |
| 20242 RecoverStateLAF *pLaf = &p->laf; | |
| 20243 int rc = p->errCode; | |
| 20244 if( rc==SQLITE_OK ){ | |
| 20245 rc = sqlite3_step(pLaf->pUsedPages); | |
| 20246 if( rc==SQLITE_ROW ){ | |
| 20247 i64 iPg = sqlite3_column_int64(pLaf->pUsedPages, 0); | |
| 20248 recoverBitmapSet(pLaf->pUsed, iPg); | |
| 20249 rc = SQLITE_OK; | |
| 20250 }else{ | |
| 20251 recoverFinalize(p, pLaf->pUsedPages); | |
| 20252 pLaf->pUsedPages = 0; | |
| 20253 } | |
| 20254 } | |
| 20255 return rc; | |
| 20256 } | |
| 20257 | |
| 20258 /* | |
| 20259 ** Initialize resources required by RECOVER_STATE_LOSTANDFOUND2 | |
| 20260 ** state - during which the pages identified in RECOVER_STATE_LOSTANDFOUND1 | |
| 20261 ** are sorted into sets that likely belonged to the same database tree. | |
| 20262 */ | |
| 20263 static void recoverLostAndFound2Init(sqlite3_recover *p){ | |
| 20264 RecoverStateLAF *pLaf = &p->laf; | |
| 20265 | |
| 20266 assert( p->laf.pAllAndParent==0 ); | |
| 20267 assert( p->laf.pMapInsert==0 ); | |
| 20268 assert( p->laf.pMaxField==0 ); | |
| 20269 assert( p->laf.nMaxField==0 ); | |
| 20270 | |
| 20271 pLaf->pMapInsert = recoverPrepare(p, p->dbOut, | |
| 20272 "INSERT OR IGNORE INTO recovery.map(pgno, parent) VALUES(?, ?)" | |
| 20273 ); | |
| 20274 pLaf->pAllAndParent = recoverPreparePrintf(p, p->dbOut, | |
| 20275 "WITH RECURSIVE seq(ii) AS (" | |
| 20276 " SELECT 1 UNION ALL SELECT ii+1 FROM seq WHERE ii<%lld" | |
| 20277 ")" | |
| 20278 "SELECT pgno, child FROM sqlite_dbptr('getpage()') " | |
| 20279 " UNION ALL " | |
| 20280 "SELECT NULL, ii FROM seq", p->laf.nPg | |
| 20281 ); | |
| 20282 pLaf->pMaxField = recoverPreparePrintf(p, p->dbOut, | |
| 20283 "SELECT max(field)+1 FROM sqlite_dbdata('getpage') WHERE pgno = ?" | |
| 20284 ); | |
| 20285 } | |
| 20286 | |
| 20287 /* | |
| 20288 ** Perform one step (sqlite3_recover_step()) of work for the connection | |
| 20289 ** passed as the only argument, which is guaranteed to be in | |
| 20290 ** RECOVER_STATE_LOSTANDFOUND2 state - during which the pages identified | |
| 20291 ** in RECOVER_STATE_LOSTANDFOUND1 are sorted into sets that likely belonged | |
| 20292 ** to the same database tree. | |
| 20293 */ | |
| 20294 static int recoverLostAndFound2Step(sqlite3_recover *p){ | |
| 20295 RecoverStateLAF *pLaf = &p->laf; | |
| 20296 if( p->errCode==SQLITE_OK ){ | |
| 20297 int res = sqlite3_step(pLaf->pAllAndParent); | |
| 20298 if( res==SQLITE_ROW ){ | |
| 20299 i64 iChild = sqlite3_column_int(pLaf->pAllAndParent, 1); | |
| 20300 if( recoverBitmapQuery(pLaf->pUsed, iChild)==0 ){ | |
| 20301 sqlite3_bind_int64(pLaf->pMapInsert, 1, iChild); | |
| 20302 sqlite3_bind_value(pLaf->pMapInsert, 2, | |
| 20303 sqlite3_column_value(pLaf->pAllAndParent, 0) | |
| 20304 ); | |
| 20305 sqlite3_step(pLaf->pMapInsert); | |
| 20306 recoverReset(p, pLaf->pMapInsert); | |
| 20307 sqlite3_bind_int64(pLaf->pMaxField, 1, iChild); | |
| 20308 if( SQLITE_ROW==sqlite3_step(pLaf->pMaxField) ){ | |
| 20309 int nMax = sqlite3_column_int(pLaf->pMaxField, 0); | |
| 20310 if( nMax>pLaf->nMaxField ) pLaf->nMaxField = nMax; | |
| 20311 } | |
| 20312 recoverReset(p, pLaf->pMaxField); | |
| 20313 } | |
| 20314 }else{ | |
| 20315 recoverFinalize(p, pLaf->pAllAndParent); | |
| 20316 pLaf->pAllAndParent =0; | |
| 20317 return SQLITE_DONE; | |
| 20318 } | |
| 20319 } | |
| 20320 return p->errCode; | |
| 20321 } | |
| 20322 | |
| 20323 /* | |
| 20324 ** Free all resources allocated as part of sqlite3_recover_step() calls | |
| 20325 ** in one of the RECOVER_STATE_LOSTANDFOUND[123] states. | |
| 20326 */ | |
| 20327 static void recoverLostAndFoundCleanup(sqlite3_recover *p){ | |
| 20328 recoverBitmapFree(p->laf.pUsed); | |
| 20329 p->laf.pUsed = 0; | |
| 20330 sqlite3_finalize(p->laf.pUsedPages); | |
| 20331 sqlite3_finalize(p->laf.pAllAndParent); | |
| 20332 sqlite3_finalize(p->laf.pMapInsert); | |
| 20333 sqlite3_finalize(p->laf.pMaxField); | |
| 20334 sqlite3_finalize(p->laf.pFindRoot); | |
| 20335 sqlite3_finalize(p->laf.pInsert); | |
| 20336 sqlite3_finalize(p->laf.pAllPage); | |
| 20337 sqlite3_finalize(p->laf.pPageData); | |
| 20338 p->laf.pUsedPages = 0; | |
| 20339 p->laf.pAllAndParent = 0; | |
| 20340 p->laf.pMapInsert = 0; | |
| 20341 p->laf.pMaxField = 0; | |
| 20342 p->laf.pFindRoot = 0; | |
| 20343 p->laf.pInsert = 0; | |
| 20344 p->laf.pAllPage = 0; | |
| 20345 p->laf.pPageData = 0; | |
| 20346 sqlite3_free(p->laf.apVal); | |
| 20347 p->laf.apVal = 0; | |
| 20348 } | |
| 20349 | |
| 20350 /* | |
| 20351 ** Free all resources allocated as part of sqlite3_recover_step() calls. | |
| 20352 */ | |
| 20353 static void recoverFinalCleanup(sqlite3_recover *p){ | |
| 20354 RecoverTable *pTab = 0; | |
| 20355 RecoverTable *pNext = 0; | |
| 20356 | |
| 20357 recoverWriteDataCleanup(p); | |
| 20358 recoverLostAndFoundCleanup(p); | |
| 20359 | |
| 20360 for(pTab=p->pTblList; pTab; pTab=pNext){ | |
| 20361 pNext = pTab->pNext; | |
| 20362 sqlite3_free(pTab); | |
| 20363 } | |
| 20364 p->pTblList = 0; | |
| 20365 sqlite3_finalize(p->pGetPage); | |
| 20366 p->pGetPage = 0; | |
| 20367 sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0); | |
| 20368 | |
| 20369 { | |
| 20370 #ifndef NDEBUG | |
| 20371 int res = | |
| 20372 #endif | |
| 20373 sqlite3_close(p->dbOut); | |
| 20374 assert( res==SQLITE_OK ); | |
| 20375 } | |
| 20376 p->dbOut = 0; | |
| 20377 } | |
| 20378 | |
| 20379 /* | |
| 20380 ** Decode and return an unsigned 16-bit big-endian integer value from | |
| 20381 ** buffer a[]. | |
| 20382 */ | |
| 20383 static u32 recoverGetU16(const u8 *a){ | |
| 20384 return (((u32)a[0])<<8) + ((u32)a[1]); | |
| 20385 } | |
| 20386 | |
| 20387 /* | |
| 20388 ** Decode and return an unsigned 32-bit big-endian integer value from | |
| 20389 ** buffer a[]. | |
| 20390 */ | |
| 20391 static u32 recoverGetU32(const u8 *a){ | |
| 20392 return (((u32)a[0])<<24) + (((u32)a[1])<<16) + (((u32)a[2])<<8) + ((u32)a[3]); | |
| 20393 } | |
| 20394 | |
| 20395 /* | |
| 20396 ** Decode an SQLite varint from buffer a[]. Write the decoded value to (*pVal) | |
| 20397 ** and return the number of bytes consumed. | |
| 20398 */ | |
| 20399 static int recoverGetVarint(const u8 *a, i64 *pVal){ | |
| 20400 sqlite3_uint64 u = 0; | |
| 20401 int i; | |
| 20402 for(i=0; i<8; i++){ | |
| 20403 u = (u<<7) + (a[i]&0x7f); | |
| 20404 if( (a[i]&0x80)==0 ){ *pVal = (sqlite3_int64)u; return i+1; } | |
| 20405 } | |
| 20406 u = (u<<8) + (a[i]&0xff); | |
| 20407 *pVal = (sqlite3_int64)u; | |
| 20408 return 9; | |
| 20409 } | |
| 20410 | |
| 20411 /* | |
| 20412 ** The second argument points to a buffer n bytes in size. If this buffer | |
| 20413 ** or a prefix thereof appears to contain a well-formed SQLite b-tree page, | |
| 20414 ** return the page-size in bytes. Otherwise, if the buffer does not | |
| 20415 ** appear to contain a well-formed b-tree page, return 0. | |
| 20416 */ | |
| 20417 static int recoverIsValidPage(u8 *aTmp, const u8 *a, int n){ | |
| 20418 u8 *aUsed = aTmp; | |
| 20419 int nFrag = 0; | |
| 20420 int nActual = 0; | |
| 20421 int iFree = 0; | |
| 20422 int nCell = 0; /* Number of cells on page */ | |
| 20423 int iCellOff = 0; /* Offset of cell array in page */ | |
| 20424 int iContent = 0; | |
| 20425 int eType = 0; | |
| 20426 int ii = 0; | |
| 20427 | |
| 20428 eType = (int)a[0]; | |
| 20429 if( eType!=0x02 && eType!=0x05 && eType!=0x0A && eType!=0x0D ) return 0; | |
| 20430 | |
| 20431 iFree = (int)recoverGetU16(&a[1]); | |
| 20432 nCell = (int)recoverGetU16(&a[3]); | |
| 20433 iContent = (int)recoverGetU16(&a[5]); | |
| 20434 if( iContent==0 ) iContent = 65536; | |
| 20435 nFrag = (int)a[7]; | |
| 20436 | |
| 20437 if( iContent>n ) return 0; | |
| 20438 | |
| 20439 memset(aUsed, 0, n); | |
| 20440 memset(aUsed, 0xFF, iContent); | |
| 20441 | |
| 20442 /* Follow the free-list. This is the same format for all b-tree pages. */ | |
| 20443 if( iFree && iFree<=iContent ) return 0; | |
| 20444 while( iFree ){ | |
| 20445 int iNext = 0; | |
| 20446 int nByte = 0; | |
| 20447 if( iFree>(n-4) ) return 0; | |
| 20448 iNext = recoverGetU16(&a[iFree]); | |
| 20449 nByte = recoverGetU16(&a[iFree+2]); | |
| 20450 if( iFree+nByte>n || nByte<4 ) return 0; | |
| 20451 if( iNext && iNext<iFree+nByte ) return 0; | |
| 20452 memset(&aUsed[iFree], 0xFF, nByte); | |
| 20453 iFree = iNext; | |
| 20454 } | |
| 20455 | |
| 20456 /* Run through the cells */ | |
| 20457 if( eType==0x02 || eType==0x05 ){ | |
| 20458 iCellOff = 12; | |
| 20459 }else{ | |
| 20460 iCellOff = 8; | |
| 20461 } | |
| 20462 if( (iCellOff + 2*nCell)>iContent ) return 0; | |
| 20463 for(ii=0; ii<nCell; ii++){ | |
| 20464 int iByte; | |
| 20465 i64 nPayload = 0; | |
| 20466 int nByte = 0; | |
| 20467 int iOff = recoverGetU16(&a[iCellOff + 2*ii]); | |
| 20468 if( iOff<iContent || iOff>n ){ | |
| 20469 return 0; | |
| 20470 } | |
| 20471 if( eType==0x05 || eType==0x02 ) nByte += 4; | |
| 20472 nByte += recoverGetVarint(&a[iOff+nByte], &nPayload); | |
| 20473 if( eType==0x0D ){ | |
| 20474 i64 dummy = 0; | |
| 20475 nByte += recoverGetVarint(&a[iOff+nByte], &dummy); | |
| 20476 } | |
| 20477 if( eType!=0x05 ){ | |
| 20478 int X = (eType==0x0D) ? n-35 : (((n-12)*64/255)-23); | |
| 20479 int M = ((n-12)*32/255)-23; | |
| 20480 int K = M+((nPayload-M)%(n-4)); | |
| 20481 | |
| 20482 if( nPayload<X ){ | |
| 20483 nByte += nPayload; | |
| 20484 }else if( K<=X ){ | |
| 20485 nByte += K+4; | |
| 20486 }else{ | |
| 20487 nByte += M+4; | |
| 20488 } | |
| 20489 } | |
| 20490 | |
| 20491 if( iOff+nByte>n ){ | |
| 20492 return 0; | |
| 20493 } | |
| 20494 for(iByte=iOff; iByte<(iOff+nByte); iByte++){ | |
| 20495 if( aUsed[iByte]!=0 ){ | |
| 20496 return 0; | |
| 20497 } | |
| 20498 aUsed[iByte] = 0xFF; | |
| 20499 } | |
| 20500 } | |
| 20501 | |
| 20502 nActual = 0; | |
| 20503 for(ii=0; ii<n; ii++){ | |
| 20504 if( aUsed[ii]==0 ) nActual++; | |
| 20505 } | |
| 20506 return (nActual==nFrag); | |
| 20507 } | |
| 20508 | |
| 20509 | |
| 20510 static int recoverVfsClose(sqlite3_file*); | |
| 20511 static int recoverVfsRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); | |
| 20512 static int recoverVfsWrite(sqlite3_file*, const void*, int, sqlite3_int64); | |
| 20513 static int recoverVfsTruncate(sqlite3_file*, sqlite3_int64 size); | |
| 20514 static int recoverVfsSync(sqlite3_file*, int flags); | |
| 20515 static int recoverVfsFileSize(sqlite3_file*, sqlite3_int64 *pSize); | |
| 20516 static int recoverVfsLock(sqlite3_file*, int); | |
| 20517 static int recoverVfsUnlock(sqlite3_file*, int); | |
| 20518 static int recoverVfsCheckReservedLock(sqlite3_file*, int *pResOut); | |
| 20519 static int recoverVfsFileControl(sqlite3_file*, int op, void *pArg); | |
| 20520 static int recoverVfsSectorSize(sqlite3_file*); | |
| 20521 static int recoverVfsDeviceCharacteristics(sqlite3_file*); | |
| 20522 static int recoverVfsShmMap(sqlite3_file*, int, int, int, void volatile**); | |
| 20523 static int recoverVfsShmLock(sqlite3_file*, int offset, int n, int flags); | |
| 20524 static void recoverVfsShmBarrier(sqlite3_file*); | |
| 20525 static int recoverVfsShmUnmap(sqlite3_file*, int deleteFlag); | |
| 20526 static int recoverVfsFetch(sqlite3_file*, sqlite3_int64, int, void**); | |
| 20527 static int recoverVfsUnfetch(sqlite3_file *pFd, sqlite3_int64 iOff, void *p); | |
| 20528 | |
| 20529 static sqlite3_io_methods recover_methods = { | |
| 20530 2, /* iVersion */ | |
| 20531 recoverVfsClose, | |
| 20532 recoverVfsRead, | |
| 20533 recoverVfsWrite, | |
| 20534 recoverVfsTruncate, | |
| 20535 recoverVfsSync, | |
| 20536 recoverVfsFileSize, | |
| 20537 recoverVfsLock, | |
| 20538 recoverVfsUnlock, | |
| 20539 recoverVfsCheckReservedLock, | |
| 20540 recoverVfsFileControl, | |
| 20541 recoverVfsSectorSize, | |
| 20542 recoverVfsDeviceCharacteristics, | |
| 20543 recoverVfsShmMap, | |
| 20544 recoverVfsShmLock, | |
| 20545 recoverVfsShmBarrier, | |
| 20546 recoverVfsShmUnmap, | |
| 20547 recoverVfsFetch, | |
| 20548 recoverVfsUnfetch | |
| 20549 }; | |
| 20550 | |
| 20551 static int recoverVfsClose(sqlite3_file *pFd){ | |
| 20552 assert( pFd->pMethods!=&recover_methods ); | |
| 20553 return pFd->pMethods->xClose(pFd); | |
| 20554 } | |
| 20555 | |
| 20556 /* | |
| 20557 ** Write value v to buffer a[] as a 16-bit big-endian unsigned integer. | |
| 20558 */ | |
| 20559 static void recoverPutU16(u8 *a, u32 v){ | |
| 20560 a[0] = (v>>8) & 0x00FF; | |
| 20561 a[1] = (v>>0) & 0x00FF; | |
| 20562 } | |
| 20563 | |
| 20564 /* | |
| 20565 ** Write value v to buffer a[] as a 32-bit big-endian unsigned integer. | |
| 20566 */ | |
| 20567 static void recoverPutU32(u8 *a, u32 v){ | |
| 20568 a[0] = (v>>24) & 0x00FF; | |
| 20569 a[1] = (v>>16) & 0x00FF; | |
| 20570 a[2] = (v>>8) & 0x00FF; | |
| 20571 a[3] = (v>>0) & 0x00FF; | |
| 20572 } | |
| 20573 | |
| 20574 /* | |
| 20575 ** Detect the page-size of the database opened by file-handle pFd by | |
| 20576 ** searching the first part of the file for a well-formed SQLite b-tree | |
| 20577 ** page. If parameter nReserve is non-zero, then as well as searching for | |
| 20578 ** a b-tree page with zero reserved bytes, this function searches for one | |
| 20579 ** with nReserve reserved bytes at the end of it. | |
| 20580 ** | |
| 20581 ** If successful, set variable p->detected_pgsz to the detected page-size | |
| 20582 ** in bytes and return SQLITE_OK. Or, if no error occurs but no valid page | |
| 20583 ** can be found, return SQLITE_OK but leave p->detected_pgsz set to 0. Or, | |
| 20584 ** if an error occurs (e.g. an IO or OOM error), then an SQLite error code | |
| 20585 ** is returned. The final value of p->detected_pgsz is undefined in this | |
| 20586 ** case. | |
| 20587 */ | |
| 20588 static int recoverVfsDetectPagesize( | |
| 20589 sqlite3_recover *p, /* Recover handle */ | |
| 20590 sqlite3_file *pFd, /* File-handle open on input database */ | |
| 20591 u32 nReserve, /* Possible nReserve value */ | |
| 20592 i64 nSz /* Size of database file in bytes */ | |
| 20593 ){ | |
| 20594 int rc = SQLITE_OK; | |
| 20595 const int nMin = 512; | |
| 20596 const int nMax = 65536; | |
| 20597 const int nMaxBlk = 4; | |
| 20598 u32 pgsz = 0; | |
| 20599 int iBlk = 0; | |
| 20600 u8 *aPg = 0; | |
| 20601 u8 *aTmp = 0; | |
| 20602 int nBlk = 0; | |
| 20603 | |
| 20604 aPg = (u8*)sqlite3_malloc(2*nMax); | |
| 20605 if( aPg==0 ) return SQLITE_NOMEM; | |
| 20606 aTmp = &aPg[nMax]; | |
| 20607 | |
| 20608 nBlk = (nSz+nMax-1)/nMax; | |
| 20609 if( nBlk>nMaxBlk ) nBlk = nMaxBlk; | |
| 20610 | |
| 20611 do { | |
| 20612 for(iBlk=0; rc==SQLITE_OK && iBlk<nBlk; iBlk++){ | |
| 20613 int nByte = (nSz>=((iBlk+1)*nMax)) ? nMax : (nSz % nMax); | |
| 20614 memset(aPg, 0, nMax); | |
| 20615 rc = pFd->pMethods->xRead(pFd, aPg, nByte, iBlk*nMax); | |
| 20616 if( rc==SQLITE_OK ){ | |
| 20617 int pgsz2; | |
| 20618 for(pgsz2=(pgsz ? pgsz*2 : nMin); pgsz2<=nMax; pgsz2=pgsz2*2){ | |
| 20619 int iOff; | |
| 20620 for(iOff=0; iOff<nMax; iOff+=pgsz2){ | |
| 20621 if( recoverIsValidPage(aTmp, &aPg[iOff], pgsz2-nReserve) ){ | |
| 20622 pgsz = pgsz2; | |
| 20623 break; | |
| 20624 } | |
| 20625 } | |
| 20626 } | |
| 20627 } | |
| 20628 } | |
| 20629 if( pgsz>(u32)p->detected_pgsz ){ | |
| 20630 p->detected_pgsz = pgsz; | |
| 20631 p->nReserve = nReserve; | |
| 20632 } | |
| 20633 if( nReserve==0 ) break; | |
| 20634 nReserve = 0; | |
| 20635 }while( 1 ); | |
| 20636 | |
| 20637 p->detected_pgsz = pgsz; | |
| 20638 sqlite3_free(aPg); | |
| 20639 return rc; | |
| 20640 } | |
| 20641 | |
| 20642 /* | |
| 20643 ** The xRead() method of the wrapper VFS. This is used to intercept calls | |
| 20644 ** to read page 1 of the input database. | |
| 20645 */ | |
| 20646 static int recoverVfsRead(sqlite3_file *pFd, void *aBuf, int nByte, i64 iOff){ | |
| 20647 int rc = SQLITE_OK; | |
| 20648 if( pFd->pMethods==&recover_methods ){ | |
| 20649 pFd->pMethods = recover_g.pMethods; | |
| 20650 rc = pFd->pMethods->xRead(pFd, aBuf, nByte, iOff); | |
| 20651 if( nByte==16 ){ | |
| 20652 sqlite3_randomness(16, aBuf); | |
| 20653 }else | |
| 20654 if( rc==SQLITE_OK && iOff==0 && nByte>=108 ){ | |
| 20655 /* Ensure that the database has a valid header file. The only fields | |
| 20656 ** that really matter to recovery are: | |
| 20657 ** | |
| 20658 ** + Database page size (16-bits at offset 16) | |
| 20659 ** + Size of db in pages (32-bits at offset 28) | |
| 20660 ** + Database encoding (32-bits at offset 56) | |
| 20661 ** | |
| 20662 ** Also preserved are: | |
| 20663 ** | |
| 20664 ** + first freelist page (32-bits at offset 32) | |
| 20665 ** + size of freelist (32-bits at offset 36) | |
| 20666 ** + the wal-mode flags (16-bits at offset 18) | |
| 20667 ** | |
| 20668 ** We also try to preserve the auto-vacuum, incr-value, user-version | |
| 20669 ** and application-id fields - all 32 bit quantities at offsets | |
| 20670 ** 52, 60, 64 and 68. All other fields are set to known good values. | |
| 20671 ** | |
| 20672 ** Byte offset 105 should also contain the page-size as a 16-bit | |
| 20673 ** integer. | |
| 20674 */ | |
| 20675 const int aPreserve[] = {32, 36, 52, 60, 64, 68}; | |
| 20676 u8 aHdr[108] = { | |
| 20677 0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66, | |
| 20678 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00, | |
| 20679 0xFF, 0xFF, 0x01, 0x01, 0x00, 0x40, 0x20, 0x20, | |
| 20680 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, | |
| 20681 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | |
| 20682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, | |
| 20683 0x00, 0x00, 0x10, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, | |
| 20684 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | |
| 20685 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | |
| 20686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 20687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 20688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 20689 0x00, 0x2e, 0x5b, 0x30, | |
| 20690 | |
| 20691 0x0D, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00 | |
| 20692 }; | |
| 20693 u8 *a = (u8*)aBuf; | |
| 20694 | |
| 20695 u32 pgsz = recoverGetU16(&a[16]); | |
| 20696 u32 nReserve = a[20]; | |
| 20697 u32 enc = recoverGetU32(&a[56]); | |
| 20698 u32 dbsz = 0; | |
| 20699 i64 dbFileSize = 0; | |
| 20700 int ii; | |
| 20701 sqlite3_recover *p = recover_g.p; | |
| 20702 | |
| 20703 if( pgsz==0x01 ) pgsz = 65536; | |
| 20704 rc = pFd->pMethods->xFileSize(pFd, &dbFileSize); | |
| 20705 | |
| 20706 if( rc==SQLITE_OK && p->detected_pgsz==0 ){ | |
| 20707 rc = recoverVfsDetectPagesize(p, pFd, nReserve, dbFileSize); | |
| 20708 } | |
| 20709 if( p->detected_pgsz ){ | |
| 20710 pgsz = p->detected_pgsz; | |
| 20711 nReserve = p->nReserve; | |
| 20712 } | |
| 20713 | |
| 20714 if( pgsz ){ | |
| 20715 dbsz = dbFileSize / pgsz; | |
| 20716 } | |
| 20717 if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF16BE && enc!=SQLITE_UTF16LE ){ | |
| 20718 enc = SQLITE_UTF8; | |
| 20719 } | |
| 20720 | |
| 20721 sqlite3_free(p->pPage1Cache); | |
| 20722 p->pPage1Cache = 0; | |
| 20723 p->pPage1Disk = 0; | |
| 20724 | |
| 20725 p->pgsz = nByte; | |
| 20726 p->pPage1Cache = (u8*)recoverMalloc(p, nByte*2); | |
| 20727 if( p->pPage1Cache ){ | |
| 20728 p->pPage1Disk = &p->pPage1Cache[nByte]; | |
| 20729 memcpy(p->pPage1Disk, aBuf, nByte); | |
| 20730 aHdr[18] = a[18]; | |
| 20731 aHdr[19] = a[19]; | |
| 20732 recoverPutU32(&aHdr[28], dbsz); | |
| 20733 recoverPutU32(&aHdr[56], enc); | |
| 20734 recoverPutU16(&aHdr[105], pgsz-nReserve); | |
| 20735 if( pgsz==65536 ) pgsz = 1; | |
| 20736 recoverPutU16(&aHdr[16], pgsz); | |
| 20737 aHdr[20] = nReserve; | |
| 20738 for(ii=0; ii<(int)(sizeof(aPreserve)/sizeof(aPreserve[0])); ii++){ | |
| 20739 memcpy(&aHdr[aPreserve[ii]], &a[aPreserve[ii]], 4); | |
| 20740 } | |
| 20741 memcpy(aBuf, aHdr, sizeof(aHdr)); | |
| 20742 memset(&((u8*)aBuf)[sizeof(aHdr)], 0, nByte-sizeof(aHdr)); | |
| 20743 | |
| 20744 memcpy(p->pPage1Cache, aBuf, nByte); | |
| 20745 }else{ | |
| 20746 rc = p->errCode; | |
| 20747 } | |
| 20748 | |
| 20749 } | |
| 20750 pFd->pMethods = &recover_methods; | |
| 20751 }else{ | |
| 20752 rc = pFd->pMethods->xRead(pFd, aBuf, nByte, iOff); | |
| 20753 } | |
| 20754 return rc; | |
| 20755 } | |
| 20756 | |
| 20757 /* | |
| 20758 ** Used to make sqlite3_io_methods wrapper methods less verbose. | |
| 20759 */ | |
| 20760 #define RECOVER_VFS_WRAPPER(code) \ | |
| 20761 int rc = SQLITE_OK; \ | |
| 20762 if( pFd->pMethods==&recover_methods ){ \ | |
| 20763 pFd->pMethods = recover_g.pMethods; \ | |
| 20764 rc = code; \ | |
| 20765 pFd->pMethods = &recover_methods; \ | |
| 20766 }else{ \ | |
| 20767 rc = code; \ | |
| 20768 } \ | |
| 20769 return rc; | |
| 20770 | |
| 20771 /* | |
| 20772 ** Methods of the wrapper VFS. All methods except for xRead() and xClose() | |
| 20773 ** simply uninstall the sqlite3_io_methods wrapper, invoke the equivalent | |
| 20774 ** method on the lower level VFS, then reinstall the wrapper before returning. | |
| 20775 ** Those that return an integer value use the RECOVER_VFS_WRAPPER macro. | |
| 20776 */ | |
| 20777 static int recoverVfsWrite( | |
| 20778 sqlite3_file *pFd, const void *aBuf, int nByte, i64 iOff | |
| 20779 ){ | |
| 20780 RECOVER_VFS_WRAPPER ( | |
| 20781 pFd->pMethods->xWrite(pFd, aBuf, nByte, iOff) | |
| 20782 ); | |
| 20783 } | |
| 20784 static int recoverVfsTruncate(sqlite3_file *pFd, sqlite3_int64 size){ | |
| 20785 RECOVER_VFS_WRAPPER ( | |
| 20786 pFd->pMethods->xTruncate(pFd, size) | |
| 20787 ); | |
| 20788 } | |
| 20789 static int recoverVfsSync(sqlite3_file *pFd, int flags){ | |
| 20790 RECOVER_VFS_WRAPPER ( | |
| 20791 pFd->pMethods->xSync(pFd, flags) | |
| 20792 ); | |
| 20793 } | |
| 20794 static int recoverVfsFileSize(sqlite3_file *pFd, sqlite3_int64 *pSize){ | |
| 20795 RECOVER_VFS_WRAPPER ( | |
| 20796 pFd->pMethods->xFileSize(pFd, pSize) | |
| 20797 ); | |
| 20798 } | |
| 20799 static int recoverVfsLock(sqlite3_file *pFd, int eLock){ | |
| 20800 RECOVER_VFS_WRAPPER ( | |
| 20801 pFd->pMethods->xLock(pFd, eLock) | |
| 20802 ); | |
| 20803 } | |
| 20804 static int recoverVfsUnlock(sqlite3_file *pFd, int eLock){ | |
| 20805 RECOVER_VFS_WRAPPER ( | |
| 20806 pFd->pMethods->xUnlock(pFd, eLock) | |
| 20807 ); | |
| 20808 } | |
| 20809 static int recoverVfsCheckReservedLock(sqlite3_file *pFd, int *pResOut){ | |
| 20810 RECOVER_VFS_WRAPPER ( | |
| 20811 pFd->pMethods->xCheckReservedLock(pFd, pResOut) | |
| 20812 ); | |
| 20813 } | |
| 20814 static int recoverVfsFileControl(sqlite3_file *pFd, int op, void *pArg){ | |
| 20815 RECOVER_VFS_WRAPPER ( | |
| 20816 (pFd->pMethods ? pFd->pMethods->xFileControl(pFd, op, pArg) : SQLITE_NOTFOUND) | |
| 20817 ); | |
| 20818 } | |
| 20819 static int recoverVfsSectorSize(sqlite3_file *pFd){ | |
| 20820 RECOVER_VFS_WRAPPER ( | |
| 20821 pFd->pMethods->xSectorSize(pFd) | |
| 20822 ); | |
| 20823 } | |
| 20824 static int recoverVfsDeviceCharacteristics(sqlite3_file *pFd){ | |
| 20825 RECOVER_VFS_WRAPPER ( | |
| 20826 pFd->pMethods->xDeviceCharacteristics(pFd) | |
| 20827 ); | |
| 20828 } | |
| 20829 static int recoverVfsShmMap( | |
| 20830 sqlite3_file *pFd, int iPg, int pgsz, int bExtend, void volatile **pp | |
| 20831 ){ | |
| 20832 RECOVER_VFS_WRAPPER ( | |
| 20833 pFd->pMethods->xShmMap(pFd, iPg, pgsz, bExtend, pp) | |
| 20834 ); | |
| 20835 } | |
| 20836 static int recoverVfsShmLock(sqlite3_file *pFd, int offset, int n, int flags){ | |
| 20837 RECOVER_VFS_WRAPPER ( | |
| 20838 pFd->pMethods->xShmLock(pFd, offset, n, flags) | |
| 20839 ); | |
| 20840 } | |
| 20841 static void recoverVfsShmBarrier(sqlite3_file *pFd){ | |
| 20842 if( pFd->pMethods==&recover_methods ){ | |
| 20843 pFd->pMethods = recover_g.pMethods; | |
| 20844 pFd->pMethods->xShmBarrier(pFd); | |
| 20845 pFd->pMethods = &recover_methods; | |
| 20846 }else{ | |
| 20847 pFd->pMethods->xShmBarrier(pFd); | |
| 20848 } | |
| 20849 } | |
| 20850 static int recoverVfsShmUnmap(sqlite3_file *pFd, int deleteFlag){ | |
| 20851 RECOVER_VFS_WRAPPER ( | |
| 20852 pFd->pMethods->xShmUnmap(pFd, deleteFlag) | |
| 20853 ); | |
| 20854 } | |
| 20855 | |
| 20856 static int recoverVfsFetch( | |
| 20857 sqlite3_file *pFd, | |
| 20858 sqlite3_int64 iOff, | |
| 20859 int iAmt, | |
| 20860 void **pp | |
| 20861 ){ | |
| 20862 (void)pFd; | |
| 20863 (void)iOff; | |
| 20864 (void)iAmt; | |
| 20865 *pp = 0; | |
| 20866 return SQLITE_OK; | |
| 20867 } | |
| 20868 static int recoverVfsUnfetch(sqlite3_file *pFd, sqlite3_int64 iOff, void *p){ | |
| 20869 (void)pFd; | |
| 20870 (void)iOff; | |
| 20871 (void)p; | |
| 20872 return SQLITE_OK; | |
| 20873 } | |
| 20874 | |
| 20875 /* | |
| 20876 ** Install the VFS wrapper around the file-descriptor open on the input | |
| 20877 ** database for recover handle p. Mutex RECOVER_MUTEX_ID must be held | |
| 20878 ** when this function is called. | |
| 20879 */ | |
| 20880 static void recoverInstallWrapper(sqlite3_recover *p){ | |
| 20881 sqlite3_file *pFd = 0; | |
| 20882 assert( recover_g.pMethods==0 ); | |
| 20883 recoverAssertMutexHeld(); | |
| 20884 sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_FILE_POINTER, (void*)&pFd); | |
| 20885 assert( pFd==0 || pFd->pMethods!=&recover_methods ); | |
| 20886 if( pFd && pFd->pMethods ){ | |
| 20887 int iVersion = 1 + (pFd->pMethods->iVersion>1 && pFd->pMethods->xShmMap!=0); | |
| 20888 recover_g.pMethods = pFd->pMethods; | |
| 20889 recover_g.p = p; | |
| 20890 recover_methods.iVersion = iVersion; | |
| 20891 pFd->pMethods = &recover_methods; | |
| 20892 } | |
| 20893 } | |
| 20894 | |
| 20895 /* | |
| 20896 ** Uninstall the VFS wrapper that was installed around the file-descriptor open | |
| 20897 ** on the input database for recover handle p. Mutex RECOVER_MUTEX_ID must be | |
| 20898 ** held when this function is called. | |
| 20899 */ | |
| 20900 static void recoverUninstallWrapper(sqlite3_recover *p){ | |
| 20901 sqlite3_file *pFd = 0; | |
| 20902 recoverAssertMutexHeld(); | |
| 20903 sqlite3_file_control(p->dbIn, p->zDb,SQLITE_FCNTL_FILE_POINTER,(void*)&pFd); | |
| 20904 if( pFd && pFd->pMethods ){ | |
| 20905 pFd->pMethods = recover_g.pMethods; | |
| 20906 recover_g.pMethods = 0; | |
| 20907 recover_g.p = 0; | |
| 20908 } | |
| 20909 } | |
| 20910 | |
| 20911 /* | |
| 20912 ** This function does the work of a single sqlite3_recover_step() call. It | |
| 20913 ** is guaranteed that the handle is not in an error state when this | |
| 20914 ** function is called. | |
| 20915 */ | |
| 20916 static void recoverStep(sqlite3_recover *p){ | |
| 20917 assert( p && p->errCode==SQLITE_OK ); | |
| 20918 switch( p->eState ){ | |
| 20919 case RECOVER_STATE_INIT: { | |
| 20920 int bUseWrapper = 1; | |
| 20921 /* This is the very first call to sqlite3_recover_step() on this object. | |
| 20922 */ | |
| 20923 recoverSqlCallback(p, "BEGIN"); | |
| 20924 recoverSqlCallback(p, "PRAGMA writable_schema = on"); | |
| 20925 recoverSqlCallback(p, "PRAGMA foreign_keys = off"); | |
| 20926 | |
| 20927 recoverEnterMutex(); | |
| 20928 | |
| 20929 /* Open the output database. And register required virtual tables and | |
| 20930 ** user functions with the new handle. */ | |
| 20931 recoverOpenOutput(p); | |
| 20932 | |
| 20933 /* Attempt to open a transaction and read page 1 of the input database. | |
| 20934 ** Two attempts may be made - one with a wrapper installed to ensure | |
| 20935 ** that the database header is sane, and then if that attempt returns | |
| 20936 ** SQLITE_NOTADB, then again with no wrapper. The second attempt is | |
| 20937 ** required for encrypted databases. */ | |
| 20938 if( p->errCode==SQLITE_OK ){ | |
| 20939 do{ | |
| 20940 p->errCode = SQLITE_OK; | |
| 20941 if( bUseWrapper ) recoverInstallWrapper(p); | |
| 20942 | |
| 20943 /* Open a transaction on the input database. */ | |
| 20944 sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0); | |
| 20945 recoverExec(p, p->dbIn, "PRAGMA writable_schema = on"); | |
| 20946 recoverExec(p, p->dbIn, "BEGIN"); | |
| 20947 if( p->errCode==SQLITE_OK ) p->bCloseTransaction = 1; | |
| 20948 recoverExec(p, p->dbIn, "SELECT 1 FROM sqlite_schema"); | |
| 20949 recoverTransferSettings(p); | |
| 20950 recoverOpenRecovery(p); | |
| 20951 recoverCacheSchema(p); | |
| 20952 | |
| 20953 if( bUseWrapper ) recoverUninstallWrapper(p); | |
| 20954 }while( p->errCode==SQLITE_NOTADB | |
| 20955 && (bUseWrapper--) | |
| 20956 && SQLITE_OK==sqlite3_exec(p->dbIn, "ROLLBACK", 0, 0, 0) | |
| 20957 ); | |
| 20958 } | |
| 20959 | |
| 20960 recoverLeaveMutex(); | |
| 20961 recoverExec(p, p->dbOut, "BEGIN"); | |
| 20962 recoverWriteSchema1(p); | |
| 20963 p->eState = RECOVER_STATE_WRITING; | |
| 20964 break; | |
| 20965 } | |
| 20966 | |
| 20967 case RECOVER_STATE_WRITING: { | |
| 20968 if( p->w1.pTbls==0 ){ | |
| 20969 recoverWriteDataInit(p); | |
| 20970 } | |
| 20971 if( SQLITE_DONE==recoverWriteDataStep(p) ){ | |
| 20972 recoverWriteDataCleanup(p); | |
| 20973 if( p->zLostAndFound ){ | |
| 20974 p->eState = RECOVER_STATE_LOSTANDFOUND1; | |
| 20975 }else{ | |
| 20976 p->eState = RECOVER_STATE_SCHEMA2; | |
| 20977 } | |
| 20978 } | |
| 20979 break; | |
| 20980 } | |
| 20981 | |
| 20982 case RECOVER_STATE_LOSTANDFOUND1: { | |
| 20983 if( p->laf.pUsed==0 ){ | |
| 20984 recoverLostAndFound1Init(p); | |
| 20985 } | |
| 20986 if( SQLITE_DONE==recoverLostAndFound1Step(p) ){ | |
| 20987 p->eState = RECOVER_STATE_LOSTANDFOUND2; | |
| 20988 } | |
| 20989 break; | |
| 20990 } | |
| 20991 case RECOVER_STATE_LOSTANDFOUND2: { | |
| 20992 if( p->laf.pAllAndParent==0 ){ | |
| 20993 recoverLostAndFound2Init(p); | |
| 20994 } | |
| 20995 if( SQLITE_DONE==recoverLostAndFound2Step(p) ){ | |
| 20996 p->eState = RECOVER_STATE_LOSTANDFOUND3; | |
| 20997 } | |
| 20998 break; | |
| 20999 } | |
| 21000 | |
| 21001 case RECOVER_STATE_LOSTANDFOUND3: { | |
| 21002 if( p->laf.pInsert==0 ){ | |
| 21003 recoverLostAndFound3Init(p); | |
| 21004 } | |
| 21005 if( SQLITE_DONE==recoverLostAndFound3Step(p) ){ | |
| 21006 p->eState = RECOVER_STATE_SCHEMA2; | |
| 21007 } | |
| 21008 break; | |
| 21009 } | |
| 21010 | |
| 21011 case RECOVER_STATE_SCHEMA2: { | |
| 21012 int rc = SQLITE_OK; | |
| 21013 | |
| 21014 recoverWriteSchema2(p); | |
| 21015 p->eState = RECOVER_STATE_DONE; | |
| 21016 | |
| 21017 /* If no error has occurred, commit the write transaction on the output | |
| 21018 ** database. Regardless of whether or not an error has occurred, make | |
| 21019 ** an attempt to end the read transaction on the input database. */ | |
| 21020 recoverExec(p, p->dbOut, "COMMIT"); | |
| 21021 rc = sqlite3_exec(p->dbIn, "END", 0, 0, 0); | |
| 21022 if( p->errCode==SQLITE_OK ) p->errCode = rc; | |
| 21023 | |
| 21024 recoverSqlCallback(p, "PRAGMA writable_schema = off"); | |
| 21025 recoverSqlCallback(p, "COMMIT"); | |
| 21026 p->eState = RECOVER_STATE_DONE; | |
| 21027 recoverFinalCleanup(p); | |
| 21028 break; | |
| 21029 }; | |
| 21030 | |
| 21031 case RECOVER_STATE_DONE: { | |
| 21032 /* no-op */ | |
| 21033 break; | |
| 21034 }; | |
| 21035 } | |
| 21036 } | |
| 21037 | |
| 21038 | |
| 21039 /* | |
| 21040 ** This is a worker function that does the heavy lifting for both init | |
| 21041 ** functions: | |
| 21042 ** | |
| 21043 ** sqlite3_recover_init() | |
| 21044 ** sqlite3_recover_init_sql() | |
| 21045 ** | |
| 21046 ** All this function does is allocate space for the recover handle and | |
| 21047 ** take copies of the input parameters. All the real work is done within | |
| 21048 ** sqlite3_recover_run(). | |
| 21049 */ | |
| 21050 sqlite3_recover *recoverInit( | |
| 21051 sqlite3* db, | |
| 21052 const char *zDb, | |
| 21053 const char *zUri, /* Output URI for _recover_init() */ | |
| 21054 int (*xSql)(void*, const char*),/* SQL callback for _recover_init_sql() */ | |
| 21055 void *pSqlCtx /* Context arg for _recover_init_sql() */ | |
| 21056 ){ | |
| 21057 sqlite3_recover *pRet = 0; | |
| 21058 int nDb = 0; | |
| 21059 int nUri = 0; | |
| 21060 int nByte = 0; | |
| 21061 | |
| 21062 if( zDb==0 ){ zDb = "main"; } | |
| 21063 | |
| 21064 nDb = recoverStrlen(zDb); | |
| 21065 nUri = recoverStrlen(zUri); | |
| 21066 | |
| 21067 nByte = sizeof(sqlite3_recover) + nDb+1 + nUri+1; | |
| 21068 pRet = (sqlite3_recover*)sqlite3_malloc(nByte); | |
| 21069 if( pRet ){ | |
| 21070 memset(pRet, 0, nByte); | |
| 21071 pRet->dbIn = db; | |
| 21072 pRet->zDb = (char*)&pRet[1]; | |
| 21073 pRet->zUri = &pRet->zDb[nDb+1]; | |
| 21074 memcpy(pRet->zDb, zDb, nDb); | |
| 21075 if( nUri>0 && zUri ) memcpy(pRet->zUri, zUri, nUri); | |
| 21076 pRet->xSql = xSql; | |
| 21077 pRet->pSqlCtx = pSqlCtx; | |
| 21078 pRet->bRecoverRowid = RECOVER_ROWID_DEFAULT; | |
| 21079 } | |
| 21080 | |
| 21081 return pRet; | |
| 21082 } | |
| 21083 | |
| 21084 /* | |
| 21085 ** Initialize a recovery handle that creates a new database containing | |
| 21086 ** the recovered data. | |
| 21087 */ | |
| 21088 sqlite3_recover *sqlite3_recover_init( | |
| 21089 sqlite3* db, | |
| 21090 const char *zDb, | |
| 21091 const char *zUri | |
| 21092 ){ | |
| 21093 return recoverInit(db, zDb, zUri, 0, 0); | |
| 21094 } | |
| 21095 | |
| 21096 /* | |
| 21097 ** Initialize a recovery handle that returns recovered data in the | |
| 21098 ** form of SQL statements via a callback. | |
| 21099 */ | |
| 21100 sqlite3_recover *sqlite3_recover_init_sql( | |
| 21101 sqlite3* db, | |
| 21102 const char *zDb, | |
| 21103 int (*xSql)(void*, const char*), | |
| 21104 void *pSqlCtx | |
| 21105 ){ | |
| 21106 return recoverInit(db, zDb, 0, xSql, pSqlCtx); | |
| 21107 } | |
| 21108 | |
| 21109 /* | |
| 21110 ** Return the handle error message, if any. | |
| 21111 */ | |
| 21112 const char *sqlite3_recover_errmsg(sqlite3_recover *p){ | |
| 21113 return (p && p->errCode!=SQLITE_NOMEM) ? p->zErrMsg : "out of memory"; | |
| 21114 } | |
| 21115 | |
| 21116 /* | |
| 21117 ** Return the handle error code. | |
| 21118 */ | |
| 21119 int sqlite3_recover_errcode(sqlite3_recover *p){ | |
| 21120 return p ? p->errCode : SQLITE_NOMEM; | |
| 21121 } | |
| 21122 | |
| 21123 /* | |
| 21124 ** Configure the handle. | |
| 21125 */ | |
| 21126 int sqlite3_recover_config(sqlite3_recover *p, int op, void *pArg){ | |
| 21127 int rc = SQLITE_OK; | |
| 21128 if( p==0 ){ | |
| 21129 rc = SQLITE_NOMEM; | |
| 21130 }else if( p->eState!=RECOVER_STATE_INIT ){ | |
| 21131 rc = SQLITE_MISUSE; | |
| 21132 }else{ | |
| 21133 switch( op ){ | |
| 21134 case 789: | |
| 21135 /* This undocumented magic configuration option is used to set the | |
| 21136 ** name of the auxiliary database that is ATTACH-ed to the database | |
| 21137 ** connection and used to hold state information during the | |
| 21138 ** recovery process. This option is for debugging use only and | |
| 21139 ** is subject to change or removal at any time. */ | |
| 21140 sqlite3_free(p->zStateDb); | |
| 21141 p->zStateDb = recoverMPrintf(p, "%s", (char*)pArg); | |
| 21142 break; | |
| 21143 | |
| 21144 case SQLITE_RECOVER_LOST_AND_FOUND: { | |
| 21145 const char *zArg = (const char*)pArg; | |
| 21146 sqlite3_free(p->zLostAndFound); | |
| 21147 if( zArg ){ | |
| 21148 p->zLostAndFound = recoverMPrintf(p, "%s", zArg); | |
| 21149 }else{ | |
| 21150 p->zLostAndFound = 0; | |
| 21151 } | |
| 21152 break; | |
| 21153 } | |
| 21154 | |
| 21155 case SQLITE_RECOVER_FREELIST_CORRUPT: | |
| 21156 p->bFreelistCorrupt = *(int*)pArg; | |
| 21157 break; | |
| 21158 | |
| 21159 case SQLITE_RECOVER_ROWIDS: | |
| 21160 p->bRecoverRowid = *(int*)pArg; | |
| 21161 break; | |
| 21162 | |
| 21163 case SQLITE_RECOVER_SLOWINDEXES: | |
| 21164 p->bSlowIndexes = *(int*)pArg; | |
| 21165 break; | |
| 21166 | |
| 21167 default: | |
| 21168 rc = SQLITE_NOTFOUND; | |
| 21169 break; | |
| 21170 } | |
| 21171 } | |
| 21172 | |
| 21173 return rc; | |
| 21174 } | |
| 21175 | |
| 21176 /* | |
| 21177 ** Do a unit of work towards the recovery job. Return SQLITE_OK if | |
| 21178 ** no error has occurred but database recovery is not finished, SQLITE_DONE | |
| 21179 ** if database recovery has been successfully completed, or an SQLite | |
| 21180 ** error code if an error has occurred. | |
| 21181 */ | |
| 21182 int sqlite3_recover_step(sqlite3_recover *p){ | |
| 21183 if( p==0 ) return SQLITE_NOMEM; | |
| 21184 if( p->errCode==SQLITE_OK ) recoverStep(p); | |
| 21185 if( p->eState==RECOVER_STATE_DONE && p->errCode==SQLITE_OK ){ | |
| 21186 return SQLITE_DONE; | |
| 21187 } | |
| 21188 return p->errCode; | |
| 21189 } | |
| 21190 | |
| 21191 /* | |
| 21192 ** Do the configured recovery operation. Return SQLITE_OK if successful, or | |
| 21193 ** else an SQLite error code. | |
| 21194 */ | |
| 21195 int sqlite3_recover_run(sqlite3_recover *p){ | |
| 21196 while( SQLITE_OK==sqlite3_recover_step(p) ); | |
| 21197 return sqlite3_recover_errcode(p); | |
| 21198 } | |
| 21199 | |
| 21200 | |
| 21201 /* | |
| 21202 ** Free all resources associated with the recover handle passed as the only | |
| 21203 ** argument. The results of using a handle with any sqlite3_recover_** | |
| 21204 ** API function after it has been passed to this function are undefined. | |
| 21205 ** | |
| 21206 ** A copy of the value returned by the first call made to sqlite3_recover_run() | |
| 21207 ** on this handle is returned, or SQLITE_OK if sqlite3_recover_run() has | |
| 21208 ** not been called on this handle. | |
| 21209 */ | |
| 21210 int sqlite3_recover_finish(sqlite3_recover *p){ | |
| 21211 int rc; | |
| 21212 if( p==0 ){ | |
| 21213 rc = SQLITE_NOMEM; | |
| 21214 }else{ | |
| 21215 recoverFinalCleanup(p); | |
| 21216 if( p->bCloseTransaction && sqlite3_get_autocommit(p->dbIn)==0 ){ | |
| 21217 rc = sqlite3_exec(p->dbIn, "END", 0, 0, 0); | |
| 21218 if( p->errCode==SQLITE_OK ) p->errCode = rc; | |
| 21219 } | |
| 21220 rc = p->errCode; | |
| 21221 sqlite3_free(p->zErrMsg); | |
| 21222 sqlite3_free(p->zStateDb); | |
| 21223 sqlite3_free(p->zLostAndFound); | |
| 21224 sqlite3_free(p->pPage1Cache); | |
| 21225 sqlite3_free(p); | |
| 21226 } | |
| 21227 return rc; | |
| 21228 } | |
| 21229 | |
| 21230 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ | |
| 21231 | |
| 21232 /************************* End ../ext/recover/sqlite3recover.c ********************/ | |
| 21233 # endif /* SQLITE_HAVE_SQLITE3R */ | |
| 21234 #endif | |
| 21235 #ifdef SQLITE_SHELL_EXTSRC | |
| 21236 # include SHELL_STRINGIFY(SQLITE_SHELL_EXTSRC) | |
| 21237 #endif | |
| 21238 | |
| 21239 #if defined(SQLITE_ENABLE_SESSION) | |
| 21240 /* | |
| 21241 ** State information for a single open session | |
| 21242 */ | |
| 21243 typedef struct OpenSession OpenSession; | |
| 21244 struct OpenSession { | |
| 21245 char *zName; /* Symbolic name for this session */ | |
| 21246 int nFilter; /* Number of xFilter rejection GLOB patterns */ | |
| 21247 char **azFilter; /* Array of xFilter rejection GLOB patterns */ | |
| 21248 sqlite3_session *p; /* The open session */ | |
| 21249 }; | |
| 21250 #endif | |
| 21251 | |
| 21252 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 21253 typedef struct ExpertInfo ExpertInfo; | |
| 21254 struct ExpertInfo { | |
| 21255 sqlite3expert *pExpert; | |
| 21256 int bVerbose; | |
| 21257 }; | |
| 21258 #endif | |
| 21259 | |
| 21260 /* A single line in the EQP output */ | |
| 21261 typedef struct EQPGraphRow EQPGraphRow; | |
| 21262 struct EQPGraphRow { | |
| 21263 int iEqpId; /* ID for this row */ | |
| 21264 int iParentId; /* ID of the parent row */ | |
| 21265 EQPGraphRow *pNext; /* Next row in sequence */ | |
| 21266 char zText[1]; /* Text to display for this row */ | |
| 21267 }; | |
| 21268 | |
| 21269 /* All EQP output is collected into an instance of the following */ | |
| 21270 typedef struct EQPGraph EQPGraph; | |
| 21271 struct EQPGraph { | |
| 21272 EQPGraphRow *pRow; /* Linked list of all rows of the EQP output */ | |
| 21273 EQPGraphRow *pLast; /* Last element of the pRow list */ | |
| 21274 char zPrefix[100]; /* Graph prefix */ | |
| 21275 }; | |
| 21276 | |
| 21277 /* Parameters affecting columnar mode result display (defaulting together) */ | |
| 21278 typedef struct ColModeOpts { | |
| 21279 int iWrap; /* In columnar modes, wrap lines reaching this limit */ | |
| 21280 u8 bQuote; /* Quote results for .mode box and table */ | |
| 21281 u8 bWordWrap; /* In columnar modes, wrap at word boundaries */ | |
| 21282 } ColModeOpts; | |
| 21283 #define ColModeOpts_default { 60, 0, 0 } | |
| 21284 #define ColModeOpts_default_qbox { 60, 1, 0 } | |
| 21285 | |
| 21286 /* | |
| 21287 ** State information about the database connection is contained in an | |
| 21288 ** instance of the following structure. | |
| 21289 */ | |
| 21290 typedef struct ShellState ShellState; | |
| 21291 struct ShellState { | |
| 21292 sqlite3 *db; /* The database */ | |
| 21293 u8 autoExplain; /* Automatically turn on .explain mode */ | |
| 21294 u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to each SQL stmt */ | |
| 21295 u8 autoEQPtest; /* autoEQP is in test mode */ | |
| 21296 u8 autoEQPtrace; /* autoEQP is in trace mode */ | |
| 21297 u8 scanstatsOn; /* True to display scan stats before each finalize */ | |
| 21298 u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ | |
| 21299 u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ | |
| 21300 u8 nEqpLevel; /* Depth of the EQP output graph */ | |
| 21301 u8 eTraceType; /* SHELL_TRACE_* value for type of trace */ | |
| 21302 u8 bSafeMode; /* True to prohibit unsafe operations */ | |
| 21303 u8 bSafeModePersist; /* The long-term value of bSafeMode */ | |
| 21304 u8 eRestoreState; /* See comments above doAutoDetectRestore() */ | |
| 21305 u8 crlfMode; /* Do NL-to-CRLF translations when enabled (maybe) */ | |
| 21306 u8 eEscMode; /* Escape mode for text output */ | |
| 21307 ColModeOpts cmOpts; /* Option values affecting columnar mode output */ | |
| 21308 unsigned statsOn; /* True to display memory stats before each finalize */ | |
| 21309 unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */ | |
| 21310 int inputNesting; /* Track nesting level of .read and other redirects */ | |
| 21311 int outCount; /* Revert to stdout when reaching zero */ | |
| 21312 int cnt; /* Number of records displayed so far */ | |
| 21313 i64 lineno; /* Line number of last line read from in */ | |
| 21314 int openFlags; /* Additional flags to open. (SQLITE_OPEN_NOFOLLOW) */ | |
| 21315 FILE *in; /* Read commands from this stream */ | |
| 21316 FILE *out; /* Write results here */ | |
| 21317 FILE *traceOut; /* Output for sqlite3_trace() */ | |
| 21318 int nErr; /* Number of errors seen */ | |
| 21319 int mode; /* An output mode setting */ | |
| 21320 int modePrior; /* Saved mode */ | |
| 21321 int cMode; /* temporary output mode for the current query */ | |
| 21322 int normalMode; /* Output mode before ".explain on" */ | |
| 21323 int writableSchema; /* True if PRAGMA writable_schema=ON */ | |
| 21324 int showHeader; /* True to show column names in List or Column mode */ | |
| 21325 int nCheck; /* Number of ".check" commands run */ | |
| 21326 unsigned nProgress; /* Number of progress callbacks encountered */ | |
| 21327 unsigned mxProgress; /* Maximum progress callbacks before failing */ | |
| 21328 unsigned flgProgress; /* Flags for the progress callback */ | |
| 21329 unsigned shellFlgs; /* Various flags */ | |
| 21330 unsigned priorShFlgs; /* Saved copy of flags */ | |
| 21331 sqlite3_int64 szMax; /* --maxsize argument to .open */ | |
| 21332 char *zDestTable; /* Name of destination table when MODE_Insert */ | |
| 21333 char *zTempFile; /* Temporary file that might need deleting */ | |
| 21334 char zTestcase[30]; /* Name of current test case */ | |
| 21335 char colSeparator[20]; /* Column separator character for several modes */ | |
| 21336 char rowSeparator[20]; /* Row separator character for MODE_Ascii */ | |
| 21337 char colSepPrior[20]; /* Saved column separator */ | |
| 21338 char rowSepPrior[20]; /* Saved row separator */ | |
| 21339 int *colWidth; /* Requested width of each column in columnar modes */ | |
| 21340 int *actualWidth; /* Actual width of each column */ | |
| 21341 int nWidth; /* Number of slots in colWidth[] and actualWidth[] */ | |
| 21342 char nullValue[20]; /* The text to print when a NULL comes back from | |
| 21343 ** the database */ | |
| 21344 char outfile[FILENAME_MAX]; /* Filename for *out */ | |
| 21345 sqlite3_stmt *pStmt; /* Current statement if any. */ | |
| 21346 FILE *pLog; /* Write log output here */ | |
| 21347 struct AuxDb { /* Storage space for auxiliary database connections */ | |
| 21348 sqlite3 *db; /* Connection pointer */ | |
| 21349 const char *zDbFilename; /* Filename used to open the connection */ | |
| 21350 char *zFreeOnClose; /* Free this memory allocation on close */ | |
| 21351 #if defined(SQLITE_ENABLE_SESSION) | |
| 21352 int nSession; /* Number of active sessions */ | |
| 21353 OpenSession aSession[4]; /* Array of sessions. [0] is in focus. */ | |
| 21354 #endif | |
| 21355 } aAuxDb[5], /* Array of all database connections */ | |
| 21356 *pAuxDb; /* Currently active database connection */ | |
| 21357 int *aiIndent; /* Array of indents used in MODE_Explain */ | |
| 21358 int nIndent; /* Size of array aiIndent[] */ | |
| 21359 int iIndent; /* Index of current op in aiIndent[] */ | |
| 21360 char *zNonce; /* Nonce for temporary safe-mode escapes */ | |
| 21361 EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */ | |
| 21362 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 21363 ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ | |
| 21364 #endif | |
| 21365 #ifdef SQLITE_SHELL_FIDDLE | |
| 21366 struct { | |
| 21367 const char * zInput; /* Input string from wasm/JS proxy */ | |
| 21368 const char * zPos; /* Cursor pos into zInput */ | |
| 21369 const char * zDefaultDbName; /* Default name for db file */ | |
| 21370 } wasm; | |
| 21371 #endif | |
| 21372 }; | |
| 21373 | |
| 21374 #ifdef SQLITE_SHELL_FIDDLE | |
| 21375 static ShellState shellState; | |
| 21376 #endif | |
| 21377 | |
| 21378 | |
| 21379 /* Allowed values for ShellState.autoEQP | |
| 21380 */ | |
| 21381 #define AUTOEQP_off 0 /* Automatic EXPLAIN QUERY PLAN is off */ | |
| 21382 #define AUTOEQP_on 1 /* Automatic EQP is on */ | |
| 21383 #define AUTOEQP_trigger 2 /* On and also show plans for triggers */ | |
| 21384 #define AUTOEQP_full 3 /* Show full EXPLAIN */ | |
| 21385 | |
| 21386 /* Allowed values for ShellState.openMode | |
| 21387 */ | |
| 21388 #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ | |
| 21389 #define SHELL_OPEN_NORMAL 1 /* Normal database file */ | |
| 21390 #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ | |
| 21391 #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ | |
| 21392 #define SHELL_OPEN_DESERIALIZE 4 /* Open using sqlite3_deserialize() */ | |
| 21393 #define SHELL_OPEN_HEXDB 5 /* Use "dbtotxt" output as data source */ | |
| 21394 | |
| 21395 /* Allowed values for ShellState.eTraceType | |
| 21396 */ | |
| 21397 #define SHELL_TRACE_PLAIN 0 /* Show input SQL text */ | |
| 21398 #define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */ | |
| 21399 #define SHELL_TRACE_NORMALIZED 2 /* Show normalized SQL text */ | |
| 21400 | |
| 21401 /* Bits in the ShellState.flgProgress variable */ | |
| 21402 #define SHELL_PROGRESS_QUIET 0x01 /* Omit announcing every progress callback */ | |
| 21403 #define SHELL_PROGRESS_RESET 0x02 /* Reset the count when the progress | |
| 21404 ** callback limit is reached, and for each | |
| 21405 ** top-level SQL statement */ | |
| 21406 #define SHELL_PROGRESS_ONCE 0x04 /* Cancel the --limit after firing once */ | |
| 21407 | |
| 21408 /* Allowed values for ShellState.eEscMode. The default value should | |
| 21409 ** be 0, so to change the default, reorder the names. | |
| 21410 */ | |
| 21411 #define SHELL_ESC_ASCII 0 /* Substitute ^Y for X where Y=X+0x40 */ | |
| 21412 #define SHELL_ESC_SYMBOL 1 /* Substitute U+2400 graphics */ | |
| 21413 #define SHELL_ESC_OFF 2 /* Send characters verbatim */ | |
| 21414 | |
| 21415 static const char *shell_EscModeNames[] = { "ascii", "symbol", "off" }; | |
| 21416 | |
| 21417 /* | |
| 21418 ** These are the allowed shellFlgs values | |
| 21419 */ | |
| 21420 #define SHFLG_Pagecache 0x00000001 /* The --pagecache option is used */ | |
| 21421 #define SHFLG_Lookaside 0x00000002 /* Lookaside memory is used */ | |
| 21422 #define SHFLG_Backslash 0x00000004 /* The --backslash option is used */ | |
| 21423 #define SHFLG_PreserveRowid 0x00000008 /* .dump preserves rowid values */ | |
| 21424 #define SHFLG_Newlines 0x00000010 /* .dump --newline flag */ | |
| 21425 #define SHFLG_CountChanges 0x00000020 /* .changes setting */ | |
| 21426 #define SHFLG_Echo 0x00000040 /* .echo on/off, or --echo setting */ | |
| 21427 #define SHFLG_HeaderSet 0x00000080 /* showHeader has been specified */ | |
| 21428 #define SHFLG_DumpDataOnly 0x00000100 /* .dump show data only */ | |
| 21429 #define SHFLG_DumpNoSys 0x00000200 /* .dump omits system tables */ | |
| 21430 #define SHFLG_TestingMode 0x00000400 /* allow unsafe testing features */ | |
| 21431 | |
| 21432 /* | |
| 21433 ** Macros for testing and setting shellFlgs | |
| 21434 */ | |
| 21435 #define ShellHasFlag(P,X) (((P)->shellFlgs & (X))!=0) | |
| 21436 #define ShellSetFlag(P,X) ((P)->shellFlgs|=(X)) | |
| 21437 #define ShellClearFlag(P,X) ((P)->shellFlgs&=(~(X))) | |
| 21438 | |
| 21439 /* | |
| 21440 ** These are the allowed modes. | |
| 21441 */ | |
| 21442 #define MODE_Line 0 /* One column per line. Blank line between records */ | |
| 21443 #define MODE_Column 1 /* One record per line in neat columns */ | |
| 21444 #define MODE_List 2 /* One record per line with a separator */ | |
| 21445 #define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */ | |
| 21446 #define MODE_Html 4 /* Generate an XHTML table */ | |
| 21447 #define MODE_Insert 5 /* Generate SQL "insert" statements */ | |
| 21448 #define MODE_Quote 6 /* Quote values as for SQL */ | |
| 21449 #define MODE_Tcl 7 /* Generate ANSI-C or TCL quoted elements */ | |
| 21450 #define MODE_Csv 8 /* Quote strings, numbers are plain */ | |
| 21451 #define MODE_Explain 9 /* Like MODE_Column, but do not truncate data */ | |
| 21452 #define MODE_Ascii 10 /* Use ASCII unit and record separators (0x1F/0x1E) */ | |
| 21453 #define MODE_Pretty 11 /* Pretty-print schemas */ | |
| 21454 #define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */ | |
| 21455 #define MODE_Json 13 /* Output JSON */ | |
| 21456 #define MODE_Markdown 14 /* Markdown formatting */ | |
| 21457 #define MODE_Table 15 /* MySQL-style table formatting */ | |
| 21458 #define MODE_Box 16 /* Unicode box-drawing characters */ | |
| 21459 #define MODE_Count 17 /* Output only a count of the rows of output */ | |
| 21460 #define MODE_Off 18 /* No query output shown */ | |
| 21461 #define MODE_ScanExp 19 /* Like MODE_Explain, but for ".scanstats vm" */ | |
| 21462 #define MODE_Www 20 /* Full web-page output */ | |
| 21463 | |
| 21464 static const char *modeDescr[] = { | |
| 21465 "line", | |
| 21466 "column", | |
| 21467 "list", | |
| 21468 "semi", | |
| 21469 "html", | |
| 21470 "insert", | |
| 21471 "quote", | |
| 21472 "tcl", | |
| 21473 "csv", | |
| 21474 "explain", | |
| 21475 "ascii", | |
| 21476 "prettyprint", | |
| 21477 "eqp", | |
| 21478 "json", | |
| 21479 "markdown", | |
| 21480 "table", | |
| 21481 "box", | |
| 21482 "count", | |
| 21483 "off", | |
| 21484 "scanexp", | |
| 21485 "www", | |
| 21486 }; | |
| 21487 | |
| 21488 /* | |
| 21489 ** These are the column/row/line separators used by the various | |
| 21490 ** import/export modes. | |
| 21491 */ | |
| 21492 #define SEP_Column "|" | |
| 21493 #define SEP_Row "\n" | |
| 21494 #define SEP_Tab "\t" | |
| 21495 #define SEP_Space " " | |
| 21496 #define SEP_Comma "," | |
| 21497 #define SEP_CrLf "\r\n" | |
| 21498 #define SEP_Unit "\x1F" | |
| 21499 #define SEP_Record "\x1E" | |
| 21500 | |
| 21501 /* | |
| 21502 ** Limit input nesting via .read or any other input redirect. | |
| 21503 ** It's not too expensive, so a generous allowance can be made. | |
| 21504 */ | |
| 21505 #define MAX_INPUT_NESTING 25 | |
| 21506 | |
| 21507 /* | |
| 21508 ** A callback for the sqlite3_log() interface. | |
| 21509 */ | |
| 21510 static void shellLog(void *pArg, int iErrCode, const char *zMsg){ | |
| 21511 ShellState *p = (ShellState*)pArg; | |
| 21512 if( p->pLog==0 ) return; | |
| 21513 sqlite3_fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg); | |
| 21514 fflush(p->pLog); | |
| 21515 } | |
| 21516 | |
| 21517 /* | |
| 21518 ** SQL function: shell_putsnl(X) | |
| 21519 ** | |
| 21520 ** Write the text X to the screen (or whatever output is being directed) | |
| 21521 ** adding a newline at the end, and then return X. | |
| 21522 */ | |
| 21523 static void shellPutsFunc( | |
| 21524 sqlite3_context *pCtx, | |
| 21525 int nVal, | |
| 21526 sqlite3_value **apVal | |
| 21527 ){ | |
| 21528 ShellState *p = (ShellState*)sqlite3_user_data(pCtx); | |
| 21529 (void)nVal; | |
| 21530 sqlite3_fprintf(p->out, "%s\n", sqlite3_value_text(apVal[0])); | |
| 21531 sqlite3_result_value(pCtx, apVal[0]); | |
| 21532 } | |
| 21533 | |
| 21534 /* | |
| 21535 ** If in safe mode, print an error message described by the arguments | |
| 21536 ** and exit immediately. | |
| 21537 */ | |
| 21538 static void failIfSafeMode( | |
| 21539 ShellState *p, | |
| 21540 const char *zErrMsg, | |
| 21541 ... | |
| 21542 ){ | |
| 21543 if( p->bSafeMode ){ | |
| 21544 va_list ap; | |
| 21545 char *zMsg; | |
| 21546 va_start(ap, zErrMsg); | |
| 21547 zMsg = sqlite3_vmprintf(zErrMsg, ap); | |
| 21548 va_end(ap); | |
| 21549 sqlite3_fprintf(stderr, "line %lld: %s\n", p->lineno, zMsg); | |
| 21550 exit(1); | |
| 21551 } | |
| 21552 } | |
| 21553 | |
| 21554 /* | |
| 21555 ** SQL function: edit(VALUE) | |
| 21556 ** edit(VALUE,EDITOR) | |
| 21557 ** | |
| 21558 ** These steps: | |
| 21559 ** | |
| 21560 ** (1) Write VALUE into a temporary file. | |
| 21561 ** (2) Run program EDITOR on that temporary file. | |
| 21562 ** (3) Read the temporary file back and return its content as the result. | |
| 21563 ** (4) Delete the temporary file | |
| 21564 ** | |
| 21565 ** If the EDITOR argument is omitted, use the value in the VISUAL | |
| 21566 ** environment variable. If still there is no EDITOR, through an error. | |
| 21567 ** | |
| 21568 ** Also throw an error if the EDITOR program returns a non-zero exit code. | |
| 21569 */ | |
| 21570 #ifndef SQLITE_NOHAVE_SYSTEM | |
| 21571 static void editFunc( | |
| 21572 sqlite3_context *context, | |
| 21573 int argc, | |
| 21574 sqlite3_value **argv | |
| 21575 ){ | |
| 21576 const char *zEditor; | |
| 21577 char *zTempFile = 0; | |
| 21578 sqlite3 *db; | |
| 21579 char *zCmd = 0; | |
| 21580 int bBin; | |
| 21581 int rc; | |
| 21582 int hasCRLF = 0; | |
| 21583 FILE *f = 0; | |
| 21584 sqlite3_int64 sz; | |
| 21585 sqlite3_int64 x; | |
| 21586 unsigned char *p = 0; | |
| 21587 | |
| 21588 if( argc==2 ){ | |
| 21589 zEditor = (const char*)sqlite3_value_text(argv[1]); | |
| 21590 }else{ | |
| 21591 zEditor = getenv("VISUAL"); | |
| 21592 } | |
| 21593 if( zEditor==0 ){ | |
| 21594 sqlite3_result_error(context, "no editor for edit()", -1); | |
| 21595 return; | |
| 21596 } | |
| 21597 if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ | |
| 21598 sqlite3_result_error(context, "NULL input to edit()", -1); | |
| 21599 return; | |
| 21600 } | |
| 21601 db = sqlite3_context_db_handle(context); | |
| 21602 zTempFile = 0; | |
| 21603 sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile); | |
| 21604 if( zTempFile==0 ){ | |
| 21605 sqlite3_uint64 r = 0; | |
| 21606 sqlite3_randomness(sizeof(r), &r); | |
| 21607 zTempFile = sqlite3_mprintf("temp%llx", r); | |
| 21608 if( zTempFile==0 ){ | |
| 21609 sqlite3_result_error_nomem(context); | |
| 21610 return; | |
| 21611 } | |
| 21612 } | |
| 21613 bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB; | |
| 21614 /* When writing the file to be edited, do \n to \r\n conversions on systems | |
| 21615 ** that want \r\n line endings */ | |
| 21616 f = sqlite3_fopen(zTempFile, bBin ? "wb" : "w"); | |
| 21617 if( f==0 ){ | |
| 21618 sqlite3_result_error(context, "edit() cannot open temp file", -1); | |
| 21619 goto edit_func_end; | |
| 21620 } | |
| 21621 sz = sqlite3_value_bytes(argv[0]); | |
| 21622 if( bBin ){ | |
| 21623 x = fwrite(sqlite3_value_blob(argv[0]), 1, (size_t)sz, f); | |
| 21624 }else{ | |
| 21625 const char *z = (const char*)sqlite3_value_text(argv[0]); | |
| 21626 /* Remember whether or not the value originally contained \r\n */ | |
| 21627 if( z && strstr(z,"\r\n")!=0 ) hasCRLF = 1; | |
| 21628 x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f); | |
| 21629 } | |
| 21630 fclose(f); | |
| 21631 f = 0; | |
| 21632 if( x!=sz ){ | |
| 21633 sqlite3_result_error(context, "edit() could not write the whole file", -1); | |
| 21634 goto edit_func_end; | |
| 21635 } | |
| 21636 zCmd = sqlite3_mprintf("%s \"%s\"", zEditor, zTempFile); | |
| 21637 if( zCmd==0 ){ | |
| 21638 sqlite3_result_error_nomem(context); | |
| 21639 goto edit_func_end; | |
| 21640 } | |
| 21641 rc = system(zCmd); | |
| 21642 sqlite3_free(zCmd); | |
| 21643 if( rc ){ | |
| 21644 sqlite3_result_error(context, "EDITOR returned non-zero", -1); | |
| 21645 goto edit_func_end; | |
| 21646 } | |
| 21647 f = sqlite3_fopen(zTempFile, "rb"); | |
| 21648 if( f==0 ){ | |
| 21649 sqlite3_result_error(context, | |
| 21650 "edit() cannot reopen temp file after edit", -1); | |
| 21651 goto edit_func_end; | |
| 21652 } | |
| 21653 fseek(f, 0, SEEK_END); | |
| 21654 sz = ftell(f); | |
| 21655 rewind(f); | |
| 21656 p = sqlite3_malloc64( sz+1 ); | |
| 21657 if( p==0 ){ | |
| 21658 sqlite3_result_error_nomem(context); | |
| 21659 goto edit_func_end; | |
| 21660 } | |
| 21661 x = fread(p, 1, (size_t)sz, f); | |
| 21662 fclose(f); | |
| 21663 f = 0; | |
| 21664 if( x!=sz ){ | |
| 21665 sqlite3_result_error(context, "could not read back the whole file", -1); | |
| 21666 goto edit_func_end; | |
| 21667 } | |
| 21668 if( bBin ){ | |
| 21669 sqlite3_result_blob64(context, p, sz, sqlite3_free); | |
| 21670 }else{ | |
| 21671 sqlite3_int64 i, j; | |
| 21672 if( hasCRLF ){ | |
| 21673 /* If the original contains \r\n then do no conversions back to \n */ | |
| 21674 }else{ | |
| 21675 /* If the file did not originally contain \r\n then convert any new | |
| 21676 ** \r\n back into \n */ | |
| 21677 p[sz] = 0; | |
| 21678 for(i=j=0; i<sz; i++){ | |
| 21679 if( p[i]=='\r' && p[i+1]=='\n' ) i++; | |
| 21680 p[j++] = p[i]; | |
| 21681 } | |
| 21682 sz = j; | |
| 21683 p[sz] = 0; | |
| 21684 } | |
| 21685 sqlite3_result_text64(context, (const char*)p, sz, | |
| 21686 sqlite3_free, SQLITE_UTF8); | |
| 21687 } | |
| 21688 p = 0; | |
| 21689 | |
| 21690 edit_func_end: | |
| 21691 if( f ) fclose(f); | |
| 21692 unlink(zTempFile); | |
| 21693 sqlite3_free(zTempFile); | |
| 21694 sqlite3_free(p); | |
| 21695 } | |
| 21696 #endif /* SQLITE_NOHAVE_SYSTEM */ | |
| 21697 | |
| 21698 /* | |
| 21699 ** Save or restore the current output mode | |
| 21700 */ | |
| 21701 static void outputModePush(ShellState *p){ | |
| 21702 p->modePrior = p->mode; | |
| 21703 p->priorShFlgs = p->shellFlgs; | |
| 21704 memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator)); | |
| 21705 memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator)); | |
| 21706 } | |
| 21707 static void outputModePop(ShellState *p){ | |
| 21708 p->mode = p->modePrior; | |
| 21709 p->shellFlgs = p->priorShFlgs; | |
| 21710 memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator)); | |
| 21711 memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator)); | |
| 21712 } | |
| 21713 | |
| 21714 /* | |
| 21715 ** Set output mode to text or binary for Windows. | |
| 21716 */ | |
| 21717 static void setCrlfMode(ShellState *p){ | |
| 21718 #ifdef _WIN32 | |
| 21719 if( p->crlfMode ){ | |
| 21720 sqlite3_fsetmode(p->out, _O_TEXT); | |
| 21721 }else{ | |
| 21722 sqlite3_fsetmode(p->out, _O_BINARY); | |
| 21723 } | |
| 21724 #else | |
| 21725 UNUSED_PARAMETER(p); | |
| 21726 #endif | |
| 21727 } | |
| 21728 | |
| 21729 /* | |
| 21730 ** Output the given string as a hex-encoded blob (eg. X'1234' ) | |
| 21731 */ | |
| 21732 static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){ | |
| 21733 int i; | |
| 21734 unsigned char *aBlob = (unsigned char*)pBlob; | |
| 21735 | |
| 21736 char *zStr = sqlite3_malloc64((i64)nBlob*2 + 1); | |
| 21737 shell_check_oom(zStr); | |
| 21738 | |
| 21739 for(i=0; i<nBlob; i++){ | |
| 21740 static const char aHex[] = { | |
| 21741 '0', '1', '2', '3', '4', '5', '6', '7', | |
| 21742 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' | |
| 21743 }; | |
| 21744 zStr[i*2] = aHex[ (aBlob[i] >> 4) ]; | |
| 21745 zStr[i*2+1] = aHex[ (aBlob[i] & 0x0F) ]; | |
| 21746 } | |
| 21747 zStr[i*2] = '\0'; | |
| 21748 | |
| 21749 sqlite3_fprintf(out, "X'%s'", zStr); | |
| 21750 sqlite3_free(zStr); | |
| 21751 } | |
| 21752 | |
| 21753 /* | |
| 21754 ** Output the given string as a quoted string using SQL quoting conventions: | |
| 21755 ** | |
| 21756 ** (1) Single quotes (') within the string are doubled | |
| 21757 ** (2) The while string is enclosed in '...' | |
| 21758 ** (3) Control characters other than \n, \t, and \r\n are escaped | |
| 21759 ** using \u00XX notation and if such substitutions occur, | |
| 21760 ** the whole string is enclosed in unistr('...') instead of '...'. | |
| 21761 ** | |
| 21762 ** Step (3) is omitted if the control-character escape mode is OFF. | |
| 21763 ** | |
| 21764 ** See also: output_quoted_escaped_string() which does the same except | |
| 21765 ** that it does not make exceptions for \n, \t, and \r\n in step (3). | |
| 21766 */ | |
| 21767 static void output_quoted_string(ShellState *p, const char *zInX){ | |
| 21768 int i; | |
| 21769 int needUnistr = 0; | |
| 21770 int needDblQuote = 0; | |
| 21771 const unsigned char *z = (const unsigned char*)zInX; | |
| 21772 unsigned char c; | |
| 21773 FILE *out = p->out; | |
| 21774 sqlite3_fsetmode(out, _O_BINARY); | |
| 21775 if( z==0 ) return; | |
| 21776 for(i=0; (c = z[i])!=0; i++){ | |
| 21777 if( c=='\'' ){ needDblQuote = 1; } | |
| 21778 if( c>0x1f ) continue; | |
| 21779 if( c=='\t' || c=='\n' ) continue; | |
| 21780 if( c=='\r' && z[i+1]=='\n' ) continue; | |
| 21781 needUnistr = 1; | |
| 21782 break; | |
| 21783 } | |
| 21784 if( (needDblQuote==0 && needUnistr==0) | |
| 21785 || (needDblQuote==0 && p->eEscMode==SHELL_ESC_OFF) | |
| 21786 ){ | |
| 21787 sqlite3_fprintf(out, "'%s'",z); | |
| 21788 }else if( p->eEscMode==SHELL_ESC_OFF ){ | |
| 21789 char *zEncoded = sqlite3_mprintf("%Q", z); | |
| 21790 sqlite3_fputs(zEncoded, out); | |
| 21791 sqlite3_free(zEncoded); | |
| 21792 }else{ | |
| 21793 if( needUnistr ){ | |
| 21794 sqlite3_fputs("unistr('", out); | |
| 21795 }else{ | |
| 21796 sqlite3_fputs("'", out); | |
| 21797 } | |
| 21798 while( *z ){ | |
| 21799 for(i=0; (c = z[i])!=0; i++){ | |
| 21800 if( c=='\'' ) break; | |
| 21801 if( c>0x1f ) continue; | |
| 21802 if( c=='\t' || c=='\n' ) continue; | |
| 21803 if( c=='\r' && z[i+1]=='\n' ) continue; | |
| 21804 break; | |
| 21805 } | |
| 21806 if( i ){ | |
| 21807 sqlite3_fprintf(out, "%.*s", i, z); | |
| 21808 z += i; | |
| 21809 } | |
| 21810 if( c==0 ) break; | |
| 21811 if( c=='\'' ){ | |
| 21812 sqlite3_fputs("''", out); | |
| 21813 }else{ | |
| 21814 sqlite3_fprintf(out, "\\u%04x", c); | |
| 21815 } | |
| 21816 z++; | |
| 21817 } | |
| 21818 if( needUnistr ){ | |
| 21819 sqlite3_fputs("')", out); | |
| 21820 }else{ | |
| 21821 sqlite3_fputs("'", out); | |
| 21822 } | |
| 21823 } | |
| 21824 setCrlfMode(p); | |
| 21825 } | |
| 21826 | |
| 21827 /* | |
| 21828 ** Output the given string as a quoted string using SQL quoting conventions. | |
| 21829 ** Additionallly , escape the "\n" and "\r" characters so that they do not | |
| 21830 ** get corrupted by end-of-line translation facilities in some operating | |
| 21831 ** systems. | |
| 21832 ** | |
| 21833 ** This is like output_quoted_string() but with the addition of the \r\n | |
| 21834 ** escape mechanism. | |
| 21835 */ | |
| 21836 static void output_quoted_escaped_string(ShellState *p, const char *z){ | |
| 21837 char *zEscaped; | |
| 21838 sqlite3_fsetmode(p->out, _O_BINARY); | |
| 21839 if( p->eEscMode==SHELL_ESC_OFF ){ | |
| 21840 zEscaped = sqlite3_mprintf("%Q", z); | |
| 21841 }else{ | |
| 21842 zEscaped = sqlite3_mprintf("%#Q", z); | |
| 21843 } | |
| 21844 sqlite3_fputs(zEscaped, p->out); | |
| 21845 sqlite3_free(zEscaped); | |
| 21846 setCrlfMode(p); | |
| 21847 } | |
| 21848 | |
| 21849 /* | |
| 21850 ** Find earliest of chars within s specified in zAny. | |
| 21851 ** With ns == ~0, is like strpbrk(s,zAny) and s must be 0-terminated. | |
| 21852 */ | |
| 21853 static const char *anyOfInStr(const char *s, const char *zAny, size_t ns){ | |
| 21854 const char *pcFirst = 0; | |
| 21855 if( ns == ~(size_t)0 ) ns = strlen(s); | |
| 21856 while(*zAny){ | |
| 21857 const char *pc = (const char*)memchr(s, *zAny&0xff, ns); | |
| 21858 if( pc ){ | |
| 21859 pcFirst = pc; | |
| 21860 ns = pcFirst - s; | |
| 21861 } | |
| 21862 ++zAny; | |
| 21863 } | |
| 21864 return pcFirst; | |
| 21865 } | |
| 21866 | |
| 21867 /* Skip over as much z[] input char sequence as is valid UTF-8, | |
| 21868 ** limited per nAccept char's or whole characters and containing | |
| 21869 ** no char cn such that ((1<<cn) & ccm)!=0. On return, the | |
| 21870 ** sequence z:return (inclusive:exclusive) is validated UTF-8. | |
| 21871 ** Limit: nAccept>=0 => char count, nAccept<0 => character | |
| 21872 */ | |
| 21873 const char *zSkipValidUtf8(const char *z, int nAccept, long ccm){ | |
| 21874 int ng = (nAccept<0)? -nAccept : 0; | |
| 21875 const char *pcLimit = (nAccept>=0)? z+nAccept : 0; | |
| 21876 assert(z!=0); | |
| 21877 while( (pcLimit)? (z<pcLimit) : (ng-- != 0) ){ | |
| 21878 unsigned char c = *(u8*)z; | |
| 21879 if( c<0x7f ){ | |
| 21880 if( ccm != 0L && c < 0x20 && ((1L<<c) & ccm) != 0 ) return z; | |
| 21881 ++z; /* ASCII */ | |
| 21882 }else if( (c & 0xC0) != 0xC0 ) return z; /* not a lead byte */ | |
| 21883 else{ | |
| 21884 const char *zt = z+1; /* Got lead byte, look at trail bytes.*/ | |
| 21885 do{ | |
| 21886 if( pcLimit && zt >= pcLimit ) return z; | |
| 21887 else{ | |
| 21888 char ct = *zt++; | |
| 21889 if( ct==0 || (zt-z)>4 || (ct & 0xC0)!=0x80 ){ | |
| 21890 /* Trailing bytes are too few, too many, or invalid. */ | |
| 21891 return z; | |
| 21892 } | |
| 21893 } | |
| 21894 } while( ((c <<= 1) & 0x40) == 0x40 ); /* Eat lead byte's count. */ | |
| 21895 z = zt; | |
| 21896 } | |
| 21897 } | |
| 21898 return z; | |
| 21899 } | |
| 21900 | |
| 21901 | |
| 21902 /* | |
| 21903 ** Output the given string as a quoted according to C or TCL quoting rules. | |
| 21904 */ | |
| 21905 static void output_c_string(FILE *out, const char *z){ | |
| 21906 char c; | |
| 21907 static const char *zq = "\""; | |
| 21908 static long ctrlMask = ~0L; | |
| 21909 static const char *zDQBSRO = "\"\\\x7f"; /* double-quote, backslash, rubout */ | |
| 21910 char ace[3] = "\\?"; | |
| 21911 char cbsSay; | |
| 21912 sqlite3_fputs(zq, out); | |
| 21913 while( *z!=0 ){ | |
| 21914 const char *pcDQBSRO = anyOfInStr(z, zDQBSRO, ~(size_t)0); | |
| 21915 const char *pcPast = zSkipValidUtf8(z, INT_MAX, ctrlMask); | |
| 21916 const char *pcEnd = (pcDQBSRO && pcDQBSRO < pcPast)? pcDQBSRO : pcPast; | |
| 21917 if( pcEnd > z ){ | |
| 21918 sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z); | |
| 21919 } | |
| 21920 if( (c = *pcEnd)==0 ) break; | |
| 21921 ++pcEnd; | |
| 21922 switch( c ){ | |
| 21923 case '\\': case '"': | |
| 21924 cbsSay = (char)c; | |
| 21925 break; | |
| 21926 case '\t': cbsSay = 't'; break; | |
| 21927 case '\n': cbsSay = 'n'; break; | |
| 21928 case '\r': cbsSay = 'r'; break; | |
| 21929 case '\f': cbsSay = 'f'; break; | |
| 21930 default: cbsSay = 0; break; | |
| 21931 } | |
| 21932 if( cbsSay ){ | |
| 21933 ace[1] = cbsSay; | |
| 21934 sqlite3_fputs(ace, out); | |
| 21935 }else if( !isprint(c&0xff) ){ | |
| 21936 sqlite3_fprintf(out, "\\%03o", c&0xff); | |
| 21937 }else{ | |
| 21938 ace[1] = (char)c; | |
| 21939 sqlite3_fputs(ace+1, out); | |
| 21940 } | |
| 21941 z = pcEnd; | |
| 21942 } | |
| 21943 sqlite3_fputs(zq, out); | |
| 21944 } | |
| 21945 | |
| 21946 /* | |
| 21947 ** Output the given string as quoted according to JSON quoting rules. | |
| 21948 */ | |
| 21949 static void output_json_string(FILE *out, const char *z, i64 n){ | |
| 21950 unsigned char c; | |
| 21951 static const char *zq = "\""; | |
| 21952 static long ctrlMask = ~0L; | |
| 21953 static const char *zDQBS = "\"\\"; | |
| 21954 const char *pcLimit; | |
| 21955 char ace[3] = "\\?"; | |
| 21956 char cbsSay; | |
| 21957 | |
| 21958 if( z==0 ) z = ""; | |
| 21959 pcLimit = z + ((n<0)? strlen(z) : (size_t)n); | |
| 21960 sqlite3_fputs(zq, out); | |
| 21961 while( z < pcLimit ){ | |
| 21962 const char *pcDQBS = anyOfInStr(z, zDQBS, pcLimit-z); | |
| 21963 const char *pcPast = zSkipValidUtf8(z, (int)(pcLimit-z), ctrlMask); | |
| 21964 const char *pcEnd = (pcDQBS && pcDQBS < pcPast)? pcDQBS : pcPast; | |
| 21965 if( pcEnd > z ){ | |
| 21966 sqlite3_fprintf(out, "%.*s", (int)(pcEnd-z), z); | |
| 21967 z = pcEnd; | |
| 21968 } | |
| 21969 if( z >= pcLimit ) break; | |
| 21970 c = (unsigned char)*(z++); | |
| 21971 switch( c ){ | |
| 21972 case '"': case '\\': | |
| 21973 cbsSay = (char)c; | |
| 21974 break; | |
| 21975 case '\b': cbsSay = 'b'; break; | |
| 21976 case '\f': cbsSay = 'f'; break; | |
| 21977 case '\n': cbsSay = 'n'; break; | |
| 21978 case '\r': cbsSay = 'r'; break; | |
| 21979 case '\t': cbsSay = 't'; break; | |
| 21980 default: cbsSay = 0; break; | |
| 21981 } | |
| 21982 if( cbsSay ){ | |
| 21983 ace[1] = cbsSay; | |
| 21984 sqlite3_fputs(ace, out); | |
| 21985 }else if( c<=0x1f || c>=0x7f ){ | |
| 21986 sqlite3_fprintf(out, "\\u%04x", c); | |
| 21987 }else{ | |
| 21988 ace[1] = (char)c; | |
| 21989 sqlite3_fputs(ace+1, out); | |
| 21990 } | |
| 21991 } | |
| 21992 sqlite3_fputs(zq, out); | |
| 21993 } | |
| 21994 | |
| 21995 /* | |
| 21996 ** Escape the input string if it is needed and in accordance with | |
| 21997 ** eEscMode. | |
| 21998 ** | |
| 21999 ** Escaping is needed if the string contains any control characters | |
| 22000 ** other than \t, \n, and \r\n | |
| 22001 ** | |
| 22002 ** If no escaping is needed (the common case) then set *ppFree to NULL | |
| 22003 ** and return the original string. If escaping is needed, write the | |
| 22004 ** escaped string into memory obtained from sqlite3_malloc64() or the | |
| 22005 ** equivalent, and return the new string and set *ppFree to the new string | |
| 22006 ** as well. | |
| 22007 ** | |
| 22008 ** The caller is responsible for freeing *ppFree if it is non-NULL in order | |
| 22009 ** to reclaim memory. | |
| 22010 */ | |
| 22011 static const char *escapeOutput( | |
| 22012 ShellState *p, | |
| 22013 const char *zInX, | |
| 22014 char **ppFree | |
| 22015 ){ | |
| 22016 i64 i, j; | |
| 22017 i64 nCtrl = 0; | |
| 22018 unsigned char *zIn; | |
| 22019 unsigned char c; | |
| 22020 unsigned char *zOut; | |
| 22021 | |
| 22022 | |
| 22023 /* No escaping if disabled */ | |
| 22024 if( p->eEscMode==SHELL_ESC_OFF ){ | |
| 22025 *ppFree = 0; | |
| 22026 return zInX; | |
| 22027 } | |
| 22028 | |
| 22029 /* Count the number of control characters in the string. */ | |
| 22030 zIn = (unsigned char*)zInX; | |
| 22031 for(i=0; (c = zIn[i])!=0; i++){ | |
| 22032 if( c<=0x1f | |
| 22033 && c!='\t' | |
| 22034 && c!='\n' | |
| 22035 && (c!='\r' || zIn[i+1]!='\n') | |
| 22036 ){ | |
| 22037 nCtrl++; | |
| 22038 } | |
| 22039 } | |
| 22040 if( nCtrl==0 ){ | |
| 22041 *ppFree = 0; | |
| 22042 return zInX; | |
| 22043 } | |
| 22044 if( p->eEscMode==SHELL_ESC_SYMBOL ) nCtrl *= 2; | |
| 22045 zOut = sqlite3_malloc64( i + nCtrl + 1 ); | |
| 22046 shell_check_oom(zOut); | |
| 22047 for(i=j=0; (c = zIn[i])!=0; i++){ | |
| 22048 if( c>0x1f | |
| 22049 || c=='\t' | |
| 22050 || c=='\n' | |
| 22051 || (c=='\r' && zIn[i+1]=='\n') | |
| 22052 ){ | |
| 22053 continue; | |
| 22054 } | |
| 22055 if( i>0 ){ | |
| 22056 memcpy(&zOut[j], zIn, i); | |
| 22057 j += i; | |
| 22058 } | |
| 22059 zIn += i+1; | |
| 22060 i = -1; | |
| 22061 switch( p->eEscMode ){ | |
| 22062 case SHELL_ESC_SYMBOL: | |
| 22063 zOut[j++] = 0xe2; | |
| 22064 zOut[j++] = 0x90; | |
| 22065 zOut[j++] = 0x80+c; | |
| 22066 break; | |
| 22067 case SHELL_ESC_ASCII: | |
| 22068 zOut[j++] = '^'; | |
| 22069 zOut[j++] = 0x40+c; | |
| 22070 break; | |
| 22071 } | |
| 22072 } | |
| 22073 if( i>0 ){ | |
| 22074 memcpy(&zOut[j], zIn, i); | |
| 22075 j += i; | |
| 22076 } | |
| 22077 zOut[j] = 0; | |
| 22078 *ppFree = (char*)zOut; | |
| 22079 return (char*)zOut; | |
| 22080 } | |
| 22081 | |
| 22082 /* | |
| 22083 ** Output the given string with characters that are special to | |
| 22084 ** HTML escaped. | |
| 22085 */ | |
| 22086 static void output_html_string(FILE *out, const char *z){ | |
| 22087 int i; | |
| 22088 if( z==0 ) z = ""; | |
| 22089 while( *z ){ | |
| 22090 for(i=0; z[i] | |
| 22091 && z[i]!='<' | |
| 22092 && z[i]!='&' | |
| 22093 && z[i]!='>' | |
| 22094 && z[i]!='\"' | |
| 22095 && z[i]!='\''; | |
| 22096 i++){} | |
| 22097 if( i>0 ){ | |
| 22098 sqlite3_fprintf(out, "%.*s",i,z); | |
| 22099 } | |
| 22100 if( z[i]=='<' ){ | |
| 22101 sqlite3_fputs("<", out); | |
| 22102 }else if( z[i]=='&' ){ | |
| 22103 sqlite3_fputs("&", out); | |
| 22104 }else if( z[i]=='>' ){ | |
| 22105 sqlite3_fputs(">", out); | |
| 22106 }else if( z[i]=='\"' ){ | |
| 22107 sqlite3_fputs(""", out); | |
| 22108 }else if( z[i]=='\'' ){ | |
| 22109 sqlite3_fputs("'", out); | |
| 22110 }else{ | |
| 22111 break; | |
| 22112 } | |
| 22113 z += i + 1; | |
| 22114 } | |
| 22115 } | |
| 22116 | |
| 22117 /* | |
| 22118 ** If a field contains any character identified by a 1 in the following | |
| 22119 ** array, then the string must be quoted for CSV. | |
| 22120 */ | |
| 22121 static const char needCsvQuote[] = { | |
| 22122 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 22123 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 22124 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 22125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 22126 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 22127 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 22128 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 22129 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, | |
| 22130 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 22131 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 22132 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 22133 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 22134 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 22135 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 22136 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 22137 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | |
| 22138 }; | |
| 22139 | |
| 22140 /* | |
| 22141 ** Output a single term of CSV. Actually, p->colSeparator is used for | |
| 22142 ** the separator, which may or may not be a comma. p->nullValue is | |
| 22143 ** the null value. Strings are quoted if necessary. The separator | |
| 22144 ** is only issued if bSep is true. | |
| 22145 */ | |
| 22146 static void output_csv(ShellState *p, const char *z, int bSep){ | |
| 22147 if( z==0 ){ | |
| 22148 sqlite3_fprintf(p->out, "%s",p->nullValue); | |
| 22149 }else{ | |
| 22150 unsigned i; | |
| 22151 for(i=0; z[i]; i++){ | |
| 22152 if( needCsvQuote[((unsigned char*)z)[i]] ){ | |
| 22153 i = 0; | |
| 22154 break; | |
| 22155 } | |
| 22156 } | |
| 22157 if( i==0 || strstr(z, p->colSeparator)!=0 ){ | |
| 22158 char *zQuoted = sqlite3_mprintf("\"%w\"", z); | |
| 22159 shell_check_oom(zQuoted); | |
| 22160 sqlite3_fputs(zQuoted, p->out); | |
| 22161 sqlite3_free(zQuoted); | |
| 22162 }else{ | |
| 22163 sqlite3_fputs(z, p->out); | |
| 22164 } | |
| 22165 } | |
| 22166 if( bSep ){ | |
| 22167 sqlite3_fputs(p->colSeparator, p->out); | |
| 22168 } | |
| 22169 } | |
| 22170 | |
| 22171 /* | |
| 22172 ** This routine runs when the user presses Ctrl-C | |
| 22173 */ | |
| 22174 static void interrupt_handler(int NotUsed){ | |
| 22175 UNUSED_PARAMETER(NotUsed); | |
| 22176 if( ++seenInterrupt>1 ) exit(1); | |
| 22177 if( globalDb ) sqlite3_interrupt(globalDb); | |
| 22178 } | |
| 22179 | |
| 22180 #if (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) | |
| 22181 /* | |
| 22182 ** This routine runs for console events (e.g. Ctrl-C) on Win32 | |
| 22183 */ | |
| 22184 static BOOL WINAPI ConsoleCtrlHandler( | |
| 22185 DWORD dwCtrlType /* One of the CTRL_*_EVENT constants */ | |
| 22186 ){ | |
| 22187 if( dwCtrlType==CTRL_C_EVENT ){ | |
| 22188 interrupt_handler(0); | |
| 22189 return TRUE; | |
| 22190 } | |
| 22191 return FALSE; | |
| 22192 } | |
| 22193 #endif | |
| 22194 | |
| 22195 #ifndef SQLITE_OMIT_AUTHORIZATION | |
| 22196 /* | |
| 22197 ** This authorizer runs in safe mode. | |
| 22198 */ | |
| 22199 static int safeModeAuth( | |
| 22200 void *pClientData, | |
| 22201 int op, | |
| 22202 const char *zA1, | |
| 22203 const char *zA2, | |
| 22204 const char *zA3, | |
| 22205 const char *zA4 | |
| 22206 ){ | |
| 22207 ShellState *p = (ShellState*)pClientData; | |
| 22208 static const char *azProhibitedFunctions[] = { | |
| 22209 "edit", | |
| 22210 "fts3_tokenizer", | |
| 22211 "load_extension", | |
| 22212 "readfile", | |
| 22213 "writefile", | |
| 22214 "zipfile", | |
| 22215 "zipfile_cds", | |
| 22216 }; | |
| 22217 UNUSED_PARAMETER(zA1); | |
| 22218 UNUSED_PARAMETER(zA3); | |
| 22219 UNUSED_PARAMETER(zA4); | |
| 22220 switch( op ){ | |
| 22221 case SQLITE_ATTACH: { | |
| 22222 #ifndef SQLITE_SHELL_FIDDLE | |
| 22223 /* In WASM builds the filesystem is a virtual sandbox, so | |
| 22224 ** there's no harm in using ATTACH. */ | |
| 22225 failIfSafeMode(p, "cannot run ATTACH in safe mode"); | |
| 22226 #endif | |
| 22227 break; | |
| 22228 } | |
| 22229 case SQLITE_FUNCTION: { | |
| 22230 int i; | |
| 22231 for(i=0; i<ArraySize(azProhibitedFunctions); i++){ | |
| 22232 if( sqlite3_stricmp(zA2, azProhibitedFunctions[i])==0 ){ | |
| 22233 failIfSafeMode(p, "cannot use the %s() function in safe mode", | |
| 22234 azProhibitedFunctions[i]); | |
| 22235 } | |
| 22236 } | |
| 22237 break; | |
| 22238 } | |
| 22239 } | |
| 22240 return SQLITE_OK; | |
| 22241 } | |
| 22242 | |
| 22243 /* | |
| 22244 ** When the ".auth ON" is set, the following authorizer callback is | |
| 22245 ** invoked. It always returns SQLITE_OK. | |
| 22246 */ | |
| 22247 static int shellAuth( | |
| 22248 void *pClientData, | |
| 22249 int op, | |
| 22250 const char *zA1, | |
| 22251 const char *zA2, | |
| 22252 const char *zA3, | |
| 22253 const char *zA4 | |
| 22254 ){ | |
| 22255 ShellState *p = (ShellState*)pClientData; | |
| 22256 static const char *azAction[] = { 0, | |
| 22257 "CREATE_INDEX", "CREATE_TABLE", "CREATE_TEMP_INDEX", | |
| 22258 "CREATE_TEMP_TABLE", "CREATE_TEMP_TRIGGER", "CREATE_TEMP_VIEW", | |
| 22259 "CREATE_TRIGGER", "CREATE_VIEW", "DELETE", | |
| 22260 "DROP_INDEX", "DROP_TABLE", "DROP_TEMP_INDEX", | |
| 22261 "DROP_TEMP_TABLE", "DROP_TEMP_TRIGGER", "DROP_TEMP_VIEW", | |
| 22262 "DROP_TRIGGER", "DROP_VIEW", "INSERT", | |
| 22263 "PRAGMA", "READ", "SELECT", | |
| 22264 "TRANSACTION", "UPDATE", "ATTACH", | |
| 22265 "DETACH", "ALTER_TABLE", "REINDEX", | |
| 22266 "ANALYZE", "CREATE_VTABLE", "DROP_VTABLE", | |
| 22267 "FUNCTION", "SAVEPOINT", "RECURSIVE" | |
| 22268 }; | |
| 22269 int i; | |
| 22270 const char *az[4]; | |
| 22271 az[0] = zA1; | |
| 22272 az[1] = zA2; | |
| 22273 az[2] = zA3; | |
| 22274 az[3] = zA4; | |
| 22275 sqlite3_fprintf(p->out, "authorizer: %s", azAction[op]); | |
| 22276 for(i=0; i<4; i++){ | |
| 22277 sqlite3_fputs(" ", p->out); | |
| 22278 if( az[i] ){ | |
| 22279 output_c_string(p->out, az[i]); | |
| 22280 }else{ | |
| 22281 sqlite3_fputs("NULL", p->out); | |
| 22282 } | |
| 22283 } | |
| 22284 sqlite3_fputs("\n", p->out); | |
| 22285 if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4); | |
| 22286 return SQLITE_OK; | |
| 22287 } | |
| 22288 #endif | |
| 22289 | |
| 22290 /* | |
| 22291 ** Print a schema statement. Part of MODE_Semi and MODE_Pretty output. | |
| 22292 ** | |
| 22293 ** This routine converts some CREATE TABLE statements for shadow tables | |
| 22294 ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements. | |
| 22295 ** | |
| 22296 ** If the schema statement in z[] contains a start-of-comment and if | |
| 22297 ** sqlite3_complete() returns false, try to terminate the comment before | |
| 22298 ** printing the result. https://sqlite.org/forum/forumpost/d7be961c5c | |
| 22299 */ | |
| 22300 static void printSchemaLine(FILE *out, const char *z, const char *zTail){ | |
| 22301 char *zToFree = 0; | |
| 22302 if( z==0 ) return; | |
| 22303 if( zTail==0 ) return; | |
| 22304 if( zTail[0]==';' && (strstr(z, "/*")!=0 || strstr(z,"--")!=0) ){ | |
| 22305 const char *zOrig = z; | |
| 22306 static const char *azTerm[] = { "", "*/", "\n" }; | |
| 22307 int i; | |
| 22308 for(i=0; i<ArraySize(azTerm); i++){ | |
| 22309 char *zNew = sqlite3_mprintf("%s%s;", zOrig, azTerm[i]); | |
| 22310 shell_check_oom(zNew); | |
| 22311 if( sqlite3_complete(zNew) ){ | |
| 22312 size_t n = strlen(zNew); | |
| 22313 zNew[n-1] = 0; | |
| 22314 zToFree = zNew; | |
| 22315 z = zNew; | |
| 22316 break; | |
| 22317 } | |
| 22318 sqlite3_free(zNew); | |
| 22319 } | |
| 22320 } | |
| 22321 if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){ | |
| 22322 sqlite3_fprintf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); | |
| 22323 }else{ | |
| 22324 sqlite3_fprintf(out, "%s%s", z, zTail); | |
| 22325 } | |
| 22326 sqlite3_free(zToFree); | |
| 22327 } | |
| 22328 static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){ | |
| 22329 char c = z[n]; | |
| 22330 z[n] = 0; | |
| 22331 printSchemaLine(out, z, zTail); | |
| 22332 z[n] = c; | |
| 22333 } | |
| 22334 | |
| 22335 /* | |
| 22336 ** Return true if string z[] has nothing but whitespace and comments to the | |
| 22337 ** end of the first line. | |
| 22338 */ | |
| 22339 static int wsToEol(const char *z){ | |
| 22340 int i; | |
| 22341 for(i=0; z[i]; i++){ | |
| 22342 if( z[i]=='\n' ) return 1; | |
| 22343 if( IsSpace(z[i]) ) continue; | |
| 22344 if( z[i]=='-' && z[i+1]=='-' ) return 1; | |
| 22345 return 0; | |
| 22346 } | |
| 22347 return 1; | |
| 22348 } | |
| 22349 | |
| 22350 /* | |
| 22351 ** Add a new entry to the EXPLAIN QUERY PLAN data | |
| 22352 */ | |
| 22353 static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){ | |
| 22354 EQPGraphRow *pNew; | |
| 22355 i64 nText; | |
| 22356 if( zText==0 ) return; | |
| 22357 nText = strlen(zText); | |
| 22358 if( p->autoEQPtest ){ | |
| 22359 sqlite3_fprintf(p->out, "%d,%d,%s\n", iEqpId, p2, zText); | |
| 22360 } | |
| 22361 pNew = sqlite3_malloc64( sizeof(*pNew) + nText ); | |
| 22362 shell_check_oom(pNew); | |
| 22363 pNew->iEqpId = iEqpId; | |
| 22364 pNew->iParentId = p2; | |
| 22365 memcpy(pNew->zText, zText, nText+1); | |
| 22366 pNew->pNext = 0; | |
| 22367 if( p->sGraph.pLast ){ | |
| 22368 p->sGraph.pLast->pNext = pNew; | |
| 22369 }else{ | |
| 22370 p->sGraph.pRow = pNew; | |
| 22371 } | |
| 22372 p->sGraph.pLast = pNew; | |
| 22373 } | |
| 22374 | |
| 22375 /* | |
| 22376 ** Free and reset the EXPLAIN QUERY PLAN data that has been collected | |
| 22377 ** in p->sGraph. | |
| 22378 */ | |
| 22379 static void eqp_reset(ShellState *p){ | |
| 22380 EQPGraphRow *pRow, *pNext; | |
| 22381 for(pRow = p->sGraph.pRow; pRow; pRow = pNext){ | |
| 22382 pNext = pRow->pNext; | |
| 22383 sqlite3_free(pRow); | |
| 22384 } | |
| 22385 memset(&p->sGraph, 0, sizeof(p->sGraph)); | |
| 22386 } | |
| 22387 | |
| 22388 /* Return the next EXPLAIN QUERY PLAN line with iEqpId that occurs after | |
| 22389 ** pOld, or return the first such line if pOld is NULL | |
| 22390 */ | |
| 22391 static EQPGraphRow *eqp_next_row(ShellState *p, int iEqpId, EQPGraphRow *pOld){ | |
| 22392 EQPGraphRow *pRow = pOld ? pOld->pNext : p->sGraph.pRow; | |
| 22393 while( pRow && pRow->iParentId!=iEqpId ) pRow = pRow->pNext; | |
| 22394 return pRow; | |
| 22395 } | |
| 22396 | |
| 22397 /* Render a single level of the graph that has iEqpId as its parent. Called | |
| 22398 ** recursively to render sublevels. | |
| 22399 */ | |
| 22400 static void eqp_render_level(ShellState *p, int iEqpId){ | |
| 22401 EQPGraphRow *pRow, *pNext; | |
| 22402 i64 n = strlen(p->sGraph.zPrefix); | |
| 22403 char *z; | |
| 22404 for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){ | |
| 22405 pNext = eqp_next_row(p, iEqpId, pRow); | |
| 22406 z = pRow->zText; | |
| 22407 sqlite3_fprintf(p->out, "%s%s%s\n", p->sGraph.zPrefix, | |
| 22408 pNext ? "|--" : "`--", z); | |
| 22409 if( n<(i64)sizeof(p->sGraph.zPrefix)-7 ){ | |
| 22410 memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4); | |
| 22411 eqp_render_level(p, pRow->iEqpId); | |
| 22412 p->sGraph.zPrefix[n] = 0; | |
| 22413 } | |
| 22414 } | |
| 22415 } | |
| 22416 | |
| 22417 /* | |
| 22418 ** Display and reset the EXPLAIN QUERY PLAN data | |
| 22419 */ | |
| 22420 static void eqp_render(ShellState *p, i64 nCycle){ | |
| 22421 EQPGraphRow *pRow = p->sGraph.pRow; | |
| 22422 if( pRow ){ | |
| 22423 if( pRow->zText[0]=='-' ){ | |
| 22424 if( pRow->pNext==0 ){ | |
| 22425 eqp_reset(p); | |
| 22426 return; | |
| 22427 } | |
| 22428 sqlite3_fprintf(p->out, "%s\n", pRow->zText+3); | |
| 22429 p->sGraph.pRow = pRow->pNext; | |
| 22430 sqlite3_free(pRow); | |
| 22431 }else if( nCycle>0 ){ | |
| 22432 sqlite3_fprintf(p->out, "QUERY PLAN (cycles=%lld [100%%])\n", nCycle); | |
| 22433 }else{ | |
| 22434 sqlite3_fputs("QUERY PLAN\n", p->out); | |
| 22435 } | |
| 22436 p->sGraph.zPrefix[0] = 0; | |
| 22437 eqp_render_level(p, 0); | |
| 22438 eqp_reset(p); | |
| 22439 } | |
| 22440 } | |
| 22441 | |
| 22442 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | |
| 22443 /* | |
| 22444 ** Progress handler callback. | |
| 22445 */ | |
| 22446 static int progress_handler(void *pClientData) { | |
| 22447 ShellState *p = (ShellState*)pClientData; | |
| 22448 p->nProgress++; | |
| 22449 if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){ | |
| 22450 sqlite3_fprintf(p->out, "Progress limit reached (%u)\n", p->nProgress); | |
| 22451 if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0; | |
| 22452 if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0; | |
| 22453 return 1; | |
| 22454 } | |
| 22455 if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){ | |
| 22456 sqlite3_fprintf(p->out, "Progress %u\n", p->nProgress); | |
| 22457 } | |
| 22458 return 0; | |
| 22459 } | |
| 22460 #endif /* SQLITE_OMIT_PROGRESS_CALLBACK */ | |
| 22461 | |
| 22462 /* | |
| 22463 ** Print N dashes | |
| 22464 */ | |
| 22465 static void print_dashes(FILE *out, int N){ | |
| 22466 const char zDash[] = "--------------------------------------------------"; | |
| 22467 const int nDash = sizeof(zDash) - 1; | |
| 22468 while( N>nDash ){ | |
| 22469 sqlite3_fputs(zDash, out); | |
| 22470 N -= nDash; | |
| 22471 } | |
| 22472 sqlite3_fprintf(out, "%.*s", N, zDash); | |
| 22473 } | |
| 22474 | |
| 22475 /* | |
| 22476 ** Print a markdown or table-style row separator using ascii-art | |
| 22477 */ | |
| 22478 static void print_row_separator( | |
| 22479 ShellState *p, | |
| 22480 int nArg, | |
| 22481 const char *zSep | |
| 22482 ){ | |
| 22483 int i; | |
| 22484 if( nArg>0 ){ | |
| 22485 sqlite3_fputs(zSep, p->out); | |
| 22486 print_dashes(p->out, p->actualWidth[0]+2); | |
| 22487 for(i=1; i<nArg; i++){ | |
| 22488 sqlite3_fputs(zSep, p->out); | |
| 22489 print_dashes(p->out, p->actualWidth[i]+2); | |
| 22490 } | |
| 22491 sqlite3_fputs(zSep, p->out); | |
| 22492 } | |
| 22493 sqlite3_fputs("\n", p->out); | |
| 22494 } | |
| 22495 | |
| 22496 /* | |
| 22497 ** This is the callback routine that the shell | |
| 22498 ** invokes for each row of a query result. | |
| 22499 */ | |
| 22500 static int shell_callback( | |
| 22501 void *pArg, | |
| 22502 int nArg, /* Number of result columns */ | |
| 22503 char **azArg, /* Text of each result column */ | |
| 22504 char **azCol, /* Column names */ | |
| 22505 int *aiType /* Column types. Might be NULL */ | |
| 22506 ){ | |
| 22507 int i; | |
| 22508 ShellState *p = (ShellState*)pArg; | |
| 22509 | |
| 22510 if( azArg==0 ) return 0; | |
| 22511 switch( p->cMode ){ | |
| 22512 case MODE_Count: | |
| 22513 case MODE_Off: { | |
| 22514 break; | |
| 22515 } | |
| 22516 case MODE_Line: { | |
| 22517 int w = 5; | |
| 22518 if( azArg==0 ) break; | |
| 22519 for(i=0; i<nArg; i++){ | |
| 22520 int len = strlen30(azCol[i] ? azCol[i] : ""); | |
| 22521 if( len>w ) w = len; | |
| 22522 } | |
| 22523 if( p->cnt++>0 ) sqlite3_fputs(p->rowSeparator, p->out); | |
| 22524 for(i=0; i<nArg; i++){ | |
| 22525 char *pFree = 0; | |
| 22526 const char *pDisplay; | |
| 22527 pDisplay = escapeOutput(p, azArg[i] ? azArg[i] : p->nullValue, &pFree); | |
| 22528 sqlite3_fprintf(p->out, "%*s = %s%s", w, azCol[i], | |
| 22529 pDisplay, p->rowSeparator); | |
| 22530 if( pFree ) sqlite3_free(pFree); | |
| 22531 } | |
| 22532 break; | |
| 22533 } | |
| 22534 case MODE_ScanExp: | |
| 22535 case MODE_Explain: { | |
| 22536 static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13}; | |
| 22537 static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 }; | |
| 22538 static const int aScanExpWidth[] = {4, 15, 6, 13, 4, 4, 4, 13, 2, 13}; | |
| 22539 static const int aScanExpMap[] = {0, 9, 8, 1, 2, 3, 4, 5, 6, 7 }; | |
| 22540 | |
| 22541 const int *aWidth = aExplainWidth; | |
| 22542 const int *aMap = aExplainMap; | |
| 22543 int nWidth = ArraySize(aExplainWidth); | |
| 22544 int iIndent = 1; | |
| 22545 | |
| 22546 if( p->cMode==MODE_ScanExp ){ | |
| 22547 aWidth = aScanExpWidth; | |
| 22548 aMap = aScanExpMap; | |
| 22549 nWidth = ArraySize(aScanExpWidth); | |
| 22550 iIndent = 3; | |
| 22551 } | |
| 22552 if( nArg>nWidth ) nArg = nWidth; | |
| 22553 | |
| 22554 /* If this is the first row seen, print out the headers */ | |
| 22555 if( p->cnt++==0 ){ | |
| 22556 for(i=0; i<nArg; i++){ | |
| 22557 utf8_width_print(p->out, aWidth[i], azCol[ aMap[i] ]); | |
| 22558 sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out); | |
| 22559 } | |
| 22560 for(i=0; i<nArg; i++){ | |
| 22561 print_dashes(p->out, aWidth[i]); | |
| 22562 sqlite3_fputs(i==nArg-1 ? "\n" : " ", p->out); | |
| 22563 } | |
| 22564 } | |
| 22565 | |
| 22566 /* If there is no data, exit early. */ | |
| 22567 if( azArg==0 ) break; | |
| 22568 | |
| 22569 for(i=0; i<nArg; i++){ | |
| 22570 const char *zSep = " "; | |
| 22571 int w = aWidth[i]; | |
| 22572 const char *zVal = azArg[ aMap[i] ]; | |
| 22573 if( i==nArg-1 ) w = 0; | |
| 22574 if( zVal && strlenChar(zVal)>w ){ | |
| 22575 w = strlenChar(zVal); | |
| 22576 zSep = " "; | |
| 22577 } | |
| 22578 if( i==iIndent && p->aiIndent && p->pStmt ){ | |
| 22579 if( p->iIndent<p->nIndent ){ | |
| 22580 sqlite3_fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); | |
| 22581 } | |
| 22582 p->iIndent++; | |
| 22583 } | |
| 22584 utf8_width_print(p->out, w, zVal ? zVal : p->nullValue); | |
| 22585 sqlite3_fputs(i==nArg-1 ? "\n" : zSep, p->out); | |
| 22586 } | |
| 22587 break; | |
| 22588 } | |
| 22589 case MODE_Semi: { /* .schema and .fullschema output */ | |
| 22590 printSchemaLine(p->out, azArg[0], ";\n"); | |
| 22591 break; | |
| 22592 } | |
| 22593 case MODE_Pretty: { /* .schema and .fullschema with --indent */ | |
| 22594 char *z; | |
| 22595 int j; | |
| 22596 int nParen = 0; | |
| 22597 char cEnd = 0; | |
| 22598 char c; | |
| 22599 int nLine = 0; | |
| 22600 int isIndex; | |
| 22601 int isWhere = 0; | |
| 22602 assert( nArg==1 ); | |
| 22603 if( azArg[0]==0 ) break; | |
| 22604 if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0 | |
| 22605 || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0 | |
| 22606 ){ | |
| 22607 sqlite3_fprintf(p->out, "%s;\n", azArg[0]); | |
| 22608 break; | |
| 22609 } | |
| 22610 isIndex = sqlite3_strlike("CREATE INDEX%", azArg[0], 0)==0 | |
| 22611 || sqlite3_strlike("CREATE UNIQUE INDEX%", azArg[0], 0)==0; | |
| 22612 z = sqlite3_mprintf("%s", azArg[0]); | |
| 22613 shell_check_oom(z); | |
| 22614 j = 0; | |
| 22615 for(i=0; IsSpace(z[i]); i++){} | |
| 22616 for(; (c = z[i])!=0; i++){ | |
| 22617 if( IsSpace(c) ){ | |
| 22618 if( z[j-1]=='\r' ) z[j-1] = '\n'; | |
| 22619 if( IsSpace(z[j-1]) || z[j-1]=='(' ) continue; | |
| 22620 }else if( (c=='(' || c==')') && j>0 && IsSpace(z[j-1]) ){ | |
| 22621 j--; | |
| 22622 } | |
| 22623 z[j++] = c; | |
| 22624 } | |
| 22625 while( j>0 && IsSpace(z[j-1]) ){ j--; } | |
| 22626 z[j] = 0; | |
| 22627 if( strlen30(z)>=79 ){ | |
| 22628 for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */ | |
| 22629 if( c==cEnd ){ | |
| 22630 cEnd = 0; | |
| 22631 }else if( c=='"' || c=='\'' || c=='`' ){ | |
| 22632 cEnd = c; | |
| 22633 }else if( c=='[' ){ | |
| 22634 cEnd = ']'; | |
| 22635 }else if( c=='-' && z[i+1]=='-' ){ | |
| 22636 cEnd = '\n'; | |
| 22637 }else if( c=='(' ){ | |
| 22638 nParen++; | |
| 22639 }else if( c==')' ){ | |
| 22640 nParen--; | |
| 22641 if( nLine>0 && nParen==0 && j>0 && !isWhere ){ | |
| 22642 printSchemaLineN(p->out, z, j, "\n"); | |
| 22643 j = 0; | |
| 22644 } | |
| 22645 }else if( (c=='w' || c=='W') | |
| 22646 && nParen==0 && isIndex | |
| 22647 && sqlite3_strnicmp("WHERE",&z[i],5)==0 | |
| 22648 && !IsAlnum(z[i+5]) && z[i+5]!='_' ){ | |
| 22649 isWhere = 1; | |
| 22650 }else if( isWhere && (c=='A' || c=='a') | |
| 22651 && nParen==0 | |
| 22652 && sqlite3_strnicmp("AND",&z[i],3)==0 | |
| 22653 && !IsAlnum(z[i+3]) && z[i+3]!='_' ){ | |
| 22654 printSchemaLineN(p->out, z, j, "\n "); | |
| 22655 j = 0; | |
| 22656 } | |
| 22657 z[j++] = c; | |
| 22658 if( nParen==1 && cEnd==0 | |
| 22659 && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1))) | |
| 22660 && !isWhere | |
| 22661 ){ | |
| 22662 if( c=='\n' ) j--; | |
| 22663 printSchemaLineN(p->out, z, j, "\n "); | |
| 22664 j = 0; | |
| 22665 nLine++; | |
| 22666 while( IsSpace(z[i+1]) ){ i++; } | |
| 22667 } | |
| 22668 } | |
| 22669 z[j] = 0; | |
| 22670 } | |
| 22671 printSchemaLine(p->out, z, ";\n"); | |
| 22672 sqlite3_free(z); | |
| 22673 break; | |
| 22674 } | |
| 22675 case MODE_List: { | |
| 22676 if( p->cnt++==0 && p->showHeader ){ | |
| 22677 for(i=0; i<nArg; i++){ | |
| 22678 char *z = azCol[i]; | |
| 22679 char *pFree; | |
| 22680 const char *zOut = escapeOutput(p, z, &pFree); | |
| 22681 sqlite3_fprintf(p->out, "%s%s", zOut, | |
| 22682 i==nArg-1 ? p->rowSeparator : p->colSeparator); | |
| 22683 if( pFree ) sqlite3_free(pFree); | |
| 22684 } | |
| 22685 } | |
| 22686 if( azArg==0 ) break; | |
| 22687 for(i=0; i<nArg; i++){ | |
| 22688 char *z = azArg[i]; | |
| 22689 char *pFree; | |
| 22690 const char *zOut; | |
| 22691 if( z==0 ) z = p->nullValue; | |
| 22692 zOut = escapeOutput(p, z, &pFree); | |
| 22693 sqlite3_fputs(zOut, p->out); | |
| 22694 if( pFree ) sqlite3_free(pFree); | |
| 22695 sqlite3_fputs((i<nArg-1)? p->colSeparator : p->rowSeparator, p->out); | |
| 22696 } | |
| 22697 break; | |
| 22698 } | |
| 22699 case MODE_Www: | |
| 22700 case MODE_Html: { | |
| 22701 if( p->cnt==0 && p->cMode==MODE_Www ){ | |
| 22702 sqlite3_fputs( | |
| 22703 "</PRE>\n" | |
| 22704 "<TABLE border='1' cellspacing='0' cellpadding='2'>\n" | |
| 22705 ,p->out | |
| 22706 ); | |
| 22707 } | |
| 22708 if( p->cnt==0 && (p->showHeader || p->cMode==MODE_Www) ){ | |
| 22709 sqlite3_fputs("<TR>", p->out); | |
| 22710 for(i=0; i<nArg; i++){ | |
| 22711 sqlite3_fputs("<TH>", p->out); | |
| 22712 output_html_string(p->out, azCol[i]); | |
| 22713 sqlite3_fputs("</TH>\n", p->out); | |
| 22714 } | |
| 22715 sqlite3_fputs("</TR>\n", p->out); | |
| 22716 } | |
| 22717 p->cnt++; | |
| 22718 if( azArg==0 ) break; | |
| 22719 sqlite3_fputs("<TR>", p->out); | |
| 22720 for(i=0; i<nArg; i++){ | |
| 22721 sqlite3_fputs("<TD>", p->out); | |
| 22722 output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue); | |
| 22723 sqlite3_fputs("</TD>\n", p->out); | |
| 22724 } | |
| 22725 sqlite3_fputs("</TR>\n", p->out); | |
| 22726 break; | |
| 22727 } | |
| 22728 case MODE_Tcl: { | |
| 22729 if( p->cnt++==0 && p->showHeader ){ | |
| 22730 for(i=0; i<nArg; i++){ | |
| 22731 output_c_string(p->out, azCol[i] ? azCol[i] : ""); | |
| 22732 if(i<nArg-1) sqlite3_fputs(p->colSeparator, p->out); | |
| 22733 } | |
| 22734 sqlite3_fputs(p->rowSeparator, p->out); | |
| 22735 } | |
| 22736 if( azArg==0 ) break; | |
| 22737 for(i=0; i<nArg; i++){ | |
| 22738 output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue); | |
| 22739 if(i<nArg-1) sqlite3_fputs(p->colSeparator, p->out); | |
| 22740 } | |
| 22741 sqlite3_fputs(p->rowSeparator, p->out); | |
| 22742 break; | |
| 22743 } | |
| 22744 case MODE_Csv: { | |
| 22745 sqlite3_fsetmode(p->out, _O_BINARY); | |
| 22746 if( p->cnt++==0 && p->showHeader ){ | |
| 22747 for(i=0; i<nArg; i++){ | |
| 22748 output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1); | |
| 22749 } | |
| 22750 sqlite3_fputs(p->rowSeparator, p->out); | |
| 22751 } | |
| 22752 if( nArg>0 ){ | |
| 22753 for(i=0; i<nArg; i++){ | |
| 22754 output_csv(p, azArg[i], i<nArg-1); | |
| 22755 } | |
| 22756 sqlite3_fputs(p->rowSeparator, p->out); | |
| 22757 } | |
| 22758 setCrlfMode(p); | |
| 22759 break; | |
| 22760 } | |
| 22761 case MODE_Insert: { | |
| 22762 if( azArg==0 ) break; | |
| 22763 sqlite3_fprintf(p->out, "INSERT INTO %s",p->zDestTable); | |
| 22764 if( p->showHeader ){ | |
| 22765 sqlite3_fputs("(", p->out); | |
| 22766 for(i=0; i<nArg; i++){ | |
| 22767 if( i>0 ) sqlite3_fputs(",", p->out); | |
| 22768 if( quoteChar(azCol[i]) ){ | |
| 22769 char *z = sqlite3_mprintf("\"%w\"", azCol[i]); | |
| 22770 shell_check_oom(z); | |
| 22771 sqlite3_fputs(z, p->out); | |
| 22772 sqlite3_free(z); | |
| 22773 }else{ | |
| 22774 sqlite3_fprintf(p->out, "%s", azCol[i]); | |
| 22775 } | |
| 22776 } | |
| 22777 sqlite3_fputs(")", p->out); | |
| 22778 } | |
| 22779 p->cnt++; | |
| 22780 for(i=0; i<nArg; i++){ | |
| 22781 sqlite3_fputs(i>0 ? "," : " VALUES(", p->out); | |
| 22782 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ | |
| 22783 sqlite3_fputs("NULL", p->out); | |
| 22784 }else if( aiType && aiType[i]==SQLITE_TEXT ){ | |
| 22785 if( ShellHasFlag(p, SHFLG_Newlines) ){ | |
| 22786 output_quoted_string(p, azArg[i]); | |
| 22787 }else{ | |
| 22788 output_quoted_escaped_string(p, azArg[i]); | |
| 22789 } | |
| 22790 }else if( aiType && aiType[i]==SQLITE_INTEGER ){ | |
| 22791 sqlite3_fputs(azArg[i], p->out); | |
| 22792 }else if( aiType && aiType[i]==SQLITE_FLOAT ){ | |
| 22793 char z[50]; | |
| 22794 double r = sqlite3_column_double(p->pStmt, i); | |
| 22795 sqlite3_uint64 ur; | |
| 22796 memcpy(&ur,&r,sizeof(r)); | |
| 22797 if( ur==0x7ff0000000000000LL ){ | |
| 22798 sqlite3_fputs("9.0e+999", p->out); | |
| 22799 }else if( ur==0xfff0000000000000LL ){ | |
| 22800 sqlite3_fputs("-9.0e+999", p->out); | |
| 22801 }else{ | |
| 22802 sqlite3_int64 ir = (sqlite3_int64)r; | |
| 22803 if( r==(double)ir ){ | |
| 22804 sqlite3_snprintf(50,z,"%lld.0", ir); | |
| 22805 }else{ | |
| 22806 sqlite3_snprintf(50,z,"%!.20g", r); | |
| 22807 } | |
| 22808 sqlite3_fputs(z, p->out); | |
| 22809 } | |
| 22810 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ | |
| 22811 const void *pBlob = sqlite3_column_blob(p->pStmt, i); | |
| 22812 int nBlob = sqlite3_column_bytes(p->pStmt, i); | |
| 22813 output_hex_blob(p->out, pBlob, nBlob); | |
| 22814 }else if( isNumber(azArg[i], 0) ){ | |
| 22815 sqlite3_fputs(azArg[i], p->out); | |
| 22816 }else if( ShellHasFlag(p, SHFLG_Newlines) ){ | |
| 22817 output_quoted_string(p, azArg[i]); | |
| 22818 }else{ | |
| 22819 output_quoted_escaped_string(p, azArg[i]); | |
| 22820 } | |
| 22821 } | |
| 22822 sqlite3_fputs(");\n", p->out); | |
| 22823 break; | |
| 22824 } | |
| 22825 case MODE_Json: { | |
| 22826 if( azArg==0 ) break; | |
| 22827 if( p->cnt==0 ){ | |
| 22828 sqlite3_fputs("[{", p->out); | |
| 22829 }else{ | |
| 22830 sqlite3_fputs(",\n{", p->out); | |
| 22831 } | |
| 22832 p->cnt++; | |
| 22833 for(i=0; i<nArg; i++){ | |
| 22834 output_json_string(p->out, azCol[i], -1); | |
| 22835 sqlite3_fputs(":", p->out); | |
| 22836 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ | |
| 22837 sqlite3_fputs("null", p->out); | |
| 22838 }else if( aiType && aiType[i]==SQLITE_FLOAT ){ | |
| 22839 char z[50]; | |
| 22840 double r = sqlite3_column_double(p->pStmt, i); | |
| 22841 sqlite3_uint64 ur; | |
| 22842 memcpy(&ur,&r,sizeof(r)); | |
| 22843 if( ur==0x7ff0000000000000LL ){ | |
| 22844 sqlite3_fputs("9.0e+999", p->out); | |
| 22845 }else if( ur==0xfff0000000000000LL ){ | |
| 22846 sqlite3_fputs("-9.0e+999", p->out); | |
| 22847 }else{ | |
| 22848 sqlite3_snprintf(50,z,"%!.20g", r); | |
| 22849 sqlite3_fputs(z, p->out); | |
| 22850 } | |
| 22851 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ | |
| 22852 const void *pBlob = sqlite3_column_blob(p->pStmt, i); | |
| 22853 int nBlob = sqlite3_column_bytes(p->pStmt, i); | |
| 22854 output_json_string(p->out, pBlob, nBlob); | |
| 22855 }else if( aiType && aiType[i]==SQLITE_TEXT ){ | |
| 22856 output_json_string(p->out, azArg[i], -1); | |
| 22857 }else{ | |
| 22858 sqlite3_fputs(azArg[i], p->out); | |
| 22859 } | |
| 22860 if( i<nArg-1 ){ | |
| 22861 sqlite3_fputs(",", p->out); | |
| 22862 } | |
| 22863 } | |
| 22864 sqlite3_fputs("}", p->out); | |
| 22865 break; | |
| 22866 } | |
| 22867 case MODE_Quote: { | |
| 22868 if( azArg==0 ) break; | |
| 22869 if( p->cnt==0 && p->showHeader ){ | |
| 22870 for(i=0; i<nArg; i++){ | |
| 22871 if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); | |
| 22872 output_quoted_string(p, azCol[i]); | |
| 22873 } | |
| 22874 sqlite3_fputs(p->rowSeparator, p->out); | |
| 22875 } | |
| 22876 p->cnt++; | |
| 22877 for(i=0; i<nArg; i++){ | |
| 22878 if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); | |
| 22879 if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){ | |
| 22880 sqlite3_fputs("NULL", p->out); | |
| 22881 }else if( aiType && aiType[i]==SQLITE_TEXT ){ | |
| 22882 output_quoted_string(p, azArg[i]); | |
| 22883 }else if( aiType && aiType[i]==SQLITE_INTEGER ){ | |
| 22884 sqlite3_fputs(azArg[i], p->out); | |
| 22885 }else if( aiType && aiType[i]==SQLITE_FLOAT ){ | |
| 22886 char z[50]; | |
| 22887 double r = sqlite3_column_double(p->pStmt, i); | |
| 22888 sqlite3_snprintf(50,z,"%!.20g", r); | |
| 22889 sqlite3_fputs(z, p->out); | |
| 22890 }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){ | |
| 22891 const void *pBlob = sqlite3_column_blob(p->pStmt, i); | |
| 22892 int nBlob = sqlite3_column_bytes(p->pStmt, i); | |
| 22893 output_hex_blob(p->out, pBlob, nBlob); | |
| 22894 }else if( isNumber(azArg[i], 0) ){ | |
| 22895 sqlite3_fputs(azArg[i], p->out); | |
| 22896 }else{ | |
| 22897 output_quoted_string(p, azArg[i]); | |
| 22898 } | |
| 22899 } | |
| 22900 sqlite3_fputs(p->rowSeparator, p->out); | |
| 22901 break; | |
| 22902 } | |
| 22903 case MODE_Ascii: { | |
| 22904 if( p->cnt++==0 && p->showHeader ){ | |
| 22905 for(i=0; i<nArg; i++){ | |
| 22906 if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); | |
| 22907 sqlite3_fputs(azCol[i] ? azCol[i] : "", p->out); | |
| 22908 } | |
| 22909 sqlite3_fputs(p->rowSeparator, p->out); | |
| 22910 } | |
| 22911 if( azArg==0 ) break; | |
| 22912 for(i=0; i<nArg; i++){ | |
| 22913 if( i>0 ) sqlite3_fputs(p->colSeparator, p->out); | |
| 22914 sqlite3_fputs(azArg[i] ? azArg[i] : p->nullValue, p->out); | |
| 22915 } | |
| 22916 sqlite3_fputs(p->rowSeparator, p->out); | |
| 22917 break; | |
| 22918 } | |
| 22919 case MODE_EQP: { | |
| 22920 eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]); | |
| 22921 break; | |
| 22922 } | |
| 22923 } | |
| 22924 return 0; | |
| 22925 } | |
| 22926 | |
| 22927 /* | |
| 22928 ** This is the callback routine that the SQLite library | |
| 22929 ** invokes for each row of a query result. | |
| 22930 */ | |
| 22931 static int callback(void *pArg, int nArg, char **azArg, char **azCol){ | |
| 22932 /* since we don't have type info, call the shell_callback with a NULL value */ | |
| 22933 return shell_callback(pArg, nArg, azArg, azCol, NULL); | |
| 22934 } | |
| 22935 | |
| 22936 /* | |
| 22937 ** This is the callback routine from sqlite3_exec() that appends all | |
| 22938 ** output onto the end of a ShellText object. | |
| 22939 */ | |
| 22940 static int captureOutputCallback(void *pArg, int nArg, char **azArg, char **az){ | |
| 22941 ShellText *p = (ShellText*)pArg; | |
| 22942 int i; | |
| 22943 UNUSED_PARAMETER(az); | |
| 22944 if( azArg==0 ) return 0; | |
| 22945 if( p->n ) appendText(p, "|", 0); | |
| 22946 for(i=0; i<nArg; i++){ | |
| 22947 if( i ) appendText(p, ",", 0); | |
| 22948 if( azArg[i] ) appendText(p, azArg[i], 0); | |
| 22949 } | |
| 22950 return 0; | |
| 22951 } | |
| 22952 | |
| 22953 /* | |
| 22954 ** Generate an appropriate SELFTEST table in the main database. | |
| 22955 */ | |
| 22956 static void createSelftestTable(ShellState *p){ | |
| 22957 char *zErrMsg = 0; | |
| 22958 sqlite3_exec(p->db, | |
| 22959 "SAVEPOINT selftest_init;\n" | |
| 22960 "CREATE TABLE IF NOT EXISTS selftest(\n" | |
| 22961 " tno INTEGER PRIMARY KEY,\n" /* Test number */ | |
| 22962 " op TEXT,\n" /* Operator: memo run */ | |
| 22963 " cmd TEXT,\n" /* Command text */ | |
| 22964 " ans TEXT\n" /* Desired answer */ | |
| 22965 ");" | |
| 22966 "CREATE TEMP TABLE [_shell$self](op,cmd,ans);\n" | |
| 22967 "INSERT INTO [_shell$self](rowid,op,cmd)\n" | |
| 22968 " VALUES(coalesce((SELECT (max(tno)+100)/10 FROM selftest),10),\n" | |
| 22969 " 'memo','Tests generated by --init');\n" | |
| 22970 "INSERT INTO [_shell$self]\n" | |
| 22971 " SELECT 'run',\n" | |
| 22972 " 'SELECT hex(sha3_query(''SELECT type,name,tbl_name,sql " | |
| 22973 "FROM sqlite_schema ORDER BY 2'',224))',\n" | |
| 22974 " hex(sha3_query('SELECT type,name,tbl_name,sql " | |
| 22975 "FROM sqlite_schema ORDER BY 2',224));\n" | |
| 22976 "INSERT INTO [_shell$self]\n" | |
| 22977 " SELECT 'run'," | |
| 22978 " 'SELECT hex(sha3_query(''SELECT * FROM \"' ||" | |
| 22979 " printf('%w',name) || '\" NOT INDEXED'',224))',\n" | |
| 22980 " hex(sha3_query(printf('SELECT * FROM \"%w\" NOT INDEXED',name),224))\n" | |
| 22981 " FROM (\n" | |
| 22982 " SELECT name FROM sqlite_schema\n" | |
| 22983 " WHERE type='table'\n" | |
| 22984 " AND name<>'selftest'\n" | |
| 22985 " AND coalesce(rootpage,0)>0\n" | |
| 22986 " )\n" | |
| 22987 " ORDER BY name;\n" | |
| 22988 "INSERT INTO [_shell$self]\n" | |
| 22989 " VALUES('run','PRAGMA integrity_check','ok');\n" | |
| 22990 "INSERT INTO selftest(tno,op,cmd,ans)" | |
| 22991 " SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n" | |
| 22992 "DROP TABLE [_shell$self];" | |
| 22993 ,0,0,&zErrMsg); | |
| 22994 if( zErrMsg ){ | |
| 22995 sqlite3_fprintf(stderr, "SELFTEST initialization failure: %s\n", zErrMsg); | |
| 22996 sqlite3_free(zErrMsg); | |
| 22997 } | |
| 22998 sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0); | |
| 22999 } | |
| 23000 | |
| 23001 | |
| 23002 /* | |
| 23003 ** Set the destination table field of the ShellState structure to | |
| 23004 ** the name of the table given. Escape any quote characters in the | |
| 23005 ** table name. | |
| 23006 */ | |
| 23007 static void set_table_name(ShellState *p, const char *zName){ | |
| 23008 if( p->zDestTable ){ | |
| 23009 sqlite3_free(p->zDestTable); | |
| 23010 p->zDestTable = 0; | |
| 23011 } | |
| 23012 if( zName==0 ) return; | |
| 23013 if( quoteChar(zName) ){ | |
| 23014 p->zDestTable = sqlite3_mprintf("\"%w\"", zName); | |
| 23015 }else{ | |
| 23016 p->zDestTable = sqlite3_mprintf("%s", zName); | |
| 23017 } | |
| 23018 shell_check_oom(p->zDestTable); | |
| 23019 } | |
| 23020 | |
| 23021 /* | |
| 23022 ** Maybe construct two lines of text that point out the position of a | |
| 23023 ** syntax error. Return a pointer to the text, in memory obtained from | |
| 23024 ** sqlite3_malloc(). Or, if the most recent error does not involve a | |
| 23025 ** specific token that we can point to, return an empty string. | |
| 23026 ** | |
| 23027 ** In all cases, the memory returned is obtained from sqlite3_malloc64() | |
| 23028 ** and should be released by the caller invoking sqlite3_free(). | |
| 23029 */ | |
| 23030 static char *shell_error_context(const char *zSql, sqlite3 *db){ | |
| 23031 int iOffset; | |
| 23032 size_t len; | |
| 23033 char *zCode; | |
| 23034 char *zMsg; | |
| 23035 int i; | |
| 23036 if( db==0 | |
| 23037 || zSql==0 | |
| 23038 || (iOffset = sqlite3_error_offset(db))<0 | |
| 23039 || iOffset>=(int)strlen(zSql) | |
| 23040 ){ | |
| 23041 return sqlite3_mprintf(""); | |
| 23042 } | |
| 23043 while( iOffset>50 ){ | |
| 23044 iOffset--; | |
| 23045 zSql++; | |
| 23046 while( (zSql[0]&0xc0)==0x80 ){ zSql++; iOffset--; } | |
| 23047 } | |
| 23048 len = strlen(zSql); | |
| 23049 if( len>78 ){ | |
| 23050 len = 78; | |
| 23051 while( len>0 && (zSql[len]&0xc0)==0x80 ) len--; | |
| 23052 } | |
| 23053 zCode = sqlite3_mprintf("%.*s", len, zSql); | |
| 23054 shell_check_oom(zCode); | |
| 23055 for(i=0; zCode[i]; i++){ if( IsSpace(zSql[i]) ) zCode[i] = ' '; } | |
| 23056 if( iOffset<25 ){ | |
| 23057 zMsg = sqlite3_mprintf("\n %z\n %*s^--- error here", zCode,iOffset,""); | |
| 23058 }else{ | |
| 23059 zMsg = sqlite3_mprintf("\n %z\n %*serror here ---^", zCode,iOffset-14,""); | |
| 23060 } | |
| 23061 return zMsg; | |
| 23062 } | |
| 23063 | |
| 23064 | |
| 23065 /* | |
| 23066 ** Execute a query statement that will generate SQL output. Print | |
| 23067 ** the result columns, comma-separated, on a line and then add a | |
| 23068 ** semicolon terminator to the end of that line. | |
| 23069 ** | |
| 23070 ** If the number of columns is 1 and that column contains text "--" | |
| 23071 ** then write the semicolon on a separate line. That way, if a | |
| 23072 ** "--" comment occurs at the end of the statement, the comment | |
| 23073 ** won't consume the semicolon terminator. | |
| 23074 */ | |
| 23075 static int run_table_dump_query( | |
| 23076 ShellState *p, /* Query context */ | |
| 23077 const char *zSelect /* SELECT statement to extract content */ | |
| 23078 ){ | |
| 23079 sqlite3_stmt *pSelect; | |
| 23080 int rc; | |
| 23081 int nResult; | |
| 23082 int i; | |
| 23083 const char *z; | |
| 23084 rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0); | |
| 23085 if( rc!=SQLITE_OK || !pSelect ){ | |
| 23086 char *zContext = shell_error_context(zSelect, p->db); | |
| 23087 sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n%s", | |
| 23088 rc, sqlite3_errmsg(p->db), zContext); | |
| 23089 sqlite3_free(zContext); | |
| 23090 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; | |
| 23091 return rc; | |
| 23092 } | |
| 23093 rc = sqlite3_step(pSelect); | |
| 23094 nResult = sqlite3_column_count(pSelect); | |
| 23095 while( rc==SQLITE_ROW ){ | |
| 23096 z = (const char*)sqlite3_column_text(pSelect, 0); | |
| 23097 sqlite3_fprintf(p->out, "%s", z); | |
| 23098 for(i=1; i<nResult; i++){ | |
| 23099 sqlite3_fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i)); | |
| 23100 } | |
| 23101 if( z==0 ) z = ""; | |
| 23102 while( z[0] && (z[0]!='-' || z[1]!='-') ) z++; | |
| 23103 if( z[0] ){ | |
| 23104 sqlite3_fputs("\n;\n", p->out); | |
| 23105 }else{ | |
| 23106 sqlite3_fputs(";\n", p->out); | |
| 23107 } | |
| 23108 rc = sqlite3_step(pSelect); | |
| 23109 } | |
| 23110 rc = sqlite3_finalize(pSelect); | |
| 23111 if( rc!=SQLITE_OK ){ | |
| 23112 sqlite3_fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", | |
| 23113 rc, sqlite3_errmsg(p->db)); | |
| 23114 if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; | |
| 23115 } | |
| 23116 return rc; | |
| 23117 } | |
| 23118 | |
| 23119 /* | |
| 23120 ** Allocate space and save off string indicating current error. | |
| 23121 */ | |
| 23122 static char *save_err_msg( | |
| 23123 sqlite3 *db, /* Database to query */ | |
| 23124 const char *zPhase, /* When the error occurs */ | |
| 23125 int rc, /* Error code returned from API */ | |
| 23126 const char *zSql /* SQL string, or NULL */ | |
| 23127 ){ | |
| 23128 char *zErr; | |
| 23129 char *zContext; | |
| 23130 sqlite3_str *pStr = sqlite3_str_new(0); | |
| 23131 sqlite3_str_appendf(pStr, "%s, %s", zPhase, sqlite3_errmsg(db)); | |
| 23132 if( rc>1 ){ | |
| 23133 sqlite3_str_appendf(pStr, " (%d)", rc); | |
| 23134 } | |
| 23135 zContext = shell_error_context(zSql, db); | |
| 23136 if( zContext ){ | |
| 23137 sqlite3_str_appendall(pStr, zContext); | |
| 23138 sqlite3_free(zContext); | |
| 23139 } | |
| 23140 zErr = sqlite3_str_finish(pStr); | |
| 23141 shell_check_oom(zErr); | |
| 23142 return zErr; | |
| 23143 } | |
| 23144 | |
| 23145 #ifdef __linux__ | |
| 23146 /* | |
| 23147 ** Attempt to display I/O stats on Linux using /proc/PID/io | |
| 23148 */ | |
| 23149 static void displayLinuxIoStats(FILE *out){ | |
| 23150 FILE *in; | |
| 23151 char z[200]; | |
| 23152 sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid()); | |
| 23153 in = sqlite3_fopen(z, "rb"); | |
| 23154 if( in==0 ) return; | |
| 23155 while( sqlite3_fgets(z, sizeof(z), in)!=0 ){ | |
| 23156 static const struct { | |
| 23157 const char *zPattern; | |
| 23158 const char *zDesc; | |
| 23159 } aTrans[] = { | |
| 23160 { "rchar: ", "Bytes received by read():" }, | |
| 23161 { "wchar: ", "Bytes sent to write():" }, | |
| 23162 { "syscr: ", "Read() system calls:" }, | |
| 23163 { "syscw: ", "Write() system calls:" }, | |
| 23164 { "read_bytes: ", "Bytes read from storage:" }, | |
| 23165 { "write_bytes: ", "Bytes written to storage:" }, | |
| 23166 { "cancelled_write_bytes: ", "Cancelled write bytes:" }, | |
| 23167 }; | |
| 23168 int i; | |
| 23169 for(i=0; i<ArraySize(aTrans); i++){ | |
| 23170 int n = strlen30(aTrans[i].zPattern); | |
| 23171 if( cli_strncmp(aTrans[i].zPattern, z, n)==0 ){ | |
| 23172 sqlite3_fprintf(out, "%-36s %s", aTrans[i].zDesc, &z[n]); | |
| 23173 break; | |
| 23174 } | |
| 23175 } | |
| 23176 } | |
| 23177 fclose(in); | |
| 23178 } | |
| 23179 #endif | |
| 23180 | |
| 23181 /* | |
| 23182 ** Display a single line of status using 64-bit values. | |
| 23183 */ | |
| 23184 static void displayStatLine( | |
| 23185 FILE *out, /* Write to this channel */ | |
| 23186 char *zLabel, /* Label for this one line */ | |
| 23187 char *zFormat, /* Format for the result */ | |
| 23188 int iStatusCtrl, /* Which status to display */ | |
| 23189 int bReset /* True to reset the stats */ | |
| 23190 ){ | |
| 23191 sqlite3_int64 iCur = -1; | |
| 23192 sqlite3_int64 iHiwtr = -1; | |
| 23193 int i, nPercent; | |
| 23194 char zLine[200]; | |
| 23195 sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset); | |
| 23196 for(i=0, nPercent=0; zFormat[i]; i++){ | |
| 23197 if( zFormat[i]=='%' ) nPercent++; | |
| 23198 } | |
| 23199 if( nPercent>1 ){ | |
| 23200 sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr); | |
| 23201 }else{ | |
| 23202 sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr); | |
| 23203 } | |
| 23204 sqlite3_fprintf(out, "%-36s %s\n", zLabel, zLine); | |
| 23205 } | |
| 23206 | |
| 23207 /* | |
| 23208 ** Display memory stats. | |
| 23209 */ | |
| 23210 static int display_stats( | |
| 23211 sqlite3 *db, /* Database to query */ | |
| 23212 ShellState *pArg, /* Pointer to ShellState */ | |
| 23213 int bReset /* True to reset the stats */ | |
| 23214 ){ | |
| 23215 int iCur, iHiwtr; | |
| 23216 sqlite3_int64 iCur64, iHiwtr64; | |
| 23217 FILE *out; | |
| 23218 if( pArg==0 || pArg->out==0 ) return 0; | |
| 23219 out = pArg->out; | |
| 23220 | |
| 23221 if( pArg->pStmt && pArg->statsOn==2 ){ | |
| 23222 int nCol, i, x; | |
| 23223 sqlite3_stmt *pStmt = pArg->pStmt; | |
| 23224 char z[100]; | |
| 23225 nCol = sqlite3_column_count(pStmt); | |
| 23226 sqlite3_fprintf(out, "%-36s %d\n", "Number of output columns:", nCol); | |
| 23227 for(i=0; i<nCol; i++){ | |
| 23228 sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x); | |
| 23229 sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i)); | |
| 23230 #ifndef SQLITE_OMIT_DECLTYPE | |
| 23231 sqlite3_snprintf(30, z+x, "declared type:"); | |
| 23232 sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i)); | |
| 23233 #endif | |
| 23234 #ifdef SQLITE_ENABLE_COLUMN_METADATA | |
| 23235 sqlite3_snprintf(30, z+x, "database name:"); | |
| 23236 sqlite3_fprintf(out, "%-36s %s\n", z, | |
| 23237 sqlite3_column_database_name(pStmt,i)); | |
| 23238 sqlite3_snprintf(30, z+x, "table name:"); | |
| 23239 sqlite3_fprintf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i)); | |
| 23240 sqlite3_snprintf(30, z+x, "origin name:"); | |
| 23241 sqlite3_fprintf(out, "%-36s %s\n", z,sqlite3_column_origin_name(pStmt,i)); | |
| 23242 #endif | |
| 23243 } | |
| 23244 } | |
| 23245 | |
| 23246 if( pArg->statsOn==3 ){ | |
| 23247 if( pArg->pStmt ){ | |
| 23248 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset); | |
| 23249 sqlite3_fprintf(out, "VM-steps: %d\n", iCur); | |
| 23250 } | |
| 23251 return 0; | |
| 23252 } | |
| 23253 | |
| 23254 displayStatLine(out, "Memory Used:", | |
| 23255 "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); | |
| 23256 displayStatLine(out, "Number of Outstanding Allocations:", | |
| 23257 "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); | |
| 23258 if( pArg->shellFlgs & SHFLG_Pagecache ){ | |
| 23259 displayStatLine(out, "Number of Pcache Pages Used:", | |
| 23260 "%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset); | |
| 23261 } | |
| 23262 displayStatLine(out, "Number of Pcache Overflow Bytes:", | |
| 23263 "%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset); | |
| 23264 displayStatLine(out, "Largest Allocation:", | |
| 23265 "%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset); | |
| 23266 displayStatLine(out, "Largest Pcache Allocation:", | |
| 23267 "%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset); | |
| 23268 #ifdef YYTRACKMAXSTACKDEPTH | |
| 23269 displayStatLine(out, "Deepest Parser Stack:", | |
| 23270 "%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset); | |
| 23271 #endif | |
| 23272 | |
| 23273 if( db ){ | |
| 23274 if( pArg->shellFlgs & SHFLG_Lookaside ){ | |
| 23275 iHiwtr = iCur = -1; | |
| 23276 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, | |
| 23277 &iCur, &iHiwtr, bReset); | |
| 23278 sqlite3_fprintf(out, | |
| 23279 "Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr); | |
| 23280 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, | |
| 23281 &iCur, &iHiwtr, bReset); | |
| 23282 sqlite3_fprintf(out, | |
| 23283 "Successful lookaside attempts: %d\n", iHiwtr); | |
| 23284 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, | |
| 23285 &iCur, &iHiwtr, bReset); | |
| 23286 sqlite3_fprintf(out, | |
| 23287 "Lookaside failures due to size: %d\n", iHiwtr); | |
| 23288 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, | |
| 23289 &iCur, &iHiwtr, bReset); | |
| 23290 sqlite3_fprintf(out, | |
| 23291 "Lookaside failures due to OOM: %d\n", iHiwtr); | |
| 23292 } | |
| 23293 iHiwtr = iCur = -1; | |
| 23294 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset); | |
| 23295 sqlite3_fprintf(out, | |
| 23296 "Pager Heap Usage: %d bytes\n", iCur); | |
| 23297 iHiwtr = iCur = -1; | |
| 23298 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1); | |
| 23299 sqlite3_fprintf(out, | |
| 23300 "Page cache hits: %d\n", iCur); | |
| 23301 iHiwtr = iCur = -1; | |
| 23302 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1); | |
| 23303 sqlite3_fprintf(out, | |
| 23304 "Page cache misses: %d\n", iCur); | |
| 23305 iHiwtr64 = iCur64 = -1; | |
| 23306 sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64, | |
| 23307 0); | |
| 23308 iHiwtr = iCur = -1; | |
| 23309 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1); | |
| 23310 sqlite3_fprintf(out, | |
| 23311 "Page cache writes: %d\n", iCur); | |
| 23312 iHiwtr = iCur = -1; | |
| 23313 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1); | |
| 23314 sqlite3_fprintf(out, | |
| 23315 "Page cache spills: %d\n", iCur); | |
| 23316 sqlite3_fprintf(out, | |
| 23317 "Temporary data spilled to disk: %lld\n", iCur64); | |
| 23318 sqlite3_db_status64(db, SQLITE_DBSTATUS_TEMPBUF_SPILL, &iCur64, &iHiwtr64, | |
| 23319 1); | |
| 23320 iHiwtr = iCur = -1; | |
| 23321 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset); | |
| 23322 sqlite3_fprintf(out, | |
| 23323 "Schema Heap Usage: %d bytes\n", iCur); | |
| 23324 iHiwtr = iCur = -1; | |
| 23325 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset); | |
| 23326 sqlite3_fprintf(out, | |
| 23327 "Statement Heap/Lookaside Usage: %d bytes\n", iCur); | |
| 23328 } | |
| 23329 | |
| 23330 if( pArg->pStmt ){ | |
| 23331 int iHit, iMiss; | |
| 23332 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, | |
| 23333 bReset); | |
| 23334 sqlite3_fprintf(out, | |
| 23335 "Fullscan Steps: %d\n", iCur); | |
| 23336 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset); | |
| 23337 sqlite3_fprintf(out, | |
| 23338 "Sort Operations: %d\n", iCur); | |
| 23339 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset); | |
| 23340 sqlite3_fprintf(out, | |
| 23341 "Autoindex Inserts: %d\n", iCur); | |
| 23342 iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, | |
| 23343 bReset); | |
| 23344 iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, | |
| 23345 bReset); | |
| 23346 if( iHit || iMiss ){ | |
| 23347 sqlite3_fprintf(out, | |
| 23348 "Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss); | |
| 23349 } | |
| 23350 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); | |
| 23351 sqlite3_fprintf(out, | |
| 23352 "Virtual Machine Steps: %d\n", iCur); | |
| 23353 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset); | |
| 23354 sqlite3_fprintf(out, | |
| 23355 "Reprepare operations: %d\n", iCur); | |
| 23356 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset); | |
| 23357 sqlite3_fprintf(out, | |
| 23358 "Number of times run: %d\n", iCur); | |
| 23359 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset); | |
| 23360 sqlite3_fprintf(out, | |
| 23361 "Memory used by prepared stmt: %d\n", iCur); | |
| 23362 } | |
| 23363 | |
| 23364 #ifdef __linux__ | |
| 23365 displayLinuxIoStats(pArg->out); | |
| 23366 #endif | |
| 23367 | |
| 23368 /* Do not remove this machine readable comment: extra-stats-output-here */ | |
| 23369 | |
| 23370 return 0; | |
| 23371 } | |
| 23372 | |
| 23373 | |
| 23374 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | |
| 23375 static int scanStatsHeight(sqlite3_stmt *p, int iEntry){ | |
| 23376 int iPid = 0; | |
| 23377 int ret = 1; | |
| 23378 sqlite3_stmt_scanstatus_v2(p, iEntry, | |
| 23379 SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid | |
| 23380 ); | |
| 23381 while( iPid!=0 ){ | |
| 23382 int ii; | |
| 23383 for(ii=0; 1; ii++){ | |
| 23384 int iId; | |
| 23385 int res; | |
| 23386 res = sqlite3_stmt_scanstatus_v2(p, ii, | |
| 23387 SQLITE_SCANSTAT_SELECTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iId | |
| 23388 ); | |
| 23389 if( res ) break; | |
| 23390 if( iId==iPid ){ | |
| 23391 sqlite3_stmt_scanstatus_v2(p, ii, | |
| 23392 SQLITE_SCANSTAT_PARENTID, SQLITE_SCANSTAT_COMPLEX, (void*)&iPid | |
| 23393 ); | |
| 23394 } | |
| 23395 } | |
| 23396 ret++; | |
| 23397 } | |
| 23398 return ret; | |
| 23399 } | |
| 23400 #endif | |
| 23401 | |
| 23402 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS | |
| 23403 static void display_explain_scanstats( | |
| 23404 sqlite3 *db, /* Database to query */ | |
| 23405 ShellState *pArg /* Pointer to ShellState */ | |
| 23406 ){ | |
| 23407 static const int f = SQLITE_SCANSTAT_COMPLEX; | |
| 23408 sqlite3_stmt *p = pArg->pStmt; | |
| 23409 int ii = 0; | |
| 23410 i64 nTotal = 0; | |
| 23411 int nWidth = 0; | |
| 23412 eqp_reset(pArg); | |
| 23413 | |
| 23414 for(ii=0; 1; ii++){ | |
| 23415 const char *z = 0; | |
| 23416 int n = 0; | |
| 23417 if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&z) ){ | |
| 23418 break; | |
| 23419 } | |
| 23420 n = (int)strlen(z) + scanStatsHeight(p, ii)*3; | |
| 23421 if( n>nWidth ) nWidth = n; | |
| 23422 } | |
| 23423 nWidth += 4; | |
| 23424 | |
| 23425 sqlite3_stmt_scanstatus_v2(p, -1, SQLITE_SCANSTAT_NCYCLE, f, (void*)&nTotal); | |
| 23426 for(ii=0; 1; ii++){ | |
| 23427 i64 nLoop = 0; | |
| 23428 i64 nRow = 0; | |
| 23429 i64 nCycle = 0; | |
| 23430 int iId = 0; | |
| 23431 int iPid = 0; | |
| 23432 const char *zo = 0; | |
| 23433 const char *zName = 0; | |
| 23434 char *zText = 0; | |
| 23435 double rEst = 0.0; | |
| 23436 | |
| 23437 if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&zo) ){ | |
| 23438 break; | |
| 23439 } | |
| 23440 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_EST,f,(void*)&rEst); | |
| 23441 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NLOOP,f,(void*)&nLoop); | |
| 23442 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NVISIT,f,(void*)&nRow); | |
| 23443 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NCYCLE,f,(void*)&nCycle); | |
| 23444 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_SELECTID,f,(void*)&iId); | |
| 23445 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_PARENTID,f,(void*)&iPid); | |
| 23446 sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NAME,f,(void*)&zName); | |
| 23447 | |
| 23448 zText = sqlite3_mprintf("%s", zo); | |
| 23449 if( nCycle>=0 || nLoop>=0 || nRow>=0 ){ | |
| 23450 char *z = 0; | |
| 23451 if( nCycle>=0 && nTotal>0 ){ | |
| 23452 z = sqlite3_mprintf("%zcycles=%lld [%d%%]", z, | |
| 23453 nCycle, ((nCycle*100)+nTotal/2) / nTotal | |
| 23454 ); | |
| 23455 } | |
| 23456 if( nLoop>=0 ){ | |
| 23457 z = sqlite3_mprintf("%z%sloops=%lld", z, z ? " " : "", nLoop); | |
| 23458 } | |
| 23459 if( nRow>=0 ){ | |
| 23460 z = sqlite3_mprintf("%z%srows=%lld", z, z ? " " : "", nRow); | |
| 23461 } | |
| 23462 | |
| 23463 if( zName && pArg->scanstatsOn>1 ){ | |
| 23464 double rpl = (double)nRow / (double)nLoop; | |
| 23465 z = sqlite3_mprintf("%z rpl=%.1f est=%.1f", z, rpl, rEst); | |
| 23466 } | |
| 23467 | |
| 23468 zText = sqlite3_mprintf( | |
| 23469 "% *z (%z)", -1*(nWidth-scanStatsHeight(p, ii)*3), zText, z | |
| 23470 ); | |
| 23471 } | |
| 23472 | |
| 23473 eqp_append(pArg, iId, iPid, zText); | |
| 23474 sqlite3_free(zText); | |
| 23475 } | |
| 23476 | |
| 23477 eqp_render(pArg, nTotal); | |
| 23478 } | |
| 23479 #endif | |
| 23480 | |
| 23481 | |
| 23482 /* | |
| 23483 ** Parameter azArray points to a zero-terminated array of strings. zStr | |
| 23484 ** points to a single nul-terminated string. Return non-zero if zStr | |
| 23485 ** is equal, according to strcmp(), to any of the strings in the array. | |
| 23486 ** Otherwise, return zero. | |
| 23487 */ | |
| 23488 static int str_in_array(const char *zStr, const char **azArray){ | |
| 23489 int i; | |
| 23490 for(i=0; azArray[i]; i++){ | |
| 23491 if( 0==cli_strcmp(zStr, azArray[i]) ) return 1; | |
| 23492 } | |
| 23493 return 0; | |
| 23494 } | |
| 23495 | |
| 23496 /* | |
| 23497 ** If compiled statement pSql appears to be an EXPLAIN statement, allocate | |
| 23498 ** and populate the ShellState.aiIndent[] array with the number of | |
| 23499 ** spaces each opcode should be indented before it is output. | |
| 23500 ** | |
| 23501 ** The indenting rules are: | |
| 23502 ** | |
| 23503 ** * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent | |
| 23504 ** all opcodes that occur between the p2 jump destination and the opcode | |
| 23505 ** itself by 2 spaces. | |
| 23506 ** | |
| 23507 ** * Do the previous for "Return" instructions for when P2 is positive. | |
| 23508 ** See tag-20220407a in wherecode.c and vdbe.c. | |
| 23509 ** | |
| 23510 ** * For each "Goto", if the jump destination is earlier in the program | |
| 23511 ** and ends on one of: | |
| 23512 ** Yield SeekGt SeekLt RowSetRead Rewind | |
| 23513 ** or if the P1 parameter is one instead of zero, | |
| 23514 ** then indent all opcodes between the earlier instruction | |
| 23515 ** and "Goto" by 2 spaces. | |
| 23516 */ | |
| 23517 static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ | |
| 23518 int *abYield = 0; /* True if op is an OP_Yield */ | |
| 23519 int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ | |
| 23520 int iOp; /* Index of operation in p->aiIndent[] */ | |
| 23521 | |
| 23522 const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", | |
| 23523 "Return", 0 }; | |
| 23524 const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", | |
| 23525 "Rewind", 0 }; | |
| 23526 const char *azGoto[] = { "Goto", 0 }; | |
| 23527 | |
| 23528 /* The caller guarantees that the leftmost 4 columns of the statement | |
| 23529 ** passed to this function are equivalent to the leftmost 4 columns | |
| 23530 ** of EXPLAIN statement output. In practice the statement may be | |
| 23531 ** an EXPLAIN, or it may be a query on the bytecode() virtual table. */ | |
| 23532 assert( sqlite3_column_count(pSql)>=4 ); | |
| 23533 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 0), "addr" ) ); | |
| 23534 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 1), "opcode" ) ); | |
| 23535 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 2), "p1" ) ); | |
| 23536 assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 3), "p2" ) ); | |
| 23537 | |
| 23538 for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){ | |
| 23539 int i; | |
| 23540 int iAddr = sqlite3_column_int(pSql, 0); | |
| 23541 const char *zOp = (const char*)sqlite3_column_text(pSql, 1); | |
| 23542 int p1 = sqlite3_column_int(pSql, 2); | |
| 23543 int p2 = sqlite3_column_int(pSql, 3); | |
| 23544 | |
| 23545 /* Assuming that p2 is an instruction address, set variable p2op to the | |
| 23546 ** index of that instruction in the aiIndent[] array. p2 and p2op may be | |
| 23547 ** different if the current instruction is part of a sub-program generated | |
| 23548 ** by an SQL trigger or foreign key. */ | |
| 23549 int p2op = (p2 + (iOp-iAddr)); | |
| 23550 | |
| 23551 /* Grow the p->aiIndent array as required */ | |
| 23552 if( iOp>=nAlloc ){ | |
| 23553 nAlloc += 100; | |
| 23554 p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); | |
| 23555 shell_check_oom(p->aiIndent); | |
| 23556 abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); | |
| 23557 shell_check_oom(abYield); | |
| 23558 } | |
| 23559 | |
| 23560 abYield[iOp] = str_in_array(zOp, azYield); | |
| 23561 p->aiIndent[iOp] = 0; | |
| 23562 p->nIndent = iOp+1; | |
| 23563 if( str_in_array(zOp, azNext) && p2op>0 ){ | |
| 23564 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2; | |
| 23565 } | |
| 23566 if( str_in_array(zOp, azGoto) && p2op<iOp && (abYield[p2op] || p1) ){ | |
| 23567 for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2; | |
| 23568 } | |
| 23569 } | |
| 23570 | |
| 23571 p->iIndent = 0; | |
| 23572 sqlite3_free(abYield); | |
| 23573 sqlite3_reset(pSql); | |
| 23574 } | |
| 23575 | |
| 23576 /* | |
| 23577 ** Free the array allocated by explain_data_prepare(). | |
| 23578 */ | |
| 23579 static void explain_data_delete(ShellState *p){ | |
| 23580 sqlite3_free(p->aiIndent); | |
| 23581 p->aiIndent = 0; | |
| 23582 p->nIndent = 0; | |
| 23583 p->iIndent = 0; | |
| 23584 } | |
| 23585 | |
| 23586 static void exec_prepared_stmt(ShellState*, sqlite3_stmt*); | |
| 23587 | |
| 23588 /* | |
| 23589 ** Display scan stats. | |
| 23590 */ | |
| 23591 static void display_scanstats( | |
| 23592 sqlite3 *db, /* Database to query */ | |
| 23593 ShellState *pArg /* Pointer to ShellState */ | |
| 23594 ){ | |
| 23595 #ifndef SQLITE_ENABLE_STMT_SCANSTATUS | |
| 23596 UNUSED_PARAMETER(db); | |
| 23597 UNUSED_PARAMETER(pArg); | |
| 23598 #else | |
| 23599 if( pArg->scanstatsOn==3 ){ | |
| 23600 const char *zSql = | |
| 23601 " SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec," | |
| 23602 " format('% 6s (%.2f%%)'," | |
| 23603 " CASE WHEN ncycle<100_000 THEN ncycle || ' '" | |
| 23604 " WHEN ncycle<100_000_000 THEN (ncycle/1_000) || 'K'" | |
| 23605 " WHEN ncycle<100_000_000_000 THEN (ncycle/1_000_000) || 'M'" | |
| 23606 " ELSE (ncycle/1000_000_000) || 'G' END," | |
| 23607 " ncycle*100.0/(sum(ncycle) OVER ())" | |
| 23608 " ) AS cycles" | |
| 23609 " FROM bytecode(?)"; | |
| 23610 | |
| 23611 int rc = SQLITE_OK; | |
| 23612 sqlite3_stmt *pStmt = 0; | |
| 23613 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); | |
| 23614 if( rc==SQLITE_OK ){ | |
| 23615 sqlite3_stmt *pSave = pArg->pStmt; | |
| 23616 pArg->pStmt = pStmt; | |
| 23617 sqlite3_bind_pointer(pStmt, 1, pSave, "stmt-pointer", 0); | |
| 23618 | |
| 23619 pArg->cnt = 0; | |
| 23620 pArg->cMode = MODE_ScanExp; | |
| 23621 explain_data_prepare(pArg, pStmt); | |
| 23622 exec_prepared_stmt(pArg, pStmt); | |
| 23623 explain_data_delete(pArg); | |
| 23624 | |
| 23625 sqlite3_finalize(pStmt); | |
| 23626 pArg->pStmt = pSave; | |
| 23627 } | |
| 23628 }else{ | |
| 23629 display_explain_scanstats(db, pArg); | |
| 23630 } | |
| 23631 #endif | |
| 23632 } | |
| 23633 | |
| 23634 /* | |
| 23635 ** Disable and restore .wheretrace and .treetrace/.selecttrace settings. | |
| 23636 */ | |
| 23637 static unsigned int savedSelectTrace; | |
| 23638 static unsigned int savedWhereTrace; | |
| 23639 static void disable_debug_trace_modes(void){ | |
| 23640 unsigned int zero = 0; | |
| 23641 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &savedSelectTrace); | |
| 23642 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &zero); | |
| 23643 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 2, &savedWhereTrace); | |
| 23644 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &zero); | |
| 23645 } | |
| 23646 static void restore_debug_trace_modes(void){ | |
| 23647 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &savedSelectTrace); | |
| 23648 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &savedWhereTrace); | |
| 23649 } | |
| 23650 | |
| 23651 /* Create the TEMP table used to store parameter bindings */ | |
| 23652 static void bind_table_init(ShellState *p){ | |
| 23653 int wrSchema = 0; | |
| 23654 int defensiveMode = 0; | |
| 23655 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &defensiveMode); | |
| 23656 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0); | |
| 23657 sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema); | |
| 23658 sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0); | |
| 23659 sqlite3_exec(p->db, | |
| 23660 "CREATE TABLE IF NOT EXISTS temp.sqlite_parameters(\n" | |
| 23661 " key TEXT PRIMARY KEY,\n" | |
| 23662 " value\n" | |
| 23663 ") WITHOUT ROWID;", | |
| 23664 0, 0, 0); | |
| 23665 sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0); | |
| 23666 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, defensiveMode, 0); | |
| 23667 } | |
| 23668 | |
| 23669 /* | |
| 23670 ** Bind parameters on a prepared statement. | |
| 23671 ** | |
| 23672 ** Parameter bindings are taken from a TEMP table of the form: | |
| 23673 ** | |
| 23674 ** CREATE TEMP TABLE sqlite_parameters(key TEXT PRIMARY KEY, value) | |
| 23675 ** WITHOUT ROWID; | |
| 23676 ** | |
| 23677 ** No bindings occur if this table does not exist. The name of the table | |
| 23678 ** begins with "sqlite_" so that it will not collide with ordinary application | |
| 23679 ** tables. The table must be in the TEMP schema. | |
| 23680 */ | |
| 23681 static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){ | |
| 23682 int nVar; | |
| 23683 int i; | |
| 23684 int rc; | |
| 23685 sqlite3_stmt *pQ = 0; | |
| 23686 | |
| 23687 nVar = sqlite3_bind_parameter_count(pStmt); | |
| 23688 if( nVar==0 ) return; /* Nothing to do */ | |
| 23689 if( sqlite3_table_column_metadata(pArg->db, "TEMP", "sqlite_parameters", | |
| 23690 "key", 0, 0, 0, 0, 0)!=SQLITE_OK ){ | |
| 23691 rc = SQLITE_NOTFOUND; | |
| 23692 pQ = 0; | |
| 23693 }else{ | |
| 23694 rc = sqlite3_prepare_v2(pArg->db, | |
| 23695 "SELECT value FROM temp.sqlite_parameters" | |
| 23696 " WHERE key=?1", -1, &pQ, 0); | |
| 23697 } | |
| 23698 for(i=1; i<=nVar; i++){ | |
| 23699 char zNum[30]; | |
| 23700 const char *zVar = sqlite3_bind_parameter_name(pStmt, i); | |
| 23701 if( zVar==0 ){ | |
| 23702 sqlite3_snprintf(sizeof(zNum),zNum,"?%d",i); | |
| 23703 zVar = zNum; | |
| 23704 } | |
| 23705 sqlite3_bind_text(pQ, 1, zVar, -1, SQLITE_STATIC); | |
| 23706 if( rc==SQLITE_OK && pQ && sqlite3_step(pQ)==SQLITE_ROW ){ | |
| 23707 sqlite3_bind_value(pStmt, i, sqlite3_column_value(pQ, 0)); | |
| 23708 #ifdef NAN | |
| 23709 }else if( sqlite3_strlike("_NAN", zVar, 0)==0 ){ | |
| 23710 sqlite3_bind_double(pStmt, i, NAN); | |
| 23711 #endif | |
| 23712 #ifdef INFINITY | |
| 23713 }else if( sqlite3_strlike("_INF", zVar, 0)==0 ){ | |
| 23714 sqlite3_bind_double(pStmt, i, INFINITY); | |
| 23715 #endif | |
| 23716 }else if( strncmp(zVar, "$int_", 5)==0 ){ | |
| 23717 sqlite3_bind_int(pStmt, i, atoi(&zVar[5])); | |
| 23718 }else if( strncmp(zVar, "$text_", 6)==0 ){ | |
| 23719 size_t szVar = strlen(zVar); | |
| 23720 char *zBuf = sqlite3_malloc64( szVar-5 ); | |
| 23721 if( zBuf ){ | |
| 23722 memcpy(zBuf, &zVar[6], szVar-5); | |
| 23723 sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8); | |
| 23724 } | |
| 23725 #ifdef SQLITE_ENABLE_CARRAY | |
| 23726 }else if( strncmp(zVar, "$carray_", 8)==0 ){ | |
| 23727 static char *azColorNames[] = { | |
| 23728 "azure", "black", "blue", "brown", "cyan", "fuchsia", "gold", | |
| 23729 "gray", "green", "indigo", "khaki", "lime", "magenta", "maroon", | |
| 23730 "navy", "olive", "orange", "pink", "purple", "red", "silver", | |
| 23731 "tan", "teal", "violet", "white", "yellow" | |
| 23732 }; | |
| 23733 static int aPrimes[] = { | |
| 23734 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, | |
| 23735 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 | |
| 23736 }; | |
| 23737 /* Special bindings: carray($carray_clr), carray($carray_primes) | |
| 23738 ** with --unsafe-testing: carray($carray_clr_p,26,'char*'), | |
| 23739 ** carray($carray_primes_p,26,'int32') | |
| 23740 */ | |
| 23741 if( strcmp(zVar+8,"clr")==0 ){ | |
| 23742 sqlite3_carray_bind(pStmt,i,azColorNames,26,SQLITE_CARRAY_TEXT,0); | |
| 23743 }else if( strcmp(zVar+8,"primes")==0 ){ | |
| 23744 sqlite3_carray_bind(pStmt,i,aPrimes,26,SQLITE_CARRAY_INT32,0); | |
| 23745 }else if( strcmp(zVar+8,"clr_p")==0 | |
| 23746 && ShellHasFlag(pArg,SHFLG_TestingMode) ){ | |
| 23747 sqlite3_bind_pointer(pStmt,i,azColorNames,"carray",0); | |
| 23748 }else if( strcmp(zVar+8,"primes_p")==0 | |
| 23749 && ShellHasFlag(pArg,SHFLG_TestingMode) ){ | |
| 23750 sqlite3_bind_pointer(pStmt,i,aPrimes,"carray",0); | |
| 23751 }else{ | |
| 23752 sqlite3_bind_null(pStmt, i); | |
| 23753 } | |
| 23754 #endif | |
| 23755 }else{ | |
| 23756 sqlite3_bind_null(pStmt, i); | |
| 23757 } | |
| 23758 sqlite3_reset(pQ); | |
| 23759 } | |
| 23760 sqlite3_finalize(pQ); | |
| 23761 } | |
| 23762 | |
| 23763 /* | |
| 23764 ** UTF8 box-drawing characters. Imagine box lines like this: | |
| 23765 ** | |
| 23766 ** 1 | |
| 23767 ** | | |
| 23768 ** 4 --+-- 2 | |
| 23769 ** | | |
| 23770 ** 3 | |
| 23771 ** | |
| 23772 ** Each box characters has between 2 and 4 of the lines leading from | |
| 23773 ** the center. The characters are here identified by the numbers of | |
| 23774 ** their corresponding lines. | |
| 23775 */ | |
| 23776 #define BOX_24 "\342\224\200" /* U+2500 --- */ | |
| 23777 #define BOX_13 "\342\224\202" /* U+2502 | */ | |
| 23778 #define BOX_23 "\342\224\214" /* U+250c ,- */ | |
| 23779 #define BOX_34 "\342\224\220" /* U+2510 -, */ | |
| 23780 #define BOX_12 "\342\224\224" /* U+2514 '- */ | |
| 23781 #define BOX_14 "\342\224\230" /* U+2518 -' */ | |
| 23782 #define BOX_123 "\342\224\234" /* U+251c |- */ | |
| 23783 #define BOX_134 "\342\224\244" /* U+2524 -| */ | |
| 23784 #define BOX_234 "\342\224\254" /* U+252c -,- */ | |
| 23785 #define BOX_124 "\342\224\264" /* U+2534 -'- */ | |
| 23786 #define BOX_1234 "\342\224\274" /* U+253c -|- */ | |
| 23787 | |
| 23788 /* Draw horizontal line N characters long using unicode box | |
| 23789 ** characters | |
| 23790 */ | |
| 23791 static void print_box_line(FILE *out, int N){ | |
| 23792 const char zDash[] = | |
| 23793 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 | |
| 23794 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24; | |
| 23795 const int nDash = sizeof(zDash) - 1; | |
| 23796 N *= 3; | |
| 23797 while( N>nDash ){ | |
| 23798 sqlite3_fputs(zDash, out); | |
| 23799 N -= nDash; | |
| 23800 } | |
| 23801 sqlite3_fprintf(out, "%.*s", N, zDash); | |
| 23802 } | |
| 23803 | |
| 23804 /* | |
| 23805 ** Draw a horizontal separator for a MODE_Box table. | |
| 23806 */ | |
| 23807 static void print_box_row_separator( | |
| 23808 ShellState *p, | |
| 23809 int nArg, | |
| 23810 const char *zSep1, | |
| 23811 const char *zSep2, | |
| 23812 const char *zSep3 | |
| 23813 ){ | |
| 23814 int i; | |
| 23815 if( nArg>0 ){ | |
| 23816 sqlite3_fputs(zSep1, p->out); | |
| 23817 print_box_line(p->out, p->actualWidth[0]+2); | |
| 23818 for(i=1; i<nArg; i++){ | |
| 23819 sqlite3_fputs(zSep2, p->out); | |
| 23820 print_box_line(p->out, p->actualWidth[i]+2); | |
| 23821 } | |
| 23822 sqlite3_fputs(zSep3, p->out); | |
| 23823 } | |
| 23824 sqlite3_fputs("\n", p->out); | |
| 23825 } | |
| 23826 | |
| 23827 /* | |
| 23828 ** z[] is a line of text that is to be displayed the .mode box or table or | |
| 23829 ** similar tabular formats. z[] might contain control characters such | |
| 23830 ** as \n, \t, \f, or \r. | |
| 23831 ** | |
| 23832 ** Compute characters to display on the first line of z[]. Stop at the | |
| 23833 ** first \r, \n, or \f. Expand \t into spaces. Return a copy (obtained | |
| 23834 ** from malloc()) of that first line, which caller should free sometime. | |
| 23835 ** Write anything to display on the next line into *pzTail. If this is | |
| 23836 ** the last line, write a NULL into *pzTail. (*pzTail is not allocated.) | |
| 23837 */ | |
| 23838 static char *translateForDisplayAndDup( | |
| 23839 ShellState *p, /* To access current settings */ | |
| 23840 const unsigned char *z, /* Input text to be transformed */ | |
| 23841 const unsigned char **pzTail, /* OUT: Tail of the input for next line */ | |
| 23842 int mxWidth, /* Max width. 0 means no limit */ | |
| 23843 u8 bWordWrap /* If true, avoid breaking mid-word */ | |
| 23844 ){ | |
| 23845 int i; /* Input bytes consumed */ | |
| 23846 int j; /* Output bytes generated */ | |
| 23847 int k; /* Input bytes to be displayed */ | |
| 23848 int n; /* Output column number */ | |
| 23849 unsigned char *zOut; /* Output text */ | |
| 23850 | |
| 23851 if( z==0 ){ | |
| 23852 *pzTail = 0; | |
| 23853 return 0; | |
| 23854 } | |
| 23855 if( mxWidth<0 ) mxWidth = -mxWidth; | |
| 23856 if( mxWidth==0 ) mxWidth = 1000000; | |
| 23857 i = j = n = 0; | |
| 23858 while( n<mxWidth ){ | |
| 23859 unsigned char c = z[i]; | |
| 23860 if( c>=0xc0 ){ | |
| 23861 int u; | |
| 23862 int len = decodeUtf8(&z[i], &u); | |
| 23863 i += len; | |
| 23864 j += len; | |
| 23865 n += cli_wcwidth(u); | |
| 23866 continue; | |
| 23867 } | |
| 23868 if( c>=' ' ){ | |
| 23869 n++; | |
| 23870 i++; | |
| 23871 j++; | |
| 23872 continue; | |
| 23873 } | |
| 23874 if( c==0 || c=='\n' || (c=='\r' && z[i+1]=='\n') ) break; | |
| 23875 if( c=='\t' ){ | |
| 23876 do{ | |
| 23877 n++; | |
| 23878 j++; | |
| 23879 }while( (n&7)!=0 && n<mxWidth ); | |
| 23880 i++; | |
| 23881 continue; | |
| 23882 } | |
| 23883 if( c==0x1b && p->eEscMode==SHELL_ESC_OFF && (k = isVt100(&z[i]))>0 ){ | |
| 23884 i += k; | |
| 23885 j += k; | |
| 23886 }else{ | |
| 23887 n++; | |
| 23888 j += 3; | |
| 23889 i++; | |
| 23890 } | |
| 23891 } | |
| 23892 if( n>=mxWidth && bWordWrap ){ | |
| 23893 /* Perhaps try to back up to a better place to break the line */ | |
| 23894 for(k=i; k>i/2; k--){ | |
| 23895 if( IsSpace(z[k-1]) ) break; | |
| 23896 } | |
| 23897 if( k<=i/2 ){ | |
| 23898 for(k=i; k>i/2; k--){ | |
| 23899 if( IsAlnum(z[k-1])!=IsAlnum(z[k]) && (z[k]&0xc0)!=0x80 ) break; | |
| 23900 } | |
| 23901 } | |
| 23902 if( k<=i/2 ){ | |
| 23903 k = i; | |
| 23904 }else{ | |
| 23905 i = k; | |
| 23906 while( z[i]==' ' ) i++; | |
| 23907 } | |
| 23908 }else{ | |
| 23909 k = i; | |
| 23910 } | |
| 23911 if( n>=mxWidth && z[i]>=' ' ){ | |
| 23912 *pzTail = &z[i]; | |
| 23913 }else if( z[i]=='\r' && z[i+1]=='\n' ){ | |
| 23914 *pzTail = z[i+2] ? &z[i+2] : 0; | |
| 23915 }else if( z[i]==0 || z[i+1]==0 ){ | |
| 23916 *pzTail = 0; | |
| 23917 }else{ | |
| 23918 *pzTail = &z[i+1]; | |
| 23919 } | |
| 23920 zOut = malloc( j+1 ); | |
| 23921 shell_check_oom(zOut); | |
| 23922 i = j = n = 0; | |
| 23923 while( i<k ){ | |
| 23924 unsigned char c = z[i]; | |
| 23925 if( c>=0xc0 ){ | |
| 23926 int u; | |
| 23927 int len = decodeUtf8(&z[i], &u); | |
| 23928 do{ zOut[j++] = z[i++]; }while( (--len)>0 ); | |
| 23929 n += cli_wcwidth(u); | |
| 23930 continue; | |
| 23931 } | |
| 23932 if( c>=' ' ){ | |
| 23933 n++; | |
| 23934 zOut[j++] = z[i++]; | |
| 23935 continue; | |
| 23936 } | |
| 23937 if( c==0 ) break; | |
| 23938 if( z[i]=='\t' ){ | |
| 23939 do{ | |
| 23940 n++; | |
| 23941 zOut[j++] = ' '; | |
| 23942 }while( (n&7)!=0 && n<mxWidth ); | |
| 23943 i++; | |
| 23944 continue; | |
| 23945 } | |
| 23946 switch( p->eEscMode ){ | |
| 23947 case SHELL_ESC_SYMBOL: | |
| 23948 zOut[j++] = 0xe2; | |
| 23949 zOut[j++] = 0x90; | |
| 23950 zOut[j++] = 0x80 + c; | |
| 23951 break; | |
| 23952 case SHELL_ESC_ASCII: | |
| 23953 zOut[j++] = '^'; | |
| 23954 zOut[j++] = 0x40 + c; | |
| 23955 break; | |
| 23956 case SHELL_ESC_OFF: { | |
| 23957 int nn; | |
| 23958 if( c==0x1b && (nn = isVt100(&z[i]))>0 ){ | |
| 23959 memcpy(&zOut[j], &z[i], nn); | |
| 23960 j += nn; | |
| 23961 i += nn - 1; | |
| 23962 }else{ | |
| 23963 zOut[j++] = c; | |
| 23964 } | |
| 23965 break; | |
| 23966 } | |
| 23967 } | |
| 23968 i++; | |
| 23969 } | |
| 23970 zOut[j] = 0; | |
| 23971 return (char*)zOut; | |
| 23972 } | |
| 23973 | |
| 23974 /* Return true if the text string z[] contains characters that need | |
| 23975 ** unistr() escaping. | |
| 23976 */ | |
| 23977 static int needUnistr(const unsigned char *z){ | |
| 23978 unsigned char c; | |
| 23979 if( z==0 ) return 0; | |
| 23980 while( (c = *z)>0x1f || c=='\t' || c=='\n' || (c=='\r' && z[1]=='\n') ){ z++; } | |
| 23981 return c!=0; | |
| 23982 } | |
| 23983 | |
| 23984 /* Extract the value of the i-th current column for pStmt as an SQL literal | |
| 23985 ** value. Memory is obtained from sqlite3_malloc64() and must be freed by | |
| 23986 ** the caller. | |
| 23987 */ | |
| 23988 static char *quoted_column(sqlite3_stmt *pStmt, int i){ | |
| 23989 switch( sqlite3_column_type(pStmt, i) ){ | |
| 23990 case SQLITE_NULL: { | |
| 23991 return sqlite3_mprintf("NULL"); | |
| 23992 } | |
| 23993 case SQLITE_INTEGER: | |
| 23994 case SQLITE_FLOAT: { | |
| 23995 return sqlite3_mprintf("%s",sqlite3_column_text(pStmt,i)); | |
| 23996 } | |
| 23997 case SQLITE_TEXT: { | |
| 23998 const unsigned char *zText = sqlite3_column_text(pStmt,i); | |
| 23999 return sqlite3_mprintf(needUnistr(zText)?"%#Q":"%Q",zText); | |
| 24000 } | |
| 24001 case SQLITE_BLOB: { | |
| 24002 int j; | |
| 24003 sqlite3_str *pStr = sqlite3_str_new(0); | |
| 24004 const unsigned char *a = sqlite3_column_blob(pStmt,i); | |
| 24005 int n = sqlite3_column_bytes(pStmt,i); | |
| 24006 sqlite3_str_append(pStr, "x'", 2); | |
| 24007 for(j=0; j<n; j++){ | |
| 24008 sqlite3_str_appendf(pStr, "%02x", a[j]); | |
| 24009 } | |
| 24010 sqlite3_str_append(pStr, "'", 1); | |
| 24011 return sqlite3_str_finish(pStr); | |
| 24012 } | |
| 24013 } | |
| 24014 return 0; /* Not reached */ | |
| 24015 } | |
| 24016 | |
| 24017 /* | |
| 24018 ** Run a prepared statement and output the result in one of the | |
| 24019 ** table-oriented formats: MODE_Column, MODE_Markdown, MODE_Table, | |
| 24020 ** or MODE_Box. | |
| 24021 ** | |
| 24022 ** This is different from ordinary exec_prepared_stmt() in that | |
| 24023 ** it has to run the entire query and gather the results into memory | |
| 24024 ** first, in order to determine column widths, before providing | |
| 24025 ** any output. | |
| 24026 */ | |
| 24027 static void exec_prepared_stmt_columnar( | |
| 24028 ShellState *p, /* Pointer to ShellState */ | |
| 24029 sqlite3_stmt *pStmt /* Statement to run */ | |
| 24030 ){ | |
| 24031 sqlite3_int64 nRow = 0; | |
| 24032 int nColumn = 0; | |
| 24033 char **azData = 0; | |
| 24034 sqlite3_int64 nAlloc = 0; | |
| 24035 char *abRowDiv = 0; | |
| 24036 const unsigned char *uz; | |
| 24037 const char *z; | |
| 24038 char **azQuoted = 0; | |
| 24039 int rc; | |
| 24040 sqlite3_int64 i, nData; | |
| 24041 int j, nTotal, w, n; | |
| 24042 const char *colSep = 0; | |
| 24043 const char *rowSep = 0; | |
| 24044 const unsigned char **azNextLine = 0; | |
| 24045 int bNextLine = 0; | |
| 24046 int bMultiLineRowExists = 0; | |
| 24047 int bw = p->cmOpts.bWordWrap; | |
| 24048 const char *zEmpty = ""; | |
| 24049 const char *zShowNull = p->nullValue; | |
| 24050 | |
| 24051 rc = sqlite3_step(pStmt); | |
| 24052 if( rc!=SQLITE_ROW ) return; | |
| 24053 nColumn = sqlite3_column_count(pStmt); | |
| 24054 if( nColumn==0 ) goto columnar_end; | |
| 24055 nAlloc = nColumn*4; | |
| 24056 if( nAlloc<=0 ) nAlloc = 1; | |
| 24057 azData = sqlite3_malloc64( nAlloc*sizeof(char*) ); | |
| 24058 shell_check_oom(azData); | |
| 24059 azNextLine = sqlite3_malloc64( nColumn*sizeof(char*) ); | |
| 24060 shell_check_oom(azNextLine); | |
| 24061 memset((void*)azNextLine, 0, nColumn*sizeof(char*) ); | |
| 24062 if( p->cmOpts.bQuote ){ | |
| 24063 azQuoted = sqlite3_malloc64( nColumn*sizeof(char*) ); | |
| 24064 shell_check_oom(azQuoted); | |
| 24065 memset(azQuoted, 0, nColumn*sizeof(char*) ); | |
| 24066 } | |
| 24067 abRowDiv = sqlite3_malloc64( nAlloc/nColumn ); | |
| 24068 shell_check_oom(abRowDiv); | |
| 24069 if( nColumn>p->nWidth ){ | |
| 24070 p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int)); | |
| 24071 shell_check_oom(p->colWidth); | |
| 24072 for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0; | |
| 24073 p->nWidth = nColumn; | |
| 24074 p->actualWidth = &p->colWidth[nColumn]; | |
| 24075 } | |
| 24076 memset(p->actualWidth, 0, nColumn*sizeof(int)); | |
| 24077 for(i=0; i<nColumn; i++){ | |
| 24078 w = p->colWidth[i]; | |
| 24079 if( w<0 ) w = -w; | |
| 24080 p->actualWidth[i] = w; | |
| 24081 } | |
| 24082 for(i=0; i<nColumn; i++){ | |
| 24083 const unsigned char *zNotUsed; | |
| 24084 int wx = p->colWidth[i]; | |
| 24085 if( wx==0 ){ | |
| 24086 wx = p->cmOpts.iWrap; | |
| 24087 } | |
| 24088 if( wx<0 ) wx = -wx; | |
| 24089 uz = (const unsigned char*)sqlite3_column_name(pStmt,i); | |
| 24090 if( uz==0 ) uz = (u8*)""; | |
| 24091 azData[i] = translateForDisplayAndDup(p, uz, &zNotUsed, wx, bw); | |
| 24092 } | |
| 24093 do{ | |
| 24094 int useNextLine = bNextLine; | |
| 24095 bNextLine = 0; | |
| 24096 if( (nRow+2)*nColumn >= nAlloc ){ | |
| 24097 nAlloc *= 2; | |
| 24098 azData = sqlite3_realloc64(azData, nAlloc*sizeof(char*)); | |
| 24099 shell_check_oom(azData); | |
| 24100 abRowDiv = sqlite3_realloc64(abRowDiv, nAlloc/nColumn); | |
| 24101 shell_check_oom(abRowDiv); | |
| 24102 } | |
| 24103 abRowDiv[nRow] = 1; | |
| 24104 nRow++; | |
| 24105 for(i=0; i<nColumn; i++){ | |
| 24106 int wx = p->colWidth[i]; | |
| 24107 if( wx==0 ){ | |
| 24108 wx = p->cmOpts.iWrap; | |
| 24109 } | |
| 24110 if( wx<0 ) wx = -wx; | |
| 24111 if( useNextLine ){ | |
| 24112 uz = azNextLine[i]; | |
| 24113 if( uz==0 ) uz = (u8*)zEmpty; | |
| 24114 }else if( p->cmOpts.bQuote ){ | |
| 24115 assert( azQuoted!=0 ); | |
| 24116 sqlite3_free(azQuoted[i]); | |
| 24117 azQuoted[i] = quoted_column(pStmt,i); | |
| 24118 uz = (const unsigned char*)azQuoted[i]; | |
| 24119 }else{ | |
| 24120 uz = (const unsigned char*)sqlite3_column_text(pStmt,i); | |
| 24121 if( uz==0 ) uz = (u8*)zShowNull; | |
| 24122 } | |
| 24123 azData[nRow*nColumn + i] | |
| 24124 = translateForDisplayAndDup(p, uz, &azNextLine[i], wx, bw); | |
| 24125 if( azNextLine[i] ){ | |
| 24126 bNextLine = 1; | |
| 24127 abRowDiv[nRow-1] = 0; | |
| 24128 bMultiLineRowExists = 1; | |
| 24129 } | |
| 24130 } | |
| 24131 }while( bNextLine || sqlite3_step(pStmt)==SQLITE_ROW ); | |
| 24132 nTotal = nColumn*(nRow+1); | |
| 24133 for(i=0; i<nTotal; i++){ | |
| 24134 z = azData[i]; | |
| 24135 if( z==0 ) z = (char*)zEmpty; | |
| 24136 n = strlenChar(z); | |
| 24137 j = i%nColumn; | |
| 24138 if( n>p->actualWidth[j] ) p->actualWidth[j] = n; | |
| 24139 } | |
| 24140 if( seenInterrupt ) goto columnar_end; | |
| 24141 switch( p->cMode ){ | |
| 24142 case MODE_Column: { | |
| 24143 colSep = " "; | |
| 24144 rowSep = "\n"; | |
| 24145 if( p->showHeader ){ | |
| 24146 for(i=0; i<nColumn; i++){ | |
| 24147 w = p->actualWidth[i]; | |
| 24148 if( p->colWidth[i]<0 ) w = -w; | |
| 24149 utf8_width_print(p->out, w, azData[i]); | |
| 24150 sqlite3_fputs(i==nColumn-1?"\n":" ", p->out); | |
| 24151 } | |
| 24152 for(i=0; i<nColumn; i++){ | |
| 24153 print_dashes(p->out, p->actualWidth[i]); | |
| 24154 sqlite3_fputs(i==nColumn-1?"\n":" ", p->out); | |
| 24155 } | |
| 24156 } | |
| 24157 break; | |
| 24158 } | |
| 24159 case MODE_Table: { | |
| 24160 colSep = " | "; | |
| 24161 rowSep = " |\n"; | |
| 24162 print_row_separator(p, nColumn, "+"); | |
| 24163 sqlite3_fputs("| ", p->out); | |
| 24164 for(i=0; i<nColumn; i++){ | |
| 24165 w = p->actualWidth[i]; | |
| 24166 n = strlenChar(azData[i]); | |
| 24167 sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "", | |
| 24168 azData[i], (w-n+1)/2, ""); | |
| 24169 sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out); | |
| 24170 } | |
| 24171 print_row_separator(p, nColumn, "+"); | |
| 24172 break; | |
| 24173 } | |
| 24174 case MODE_Markdown: { | |
| 24175 colSep = " | "; | |
| 24176 rowSep = " |\n"; | |
| 24177 sqlite3_fputs("| ", p->out); | |
| 24178 for(i=0; i<nColumn; i++){ | |
| 24179 w = p->actualWidth[i]; | |
| 24180 n = strlenChar(azData[i]); | |
| 24181 sqlite3_fprintf(p->out, "%*s%s%*s", (w-n)/2, "", | |
| 24182 azData[i], (w-n+1)/2, ""); | |
| 24183 sqlite3_fputs(i==nColumn-1?" |\n":" | ", p->out); | |
| 24184 } | |
| 24185 print_row_separator(p, nColumn, "|"); | |
| 24186 break; | |
| 24187 } | |
| 24188 case MODE_Box: { | |
| 24189 colSep = " " BOX_13 " "; | |
| 24190 rowSep = " " BOX_13 "\n"; | |
| 24191 print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34); | |
| 24192 sqlite3_fputs(BOX_13 " ", p->out); | |
| 24193 for(i=0; i<nColumn; i++){ | |
| 24194 w = p->actualWidth[i]; | |
| 24195 n = strlenChar(azData[i]); | |
| 24196 sqlite3_fprintf(p->out, "%*s%s%*s%s", | |
| 24197 (w-n)/2, "", azData[i], (w-n+1)/2, "", | |
| 24198 i==nColumn-1?" "BOX_13"\n":" "BOX_13" "); | |
| 24199 } | |
| 24200 print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134); | |
| 24201 break; | |
| 24202 } | |
| 24203 } | |
| 24204 for(i=nColumn, j=0; i<nTotal; i++, j++){ | |
| 24205 if( j==0 && p->cMode!=MODE_Column ){ | |
| 24206 sqlite3_fputs(p->cMode==MODE_Box?BOX_13" ":"| ", p->out); | |
| 24207 } | |
| 24208 z = azData[i]; | |
| 24209 if( z==0 ) z = p->nullValue; | |
| 24210 w = p->actualWidth[j]; | |
| 24211 if( p->colWidth[j]<0 ) w = -w; | |
| 24212 utf8_width_print(p->out, w, z); | |
| 24213 if( j==nColumn-1 ){ | |
| 24214 sqlite3_fputs(rowSep, p->out); | |
| 24215 if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1<nTotal ){ | |
| 24216 if( p->cMode==MODE_Table ){ | |
| 24217 print_row_separator(p, nColumn, "+"); | |
| 24218 }else if( p->cMode==MODE_Box ){ | |
| 24219 print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134); | |
| 24220 }else if( p->cMode==MODE_Column ){ | |
| 24221 sqlite3_fputs("\n", p->out); | |
| 24222 } | |
| 24223 } | |
| 24224 j = -1; | |
| 24225 if( seenInterrupt ) goto columnar_end; | |
| 24226 }else{ | |
| 24227 sqlite3_fputs(colSep, p->out); | |
| 24228 } | |
| 24229 } | |
| 24230 if( p->cMode==MODE_Table ){ | |
| 24231 print_row_separator(p, nColumn, "+"); | |
| 24232 }else if( p->cMode==MODE_Box ){ | |
| 24233 print_box_row_separator(p, nColumn, BOX_12, BOX_124, BOX_14); | |
| 24234 } | |
| 24235 columnar_end: | |
| 24236 if( seenInterrupt ){ | |
| 24237 sqlite3_fputs("Interrupt\n", p->out); | |
| 24238 } | |
| 24239 nData = (nRow+1)*nColumn; | |
| 24240 for(i=0; i<nData; i++){ | |
| 24241 z = azData[i]; | |
| 24242 if( z!=zEmpty && z!=zShowNull ) free(azData[i]); | |
| 24243 } | |
| 24244 sqlite3_free(azData); | |
| 24245 sqlite3_free((void*)azNextLine); | |
| 24246 sqlite3_free(abRowDiv); | |
| 24247 if( azQuoted ){ | |
| 24248 for(i=0; i<nColumn; i++) sqlite3_free(azQuoted[i]); | |
| 24249 sqlite3_free(azQuoted); | |
| 24250 } | |
| 24251 } | |
| 24252 | |
| 24253 /* | |
| 24254 ** Run a prepared statement | |
| 24255 */ | |
| 24256 static void exec_prepared_stmt( | |
| 24257 ShellState *pArg, /* Pointer to ShellState */ | |
| 24258 sqlite3_stmt *pStmt /* Statement to run */ | |
| 24259 ){ | |
| 24260 int rc; | |
| 24261 sqlite3_uint64 nRow = 0; | |
| 24262 | |
| 24263 if( pArg->cMode==MODE_Column | |
| 24264 || pArg->cMode==MODE_Table | |
| 24265 || pArg->cMode==MODE_Box | |
| 24266 || pArg->cMode==MODE_Markdown | |
| 24267 ){ | |
| 24268 exec_prepared_stmt_columnar(pArg, pStmt); | |
| 24269 return; | |
| 24270 } | |
| 24271 | |
| 24272 /* perform the first step. this will tell us if we | |
| 24273 ** have a result set or not and how wide it is. | |
| 24274 */ | |
| 24275 rc = sqlite3_step(pStmt); | |
| 24276 /* if we have a result set... */ | |
| 24277 if( SQLITE_ROW == rc ){ | |
| 24278 /* allocate space for col name ptr, value ptr, and type */ | |
| 24279 int nCol = sqlite3_column_count(pStmt); | |
| 24280 void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1); | |
| 24281 if( !pData ){ | |
| 24282 shell_out_of_memory(); | |
| 24283 }else{ | |
| 24284 char **azCols = (char **)pData; /* Names of result columns */ | |
| 24285 char **azVals = &azCols[nCol]; /* Results */ | |
| 24286 int *aiTypes = (int *)&azVals[nCol]; /* Result types */ | |
| 24287 int i, x; | |
| 24288 assert(sizeof(int) <= sizeof(char *)); | |
| 24289 /* save off ptrs to column names */ | |
| 24290 for(i=0; i<nCol; i++){ | |
| 24291 azCols[i] = (char *)sqlite3_column_name(pStmt, i); | |
| 24292 } | |
| 24293 do{ | |
| 24294 nRow++; | |
| 24295 /* extract the data and data types */ | |
| 24296 for(i=0; i<nCol; i++){ | |
| 24297 aiTypes[i] = x = sqlite3_column_type(pStmt, i); | |
| 24298 if( x==SQLITE_BLOB | |
| 24299 && pArg | |
| 24300 && (pArg->cMode==MODE_Insert || pArg->cMode==MODE_Quote) | |
| 24301 ){ | |
| 24302 azVals[i] = ""; | |
| 24303 }else{ | |
| 24304 azVals[i] = (char*)sqlite3_column_text(pStmt, i); | |
| 24305 } | |
| 24306 if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){ | |
| 24307 rc = SQLITE_NOMEM; | |
| 24308 break; /* from for */ | |
| 24309 } | |
| 24310 } /* end for */ | |
| 24311 | |
| 24312 /* if data and types extracted successfully... */ | |
| 24313 if( SQLITE_ROW == rc ){ | |
| 24314 /* call the supplied callback with the result row data */ | |
| 24315 if( shell_callback(pArg, nCol, azVals, azCols, aiTypes) ){ | |
| 24316 rc = SQLITE_ABORT; | |
| 24317 }else{ | |
| 24318 rc = sqlite3_step(pStmt); | |
| 24319 } | |
| 24320 } | |
| 24321 } while( SQLITE_ROW == rc ); | |
| 24322 sqlite3_free(pData); | |
| 24323 if( pArg->cMode==MODE_Json ){ | |
| 24324 sqlite3_fputs("]\n", pArg->out); | |
| 24325 }else if( pArg->cMode==MODE_Www ){ | |
| 24326 sqlite3_fputs("</TABLE>\n<PRE>\n", pArg->out); | |
| 24327 }else if( pArg->cMode==MODE_Count ){ | |
| 24328 char zBuf[200]; | |
| 24329 sqlite3_snprintf(sizeof(zBuf), zBuf, "%llu row%s\n", | |
| 24330 nRow, nRow!=1 ? "s" : ""); | |
| 24331 printf("%s", zBuf); | |
| 24332 } | |
| 24333 } | |
| 24334 } | |
| 24335 } | |
| 24336 | |
| 24337 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 24338 /* | |
| 24339 ** This function is called to process SQL if the previous shell command | |
| 24340 ** was ".expert". It passes the SQL in the second argument directly to | |
| 24341 ** the sqlite3expert object. | |
| 24342 ** | |
| 24343 ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error | |
| 24344 ** code. In this case, (*pzErr) may be set to point to a buffer containing | |
| 24345 ** an English language error message. It is the responsibility of the | |
| 24346 ** caller to eventually free this buffer using sqlite3_free(). | |
| 24347 */ | |
| 24348 static int expertHandleSQL( | |
| 24349 ShellState *pState, | |
| 24350 const char *zSql, | |
| 24351 char **pzErr | |
| 24352 ){ | |
| 24353 assert( pState->expert.pExpert ); | |
| 24354 assert( pzErr==0 || *pzErr==0 ); | |
| 24355 return sqlite3_expert_sql(pState->expert.pExpert, zSql, pzErr); | |
| 24356 } | |
| 24357 | |
| 24358 /* | |
| 24359 ** This function is called either to silently clean up the object | |
| 24360 ** created by the ".expert" command (if bCancel==1), or to generate a | |
| 24361 ** report from it and then clean it up (if bCancel==0). | |
| 24362 ** | |
| 24363 ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error | |
| 24364 ** code. In this case, (*pzErr) may be set to point to a buffer containing | |
| 24365 ** an English language error message. It is the responsibility of the | |
| 24366 ** caller to eventually free this buffer using sqlite3_free(). | |
| 24367 */ | |
| 24368 static int expertFinish( | |
| 24369 ShellState *pState, | |
| 24370 int bCancel, | |
| 24371 char **pzErr | |
| 24372 ){ | |
| 24373 int rc = SQLITE_OK; | |
| 24374 sqlite3expert *p = pState->expert.pExpert; | |
| 24375 FILE *out = pState->out; | |
| 24376 assert( p ); | |
| 24377 assert( bCancel || pzErr==0 || *pzErr==0 ); | |
| 24378 if( bCancel==0 ){ | |
| 24379 int bVerbose = pState->expert.bVerbose; | |
| 24380 | |
| 24381 rc = sqlite3_expert_analyze(p, pzErr); | |
| 24382 if( rc==SQLITE_OK ){ | |
| 24383 int nQuery = sqlite3_expert_count(p); | |
| 24384 int i; | |
| 24385 | |
| 24386 if( bVerbose ){ | |
| 24387 const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES); | |
| 24388 sqlite3_fputs("-- Candidates -----------------------------\n", out); | |
| 24389 sqlite3_fprintf(out, "%s\n", zCand); | |
| 24390 } | |
| 24391 for(i=0; i<nQuery; i++){ | |
| 24392 const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL); | |
| 24393 const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES); | |
| 24394 const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN); | |
| 24395 if( zIdx==0 ) zIdx = "(no new indexes)\n"; | |
| 24396 if( bVerbose ){ | |
| 24397 sqlite3_fprintf(out, | |
| 24398 "-- Query %d --------------------------------\n" | |
| 24399 "%s\n\n" | |
| 24400 ,i+1, zSql); | |
| 24401 } | |
| 24402 sqlite3_fprintf(out, "%s\n%s\n", zIdx, zEQP); | |
| 24403 } | |
| 24404 } | |
| 24405 } | |
| 24406 sqlite3_expert_destroy(p); | |
| 24407 pState->expert.pExpert = 0; | |
| 24408 return rc; | |
| 24409 } | |
| 24410 | |
| 24411 /* | |
| 24412 ** Implementation of ".expert" dot command. | |
| 24413 */ | |
| 24414 static int expertDotCommand( | |
| 24415 ShellState *pState, /* Current shell tool state */ | |
| 24416 char **azArg, /* Array of arguments passed to dot command */ | |
| 24417 int nArg /* Number of entries in azArg[] */ | |
| 24418 ){ | |
| 24419 int rc = SQLITE_OK; | |
| 24420 char *zErr = 0; | |
| 24421 int i; | |
| 24422 int iSample = 0; | |
| 24423 | |
| 24424 assert( pState->expert.pExpert==0 ); | |
| 24425 memset(&pState->expert, 0, sizeof(ExpertInfo)); | |
| 24426 | |
| 24427 for(i=1; rc==SQLITE_OK && i<nArg; i++){ | |
| 24428 char *z = azArg[i]; | |
| 24429 int n; | |
| 24430 if( z[0]=='-' && z[1]=='-' ) z++; | |
| 24431 n = strlen30(z); | |
| 24432 if( n>=2 && 0==cli_strncmp(z, "-verbose", n) ){ | |
| 24433 pState->expert.bVerbose = 1; | |
| 24434 } | |
| 24435 else if( n>=2 && 0==cli_strncmp(z, "-sample", n) ){ | |
| 24436 if( i==(nArg-1) ){ | |
| 24437 sqlite3_fprintf(stderr, "option requires an argument: %s\n", z); | |
| 24438 rc = SQLITE_ERROR; | |
| 24439 }else{ | |
| 24440 iSample = (int)integerValue(azArg[++i]); | |
| 24441 if( iSample<0 || iSample>100 ){ | |
| 24442 sqlite3_fprintf(stderr,"value out of range: %s\n", azArg[i]); | |
| 24443 rc = SQLITE_ERROR; | |
| 24444 } | |
| 24445 } | |
| 24446 } | |
| 24447 else{ | |
| 24448 sqlite3_fprintf(stderr,"unknown option: %s\n", z); | |
| 24449 rc = SQLITE_ERROR; | |
| 24450 } | |
| 24451 } | |
| 24452 | |
| 24453 if( rc==SQLITE_OK ){ | |
| 24454 pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr); | |
| 24455 if( pState->expert.pExpert==0 ){ | |
| 24456 sqlite3_fprintf(stderr, | |
| 24457 "sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory"); | |
| 24458 rc = SQLITE_ERROR; | |
| 24459 }else{ | |
| 24460 sqlite3_expert_config( | |
| 24461 pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample | |
| 24462 ); | |
| 24463 } | |
| 24464 } | |
| 24465 sqlite3_free(zErr); | |
| 24466 | |
| 24467 return rc; | |
| 24468 } | |
| 24469 #endif /* !SQLITE_OMIT_VIRTUALTABLE && !SQLITE_OMIT_AUTHORIZATION */ | |
| 24470 | |
| 24471 /* | |
| 24472 ** Execute a statement or set of statements. Print | |
| 24473 ** any result rows/columns depending on the current mode | |
| 24474 ** set via the supplied callback. | |
| 24475 ** | |
| 24476 ** This is very similar to SQLite's built-in sqlite3_exec() | |
| 24477 ** function except it takes a slightly different callback | |
| 24478 ** and callback data argument. | |
| 24479 */ | |
| 24480 static int shell_exec( | |
| 24481 ShellState *pArg, /* Pointer to ShellState */ | |
| 24482 const char *zSql, /* SQL to be evaluated */ | |
| 24483 char **pzErrMsg /* Error msg written here */ | |
| 24484 ){ | |
| 24485 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */ | |
| 24486 int rc = SQLITE_OK; /* Return Code */ | |
| 24487 int rc2; | |
| 24488 const char *zLeftover; /* Tail of unprocessed SQL */ | |
| 24489 sqlite3 *db = pArg->db; | |
| 24490 | |
| 24491 if( pzErrMsg ){ | |
| 24492 *pzErrMsg = NULL; | |
| 24493 } | |
| 24494 | |
| 24495 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 24496 if( pArg->expert.pExpert ){ | |
| 24497 rc = expertHandleSQL(pArg, zSql, pzErrMsg); | |
| 24498 return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg); | |
| 24499 } | |
| 24500 #endif | |
| 24501 | |
| 24502 while( zSql[0] && (SQLITE_OK == rc) ){ | |
| 24503 static const char *zStmtSql; | |
| 24504 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); | |
| 24505 if( SQLITE_OK != rc ){ | |
| 24506 if( pzErrMsg ){ | |
| 24507 *pzErrMsg = save_err_msg(db, "in prepare", rc, zSql); | |
| 24508 } | |
| 24509 }else{ | |
| 24510 if( !pStmt ){ | |
| 24511 /* this happens for a comment or white-space */ | |
| 24512 zSql = zLeftover; | |
| 24513 while( IsSpace(zSql[0]) ) zSql++; | |
| 24514 continue; | |
| 24515 } | |
| 24516 zStmtSql = sqlite3_sql(pStmt); | |
| 24517 if( zStmtSql==0 ) zStmtSql = ""; | |
| 24518 while( IsSpace(zStmtSql[0]) ) zStmtSql++; | |
| 24519 | |
| 24520 /* save off the prepared statement handle and reset row count */ | |
| 24521 if( pArg ){ | |
| 24522 pArg->pStmt = pStmt; | |
| 24523 pArg->cnt = 0; | |
| 24524 } | |
| 24525 | |
| 24526 /* Show the EXPLAIN QUERY PLAN if .eqp is on */ | |
| 24527 if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){ | |
| 24528 sqlite3_stmt *pExplain; | |
| 24529 int triggerEQP = 0; | |
| 24530 disable_debug_trace_modes(); | |
| 24531 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP); | |
| 24532 if( pArg->autoEQP>=AUTOEQP_trigger ){ | |
| 24533 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0); | |
| 24534 } | |
| 24535 pExplain = pStmt; | |
| 24536 sqlite3_reset(pExplain); | |
| 24537 rc = sqlite3_stmt_explain(pExplain, 2); | |
| 24538 if( rc==SQLITE_OK ){ | |
| 24539 bind_prepared_stmt(pArg, pExplain); | |
| 24540 while( sqlite3_step(pExplain)==SQLITE_ROW ){ | |
| 24541 const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3); | |
| 24542 int iEqpId = sqlite3_column_int(pExplain, 0); | |
| 24543 int iParentId = sqlite3_column_int(pExplain, 1); | |
| 24544 if( zEQPLine==0 ) zEQPLine = ""; | |
| 24545 if( zEQPLine[0]=='-' ) eqp_render(pArg, 0); | |
| 24546 eqp_append(pArg, iEqpId, iParentId, zEQPLine); | |
| 24547 } | |
| 24548 eqp_render(pArg, 0); | |
| 24549 } | |
| 24550 if( pArg->autoEQP>=AUTOEQP_full ){ | |
| 24551 /* Also do an EXPLAIN for ".eqp full" mode */ | |
| 24552 sqlite3_reset(pExplain); | |
| 24553 rc = sqlite3_stmt_explain(pExplain, 1); | |
| 24554 if( rc==SQLITE_OK ){ | |
| 24555 pArg->cMode = MODE_Explain; | |
| 24556 assert( sqlite3_stmt_isexplain(pExplain)==1 ); | |
| 24557 bind_prepared_stmt(pArg, pExplain); | |
| 24558 explain_data_prepare(pArg, pExplain); | |
| 24559 exec_prepared_stmt(pArg, pExplain); | |
| 24560 explain_data_delete(pArg); | |
| 24561 } | |
| 24562 } | |
| 24563 if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){ | |
| 24564 sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0); | |
| 24565 } | |
| 24566 sqlite3_reset(pStmt); | |
| 24567 sqlite3_stmt_explain(pStmt, 0); | |
| 24568 restore_debug_trace_modes(); | |
| 24569 } | |
| 24570 | |
| 24571 if( pArg ){ | |
| 24572 int bIsExplain = (sqlite3_stmt_isexplain(pStmt)==1); | |
| 24573 pArg->cMode = pArg->mode; | |
| 24574 if( pArg->autoExplain ){ | |
| 24575 if( bIsExplain ){ | |
| 24576 pArg->cMode = MODE_Explain; | |
| 24577 } | |
| 24578 if( sqlite3_stmt_isexplain(pStmt)==2 ){ | |
| 24579 pArg->cMode = MODE_EQP; | |
| 24580 } | |
| 24581 } | |
| 24582 | |
| 24583 /* If the shell is currently in ".explain" mode, gather the extra | |
| 24584 ** data required to add indents to the output.*/ | |
| 24585 if( pArg->cMode==MODE_Explain && bIsExplain ){ | |
| 24586 explain_data_prepare(pArg, pStmt); | |
| 24587 } | |
| 24588 } | |
| 24589 | |
| 24590 bind_prepared_stmt(pArg, pStmt); | |
| 24591 exec_prepared_stmt(pArg, pStmt); | |
| 24592 explain_data_delete(pArg); | |
| 24593 eqp_render(pArg, 0); | |
| 24594 | |
| 24595 /* print usage stats if stats on */ | |
| 24596 if( pArg && pArg->statsOn ){ | |
| 24597 display_stats(db, pArg, 0); | |
| 24598 } | |
| 24599 | |
| 24600 /* print loop-counters if required */ | |
| 24601 if( pArg && pArg->scanstatsOn ){ | |
| 24602 display_scanstats(db, pArg); | |
| 24603 } | |
| 24604 | |
| 24605 /* Finalize the statement just executed. If this fails, save a | |
| 24606 ** copy of the error message. Otherwise, set zSql to point to the | |
| 24607 ** next statement to execute. */ | |
| 24608 rc2 = sqlite3_finalize(pStmt); | |
| 24609 if( rc!=SQLITE_NOMEM ) rc = rc2; | |
| 24610 if( rc==SQLITE_OK ){ | |
| 24611 zSql = zLeftover; | |
| 24612 while( IsSpace(zSql[0]) ) zSql++; | |
| 24613 }else if( pzErrMsg ){ | |
| 24614 *pzErrMsg = save_err_msg(db, "stepping", rc, 0); | |
| 24615 } | |
| 24616 | |
| 24617 /* clear saved stmt handle */ | |
| 24618 if( pArg ){ | |
| 24619 pArg->pStmt = NULL; | |
| 24620 } | |
| 24621 } | |
| 24622 } /* end while */ | |
| 24623 | |
| 24624 return rc; | |
| 24625 } | |
| 24626 | |
| 24627 /* | |
| 24628 ** Release memory previously allocated by tableColumnList(). | |
| 24629 */ | |
| 24630 static void freeColumnList(char **azCol){ | |
| 24631 int i; | |
| 24632 for(i=1; azCol[i]; i++){ | |
| 24633 sqlite3_free(azCol[i]); | |
| 24634 } | |
| 24635 /* azCol[0] is a static string */ | |
| 24636 sqlite3_free(azCol); | |
| 24637 } | |
| 24638 | |
| 24639 /* | |
| 24640 ** Return a list of pointers to strings which are the names of all | |
| 24641 ** columns in table zTab. The memory to hold the names is dynamically | |
| 24642 ** allocated and must be released by the caller using a subsequent call | |
| 24643 ** to freeColumnList(). | |
| 24644 ** | |
| 24645 ** The azCol[0] entry is usually NULL. However, if zTab contains a rowid | |
| 24646 ** value that needs to be preserved, then azCol[0] is filled in with the | |
| 24647 ** name of the rowid column. | |
| 24648 ** | |
| 24649 ** The first regular column in the table is azCol[1]. The list is terminated | |
| 24650 ** by an entry with azCol[i]==0. | |
| 24651 */ | |
| 24652 static char **tableColumnList(ShellState *p, const char *zTab){ | |
| 24653 char **azCol = 0; | |
| 24654 sqlite3_stmt *pStmt; | |
| 24655 char *zSql; | |
| 24656 int nCol = 0; | |
| 24657 i64 nAlloc = 0; | |
| 24658 int nPK = 0; /* Number of PRIMARY KEY columns seen */ | |
| 24659 int isIPK = 0; /* True if one PRIMARY KEY column of type INTEGER */ | |
| 24660 int preserveRowid = ShellHasFlag(p, SHFLG_PreserveRowid); | |
| 24661 int rc; | |
| 24662 | |
| 24663 zSql = sqlite3_mprintf("PRAGMA table_info=%Q", zTab); | |
| 24664 shell_check_oom(zSql); | |
| 24665 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); | |
| 24666 sqlite3_free(zSql); | |
| 24667 if( rc ) return 0; | |
| 24668 while( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 24669 if( nCol>=nAlloc-2 ){ | |
| 24670 nAlloc = nAlloc*2 + nCol + 10; | |
| 24671 azCol = sqlite3_realloc64(azCol, nAlloc*sizeof(azCol[0])); | |
| 24672 shell_check_oom(azCol); | |
| 24673 } | |
| 24674 azCol[++nCol] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1)); | |
| 24675 shell_check_oom(azCol[nCol]); | |
| 24676 if( sqlite3_column_int(pStmt, 5) ){ | |
| 24677 nPK++; | |
| 24678 if( nPK==1 | |
| 24679 && sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,2), | |
| 24680 "INTEGER")==0 | |
| 24681 ){ | |
| 24682 isIPK = 1; | |
| 24683 }else{ | |
| 24684 isIPK = 0; | |
| 24685 } | |
| 24686 } | |
| 24687 } | |
| 24688 sqlite3_finalize(pStmt); | |
| 24689 if( azCol==0 ) return 0; | |
| 24690 azCol[0] = 0; | |
| 24691 azCol[nCol+1] = 0; | |
| 24692 | |
| 24693 /* The decision of whether or not a rowid really needs to be preserved | |
| 24694 ** is tricky. We never need to preserve a rowid for a WITHOUT ROWID table | |
| 24695 ** or a table with an INTEGER PRIMARY KEY. We are unable to preserve | |
| 24696 ** rowids on tables where the rowid is inaccessible because there are other | |
| 24697 ** columns in the table named "rowid", "_rowid_", and "oid". | |
| 24698 */ | |
| 24699 if( preserveRowid && isIPK ){ | |
| 24700 /* If a single PRIMARY KEY column with type INTEGER was seen, then it | |
| 24701 ** might be an alias for the ROWID. But it might also be a WITHOUT ROWID | |
| 24702 ** table or a INTEGER PRIMARY KEY DESC column, neither of which are | |
| 24703 ** ROWID aliases. To distinguish these cases, check to see if | |
| 24704 ** there is a "pk" entry in "PRAGMA index_list". There will be | |
| 24705 ** no "pk" index if the PRIMARY KEY really is an alias for the ROWID. | |
| 24706 */ | |
| 24707 zSql = sqlite3_mprintf("SELECT 1 FROM pragma_index_list(%Q)" | |
| 24708 " WHERE origin='pk'", zTab); | |
| 24709 shell_check_oom(zSql); | |
| 24710 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); | |
| 24711 sqlite3_free(zSql); | |
| 24712 if( rc ){ | |
| 24713 freeColumnList(azCol); | |
| 24714 return 0; | |
| 24715 } | |
| 24716 rc = sqlite3_step(pStmt); | |
| 24717 sqlite3_finalize(pStmt); | |
| 24718 preserveRowid = rc==SQLITE_ROW; | |
| 24719 } | |
| 24720 if( preserveRowid ){ | |
| 24721 /* Only preserve the rowid if we can find a name to use for the | |
| 24722 ** rowid */ | |
| 24723 static char *azRowid[] = { "rowid", "_rowid_", "oid" }; | |
| 24724 int i, j; | |
| 24725 for(j=0; j<3; j++){ | |
| 24726 for(i=1; i<=nCol; i++){ | |
| 24727 if( sqlite3_stricmp(azRowid[j],azCol[i])==0 ) break; | |
| 24728 } | |
| 24729 if( i>nCol ){ | |
| 24730 /* At this point, we know that azRowid[j] is not the name of any | |
| 24731 ** ordinary column in the table. Verify that azRowid[j] is a valid | |
| 24732 ** name for the rowid before adding it to azCol[0]. WITHOUT ROWID | |
| 24733 ** tables will fail this last check */ | |
| 24734 rc = sqlite3_table_column_metadata(p->db,0,zTab,azRowid[j],0,0,0,0,0); | |
| 24735 if( rc==SQLITE_OK ) azCol[0] = azRowid[j]; | |
| 24736 break; | |
| 24737 } | |
| 24738 } | |
| 24739 } | |
| 24740 return azCol; | |
| 24741 } | |
| 24742 | |
| 24743 /* | |
| 24744 ** Toggle the reverse_unordered_selects setting. | |
| 24745 */ | |
| 24746 static void toggleSelectOrder(sqlite3 *db){ | |
| 24747 sqlite3_stmt *pStmt = 0; | |
| 24748 int iSetting = 0; | |
| 24749 char zStmt[100]; | |
| 24750 sqlite3_prepare_v2(db, "PRAGMA reverse_unordered_selects", -1, &pStmt, 0); | |
| 24751 if( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 24752 iSetting = sqlite3_column_int(pStmt, 0); | |
| 24753 } | |
| 24754 sqlite3_finalize(pStmt); | |
| 24755 sqlite3_snprintf(sizeof(zStmt), zStmt, | |
| 24756 "PRAGMA reverse_unordered_selects(%d)", !iSetting); | |
| 24757 sqlite3_exec(db, zStmt, 0, 0, 0); | |
| 24758 } | |
| 24759 | |
| 24760 /* Forward reference */ | |
| 24761 static int db_int(sqlite3 *db, const char *zSql, ...); | |
| 24762 | |
| 24763 /* | |
| 24764 ** This is a different callback routine used for dumping the database. | |
| 24765 ** Each row received by this callback consists of a table name, | |
| 24766 ** the table type ("index" or "table") and SQL to create the table. | |
| 24767 ** This routine should print text sufficient to recreate the table. | |
| 24768 */ | |
| 24769 static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){ | |
| 24770 int rc; | |
| 24771 const char *zTable; | |
| 24772 const char *zType; | |
| 24773 const char *zSql; | |
| 24774 ShellState *p = (ShellState *)pArg; | |
| 24775 int dataOnly; | |
| 24776 int noSys; | |
| 24777 | |
| 24778 UNUSED_PARAMETER(azNotUsed); | |
| 24779 if( nArg!=3 || azArg==0 ) return 0; | |
| 24780 zTable = azArg[0]; | |
| 24781 zType = azArg[1]; | |
| 24782 zSql = azArg[2]; | |
| 24783 if( zTable==0 ) return 0; | |
| 24784 if( zType==0 ) return 0; | |
| 24785 dataOnly = (p->shellFlgs & SHFLG_DumpDataOnly)!=0; | |
| 24786 noSys = (p->shellFlgs & SHFLG_DumpNoSys)!=0; | |
| 24787 | |
| 24788 if( cli_strcmp(zTable, "sqlite_sequence")==0 && !noSys ){ | |
| 24789 /* The sqlite_sequence table is repopulated last. Delete content | |
| 24790 ** in the sqlite_sequence table added by prior repopulations prior to | |
| 24791 ** repopulating sqlite_sequence itself. But only do this if the | |
| 24792 ** table is non-empty, because if it is empty the table might not | |
| 24793 ** have been recreated by prior repopulations. See forum posts: | |
| 24794 ** 2024-10-13T17:10:01z and 2025-10-29T19:38:43z | |
| 24795 */ | |
| 24796 if( db_int(p->db, "SELECT count(*) FROM sqlite_sequence")>0 ){ | |
| 24797 if( !p->writableSchema ){ | |
| 24798 sqlite3_fputs("PRAGMA writable_schema=ON;\n", p->out); | |
| 24799 p->writableSchema = 1; | |
| 24800 } | |
| 24801 sqlite3_fputs("CREATE TABLE IF NOT EXISTS sqlite_sequence(name,seq);\n" | |
| 24802 "DELETE FROM sqlite_sequence;\n", p->out); | |
| 24803 } | |
| 24804 }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){ | |
| 24805 if( !dataOnly ) sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); | |
| 24806 }else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){ | |
| 24807 return 0; | |
| 24808 }else if( dataOnly ){ | |
| 24809 /* no-op */ | |
| 24810 }else if( cli_strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){ | |
| 24811 char *zIns; | |
| 24812 if( !p->writableSchema ){ | |
| 24813 sqlite3_fputs("PRAGMA writable_schema=ON;\n", p->out); | |
| 24814 p->writableSchema = 1; | |
| 24815 } | |
| 24816 zIns = sqlite3_mprintf( | |
| 24817 "INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)" | |
| 24818 "VALUES('table','%q','%q',0,'%q');", | |
| 24819 zTable, zTable, zSql); | |
| 24820 shell_check_oom(zIns); | |
| 24821 sqlite3_fprintf(p->out, "%s\n", zIns); | |
| 24822 sqlite3_free(zIns); | |
| 24823 return 0; | |
| 24824 }else{ | |
| 24825 printSchemaLine(p->out, zSql, ";\n"); | |
| 24826 } | |
| 24827 | |
| 24828 if( cli_strcmp(zType, "table")==0 ){ | |
| 24829 ShellText sSelect; | |
| 24830 ShellText sTable; | |
| 24831 char **azCol; | |
| 24832 int i; | |
| 24833 char *savedDestTable; | |
| 24834 int savedMode; | |
| 24835 | |
| 24836 azCol = tableColumnList(p, zTable); | |
| 24837 if( azCol==0 ){ | |
| 24838 p->nErr++; | |
| 24839 return 0; | |
| 24840 } | |
| 24841 | |
| 24842 /* Always quote the table name, even if it appears to be pure ascii, | |
| 24843 ** in case it is a keyword. Ex: INSERT INTO "table" ... */ | |
| 24844 initText(&sTable); | |
| 24845 appendText(&sTable, zTable, quoteChar(zTable)); | |
| 24846 /* If preserving the rowid, add a column list after the table name. | |
| 24847 ** In other words: "INSERT INTO tab(rowid,a,b,c,...) VALUES(...)" | |
| 24848 ** instead of the usual "INSERT INTO tab VALUES(...)". | |
| 24849 */ | |
| 24850 if( azCol[0] ){ | |
| 24851 appendText(&sTable, "(", 0); | |
| 24852 appendText(&sTable, azCol[0], 0); | |
| 24853 for(i=1; azCol[i]; i++){ | |
| 24854 appendText(&sTable, ",", 0); | |
| 24855 appendText(&sTable, azCol[i], quoteChar(azCol[i])); | |
| 24856 } | |
| 24857 appendText(&sTable, ")", 0); | |
| 24858 } | |
| 24859 | |
| 24860 /* Build an appropriate SELECT statement */ | |
| 24861 initText(&sSelect); | |
| 24862 appendText(&sSelect, "SELECT ", 0); | |
| 24863 if( azCol[0] ){ | |
| 24864 appendText(&sSelect, azCol[0], 0); | |
| 24865 appendText(&sSelect, ",", 0); | |
| 24866 } | |
| 24867 for(i=1; azCol[i]; i++){ | |
| 24868 appendText(&sSelect, azCol[i], quoteChar(azCol[i])); | |
| 24869 if( azCol[i+1] ){ | |
| 24870 appendText(&sSelect, ",", 0); | |
| 24871 } | |
| 24872 } | |
| 24873 freeColumnList(azCol); | |
| 24874 appendText(&sSelect, " FROM ", 0); | |
| 24875 appendText(&sSelect, zTable, quoteChar(zTable)); | |
| 24876 | |
| 24877 savedDestTable = p->zDestTable; | |
| 24878 savedMode = p->mode; | |
| 24879 p->zDestTable = sTable.zTxt; | |
| 24880 p->mode = p->cMode = MODE_Insert; | |
| 24881 rc = shell_exec(p, sSelect.zTxt, 0); | |
| 24882 if( (rc&0xff)==SQLITE_CORRUPT ){ | |
| 24883 sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out); | |
| 24884 toggleSelectOrder(p->db); | |
| 24885 shell_exec(p, sSelect.zTxt, 0); | |
| 24886 toggleSelectOrder(p->db); | |
| 24887 } | |
| 24888 p->zDestTable = savedDestTable; | |
| 24889 p->mode = savedMode; | |
| 24890 freeText(&sTable); | |
| 24891 freeText(&sSelect); | |
| 24892 if( rc ) p->nErr++; | |
| 24893 } | |
| 24894 return 0; | |
| 24895 } | |
| 24896 | |
| 24897 /* | |
| 24898 ** Run zQuery. Use dump_callback() as the callback routine so that | |
| 24899 ** the contents of the query are output as SQL statements. | |
| 24900 ** | |
| 24901 ** If we get a SQLITE_CORRUPT error, rerun the query after appending | |
| 24902 ** "ORDER BY rowid DESC" to the end. | |
| 24903 */ | |
| 24904 static int run_schema_dump_query( | |
| 24905 ShellState *p, | |
| 24906 const char *zQuery | |
| 24907 ){ | |
| 24908 int rc; | |
| 24909 char *zErr = 0; | |
| 24910 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr); | |
| 24911 if( rc==SQLITE_CORRUPT ){ | |
| 24912 char *zQ2; | |
| 24913 int len = strlen30(zQuery); | |
| 24914 sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out); | |
| 24915 if( zErr ){ | |
| 24916 sqlite3_fprintf(p->out, "/****** %s ******/\n", zErr); | |
| 24917 sqlite3_free(zErr); | |
| 24918 zErr = 0; | |
| 24919 } | |
| 24920 zQ2 = malloc( len+100 ); | |
| 24921 if( zQ2==0 ) return rc; | |
| 24922 sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery); | |
| 24923 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr); | |
| 24924 if( rc ){ | |
| 24925 sqlite3_fprintf(p->out, "/****** ERROR: %s ******/\n", zErr); | |
| 24926 }else{ | |
| 24927 rc = SQLITE_CORRUPT; | |
| 24928 } | |
| 24929 free(zQ2); | |
| 24930 } | |
| 24931 sqlite3_free(zErr); | |
| 24932 return rc; | |
| 24933 } | |
| 24934 | |
| 24935 /* | |
| 24936 ** Text of help messages. | |
| 24937 ** | |
| 24938 ** The help text for each individual command begins with a line that starts | |
| 24939 ** with ".". Subsequent lines are supplemental information. | |
| 24940 ** | |
| 24941 ** There must be two or more spaces between the end of the command and the | |
| 24942 ** start of the description of what that command does. | |
| 24943 */ | |
| 24944 static const char *(azHelp[]) = { | |
| 24945 #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) \ | |
| 24946 && !defined(SQLITE_SHELL_FIDDLE) | |
| 24947 ".archive ... Manage SQL archives", | |
| 24948 " Each command must have exactly one of the following options:", | |
| 24949 " -c, --create Create a new archive", | |
| 24950 " -u, --update Add or update files with changed mtime", | |
| 24951 " -i, --insert Like -u but always add even if unchanged", | |
| 24952 " -r, --remove Remove files from archive", | |
| 24953 " -t, --list List contents of archive", | |
| 24954 " -x, --extract Extract files from archive", | |
| 24955 " Optional arguments:", | |
| 24956 " -v, --verbose Print each filename as it is processed", | |
| 24957 " -f FILE, --file FILE Use archive FILE (default is current db)", | |
| 24958 " -a FILE, --append FILE Open FILE using the apndvfs VFS", | |
| 24959 " -C DIR, --directory DIR Read/extract files from directory DIR", | |
| 24960 " -g, --glob Use glob matching for names in archive", | |
| 24961 " -n, --dryrun Show the SQL that would have occurred", | |
| 24962 " Examples:", | |
| 24963 " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar", | |
| 24964 " .ar -tf ARCHIVE # List members of ARCHIVE", | |
| 24965 " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE", | |
| 24966 " See also:", | |
| 24967 " http://sqlite.org/cli.html#sqlite_archive_support", | |
| 24968 #endif | |
| 24969 #ifndef SQLITE_OMIT_AUTHORIZATION | |
| 24970 ".auth ON|OFF Show authorizer callbacks", | |
| 24971 #endif | |
| 24972 #ifndef SQLITE_SHELL_FIDDLE | |
| 24973 ".backup ?DB? FILE Backup DB (default \"main\") to FILE", | |
| 24974 " Options:", | |
| 24975 " --append Use the appendvfs", | |
| 24976 " --async Write to FILE without journal and fsync()", | |
| 24977 #endif | |
| 24978 ".bail on|off Stop after hitting an error. Default OFF", | |
| 24979 #ifndef SQLITE_SHELL_FIDDLE | |
| 24980 ".cd DIRECTORY Change the working directory to DIRECTORY", | |
| 24981 #endif | |
| 24982 ".changes on|off Show number of rows changed by SQL", | |
| 24983 #ifndef SQLITE_SHELL_FIDDLE | |
| 24984 ".check GLOB Fail if output since .testcase does not match", | |
| 24985 ".clone NEWDB Clone data into NEWDB from the existing database", | |
| 24986 #endif | |
| 24987 ".connection [close] [#] Open or close an auxiliary database connection", | |
| 24988 ".crlf ?on|off? Whether or not to use \\r\\n line endings", | |
| 24989 ".databases List names and files of attached databases", | |
| 24990 ".dbconfig ?op? ?val? List or change sqlite3_db_config() options", | |
| 24991 #if SQLITE_SHELL_HAVE_RECOVER | |
| 24992 ".dbinfo ?DB? Show status information about the database", | |
| 24993 #endif | |
| 24994 ".dbtotxt Hex dump of the database file", | |
| 24995 ".dump ?OBJECTS? Render database content as SQL", | |
| 24996 " Options:", | |
| 24997 " --data-only Output only INSERT statements", | |
| 24998 " --newlines Allow unescaped newline characters in output", | |
| 24999 " --nosys Omit system tables (ex: \"sqlite_stat1\")", | |
| 25000 " --preserve-rowids Include ROWID values in the output", | |
| 25001 " OBJECTS is a LIKE pattern for tables, indexes, triggers or views to dump", | |
| 25002 " Additional LIKE patterns can be given in subsequent arguments", | |
| 25003 ".echo on|off Turn command echo on or off", | |
| 25004 ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN", | |
| 25005 " Other Modes:", | |
| 25006 #ifdef SQLITE_DEBUG | |
| 25007 " test Show raw EXPLAIN QUERY PLAN output", | |
| 25008 " trace Like \"full\" but enable \"PRAGMA vdbe_trace\"", | |
| 25009 #endif | |
| 25010 " trigger Like \"full\" but also show trigger bytecode", | |
| 25011 #ifndef SQLITE_SHELL_FIDDLE | |
| 25012 ".excel Display the output of next command in spreadsheet", | |
| 25013 " --bom Put a UTF8 byte-order mark on intermediate file", | |
| 25014 #endif | |
| 25015 #ifndef SQLITE_SHELL_FIDDLE | |
| 25016 ".exit ?CODE? Exit this program with return-code CODE", | |
| 25017 #endif | |
| 25018 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 25019 ".expert EXPERIMENTAL. Suggest indexes for queries", | |
| 25020 #endif | |
| 25021 ".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto", | |
| 25022 ".filectrl CMD ... Run various sqlite3_file_control() operations", | |
| 25023 " --schema SCHEMA Use SCHEMA instead of \"main\"", | |
| 25024 " --help Show CMD details", | |
| 25025 ".fullschema ?--indent? Show schema and the content of sqlite_stat tables", | |
| 25026 ".headers on|off Turn display of headers on or off", | |
| 25027 ".help ?-all? ?PATTERN? Show help text for PATTERN", | |
| 25028 #ifndef SQLITE_SHELL_FIDDLE | |
| 25029 ".import FILE TABLE Import data from FILE into TABLE", | |
| 25030 " Options:", | |
| 25031 " --ascii Use \\037 and \\036 as column and row separators", | |
| 25032 " --csv Use , and \\n as column and row separators", | |
| 25033 " --skip N Skip the first N rows of input", | |
| 25034 " --schema S Target table to be S.TABLE", | |
| 25035 " -v \"Verbose\" - increase auxiliary output", | |
| 25036 " Notes:", | |
| 25037 " * If TABLE does not exist, it is created. The first row of input", | |
| 25038 " determines the column names.", | |
| 25039 " * If neither --csv or --ascii are used, the input mode is derived", | |
| 25040 " from the \".mode\" output mode", | |
| 25041 " * If FILE begins with \"|\" then it is a command that generates the", | |
| 25042 " input text.", | |
| 25043 #endif | |
| 25044 #ifndef SQLITE_OMIT_TEST_CONTROL | |
| 25045 ".imposter INDEX TABLE Create imposter table TABLE on index INDEX", | |
| 25046 #endif | |
| 25047 ".indexes ?TABLE? Show names of indexes", | |
| 25048 " If TABLE is specified, only show indexes for", | |
| 25049 " tables matching TABLE using the LIKE operator.", | |
| 25050 ".intck ?STEPS_PER_UNLOCK? Run an incremental integrity check on the db", | |
| 25051 #ifdef SQLITE_ENABLE_IOTRACE | |
| 25052 ",iotrace FILE Enable I/O diagnostic logging to FILE", | |
| 25053 #endif | |
| 25054 ".limit ?LIMIT? ?VAL? Display or change the value of an SQLITE_LIMIT", | |
| 25055 ".lint OPTIONS Report potential schema issues.", | |
| 25056 " Options:", | |
| 25057 " fkey-indexes Find missing foreign key indexes", | |
| 25058 #if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_FIDDLE) | |
| 25059 ".load FILE ?ENTRY? Load an extension library", | |
| 25060 #endif | |
| 25061 #if !defined(SQLITE_SHELL_FIDDLE) | |
| 25062 ".log FILE|on|off Turn logging on or off. FILE can be stderr/stdout", | |
| 25063 #else | |
| 25064 ".log on|off Turn logging on or off.", | |
| 25065 #endif | |
| 25066 ".mode ?MODE? ?OPTIONS? Set output mode", | |
| 25067 " MODE is one of:", | |
| 25068 " ascii Columns/rows delimited by 0x1F and 0x1E", | |
| 25069 " box Tables using unicode box-drawing characters", | |
| 25070 " csv Comma-separated values", | |
| 25071 " column Output in columns. (See .width)", | |
| 25072 " html HTML <table> code", | |
| 25073 " insert SQL insert statements for TABLE", | |
| 25074 " json Results in a JSON array", | |
| 25075 " line One value per line", | |
| 25076 " list Values delimited by \"|\"", | |
| 25077 " markdown Markdown table format", | |
| 25078 " qbox Shorthand for \"box --wrap 60 --quote\"", | |
| 25079 " quote Escape answers as for SQL", | |
| 25080 " table ASCII-art table", | |
| 25081 " tabs Tab-separated values", | |
| 25082 " tcl TCL list elements", | |
| 25083 " OPTIONS: (for columnar modes or insert mode):", | |
| 25084 " --escape T ctrl-char escape; T is one of: symbol, ascii, off", | |
| 25085 " --wrap N Wrap output lines to no longer than N characters", | |
| 25086 " --wordwrap B Wrap or not at word boundaries per B (on/off)", | |
| 25087 " --ww Shorthand for \"--wordwrap 1\"", | |
| 25088 " --quote Quote output text as SQL literals", | |
| 25089 " --noquote Do not quote output text", | |
| 25090 " TABLE The name of SQL table used for \"insert\" mode", | |
| 25091 #ifndef SQLITE_SHELL_FIDDLE | |
| 25092 ".nonce STRING Suspend safe mode for one command if nonce matches", | |
| 25093 #endif | |
| 25094 ".nullvalue STRING Use STRING in place of NULL values", | |
| 25095 #ifndef SQLITE_SHELL_FIDDLE | |
| 25096 ".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE", | |
| 25097 " If FILE begins with '|' then open as a pipe", | |
| 25098 " --bom Put a UTF8 byte-order mark at the beginning", | |
| 25099 " -e Send output to the system text editor", | |
| 25100 " --plain Use text/plain output instead of HTML for -w option", | |
| 25101 " -w Send output as HTML to a web browser (same as \".www\")", | |
| 25102 " -x Send output as CSV to a spreadsheet (same as \".excel\")", | |
| 25103 /* Note that .open is (partially) available in WASM builds but is | |
| 25104 ** currently only intended to be used by the fiddle tool, not | |
| 25105 ** end users, so is "undocumented." */ | |
| 25106 ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE", | |
| 25107 " Options:", | |
| 25108 " --append Use appendvfs to append database to the end of FILE", | |
| 25109 #endif | |
| 25110 #ifndef SQLITE_OMIT_DESERIALIZE | |
| 25111 " --deserialize Load into memory using sqlite3_deserialize()", | |
| 25112 #endif | |
| 25113 /*" --exclusive Set the SQLITE_OPEN_EXCLUSIVE flag", UNDOCUMENTED */ | |
| 25114 #ifndef SQLITE_OMIT_DESERIALIZE | |
| 25115 " --hexdb Load the output of \"dbtotxt\" as an in-memory db", | |
| 25116 #endif | |
| 25117 " --ifexist Only open if FILE already exists", | |
| 25118 #ifndef SQLITE_OMIT_DESERIALIZE | |
| 25119 " --maxsize N Maximum size for --hexdb or --deserialized database", | |
| 25120 #endif | |
| 25121 " --new Initialize FILE to an empty database", | |
| 25122 " --normal FILE is an ordinary SQLite database", | |
| 25123 " --nofollow Do not follow symbolic links", | |
| 25124 " --readonly Open FILE readonly", | |
| 25125 " --zip FILE is a ZIP archive", | |
| 25126 #ifndef SQLITE_SHELL_FIDDLE | |
| 25127 ".output ?FILE? Send output to FILE or stdout if FILE is omitted", | |
| 25128 " If FILE begins with '|' then open it as a pipe.", | |
| 25129 " If FILE is 'off' then output is disabled.", | |
| 25130 " Options:", | |
| 25131 " --bom Prefix output with a UTF8 byte-order mark", | |
| 25132 " -e Send output to the system text editor", | |
| 25133 " --plain Use text/plain for -w option", | |
| 25134 " -w Send output to a web browser", | |
| 25135 " -x Send output as CSV to a spreadsheet", | |
| 25136 #endif | |
| 25137 ".parameter CMD ... Manage SQL parameter bindings", | |
| 25138 " clear Erase all bindings", | |
| 25139 " init Initialize the TEMP table that holds bindings", | |
| 25140 " list List the current parameter bindings", | |
| 25141 " set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE", | |
| 25142 " PARAMETER should start with one of: $ : @ ?", | |
| 25143 " unset PARAMETER Remove PARAMETER from the binding table", | |
| 25144 ".print STRING... Print literal STRING", | |
| 25145 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | |
| 25146 ".progress N Invoke progress handler after every N opcodes", | |
| 25147 " --limit N Interrupt after N progress callbacks", | |
| 25148 " --once Do no more than one progress interrupt", | |
| 25149 " --quiet|-q No output except at interrupts", | |
| 25150 " --reset Reset the count for each input and interrupt", | |
| 25151 #endif | |
| 25152 ".prompt MAIN CONTINUE Replace the standard prompts", | |
| 25153 #ifndef SQLITE_SHELL_FIDDLE | |
| 25154 ".quit Stop interpreting input stream, exit if primary.", | |
| 25155 ".read FILE Read input from FILE or command output", | |
| 25156 " If FILE begins with \"|\", it is a command that generates the input.", | |
| 25157 #endif | |
| 25158 #if SQLITE_SHELL_HAVE_RECOVER | |
| 25159 ".recover Recover as much data as possible from corrupt db.", | |
| 25160 " --ignore-freelist Ignore pages that appear to be on db freelist", | |
| 25161 " --lost-and-found TABLE Alternative name for the lost-and-found table", | |
| 25162 " --no-rowids Do not attempt to recover rowid values", | |
| 25163 " that are not also INTEGER PRIMARY KEYs", | |
| 25164 #endif | |
| 25165 #ifndef SQLITE_SHELL_FIDDLE | |
| 25166 ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE", | |
| 25167 ".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)", | |
| 25168 #endif | |
| 25169 ".scanstats on|off|est Turn sqlite3_stmt_scanstatus() metrics on or off", | |
| 25170 ".schema ?PATTERN? Show the CREATE statements matching PATTERN", | |
| 25171 " Options:", | |
| 25172 " --indent Try to pretty-print the schema", | |
| 25173 " --nosys Omit objects whose names start with \"sqlite_\"", | |
| 25174 ",selftest ?OPTIONS? Run tests defined in the SELFTEST table", | |
| 25175 " Options:", | |
| 25176 " --init Create a new SELFTEST table", | |
| 25177 " -v Verbose output", | |
| 25178 ".separator COL ?ROW? Change the column and row separators", | |
| 25179 #if defined(SQLITE_ENABLE_SESSION) | |
| 25180 ".session ?NAME? CMD ... Create or control sessions", | |
| 25181 " Subcommands:", | |
| 25182 " attach TABLE Attach TABLE", | |
| 25183 " changeset FILE Write a changeset into FILE", | |
| 25184 " close Close one session", | |
| 25185 " enable ?BOOLEAN? Set or query the enable bit", | |
| 25186 " filter GLOB... Reject tables matching GLOBs", | |
| 25187 " indirect ?BOOLEAN? Mark or query the indirect status", | |
| 25188 " isempty Query whether the session is empty", | |
| 25189 " list List currently open session names", | |
| 25190 " open DB NAME Open a new session on DB", | |
| 25191 " patchset FILE Write a patchset into FILE", | |
| 25192 " If ?NAME? is omitted, the first defined session is used.", | |
| 25193 #endif | |
| 25194 ".sha3sum ... Compute a SHA3 hash of database content", | |
| 25195 " Options:", | |
| 25196 " --schema Also hash the sqlite_schema table", | |
| 25197 " --sha3-224 Use the sha3-224 algorithm", | |
| 25198 " --sha3-256 Use the sha3-256 algorithm (default)", | |
| 25199 " --sha3-384 Use the sha3-384 algorithm", | |
| 25200 " --sha3-512 Use the sha3-512 algorithm", | |
| 25201 " Any other argument is a LIKE pattern for tables to hash", | |
| 25202 #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) | |
| 25203 ".shell CMD ARGS... Run CMD ARGS... in a system shell", | |
| 25204 #endif | |
| 25205 ".show Show the current values for various settings", | |
| 25206 ".stats ?ARG? Show stats or turn stats on or off", | |
| 25207 " off Turn off automatic stat display", | |
| 25208 " on Turn on automatic stat display", | |
| 25209 " stmt Show statement stats", | |
| 25210 " vmstep Show the virtual machine step count only", | |
| 25211 #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) | |
| 25212 ".system CMD ARGS... Run CMD ARGS... in a system shell", | |
| 25213 #endif | |
| 25214 ".tables ?TABLE? List names of tables matching LIKE pattern TABLE", | |
| 25215 #ifndef SQLITE_SHELL_FIDDLE | |
| 25216 ",testcase NAME Begin redirecting output to 'testcase-out.txt'", | |
| 25217 #endif | |
| 25218 ",testctrl CMD ... Run various sqlite3_test_control() operations", | |
| 25219 " Run \".testctrl\" with no arguments for details", | |
| 25220 ".timeout MS Try opening locked tables for MS milliseconds", | |
| 25221 ".timer on|off Turn SQL timer on or off", | |
| 25222 #ifndef SQLITE_OMIT_TRACE | |
| 25223 ".trace ?OPTIONS? Output each SQL statement as it is run", | |
| 25224 " FILE Send output to FILE", | |
| 25225 " stdout Send output to stdout", | |
| 25226 " stderr Send output to stderr", | |
| 25227 " off Disable tracing", | |
| 25228 " --expanded Expand query parameters", | |
| 25229 #ifdef SQLITE_ENABLE_NORMALIZE | |
| 25230 " --normalized Normal the SQL statements", | |
| 25231 #endif | |
| 25232 " --plain Show SQL as it is input", | |
| 25233 " --stmt Trace statement execution (SQLITE_TRACE_STMT)", | |
| 25234 " --profile Profile statements (SQLITE_TRACE_PROFILE)", | |
| 25235 " --row Trace each row (SQLITE_TRACE_ROW)", | |
| 25236 " --close Trace connection close (SQLITE_TRACE_CLOSE)", | |
| 25237 #endif /* SQLITE_OMIT_TRACE */ | |
| 25238 #ifdef SQLITE_DEBUG | |
| 25239 ".unmodule NAME ... Unregister virtual table modules", | |
| 25240 " --allexcept Unregister everything except those named", | |
| 25241 #endif | |
| 25242 ".version Show source, library and compiler versions", | |
| 25243 ".vfsinfo ?AUX? Information about the top-level VFS", | |
| 25244 ".vfslist List all available VFSes", | |
| 25245 ".vfsname ?AUX? Print the name of the VFS stack", | |
| 25246 ".width NUM1 NUM2 ... Set minimum column widths for columnar output", | |
| 25247 " Negative values right-justify", | |
| 25248 #ifndef SQLITE_SHELL_FIDDLE | |
| 25249 ".www Display output of the next command in web browser", | |
| 25250 " --plain Show results as text/plain, not as HTML", | |
| 25251 #endif | |
| 25252 }; | |
| 25253 | |
| 25254 /* | |
| 25255 ** Output help text for commands that match zPattern. | |
| 25256 ** | |
| 25257 ** * If zPattern is NULL, then show all documented commands, but | |
| 25258 ** only give a one-line summary of each. | |
| 25259 ** | |
| 25260 ** * If zPattern is "-a" or "-all" or "--all" then show all help text | |
| 25261 ** for all commands except undocumented commands. | |
| 25262 ** | |
| 25263 ** * If zPattern is "0" then show all help for undocumented commands. | |
| 25264 ** Undocumented commands begin with "," instead of "." in the azHelp[] | |
| 25265 ** array. | |
| 25266 ** | |
| 25267 ** * If zPattern is a prefix for one or more documented commands, then | |
| 25268 ** show help for those commands. If only a single command matches the | |
| 25269 ** prefix, show the full text of the help. If multiple commands match, | |
| 25270 ** Only show just the first line of each. | |
| 25271 ** | |
| 25272 ** * Otherwise, show the complete text of any documented command for which | |
| 25273 ** zPattern is a LIKE match for any text within that command help | |
| 25274 ** text. | |
| 25275 ** | |
| 25276 ** Return the number commands that match zPattern. | |
| 25277 */ | |
| 25278 static int showHelp(FILE *out, const char *zPattern){ | |
| 25279 int i = 0; | |
| 25280 int j = 0; | |
| 25281 int n = 0; | |
| 25282 char *zPat; | |
| 25283 if( zPattern==0 ){ | |
| 25284 /* Show just the first line for all help topics */ | |
| 25285 zPattern = "[a-z]"; | |
| 25286 }else if( cli_strcmp(zPattern,"-a")==0 | |
| 25287 || cli_strcmp(zPattern,"-all")==0 | |
| 25288 || cli_strcmp(zPattern,"--all")==0 | |
| 25289 ){ | |
| 25290 /* Show everything except undocumented commands */ | |
| 25291 zPattern = "."; | |
| 25292 }else if( cli_strcmp(zPattern,"0")==0 ){ | |
| 25293 /* Show complete help text of undocumented commands */ | |
| 25294 int show = 0; | |
| 25295 for(i=0; i<ArraySize(azHelp); i++){ | |
| 25296 if( azHelp[i][0]=='.' ){ | |
| 25297 show = 0; | |
| 25298 }else if( azHelp[i][0]==',' ){ | |
| 25299 show = 1; | |
| 25300 sqlite3_fprintf(out, ".%s\n", &azHelp[i][1]); | |
| 25301 n++; | |
| 25302 }else if( show ){ | |
| 25303 sqlite3_fprintf(out, "%s\n", azHelp[i]); | |
| 25304 } | |
| 25305 } | |
| 25306 return n; | |
| 25307 } | |
| 25308 | |
| 25309 /* Seek documented commands for which zPattern is an exact prefix */ | |
| 25310 zPat = sqlite3_mprintf(".%s*", zPattern); | |
| 25311 shell_check_oom(zPat); | |
| 25312 for(i=0; i<ArraySize(azHelp); i++){ | |
| 25313 if( sqlite3_strglob(zPat, azHelp[i])==0 ){ | |
| 25314 sqlite3_fprintf(out, "%s\n", azHelp[i]); | |
| 25315 j = i+1; | |
| 25316 n++; | |
| 25317 } | |
| 25318 } | |
| 25319 sqlite3_free(zPat); | |
| 25320 if( n ){ | |
| 25321 if( n==1 ){ | |
| 25322 /* when zPattern is a prefix of exactly one command, then include | |
| 25323 ** the details of that command, which should begin at offset j */ | |
| 25324 while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){ | |
| 25325 sqlite3_fprintf(out, "%s\n", azHelp[j]); | |
| 25326 j++; | |
| 25327 } | |
| 25328 } | |
| 25329 return n; | |
| 25330 } | |
| 25331 | |
| 25332 /* Look for documented commands that contain zPattern anywhere. | |
| 25333 ** Show complete text of all documented commands that match. */ | |
| 25334 zPat = sqlite3_mprintf("%%%s%%", zPattern); | |
| 25335 shell_check_oom(zPat); | |
| 25336 for(i=0; i<ArraySize(azHelp); i++){ | |
| 25337 if( azHelp[i][0]==',' ){ | |
| 25338 while( i<ArraySize(azHelp)-1 && azHelp[i+1][0]==' ' ) ++i; | |
| 25339 continue; | |
| 25340 } | |
| 25341 if( azHelp[i][0]=='.' ) j = i; | |
| 25342 if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){ | |
| 25343 sqlite3_fprintf(out, "%s\n", azHelp[j]); | |
| 25344 while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]==' ' ){ | |
| 25345 j++; | |
| 25346 sqlite3_fprintf(out, "%s\n", azHelp[j]); | |
| 25347 } | |
| 25348 i = j; | |
| 25349 n++; | |
| 25350 } | |
| 25351 } | |
| 25352 sqlite3_free(zPat); | |
| 25353 return n; | |
| 25354 } | |
| 25355 | |
| 25356 /* Forward reference */ | |
| 25357 static int process_input(ShellState *p, const char*); | |
| 25358 | |
| 25359 /* | |
| 25360 ** Read the content of file zName into memory obtained from sqlite3_malloc64() | |
| 25361 ** and return a pointer to the buffer. The caller is responsible for freeing | |
| 25362 ** the memory. | |
| 25363 ** | |
| 25364 ** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes | |
| 25365 ** read. | |
| 25366 ** | |
| 25367 ** For convenience, a nul-terminator byte is always appended to the data read | |
| 25368 ** from the file before the buffer is returned. This byte is not included in | |
| 25369 ** the final value of (*pnByte), if applicable. | |
| 25370 ** | |
| 25371 ** NULL is returned if any error is encountered. The final value of *pnByte | |
| 25372 ** is undefined in this case. | |
| 25373 */ | |
| 25374 static char *readFile(const char *zName, int *pnByte){ | |
| 25375 FILE *in = sqlite3_fopen(zName, "rb"); | |
| 25376 long nIn; | |
| 25377 size_t nRead; | |
| 25378 char *pBuf; | |
| 25379 int rc; | |
| 25380 if( in==0 ) return 0; | |
| 25381 rc = fseek(in, 0, SEEK_END); | |
| 25382 if( rc!=0 ){ | |
| 25383 sqlite3_fprintf(stderr,"Error: '%s' not seekable\n", zName); | |
| 25384 fclose(in); | |
| 25385 return 0; | |
| 25386 } | |
| 25387 nIn = ftell(in); | |
| 25388 rewind(in); | |
| 25389 pBuf = sqlite3_malloc64( nIn+1 ); | |
| 25390 if( pBuf==0 ){ | |
| 25391 sqlite3_fputs("Error: out of memory\n", stderr); | |
| 25392 fclose(in); | |
| 25393 return 0; | |
| 25394 } | |
| 25395 nRead = fread(pBuf, nIn, 1, in); | |
| 25396 fclose(in); | |
| 25397 if( nRead!=1 ){ | |
| 25398 sqlite3_free(pBuf); | |
| 25399 sqlite3_fprintf(stderr,"Error: cannot read '%s'\n", zName); | |
| 25400 return 0; | |
| 25401 } | |
| 25402 pBuf[nIn] = 0; | |
| 25403 if( pnByte ) *pnByte = nIn; | |
| 25404 return pBuf; | |
| 25405 } | |
| 25406 | |
| 25407 #if defined(SQLITE_ENABLE_SESSION) | |
| 25408 /* | |
| 25409 ** Close a single OpenSession object and release all of its associated | |
| 25410 ** resources. | |
| 25411 */ | |
| 25412 static void session_close(OpenSession *pSession){ | |
| 25413 int i; | |
| 25414 sqlite3session_delete(pSession->p); | |
| 25415 sqlite3_free(pSession->zName); | |
| 25416 for(i=0; i<pSession->nFilter; i++){ | |
| 25417 sqlite3_free(pSession->azFilter[i]); | |
| 25418 } | |
| 25419 sqlite3_free(pSession->azFilter); | |
| 25420 memset(pSession, 0, sizeof(OpenSession)); | |
| 25421 } | |
| 25422 #endif | |
| 25423 | |
| 25424 /* | |
| 25425 ** Close all OpenSession objects and release all associated resources. | |
| 25426 */ | |
| 25427 #if defined(SQLITE_ENABLE_SESSION) | |
| 25428 static void session_close_all(ShellState *p, int i){ | |
| 25429 int j; | |
| 25430 struct AuxDb *pAuxDb = i<0 ? p->pAuxDb : &p->aAuxDb[i]; | |
| 25431 for(j=0; j<pAuxDb->nSession; j++){ | |
| 25432 session_close(&pAuxDb->aSession[j]); | |
| 25433 } | |
| 25434 pAuxDb->nSession = 0; | |
| 25435 } | |
| 25436 #else | |
| 25437 # define session_close_all(X,Y) | |
| 25438 #endif | |
| 25439 | |
| 25440 /* | |
| 25441 ** Implementation of the xFilter function for an open session. Omit | |
| 25442 ** any tables named by ".session filter" but let all other table through. | |
| 25443 */ | |
| 25444 #if defined(SQLITE_ENABLE_SESSION) | |
| 25445 static int session_filter(void *pCtx, const char *zTab){ | |
| 25446 OpenSession *pSession = (OpenSession*)pCtx; | |
| 25447 int i; | |
| 25448 for(i=0; i<pSession->nFilter; i++){ | |
| 25449 if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0; | |
| 25450 } | |
| 25451 return 1; | |
| 25452 } | |
| 25453 #endif | |
| 25454 | |
| 25455 /* | |
| 25456 ** Try to deduce the type of file for zName based on its content. Return | |
| 25457 ** one of the SHELL_OPEN_* constants. | |
| 25458 ** | |
| 25459 ** If the file does not exist or is empty but its name looks like a ZIP | |
| 25460 ** archive and the dfltZip flag is true, then assume it is a ZIP archive. | |
| 25461 ** Otherwise, assume an ordinary database regardless of the filename if | |
| 25462 ** the type cannot be determined from content. | |
| 25463 */ | |
| 25464 int deduceDatabaseType(const char *zName, int dfltZip, int openFlags){ | |
| 25465 FILE *f; | |
| 25466 size_t n; | |
| 25467 sqlite3 *db = 0; | |
| 25468 sqlite3_stmt *pStmt = 0; | |
| 25469 int rc = SHELL_OPEN_UNSPEC; | |
| 25470 char zBuf[100]; | |
| 25471 if( access(zName,0)!=0 ) goto database_type_by_name; | |
| 25472 if( sqlite3_open_v2(zName, &db, openFlags, 0)==SQLITE_OK | |
| 25473 && sqlite3_prepare_v2(db,"SELECT count(*) FROM sqlite_schema",-1,&pStmt,0) | |
| 25474 ==SQLITE_OK | |
| 25475 && sqlite3_step(pStmt)==SQLITE_ROW | |
| 25476 ){ | |
| 25477 rc = SHELL_OPEN_NORMAL; | |
| 25478 } | |
| 25479 sqlite3_finalize(pStmt); | |
| 25480 sqlite3_close(db); | |
| 25481 if( rc==SHELL_OPEN_NORMAL ) return SHELL_OPEN_NORMAL; | |
| 25482 f = sqlite3_fopen(zName, "rb"); | |
| 25483 if( f==0 ) goto database_type_by_name; | |
| 25484 n = fread(zBuf, 16, 1, f); | |
| 25485 if( n==1 && memcmp(zBuf, "SQLite format 3", 16)==0 ){ | |
| 25486 fclose(f); | |
| 25487 return SHELL_OPEN_NORMAL; | |
| 25488 } | |
| 25489 fseek(f, -25, SEEK_END); | |
| 25490 n = fread(zBuf, 25, 1, f); | |
| 25491 if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){ | |
| 25492 rc = SHELL_OPEN_APPENDVFS; | |
| 25493 }else{ | |
| 25494 fseek(f, -22, SEEK_END); | |
| 25495 n = fread(zBuf, 22, 1, f); | |
| 25496 if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05 | |
| 25497 && zBuf[3]==0x06 ){ | |
| 25498 rc = SHELL_OPEN_ZIPFILE; | |
| 25499 }else if( n==0 && dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){ | |
| 25500 rc = SHELL_OPEN_ZIPFILE; | |
| 25501 } | |
| 25502 } | |
| 25503 fclose(f); | |
| 25504 return rc; | |
| 25505 | |
| 25506 database_type_by_name: | |
| 25507 if( dfltZip && sqlite3_strlike("%.zip",zName,0)==0 ){ | |
| 25508 rc = SHELL_OPEN_ZIPFILE; | |
| 25509 }else{ | |
| 25510 rc = SHELL_OPEN_NORMAL; | |
| 25511 } | |
| 25512 return rc; | |
| 25513 } | |
| 25514 | |
| 25515 #ifndef SQLITE_OMIT_DESERIALIZE | |
| 25516 /* | |
| 25517 ** Reconstruct an in-memory database using the output from the "dbtotxt" | |
| 25518 ** program. Read content from the file in p->aAuxDb[].zDbFilename. | |
| 25519 ** If p->aAuxDb[].zDbFilename is 0, then read from standard input. | |
| 25520 */ | |
| 25521 static unsigned char *readHexDb(ShellState *p, int *pnData){ | |
| 25522 unsigned char *a = 0; | |
| 25523 i64 nLine; | |
| 25524 int n = 0; /* Size of db per first line of hex dump */ | |
| 25525 i64 sz = 0; /* n rounded up to nearest page boundary */ | |
| 25526 int pgsz = 0; | |
| 25527 i64 iOffset = 0; | |
| 25528 int rc; | |
| 25529 FILE *in; | |
| 25530 const char *zDbFilename = p->pAuxDb->zDbFilename; | |
| 25531 unsigned int x[16]; | |
| 25532 char zLine[1000]; | |
| 25533 if( zDbFilename ){ | |
| 25534 in = sqlite3_fopen(zDbFilename, "r"); | |
| 25535 if( in==0 ){ | |
| 25536 sqlite3_fprintf(stderr,"cannot open \"%s\" for reading\n", zDbFilename); | |
| 25537 return 0; | |
| 25538 } | |
| 25539 nLine = 0; | |
| 25540 }else{ | |
| 25541 in = p->in; | |
| 25542 nLine = p->lineno; | |
| 25543 if( in==0 ) in = stdin; | |
| 25544 } | |
| 25545 *pnData = 0; | |
| 25546 nLine++; | |
| 25547 if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; | |
| 25548 rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); | |
| 25549 if( rc!=2 ) goto readHexDb_error; | |
| 25550 if( n<0 ) goto readHexDb_error; | |
| 25551 if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ | |
| 25552 sqlite3_fputs("invalid pagesize\n", stderr); | |
| 25553 goto readHexDb_error; | |
| 25554 } | |
| 25555 sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */ | |
| 25556 a = sqlite3_malloc64( sz ? sz : 1 ); | |
| 25557 shell_check_oom(a); | |
| 25558 memset(a, 0, sz); | |
| 25559 for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){ | |
| 25560 int j = 0; /* Page number from "| page" line */ | |
| 25561 int k = 0; /* Offset from "| page" line */ | |
| 25562 if( nLine>=2000000000 ){ | |
| 25563 sqlite3_fprintf(stderr, "input too big\n"); | |
| 25564 goto readHexDb_error; | |
| 25565 } | |
| 25566 rc = sscanf(zLine, "| page %d offset %d", &j, &k); | |
| 25567 if( rc==2 ){ | |
| 25568 iOffset = k; | |
| 25569 continue; | |
| 25570 } | |
| 25571 if( cli_strncmp(zLine, "| end ", 6)==0 ){ | |
| 25572 break; | |
| 25573 } | |
| 25574 rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", | |
| 25575 &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], | |
| 25576 &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]); | |
| 25577 if( rc==17 ){ | |
| 25578 i64 iOff = iOffset+j; | |
| 25579 if( iOff+16<=sz && iOff>=0 ){ | |
| 25580 int ii; | |
| 25581 for(ii=0; ii<16; ii++) a[iOff+ii] = x[ii]&0xff; | |
| 25582 } | |
| 25583 } | |
| 25584 } | |
| 25585 *pnData = sz; | |
| 25586 if( in!=p->in ){ | |
| 25587 fclose(in); | |
| 25588 }else{ | |
| 25589 p->lineno = nLine; | |
| 25590 } | |
| 25591 return a; | |
| 25592 | |
| 25593 readHexDb_error: | |
| 25594 if( in!=p->in ){ | |
| 25595 fclose(in); | |
| 25596 }else{ | |
| 25597 while( sqlite3_fgets(zLine, sizeof(zLine), p->in)!=0 ){ | |
| 25598 nLine++; | |
| 25599 if(cli_strncmp(zLine, "| end ", 6)==0 ) break; | |
| 25600 } | |
| 25601 p->lineno = nLine; | |
| 25602 } | |
| 25603 sqlite3_free(a); | |
| 25604 sqlite3_fprintf(stderr,"Error on line %lld of --hexdb input\n", nLine); | |
| 25605 return 0; | |
| 25606 } | |
| 25607 #endif /* SQLITE_OMIT_DESERIALIZE */ | |
| 25608 | |
| 25609 /* | |
| 25610 ** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X. | |
| 25611 */ | |
| 25612 static void shellUSleepFunc( | |
| 25613 sqlite3_context *context, | |
| 25614 int argcUnused, | |
| 25615 sqlite3_value **argv | |
| 25616 ){ | |
| 25617 int sleep = sqlite3_value_int(argv[0]); | |
| 25618 (void)argcUnused; | |
| 25619 sqlite3_sleep(sleep/1000); | |
| 25620 sqlite3_result_int(context, sleep); | |
| 25621 } | |
| 25622 | |
| 25623 /* | |
| 25624 ** SQL function: shell_module_schema(X) | |
| 25625 ** | |
| 25626 ** Return a fake schema for the table-valued function or eponymous virtual | |
| 25627 ** table X. | |
| 25628 */ | |
| 25629 static void shellModuleSchema( | |
| 25630 sqlite3_context *pCtx, | |
| 25631 int nVal, | |
| 25632 sqlite3_value **apVal | |
| 25633 ){ | |
| 25634 const char *zName; | |
| 25635 char *zFake; | |
| 25636 ShellState *p = (ShellState*)sqlite3_user_data(pCtx); | |
| 25637 FILE *pSavedLog = p->pLog; | |
| 25638 UNUSED_PARAMETER(nVal); | |
| 25639 zName = (const char*)sqlite3_value_text(apVal[0]); | |
| 25640 | |
| 25641 /* Temporarily disable the ".log" when calling shellFakeSchema() because | |
| 25642 ** shellFakeSchema() might generate failures for some ephemeral virtual | |
| 25643 ** tables due to missing arguments. Example: fts4aux. | |
| 25644 ** https://sqlite.org/forum/forumpost/42fe6520b803be51 */ | |
| 25645 p->pLog = 0; | |
| 25646 zFake = zName? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0; | |
| 25647 p->pLog = pSavedLog; | |
| 25648 | |
| 25649 if( zFake ){ | |
| 25650 sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake), | |
| 25651 -1, sqlite3_free); | |
| 25652 sqlite3_free(zFake); | |
| 25653 } | |
| 25654 } | |
| 25655 | |
| 25656 /* Flags for open_db(). | |
| 25657 ** | |
| 25658 ** The default behavior of open_db() is to exit(1) if the database fails to | |
| 25659 ** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error | |
| 25660 ** but still returns without calling exit. | |
| 25661 ** | |
| 25662 ** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a | |
| 25663 ** ZIP archive if the file does not exist or is empty and its name matches | |
| 25664 ** the *.zip pattern. | |
| 25665 */ | |
| 25666 #define OPEN_DB_KEEPALIVE 0x001 /* Return after error if true */ | |
| 25667 #define OPEN_DB_ZIPFILE 0x002 /* Open as ZIP if name matches *.zip */ | |
| 25668 | |
| 25669 /* | |
| 25670 ** Make sure the database is open. If it is not, then open it. If | |
| 25671 ** the database fails to open, print an error message and exit. | |
| 25672 */ | |
| 25673 static void open_db(ShellState *p, int openFlags){ | |
| 25674 if( p->db==0 ){ | |
| 25675 const char *zDbFilename = p->pAuxDb->zDbFilename; | |
| 25676 if( p->openMode==SHELL_OPEN_UNSPEC ){ | |
| 25677 if( zDbFilename==0 || zDbFilename[0]==0 ){ | |
| 25678 p->openMode = SHELL_OPEN_NORMAL; | |
| 25679 }else{ | |
| 25680 p->openMode = (u8)deduceDatabaseType(zDbFilename, | |
| 25681 (openFlags & OPEN_DB_ZIPFILE)!=0, p->openFlags); | |
| 25682 } | |
| 25683 } | |
| 25684 if( (p->openFlags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE))==0 ){ | |
| 25685 if( p->openFlags==0 ) p->openFlags = SQLITE_OPEN_CREATE; | |
| 25686 p->openFlags |= SQLITE_OPEN_READWRITE; | |
| 25687 } | |
| 25688 switch( p->openMode ){ | |
| 25689 case SHELL_OPEN_APPENDVFS: { | |
| 25690 sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, "apndvfs"); | |
| 25691 break; | |
| 25692 } | |
| 25693 case SHELL_OPEN_HEXDB: | |
| 25694 case SHELL_OPEN_DESERIALIZE: { | |
| 25695 sqlite3_open(0, &p->db); | |
| 25696 break; | |
| 25697 } | |
| 25698 case SHELL_OPEN_ZIPFILE: { | |
| 25699 sqlite3_open(":memory:", &p->db); | |
| 25700 break; | |
| 25701 } | |
| 25702 case SHELL_OPEN_UNSPEC: | |
| 25703 case SHELL_OPEN_NORMAL: { | |
| 25704 sqlite3_open_v2(zDbFilename, &p->db, p->openFlags, 0); | |
| 25705 break; | |
| 25706 } | |
| 25707 } | |
| 25708 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ | |
| 25709 sqlite3_fprintf(stderr,"Error: unable to open database \"%s\": %s\n", | |
| 25710 zDbFilename, sqlite3_errmsg(p->db)); | |
| 25711 if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){ | |
| 25712 exit(1); | |
| 25713 } | |
| 25714 sqlite3_close(p->db); | |
| 25715 sqlite3_open(":memory:", &p->db); | |
| 25716 if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){ | |
| 25717 sqlite3_fputs("Also: unable to open substitute in-memory database.\n", | |
| 25718 stderr); | |
| 25719 exit(1); | |
| 25720 }else{ | |
| 25721 sqlite3_fprintf(stderr, | |
| 25722 "Notice: using substitute in-memory database instead of \"%s\"\n", | |
| 25723 zDbFilename); | |
| 25724 } | |
| 25725 } | |
| 25726 globalDb = p->db; | |
| 25727 sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, (int)0, (int*)0); | |
| 25728 | |
| 25729 /* Reflect the use or absence of --unsafe-testing invocation. */ | |
| 25730 { | |
| 25731 int testmode_on = ShellHasFlag(p,SHFLG_TestingMode); | |
| 25732 sqlite3_db_config(p->db, SQLITE_DBCONFIG_TRUSTED_SCHEMA, testmode_on,0); | |
| 25733 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, !testmode_on,0); | |
| 25734 } | |
| 25735 | |
| 25736 #ifndef SQLITE_OMIT_LOAD_EXTENSION | |
| 25737 sqlite3_enable_load_extension(p->db, 1); | |
| 25738 #endif | |
| 25739 sqlite3_sha_init(p->db, 0, 0); | |
| 25740 sqlite3_shathree_init(p->db, 0, 0); | |
| 25741 sqlite3_uint_init(p->db, 0, 0); | |
| 25742 sqlite3_stmtrand_init(p->db, 0, 0); | |
| 25743 sqlite3_decimal_init(p->db, 0, 0); | |
| 25744 sqlite3_base64_init(p->db, 0, 0); | |
| 25745 sqlite3_base85_init(p->db, 0, 0); | |
| 25746 sqlite3_regexp_init(p->db, 0, 0); | |
| 25747 sqlite3_ieee_init(p->db, 0, 0); | |
| 25748 sqlite3_series_init(p->db, 0, 0); | |
| 25749 #ifndef SQLITE_SHELL_FIDDLE | |
| 25750 sqlite3_fileio_init(p->db, 0, 0); | |
| 25751 sqlite3_completion_init(p->db, 0, 0); | |
| 25752 #endif | |
| 25753 #ifdef SQLITE_HAVE_ZLIB | |
| 25754 if( !p->bSafeModePersist ){ | |
| 25755 sqlite3_zipfile_init(p->db, 0, 0); | |
| 25756 sqlite3_sqlar_init(p->db, 0, 0); | |
| 25757 } | |
| 25758 #endif | |
| 25759 #ifdef SQLITE_SHELL_EXTFUNCS | |
| 25760 /* Create a preprocessing mechanism for extensions to make | |
| 25761 * their own provisions for being built into the shell. | |
| 25762 * This is a short-span macro. See further below for usage. | |
| 25763 */ | |
| 25764 #define SHELL_SUB_MACRO(base, variant) base ## _ ## variant | |
| 25765 #define SHELL_SUBMACRO(base, variant) SHELL_SUB_MACRO(base, variant) | |
| 25766 /* Let custom-included extensions get their ..._init() called. | |
| 25767 * The WHATEVER_INIT( db, pzErrorMsg, pApi ) macro should cause | |
| 25768 * the extension's sqlite3_*_init( db, pzErrorMsg, pApi ) | |
| 25769 * initialization routine to be called. | |
| 25770 */ | |
| 25771 { | |
| 25772 int irc = SHELL_SUBMACRO(SQLITE_SHELL_EXTFUNCS, INIT)(p->db); | |
| 25773 /* Let custom-included extensions expose their functionality. | |
| 25774 * The WHATEVER_EXPOSE( db, pzErrorMsg ) macro should cause | |
| 25775 * the SQL functions, virtual tables, collating sequences or | |
| 25776 * VFS's implemented by the extension to be registered. | |
| 25777 */ | |
| 25778 if( irc==SQLITE_OK | |
| 25779 || irc==SQLITE_OK_LOAD_PERMANENTLY ){ | |
| 25780 SHELL_SUBMACRO(SQLITE_SHELL_EXTFUNCS, EXPOSE)(p->db, 0); | |
| 25781 } | |
| 25782 #undef SHELL_SUB_MACRO | |
| 25783 #undef SHELL_SUBMACRO | |
| 25784 } | |
| 25785 #endif | |
| 25786 | |
| 25787 sqlite3_create_function(p->db, "strtod", 1, SQLITE_UTF8, 0, | |
| 25788 shellStrtod, 0, 0); | |
| 25789 sqlite3_create_function(p->db, "dtostr", 1, SQLITE_UTF8, 0, | |
| 25790 shellDtostr, 0, 0); | |
| 25791 sqlite3_create_function(p->db, "dtostr", 2, SQLITE_UTF8, 0, | |
| 25792 shellDtostr, 0, 0); | |
| 25793 sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0, | |
| 25794 shellAddSchemaName, 0, 0); | |
| 25795 sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, p, | |
| 25796 shellModuleSchema, 0, 0); | |
| 25797 sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p, | |
| 25798 shellPutsFunc, 0, 0); | |
| 25799 sqlite3_create_function(p->db, "usleep",1,SQLITE_UTF8,0, | |
| 25800 shellUSleepFunc, 0, 0); | |
| 25801 #ifndef SQLITE_NOHAVE_SYSTEM | |
| 25802 sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0, | |
| 25803 editFunc, 0, 0); | |
| 25804 sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0, | |
| 25805 editFunc, 0, 0); | |
| 25806 #endif | |
| 25807 | |
| 25808 if( p->openMode==SHELL_OPEN_ZIPFILE ){ | |
| 25809 char *zSql = sqlite3_mprintf( | |
| 25810 "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", zDbFilename); | |
| 25811 shell_check_oom(zSql); | |
| 25812 sqlite3_exec(p->db, zSql, 0, 0, 0); | |
| 25813 sqlite3_free(zSql); | |
| 25814 } | |
| 25815 #ifndef SQLITE_OMIT_DESERIALIZE | |
| 25816 else | |
| 25817 if( p->openMode==SHELL_OPEN_DESERIALIZE || p->openMode==SHELL_OPEN_HEXDB ){ | |
| 25818 int rc; | |
| 25819 int nData = 0; | |
| 25820 unsigned char *aData; | |
| 25821 if( p->openMode==SHELL_OPEN_DESERIALIZE ){ | |
| 25822 aData = (unsigned char*)readFile(zDbFilename, &nData); | |
| 25823 }else{ | |
| 25824 aData = readHexDb(p, &nData); | |
| 25825 } | |
| 25826 if( aData==0 ){ | |
| 25827 return; | |
| 25828 } | |
| 25829 rc = sqlite3_deserialize(p->db, "main", aData, nData, nData, | |
| 25830 SQLITE_DESERIALIZE_RESIZEABLE | | |
| 25831 SQLITE_DESERIALIZE_FREEONCLOSE); | |
| 25832 if( rc ){ | |
| 25833 sqlite3_fprintf(stderr,"Error: sqlite3_deserialize() returns %d\n", rc); | |
| 25834 } | |
| 25835 if( p->szMax>0 ){ | |
| 25836 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax); | |
| 25837 } | |
| 25838 } | |
| 25839 #endif | |
| 25840 } | |
| 25841 if( p->db!=0 ){ | |
| 25842 #ifndef SQLITE_OMIT_AUTHORIZATION | |
| 25843 if( p->bSafeModePersist ){ | |
| 25844 sqlite3_set_authorizer(p->db, safeModeAuth, p); | |
| 25845 } | |
| 25846 #endif | |
| 25847 sqlite3_db_config( | |
| 25848 p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0 | |
| 25849 ); | |
| 25850 } | |
| 25851 } | |
| 25852 | |
| 25853 /* | |
| 25854 ** Attempt to close the database connection. Report errors. | |
| 25855 */ | |
| 25856 void close_db(sqlite3 *db){ | |
| 25857 int rc = sqlite3_close(db); | |
| 25858 if( rc ){ | |
| 25859 sqlite3_fprintf(stderr, | |
| 25860 "Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db)); | |
| 25861 } | |
| 25862 } | |
| 25863 | |
| 25864 #if (HAVE_READLINE || HAVE_EDITLINE) \ | |
| 25865 && !defined(SQLITE_OMIT_READLINE_COMPLETION) | |
| 25866 /* | |
| 25867 ** Readline completion callbacks | |
| 25868 */ | |
| 25869 static char *readline_completion_generator(const char *text, int state){ | |
| 25870 static sqlite3_stmt *pStmt = 0; | |
| 25871 char *zRet; | |
| 25872 if( state==0 ){ | |
| 25873 char *zSql; | |
| 25874 sqlite3_finalize(pStmt); | |
| 25875 zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" | |
| 25876 " FROM completion(%Q) ORDER BY 1", text); | |
| 25877 shell_check_oom(zSql); | |
| 25878 sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); | |
| 25879 sqlite3_free(zSql); | |
| 25880 } | |
| 25881 if( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 25882 const char *z = (const char*)sqlite3_column_text(pStmt,0); | |
| 25883 zRet = z ? strdup(z) : 0; | |
| 25884 }else{ | |
| 25885 sqlite3_finalize(pStmt); | |
| 25886 pStmt = 0; | |
| 25887 zRet = 0; | |
| 25888 } | |
| 25889 return zRet; | |
| 25890 } | |
| 25891 static char **readline_completion(const char *zText, int iStart, int iEnd){ | |
| 25892 (void)iStart; | |
| 25893 (void)iEnd; | |
| 25894 rl_attempted_completion_over = 1; | |
| 25895 return rl_completion_matches(zText, readline_completion_generator); | |
| 25896 } | |
| 25897 | |
| 25898 #elif HAVE_LINENOISE | |
| 25899 /* | |
| 25900 ** Linenoise completion callback. Note that the 3rd argument is from | |
| 25901 ** the "msteveb" version of linenoise, not the "antirez" version. | |
| 25902 */ | |
| 25903 static void linenoise_completion( | |
| 25904 const char *zLine, | |
| 25905 linenoiseCompletions *lc | |
| 25906 #if HAVE_LINENOISE==2 | |
| 25907 ,void *pUserData | |
| 25908 #endif | |
| 25909 ){ | |
| 25910 i64 nLine = strlen(zLine); | |
| 25911 i64 i, iStart; | |
| 25912 sqlite3_stmt *pStmt = 0; | |
| 25913 char *zSql; | |
| 25914 char zBuf[1000]; | |
| 25915 | |
| 25916 #if HAVE_LINENOISE==2 | |
| 25917 UNUSED_PARAMETER(pUserData); | |
| 25918 #endif | |
| 25919 if( nLine>(i64)sizeof(zBuf)-30 ) return; | |
| 25920 if( zLine[0]=='.' || zLine[0]=='#') return; | |
| 25921 for(i=nLine-1; i>=0 && (IsAlnum(zLine[i]) || zLine[i]=='_'); i--){} | |
| 25922 if( i==nLine-1 ) return; | |
| 25923 iStart = i+1; | |
| 25924 memcpy(zBuf, zLine, iStart); | |
| 25925 zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase" | |
| 25926 " FROM completion(%Q,%Q) ORDER BY 1", | |
| 25927 &zLine[iStart], zLine); | |
| 25928 shell_check_oom(zSql); | |
| 25929 sqlite3_prepare_v2(globalDb, zSql, -1, &pStmt, 0); | |
| 25930 sqlite3_free(zSql); | |
| 25931 sqlite3_exec(globalDb, "PRAGMA page_count", 0, 0, 0); /* Load the schema */ | |
| 25932 while( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 25933 const char *zCompletion = (const char*)sqlite3_column_text(pStmt, 0); | |
| 25934 int nCompletion = sqlite3_column_bytes(pStmt, 0); | |
| 25935 if( iStart+nCompletion < (i64)sizeof(zBuf)-1 && zCompletion ){ | |
| 25936 memcpy(zBuf+iStart, zCompletion, nCompletion+1); | |
| 25937 linenoiseAddCompletion(lc, zBuf); | |
| 25938 } | |
| 25939 } | |
| 25940 sqlite3_finalize(pStmt); | |
| 25941 } | |
| 25942 #endif | |
| 25943 | |
| 25944 /* | |
| 25945 ** Do C-language style dequoting. | |
| 25946 ** | |
| 25947 ** \a -> alarm | |
| 25948 ** \b -> backspace | |
| 25949 ** \t -> tab | |
| 25950 ** \n -> newline | |
| 25951 ** \v -> vertical tab | |
| 25952 ** \f -> form feed | |
| 25953 ** \r -> carriage return | |
| 25954 ** \s -> space | |
| 25955 ** \" -> " | |
| 25956 ** \' -> ' | |
| 25957 ** \\ -> backslash | |
| 25958 ** \NNN -> ascii character NNN in octal | |
| 25959 ** \xHH -> ascii character HH in hexadecimal | |
| 25960 */ | |
| 25961 static void resolve_backslashes(char *z){ | |
| 25962 int i, j; | |
| 25963 char c; | |
| 25964 while( *z && *z!='\\' ) z++; | |
| 25965 for(i=j=0; (c = z[i])!=0; i++, j++){ | |
| 25966 if( c=='\\' && z[i+1]!=0 ){ | |
| 25967 c = z[++i]; | |
| 25968 if( c=='a' ){ | |
| 25969 c = '\a'; | |
| 25970 }else if( c=='b' ){ | |
| 25971 c = '\b'; | |
| 25972 }else if( c=='t' ){ | |
| 25973 c = '\t'; | |
| 25974 }else if( c=='n' ){ | |
| 25975 c = '\n'; | |
| 25976 }else if( c=='v' ){ | |
| 25977 c = '\v'; | |
| 25978 }else if( c=='f' ){ | |
| 25979 c = '\f'; | |
| 25980 }else if( c=='r' ){ | |
| 25981 c = '\r'; | |
| 25982 }else if( c=='"' ){ | |
| 25983 c = '"'; | |
| 25984 }else if( c=='\'' ){ | |
| 25985 c = '\''; | |
| 25986 }else if( c=='\\' ){ | |
| 25987 c = '\\'; | |
| 25988 }else if( c=='x' ){ | |
| 25989 int nhd = 0, hdv; | |
| 25990 u8 hv = 0; | |
| 25991 while( nhd<2 && (c=z[i+1+nhd])!=0 && (hdv=hexDigitValue(c))>=0 ){ | |
| 25992 hv = (u8)((hv<<4)|hdv); | |
| 25993 ++nhd; | |
| 25994 } | |
| 25995 i += nhd; | |
| 25996 c = (u8)hv; | |
| 25997 }else if( c>='0' && c<='7' ){ | |
| 25998 c -= '0'; | |
| 25999 if( z[i+1]>='0' && z[i+1]<='7' ){ | |
| 26000 i++; | |
| 26001 c = (c<<3) + z[i] - '0'; | |
| 26002 if( z[i+1]>='0' && z[i+1]<='7' ){ | |
| 26003 i++; | |
| 26004 c = (c<<3) + z[i] - '0'; | |
| 26005 } | |
| 26006 } | |
| 26007 } | |
| 26008 } | |
| 26009 z[j] = c; | |
| 26010 } | |
| 26011 if( j<i ) z[j] = 0; | |
| 26012 } | |
| 26013 | |
| 26014 /* | |
| 26015 ** Interpret zArg as either an integer or a boolean value. Return 1 or 0 | |
| 26016 ** for TRUE and FALSE. Return the integer value if appropriate. | |
| 26017 */ | |
| 26018 static int booleanValue(const char *zArg){ | |
| 26019 int i; | |
| 26020 if( zArg[0]=='0' && zArg[1]=='x' ){ | |
| 26021 for(i=2; hexDigitValue(zArg[i])>=0; i++){} | |
| 26022 }else{ | |
| 26023 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){} | |
| 26024 } | |
| 26025 if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff); | |
| 26026 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){ | |
| 26027 return 1; | |
| 26028 } | |
| 26029 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){ | |
| 26030 return 0; | |
| 26031 } | |
| 26032 sqlite3_fprintf(stderr, | |
| 26033 "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg); | |
| 26034 return 0; | |
| 26035 } | |
| 26036 | |
| 26037 /* | |
| 26038 ** Set or clear a shell flag according to a boolean value. | |
| 26039 */ | |
| 26040 static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){ | |
| 26041 if( booleanValue(zArg) ){ | |
| 26042 ShellSetFlag(p, mFlag); | |
| 26043 }else{ | |
| 26044 ShellClearFlag(p, mFlag); | |
| 26045 } | |
| 26046 } | |
| 26047 | |
| 26048 /* | |
| 26049 ** Close an output file, assuming it is not stderr or stdout | |
| 26050 */ | |
| 26051 static void output_file_close(FILE *f){ | |
| 26052 if( f && f!=stdout && f!=stderr ) fclose(f); | |
| 26053 } | |
| 26054 | |
| 26055 /* | |
| 26056 ** Try to open an output file. The names "stdout" and "stderr" are | |
| 26057 ** recognized and do the right thing. NULL is returned if the output | |
| 26058 ** filename is "off". | |
| 26059 */ | |
| 26060 static FILE *output_file_open(const char *zFile){ | |
| 26061 FILE *f; | |
| 26062 if( cli_strcmp(zFile,"stdout")==0 ){ | |
| 26063 f = stdout; | |
| 26064 }else if( cli_strcmp(zFile, "stderr")==0 ){ | |
| 26065 f = stderr; | |
| 26066 }else if( cli_strcmp(zFile, "off")==0 ){ | |
| 26067 f = 0; | |
| 26068 }else{ | |
| 26069 f = sqlite3_fopen(zFile, "w"); | |
| 26070 if( f==0 ){ | |
| 26071 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile); | |
| 26072 } | |
| 26073 } | |
| 26074 return f; | |
| 26075 } | |
| 26076 | |
| 26077 #ifndef SQLITE_OMIT_TRACE | |
| 26078 /* | |
| 26079 ** A routine for handling output from sqlite3_trace(). | |
| 26080 */ | |
| 26081 static int sql_trace_callback( | |
| 26082 unsigned mType, /* The trace type */ | |
| 26083 void *pArg, /* The ShellState pointer */ | |
| 26084 void *pP, /* Usually a pointer to sqlite_stmt */ | |
| 26085 void *pX /* Auxiliary output */ | |
| 26086 ){ | |
| 26087 ShellState *p = (ShellState*)pArg; | |
| 26088 sqlite3_stmt *pStmt; | |
| 26089 const char *zSql; | |
| 26090 i64 nSql; | |
| 26091 if( p->traceOut==0 ) return 0; | |
| 26092 if( mType==SQLITE_TRACE_CLOSE ){ | |
| 26093 sputz(p->traceOut, "-- closing database connection\n"); | |
| 26094 return 0; | |
| 26095 } | |
| 26096 if( mType!=SQLITE_TRACE_ROW && pX!=0 && ((const char*)pX)[0]=='-' ){ | |
| 26097 zSql = (const char*)pX; | |
| 26098 }else{ | |
| 26099 pStmt = (sqlite3_stmt*)pP; | |
| 26100 switch( p->eTraceType ){ | |
| 26101 case SHELL_TRACE_EXPANDED: { | |
| 26102 zSql = sqlite3_expanded_sql(pStmt); | |
| 26103 break; | |
| 26104 } | |
| 26105 #ifdef SQLITE_ENABLE_NORMALIZE | |
| 26106 case SHELL_TRACE_NORMALIZED: { | |
| 26107 zSql = sqlite3_normalized_sql(pStmt); | |
| 26108 break; | |
| 26109 } | |
| 26110 #endif | |
| 26111 default: { | |
| 26112 zSql = sqlite3_sql(pStmt); | |
| 26113 break; | |
| 26114 } | |
| 26115 } | |
| 26116 } | |
| 26117 if( zSql==0 ) return 0; | |
| 26118 nSql = strlen(zSql); | |
| 26119 if( nSql>1000000000 ) nSql = 1000000000; | |
| 26120 while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; } | |
| 26121 switch( mType ){ | |
| 26122 case SQLITE_TRACE_ROW: | |
| 26123 case SQLITE_TRACE_STMT: { | |
| 26124 sqlite3_fprintf(p->traceOut, "%.*s;\n", (int)nSql, zSql); | |
| 26125 break; | |
| 26126 } | |
| 26127 case SQLITE_TRACE_PROFILE: { | |
| 26128 sqlite3_int64 nNanosec = pX ? *(sqlite3_int64*)pX : 0; | |
| 26129 sqlite3_fprintf(p->traceOut, | |
| 26130 "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec); | |
| 26131 break; | |
| 26132 } | |
| 26133 } | |
| 26134 return 0; | |
| 26135 } | |
| 26136 #endif | |
| 26137 | |
| 26138 /* | |
| 26139 ** A no-op routine that runs with the ".breakpoint" doc-command. This is | |
| 26140 ** a useful spot to set a debugger breakpoint. | |
| 26141 ** | |
| 26142 ** This routine does not do anything practical. The code are there simply | |
| 26143 ** to prevent the compiler from optimizing this routine out. | |
| 26144 */ | |
| 26145 static void test_breakpoint(void){ | |
| 26146 static unsigned int nCall = 0; | |
| 26147 if( (nCall++)==0xffffffff ) printf("Many .breakpoints have run\n"); | |
| 26148 } | |
| 26149 | |
| 26150 /* | |
| 26151 ** An object used to read a CSV and other files for import. | |
| 26152 */ | |
| 26153 typedef struct ImportCtx ImportCtx; | |
| 26154 struct ImportCtx { | |
| 26155 const char *zFile; /* Name of the input file */ | |
| 26156 FILE *in; /* Read the CSV text from this input stream */ | |
| 26157 int (SQLITE_CDECL *xCloser)(FILE*); /* Func to close in */ | |
| 26158 char *z; /* Accumulated text for a field */ | |
| 26159 i64 n; /* Number of bytes in z */ | |
| 26160 i64 nAlloc; /* Space allocated for z[] */ | |
| 26161 int nLine; /* Current line number */ | |
| 26162 int nRow; /* Number of rows imported */ | |
| 26163 int nErr; /* Number of errors encountered */ | |
| 26164 int bNotFirst; /* True if one or more bytes already read */ | |
| 26165 int cTerm; /* Character that terminated the most recent field */ | |
| 26166 int cColSep; /* The column separator character. (Usually ",") */ | |
| 26167 int cRowSep; /* The row separator character. (Usually "\n") */ | |
| 26168 }; | |
| 26169 | |
| 26170 /* Clean up resourced used by an ImportCtx */ | |
| 26171 static void import_cleanup(ImportCtx *p){ | |
| 26172 if( p->in!=0 && p->xCloser!=0 ){ | |
| 26173 p->xCloser(p->in); | |
| 26174 p->in = 0; | |
| 26175 } | |
| 26176 sqlite3_free(p->z); | |
| 26177 p->z = 0; | |
| 26178 } | |
| 26179 | |
| 26180 /* Append a single byte to z[] */ | |
| 26181 static void import_append_char(ImportCtx *p, int c){ | |
| 26182 if( p->n+1>=p->nAlloc ){ | |
| 26183 p->nAlloc += p->nAlloc + 100; | |
| 26184 p->z = sqlite3_realloc64(p->z, p->nAlloc); | |
| 26185 shell_check_oom(p->z); | |
| 26186 } | |
| 26187 p->z[p->n++] = (char)c; | |
| 26188 } | |
| 26189 | |
| 26190 /* Read a single field of CSV text. Compatible with rfc4180 and extended | |
| 26191 ** with the option of having a separator other than ",". | |
| 26192 ** | |
| 26193 ** + Input comes from p->in. | |
| 26194 ** + Store results in p->z of length p->n. Space to hold p->z comes | |
| 26195 ** from sqlite3_malloc64(). | |
| 26196 ** + Use p->cSep as the column separator. The default is ",". | |
| 26197 ** + Use p->rSep as the row separator. The default is "\n". | |
| 26198 ** + Keep track of the line number in p->nLine. | |
| 26199 ** + Store the character that terminates the field in p->cTerm. Store | |
| 26200 ** EOF on end-of-file. | |
| 26201 ** + Report syntax errors on stderr | |
| 26202 */ | |
| 26203 static char *SQLITE_CDECL csv_read_one_field(ImportCtx *p){ | |
| 26204 int c; | |
| 26205 int cSep = (u8)p->cColSep; | |
| 26206 int rSep = (u8)p->cRowSep; | |
| 26207 p->n = 0; | |
| 26208 c = fgetc(p->in); | |
| 26209 if( c==EOF || seenInterrupt ){ | |
| 26210 p->cTerm = EOF; | |
| 26211 return 0; | |
| 26212 } | |
| 26213 if( c=='"' ){ | |
| 26214 int pc, ppc; | |
| 26215 int startLine = p->nLine; | |
| 26216 int cQuote = c; | |
| 26217 pc = ppc = 0; | |
| 26218 while( 1 ){ | |
| 26219 c = fgetc(p->in); | |
| 26220 if( c==rSep ) p->nLine++; | |
| 26221 if( c==cQuote ){ | |
| 26222 if( pc==cQuote ){ | |
| 26223 pc = 0; | |
| 26224 continue; | |
| 26225 } | |
| 26226 } | |
| 26227 if( (c==cSep && pc==cQuote) | |
| 26228 || (c==rSep && pc==cQuote) | |
| 26229 || (c==rSep && pc=='\r' && ppc==cQuote) | |
| 26230 || (c==EOF && pc==cQuote) | |
| 26231 ){ | |
| 26232 do{ p->n--; }while( p->z[p->n]!=cQuote ); | |
| 26233 p->cTerm = c; | |
| 26234 break; | |
| 26235 } | |
| 26236 if( pc==cQuote && c!='\r' ){ | |
| 26237 sqlite3_fprintf(stderr,"%s:%d: unescaped %c character\n", | |
| 26238 p->zFile, p->nLine, cQuote); | |
| 26239 } | |
| 26240 if( c==EOF ){ | |
| 26241 sqlite3_fprintf(stderr,"%s:%d: unterminated %c-quoted field\n", | |
| 26242 p->zFile, startLine, cQuote); | |
| 26243 p->cTerm = c; | |
| 26244 break; | |
| 26245 } | |
| 26246 import_append_char(p, c); | |
| 26247 ppc = pc; | |
| 26248 pc = c; | |
| 26249 } | |
| 26250 }else{ | |
| 26251 /* If this is the first field being parsed and it begins with the | |
| 26252 ** UTF-8 BOM (0xEF BB BF) then skip the BOM */ | |
| 26253 if( (c&0xff)==0xef && p->bNotFirst==0 ){ | |
| 26254 import_append_char(p, c); | |
| 26255 c = fgetc(p->in); | |
| 26256 if( (c&0xff)==0xbb ){ | |
| 26257 import_append_char(p, c); | |
| 26258 c = fgetc(p->in); | |
| 26259 if( (c&0xff)==0xbf ){ | |
| 26260 p->bNotFirst = 1; | |
| 26261 p->n = 0; | |
| 26262 return csv_read_one_field(p); | |
| 26263 } | |
| 26264 } | |
| 26265 } | |
| 26266 while( c!=EOF && c!=cSep && c!=rSep ){ | |
| 26267 import_append_char(p, c); | |
| 26268 c = fgetc(p->in); | |
| 26269 } | |
| 26270 if( c==rSep ){ | |
| 26271 p->nLine++; | |
| 26272 if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; | |
| 26273 } | |
| 26274 p->cTerm = c; | |
| 26275 } | |
| 26276 if( p->z ) p->z[p->n] = 0; | |
| 26277 p->bNotFirst = 1; | |
| 26278 return p->z; | |
| 26279 } | |
| 26280 | |
| 26281 /* Read a single field of ASCII delimited text. | |
| 26282 ** | |
| 26283 ** + Input comes from p->in. | |
| 26284 ** + Store results in p->z of length p->n. Space to hold p->z comes | |
| 26285 ** from sqlite3_malloc64(). | |
| 26286 ** + Use p->cSep as the column separator. The default is "\x1F". | |
| 26287 ** + Use p->rSep as the row separator. The default is "\x1E". | |
| 26288 ** + Keep track of the row number in p->nLine. | |
| 26289 ** + Store the character that terminates the field in p->cTerm. Store | |
| 26290 ** EOF on end-of-file. | |
| 26291 ** + Report syntax errors on stderr | |
| 26292 */ | |
| 26293 static char *SQLITE_CDECL ascii_read_one_field(ImportCtx *p){ | |
| 26294 int c; | |
| 26295 int cSep = (u8)p->cColSep; | |
| 26296 int rSep = (u8)p->cRowSep; | |
| 26297 p->n = 0; | |
| 26298 c = fgetc(p->in); | |
| 26299 if( c==EOF || seenInterrupt ){ | |
| 26300 p->cTerm = EOF; | |
| 26301 return 0; | |
| 26302 } | |
| 26303 while( c!=EOF && c!=cSep && c!=rSep ){ | |
| 26304 import_append_char(p, c); | |
| 26305 c = fgetc(p->in); | |
| 26306 } | |
| 26307 if( c==rSep ){ | |
| 26308 p->nLine++; | |
| 26309 } | |
| 26310 p->cTerm = c; | |
| 26311 if( p->z ) p->z[p->n] = 0; | |
| 26312 return p->z; | |
| 26313 } | |
| 26314 | |
| 26315 /* | |
| 26316 ** Try to transfer data for table zTable. If an error is seen while | |
| 26317 ** moving forward, try to go backwards. The backwards movement won't | |
| 26318 ** work for WITHOUT ROWID tables. | |
| 26319 */ | |
| 26320 static void tryToCloneData( | |
| 26321 ShellState *p, | |
| 26322 sqlite3 *newDb, | |
| 26323 const char *zTable | |
| 26324 ){ | |
| 26325 sqlite3_stmt *pQuery = 0; | |
| 26326 sqlite3_stmt *pInsert = 0; | |
| 26327 char *zQuery = 0; | |
| 26328 char *zInsert = 0; | |
| 26329 int rc; | |
| 26330 int i, j, n; | |
| 26331 int nTable = strlen30(zTable); | |
| 26332 int k = 0; | |
| 26333 int cnt = 0; | |
| 26334 const int spinRate = 10000; | |
| 26335 | |
| 26336 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable); | |
| 26337 shell_check_oom(zQuery); | |
| 26338 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); | |
| 26339 if( rc ){ | |
| 26340 sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n", | |
| 26341 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); | |
| 26342 goto end_data_xfer; | |
| 26343 } | |
| 26344 n = sqlite3_column_count(pQuery); | |
| 26345 zInsert = sqlite3_malloc64(200 + nTable + n*3); | |
| 26346 shell_check_oom(zInsert); | |
| 26347 sqlite3_snprintf(200+nTable,zInsert, | |
| 26348 "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable); | |
| 26349 i = strlen30(zInsert); | |
| 26350 for(j=1; j<n; j++){ | |
| 26351 memcpy(zInsert+i, ",?", 2); | |
| 26352 i += 2; | |
| 26353 } | |
| 26354 memcpy(zInsert+i, ");", 3); | |
| 26355 rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0); | |
| 26356 if( rc ){ | |
| 26357 sqlite3_fprintf(stderr,"Error %d: %s on [%s]\n", | |
| 26358 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zInsert); | |
| 26359 goto end_data_xfer; | |
| 26360 } | |
| 26361 for(k=0; k<2; k++){ | |
| 26362 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ | |
| 26363 for(i=0; i<n; i++){ | |
| 26364 switch( sqlite3_column_type(pQuery, i) ){ | |
| 26365 case SQLITE_NULL: { | |
| 26366 sqlite3_bind_null(pInsert, i+1); | |
| 26367 break; | |
| 26368 } | |
| 26369 case SQLITE_INTEGER: { | |
| 26370 sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i)); | |
| 26371 break; | |
| 26372 } | |
| 26373 case SQLITE_FLOAT: { | |
| 26374 sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i)); | |
| 26375 break; | |
| 26376 } | |
| 26377 case SQLITE_TEXT: { | |
| 26378 sqlite3_bind_text(pInsert, i+1, | |
| 26379 (const char*)sqlite3_column_text(pQuery,i), | |
| 26380 -1, SQLITE_STATIC); | |
| 26381 break; | |
| 26382 } | |
| 26383 case SQLITE_BLOB: { | |
| 26384 sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i), | |
| 26385 sqlite3_column_bytes(pQuery,i), | |
| 26386 SQLITE_STATIC); | |
| 26387 break; | |
| 26388 } | |
| 26389 } | |
| 26390 } /* End for */ | |
| 26391 rc = sqlite3_step(pInsert); | |
| 26392 if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){ | |
| 26393 sqlite3_fprintf(stderr,"Error %d: %s\n", | |
| 26394 sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb)); | |
| 26395 } | |
| 26396 sqlite3_reset(pInsert); | |
| 26397 cnt++; | |
| 26398 if( (cnt%spinRate)==0 ){ | |
| 26399 printf("%c\b", "|/-\\"[(cnt/spinRate)%4]); | |
| 26400 fflush(stdout); | |
| 26401 } | |
| 26402 } /* End while */ | |
| 26403 if( rc==SQLITE_DONE ) break; | |
| 26404 sqlite3_finalize(pQuery); | |
| 26405 sqlite3_free(zQuery); | |
| 26406 zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;", | |
| 26407 zTable); | |
| 26408 shell_check_oom(zQuery); | |
| 26409 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); | |
| 26410 if( rc ){ | |
| 26411 sqlite3_fprintf(stderr,"Warning: cannot step \"%s\" backwards", zTable); | |
| 26412 break; | |
| 26413 } | |
| 26414 } /* End for(k=0...) */ | |
| 26415 | |
| 26416 end_data_xfer: | |
| 26417 sqlite3_finalize(pQuery); | |
| 26418 sqlite3_finalize(pInsert); | |
| 26419 sqlite3_free(zQuery); | |
| 26420 sqlite3_free(zInsert); | |
| 26421 } | |
| 26422 | |
| 26423 | |
| 26424 /* | |
| 26425 ** Try to transfer all rows of the schema that match zWhere. For | |
| 26426 ** each row, invoke xForEach() on the object defined by that row. | |
| 26427 ** If an error is encountered while moving forward through the | |
| 26428 ** sqlite_schema table, try again moving backwards. | |
| 26429 */ | |
| 26430 static void tryToCloneSchema( | |
| 26431 ShellState *p, | |
| 26432 sqlite3 *newDb, | |
| 26433 const char *zWhere, | |
| 26434 void (*xForEach)(ShellState*,sqlite3*,const char*) | |
| 26435 ){ | |
| 26436 sqlite3_stmt *pQuery = 0; | |
| 26437 char *zQuery = 0; | |
| 26438 int rc; | |
| 26439 const unsigned char *zName; | |
| 26440 const unsigned char *zSql; | |
| 26441 char *zErrMsg = 0; | |
| 26442 | |
| 26443 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema" | |
| 26444 " WHERE %s ORDER BY rowid ASC", zWhere); | |
| 26445 shell_check_oom(zQuery); | |
| 26446 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); | |
| 26447 if( rc ){ | |
| 26448 sqlite3_fprintf(stderr, | |
| 26449 "Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db), | |
| 26450 sqlite3_errmsg(p->db), zQuery); | |
| 26451 goto end_schema_xfer; | |
| 26452 } | |
| 26453 while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){ | |
| 26454 zName = sqlite3_column_text(pQuery, 0); | |
| 26455 zSql = sqlite3_column_text(pQuery, 1); | |
| 26456 if( zName==0 || zSql==0 ) continue; | |
| 26457 if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ){ | |
| 26458 sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout); | |
| 26459 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); | |
| 26460 if( zErrMsg ){ | |
| 26461 sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql); | |
| 26462 sqlite3_free(zErrMsg); | |
| 26463 zErrMsg = 0; | |
| 26464 } | |
| 26465 } | |
| 26466 if( xForEach ){ | |
| 26467 xForEach(p, newDb, (const char*)zName); | |
| 26468 } | |
| 26469 sputz(stdout, "done\n"); | |
| 26470 } | |
| 26471 if( rc!=SQLITE_DONE ){ | |
| 26472 sqlite3_finalize(pQuery); | |
| 26473 sqlite3_free(zQuery); | |
| 26474 zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema" | |
| 26475 " WHERE %s ORDER BY rowid DESC", zWhere); | |
| 26476 shell_check_oom(zQuery); | |
| 26477 rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0); | |
| 26478 if( rc ){ | |
| 26479 sqlite3_fprintf(stderr,"Error: (%d) %s on [%s]\n", | |
| 26480 sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery); | |
| 26481 goto end_schema_xfer; | |
| 26482 } | |
| 26483 while( sqlite3_step(pQuery)==SQLITE_ROW ){ | |
| 26484 zName = sqlite3_column_text(pQuery, 0); | |
| 26485 zSql = sqlite3_column_text(pQuery, 1); | |
| 26486 if( zName==0 || zSql==0 ) continue; | |
| 26487 if( sqlite3_stricmp((char*)zName, "sqlite_sequence")==0 ) continue; | |
| 26488 sqlite3_fprintf(stdout, "%s... ", zName); fflush(stdout); | |
| 26489 sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg); | |
| 26490 if( zErrMsg ){ | |
| 26491 sqlite3_fprintf(stderr,"Error: %s\nSQL: [%s]\n", zErrMsg, zSql); | |
| 26492 sqlite3_free(zErrMsg); | |
| 26493 zErrMsg = 0; | |
| 26494 } | |
| 26495 if( xForEach ){ | |
| 26496 xForEach(p, newDb, (const char*)zName); | |
| 26497 } | |
| 26498 sputz(stdout, "done\n"); | |
| 26499 } | |
| 26500 } | |
| 26501 end_schema_xfer: | |
| 26502 sqlite3_finalize(pQuery); | |
| 26503 sqlite3_free(zQuery); | |
| 26504 } | |
| 26505 | |
| 26506 /* | |
| 26507 ** Open a new database file named "zNewDb". Try to recover as much information | |
| 26508 ** as possible out of the main database (which might be corrupt) and write it | |
| 26509 ** into zNewDb. | |
| 26510 */ | |
| 26511 static void tryToClone(ShellState *p, const char *zNewDb){ | |
| 26512 int rc; | |
| 26513 sqlite3 *newDb = 0; | |
| 26514 if( access(zNewDb,0)==0 ){ | |
| 26515 sqlite3_fprintf(stderr,"File \"%s\" already exists.\n", zNewDb); | |
| 26516 return; | |
| 26517 } | |
| 26518 rc = sqlite3_open(zNewDb, &newDb); | |
| 26519 if( rc ){ | |
| 26520 sqlite3_fprintf(stderr, | |
| 26521 "Cannot create output database: %s\n", sqlite3_errmsg(newDb)); | |
| 26522 }else{ | |
| 26523 sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0); | |
| 26524 sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0); | |
| 26525 tryToCloneSchema(p, newDb, "type='table'", tryToCloneData); | |
| 26526 tryToCloneSchema(p, newDb, "type!='table'", 0); | |
| 26527 sqlite3_exec(newDb, "COMMIT;", 0, 0, 0); | |
| 26528 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); | |
| 26529 } | |
| 26530 close_db(newDb); | |
| 26531 } | |
| 26532 | |
| 26533 #ifndef SQLITE_SHELL_FIDDLE | |
| 26534 /* | |
| 26535 ** Change the output stream (file or pipe or console) to something else. | |
| 26536 */ | |
| 26537 static void output_redir(ShellState *p, FILE *pfNew){ | |
| 26538 if( p->out != stdout ){ | |
| 26539 sqlite3_fputs("Output already redirected.\n", stderr); | |
| 26540 }else{ | |
| 26541 p->out = pfNew; | |
| 26542 setCrlfMode(p); | |
| 26543 if( p->mode==MODE_Www ){ | |
| 26544 sqlite3_fputs( | |
| 26545 "<!DOCTYPE html>\n" | |
| 26546 "<HTML><BODY><PRE>\n", | |
| 26547 p->out | |
| 26548 ); | |
| 26549 } | |
| 26550 } | |
| 26551 } | |
| 26552 | |
| 26553 /* | |
| 26554 ** Change the output file back to stdout. | |
| 26555 ** | |
| 26556 ** If the p->doXdgOpen flag is set, that means the output was being | |
| 26557 ** redirected to a temporary file named by p->zTempFile. In that case, | |
| 26558 ** launch start/open/xdg-open on that temporary file. | |
| 26559 */ | |
| 26560 static void output_reset(ShellState *p){ | |
| 26561 if( p->outfile[0]=='|' ){ | |
| 26562 #ifndef SQLITE_OMIT_POPEN | |
| 26563 pclose(p->out); | |
| 26564 #endif | |
| 26565 }else{ | |
| 26566 if( p->mode==MODE_Www ){ | |
| 26567 sqlite3_fputs("</PRE></BODY></HTML>\n", p->out); | |
| 26568 } | |
| 26569 output_file_close(p->out); | |
| 26570 #ifndef SQLITE_NOHAVE_SYSTEM | |
| 26571 if( p->doXdgOpen ){ | |
| 26572 const char *zXdgOpenCmd = | |
| 26573 #if defined(_WIN32) | |
| 26574 "start"; | |
| 26575 #elif defined(__APPLE__) | |
| 26576 "open"; | |
| 26577 #else | |
| 26578 "xdg-open"; | |
| 26579 #endif | |
| 26580 char *zCmd; | |
| 26581 zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile); | |
| 26582 if( system(zCmd) ){ | |
| 26583 sqlite3_fprintf(stderr,"Failed: [%s]\n", zCmd); | |
| 26584 }else{ | |
| 26585 /* Give the start/open/xdg-open command some time to get | |
| 26586 ** going before we continue, and potential delete the | |
| 26587 ** p->zTempFile data file out from under it */ | |
| 26588 sqlite3_sleep(2000); | |
| 26589 } | |
| 26590 sqlite3_free(zCmd); | |
| 26591 outputModePop(p); | |
| 26592 p->doXdgOpen = 0; | |
| 26593 } | |
| 26594 #endif /* !defined(SQLITE_NOHAVE_SYSTEM) */ | |
| 26595 } | |
| 26596 p->outfile[0] = 0; | |
| 26597 p->out = stdout; | |
| 26598 setCrlfMode(p); | |
| 26599 } | |
| 26600 #else | |
| 26601 # define output_redir(SS,pfO) | |
| 26602 # define output_reset(SS) | |
| 26603 #endif | |
| 26604 | |
| 26605 /* | |
| 26606 ** Run an SQL command and return the single integer result. | |
| 26607 */ | |
| 26608 static int db_int(sqlite3 *db, const char *zSql, ...){ | |
| 26609 sqlite3_stmt *pStmt; | |
| 26610 int res = 0; | |
| 26611 char *z; | |
| 26612 va_list ap; | |
| 26613 va_start(ap, zSql); | |
| 26614 z = sqlite3_vmprintf(zSql, ap); | |
| 26615 va_end(ap); | |
| 26616 sqlite3_prepare_v2(db, z, -1, &pStmt, 0); | |
| 26617 if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 26618 res = sqlite3_column_int(pStmt,0); | |
| 26619 } | |
| 26620 sqlite3_finalize(pStmt); | |
| 26621 sqlite3_free(z); | |
| 26622 return res; | |
| 26623 } | |
| 26624 | |
| 26625 #if SQLITE_SHELL_HAVE_RECOVER | |
| 26626 /* | |
| 26627 ** Convert a 2-byte or 4-byte big-endian integer into a native integer | |
| 26628 */ | |
| 26629 static unsigned int get2byteInt(unsigned char *a){ | |
| 26630 return ((unsigned int)a[0]<<8) + (unsigned int)a[1]; | |
| 26631 } | |
| 26632 static unsigned int get4byteInt(unsigned char *a){ | |
| 26633 return ((unsigned int)a[0]<<24) | |
| 26634 + ((unsigned int)a[1]<<16) | |
| 26635 + ((unsigned int)a[2]<<8) | |
| 26636 + (unsigned int)a[3]; | |
| 26637 } | |
| 26638 | |
| 26639 /* | |
| 26640 ** Implementation of the ".dbinfo" command. | |
| 26641 ** | |
| 26642 ** Return 1 on error, 2 to exit, and 0 otherwise. | |
| 26643 */ | |
| 26644 static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){ | |
| 26645 static const struct { const char *zName; int ofst; } aField[] = { | |
| 26646 { "file change counter:", 24 }, | |
| 26647 { "database page count:", 28 }, | |
| 26648 { "freelist page count:", 36 }, | |
| 26649 { "schema cookie:", 40 }, | |
| 26650 { "schema format:", 44 }, | |
| 26651 { "default cache size:", 48 }, | |
| 26652 { "autovacuum top root:", 52 }, | |
| 26653 { "incremental vacuum:", 64 }, | |
| 26654 { "text encoding:", 56 }, | |
| 26655 { "user version:", 60 }, | |
| 26656 { "application id:", 68 }, | |
| 26657 { "software version:", 96 }, | |
| 26658 }; | |
| 26659 static const struct { const char *zName; const char *zSql; } aQuery[] = { | |
| 26660 { "number of tables:", | |
| 26661 "SELECT count(*) FROM %s WHERE type='table'" }, | |
| 26662 { "number of indexes:", | |
| 26663 "SELECT count(*) FROM %s WHERE type='index'" }, | |
| 26664 { "number of triggers:", | |
| 26665 "SELECT count(*) FROM %s WHERE type='trigger'" }, | |
| 26666 { "number of views:", | |
| 26667 "SELECT count(*) FROM %s WHERE type='view'" }, | |
| 26668 { "schema size:", | |
| 26669 "SELECT total(length(sql)) FROM %s" }, | |
| 26670 }; | |
| 26671 int i, rc; | |
| 26672 unsigned iDataVersion; | |
| 26673 char *zSchemaTab; | |
| 26674 char *zDb = nArg>=2 ? azArg[1] : "main"; | |
| 26675 sqlite3_stmt *pStmt = 0; | |
| 26676 unsigned char aHdr[100]; | |
| 26677 open_db(p, 0); | |
| 26678 if( p->db==0 ) return 1; | |
| 26679 rc = sqlite3_prepare_v2(p->db, | |
| 26680 "SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1", | |
| 26681 -1, &pStmt, 0); | |
| 26682 if( rc ){ | |
| 26683 sqlite3_fprintf(stderr,"error: %s\n", sqlite3_errmsg(p->db)); | |
| 26684 sqlite3_finalize(pStmt); | |
| 26685 return 1; | |
| 26686 } | |
| 26687 sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC); | |
| 26688 if( sqlite3_step(pStmt)==SQLITE_ROW | |
| 26689 && sqlite3_column_bytes(pStmt,0)>100 | |
| 26690 ){ | |
| 26691 const u8 *pb = sqlite3_column_blob(pStmt,0); | |
| 26692 shell_check_oom(pb); | |
| 26693 memcpy(aHdr, pb, 100); | |
| 26694 sqlite3_finalize(pStmt); | |
| 26695 }else{ | |
| 26696 sqlite3_fputs("unable to read database header\n", stderr); | |
| 26697 sqlite3_finalize(pStmt); | |
| 26698 return 1; | |
| 26699 } | |
| 26700 i = get2byteInt(aHdr+16); | |
| 26701 if( i==1 ) i = 65536; | |
| 26702 sqlite3_fprintf(p->out, "%-20s %d\n", "database page size:", i); | |
| 26703 sqlite3_fprintf(p->out, "%-20s %d\n", "write format:", aHdr[18]); | |
| 26704 sqlite3_fprintf(p->out, "%-20s %d\n", "read format:", aHdr[19]); | |
| 26705 sqlite3_fprintf(p->out, "%-20s %d\n", "reserved bytes:", aHdr[20]); | |
| 26706 for(i=0; i<ArraySize(aField); i++){ | |
| 26707 int ofst = aField[i].ofst; | |
| 26708 unsigned int val = get4byteInt(aHdr + ofst); | |
| 26709 sqlite3_fprintf(p->out, "%-20s %u", aField[i].zName, val); | |
| 26710 switch( ofst ){ | |
| 26711 case 56: { | |
| 26712 if( val==1 ) sqlite3_fputs(" (utf8)", p->out); | |
| 26713 if( val==2 ) sqlite3_fputs(" (utf16le)", p->out); | |
| 26714 if( val==3 ) sqlite3_fputs(" (utf16be)", p->out); | |
| 26715 } | |
| 26716 } | |
| 26717 sqlite3_fputs("\n", p->out); | |
| 26718 } | |
| 26719 if( zDb==0 ){ | |
| 26720 zSchemaTab = sqlite3_mprintf("main.sqlite_schema"); | |
| 26721 }else if( cli_strcmp(zDb,"temp")==0 ){ | |
| 26722 zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema"); | |
| 26723 }else{ | |
| 26724 zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb); | |
| 26725 } | |
| 26726 for(i=0; i<ArraySize(aQuery); i++){ | |
| 26727 int val = db_int(p->db, aQuery[i].zSql, zSchemaTab); | |
| 26728 sqlite3_fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val); | |
| 26729 } | |
| 26730 sqlite3_free(zSchemaTab); | |
| 26731 sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion); | |
| 26732 sqlite3_fprintf(p->out, "%-20s %u\n", "data version", iDataVersion); | |
| 26733 return 0; | |
| 26734 } | |
| 26735 #endif /* SQLITE_SHELL_HAVE_RECOVER */ | |
| 26736 | |
| 26737 /* | |
| 26738 ** Implementation of the ".dbtotxt" command. | |
| 26739 ** | |
| 26740 ** Return 1 on error, 2 to exit, and 0 otherwise. | |
| 26741 */ | |
| 26742 static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){ | |
| 26743 sqlite3_stmt *pStmt = 0; | |
| 26744 sqlite3_int64 nPage = 0; | |
| 26745 int pgSz = 0; | |
| 26746 const char *zTail; | |
| 26747 char *zName = 0; | |
| 26748 int rc, i, j; | |
| 26749 unsigned char bShow[256]; /* Characters ok to display */ | |
| 26750 | |
| 26751 UNUSED_PARAMETER(nArg); | |
| 26752 UNUSED_PARAMETER(azArg); | |
| 26753 memset(bShow, '.', sizeof(bShow)); | |
| 26754 for(i=' '; i<='~'; i++){ | |
| 26755 if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i; | |
| 26756 } | |
| 26757 rc = sqlite3_prepare_v2(p->db, "PRAGMA page_size", -1, &pStmt, 0); | |
| 26758 if( rc ) goto dbtotxt_error; | |
| 26759 rc = 0; | |
| 26760 if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; | |
| 26761 pgSz = sqlite3_column_int(pStmt, 0); | |
| 26762 sqlite3_finalize(pStmt); | |
| 26763 pStmt = 0; | |
| 26764 if( pgSz<512 || pgSz>65536 || (pgSz&(pgSz-1))!=0 ) goto dbtotxt_error; | |
| 26765 rc = sqlite3_prepare_v2(p->db, "PRAGMA page_count", -1, &pStmt, 0); | |
| 26766 if( rc ) goto dbtotxt_error; | |
| 26767 rc = 0; | |
| 26768 if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error; | |
| 26769 nPage = sqlite3_column_int64(pStmt, 0); | |
| 26770 sqlite3_finalize(pStmt); | |
| 26771 pStmt = 0; | |
| 26772 if( nPage<1 ) goto dbtotxt_error; | |
| 26773 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); | |
| 26774 if( rc ) goto dbtotxt_error; | |
| 26775 if( sqlite3_step(pStmt)!=SQLITE_ROW ){ | |
| 26776 zTail = "unk.db"; | |
| 26777 }else{ | |
| 26778 const char *zFilename = (const char*)sqlite3_column_text(pStmt, 2); | |
| 26779 if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db"; | |
| 26780 zTail = strrchr(zFilename, '/'); | |
| 26781 #if defined(_WIN32) | |
| 26782 if( zTail==0 ) zTail = strrchr(zFilename, '\\'); | |
| 26783 #endif | |
| 26784 if( zTail==0 ){ | |
| 26785 zTail = zFilename; | |
| 26786 }else if( zTail[1]!=0 ){ | |
| 26787 zTail++; | |
| 26788 } | |
| 26789 } | |
| 26790 zName = strdup(zTail); | |
| 26791 shell_check_oom(zName); | |
| 26792 sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n", | |
| 26793 nPage*pgSz, pgSz, zName); | |
| 26794 sqlite3_finalize(pStmt); | |
| 26795 pStmt = 0; | |
| 26796 rc = sqlite3_prepare_v2(p->db, | |
| 26797 "SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0); | |
| 26798 if( rc ) goto dbtotxt_error; | |
| 26799 while( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 26800 sqlite3_int64 pgno = sqlite3_column_int64(pStmt, 0); | |
| 26801 const u8 *aData = sqlite3_column_blob(pStmt, 1); | |
| 26802 int seenPageLabel = 0; | |
| 26803 for(i=0; i<pgSz; i+=16){ | |
| 26804 const u8 *aLine = aData+i; | |
| 26805 for(j=0; j<16 && aLine[j]==0; j++){} | |
| 26806 if( j==16 ) continue; | |
| 26807 if( !seenPageLabel ){ | |
| 26808 sqlite3_fprintf(p->out, "| page %lld offset %lld\n",pgno,(pgno-1)*pgSz); | |
| 26809 seenPageLabel = 1; | |
| 26810 } | |
| 26811 sqlite3_fprintf(p->out, "| %5d:", i); | |
| 26812 for(j=0; j<16; j++) sqlite3_fprintf(p->out, " %02x", aLine[j]); | |
| 26813 sqlite3_fprintf(p->out, " "); | |
| 26814 for(j=0; j<16; j++){ | |
| 26815 unsigned char c = (unsigned char)aLine[j]; | |
| 26816 sqlite3_fprintf(p->out, "%c", bShow[c]); | |
| 26817 } | |
| 26818 sqlite3_fprintf(p->out, "\n"); | |
| 26819 } | |
| 26820 } | |
| 26821 sqlite3_finalize(pStmt); | |
| 26822 sqlite3_fprintf(p->out, "| end %s\n", zName); | |
| 26823 free(zName); | |
| 26824 return 0; | |
| 26825 | |
| 26826 dbtotxt_error: | |
| 26827 if( rc ){ | |
| 26828 sqlite3_fprintf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db)); | |
| 26829 } | |
| 26830 sqlite3_finalize(pStmt); | |
| 26831 free(zName); | |
| 26832 return 1; | |
| 26833 } | |
| 26834 | |
| 26835 /* | |
| 26836 ** Print the given string as an error message. | |
| 26837 */ | |
| 26838 static void shellEmitError(const char *zErr){ | |
| 26839 sqlite3_fprintf(stderr,"Error: %s\n", zErr); | |
| 26840 } | |
| 26841 /* | |
| 26842 ** Print the current sqlite3_errmsg() value to stderr and return 1. | |
| 26843 */ | |
| 26844 static int shellDatabaseError(sqlite3 *db){ | |
| 26845 shellEmitError(sqlite3_errmsg(db)); | |
| 26846 return 1; | |
| 26847 } | |
| 26848 | |
| 26849 /* | |
| 26850 ** Compare the pattern in zGlob[] against the text in z[]. Return TRUE | |
| 26851 ** if they match and FALSE (0) if they do not match. | |
| 26852 ** | |
| 26853 ** Globbing rules: | |
| 26854 ** | |
| 26855 ** '*' Matches any sequence of zero or more characters. | |
| 26856 ** | |
| 26857 ** '?' Matches exactly one character. | |
| 26858 ** | |
| 26859 ** [...] Matches one character from the enclosed list of | |
| 26860 ** characters. | |
| 26861 ** | |
| 26862 ** [^...] Matches one character not in the enclosed list. | |
| 26863 ** | |
| 26864 ** '#' Matches any sequence of one or more digits with an | |
| 26865 ** optional + or - sign in front | |
| 26866 ** | |
| 26867 ** ' ' Any span of whitespace matches any other span of | |
| 26868 ** whitespace. | |
| 26869 ** | |
| 26870 ** Extra whitespace at the end of z[] is ignored. | |
| 26871 */ | |
| 26872 static int testcase_glob(const char *zGlob, const char *z){ | |
| 26873 int c, c2; | |
| 26874 int invert; | |
| 26875 int seen; | |
| 26876 | |
| 26877 while( (c = (*(zGlob++)))!=0 ){ | |
| 26878 if( IsSpace(c) ){ | |
| 26879 if( !IsSpace(*z) ) return 0; | |
| 26880 while( IsSpace(*zGlob) ) zGlob++; | |
| 26881 while( IsSpace(*z) ) z++; | |
| 26882 }else if( c=='*' ){ | |
| 26883 while( (c=(*(zGlob++))) == '*' || c=='?' ){ | |
| 26884 if( c=='?' && (*(z++))==0 ) return 0; | |
| 26885 } | |
| 26886 if( c==0 ){ | |
| 26887 return 1; | |
| 26888 }else if( c=='[' ){ | |
| 26889 while( *z && testcase_glob(zGlob-1,z)==0 ){ | |
| 26890 z++; | |
| 26891 } | |
| 26892 return (*z)!=0; | |
| 26893 } | |
| 26894 while( (c2 = (*(z++)))!=0 ){ | |
| 26895 while( c2!=c ){ | |
| 26896 c2 = *(z++); | |
| 26897 if( c2==0 ) return 0; | |
| 26898 } | |
| 26899 if( testcase_glob(zGlob,z) ) return 1; | |
| 26900 } | |
| 26901 return 0; | |
| 26902 }else if( c=='?' ){ | |
| 26903 if( (*(z++))==0 ) return 0; | |
| 26904 }else if( c=='[' ){ | |
| 26905 int prior_c = 0; | |
| 26906 seen = 0; | |
| 26907 invert = 0; | |
| 26908 c = *(z++); | |
| 26909 if( c==0 ) return 0; | |
| 26910 c2 = *(zGlob++); | |
| 26911 if( c2=='^' ){ | |
| 26912 invert = 1; | |
| 26913 c2 = *(zGlob++); | |
| 26914 } | |
| 26915 if( c2==']' ){ | |
| 26916 if( c==']' ) seen = 1; | |
| 26917 c2 = *(zGlob++); | |
| 26918 } | |
| 26919 while( c2 && c2!=']' ){ | |
| 26920 if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ | |
| 26921 c2 = *(zGlob++); | |
| 26922 if( c>=prior_c && c<=c2 ) seen = 1; | |
| 26923 prior_c = 0; | |
| 26924 }else{ | |
| 26925 if( c==c2 ){ | |
| 26926 seen = 1; | |
| 26927 } | |
| 26928 prior_c = c2; | |
| 26929 } | |
| 26930 c2 = *(zGlob++); | |
| 26931 } | |
| 26932 if( c2==0 || (seen ^ invert)==0 ) return 0; | |
| 26933 }else if( c=='#' ){ | |
| 26934 if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++; | |
| 26935 if( !IsDigit(z[0]) ) return 0; | |
| 26936 z++; | |
| 26937 while( IsDigit(z[0]) ){ z++; } | |
| 26938 }else{ | |
| 26939 if( c!=(*(z++)) ) return 0; | |
| 26940 } | |
| 26941 } | |
| 26942 while( IsSpace(*z) ){ z++; } | |
| 26943 return *z==0; | |
| 26944 } | |
| 26945 | |
| 26946 | |
| 26947 /* | |
| 26948 ** Compare the string as a command-line option with either one or two | |
| 26949 ** initial "-" characters. | |
| 26950 */ | |
| 26951 static int optionMatch(const char *zStr, const char *zOpt){ | |
| 26952 if( zStr[0]!='-' ) return 0; | |
| 26953 zStr++; | |
| 26954 if( zStr[0]=='-' ) zStr++; | |
| 26955 return cli_strcmp(zStr, zOpt)==0; | |
| 26956 } | |
| 26957 | |
| 26958 /* | |
| 26959 ** The input zFN is guaranteed to start with "file:" and is thus a URI | |
| 26960 ** filename. Extract the actual filename and return a pointer to that | |
| 26961 ** filename in spaced obtained from sqlite3_malloc(). | |
| 26962 ** | |
| 26963 ** The caller is responsible for freeing space using sqlite3_free() when | |
| 26964 ** it has finished with the filename. | |
| 26965 */ | |
| 26966 static char *shellFilenameFromUri(const char *zFN){ | |
| 26967 char *zOut; | |
| 26968 int i, j, d1, d2; | |
| 26969 | |
| 26970 assert( cli_strncmp(zFN,"file:",5)==0 ); | |
| 26971 zOut = sqlite3_mprintf("%s", zFN+5); | |
| 26972 shell_check_oom(zOut); | |
| 26973 for(i=j=0; zOut[i]!=0 && zOut[i]!='?'; i++){ | |
| 26974 if( zOut[i]!='%' ){ | |
| 26975 zOut[j++] = zOut[i]; | |
| 26976 continue; | |
| 26977 } | |
| 26978 d1 = hexDigitValue(zOut[i+1]); | |
| 26979 if( d1<0 ){ | |
| 26980 zOut[j] = 0; | |
| 26981 break; | |
| 26982 } | |
| 26983 d2 = hexDigitValue(zOut[i+2]); | |
| 26984 if( d2<0 ){ | |
| 26985 zOut[j] = 0; | |
| 26986 break; | |
| 26987 } | |
| 26988 zOut[j++] = d1*16 + d2; | |
| 26989 i += 2; | |
| 26990 } | |
| 26991 zOut[j] = 0; | |
| 26992 return zOut; | |
| 26993 } | |
| 26994 | |
| 26995 /* | |
| 26996 ** Delete a file. | |
| 26997 */ | |
| 26998 int shellDeleteFile(const char *zFilename){ | |
| 26999 int rc; | |
| 27000 #ifdef _WIN32 | |
| 27001 wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename); | |
| 27002 rc = _wunlink(z); | |
| 27003 sqlite3_free(z); | |
| 27004 #else | |
| 27005 rc = unlink(zFilename); | |
| 27006 #endif | |
| 27007 return rc; | |
| 27008 } | |
| 27009 | |
| 27010 /* | |
| 27011 ** Try to delete the temporary file (if there is one) and free the | |
| 27012 ** memory used to hold the name of the temp file. | |
| 27013 */ | |
| 27014 static void clearTempFile(ShellState *p){ | |
| 27015 if( p->zTempFile==0 ) return; | |
| 27016 if( p->doXdgOpen ) return; | |
| 27017 if( shellDeleteFile(p->zTempFile) ) return; | |
| 27018 sqlite3_free(p->zTempFile); | |
| 27019 p->zTempFile = 0; | |
| 27020 } | |
| 27021 | |
| 27022 /* | |
| 27023 ** Create a new temp file name with the given suffix. | |
| 27024 */ | |
| 27025 static void newTempFile(ShellState *p, const char *zSuffix){ | |
| 27026 clearTempFile(p); | |
| 27027 sqlite3_free(p->zTempFile); | |
| 27028 p->zTempFile = 0; | |
| 27029 if( p->db ){ | |
| 27030 sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile); | |
| 27031 } | |
| 27032 if( p->zTempFile==0 ){ | |
| 27033 /* If p->db is an in-memory database then the TEMPFILENAME file-control | |
| 27034 ** will not work and we will need to fallback to guessing */ | |
| 27035 char *zTemp; | |
| 27036 sqlite3_uint64 r; | |
| 27037 sqlite3_randomness(sizeof(r), &r); | |
| 27038 zTemp = getenv("TEMP"); | |
| 27039 if( zTemp==0 ) zTemp = getenv("TMP"); | |
| 27040 if( zTemp==0 ){ | |
| 27041 #ifdef _WIN32 | |
| 27042 zTemp = "\\tmp"; | |
| 27043 #else | |
| 27044 zTemp = "/tmp"; | |
| 27045 #endif | |
| 27046 } | |
| 27047 p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix); | |
| 27048 }else{ | |
| 27049 p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix); | |
| 27050 } | |
| 27051 shell_check_oom(p->zTempFile); | |
| 27052 } | |
| 27053 | |
| 27054 | |
| 27055 /* | |
| 27056 ** The implementation of SQL scalar function fkey_collate_clause(), used | |
| 27057 ** by the ".lint fkey-indexes" command. This scalar function is always | |
| 27058 ** called with four arguments - the parent table name, the parent column name, | |
| 27059 ** the child table name and the child column name. | |
| 27060 ** | |
| 27061 ** fkey_collate_clause('parent-tab', 'parent-col', 'child-tab', 'child-col') | |
| 27062 ** | |
| 27063 ** If either of the named tables or columns do not exist, this function | |
| 27064 ** returns an empty string. An empty string is also returned if both tables | |
| 27065 ** and columns exist but have the same default collation sequence. Or, | |
| 27066 ** if both exist but the default collation sequences are different, this | |
| 27067 ** function returns the string " COLLATE <parent-collation>", where | |
| 27068 ** <parent-collation> is the default collation sequence of the parent column. | |
| 27069 */ | |
| 27070 static void shellFkeyCollateClause( | |
| 27071 sqlite3_context *pCtx, | |
| 27072 int nVal, | |
| 27073 sqlite3_value **apVal | |
| 27074 ){ | |
| 27075 sqlite3 *db = sqlite3_context_db_handle(pCtx); | |
| 27076 const char *zParent; | |
| 27077 const char *zParentCol; | |
| 27078 const char *zParentSeq; | |
| 27079 const char *zChild; | |
| 27080 const char *zChildCol; | |
| 27081 const char *zChildSeq = 0; /* Initialize to avoid false-positive warning */ | |
| 27082 int rc; | |
| 27083 | |
| 27084 assert( nVal==4 ); | |
| 27085 zParent = (const char*)sqlite3_value_text(apVal[0]); | |
| 27086 zParentCol = (const char*)sqlite3_value_text(apVal[1]); | |
| 27087 zChild = (const char*)sqlite3_value_text(apVal[2]); | |
| 27088 zChildCol = (const char*)sqlite3_value_text(apVal[3]); | |
| 27089 | |
| 27090 sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); | |
| 27091 rc = sqlite3_table_column_metadata( | |
| 27092 db, "main", zParent, zParentCol, 0, &zParentSeq, 0, 0, 0 | |
| 27093 ); | |
| 27094 if( rc==SQLITE_OK ){ | |
| 27095 rc = sqlite3_table_column_metadata( | |
| 27096 db, "main", zChild, zChildCol, 0, &zChildSeq, 0, 0, 0 | |
| 27097 ); | |
| 27098 } | |
| 27099 | |
| 27100 if( rc==SQLITE_OK && sqlite3_stricmp(zParentSeq, zChildSeq) ){ | |
| 27101 char *z = sqlite3_mprintf(" COLLATE %s", zParentSeq); | |
| 27102 sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); | |
| 27103 sqlite3_free(z); | |
| 27104 } | |
| 27105 } | |
| 27106 | |
| 27107 | |
| 27108 /* | |
| 27109 ** The implementation of dot-command ".lint fkey-indexes". | |
| 27110 */ | |
| 27111 static int lintFkeyIndexes( | |
| 27112 ShellState *pState, /* Current shell tool state */ | |
| 27113 char **azArg, /* Array of arguments passed to dot command */ | |
| 27114 int nArg /* Number of entries in azArg[] */ | |
| 27115 ){ | |
| 27116 sqlite3 *db = pState->db; /* Database handle to query "main" db of */ | |
| 27117 int bVerbose = 0; /* If -verbose is present */ | |
| 27118 int bGroupByParent = 0; /* If -groupbyparent is present */ | |
| 27119 int i; /* To iterate through azArg[] */ | |
| 27120 const char *zIndent = ""; /* How much to indent CREATE INDEX by */ | |
| 27121 int rc; /* Return code */ | |
| 27122 sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */ | |
| 27123 FILE *out = pState->out; /* Send output here */ | |
| 27124 | |
| 27125 /* | |
| 27126 ** This SELECT statement returns one row for each foreign key constraint | |
| 27127 ** in the schema of the main database. The column values are: | |
| 27128 ** | |
| 27129 ** 0. The text of an SQL statement similar to: | |
| 27130 ** | |
| 27131 ** "EXPLAIN QUERY PLAN SELECT 1 FROM child_table WHERE child_key=?" | |
| 27132 ** | |
| 27133 ** This SELECT is similar to the one that the foreign keys implementation | |
| 27134 ** needs to run internally on child tables. If there is an index that can | |
| 27135 ** be used to optimize this query, then it can also be used by the FK | |
| 27136 ** implementation to optimize DELETE or UPDATE statements on the parent | |
| 27137 ** table. | |
| 27138 ** | |
| 27139 ** 1. A GLOB pattern suitable for sqlite3_strglob(). If the plan output by | |
| 27140 ** the EXPLAIN QUERY PLAN command matches this pattern, then the schema | |
| 27141 ** contains an index that can be used to optimize the query. | |
| 27142 ** | |
| 27143 ** 2. Human readable text that describes the child table and columns. e.g. | |
| 27144 ** | |
| 27145 ** "child_table(child_key1, child_key2)" | |
| 27146 ** | |
| 27147 ** 3. Human readable text that describes the parent table and columns. e.g. | |
| 27148 ** | |
| 27149 ** "parent_table(parent_key1, parent_key2)" | |
| 27150 ** | |
| 27151 ** 4. A full CREATE INDEX statement for an index that could be used to | |
| 27152 ** optimize DELETE or UPDATE statements on the parent table. e.g. | |
| 27153 ** | |
| 27154 ** "CREATE INDEX child_table_child_key ON child_table(child_key)" | |
| 27155 ** | |
| 27156 ** 5. The name of the parent table. | |
| 27157 ** | |
| 27158 ** These six values are used by the C logic below to generate the report. | |
| 27159 */ | |
| 27160 const char *zSql = | |
| 27161 "SELECT " | |
| 27162 " 'EXPLAIN QUERY PLAN SELECT 1 FROM ' || quote(s.name) || ' WHERE '" | |
| 27163 " || group_concat(quote(s.name) || '.' || quote(f.[from]) || '=?' " | |
| 27164 " || fkey_collate_clause(" | |
| 27165 " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]),' AND ')" | |
| 27166 ", " | |
| 27167 " 'SEARCH ' || s.name || ' USING COVERING INDEX*('" | |
| 27168 " || group_concat('*=?', ' AND ') || ')'" | |
| 27169 ", " | |
| 27170 " s.name || '(' || group_concat(f.[from], ', ') || ')'" | |
| 27171 ", " | |
| 27172 " f.[table] || '(' || group_concat(COALESCE(f.[to], p.[name])) || ')'" | |
| 27173 ", " | |
| 27174 " 'CREATE INDEX ' || quote(s.name ||'_'|| group_concat(f.[from], '_'))" | |
| 27175 " || ' ON ' || quote(s.name) || '('" | |
| 27176 " || group_concat(quote(f.[from]) ||" | |
| 27177 " fkey_collate_clause(" | |
| 27178 " f.[table], COALESCE(f.[to], p.[name]), s.name, f.[from]), ', ')" | |
| 27179 " || ');'" | |
| 27180 ", " | |
| 27181 " f.[table] " | |
| 27182 "FROM sqlite_schema AS s, pragma_foreign_key_list(s.name) AS f " | |
| 27183 "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) " | |
| 27184 "GROUP BY s.name, f.id " | |
| 27185 "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)" | |
| 27186 ; | |
| 27187 const char *zGlobIPK = "SEARCH * USING INTEGER PRIMARY KEY (rowid=?)"; | |
| 27188 | |
| 27189 for(i=2; i<nArg; i++){ | |
| 27190 int n = strlen30(azArg[i]); | |
| 27191 if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){ | |
| 27192 bVerbose = 1; | |
| 27193 } | |
| 27194 else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){ | |
| 27195 bGroupByParent = 1; | |
| 27196 zIndent = " "; | |
| 27197 } | |
| 27198 else{ | |
| 27199 sqlite3_fprintf(stderr, | |
| 27200 "Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]); | |
| 27201 return SQLITE_ERROR; | |
| 27202 } | |
| 27203 } | |
| 27204 | |
| 27205 /* Register the fkey_collate_clause() SQL function */ | |
| 27206 rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8, | |
| 27207 0, shellFkeyCollateClause, 0, 0 | |
| 27208 ); | |
| 27209 | |
| 27210 | |
| 27211 if( rc==SQLITE_OK ){ | |
| 27212 rc = sqlite3_prepare_v2(db, zSql, -1, &pSql, 0); | |
| 27213 } | |
| 27214 if( rc==SQLITE_OK ){ | |
| 27215 sqlite3_bind_int(pSql, 1, bGroupByParent); | |
| 27216 } | |
| 27217 | |
| 27218 if( rc==SQLITE_OK ){ | |
| 27219 int rc2; | |
| 27220 char *zPrev = 0; | |
| 27221 while( SQLITE_ROW==sqlite3_step(pSql) ){ | |
| 27222 int res = -1; | |
| 27223 sqlite3_stmt *pExplain = 0; | |
| 27224 const char *zEQP = (const char*)sqlite3_column_text(pSql, 0); | |
| 27225 const char *zGlob = (const char*)sqlite3_column_text(pSql, 1); | |
| 27226 const char *zFrom = (const char*)sqlite3_column_text(pSql, 2); | |
| 27227 const char *zTarget = (const char*)sqlite3_column_text(pSql, 3); | |
| 27228 const char *zCI = (const char*)sqlite3_column_text(pSql, 4); | |
| 27229 const char *zParent = (const char*)sqlite3_column_text(pSql, 5); | |
| 27230 | |
| 27231 if( zEQP==0 ) continue; | |
| 27232 if( zGlob==0 ) continue; | |
| 27233 rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); | |
| 27234 if( rc!=SQLITE_OK ) break; | |
| 27235 if( SQLITE_ROW==sqlite3_step(pExplain) ){ | |
| 27236 const char *zPlan = (const char*)sqlite3_column_text(pExplain, 3); | |
| 27237 res = zPlan!=0 && ( 0==sqlite3_strglob(zGlob, zPlan) | |
| 27238 || 0==sqlite3_strglob(zGlobIPK, zPlan)); | |
| 27239 } | |
| 27240 rc = sqlite3_finalize(pExplain); | |
| 27241 if( rc!=SQLITE_OK ) break; | |
| 27242 | |
| 27243 if( res<0 ){ | |
| 27244 sqlite3_fputs("Error: internal error", stderr); | |
| 27245 break; | |
| 27246 }else{ | |
| 27247 if( bGroupByParent | |
| 27248 && (bVerbose || res==0) | |
| 27249 && (zPrev==0 || sqlite3_stricmp(zParent, zPrev)) | |
| 27250 ){ | |
| 27251 sqlite3_fprintf(out, "-- Parent table %s\n", zParent); | |
| 27252 sqlite3_free(zPrev); | |
| 27253 zPrev = sqlite3_mprintf("%s", zParent); | |
| 27254 } | |
| 27255 | |
| 27256 if( res==0 ){ | |
| 27257 sqlite3_fprintf(out, "%s%s --> %s\n", zIndent, zCI, zTarget); | |
| 27258 }else if( bVerbose ){ | |
| 27259 sqlite3_fprintf(out, | |
| 27260 "%s/* no extra indexes required for %s -> %s */\n", | |
| 27261 zIndent, zFrom, zTarget | |
| 27262 ); | |
| 27263 } | |
| 27264 } | |
| 27265 } | |
| 27266 sqlite3_free(zPrev); | |
| 27267 | |
| 27268 if( rc!=SQLITE_OK ){ | |
| 27269 sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); | |
| 27270 } | |
| 27271 | |
| 27272 rc2 = sqlite3_finalize(pSql); | |
| 27273 if( rc==SQLITE_OK && rc2!=SQLITE_OK ){ | |
| 27274 rc = rc2; | |
| 27275 sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); | |
| 27276 } | |
| 27277 }else{ | |
| 27278 sqlite3_fprintf(stderr,"%s\n", sqlite3_errmsg(db)); | |
| 27279 } | |
| 27280 | |
| 27281 return rc; | |
| 27282 } | |
| 27283 | |
| 27284 /* | |
| 27285 ** Implementation of ".lint" dot command. | |
| 27286 */ | |
| 27287 static int lintDotCommand( | |
| 27288 ShellState *pState, /* Current shell tool state */ | |
| 27289 char **azArg, /* Array of arguments passed to dot command */ | |
| 27290 int nArg /* Number of entries in azArg[] */ | |
| 27291 ){ | |
| 27292 int n; | |
| 27293 n = (nArg>=2 ? strlen30(azArg[1]) : 0); | |
| 27294 if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage; | |
| 27295 return lintFkeyIndexes(pState, azArg, nArg); | |
| 27296 | |
| 27297 usage: | |
| 27298 sqlite3_fprintf(stderr,"Usage %s sub-command ?switches...?\n", azArg[0]); | |
| 27299 sqlite3_fprintf(stderr, "Where sub-commands are:\n"); | |
| 27300 sqlite3_fprintf(stderr, " fkey-indexes\n"); | |
| 27301 return SQLITE_ERROR; | |
| 27302 } | |
| 27303 | |
| 27304 static void shellPrepare( | |
| 27305 sqlite3 *db, | |
| 27306 int *pRc, | |
| 27307 const char *zSql, | |
| 27308 sqlite3_stmt **ppStmt | |
| 27309 ){ | |
| 27310 *ppStmt = 0; | |
| 27311 if( *pRc==SQLITE_OK ){ | |
| 27312 int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); | |
| 27313 if( rc!=SQLITE_OK ){ | |
| 27314 sqlite3_fprintf(stderr, | |
| 27315 "sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db)); | |
| 27316 *pRc = rc; | |
| 27317 } | |
| 27318 } | |
| 27319 } | |
| 27320 | |
| 27321 /* | |
| 27322 ** Create a prepared statement using printf-style arguments for the SQL. | |
| 27323 */ | |
| 27324 static void shellPreparePrintf( | |
| 27325 sqlite3 *db, | |
| 27326 int *pRc, | |
| 27327 sqlite3_stmt **ppStmt, | |
| 27328 const char *zFmt, | |
| 27329 ... | |
| 27330 ){ | |
| 27331 *ppStmt = 0; | |
| 27332 if( *pRc==SQLITE_OK ){ | |
| 27333 va_list ap; | |
| 27334 char *z; | |
| 27335 va_start(ap, zFmt); | |
| 27336 z = sqlite3_vmprintf(zFmt, ap); | |
| 27337 va_end(ap); | |
| 27338 if( z==0 ){ | |
| 27339 *pRc = SQLITE_NOMEM; | |
| 27340 }else{ | |
| 27341 shellPrepare(db, pRc, z, ppStmt); | |
| 27342 sqlite3_free(z); | |
| 27343 } | |
| 27344 } | |
| 27345 } | |
| 27346 | |
| 27347 /* | |
| 27348 ** Finalize the prepared statement created using shellPreparePrintf(). | |
| 27349 */ | |
| 27350 static void shellFinalize( | |
| 27351 int *pRc, | |
| 27352 sqlite3_stmt *pStmt | |
| 27353 ){ | |
| 27354 if( pStmt ){ | |
| 27355 sqlite3 *db = sqlite3_db_handle(pStmt); | |
| 27356 int rc = sqlite3_finalize(pStmt); | |
| 27357 if( *pRc==SQLITE_OK ){ | |
| 27358 if( rc!=SQLITE_OK ){ | |
| 27359 sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db)); | |
| 27360 } | |
| 27361 *pRc = rc; | |
| 27362 } | |
| 27363 } | |
| 27364 } | |
| 27365 | |
| 27366 #if !defined SQLITE_OMIT_VIRTUALTABLE | |
| 27367 /* Reset the prepared statement created using shellPreparePrintf(). | |
| 27368 ** | |
| 27369 ** This routine is could be marked "static". But it is not always used, | |
| 27370 ** depending on compile-time options. By omitting the "static", we avoid | |
| 27371 ** nuisance compiler warnings about "defined but not used". | |
| 27372 */ | |
| 27373 void shellReset( | |
| 27374 int *pRc, | |
| 27375 sqlite3_stmt *pStmt | |
| 27376 ){ | |
| 27377 int rc = sqlite3_reset(pStmt); | |
| 27378 if( *pRc==SQLITE_OK ){ | |
| 27379 if( rc!=SQLITE_OK ){ | |
| 27380 sqlite3 *db = sqlite3_db_handle(pStmt); | |
| 27381 sqlite3_fprintf(stderr,"SQL error: %s\n", sqlite3_errmsg(db)); | |
| 27382 } | |
| 27383 *pRc = rc; | |
| 27384 } | |
| 27385 } | |
| 27386 #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */ | |
| 27387 | |
| 27388 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) | |
| 27389 /****************************************************************************** | |
| 27390 ** The ".archive" or ".ar" command. | |
| 27391 */ | |
| 27392 /* | |
| 27393 ** Structure representing a single ".ar" command. | |
| 27394 */ | |
| 27395 typedef struct ArCommand ArCommand; | |
| 27396 struct ArCommand { | |
| 27397 u8 eCmd; /* An AR_CMD_* value */ | |
| 27398 u8 bVerbose; /* True if --verbose */ | |
| 27399 u8 bZip; /* True if the archive is a ZIP */ | |
| 27400 u8 bDryRun; /* True if --dry-run */ | |
| 27401 u8 bAppend; /* True if --append */ | |
| 27402 u8 bGlob; /* True if --glob */ | |
| 27403 u8 fromCmdLine; /* Run from -A instead of .archive */ | |
| 27404 int nArg; /* Number of command arguments */ | |
| 27405 char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */ | |
| 27406 const char *zFile; /* --file argument, or NULL */ | |
| 27407 const char *zDir; /* --directory argument, or NULL */ | |
| 27408 char **azArg; /* Array of command arguments */ | |
| 27409 ShellState *p; /* Shell state */ | |
| 27410 FILE *out; /* Output to this stream */ | |
| 27411 sqlite3 *db; /* Database containing the archive */ | |
| 27412 }; | |
| 27413 | |
| 27414 /* | |
| 27415 ** Print a usage message for the .ar command to stderr and return SQLITE_ERROR. | |
| 27416 */ | |
| 27417 static int arUsage(FILE *f){ | |
| 27418 showHelp(f,"archive"); | |
| 27419 return SQLITE_ERROR; | |
| 27420 } | |
| 27421 | |
| 27422 /* | |
| 27423 ** Print an error message for the .ar command to stderr and return | |
| 27424 ** SQLITE_ERROR. | |
| 27425 */ | |
| 27426 static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){ | |
| 27427 va_list ap; | |
| 27428 char *z; | |
| 27429 va_start(ap, zFmt); | |
| 27430 z = sqlite3_vmprintf(zFmt, ap); | |
| 27431 va_end(ap); | |
| 27432 shellEmitError(z); | |
| 27433 if( pAr->fromCmdLine ){ | |
| 27434 sqlite3_fputs("Use \"-A\" for more help\n", stderr); | |
| 27435 }else{ | |
| 27436 sqlite3_fputs("Use \".archive --help\" for more help\n", stderr); | |
| 27437 } | |
| 27438 sqlite3_free(z); | |
| 27439 return SQLITE_ERROR; | |
| 27440 } | |
| 27441 | |
| 27442 /* | |
| 27443 ** Values for ArCommand.eCmd. | |
| 27444 */ | |
| 27445 #define AR_CMD_CREATE 1 | |
| 27446 #define AR_CMD_UPDATE 2 | |
| 27447 #define AR_CMD_INSERT 3 | |
| 27448 #define AR_CMD_EXTRACT 4 | |
| 27449 #define AR_CMD_LIST 5 | |
| 27450 #define AR_CMD_HELP 6 | |
| 27451 #define AR_CMD_REMOVE 7 | |
| 27452 | |
| 27453 /* | |
| 27454 ** Other (non-command) switches. | |
| 27455 */ | |
| 27456 #define AR_SWITCH_VERBOSE 8 | |
| 27457 #define AR_SWITCH_FILE 9 | |
| 27458 #define AR_SWITCH_DIRECTORY 10 | |
| 27459 #define AR_SWITCH_APPEND 11 | |
| 27460 #define AR_SWITCH_DRYRUN 12 | |
| 27461 #define AR_SWITCH_GLOB 13 | |
| 27462 | |
| 27463 static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){ | |
| 27464 switch( eSwitch ){ | |
| 27465 case AR_CMD_CREATE: | |
| 27466 case AR_CMD_EXTRACT: | |
| 27467 case AR_CMD_LIST: | |
| 27468 case AR_CMD_REMOVE: | |
| 27469 case AR_CMD_UPDATE: | |
| 27470 case AR_CMD_INSERT: | |
| 27471 case AR_CMD_HELP: | |
| 27472 if( pAr->eCmd ){ | |
| 27473 return arErrorMsg(pAr, "multiple command options"); | |
| 27474 } | |
| 27475 pAr->eCmd = eSwitch; | |
| 27476 break; | |
| 27477 | |
| 27478 case AR_SWITCH_DRYRUN: | |
| 27479 pAr->bDryRun = 1; | |
| 27480 break; | |
| 27481 case AR_SWITCH_GLOB: | |
| 27482 pAr->bGlob = 1; | |
| 27483 break; | |
| 27484 case AR_SWITCH_VERBOSE: | |
| 27485 pAr->bVerbose = 1; | |
| 27486 break; | |
| 27487 case AR_SWITCH_APPEND: | |
| 27488 pAr->bAppend = 1; | |
| 27489 deliberate_fall_through; /* FALLTHRU */ | |
| 27490 case AR_SWITCH_FILE: | |
| 27491 pAr->zFile = zArg; | |
| 27492 break; | |
| 27493 case AR_SWITCH_DIRECTORY: | |
| 27494 pAr->zDir = zArg; | |
| 27495 break; | |
| 27496 } | |
| 27497 | |
| 27498 return SQLITE_OK; | |
| 27499 } | |
| 27500 | |
| 27501 /* | |
| 27502 ** Parse the command line for an ".ar" command. The results are written into | |
| 27503 ** structure (*pAr). SQLITE_OK is returned if the command line is parsed | |
| 27504 ** successfully, otherwise an error message is written to stderr and | |
| 27505 ** SQLITE_ERROR returned. | |
| 27506 */ | |
| 27507 static int arParseCommand( | |
| 27508 char **azArg, /* Array of arguments passed to dot command */ | |
| 27509 int nArg, /* Number of entries in azArg[] */ | |
| 27510 ArCommand *pAr /* Populate this object */ | |
| 27511 ){ | |
| 27512 struct ArSwitch { | |
| 27513 const char *zLong; | |
| 27514 char cShort; | |
| 27515 u8 eSwitch; | |
| 27516 u8 bArg; | |
| 27517 } aSwitch[] = { | |
| 27518 { "create", 'c', AR_CMD_CREATE, 0 }, | |
| 27519 { "extract", 'x', AR_CMD_EXTRACT, 0 }, | |
| 27520 { "insert", 'i', AR_CMD_INSERT, 0 }, | |
| 27521 { "list", 't', AR_CMD_LIST, 0 }, | |
| 27522 { "remove", 'r', AR_CMD_REMOVE, 0 }, | |
| 27523 { "update", 'u', AR_CMD_UPDATE, 0 }, | |
| 27524 { "help", 'h', AR_CMD_HELP, 0 }, | |
| 27525 { "verbose", 'v', AR_SWITCH_VERBOSE, 0 }, | |
| 27526 { "file", 'f', AR_SWITCH_FILE, 1 }, | |
| 27527 { "append", 'a', AR_SWITCH_APPEND, 1 }, | |
| 27528 { "directory", 'C', AR_SWITCH_DIRECTORY, 1 }, | |
| 27529 { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 }, | |
| 27530 { "glob", 'g', AR_SWITCH_GLOB, 0 }, | |
| 27531 }; | |
| 27532 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch); | |
| 27533 struct ArSwitch *pEnd = &aSwitch[nSwitch]; | |
| 27534 | |
| 27535 if( nArg<=1 ){ | |
| 27536 sqlite3_fprintf(stderr, "Wrong number of arguments. Usage:\n"); | |
| 27537 return arUsage(stderr); | |
| 27538 }else{ | |
| 27539 char *z = azArg[1]; | |
| 27540 if( z[0]!='-' ){ | |
| 27541 /* Traditional style [tar] invocation */ | |
| 27542 int i; | |
| 27543 int iArg = 2; | |
| 27544 for(i=0; z[i]; i++){ | |
| 27545 const char *zArg = 0; | |
| 27546 struct ArSwitch *pOpt; | |
| 27547 for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){ | |
| 27548 if( z[i]==pOpt->cShort ) break; | |
| 27549 } | |
| 27550 if( pOpt==pEnd ){ | |
| 27551 return arErrorMsg(pAr, "unrecognized option: %c", z[i]); | |
| 27552 } | |
| 27553 if( pOpt->bArg ){ | |
| 27554 if( iArg>=nArg ){ | |
| 27555 return arErrorMsg(pAr, "option requires an argument: %c",z[i]); | |
| 27556 } | |
| 27557 zArg = azArg[iArg++]; | |
| 27558 } | |
| 27559 if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR; | |
| 27560 } | |
| 27561 pAr->nArg = nArg-iArg; | |
| 27562 if( pAr->nArg>0 ){ | |
| 27563 pAr->azArg = &azArg[iArg]; | |
| 27564 } | |
| 27565 }else{ | |
| 27566 /* Non-traditional invocation */ | |
| 27567 int iArg; | |
| 27568 for(iArg=1; iArg<nArg; iArg++){ | |
| 27569 int n; | |
| 27570 z = azArg[iArg]; | |
| 27571 if( z[0]!='-' ){ | |
| 27572 /* All remaining command line words are command arguments. */ | |
| 27573 pAr->azArg = &azArg[iArg]; | |
| 27574 pAr->nArg = nArg-iArg; | |
| 27575 break; | |
| 27576 } | |
| 27577 n = strlen30(z); | |
| 27578 | |
| 27579 if( z[1]!='-' ){ | |
| 27580 int i; | |
| 27581 /* One or more short options */ | |
| 27582 for(i=1; i<n; i++){ | |
| 27583 const char *zArg = 0; | |
| 27584 struct ArSwitch *pOpt; | |
| 27585 for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){ | |
| 27586 if( z[i]==pOpt->cShort ) break; | |
| 27587 } | |
| 27588 if( pOpt==pEnd ){ | |
| 27589 return arErrorMsg(pAr, "unrecognized option: %c", z[i]); | |
| 27590 } | |
| 27591 if( pOpt->bArg ){ | |
| 27592 if( i<(n-1) ){ | |
| 27593 zArg = &z[i+1]; | |
| 27594 i = n; | |
| 27595 }else{ | |
| 27596 if( iArg>=(nArg-1) ){ | |
| 27597 return arErrorMsg(pAr, "option requires an argument: %c", | |
| 27598 z[i]); | |
| 27599 } | |
| 27600 zArg = azArg[++iArg]; | |
| 27601 } | |
| 27602 } | |
| 27603 if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR; | |
| 27604 } | |
| 27605 }else if( z[2]=='\0' ){ | |
| 27606 /* A -- option, indicating that all remaining command line words | |
| 27607 ** are command arguments. */ | |
| 27608 pAr->azArg = &azArg[iArg+1]; | |
| 27609 pAr->nArg = nArg-iArg-1; | |
| 27610 break; | |
| 27611 }else{ | |
| 27612 /* A long option */ | |
| 27613 const char *zArg = 0; /* Argument for option, if any */ | |
| 27614 struct ArSwitch *pMatch = 0; /* Matching option */ | |
| 27615 struct ArSwitch *pOpt; /* Iterator */ | |
| 27616 for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){ | |
| 27617 const char *zLong = pOpt->zLong; | |
| 27618 if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){ | |
| 27619 if( pMatch ){ | |
| 27620 return arErrorMsg(pAr, "ambiguous option: %s",z); | |
| 27621 }else{ | |
| 27622 pMatch = pOpt; | |
| 27623 } | |
| 27624 } | |
| 27625 } | |
| 27626 | |
| 27627 if( pMatch==0 ){ | |
| 27628 return arErrorMsg(pAr, "unrecognized option: %s", z); | |
| 27629 } | |
| 27630 if( pMatch->bArg ){ | |
| 27631 if( iArg>=(nArg-1) ){ | |
| 27632 return arErrorMsg(pAr, "option requires an argument: %s", z); | |
| 27633 } | |
| 27634 zArg = azArg[++iArg]; | |
| 27635 } | |
| 27636 if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR; | |
| 27637 } | |
| 27638 } | |
| 27639 } | |
| 27640 } | |
| 27641 if( pAr->eCmd==0 ){ | |
| 27642 sqlite3_fprintf(stderr, "Required argument missing. Usage:\n"); | |
| 27643 return arUsage(stderr); | |
| 27644 } | |
| 27645 return SQLITE_OK; | |
| 27646 } | |
| 27647 | |
| 27648 /* | |
| 27649 ** This function assumes that all arguments within the ArCommand.azArg[] | |
| 27650 ** array refer to archive members, as for the --extract, --list or --remove | |
| 27651 ** commands. It checks that each of them are "present". If any specified | |
| 27652 ** file is not present in the archive, an error is printed to stderr and an | |
| 27653 ** error code returned. Otherwise, if all specified arguments are present | |
| 27654 ** in the archive, SQLITE_OK is returned. Here, "present" means either an | |
| 27655 ** exact equality when pAr->bGlob is false or a "name GLOB pattern" match | |
| 27656 ** when pAr->bGlob is true. | |
| 27657 ** | |
| 27658 ** This function strips any trailing '/' characters from each argument. | |
| 27659 ** This is consistent with the way the [tar] command seems to work on | |
| 27660 ** Linux. | |
| 27661 */ | |
| 27662 static int arCheckEntries(ArCommand *pAr){ | |
| 27663 int rc = SQLITE_OK; | |
| 27664 if( pAr->nArg ){ | |
| 27665 int i, j; | |
| 27666 sqlite3_stmt *pTest = 0; | |
| 27667 const char *zSel = (pAr->bGlob) | |
| 27668 ? "SELECT name FROM %s WHERE glob($name,name)" | |
| 27669 : "SELECT name FROM %s WHERE name=$name"; | |
| 27670 | |
| 27671 shellPreparePrintf(pAr->db, &rc, &pTest, zSel, pAr->zSrcTable); | |
| 27672 j = sqlite3_bind_parameter_index(pTest, "$name"); | |
| 27673 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){ | |
| 27674 char *z = pAr->azArg[i]; | |
| 27675 int n = strlen30(z); | |
| 27676 int bOk = 0; | |
| 27677 while( n>0 && z[n-1]=='/' ) n--; | |
| 27678 z[n] = '\0'; | |
| 27679 sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC); | |
| 27680 if( SQLITE_ROW==sqlite3_step(pTest) ){ | |
| 27681 bOk = 1; | |
| 27682 } | |
| 27683 shellReset(&rc, pTest); | |
| 27684 if( rc==SQLITE_OK && bOk==0 ){ | |
| 27685 sqlite3_fprintf(stderr,"not found in archive: %s\n", z); | |
| 27686 rc = SQLITE_ERROR; | |
| 27687 } | |
| 27688 } | |
| 27689 shellFinalize(&rc, pTest); | |
| 27690 } | |
| 27691 return rc; | |
| 27692 } | |
| 27693 | |
| 27694 /* | |
| 27695 ** Format a WHERE clause that can be used against the "sqlar" table to | |
| 27696 ** identify all archive members that match the command arguments held | |
| 27697 ** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning. | |
| 27698 ** The caller is responsible for eventually calling sqlite3_free() on | |
| 27699 ** any non-NULL (*pzWhere) value. Here, "match" means strict equality | |
| 27700 ** when pAr->bGlob is false and GLOB match when pAr->bGlob is true. | |
| 27701 */ | |
| 27702 static void arWhereClause( | |
| 27703 int *pRc, | |
| 27704 ArCommand *pAr, | |
| 27705 char **pzWhere /* OUT: New WHERE clause */ | |
| 27706 ){ | |
| 27707 char *zWhere = 0; | |
| 27708 if( *pRc==SQLITE_OK ){ | |
| 27709 if( pAr->nArg==0 ){ | |
| 27710 zWhere = sqlite3_mprintf("1"); | |
| 27711 }else{ | |
| 27712 char *z1 = sqlite3_mprintf(pAr->bGlob ? "" : "name IN("); | |
| 27713 char *z2 = sqlite3_mprintf(""); | |
| 27714 const char *zSep1 = ""; | |
| 27715 const char *zSep2 = ""; | |
| 27716 | |
| 27717 int i; | |
| 27718 for(i=0; i<pAr->nArg && z1 && z2; i++){ | |
| 27719 const char *z = pAr->azArg[i]; | |
| 27720 int n = strlen30(z); | |
| 27721 | |
| 27722 if( pAr->bGlob ){ | |
| 27723 z1 = sqlite3_mprintf("%z%sname GLOB '%q'", z1, zSep2, z); | |
| 27724 z2 = sqlite3_mprintf( | |
| 27725 "%z%ssubstr(name,1,%d) GLOB '%q/'", z2, zSep2, n+1,z | |
| 27726 ); | |
| 27727 }else{ | |
| 27728 z1 = sqlite3_mprintf("%z%s'%q'", z1, zSep1, z); | |
| 27729 z2 = sqlite3_mprintf("%z%ssubstr(name,1,%d) = '%q/'",z2,zSep2,n+1,z); | |
| 27730 } | |
| 27731 zSep1 = ", "; | |
| 27732 zSep2 = " OR "; | |
| 27733 } | |
| 27734 if( z1==0 || z2==0 ){ | |
| 27735 *pRc = SQLITE_NOMEM; | |
| 27736 }else{ | |
| 27737 zWhere = sqlite3_mprintf("(%s%s OR (name GLOB '*/*' AND (%s))) ", | |
| 27738 z1, pAr->bGlob==0 ? ")" : "", z2 | |
| 27739 ); | |
| 27740 } | |
| 27741 sqlite3_free(z1); | |
| 27742 sqlite3_free(z2); | |
| 27743 } | |
| 27744 } | |
| 27745 *pzWhere = zWhere; | |
| 27746 } | |
| 27747 | |
| 27748 /* | |
| 27749 ** Implementation of .ar "lisT" command. | |
| 27750 */ | |
| 27751 static int arListCommand(ArCommand *pAr){ | |
| 27752 const char *zSql = "SELECT %s FROM %s WHERE %s"; | |
| 27753 const char *azCols[] = { | |
| 27754 "name", | |
| 27755 "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name" | |
| 27756 }; | |
| 27757 | |
| 27758 char *zWhere = 0; | |
| 27759 sqlite3_stmt *pSql = 0; | |
| 27760 int rc; | |
| 27761 | |
| 27762 rc = arCheckEntries(pAr); | |
| 27763 arWhereClause(&rc, pAr, &zWhere); | |
| 27764 | |
| 27765 shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose], | |
| 27766 pAr->zSrcTable, zWhere); | |
| 27767 if( pAr->bDryRun ){ | |
| 27768 sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql)); | |
| 27769 }else{ | |
| 27770 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ | |
| 27771 if( pAr->bVerbose ){ | |
| 27772 sqlite3_fprintf(pAr->out, "%s % 10d %s %s\n", | |
| 27773 sqlite3_column_text(pSql, 0), sqlite3_column_int(pSql, 1), | |
| 27774 sqlite3_column_text(pSql, 2),sqlite3_column_text(pSql, 3)); | |
| 27775 }else{ | |
| 27776 sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0)); | |
| 27777 } | |
| 27778 } | |
| 27779 } | |
| 27780 shellFinalize(&rc, pSql); | |
| 27781 sqlite3_free(zWhere); | |
| 27782 return rc; | |
| 27783 } | |
| 27784 | |
| 27785 /* | |
| 27786 ** Implementation of .ar "Remove" command. | |
| 27787 */ | |
| 27788 static int arRemoveCommand(ArCommand *pAr){ | |
| 27789 int rc = 0; | |
| 27790 char *zSql = 0; | |
| 27791 char *zWhere = 0; | |
| 27792 | |
| 27793 if( pAr->nArg ){ | |
| 27794 /* Verify that args actually exist within the archive before proceeding. | |
| 27795 ** And formulate a WHERE clause to match them. */ | |
| 27796 rc = arCheckEntries(pAr); | |
| 27797 arWhereClause(&rc, pAr, &zWhere); | |
| 27798 } | |
| 27799 if( rc==SQLITE_OK ){ | |
| 27800 zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;", | |
| 27801 pAr->zSrcTable, zWhere); | |
| 27802 if( pAr->bDryRun ){ | |
| 27803 sqlite3_fprintf(pAr->out, "%s\n", zSql); | |
| 27804 }else{ | |
| 27805 char *zErr = 0; | |
| 27806 rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0); | |
| 27807 if( rc==SQLITE_OK ){ | |
| 27808 rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); | |
| 27809 if( rc!=SQLITE_OK ){ | |
| 27810 sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0); | |
| 27811 }else{ | |
| 27812 rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0); | |
| 27813 } | |
| 27814 } | |
| 27815 if( zErr ){ | |
| 27816 sqlite3_fprintf(stdout, "ERROR: %s\n", zErr); /* stdout? */ | |
| 27817 sqlite3_free(zErr); | |
| 27818 } | |
| 27819 } | |
| 27820 } | |
| 27821 sqlite3_free(zWhere); | |
| 27822 sqlite3_free(zSql); | |
| 27823 return rc; | |
| 27824 } | |
| 27825 | |
| 27826 /* | |
| 27827 ** Implementation of .ar "eXtract" command. | |
| 27828 */ | |
| 27829 static int arExtractCommand(ArCommand *pAr){ | |
| 27830 const char *zSql1 = | |
| 27831 "SELECT " | |
| 27832 " ($dir || name)," | |
| 27833 " writefile(($dir || name), %s, mode, mtime) " | |
| 27834 "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)" | |
| 27835 " AND name NOT GLOB '*..[/\\]*'"; | |
| 27836 | |
| 27837 const char *azExtraArg[] = { | |
| 27838 "sqlar_uncompress(data, sz)", | |
| 27839 "data" | |
| 27840 }; | |
| 27841 | |
| 27842 sqlite3_stmt *pSql = 0; | |
| 27843 int rc = SQLITE_OK; | |
| 27844 char *zDir = 0; | |
| 27845 char *zWhere = 0; | |
| 27846 int i, j; | |
| 27847 | |
| 27848 /* If arguments are specified, check that they actually exist within | |
| 27849 ** the archive before proceeding. And formulate a WHERE clause to | |
| 27850 ** match them. */ | |
| 27851 rc = arCheckEntries(pAr); | |
| 27852 arWhereClause(&rc, pAr, &zWhere); | |
| 27853 | |
| 27854 if( rc==SQLITE_OK ){ | |
| 27855 if( pAr->zDir ){ | |
| 27856 zDir = sqlite3_mprintf("%s/", pAr->zDir); | |
| 27857 }else{ | |
| 27858 zDir = sqlite3_mprintf(""); | |
| 27859 } | |
| 27860 if( zDir==0 ) rc = SQLITE_NOMEM; | |
| 27861 } | |
| 27862 | |
| 27863 shellPreparePrintf(pAr->db, &rc, &pSql, zSql1, | |
| 27864 azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere | |
| 27865 ); | |
| 27866 | |
| 27867 if( rc==SQLITE_OK ){ | |
| 27868 j = sqlite3_bind_parameter_index(pSql, "$dir"); | |
| 27869 sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC); | |
| 27870 | |
| 27871 /* Run the SELECT statement twice. The first time, writefile() is called | |
| 27872 ** for all archive members that should be extracted. The second time, | |
| 27873 ** only for the directories. This is because the timestamps for | |
| 27874 ** extracted directories must be reset after they are populated (as | |
| 27875 ** populating them changes the timestamp). */ | |
| 27876 for(i=0; i<2; i++){ | |
| 27877 j = sqlite3_bind_parameter_index(pSql, "$dirOnly"); | |
| 27878 sqlite3_bind_int(pSql, j, i); | |
| 27879 if( pAr->bDryRun ){ | |
| 27880 sqlite3_fprintf(pAr->out, "%s\n", sqlite3_sql(pSql)); | |
| 27881 }else{ | |
| 27882 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){ | |
| 27883 if( i==0 && pAr->bVerbose ){ | |
| 27884 sqlite3_fprintf(pAr->out, "%s\n", sqlite3_column_text(pSql, 0)); | |
| 27885 } | |
| 27886 } | |
| 27887 } | |
| 27888 shellReset(&rc, pSql); | |
| 27889 } | |
| 27890 shellFinalize(&rc, pSql); | |
| 27891 } | |
| 27892 | |
| 27893 sqlite3_free(zDir); | |
| 27894 sqlite3_free(zWhere); | |
| 27895 return rc; | |
| 27896 } | |
| 27897 | |
| 27898 /* | |
| 27899 ** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out. | |
| 27900 */ | |
| 27901 static int arExecSql(ArCommand *pAr, const char *zSql){ | |
| 27902 int rc; | |
| 27903 if( pAr->bDryRun ){ | |
| 27904 sqlite3_fprintf(pAr->out, "%s\n", zSql); | |
| 27905 rc = SQLITE_OK; | |
| 27906 }else{ | |
| 27907 char *zErr = 0; | |
| 27908 rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr); | |
| 27909 if( zErr ){ | |
| 27910 sqlite3_fprintf(stdout, "ERROR: %s\n", zErr); | |
| 27911 sqlite3_free(zErr); | |
| 27912 } | |
| 27913 } | |
| 27914 return rc; | |
| 27915 } | |
| 27916 | |
| 27917 | |
| 27918 /* | |
| 27919 ** Implementation of .ar "create", "insert", and "update" commands. | |
| 27920 ** | |
| 27921 ** create -> Create a new SQL archive | |
| 27922 ** insert -> Insert or reinsert all files listed | |
| 27923 ** update -> Insert files that have changed or that were not | |
| 27924 ** previously in the archive | |
| 27925 ** | |
| 27926 ** Create the "sqlar" table in the database if it does not already exist. | |
| 27927 ** Then add each file in the azFile[] array to the archive. Directories | |
| 27928 ** are added recursively. If argument bVerbose is non-zero, a message is | |
| 27929 ** printed on stdout for each file archived. | |
| 27930 ** | |
| 27931 ** The create command is the same as update, except that it drops | |
| 27932 ** any existing "sqlar" table before beginning. The "insert" command | |
| 27933 ** always overwrites every file named on the command-line, where as | |
| 27934 ** "update" only overwrites if the size or mtime or mode has changed. | |
| 27935 */ | |
| 27936 static int arCreateOrUpdateCommand( | |
| 27937 ArCommand *pAr, /* Command arguments and options */ | |
| 27938 int bUpdate, /* true for a --create. */ | |
| 27939 int bOnlyIfChanged /* Only update if file has changed */ | |
| 27940 ){ | |
| 27941 const char *zCreate = | |
| 27942 "CREATE TABLE IF NOT EXISTS sqlar(\n" | |
| 27943 " name TEXT PRIMARY KEY, -- name of the file\n" | |
| 27944 " mode INT, -- access permissions\n" | |
| 27945 " mtime INT, -- last modification time\n" | |
| 27946 " sz INT, -- original file size\n" | |
| 27947 " data BLOB -- compressed content\n" | |
| 27948 ")"; | |
| 27949 const char *zDrop = "DROP TABLE IF EXISTS sqlar"; | |
| 27950 const char *zInsertFmt[2] = { | |
| 27951 "REPLACE INTO %s(name,mode,mtime,sz,data)\n" | |
| 27952 " SELECT\n" | |
| 27953 " %s,\n" | |
| 27954 " mode,\n" | |
| 27955 " mtime,\n" | |
| 27956 " CASE substr(lsmode(mode),1,1)\n" | |
| 27957 " WHEN '-' THEN length(data)\n" | |
| 27958 " WHEN 'd' THEN 0\n" | |
| 27959 " ELSE -1 END,\n" | |
| 27960 " sqlar_compress(data)\n" | |
| 27961 " FROM fsdir(%Q,%Q) AS disk\n" | |
| 27962 " WHERE lsmode(mode) NOT LIKE '?%%'%s;" | |
| 27963 , | |
| 27964 "REPLACE INTO %s(name,mode,mtime,data)\n" | |
| 27965 " SELECT\n" | |
| 27966 " %s,\n" | |
| 27967 " mode,\n" | |
| 27968 " mtime,\n" | |
| 27969 " data\n" | |
| 27970 " FROM fsdir(%Q,%Q) AS disk\n" | |
| 27971 " WHERE lsmode(mode) NOT LIKE '?%%'%s;" | |
| 27972 }; | |
| 27973 int i; /* For iterating through azFile[] */ | |
| 27974 int rc; /* Return code */ | |
| 27975 const char *zTab = 0; /* SQL table into which to insert */ | |
| 27976 char *zSql; | |
| 27977 char zTemp[50]; | |
| 27978 char *zExists = 0; | |
| 27979 | |
| 27980 arExecSql(pAr, "PRAGMA page_size=512"); | |
| 27981 rc = arExecSql(pAr, "SAVEPOINT ar;"); | |
| 27982 if( rc!=SQLITE_OK ) return rc; | |
| 27983 zTemp[0] = 0; | |
| 27984 if( pAr->bZip ){ | |
| 27985 /* Initialize the zipfile virtual table, if necessary */ | |
| 27986 if( pAr->zFile ){ | |
| 27987 sqlite3_uint64 r; | |
| 27988 sqlite3_randomness(sizeof(r),&r); | |
| 27989 sqlite3_snprintf(sizeof(zTemp),zTemp,"zip%016llx",r); | |
| 27990 zTab = zTemp; | |
| 27991 zSql = sqlite3_mprintf( | |
| 27992 "CREATE VIRTUAL TABLE temp.%s USING zipfile(%Q)", | |
| 27993 zTab, pAr->zFile | |
| 27994 ); | |
| 27995 rc = arExecSql(pAr, zSql); | |
| 27996 sqlite3_free(zSql); | |
| 27997 }else{ | |
| 27998 zTab = "zip"; | |
| 27999 } | |
| 28000 }else{ | |
| 28001 /* Initialize the table for an SQLAR */ | |
| 28002 zTab = "sqlar"; | |
| 28003 if( bUpdate==0 ){ | |
| 28004 rc = arExecSql(pAr, zDrop); | |
| 28005 if( rc!=SQLITE_OK ) goto end_ar_transaction; | |
| 28006 } | |
| 28007 rc = arExecSql(pAr, zCreate); | |
| 28008 } | |
| 28009 if( bOnlyIfChanged ){ | |
| 28010 zExists = sqlite3_mprintf( | |
| 28011 " AND NOT EXISTS(" | |
| 28012 "SELECT 1 FROM %s AS mem" | |
| 28013 " WHERE mem.name=disk.name" | |
| 28014 " AND mem.mtime=disk.mtime" | |
| 28015 " AND mem.mode=disk.mode)", zTab); | |
| 28016 }else{ | |
| 28017 zExists = sqlite3_mprintf(""); | |
| 28018 } | |
| 28019 if( zExists==0 ) rc = SQLITE_NOMEM; | |
| 28020 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){ | |
| 28021 char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab, | |
| 28022 pAr->bVerbose ? "shell_putsnl(name)" : "name", | |
| 28023 pAr->azArg[i], pAr->zDir, zExists); | |
| 28024 rc = arExecSql(pAr, zSql2); | |
| 28025 sqlite3_free(zSql2); | |
| 28026 } | |
| 28027 end_ar_transaction: | |
| 28028 if( rc!=SQLITE_OK ){ | |
| 28029 sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0); | |
| 28030 }else{ | |
| 28031 rc = arExecSql(pAr, "RELEASE ar;"); | |
| 28032 if( pAr->bZip && pAr->zFile ){ | |
| 28033 zSql = sqlite3_mprintf("DROP TABLE %s", zTemp); | |
| 28034 arExecSql(pAr, zSql); | |
| 28035 sqlite3_free(zSql); | |
| 28036 } | |
| 28037 } | |
| 28038 sqlite3_free(zExists); | |
| 28039 return rc; | |
| 28040 } | |
| 28041 | |
| 28042 /* | |
| 28043 ** Implementation of ".ar" dot command. | |
| 28044 */ | |
| 28045 static int arDotCommand( | |
| 28046 ShellState *pState, /* Current shell tool state */ | |
| 28047 int fromCmdLine, /* True if -A command-line option, not .ar cmd */ | |
| 28048 char **azArg, /* Array of arguments passed to dot command */ | |
| 28049 int nArg /* Number of entries in azArg[] */ | |
| 28050 ){ | |
| 28051 ArCommand cmd; | |
| 28052 int rc; | |
| 28053 memset(&cmd, 0, sizeof(cmd)); | |
| 28054 cmd.fromCmdLine = fromCmdLine; | |
| 28055 rc = arParseCommand(azArg, nArg, &cmd); | |
| 28056 if( rc==SQLITE_OK ){ | |
| 28057 int eDbType = SHELL_OPEN_UNSPEC; | |
| 28058 cmd.p = pState; | |
| 28059 cmd.out = pState->out; | |
| 28060 cmd.db = pState->db; | |
| 28061 if( cmd.zFile ){ | |
| 28062 eDbType = deduceDatabaseType(cmd.zFile, 1, 0); | |
| 28063 }else{ | |
| 28064 eDbType = pState->openMode; | |
| 28065 } | |
| 28066 if( eDbType==SHELL_OPEN_ZIPFILE ){ | |
| 28067 if( cmd.eCmd==AR_CMD_EXTRACT || cmd.eCmd==AR_CMD_LIST ){ | |
| 28068 if( cmd.zFile==0 ){ | |
| 28069 cmd.zSrcTable = sqlite3_mprintf("zip"); | |
| 28070 }else{ | |
| 28071 cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile); | |
| 28072 } | |
| 28073 } | |
| 28074 cmd.bZip = 1; | |
| 28075 }else if( cmd.zFile ){ | |
| 28076 int flags; | |
| 28077 if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS; | |
| 28078 if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT | |
| 28079 || cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){ | |
| 28080 flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; | |
| 28081 }else{ | |
| 28082 flags = SQLITE_OPEN_READONLY; | |
| 28083 } | |
| 28084 cmd.db = 0; | |
| 28085 if( cmd.bDryRun ){ | |
| 28086 sqlite3_fprintf(cmd.out, "-- open database '%s'%s\n", cmd.zFile, | |
| 28087 eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : ""); | |
| 28088 } | |
| 28089 rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, | |
| 28090 eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0); | |
| 28091 if( rc!=SQLITE_OK ){ | |
| 28092 sqlite3_fprintf(stderr, "cannot open file: %s (%s)\n", | |
| 28093 cmd.zFile, sqlite3_errmsg(cmd.db)); | |
| 28094 goto end_ar_command; | |
| 28095 } | |
| 28096 sqlite3_fileio_init(cmd.db, 0, 0); | |
| 28097 sqlite3_sqlar_init(cmd.db, 0, 0); | |
| 28098 sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p, | |
| 28099 shellPutsFunc, 0, 0); | |
| 28100 | |
| 28101 } | |
| 28102 if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){ | |
| 28103 if( cmd.eCmd!=AR_CMD_CREATE | |
| 28104 && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0) | |
| 28105 ){ | |
| 28106 sqlite3_fprintf(stderr, "database does not contain an 'sqlar' table\n"); | |
| 28107 rc = SQLITE_ERROR; | |
| 28108 goto end_ar_command; | |
| 28109 } | |
| 28110 cmd.zSrcTable = sqlite3_mprintf("sqlar"); | |
| 28111 } | |
| 28112 | |
| 28113 switch( cmd.eCmd ){ | |
| 28114 case AR_CMD_CREATE: | |
| 28115 rc = arCreateOrUpdateCommand(&cmd, 0, 0); | |
| 28116 break; | |
| 28117 | |
| 28118 case AR_CMD_EXTRACT: | |
| 28119 rc = arExtractCommand(&cmd); | |
| 28120 break; | |
| 28121 | |
| 28122 case AR_CMD_LIST: | |
| 28123 rc = arListCommand(&cmd); | |
| 28124 break; | |
| 28125 | |
| 28126 case AR_CMD_HELP: | |
| 28127 arUsage(pState->out); | |
| 28128 break; | |
| 28129 | |
| 28130 case AR_CMD_INSERT: | |
| 28131 rc = arCreateOrUpdateCommand(&cmd, 1, 0); | |
| 28132 break; | |
| 28133 | |
| 28134 case AR_CMD_REMOVE: | |
| 28135 rc = arRemoveCommand(&cmd); | |
| 28136 break; | |
| 28137 | |
| 28138 default: | |
| 28139 assert( cmd.eCmd==AR_CMD_UPDATE ); | |
| 28140 rc = arCreateOrUpdateCommand(&cmd, 1, 1); | |
| 28141 break; | |
| 28142 } | |
| 28143 } | |
| 28144 end_ar_command: | |
| 28145 if( cmd.db!=pState->db ){ | |
| 28146 close_db(cmd.db); | |
| 28147 } | |
| 28148 sqlite3_free(cmd.zSrcTable); | |
| 28149 | |
| 28150 return rc; | |
| 28151 } | |
| 28152 /* End of the ".archive" or ".ar" command logic | |
| 28153 *******************************************************************************/ | |
| 28154 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ | |
| 28155 | |
| 28156 #if SQLITE_SHELL_HAVE_RECOVER | |
| 28157 | |
| 28158 /* | |
| 28159 ** This function is used as a callback by the recover extension. Simply | |
| 28160 ** print the supplied SQL statement to stdout. | |
| 28161 */ | |
| 28162 static int recoverSqlCb(void *pCtx, const char *zSql){ | |
| 28163 ShellState *pState = (ShellState*)pCtx; | |
| 28164 sqlite3_fprintf(pState->out, "%s;\n", zSql); | |
| 28165 return SQLITE_OK; | |
| 28166 } | |
| 28167 | |
| 28168 /* | |
| 28169 ** This function is called to recover data from the database. A script | |
| 28170 ** to construct a new database containing all recovered data is output | |
| 28171 ** on stream pState->out. | |
| 28172 */ | |
| 28173 static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ | |
| 28174 int rc = SQLITE_OK; | |
| 28175 const char *zRecoveryDb = ""; /* Name of "recovery" database. Debug only */ | |
| 28176 const char *zLAF = "lost_and_found"; | |
| 28177 int bFreelist = 1; /* 0 if --ignore-freelist is specified */ | |
| 28178 int bRowids = 1; /* 0 if --no-rowids */ | |
| 28179 sqlite3_recover *p = 0; | |
| 28180 int i = 0; | |
| 28181 | |
| 28182 for(i=1; i<nArg; i++){ | |
| 28183 char *z = azArg[i]; | |
| 28184 int n; | |
| 28185 if( z[0]=='-' && z[1]=='-' ) z++; | |
| 28186 n = strlen30(z); | |
| 28187 if( n<=17 && memcmp("-ignore-freelist", z, n)==0 ){ | |
| 28188 bFreelist = 0; | |
| 28189 }else | |
| 28190 if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){ | |
| 28191 /* This option determines the name of the ATTACH-ed database used | |
| 28192 ** internally by the recovery extension. The default is "" which | |
| 28193 ** means to use a temporary database that is automatically deleted | |
| 28194 ** when closed. This option is undocumented and might disappear at | |
| 28195 ** any moment. */ | |
| 28196 i++; | |
| 28197 zRecoveryDb = azArg[i]; | |
| 28198 }else | |
| 28199 if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){ | |
| 28200 i++; | |
| 28201 zLAF = azArg[i]; | |
| 28202 }else | |
| 28203 if( n<=10 && memcmp("-no-rowids", z, n)==0 ){ | |
| 28204 bRowids = 0; | |
| 28205 } | |
| 28206 else{ | |
| 28207 sqlite3_fprintf(stderr,"unexpected option: %s\n", azArg[i]); | |
| 28208 showHelp(pState->out, azArg[0]); | |
| 28209 return 1; | |
| 28210 } | |
| 28211 } | |
| 28212 | |
| 28213 p = sqlite3_recover_init_sql( | |
| 28214 pState->db, "main", recoverSqlCb, (void*)pState | |
| 28215 ); | |
| 28216 | |
| 28217 sqlite3_recover_config(p, 789, (void*)zRecoveryDb); /* Debug use only */ | |
| 28218 sqlite3_recover_config(p, SQLITE_RECOVER_LOST_AND_FOUND, (void*)zLAF); | |
| 28219 sqlite3_recover_config(p, SQLITE_RECOVER_ROWIDS, (void*)&bRowids); | |
| 28220 sqlite3_recover_config(p, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist); | |
| 28221 | |
| 28222 sqlite3_fprintf(pState->out, ".dbconfig defensive off\n"); | |
| 28223 sqlite3_recover_run(p); | |
| 28224 if( sqlite3_recover_errcode(p)!=SQLITE_OK ){ | |
| 28225 const char *zErr = sqlite3_recover_errmsg(p); | |
| 28226 int errCode = sqlite3_recover_errcode(p); | |
| 28227 sqlite3_fprintf(stderr,"sql error: %s (%d)\n", zErr, errCode); | |
| 28228 } | |
| 28229 rc = sqlite3_recover_finish(p); | |
| 28230 return rc; | |
| 28231 } | |
| 28232 #endif /* SQLITE_SHELL_HAVE_RECOVER */ | |
| 28233 | |
| 28234 /* | |
| 28235 ** Implementation of ".intck STEPS_PER_UNLOCK" command. | |
| 28236 */ | |
| 28237 static int intckDatabaseCmd(ShellState *pState, i64 nStepPerUnlock){ | |
| 28238 sqlite3_intck *p = 0; | |
| 28239 int rc = SQLITE_OK; | |
| 28240 | |
| 28241 rc = sqlite3_intck_open(pState->db, "main", &p); | |
| 28242 if( rc==SQLITE_OK ){ | |
| 28243 i64 nStep = 0; | |
| 28244 i64 nError = 0; | |
| 28245 const char *zErr = 0; | |
| 28246 while( SQLITE_OK==sqlite3_intck_step(p) ){ | |
| 28247 const char *zMsg = sqlite3_intck_message(p); | |
| 28248 if( zMsg ){ | |
| 28249 sqlite3_fprintf(pState->out, "%s\n", zMsg); | |
| 28250 nError++; | |
| 28251 } | |
| 28252 nStep++; | |
| 28253 if( nStepPerUnlock && (nStep % nStepPerUnlock)==0 ){ | |
| 28254 sqlite3_intck_unlock(p); | |
| 28255 } | |
| 28256 } | |
| 28257 rc = sqlite3_intck_error(p, &zErr); | |
| 28258 if( zErr ){ | |
| 28259 sqlite3_fprintf(stderr,"%s\n", zErr); | |
| 28260 } | |
| 28261 sqlite3_intck_close(p); | |
| 28262 | |
| 28263 sqlite3_fprintf(pState->out, "%lld steps, %lld errors\n", nStep, nError); | |
| 28264 } | |
| 28265 | |
| 28266 return rc; | |
| 28267 } | |
| 28268 | |
| 28269 /* | |
| 28270 * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it. | |
| 28271 * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE, | |
| 28272 * close db and set it to 0, and return the columns spec, to later | |
| 28273 * be sqlite3_free()'ed by the caller. | |
| 28274 * The return is 0 when either: | |
| 28275 * (a) The db was not initialized and zCol==0 (There are no columns.) | |
| 28276 * (b) zCol!=0 (Column was added, db initialized as needed.) | |
| 28277 * The 3rd argument, pRenamed, references an out parameter. If the | |
| 28278 * pointer is non-zero, its referent will be set to a summary of renames | |
| 28279 * done if renaming was necessary, or set to 0 if none was done. The out | |
| 28280 * string (if any) must be sqlite3_free()'ed by the caller. | |
| 28281 */ | |
| 28282 #ifdef SHELL_DEBUG | |
| 28283 #define rc_err_oom_die(rc) \ | |
| 28284 if( rc==SQLITE_NOMEM ) shell_check_oom(0); \ | |
| 28285 else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \ | |
| 28286 sqlite3_fprintf(stderr,"E:%d\n",rc), assert(0) | |
| 28287 #else | |
| 28288 static void rc_err_oom_die(int rc){ | |
| 28289 if( rc==SQLITE_NOMEM ) shell_check_oom(0); | |
| 28290 assert(rc==SQLITE_OK||rc==SQLITE_DONE); | |
| 28291 } | |
| 28292 #endif | |
| 28293 | |
| 28294 #ifdef SHELL_COLFIX_DB /* If this is set, the DB can be in a file. */ | |
| 28295 static char zCOL_DB[] = SHELL_STRINGIFY(SHELL_COLFIX_DB); | |
| 28296 #else /* Otherwise, memory is faster/better for the transient DB. */ | |
| 28297 static const char *zCOL_DB = ":memory:"; | |
| 28298 #endif | |
| 28299 | |
| 28300 /* Define character (as C string) to separate generated column ordinal | |
| 28301 * from protected part of incoming column names. This defaults to "_" | |
| 28302 * so that incoming column identifiers that did not need not be quoted | |
| 28303 * remain usable without being quoted. It must be one character. | |
| 28304 */ | |
| 28305 #ifndef SHELL_AUTOCOLUMN_SEP | |
| 28306 # define AUTOCOLUMN_SEP "_" | |
| 28307 #else | |
| 28308 # define AUTOCOLUMN_SEP SHELL_STRINGIFY(SHELL_AUTOCOLUMN_SEP) | |
| 28309 #endif | |
| 28310 | |
| 28311 static char *zAutoColumn(const char *zColNew, sqlite3 **pDb, char **pzRenamed){ | |
| 28312 /* Queries and D{D,M}L used here */ | |
| 28313 static const char * const zTabMake = "\ | |
| 28314 CREATE TABLE ColNames(\ | |
| 28315 cpos INTEGER PRIMARY KEY,\ | |
| 28316 name TEXT, nlen INT, chop INT, reps INT, suff TEXT);\ | |
| 28317 CREATE VIEW RepeatedNames AS \ | |
| 28318 SELECT DISTINCT t.name FROM ColNames t \ | |
| 28319 WHERE t.name COLLATE NOCASE IN (\ | |
| 28320 SELECT o.name FROM ColNames o WHERE o.cpos<>t.cpos\ | |
| 28321 );\ | |
| 28322 "; | |
| 28323 static const char * const zTabFill = "\ | |
| 28324 INSERT INTO ColNames(name,nlen,chop,reps,suff)\ | |
| 28325 VALUES(iif(length(?1)>0,?1,'?'),max(length(?1),1),0,0,'')\ | |
| 28326 "; | |
| 28327 static const char * const zHasDupes = "\ | |
| 28328 SELECT count(DISTINCT (substring(name,1,nlen-chop)||suff) COLLATE NOCASE)\ | |
| 28329 <count(name) FROM ColNames\ | |
| 28330 "; | |
| 28331 #ifdef SHELL_COLUMN_RENAME_CLEAN | |
| 28332 static const char * const zDedoctor = "\ | |
| 28333 UPDATE ColNames SET chop=iif(\ | |
| 28334 (substring(name,nlen,1) BETWEEN '0' AND '9')\ | |
| 28335 AND (rtrim(name,'0123456790') glob '*"AUTOCOLUMN_SEP"'),\ | |
| 28336 nlen-length(rtrim(name, '"AUTOCOLUMN_SEP"0123456789')),\ | |
| 28337 0\ | |
| 28338 )\ | |
| 28339 "; | |
| 28340 #endif | |
| 28341 static const char * const zSetReps = "\ | |
| 28342 UPDATE ColNames AS t SET reps=\ | |
| 28343 (SELECT count(*) FROM ColNames d \ | |
| 28344 WHERE substring(t.name,1,t.nlen-t.chop)=substring(d.name,1,d.nlen-d.chop)\ | |
| 28345 COLLATE NOCASE\ | |
| 28346 )\ | |
| 28347 "; | |
| 28348 #ifdef SQLITE_ENABLE_MATH_FUNCTIONS | |
| 28349 static const char * const zColDigits = "\ | |
| 28350 SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \ | |
| 28351 "; | |
| 28352 #else | |
| 28353 /* Counting on SQLITE_MAX_COLUMN < 100,000 here. (32767 is the hard limit.) */ | |
| 28354 static const char * const zColDigits = "\ | |
| 28355 SELECT CASE WHEN (nc < 10) THEN 1 WHEN (nc < 100) THEN 2 \ | |
| 28356 WHEN (nc < 1000) THEN 3 WHEN (nc < 10000) THEN 4 \ | |
| 28357 ELSE 5 FROM (SELECT count(*) AS nc FROM ColNames) \ | |
| 28358 "; | |
| 28359 #endif | |
| 28360 static const char * const zRenameRank = | |
| 28361 #ifdef SHELL_COLUMN_RENAME_CLEAN | |
| 28362 "UPDATE ColNames AS t SET suff=" | |
| 28363 "iif(reps>1, printf('%c%0*d', '"AUTOCOLUMN_SEP"', $1, cpos), '')" | |
| 28364 #else /* ...RENAME_MINIMAL_ONE_PASS */ | |
| 28365 "WITH Lzn(nlz) AS (" /* Find minimum extraneous leading 0's for uniqueness */ | |
| 28366 " SELECT 0 AS nlz" | |
| 28367 " UNION" | |
| 28368 " SELECT nlz+1 AS nlz FROM Lzn" | |
| 28369 " WHERE EXISTS(" | |
| 28370 " SELECT 1" | |
| 28371 " FROM ColNames t, ColNames o" | |
| 28372 " WHERE" | |
| 28373 " iif(t.name IN (SELECT * FROM RepeatedNames)," | |
| 28374 " printf('%s"AUTOCOLUMN_SEP"%s'," | |
| 28375 " t.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,t.cpos),2))," | |
| 28376 " t.name" | |
| 28377 " )" | |
| 28378 " =" | |
| 28379 " iif(o.name IN (SELECT * FROM RepeatedNames)," | |
| 28380 " printf('%s"AUTOCOLUMN_SEP"%s'," | |
| 28381 " o.name, substring(printf('%.*c%0.*d',nlz+1,'0',$1,o.cpos),2))," | |
| 28382 " o.name" | |
| 28383 " )" | |
| 28384 " COLLATE NOCASE" | |
| 28385 " AND o.cpos<>t.cpos" | |
| 28386 " GROUP BY t.cpos" | |
| 28387 " )" | |
| 28388 ") UPDATE Colnames AS t SET" | |
| 28389 " chop = 0," /* No chopping, never touch incoming names. */ | |
| 28390 " suff = iif(name IN (SELECT * FROM RepeatedNames)," | |
| 28391 " printf('"AUTOCOLUMN_SEP"%s', substring(" | |
| 28392 " printf('%.*c%0.*d',(SELECT max(nlz) FROM Lzn)+1,'0',1,t.cpos),2))," | |
| 28393 " ''" | |
| 28394 " )" | |
| 28395 #endif | |
| 28396 ; | |
| 28397 static const char * const zCollectVar = "\ | |
| 28398 SELECT\ | |
| 28399 '('||x'0a'\ | |
| 28400 || group_concat(\ | |
| 28401 cname||' TEXT',\ | |
| 28402 ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\ | |
| 28403 ||')' AS ColsSpec \ | |
| 28404 FROM (\ | |
| 28405 SELECT cpos, printf('\"%w\"',printf('%!.*s%s', nlen-chop,name,suff)) AS cname \ | |
| 28406 FROM ColNames ORDER BY cpos\ | |
| 28407 )"; | |
| 28408 static const char * const zRenamesDone = | |
| 28409 "SELECT group_concat(" | |
| 28410 " printf('\"%w\" to \"%w\"',name,printf('%!.*s%s', nlen-chop, name, suff))," | |
| 28411 " ','||x'0a')" | |
| 28412 "FROM ColNames WHERE suff<>'' OR chop!=0" | |
| 28413 ; | |
| 28414 int rc; | |
| 28415 sqlite3_stmt *pStmt = 0; | |
| 28416 assert(pDb!=0); | |
| 28417 if( zColNew ){ | |
| 28418 /* Add initial or additional column. Init db if necessary. */ | |
| 28419 if( *pDb==0 ){ | |
| 28420 if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0; | |
| 28421 #ifdef SHELL_COLFIX_DB | |
| 28422 if(*zCOL_DB!=':') | |
| 28423 sqlite3_exec(*pDb,"drop table if exists ColNames;" | |
| 28424 "drop view if exists RepeatedNames;",0,0,0); | |
| 28425 #endif | |
| 28426 #undef SHELL_COLFIX_DB | |
| 28427 rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0); | |
| 28428 rc_err_oom_die(rc); | |
| 28429 } | |
| 28430 assert(*pDb!=0); | |
| 28431 rc = sqlite3_prepare_v2(*pDb, zTabFill, -1, &pStmt, 0); | |
| 28432 rc_err_oom_die(rc); | |
| 28433 rc = sqlite3_bind_text(pStmt, 1, zColNew, -1, 0); | |
| 28434 rc_err_oom_die(rc); | |
| 28435 rc = sqlite3_step(pStmt); | |
| 28436 rc_err_oom_die(rc); | |
| 28437 sqlite3_finalize(pStmt); | |
| 28438 return 0; | |
| 28439 }else if( *pDb==0 ){ | |
| 28440 return 0; | |
| 28441 }else{ | |
| 28442 /* Formulate the columns spec, close the DB, zero *pDb. */ | |
| 28443 char *zColsSpec = 0; | |
| 28444 int hasDupes = db_int(*pDb, "%s", zHasDupes); | |
| 28445 int nDigits = (hasDupes)? db_int(*pDb, "%s", zColDigits) : 0; | |
| 28446 if( hasDupes ){ | |
| 28447 #ifdef SHELL_COLUMN_RENAME_CLEAN | |
| 28448 rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0); | |
| 28449 rc_err_oom_die(rc); | |
| 28450 #endif | |
| 28451 rc = sqlite3_exec(*pDb, zSetReps, 0, 0, 0); | |
| 28452 rc_err_oom_die(rc); | |
| 28453 rc = sqlite3_prepare_v2(*pDb, zRenameRank, -1, &pStmt, 0); | |
| 28454 rc_err_oom_die(rc); | |
| 28455 sqlite3_bind_int(pStmt, 1, nDigits); | |
| 28456 rc = sqlite3_step(pStmt); | |
| 28457 sqlite3_finalize(pStmt); | |
| 28458 if( rc!=SQLITE_DONE ) rc_err_oom_die(SQLITE_NOMEM); | |
| 28459 } | |
| 28460 assert(db_int(*pDb, "%s", zHasDupes)==0); /* Consider: remove this */ | |
| 28461 rc = sqlite3_prepare_v2(*pDb, zCollectVar, -1, &pStmt, 0); | |
| 28462 rc_err_oom_die(rc); | |
| 28463 rc = sqlite3_step(pStmt); | |
| 28464 if( rc==SQLITE_ROW ){ | |
| 28465 zColsSpec = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); | |
| 28466 }else{ | |
| 28467 zColsSpec = 0; | |
| 28468 } | |
| 28469 if( pzRenamed!=0 ){ | |
| 28470 if( !hasDupes ) *pzRenamed = 0; | |
| 28471 else{ | |
| 28472 sqlite3_finalize(pStmt); | |
| 28473 if( SQLITE_OK==sqlite3_prepare_v2(*pDb, zRenamesDone, -1, &pStmt, 0) | |
| 28474 && SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 28475 *pzRenamed = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); | |
| 28476 }else | |
| 28477 *pzRenamed = 0; | |
| 28478 } | |
| 28479 } | |
| 28480 sqlite3_finalize(pStmt); | |
| 28481 sqlite3_close(*pDb); | |
| 28482 *pDb = 0; | |
| 28483 return zColsSpec; | |
| 28484 } | |
| 28485 } | |
| 28486 | |
| 28487 /* | |
| 28488 ** Check if the sqlite_schema table contains one or more virtual tables. If | |
| 28489 ** parameter zLike is not NULL, then it is an SQL expression that the | |
| 28490 ** sqlite_schema row must also match. If one or more such rows are found, | |
| 28491 ** print the following warning to the output: | |
| 28492 ** | |
| 28493 ** WARNING: Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled | |
| 28494 */ | |
| 28495 static int outputDumpWarning(ShellState *p, const char *zLike){ | |
| 28496 int rc = SQLITE_OK; | |
| 28497 sqlite3_stmt *pStmt = 0; | |
| 28498 shellPreparePrintf(p->db, &rc, &pStmt, | |
| 28499 "SELECT 1 FROM sqlite_schema o WHERE " | |
| 28500 "sql LIKE 'CREATE VIRTUAL TABLE%%' AND %s", zLike ? zLike : "true" | |
| 28501 ); | |
| 28502 if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 28503 sqlite3_fputs("/* WARNING: " | |
| 28504 "Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled */\n", | |
| 28505 p->out | |
| 28506 ); | |
| 28507 } | |
| 28508 shellFinalize(&rc, pStmt); | |
| 28509 return rc; | |
| 28510 } | |
| 28511 | |
| 28512 /* | |
| 28513 ** Fault-Simulator state and logic. | |
| 28514 */ | |
| 28515 static struct { | |
| 28516 int iId; /* ID that triggers a simulated fault. -1 means "any" */ | |
| 28517 int iErr; /* The error code to return on a fault */ | |
| 28518 int iCnt; /* Trigger the fault only if iCnt is already zero */ | |
| 28519 int iInterval; /* Reset iCnt to this value after each fault */ | |
| 28520 int eVerbose; /* When to print output */ | |
| 28521 int nHit; /* Number of hits seen so far */ | |
| 28522 int nRepeat; /* Turn off after this many hits. 0 for never */ | |
| 28523 int nSkip; /* Skip this many before first fault */ | |
| 28524 } faultsim_state = {-1, 0, 0, 0, 0, 0, 0, 0}; | |
| 28525 | |
| 28526 /* | |
| 28527 ** This is the fault-sim callback | |
| 28528 */ | |
| 28529 static int faultsim_callback(int iArg){ | |
| 28530 if( faultsim_state.iId>0 && faultsim_state.iId!=iArg ){ | |
| 28531 return SQLITE_OK; | |
| 28532 } | |
| 28533 if( faultsim_state.iCnt ){ | |
| 28534 if( faultsim_state.iCnt>0 ) faultsim_state.iCnt--; | |
| 28535 if( faultsim_state.eVerbose>=2 ){ | |
| 28536 sqlite3_fprintf(stdout, | |
| 28537 "FAULT-SIM id=%d no-fault (cnt=%d)\n", iArg, faultsim_state.iCnt); | |
| 28538 } | |
| 28539 return SQLITE_OK; | |
| 28540 } | |
| 28541 if( faultsim_state.eVerbose>=1 ){ | |
| 28542 sqlite3_fprintf(stdout, | |
| 28543 "FAULT-SIM id=%d returns %d\n", iArg, faultsim_state.iErr); | |
| 28544 } | |
| 28545 faultsim_state.iCnt = faultsim_state.iInterval; | |
| 28546 faultsim_state.nHit++; | |
| 28547 if( faultsim_state.nRepeat>0 && faultsim_state.nRepeat<=faultsim_state.nHit ){ | |
| 28548 faultsim_state.iCnt = -1; | |
| 28549 } | |
| 28550 return faultsim_state.iErr; | |
| 28551 } | |
| 28552 | |
| 28553 /* | |
| 28554 ** If an input line begins with "." then invoke this routine to | |
| 28555 ** process that line. | |
| 28556 ** | |
| 28557 ** Return 1 on error, 2 to exit, and 0 otherwise. | |
| 28558 */ | |
| 28559 static int do_meta_command(char *zLine, ShellState *p){ | |
| 28560 int h = 1; | |
| 28561 int nArg = 0; | |
| 28562 int n, c; | |
| 28563 int rc = 0; | |
| 28564 char *azArg[52]; | |
| 28565 | |
| 28566 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 28567 if( p->expert.pExpert ){ | |
| 28568 expertFinish(p, 1, 0); | |
| 28569 } | |
| 28570 #endif | |
| 28571 | |
| 28572 /* Parse the input line into tokens. | |
| 28573 */ | |
| 28574 while( zLine[h] && nArg<ArraySize(azArg)-1 ){ | |
| 28575 while( IsSpace(zLine[h]) ){ h++; } | |
| 28576 if( zLine[h]==0 ) break; | |
| 28577 if( zLine[h]=='\'' || zLine[h]=='"' ){ | |
| 28578 int delim = zLine[h++]; | |
| 28579 azArg[nArg++] = &zLine[h]; | |
| 28580 while( zLine[h] && zLine[h]!=delim ){ | |
| 28581 if( zLine[h]=='\\' && delim=='"' && zLine[h+1]!=0 ) h++; | |
| 28582 h++; | |
| 28583 } | |
| 28584 if( zLine[h]==delim ){ | |
| 28585 zLine[h++] = 0; | |
| 28586 } | |
| 28587 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]); | |
| 28588 }else{ | |
| 28589 azArg[nArg++] = &zLine[h]; | |
| 28590 while( zLine[h] && !IsSpace(zLine[h]) ){ h++; } | |
| 28591 if( zLine[h] ) zLine[h++] = 0; | |
| 28592 } | |
| 28593 } | |
| 28594 azArg[nArg] = 0; | |
| 28595 | |
| 28596 /* Process the input line. | |
| 28597 */ | |
| 28598 if( nArg==0 ) return 0; /* no tokens, no error */ | |
| 28599 n = strlen30(azArg[0]); | |
| 28600 c = azArg[0][0]; | |
| 28601 clearTempFile(p); | |
| 28602 | |
| 28603 #ifndef SQLITE_OMIT_AUTHORIZATION | |
| 28604 if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){ | |
| 28605 if( nArg!=2 ){ | |
| 28606 sqlite3_fprintf(stderr, "Usage: .auth ON|OFF\n"); | |
| 28607 rc = 1; | |
| 28608 goto meta_command_exit; | |
| 28609 } | |
| 28610 open_db(p, 0); | |
| 28611 if( booleanValue(azArg[1]) ){ | |
| 28612 sqlite3_set_authorizer(p->db, shellAuth, p); | |
| 28613 }else if( p->bSafeModePersist ){ | |
| 28614 sqlite3_set_authorizer(p->db, safeModeAuth, p); | |
| 28615 }else{ | |
| 28616 sqlite3_set_authorizer(p->db, 0, 0); | |
| 28617 } | |
| 28618 }else | |
| 28619 #endif | |
| 28620 | |
| 28621 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) \ | |
| 28622 && !defined(SQLITE_SHELL_FIDDLE) | |
| 28623 if( c=='a' && cli_strncmp(azArg[0], "archive", n)==0 ){ | |
| 28624 open_db(p, 0); | |
| 28625 failIfSafeMode(p, "cannot run .archive in safe mode"); | |
| 28626 rc = arDotCommand(p, 0, azArg, nArg); | |
| 28627 }else | |
| 28628 #endif | |
| 28629 | |
| 28630 #ifndef SQLITE_SHELL_FIDDLE | |
| 28631 if( (c=='b' && n>=3 && cli_strncmp(azArg[0], "backup", n)==0) | |
| 28632 || (c=='s' && n>=3 && cli_strncmp(azArg[0], "save", n)==0) | |
| 28633 ){ | |
| 28634 const char *zDestFile = 0; | |
| 28635 const char *zDb = 0; | |
| 28636 sqlite3 *pDest; | |
| 28637 sqlite3_backup *pBackup; | |
| 28638 int j; | |
| 28639 int bAsync = 0; | |
| 28640 const char *zVfs = 0; | |
| 28641 failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]); | |
| 28642 for(j=1; j<nArg; j++){ | |
| 28643 const char *z = azArg[j]; | |
| 28644 if( z[0]=='-' ){ | |
| 28645 if( z[1]=='-' ) z++; | |
| 28646 if( cli_strcmp(z, "-append")==0 ){ | |
| 28647 zVfs = "apndvfs"; | |
| 28648 }else | |
| 28649 if( cli_strcmp(z, "-async")==0 ){ | |
| 28650 bAsync = 1; | |
| 28651 }else | |
| 28652 { | |
| 28653 sqlite3_fprintf(stderr,"unknown option: %s\n", azArg[j]); | |
| 28654 return 1; | |
| 28655 } | |
| 28656 }else if( zDestFile==0 ){ | |
| 28657 zDestFile = azArg[j]; | |
| 28658 }else if( zDb==0 ){ | |
| 28659 zDb = zDestFile; | |
| 28660 zDestFile = azArg[j]; | |
| 28661 }else{ | |
| 28662 sqlite3_fprintf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n"); | |
| 28663 return 1; | |
| 28664 } | |
| 28665 } | |
| 28666 if( zDestFile==0 ){ | |
| 28667 sqlite3_fprintf(stderr, "missing FILENAME argument on .backup\n"); | |
| 28668 return 1; | |
| 28669 } | |
| 28670 if( zDb==0 ) zDb = "main"; | |
| 28671 rc = sqlite3_open_v2(zDestFile, &pDest, | |
| 28672 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs); | |
| 28673 if( rc!=SQLITE_OK ){ | |
| 28674 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zDestFile); | |
| 28675 close_db(pDest); | |
| 28676 return 1; | |
| 28677 } | |
| 28678 if( bAsync ){ | |
| 28679 sqlite3_exec(pDest, "PRAGMA synchronous=OFF; PRAGMA journal_mode=OFF;", | |
| 28680 0, 0, 0); | |
| 28681 } | |
| 28682 open_db(p, 0); | |
| 28683 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb); | |
| 28684 if( pBackup==0 ){ | |
| 28685 shellDatabaseError(pDest); | |
| 28686 close_db(pDest); | |
| 28687 return 1; | |
| 28688 } | |
| 28689 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){} | |
| 28690 sqlite3_backup_finish(pBackup); | |
| 28691 if( rc==SQLITE_DONE ){ | |
| 28692 rc = 0; | |
| 28693 }else{ | |
| 28694 shellDatabaseError(pDest); | |
| 28695 rc = 1; | |
| 28696 } | |
| 28697 close_db(pDest); | |
| 28698 }else | |
| 28699 #endif /* !defined(SQLITE_SHELL_FIDDLE) */ | |
| 28700 | |
| 28701 if( c=='b' && n>=3 && cli_strncmp(azArg[0], "bail", n)==0 ){ | |
| 28702 if( nArg==2 ){ | |
| 28703 bail_on_error = booleanValue(azArg[1]); | |
| 28704 }else{ | |
| 28705 eputz("Usage: .bail on|off\n"); | |
| 28706 rc = 1; | |
| 28707 } | |
| 28708 }else | |
| 28709 | |
| 28710 /* Undocumented. Legacy only. See "crlf" below */ | |
| 28711 if( c=='b' && n>=3 && cli_strncmp(azArg[0], "binary", n)==0 ){ | |
| 28712 eputz("The \".binary\" command is deprecated.\n"); | |
| 28713 rc = 1; | |
| 28714 }else | |
| 28715 | |
| 28716 /* The undocumented ".breakpoint" command causes a call to the no-op | |
| 28717 ** routine named test_breakpoint(). | |
| 28718 */ | |
| 28719 if( c=='b' && n>=3 && cli_strncmp(azArg[0], "breakpoint", n)==0 ){ | |
| 28720 test_breakpoint(); | |
| 28721 }else | |
| 28722 | |
| 28723 #ifndef SQLITE_SHELL_FIDDLE | |
| 28724 if( c=='c' && cli_strcmp(azArg[0],"cd")==0 ){ | |
| 28725 failIfSafeMode(p, "cannot run .cd in safe mode"); | |
| 28726 if( nArg==2 ){ | |
| 28727 #if defined(_WIN32) || defined(WIN32) | |
| 28728 wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]); | |
| 28729 rc = !SetCurrentDirectoryW(z); | |
| 28730 sqlite3_free(z); | |
| 28731 #else | |
| 28732 rc = chdir(azArg[1]); | |
| 28733 #endif | |
| 28734 if( rc ){ | |
| 28735 sqlite3_fprintf(stderr,"Cannot change to directory \"%s\"\n", azArg[1]); | |
| 28736 rc = 1; | |
| 28737 } | |
| 28738 }else{ | |
| 28739 eputz("Usage: .cd DIRECTORY\n"); | |
| 28740 rc = 1; | |
| 28741 } | |
| 28742 }else | |
| 28743 #endif /* !defined(SQLITE_SHELL_FIDDLE) */ | |
| 28744 | |
| 28745 if( c=='c' && n>=3 && cli_strncmp(azArg[0], "changes", n)==0 ){ | |
| 28746 if( nArg==2 ){ | |
| 28747 setOrClearFlag(p, SHFLG_CountChanges, azArg[1]); | |
| 28748 }else{ | |
| 28749 eputz("Usage: .changes on|off\n"); | |
| 28750 rc = 1; | |
| 28751 } | |
| 28752 }else | |
| 28753 | |
| 28754 #ifndef SQLITE_SHELL_FIDDLE | |
| 28755 /* Cancel output redirection, if it is currently set (by .testcase) | |
| 28756 ** Then read the content of the testcase-out.txt file and compare against | |
| 28757 ** azArg[1]. If there are differences, report an error and exit. | |
| 28758 */ | |
| 28759 if( c=='c' && n>=3 && cli_strncmp(azArg[0], "check", n)==0 ){ | |
| 28760 char *zRes = 0; | |
| 28761 output_reset(p); | |
| 28762 if( nArg!=2 ){ | |
| 28763 eputz("Usage: .check GLOB-PATTERN\n"); | |
| 28764 rc = 2; | |
| 28765 }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){ | |
| 28766 rc = 2; | |
| 28767 }else if( testcase_glob(azArg[1],zRes)==0 ){ | |
| 28768 sqlite3_fprintf(stderr, | |
| 28769 "testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n", | |
| 28770 p->zTestcase, azArg[1], zRes); | |
| 28771 rc = 1; | |
| 28772 }else{ | |
| 28773 sqlite3_fprintf(p->out, "testcase-%s ok\n", p->zTestcase); | |
| 28774 p->nCheck++; | |
| 28775 } | |
| 28776 sqlite3_free(zRes); | |
| 28777 }else | |
| 28778 #endif /* !defined(SQLITE_SHELL_FIDDLE) */ | |
| 28779 | |
| 28780 #ifndef SQLITE_SHELL_FIDDLE | |
| 28781 if( c=='c' && cli_strncmp(azArg[0], "clone", n)==0 ){ | |
| 28782 failIfSafeMode(p, "cannot run .clone in safe mode"); | |
| 28783 if( nArg==2 ){ | |
| 28784 tryToClone(p, azArg[1]); | |
| 28785 }else{ | |
| 28786 eputz("Usage: .clone FILENAME\n"); | |
| 28787 rc = 1; | |
| 28788 } | |
| 28789 }else | |
| 28790 #endif /* !defined(SQLITE_SHELL_FIDDLE) */ | |
| 28791 | |
| 28792 if( c=='c' && cli_strncmp(azArg[0], "connection", n)==0 ){ | |
| 28793 if( nArg==1 ){ | |
| 28794 /* List available connections */ | |
| 28795 int i; | |
| 28796 for(i=0; i<ArraySize(p->aAuxDb); i++){ | |
| 28797 const char *zFile = p->aAuxDb[i].zDbFilename; | |
| 28798 if( p->aAuxDb[i].db==0 && p->pAuxDb!=&p->aAuxDb[i] ){ | |
| 28799 zFile = "(not open)"; | |
| 28800 }else if( zFile==0 ){ | |
| 28801 zFile = "(memory)"; | |
| 28802 }else if( zFile[0]==0 ){ | |
| 28803 zFile = "(temporary-file)"; | |
| 28804 } | |
| 28805 if( p->pAuxDb == &p->aAuxDb[i] ){ | |
| 28806 sqlite3_fprintf(stdout, "ACTIVE %d: %s\n", i, zFile); | |
| 28807 }else if( p->aAuxDb[i].db!=0 ){ | |
| 28808 sqlite3_fprintf(stdout, " %d: %s\n", i, zFile); | |
| 28809 } | |
| 28810 } | |
| 28811 }else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){ | |
| 28812 int i = azArg[1][0] - '0'; | |
| 28813 if( p->pAuxDb != &p->aAuxDb[i] && i>=0 && i<ArraySize(p->aAuxDb) ){ | |
| 28814 p->pAuxDb->db = p->db; | |
| 28815 p->pAuxDb = &p->aAuxDb[i]; | |
| 28816 globalDb = p->db = p->pAuxDb->db; | |
| 28817 p->pAuxDb->db = 0; | |
| 28818 } | |
| 28819 }else if( nArg==3 && cli_strcmp(azArg[1], "close")==0 | |
| 28820 && IsDigit(azArg[2][0]) && azArg[2][1]==0 ){ | |
| 28821 int i = azArg[2][0] - '0'; | |
| 28822 if( i<0 || i>=ArraySize(p->aAuxDb) ){ | |
| 28823 /* No-op */ | |
| 28824 }else if( p->pAuxDb == &p->aAuxDb[i] ){ | |
| 28825 eputz("cannot close the active database connection\n"); | |
| 28826 rc = 1; | |
| 28827 }else if( p->aAuxDb[i].db ){ | |
| 28828 session_close_all(p, i); | |
| 28829 close_db(p->aAuxDb[i].db); | |
| 28830 p->aAuxDb[i].db = 0; | |
| 28831 } | |
| 28832 }else{ | |
| 28833 eputz("Usage: .connection [close] [CONNECTION-NUMBER]\n"); | |
| 28834 rc = 1; | |
| 28835 } | |
| 28836 }else | |
| 28837 | |
| 28838 if( c=='c' && n==4 | |
| 28839 && (cli_strncmp(azArg[0], "crlf", n)==0 | |
| 28840 || cli_strncmp(azArg[0], "crnl",n)==0) | |
| 28841 ){ | |
| 28842 if( nArg==2 ){ | |
| 28843 #ifdef _WIN32 | |
| 28844 p->crlfMode = booleanValue(azArg[1]); | |
| 28845 #else | |
| 28846 p->crlfMode = 0; | |
| 28847 #endif | |
| 28848 } | |
| 28849 sqlite3_fprintf(stderr, "crlf is %s\n", p->crlfMode ? "ON" : "OFF"); | |
| 28850 }else | |
| 28851 | |
| 28852 if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){ | |
| 28853 char **azName = 0; | |
| 28854 int nName = 0; | |
| 28855 sqlite3_stmt *pStmt; | |
| 28856 int i; | |
| 28857 open_db(p, 0); | |
| 28858 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); | |
| 28859 if( rc ){ | |
| 28860 shellDatabaseError(p->db); | |
| 28861 rc = 1; | |
| 28862 }else{ | |
| 28863 while( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 28864 const char *zSchema = (const char *)sqlite3_column_text(pStmt,1); | |
| 28865 const char *zFile = (const char*)sqlite3_column_text(pStmt,2); | |
| 28866 if( zSchema==0 || zFile==0 ) continue; | |
| 28867 azName = sqlite3_realloc64(azName, (nName+1)*2*sizeof(char*)); | |
| 28868 shell_check_oom(azName); | |
| 28869 azName[nName*2] = strdup(zSchema); | |
| 28870 azName[nName*2+1] = strdup(zFile); | |
| 28871 nName++; | |
| 28872 } | |
| 28873 } | |
| 28874 sqlite3_finalize(pStmt); | |
| 28875 for(i=0; i<nName; i++){ | |
| 28876 int eTxn = sqlite3_txn_state(p->db, azName[i*2]); | |
| 28877 int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]); | |
| 28878 const char *z = azName[i*2+1]; | |
| 28879 sqlite3_fprintf(p->out, "%s: %s %s%s\n", | |
| 28880 azName[i*2], z && z[0] ? z : "\"\"", bRdonly ? "r/o" : "r/w", | |
| 28881 eTxn==SQLITE_TXN_NONE ? "" : | |
| 28882 eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn"); | |
| 28883 free(azName[i*2]); | |
| 28884 free(azName[i*2+1]); | |
| 28885 } | |
| 28886 sqlite3_free(azName); | |
| 28887 }else | |
| 28888 | |
| 28889 if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbconfig", n)==0 ){ | |
| 28890 static const struct DbConfigChoices { | |
| 28891 const char *zName; | |
| 28892 int op; | |
| 28893 } aDbConfig[] = { | |
| 28894 { "attach_create", SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE }, | |
| 28895 { "attach_write", SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE }, | |
| 28896 { "comments", SQLITE_DBCONFIG_ENABLE_COMMENTS }, | |
| 28897 { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, | |
| 28898 { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, | |
| 28899 { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, | |
| 28900 { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, | |
| 28901 { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, | |
| 28902 { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, | |
| 28903 { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, | |
| 28904 { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, | |
| 28905 { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, | |
| 28906 { "legacy_file_format", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT }, | |
| 28907 { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, | |
| 28908 { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, | |
| 28909 { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, | |
| 28910 { "reverse_scanorder", SQLITE_DBCONFIG_REVERSE_SCANORDER }, | |
| 28911 { "stmt_scanstatus", SQLITE_DBCONFIG_STMT_SCANSTATUS }, | |
| 28912 { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, | |
| 28913 { "trusted_schema", SQLITE_DBCONFIG_TRUSTED_SCHEMA }, | |
| 28914 { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, | |
| 28915 }; | |
| 28916 int ii, v; | |
| 28917 open_db(p, 0); | |
| 28918 for(ii=0; ii<ArraySize(aDbConfig); ii++){ | |
| 28919 if( nArg>1 && cli_strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue; | |
| 28920 if( nArg>=3 ){ | |
| 28921 sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0); | |
| 28922 } | |
| 28923 sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v); | |
| 28924 sqlite3_fprintf(p->out, "%19s %s\n", | |
| 28925 aDbConfig[ii].zName, v ? "on" : "off"); | |
| 28926 if( nArg>1 ) break; | |
| 28927 } | |
| 28928 if( nArg>1 && ii==ArraySize(aDbConfig) ){ | |
| 28929 sqlite3_fprintf(stderr,"Error: unknown dbconfig \"%s\"\n", azArg[1]); | |
| 28930 eputz("Enter \".dbconfig\" with no arguments for a list\n"); | |
| 28931 } | |
| 28932 }else | |
| 28933 | |
| 28934 #if SQLITE_SHELL_HAVE_RECOVER | |
| 28935 if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbinfo", n)==0 ){ | |
| 28936 rc = shell_dbinfo_command(p, nArg, azArg); | |
| 28937 }else | |
| 28938 | |
| 28939 if( c=='r' && cli_strncmp(azArg[0], "recover", n)==0 ){ | |
| 28940 open_db(p, 0); | |
| 28941 rc = recoverDatabaseCmd(p, nArg, azArg); | |
| 28942 }else | |
| 28943 #endif /* SQLITE_SHELL_HAVE_RECOVER */ | |
| 28944 | |
| 28945 if( c=='d' && cli_strncmp(azArg[0], "dump", n)==0 ){ | |
| 28946 char *zLike = 0; | |
| 28947 char *zSql; | |
| 28948 int i; | |
| 28949 int savedShowHeader = p->showHeader; | |
| 28950 int savedShellFlags = p->shellFlgs; | |
| 28951 ShellClearFlag(p, | |
| 28952 SHFLG_PreserveRowid|SHFLG_Newlines|SHFLG_Echo | |
| 28953 |SHFLG_DumpDataOnly|SHFLG_DumpNoSys); | |
| 28954 for(i=1; i<nArg; i++){ | |
| 28955 if( azArg[i][0]=='-' ){ | |
| 28956 const char *z = azArg[i]+1; | |
| 28957 if( z[0]=='-' ) z++; | |
| 28958 if( cli_strcmp(z,"preserve-rowids")==0 ){ | |
| 28959 #ifdef SQLITE_OMIT_VIRTUALTABLE | |
| 28960 eputz("The --preserve-rowids option is not compatible" | |
| 28961 " with SQLITE_OMIT_VIRTUALTABLE\n"); | |
| 28962 rc = 1; | |
| 28963 sqlite3_free(zLike); | |
| 28964 goto meta_command_exit; | |
| 28965 #else | |
| 28966 ShellSetFlag(p, SHFLG_PreserveRowid); | |
| 28967 #endif | |
| 28968 }else | |
| 28969 if( cli_strcmp(z,"newlines")==0 ){ | |
| 28970 ShellSetFlag(p, SHFLG_Newlines); | |
| 28971 }else | |
| 28972 if( cli_strcmp(z,"data-only")==0 ){ | |
| 28973 ShellSetFlag(p, SHFLG_DumpDataOnly); | |
| 28974 }else | |
| 28975 if( cli_strcmp(z,"nosys")==0 ){ | |
| 28976 ShellSetFlag(p, SHFLG_DumpNoSys); | |
| 28977 }else | |
| 28978 { | |
| 28979 sqlite3_fprintf(stderr, | |
| 28980 "Unknown option \"%s\" on \".dump\"\n", azArg[i]); | |
| 28981 rc = 1; | |
| 28982 sqlite3_free(zLike); | |
| 28983 goto meta_command_exit; | |
| 28984 } | |
| 28985 }else{ | |
| 28986 /* azArg[i] contains a LIKE pattern. This ".dump" request should | |
| 28987 ** only dump data for tables for which either the table name matches | |
| 28988 ** the LIKE pattern, or the table appears to be a shadow table of | |
| 28989 ** a virtual table for which the name matches the LIKE pattern. | |
| 28990 */ | |
| 28991 char *zExpr = sqlite3_mprintf( | |
| 28992 "name LIKE %Q ESCAPE '\\' OR EXISTS (" | |
| 28993 " SELECT 1 FROM sqlite_schema WHERE " | |
| 28994 " name LIKE %Q ESCAPE '\\' AND" | |
| 28995 " sql LIKE 'CREATE VIRTUAL TABLE%%' AND" | |
| 28996 " substr(o.name, 1, length(name)+1) == (name||'_')" | |
| 28997 ")", azArg[i], azArg[i] | |
| 28998 ); | |
| 28999 | |
| 29000 if( zLike ){ | |
| 29001 zLike = sqlite3_mprintf("%z OR %z", zLike, zExpr); | |
| 29002 }else{ | |
| 29003 zLike = zExpr; | |
| 29004 } | |
| 29005 } | |
| 29006 } | |
| 29007 | |
| 29008 open_db(p, 0); | |
| 29009 | |
| 29010 outputDumpWarning(p, zLike); | |
| 29011 if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ | |
| 29012 /* When playing back a "dump", the content might appear in an order | |
| 29013 ** which causes immediate foreign key constraints to be violated. | |
| 29014 ** So disable foreign-key constraint enforcement to prevent problems. */ | |
| 29015 sqlite3_fputs("PRAGMA foreign_keys=OFF;\n", p->out); | |
| 29016 sqlite3_fputs("BEGIN TRANSACTION;\n", p->out); | |
| 29017 } | |
| 29018 p->writableSchema = 0; | |
| 29019 p->showHeader = 0; | |
| 29020 /* Set writable_schema=ON since doing so forces SQLite to initialize | |
| 29021 ** as much of the schema as it can even if the sqlite_schema table is | |
| 29022 ** corrupt. */ | |
| 29023 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0); | |
| 29024 p->nErr = 0; | |
| 29025 if( zLike==0 ) zLike = sqlite3_mprintf("true"); | |
| 29026 zSql = sqlite3_mprintf( | |
| 29027 "SELECT name, type, sql FROM sqlite_schema AS o " | |
| 29028 "WHERE (%s) AND type=='table'" | |
| 29029 " AND sql NOT NULL" | |
| 29030 " ORDER BY tbl_name='sqlite_sequence', rowid", | |
| 29031 zLike | |
| 29032 ); | |
| 29033 run_schema_dump_query(p,zSql); | |
| 29034 sqlite3_free(zSql); | |
| 29035 if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ | |
| 29036 zSql = sqlite3_mprintf( | |
| 29037 "SELECT sql FROM sqlite_schema AS o " | |
| 29038 "WHERE (%s) AND sql NOT NULL" | |
| 29039 " AND type IN ('index','trigger','view') " | |
| 29040 "ORDER BY type COLLATE NOCASE DESC", | |
| 29041 zLike | |
| 29042 ); | |
| 29043 run_table_dump_query(p, zSql); | |
| 29044 sqlite3_free(zSql); | |
| 29045 } | |
| 29046 sqlite3_free(zLike); | |
| 29047 if( p->writableSchema ){ | |
| 29048 sqlite3_fputs("PRAGMA writable_schema=OFF;\n", p->out); | |
| 29049 p->writableSchema = 0; | |
| 29050 } | |
| 29051 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); | |
| 29052 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); | |
| 29053 if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){ | |
| 29054 sqlite3_fputs(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n", p->out); | |
| 29055 } | |
| 29056 p->showHeader = savedShowHeader; | |
| 29057 p->shellFlgs = savedShellFlags; | |
| 29058 rc = p->nErr>0; | |
| 29059 }else | |
| 29060 | |
| 29061 if( c=='e' && cli_strncmp(azArg[0], "echo", n)==0 ){ | |
| 29062 if( nArg==2 ){ | |
| 29063 setOrClearFlag(p, SHFLG_Echo, azArg[1]); | |
| 29064 }else{ | |
| 29065 eputz("Usage: .echo on|off\n"); | |
| 29066 rc = 1; | |
| 29067 } | |
| 29068 }else | |
| 29069 | |
| 29070 if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){ | |
| 29071 open_db(p, 0); | |
| 29072 rc = shell_dbtotxt_command(p, nArg, azArg); | |
| 29073 }else | |
| 29074 | |
| 29075 if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){ | |
| 29076 if( nArg==2 ){ | |
| 29077 p->autoEQPtest = 0; | |
| 29078 if( p->autoEQPtrace ){ | |
| 29079 if( p->db ) sqlite3_exec(p->db, "PRAGMA vdbe_trace=OFF;", 0, 0, 0); | |
| 29080 p->autoEQPtrace = 0; | |
| 29081 } | |
| 29082 if( cli_strcmp(azArg[1],"full")==0 ){ | |
| 29083 p->autoEQP = AUTOEQP_full; | |
| 29084 }else if( cli_strcmp(azArg[1],"trigger")==0 ){ | |
| 29085 p->autoEQP = AUTOEQP_trigger; | |
| 29086 #ifdef SQLITE_DEBUG | |
| 29087 }else if( cli_strcmp(azArg[1],"test")==0 ){ | |
| 29088 p->autoEQP = AUTOEQP_on; | |
| 29089 p->autoEQPtest = 1; | |
| 29090 }else if( cli_strcmp(azArg[1],"trace")==0 ){ | |
| 29091 p->autoEQP = AUTOEQP_full; | |
| 29092 p->autoEQPtrace = 1; | |
| 29093 open_db(p, 0); | |
| 29094 sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1", 0, 0, 0); | |
| 29095 sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;", 0, 0, 0); | |
| 29096 #endif | |
| 29097 }else{ | |
| 29098 p->autoEQP = (u8)booleanValue(azArg[1]); | |
| 29099 } | |
| 29100 }else{ | |
| 29101 eputz("Usage: .eqp off|on|trace|trigger|full\n"); | |
| 29102 rc = 1; | |
| 29103 } | |
| 29104 }else | |
| 29105 | |
| 29106 #ifndef SQLITE_SHELL_FIDDLE | |
| 29107 if( c=='e' && cli_strncmp(azArg[0], "exit", n)==0 ){ | |
| 29108 if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc); | |
| 29109 rc = 2; | |
| 29110 }else | |
| 29111 #endif | |
| 29112 | |
| 29113 /* The ".explain" command is automatic now. It is largely pointless. It | |
| 29114 ** retained purely for backwards compatibility */ | |
| 29115 if( c=='e' && cli_strncmp(azArg[0], "explain", n)==0 ){ | |
| 29116 int val = 1; | |
| 29117 if( nArg>=2 ){ | |
| 29118 if( cli_strcmp(azArg[1],"auto")==0 ){ | |
| 29119 val = 99; | |
| 29120 }else{ | |
| 29121 val = booleanValue(azArg[1]); | |
| 29122 } | |
| 29123 } | |
| 29124 if( val==1 && p->mode!=MODE_Explain ){ | |
| 29125 p->normalMode = p->mode; | |
| 29126 p->mode = MODE_Explain; | |
| 29127 p->autoExplain = 0; | |
| 29128 }else if( val==0 ){ | |
| 29129 if( p->mode==MODE_Explain ) p->mode = p->normalMode; | |
| 29130 p->autoExplain = 0; | |
| 29131 }else if( val==99 ){ | |
| 29132 if( p->mode==MODE_Explain ) p->mode = p->normalMode; | |
| 29133 p->autoExplain = 1; | |
| 29134 } | |
| 29135 }else | |
| 29136 | |
| 29137 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 29138 if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){ | |
| 29139 if( p->bSafeMode ){ | |
| 29140 sqlite3_fprintf(stderr, | |
| 29141 "Cannot run experimental commands such as \"%s\" in safe mode\n", | |
| 29142 azArg[0]); | |
| 29143 rc = 1; | |
| 29144 }else{ | |
| 29145 open_db(p, 0); | |
| 29146 expertDotCommand(p, azArg, nArg); | |
| 29147 } | |
| 29148 }else | |
| 29149 #endif | |
| 29150 | |
| 29151 if( c=='f' && cli_strncmp(azArg[0], "filectrl", n)==0 ){ | |
| 29152 static const struct { | |
| 29153 const char *zCtrlName; /* Name of a test-control option */ | |
| 29154 int ctrlCode; /* Integer code for that option */ | |
| 29155 const char *zUsage; /* Usage notes */ | |
| 29156 } aCtrl[] = { | |
| 29157 { "chunk_size", SQLITE_FCNTL_CHUNK_SIZE, "SIZE" }, | |
| 29158 { "data_version", SQLITE_FCNTL_DATA_VERSION, "" }, | |
| 29159 { "has_moved", SQLITE_FCNTL_HAS_MOVED, "" }, | |
| 29160 { "lock_timeout", SQLITE_FCNTL_LOCK_TIMEOUT, "MILLISEC" }, | |
| 29161 { "persist_wal", SQLITE_FCNTL_PERSIST_WAL, "[BOOLEAN]" }, | |
| 29162 /* { "pragma", SQLITE_FCNTL_PRAGMA, "NAME ARG" },*/ | |
| 29163 { "psow", SQLITE_FCNTL_POWERSAFE_OVERWRITE, "[BOOLEAN]" }, | |
| 29164 { "reserve_bytes", SQLITE_FCNTL_RESERVE_BYTES, "[N]" }, | |
| 29165 { "size_limit", SQLITE_FCNTL_SIZE_LIMIT, "[LIMIT]" }, | |
| 29166 { "tempfilename", SQLITE_FCNTL_TEMPFILENAME, "" }, | |
| 29167 /* { "win32_av_retry", SQLITE_FCNTL_WIN32_AV_RETRY, "COUNT DELAY" },*/ | |
| 29168 }; | |
| 29169 int filectrl = -1; | |
| 29170 int iCtrl = -1; | |
| 29171 sqlite3_int64 iRes = 0; /* Integer result to display if rc2==1 */ | |
| 29172 int isOk = 0; /* 0: usage 1: %lld 2: no-result */ | |
| 29173 int n2, i; | |
| 29174 const char *zCmd = 0; | |
| 29175 const char *zSchema = 0; | |
| 29176 | |
| 29177 open_db(p, 0); | |
| 29178 zCmd = nArg>=2 ? azArg[1] : "help"; | |
| 29179 | |
| 29180 if( zCmd[0]=='-' | |
| 29181 && (cli_strcmp(zCmd,"--schema")==0 || cli_strcmp(zCmd,"-schema")==0) | |
| 29182 && nArg>=4 | |
| 29183 ){ | |
| 29184 zSchema = azArg[2]; | |
| 29185 for(i=3; i<nArg; i++) azArg[i-2] = azArg[i]; | |
| 29186 nArg -= 2; | |
| 29187 zCmd = azArg[1]; | |
| 29188 } | |
| 29189 | |
| 29190 /* The argument can optionally begin with "-" or "--" */ | |
| 29191 if( zCmd[0]=='-' && zCmd[1] ){ | |
| 29192 zCmd++; | |
| 29193 if( zCmd[0]=='-' && zCmd[1] ) zCmd++; | |
| 29194 } | |
| 29195 | |
| 29196 /* --help lists all file-controls */ | |
| 29197 if( cli_strcmp(zCmd,"help")==0 ){ | |
| 29198 sqlite3_fputs("Available file-controls:\n", p->out); | |
| 29199 for(i=0; i<ArraySize(aCtrl); i++){ | |
| 29200 sqlite3_fprintf(p->out, | |
| 29201 " .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage); | |
| 29202 } | |
| 29203 rc = 1; | |
| 29204 goto meta_command_exit; | |
| 29205 } | |
| 29206 | |
| 29207 /* convert filectrl text option to value. allow any unique prefix | |
| 29208 ** of the option name, or a numerical value. */ | |
| 29209 n2 = strlen30(zCmd); | |
| 29210 for(i=0; i<ArraySize(aCtrl); i++){ | |
| 29211 if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){ | |
| 29212 if( filectrl<0 ){ | |
| 29213 filectrl = aCtrl[i].ctrlCode; | |
| 29214 iCtrl = i; | |
| 29215 }else{ | |
| 29216 sqlite3_fprintf(stderr,"Error: ambiguous file-control: \"%s\"\n" | |
| 29217 "Use \".filectrl --help\" for help\n", zCmd); | |
| 29218 rc = 1; | |
| 29219 goto meta_command_exit; | |
| 29220 } | |
| 29221 } | |
| 29222 } | |
| 29223 if( filectrl<0 ){ | |
| 29224 sqlite3_fprintf(stderr,"Error: unknown file-control: %s\n" | |
| 29225 "Use \".filectrl --help\" for help\n", zCmd); | |
| 29226 }else{ | |
| 29227 switch(filectrl){ | |
| 29228 case SQLITE_FCNTL_SIZE_LIMIT: { | |
| 29229 if( nArg!=2 && nArg!=3 ) break; | |
| 29230 iRes = nArg==3 ? integerValue(azArg[2]) : -1; | |
| 29231 sqlite3_file_control(p->db, zSchema, SQLITE_FCNTL_SIZE_LIMIT, &iRes); | |
| 29232 isOk = 1; | |
| 29233 break; | |
| 29234 } | |
| 29235 case SQLITE_FCNTL_LOCK_TIMEOUT: | |
| 29236 case SQLITE_FCNTL_CHUNK_SIZE: { | |
| 29237 int x; | |
| 29238 if( nArg!=3 ) break; | |
| 29239 x = (int)integerValue(azArg[2]); | |
| 29240 sqlite3_file_control(p->db, zSchema, filectrl, &x); | |
| 29241 isOk = 2; | |
| 29242 break; | |
| 29243 } | |
| 29244 case SQLITE_FCNTL_PERSIST_WAL: | |
| 29245 case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { | |
| 29246 int x; | |
| 29247 if( nArg!=2 && nArg!=3 ) break; | |
| 29248 x = nArg==3 ? booleanValue(azArg[2]) : -1; | |
| 29249 sqlite3_file_control(p->db, zSchema, filectrl, &x); | |
| 29250 iRes = x; | |
| 29251 isOk = 1; | |
| 29252 break; | |
| 29253 } | |
| 29254 case SQLITE_FCNTL_DATA_VERSION: | |
| 29255 case SQLITE_FCNTL_HAS_MOVED: { | |
| 29256 int x; | |
| 29257 if( nArg!=2 ) break; | |
| 29258 sqlite3_file_control(p->db, zSchema, filectrl, &x); | |
| 29259 iRes = x; | |
| 29260 isOk = 1; | |
| 29261 break; | |
| 29262 } | |
| 29263 case SQLITE_FCNTL_TEMPFILENAME: { | |
| 29264 char *z = 0; | |
| 29265 if( nArg!=2 ) break; | |
| 29266 sqlite3_file_control(p->db, zSchema, filectrl, &z); | |
| 29267 if( z ){ | |
| 29268 sqlite3_fprintf(p->out, "%s\n", z); | |
| 29269 sqlite3_free(z); | |
| 29270 } | |
| 29271 isOk = 2; | |
| 29272 break; | |
| 29273 } | |
| 29274 case SQLITE_FCNTL_RESERVE_BYTES: { | |
| 29275 int x; | |
| 29276 if( nArg>=3 ){ | |
| 29277 x = atoi(azArg[2]); | |
| 29278 sqlite3_file_control(p->db, zSchema, filectrl, &x); | |
| 29279 } | |
| 29280 x = -1; | |
| 29281 sqlite3_file_control(p->db, zSchema, filectrl, &x); | |
| 29282 sqlite3_fprintf(p->out, "%d\n", x); | |
| 29283 isOk = 2; | |
| 29284 break; | |
| 29285 } | |
| 29286 } | |
| 29287 } | |
| 29288 if( isOk==0 && iCtrl>=0 ){ | |
| 29289 sqlite3_fprintf(p->out, "Usage: .filectrl %s %s\n", | |
| 29290 zCmd, aCtrl[iCtrl].zUsage); | |
| 29291 rc = 1; | |
| 29292 }else if( isOk==1 ){ | |
| 29293 char zBuf[100]; | |
| 29294 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes); | |
| 29295 sqlite3_fprintf(p->out, "%s\n", zBuf); | |
| 29296 } | |
| 29297 }else | |
| 29298 | |
| 29299 if( c=='f' && cli_strncmp(azArg[0], "fullschema", n)==0 ){ | |
| 29300 ShellState data; | |
| 29301 int doStats = 0; | |
| 29302 memcpy(&data, p, sizeof(data)); | |
| 29303 data.showHeader = 0; | |
| 29304 data.cMode = data.mode = MODE_Semi; | |
| 29305 if( nArg==2 && optionMatch(azArg[1], "indent") ){ | |
| 29306 data.cMode = data.mode = MODE_Pretty; | |
| 29307 nArg = 1; | |
| 29308 } | |
| 29309 if( nArg!=1 ){ | |
| 29310 eputz("Usage: .fullschema ?--indent?\n"); | |
| 29311 rc = 1; | |
| 29312 goto meta_command_exit; | |
| 29313 } | |
| 29314 open_db(p, 0); | |
| 29315 rc = sqlite3_exec(p->db, | |
| 29316 "SELECT sql FROM" | |
| 29317 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" | |
| 29318 " FROM sqlite_schema UNION ALL" | |
| 29319 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_schema) " | |
| 29320 "WHERE type!='meta' AND sql NOTNULL" | |
| 29321 " AND name NOT LIKE 'sqlite__%' ESCAPE '_' " | |
| 29322 "ORDER BY x", | |
| 29323 callback, &data, 0 | |
| 29324 ); | |
| 29325 if( rc==SQLITE_OK ){ | |
| 29326 sqlite3_stmt *pStmt; | |
| 29327 rc = sqlite3_prepare_v2(p->db, | |
| 29328 "SELECT rowid FROM sqlite_schema" | |
| 29329 " WHERE name GLOB 'sqlite_stat[134]'", | |
| 29330 -1, &pStmt, 0); | |
| 29331 if( rc==SQLITE_OK ){ | |
| 29332 doStats = sqlite3_step(pStmt)==SQLITE_ROW; | |
| 29333 sqlite3_finalize(pStmt); | |
| 29334 } | |
| 29335 } | |
| 29336 if( doStats==0 ){ | |
| 29337 sqlite3_fputs("/* No STAT tables available */\n", p->out); | |
| 29338 }else{ | |
| 29339 sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); | |
| 29340 data.cMode = data.mode = MODE_Insert; | |
| 29341 data.zDestTable = "sqlite_stat1"; | |
| 29342 shell_exec(&data, "SELECT * FROM sqlite_stat1", 0); | |
| 29343 data.zDestTable = "sqlite_stat4"; | |
| 29344 shell_exec(&data, "SELECT * FROM sqlite_stat4", 0); | |
| 29345 sqlite3_fputs("ANALYZE sqlite_schema;\n", p->out); | |
| 29346 } | |
| 29347 }else | |
| 29348 | |
| 29349 if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){ | |
| 29350 if( nArg==2 ){ | |
| 29351 p->showHeader = booleanValue(azArg[1]); | |
| 29352 p->shellFlgs |= SHFLG_HeaderSet; | |
| 29353 }else{ | |
| 29354 eputz("Usage: .headers on|off\n"); | |
| 29355 rc = 1; | |
| 29356 } | |
| 29357 }else | |
| 29358 | |
| 29359 if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){ | |
| 29360 if( nArg>=2 ){ | |
| 29361 n = showHelp(p->out, azArg[1]); | |
| 29362 if( n==0 ){ | |
| 29363 sqlite3_fprintf(p->out, "Nothing matches '%s'\n", azArg[1]); | |
| 29364 } | |
| 29365 }else{ | |
| 29366 showHelp(p->out, 0); | |
| 29367 } | |
| 29368 }else | |
| 29369 | |
| 29370 #ifndef SQLITE_SHELL_FIDDLE | |
| 29371 if( c=='i' && cli_strncmp(azArg[0], "import", n)==0 ){ | |
| 29372 char *zTable = 0; /* Insert data into this table */ | |
| 29373 char *zSchema = 0; /* Schema of zTable */ | |
| 29374 char *zFile = 0; /* Name of file to extra content from */ | |
| 29375 sqlite3_stmt *pStmt = NULL; /* A statement */ | |
| 29376 int nCol; /* Number of columns in the table */ | |
| 29377 i64 nByte; /* Number of bytes in an SQL string */ | |
| 29378 int i, j; /* Loop counters */ | |
| 29379 int needCommit; /* True to COMMIT or ROLLBACK at end */ | |
| 29380 int nSep; /* Number of bytes in p->colSeparator[] */ | |
| 29381 char *zSql = 0; /* An SQL statement */ | |
| 29382 ImportCtx sCtx; /* Reader context */ | |
| 29383 char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */ | |
| 29384 int eVerbose = 0; /* Larger for more console output */ | |
| 29385 i64 nSkip = 0; /* Initial lines to skip */ | |
| 29386 int useOutputMode = 1; /* Use output mode to determine separators */ | |
| 29387 char *zCreate = 0; /* CREATE TABLE statement text */ | |
| 29388 | |
| 29389 failIfSafeMode(p, "cannot run .import in safe mode"); | |
| 29390 memset(&sCtx, 0, sizeof(sCtx)); | |
| 29391 if( p->mode==MODE_Ascii ){ | |
| 29392 xRead = ascii_read_one_field; | |
| 29393 }else{ | |
| 29394 xRead = csv_read_one_field; | |
| 29395 } | |
| 29396 rc = 1; | |
| 29397 for(i=1; i<nArg; i++){ | |
| 29398 char *z = azArg[i]; | |
| 29399 if( z[0]=='-' && z[1]=='-' ) z++; | |
| 29400 if( z[0]!='-' ){ | |
| 29401 if( zFile==0 ){ | |
| 29402 zFile = z; | |
| 29403 }else if( zTable==0 ){ | |
| 29404 zTable = z; | |
| 29405 }else{ | |
| 29406 sqlite3_fprintf(p->out, "ERROR: extra argument: \"%s\". Usage:\n",z); | |
| 29407 showHelp(p->out, "import"); | |
| 29408 goto meta_command_exit; | |
| 29409 } | |
| 29410 }else if( cli_strcmp(z,"-v")==0 ){ | |
| 29411 eVerbose++; | |
| 29412 }else if( cli_strcmp(z,"-schema")==0 && i<nArg-1 ){ | |
| 29413 zSchema = azArg[++i]; | |
| 29414 }else if( cli_strcmp(z,"-skip")==0 && i<nArg-1 ){ | |
| 29415 nSkip = integerValue(azArg[++i]); | |
| 29416 }else if( cli_strcmp(z,"-ascii")==0 ){ | |
| 29417 sCtx.cColSep = SEP_Unit[0]; | |
| 29418 sCtx.cRowSep = SEP_Record[0]; | |
| 29419 xRead = ascii_read_one_field; | |
| 29420 useOutputMode = 0; | |
| 29421 }else if( cli_strcmp(z,"-csv")==0 ){ | |
| 29422 sCtx.cColSep = ','; | |
| 29423 sCtx.cRowSep = '\n'; | |
| 29424 xRead = csv_read_one_field; | |
| 29425 useOutputMode = 0; | |
| 29426 }else{ | |
| 29427 sqlite3_fprintf(p->out, "ERROR: unknown option: \"%s\". Usage:\n", z); | |
| 29428 showHelp(p->out, "import"); | |
| 29429 goto meta_command_exit; | |
| 29430 } | |
| 29431 } | |
| 29432 if( zTable==0 ){ | |
| 29433 sqlite3_fprintf(p->out, "ERROR: missing %s argument. Usage:\n", | |
| 29434 zFile==0 ? "FILE" : "TABLE"); | |
| 29435 showHelp(p->out, "import"); | |
| 29436 goto meta_command_exit; | |
| 29437 } | |
| 29438 seenInterrupt = 0; | |
| 29439 open_db(p, 0); | |
| 29440 if( useOutputMode ){ | |
| 29441 /* If neither the --csv or --ascii options are specified, then set | |
| 29442 ** the column and row separator characters from the output mode. */ | |
| 29443 nSep = strlen30(p->colSeparator); | |
| 29444 if( nSep==0 ){ | |
| 29445 eputz("Error: non-null column separator required for import\n"); | |
| 29446 goto meta_command_exit; | |
| 29447 } | |
| 29448 if( nSep>1 ){ | |
| 29449 eputz("Error: multi-character column separators not allowed" | |
| 29450 " for import\n"); | |
| 29451 goto meta_command_exit; | |
| 29452 } | |
| 29453 nSep = strlen30(p->rowSeparator); | |
| 29454 if( nSep==0 ){ | |
| 29455 eputz("Error: non-null row separator required for import\n"); | |
| 29456 goto meta_command_exit; | |
| 29457 } | |
| 29458 if( nSep==2 && p->mode==MODE_Csv | |
| 29459 && cli_strcmp(p->rowSeparator,SEP_CrLf)==0 | |
| 29460 ){ | |
| 29461 /* When importing CSV (only), if the row separator is set to the | |
| 29462 ** default output row separator, change it to the default input | |
| 29463 ** row separator. This avoids having to maintain different input | |
| 29464 ** and output row separators. */ | |
| 29465 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); | |
| 29466 nSep = strlen30(p->rowSeparator); | |
| 29467 } | |
| 29468 if( nSep>1 ){ | |
| 29469 eputz("Error: multi-character row separators not allowed" | |
| 29470 " for import\n"); | |
| 29471 goto meta_command_exit; | |
| 29472 } | |
| 29473 sCtx.cColSep = (u8)p->colSeparator[0]; | |
| 29474 sCtx.cRowSep = (u8)p->rowSeparator[0]; | |
| 29475 } | |
| 29476 sCtx.zFile = zFile; | |
| 29477 sCtx.nLine = 1; | |
| 29478 if( sCtx.zFile[0]=='|' ){ | |
| 29479 #ifdef SQLITE_OMIT_POPEN | |
| 29480 eputz("Error: pipes are not supported in this OS\n"); | |
| 29481 goto meta_command_exit; | |
| 29482 #else | |
| 29483 sCtx.in = sqlite3_popen(sCtx.zFile+1, "r"); | |
| 29484 sCtx.zFile = "<pipe>"; | |
| 29485 sCtx.xCloser = pclose; | |
| 29486 #endif | |
| 29487 }else{ | |
| 29488 sCtx.in = sqlite3_fopen(sCtx.zFile, "rb"); | |
| 29489 sCtx.xCloser = fclose; | |
| 29490 } | |
| 29491 if( sCtx.in==0 ){ | |
| 29492 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zFile); | |
| 29493 goto meta_command_exit; | |
| 29494 } | |
| 29495 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){ | |
| 29496 char zSep[2]; | |
| 29497 zSep[1] = 0; | |
| 29498 zSep[0] = sCtx.cColSep; | |
| 29499 sqlite3_fputs("Column separator ", p->out); | |
| 29500 output_c_string(p->out, zSep); | |
| 29501 sqlite3_fputs(", row separator ", p->out); | |
| 29502 zSep[0] = sCtx.cRowSep; | |
| 29503 output_c_string(p->out, zSep); | |
| 29504 sqlite3_fputs("\n", p->out); | |
| 29505 } | |
| 29506 sCtx.z = sqlite3_malloc64(120); | |
| 29507 if( sCtx.z==0 ){ | |
| 29508 import_cleanup(&sCtx); | |
| 29509 shell_out_of_memory(); | |
| 29510 } | |
| 29511 /* Below, resources must be freed before exit. */ | |
| 29512 while( nSkip>0 ){ | |
| 29513 nSkip--; | |
| 29514 while( xRead(&sCtx) && sCtx.cTerm==sCtx.cColSep ){} | |
| 29515 } | |
| 29516 import_append_char(&sCtx, 0); /* To ensure sCtx.z is allocated */ | |
| 29517 if( sqlite3_table_column_metadata(p->db, zSchema, zTable,0,0,0,0,0,0) | |
| 29518 && 0==db_int(p->db, "SELECT count(*) FROM \"%w\".sqlite_schema" | |
| 29519 " WHERE name=%Q AND type='view'", | |
| 29520 zSchema ? zSchema : "main", zTable) | |
| 29521 ){ | |
| 29522 /* Table does not exist. Create it. */ | |
| 29523 sqlite3 *dbCols = 0; | |
| 29524 char *zRenames = 0; | |
| 29525 char *zColDefs; | |
| 29526 zCreate = sqlite3_mprintf("CREATE TABLE \"%w\".\"%w\"", | |
| 29527 zSchema ? zSchema : "main", zTable); | |
| 29528 while( xRead(&sCtx) ){ | |
| 29529 zAutoColumn(sCtx.z, &dbCols, 0); | |
| 29530 if( sCtx.cTerm!=sCtx.cColSep ) break; | |
| 29531 } | |
| 29532 zColDefs = zAutoColumn(0, &dbCols, &zRenames); | |
| 29533 if( zRenames!=0 ){ | |
| 29534 sqlite3_fprintf((stdin_is_interactive && p->in==stdin)? p->out : stderr, | |
| 29535 "Columns renamed during .import %s due to duplicates:\n" | |
| 29536 "%s\n", sCtx.zFile, zRenames); | |
| 29537 sqlite3_free(zRenames); | |
| 29538 } | |
| 29539 assert(dbCols==0); | |
| 29540 if( zColDefs==0 ){ | |
| 29541 sqlite3_fprintf(stderr,"%s: empty file\n", sCtx.zFile); | |
| 29542 import_cleanup(&sCtx); | |
| 29543 rc = 1; | |
| 29544 sqlite3_free(zCreate); | |
| 29545 goto meta_command_exit; | |
| 29546 } | |
| 29547 zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs); | |
| 29548 if( zCreate==0 ){ | |
| 29549 import_cleanup(&sCtx); | |
| 29550 shell_out_of_memory(); | |
| 29551 } | |
| 29552 if( eVerbose>=1 ){ | |
| 29553 sqlite3_fprintf(p->out, "%s\n", zCreate); | |
| 29554 } | |
| 29555 rc = sqlite3_exec(p->db, zCreate, 0, 0, 0); | |
| 29556 if( rc ){ | |
| 29557 sqlite3_fprintf(stderr, | |
| 29558 "%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db)); | |
| 29559 } | |
| 29560 sqlite3_free(zCreate); | |
| 29561 zCreate = 0; | |
| 29562 if( rc ){ | |
| 29563 import_cleanup(&sCtx); | |
| 29564 rc = 1; | |
| 29565 goto meta_command_exit; | |
| 29566 } | |
| 29567 } | |
| 29568 zSql = sqlite3_mprintf("SELECT count(*) FROM pragma_table_info(%Q,%Q);", | |
| 29569 zTable, zSchema); | |
| 29570 if( zSql==0 ){ | |
| 29571 import_cleanup(&sCtx); | |
| 29572 shell_out_of_memory(); | |
| 29573 } | |
| 29574 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); | |
| 29575 sqlite3_free(zSql); | |
| 29576 zSql = 0; | |
| 29577 if( rc ){ | |
| 29578 if (pStmt) sqlite3_finalize(pStmt); | |
| 29579 shellDatabaseError(p->db); | |
| 29580 import_cleanup(&sCtx); | |
| 29581 rc = 1; | |
| 29582 goto meta_command_exit; | |
| 29583 } | |
| 29584 if( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 29585 nCol = sqlite3_column_int(pStmt, 0); | |
| 29586 }else{ | |
| 29587 nCol = 0; | |
| 29588 } | |
| 29589 sqlite3_finalize(pStmt); | |
| 29590 pStmt = 0; | |
| 29591 if( nCol==0 ) return 0; /* no columns, no error */ | |
| 29592 | |
| 29593 nByte = 64 /* space for "INSERT INTO", "VALUES(", ")\0" */ | |
| 29594 + (zSchema ? strlen(zSchema)*2 + 2: 0) /* Quoted schema name */ | |
| 29595 + strlen(zTable)*2 + 2 /* Quoted table name */ | |
| 29596 + nCol*2; /* Space for ",?" for each column */ | |
| 29597 zSql = sqlite3_malloc64( nByte ); | |
| 29598 if( zSql==0 ){ | |
| 29599 import_cleanup(&sCtx); | |
| 29600 shell_out_of_memory(); | |
| 29601 } | |
| 29602 if( zSchema ){ | |
| 29603 sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\".\"%w\" VALUES(?", | |
| 29604 zSchema, zTable); | |
| 29605 }else{ | |
| 29606 sqlite3_snprintf(nByte, zSql, "INSERT INTO \"%w\" VALUES(?", zTable); | |
| 29607 } | |
| 29608 j = strlen30(zSql); | |
| 29609 for(i=1; i<nCol; i++){ | |
| 29610 zSql[j++] = ','; | |
| 29611 zSql[j++] = '?'; | |
| 29612 } | |
| 29613 zSql[j++] = ')'; | |
| 29614 zSql[j] = 0; | |
| 29615 assert( j<nByte ); | |
| 29616 if( eVerbose>=2 ){ | |
| 29617 sqlite3_fprintf(p->out, "Insert using: %s\n", zSql); | |
| 29618 } | |
| 29619 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); | |
| 29620 sqlite3_free(zSql); | |
| 29621 zSql = 0; | |
| 29622 if( rc ){ | |
| 29623 shellDatabaseError(p->db); | |
| 29624 if (pStmt) sqlite3_finalize(pStmt); | |
| 29625 import_cleanup(&sCtx); | |
| 29626 rc = 1; | |
| 29627 goto meta_command_exit; | |
| 29628 } | |
| 29629 needCommit = sqlite3_get_autocommit(p->db); | |
| 29630 if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0); | |
| 29631 do{ | |
| 29632 int startLine = sCtx.nLine; | |
| 29633 for(i=0; i<nCol; i++){ | |
| 29634 char *z = xRead(&sCtx); | |
| 29635 /* | |
| 29636 ** Did we reach end-of-file before finding any columns? | |
| 29637 ** If so, stop instead of NULL filling the remaining columns. | |
| 29638 */ | |
| 29639 if( z==0 && i==0 ) break; | |
| 29640 /* | |
| 29641 ** Did we reach end-of-file OR end-of-line before finding any | |
| 29642 ** columns in ASCII mode? If so, stop instead of NULL filling | |
| 29643 ** the remaining columns. | |
| 29644 */ | |
| 29645 if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; | |
| 29646 /* | |
| 29647 ** For CSV mode, per RFC 4180, accept EOF in lieu of final | |
| 29648 ** record terminator but only for last field of multi-field row. | |
| 29649 ** (If there are too few fields, it's not valid CSV anyway.) | |
| 29650 */ | |
| 29651 if( z==0 && (xRead==csv_read_one_field) && i==nCol-1 && i>0 ){ | |
| 29652 z = ""; | |
| 29653 } | |
| 29654 sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); | |
| 29655 if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){ | |
| 29656 sqlite3_fprintf(stderr,"%s:%d: expected %d columns but found %d" | |
| 29657 " - filling the rest with NULL\n", | |
| 29658 sCtx.zFile, startLine, nCol, i+1); | |
| 29659 i += 2; | |
| 29660 while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; } | |
| 29661 } | |
| 29662 } | |
| 29663 if( sCtx.cTerm==sCtx.cColSep ){ | |
| 29664 do{ | |
| 29665 xRead(&sCtx); | |
| 29666 i++; | |
| 29667 }while( sCtx.cTerm==sCtx.cColSep ); | |
| 29668 sqlite3_fprintf(stderr, | |
| 29669 "%s:%d: expected %d columns but found %d - extras ignored\n", | |
| 29670 sCtx.zFile, startLine, nCol, i); | |
| 29671 } | |
| 29672 if( i>=nCol ){ | |
| 29673 sqlite3_step(pStmt); | |
| 29674 rc = sqlite3_reset(pStmt); | |
| 29675 if( rc!=SQLITE_OK ){ | |
| 29676 sqlite3_fprintf(stderr,"%s:%d: INSERT failed: %s\n", | |
| 29677 sCtx.zFile, startLine, sqlite3_errmsg(p->db)); | |
| 29678 sCtx.nErr++; | |
| 29679 }else{ | |
| 29680 sCtx.nRow++; | |
| 29681 } | |
| 29682 } | |
| 29683 }while( sCtx.cTerm!=EOF ); | |
| 29684 | |
| 29685 import_cleanup(&sCtx); | |
| 29686 sqlite3_finalize(pStmt); | |
| 29687 if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0); | |
| 29688 if( eVerbose>0 ){ | |
| 29689 sqlite3_fprintf(p->out, | |
| 29690 "Added %d rows with %d errors using %d lines of input\n", | |
| 29691 sCtx.nRow, sCtx.nErr, sCtx.nLine-1); | |
| 29692 } | |
| 29693 }else | |
| 29694 #endif /* !defined(SQLITE_SHELL_FIDDLE) */ | |
| 29695 | |
| 29696 #ifndef SQLITE_UNTESTABLE | |
| 29697 if( c=='i' && cli_strncmp(azArg[0], "imposter", n)==0 ){ | |
| 29698 char *zSql; | |
| 29699 char *zCollist = 0; | |
| 29700 sqlite3_stmt *pStmt; | |
| 29701 int tnum = 0; | |
| 29702 int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */ | |
| 29703 int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */ | |
| 29704 int i; | |
| 29705 if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){ | |
| 29706 eputz("Usage: .imposter INDEX IMPOSTER\n" | |
| 29707 " .imposter off\n"); | |
| 29708 /* Also allowed, but not documented: | |
| 29709 ** | |
| 29710 ** .imposter TABLE IMPOSTER | |
| 29711 ** | |
| 29712 ** where TABLE is a WITHOUT ROWID table. In that case, the | |
| 29713 ** imposter is another WITHOUT ROWID table with the columns in | |
| 29714 ** storage order. */ | |
| 29715 rc = 1; | |
| 29716 goto meta_command_exit; | |
| 29717 } | |
| 29718 open_db(p, 0); | |
| 29719 if( nArg==2 ){ | |
| 29720 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1); | |
| 29721 goto meta_command_exit; | |
| 29722 } | |
| 29723 zSql = sqlite3_mprintf( | |
| 29724 "SELECT rootpage, 0 FROM sqlite_schema" | |
| 29725 " WHERE name='%q' AND type='index'" | |
| 29726 "UNION ALL " | |
| 29727 "SELECT rootpage, 1 FROM sqlite_schema" | |
| 29728 " WHERE name='%q' AND type='table'" | |
| 29729 " AND sql LIKE '%%without%%rowid%%'", | |
| 29730 azArg[1], azArg[1] | |
| 29731 ); | |
| 29732 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); | |
| 29733 sqlite3_free(zSql); | |
| 29734 if( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 29735 tnum = sqlite3_column_int(pStmt, 0); | |
| 29736 isWO = sqlite3_column_int(pStmt, 1); | |
| 29737 } | |
| 29738 sqlite3_finalize(pStmt); | |
| 29739 zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]); | |
| 29740 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); | |
| 29741 sqlite3_free(zSql); | |
| 29742 i = 0; | |
| 29743 while( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 29744 char zLabel[20]; | |
| 29745 const char *zCol = (const char*)sqlite3_column_text(pStmt,2); | |
| 29746 i++; | |
| 29747 if( zCol==0 ){ | |
| 29748 if( sqlite3_column_int(pStmt,1)==-1 ){ | |
| 29749 zCol = "_ROWID_"; | |
| 29750 }else{ | |
| 29751 sqlite3_snprintf(sizeof(zLabel),zLabel,"expr%d",i); | |
| 29752 zCol = zLabel; | |
| 29753 } | |
| 29754 } | |
| 29755 if( isWO && lenPK==0 && sqlite3_column_int(pStmt,5)==0 && zCollist ){ | |
| 29756 lenPK = (int)strlen(zCollist); | |
| 29757 } | |
| 29758 if( zCollist==0 ){ | |
| 29759 zCollist = sqlite3_mprintf("\"%w\"", zCol); | |
| 29760 }else{ | |
| 29761 zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol); | |
| 29762 } | |
| 29763 } | |
| 29764 sqlite3_finalize(pStmt); | |
| 29765 if( i==0 || tnum==0 ){ | |
| 29766 sqlite3_fprintf(stderr,"no such index: \"%s\"\n", azArg[1]); | |
| 29767 rc = 1; | |
| 29768 sqlite3_free(zCollist); | |
| 29769 goto meta_command_exit; | |
| 29770 } | |
| 29771 if( lenPK==0 ) lenPK = 100000; | |
| 29772 zSql = sqlite3_mprintf( | |
| 29773 "CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID", | |
| 29774 azArg[2], zCollist, lenPK, zCollist); | |
| 29775 sqlite3_free(zCollist); | |
| 29776 rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 2, tnum); | |
| 29777 if( rc==SQLITE_OK ){ | |
| 29778 rc = sqlite3_exec(p->db, zSql, 0, 0, 0); | |
| 29779 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0); | |
| 29780 if( rc ){ | |
| 29781 sqlite3_fprintf(stderr, | |
| 29782 "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db)); | |
| 29783 }else{ | |
| 29784 sqlite3_fprintf(stdout, "%s;\n", zSql); | |
| 29785 } | |
| 29786 }else{ | |
| 29787 sqlite3_fprintf(stderr,"SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc); | |
| 29788 rc = 1; | |
| 29789 } | |
| 29790 sqlite3_free(zSql); | |
| 29791 }else | |
| 29792 #endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */ | |
| 29793 | |
| 29794 if( c=='i' && cli_strncmp(azArg[0], "intck", n)==0 ){ | |
| 29795 i64 iArg = 0; | |
| 29796 if( nArg==2 ){ | |
| 29797 iArg = integerValue(azArg[1]); | |
| 29798 if( iArg==0 ) iArg = -1; | |
| 29799 } | |
| 29800 if( (nArg!=1 && nArg!=2) || iArg<0 ){ | |
| 29801 sqlite3_fprintf(stderr,"%s","Usage: .intck STEPS_PER_UNLOCK\n"); | |
| 29802 rc = 1; | |
| 29803 goto meta_command_exit; | |
| 29804 } | |
| 29805 open_db(p, 0); | |
| 29806 rc = intckDatabaseCmd(p, iArg); | |
| 29807 }else | |
| 29808 | |
| 29809 #ifdef SQLITE_ENABLE_IOTRACE | |
| 29810 if( c=='i' && cli_strncmp(azArg[0], "iotrace", n)==0 ){ | |
| 29811 SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...); | |
| 29812 if( iotrace && iotrace!=stdout ) fclose(iotrace); | |
| 29813 iotrace = 0; | |
| 29814 if( nArg<2 ){ | |
| 29815 sqlite3IoTrace = 0; | |
| 29816 }else if( cli_strcmp(azArg[1], "-")==0 ){ | |
| 29817 sqlite3IoTrace = iotracePrintf; | |
| 29818 iotrace = stdout; | |
| 29819 }else{ | |
| 29820 iotrace = sqlite3_fopen(azArg[1], "w"); | |
| 29821 if( iotrace==0 ){ | |
| 29822 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); | |
| 29823 sqlite3IoTrace = 0; | |
| 29824 rc = 1; | |
| 29825 }else{ | |
| 29826 sqlite3IoTrace = iotracePrintf; | |
| 29827 } | |
| 29828 } | |
| 29829 }else | |
| 29830 #endif | |
| 29831 | |
| 29832 if( c=='l' && n>=5 && cli_strncmp(azArg[0], "limits", n)==0 ){ | |
| 29833 static const struct { | |
| 29834 const char *zLimitName; /* Name of a limit */ | |
| 29835 int limitCode; /* Integer code for that limit */ | |
| 29836 } aLimit[] = { | |
| 29837 { "length", SQLITE_LIMIT_LENGTH }, | |
| 29838 { "sql_length", SQLITE_LIMIT_SQL_LENGTH }, | |
| 29839 { "column", SQLITE_LIMIT_COLUMN }, | |
| 29840 { "expr_depth", SQLITE_LIMIT_EXPR_DEPTH }, | |
| 29841 { "compound_select", SQLITE_LIMIT_COMPOUND_SELECT }, | |
| 29842 { "vdbe_op", SQLITE_LIMIT_VDBE_OP }, | |
| 29843 { "function_arg", SQLITE_LIMIT_FUNCTION_ARG }, | |
| 29844 { "attached", SQLITE_LIMIT_ATTACHED }, | |
| 29845 { "like_pattern_length", SQLITE_LIMIT_LIKE_PATTERN_LENGTH }, | |
| 29846 { "variable_number", SQLITE_LIMIT_VARIABLE_NUMBER }, | |
| 29847 { "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH }, | |
| 29848 { "worker_threads", SQLITE_LIMIT_WORKER_THREADS }, | |
| 29849 }; | |
| 29850 int i, n2; | |
| 29851 open_db(p, 0); | |
| 29852 if( nArg==1 ){ | |
| 29853 for(i=0; i<ArraySize(aLimit); i++){ | |
| 29854 sqlite3_fprintf(stdout, "%20s %d\n", aLimit[i].zLimitName, | |
| 29855 sqlite3_limit(p->db, aLimit[i].limitCode, -1)); | |
| 29856 } | |
| 29857 }else if( nArg>3 ){ | |
| 29858 eputz("Usage: .limit NAME ?NEW-VALUE?\n"); | |
| 29859 rc = 1; | |
| 29860 goto meta_command_exit; | |
| 29861 }else{ | |
| 29862 int iLimit = -1; | |
| 29863 n2 = strlen30(azArg[1]); | |
| 29864 for(i=0; i<ArraySize(aLimit); i++){ | |
| 29865 if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){ | |
| 29866 if( iLimit<0 ){ | |
| 29867 iLimit = i; | |
| 29868 }else{ | |
| 29869 sqlite3_fprintf(stderr,"ambiguous limit: \"%s\"\n", azArg[1]); | |
| 29870 rc = 1; | |
| 29871 goto meta_command_exit; | |
| 29872 } | |
| 29873 } | |
| 29874 } | |
| 29875 if( iLimit<0 ){ | |
| 29876 sqlite3_fprintf(stderr,"unknown limit: \"%s\"\n" | |
| 29877 "enter \".limits\" with no arguments for a list.\n", | |
| 29878 azArg[1]); | |
| 29879 rc = 1; | |
| 29880 goto meta_command_exit; | |
| 29881 } | |
| 29882 if( nArg==3 ){ | |
| 29883 sqlite3_limit(p->db, aLimit[iLimit].limitCode, | |
| 29884 (int)integerValue(azArg[2])); | |
| 29885 } | |
| 29886 sqlite3_fprintf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName, | |
| 29887 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1)); | |
| 29888 } | |
| 29889 }else | |
| 29890 | |
| 29891 if( c=='l' && n>2 && cli_strncmp(azArg[0], "lint", n)==0 ){ | |
| 29892 open_db(p, 0); | |
| 29893 lintDotCommand(p, azArg, nArg); | |
| 29894 }else | |
| 29895 | |
| 29896 #if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_FIDDLE) | |
| 29897 if( c=='l' && cli_strncmp(azArg[0], "load", n)==0 ){ | |
| 29898 const char *zFile, *zProc; | |
| 29899 char *zErrMsg = 0; | |
| 29900 failIfSafeMode(p, "cannot run .load in safe mode"); | |
| 29901 if( nArg<2 || azArg[1][0]==0 ){ | |
| 29902 /* Must have a non-empty FILE. (Will not load self.) */ | |
| 29903 eputz("Usage: .load FILE ?ENTRYPOINT?\n"); | |
| 29904 rc = 1; | |
| 29905 goto meta_command_exit; | |
| 29906 } | |
| 29907 zFile = azArg[1]; | |
| 29908 zProc = nArg>=3 ? azArg[2] : 0; | |
| 29909 open_db(p, 0); | |
| 29910 rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg); | |
| 29911 if( rc!=SQLITE_OK ){ | |
| 29912 shellEmitError(zErrMsg); | |
| 29913 sqlite3_free(zErrMsg); | |
| 29914 rc = 1; | |
| 29915 } | |
| 29916 }else | |
| 29917 #endif | |
| 29918 | |
| 29919 if( c=='l' && cli_strncmp(azArg[0], "log", n)==0 ){ | |
| 29920 if( nArg!=2 ){ | |
| 29921 eputz("Usage: .log FILENAME\n"); | |
| 29922 rc = 1; | |
| 29923 }else{ | |
| 29924 const char *zFile = azArg[1]; | |
| 29925 if( p->bSafeMode | |
| 29926 && cli_strcmp(zFile,"on")!=0 | |
| 29927 && cli_strcmp(zFile,"off")!=0 | |
| 29928 ){ | |
| 29929 sputz(stdout, "cannot set .log to anything other" | |
| 29930 " than \"on\" or \"off\"\n"); | |
| 29931 zFile = "off"; | |
| 29932 } | |
| 29933 output_file_close(p->pLog); | |
| 29934 if( cli_strcmp(zFile,"on")==0 ) zFile = "stdout"; | |
| 29935 p->pLog = output_file_open(zFile); | |
| 29936 } | |
| 29937 }else | |
| 29938 | |
| 29939 if( c=='m' && cli_strncmp(azArg[0], "mode", n)==0 ){ | |
| 29940 const char *zMode = 0; | |
| 29941 const char *zTabname = 0; | |
| 29942 int i, n2; | |
| 29943 int chng = 0; /* 0x01: change to cmopts. 0x02: Any other change */ | |
| 29944 ColModeOpts cmOpts = ColModeOpts_default; | |
| 29945 for(i=1; i<nArg; i++){ | |
| 29946 const char *z = azArg[i]; | |
| 29947 if( optionMatch(z,"wrap") && i+1<nArg ){ | |
| 29948 cmOpts.iWrap = integerValue(azArg[++i]); | |
| 29949 chng |= 1; | |
| 29950 }else if( optionMatch(z,"ww") ){ | |
| 29951 cmOpts.bWordWrap = 1; | |
| 29952 chng |= 1; | |
| 29953 }else if( optionMatch(z,"wordwrap") && i+1<nArg ){ | |
| 29954 cmOpts.bWordWrap = (u8)booleanValue(azArg[++i]); | |
| 29955 chng |= 1; | |
| 29956 }else if( optionMatch(z,"quote") ){ | |
| 29957 cmOpts.bQuote = 1; | |
| 29958 chng |= 1; | |
| 29959 }else if( optionMatch(z,"noquote") ){ | |
| 29960 cmOpts.bQuote = 0; | |
| 29961 chng |= 1; | |
| 29962 }else if( optionMatch(z,"escape") && i+1<nArg ){ | |
| 29963 /* See similar code at tag-20250224-1 */ | |
| 29964 const char *zEsc = azArg[++i]; | |
| 29965 int k; | |
| 29966 for(k=0; k<ArraySize(shell_EscModeNames); k++){ | |
| 29967 if( sqlite3_stricmp(zEsc,shell_EscModeNames[k])==0 ){ | |
| 29968 p->eEscMode = k; | |
| 29969 chng |= 2; | |
| 29970 break; | |
| 29971 } | |
| 29972 } | |
| 29973 if( k>=ArraySize(shell_EscModeNames) ){ | |
| 29974 sqlite3_fprintf(stderr, "unknown control character escape mode \"%s\"" | |
| 29975 " - choices:", zEsc); | |
| 29976 for(k=0; k<ArraySize(shell_EscModeNames); k++){ | |
| 29977 sqlite3_fprintf(stderr, " %s", shell_EscModeNames[k]); | |
| 29978 } | |
| 29979 sqlite3_fprintf(stderr, "\n"); | |
| 29980 rc = 1; | |
| 29981 goto meta_command_exit; | |
| 29982 } | |
| 29983 }else if( zMode==0 ){ | |
| 29984 zMode = z; | |
| 29985 /* Apply defaults for qbox pseudo-mode. If that | |
| 29986 * overwrites already-set values, user was informed of this. | |
| 29987 */ | |
| 29988 chng |= 1; | |
| 29989 if( cli_strcmp(z, "qbox")==0 ){ | |
| 29990 ColModeOpts cmo = ColModeOpts_default_qbox; | |
| 29991 zMode = "box"; | |
| 29992 cmOpts = cmo; | |
| 29993 } | |
| 29994 }else if( zTabname==0 ){ | |
| 29995 zTabname = z; | |
| 29996 }else if( z[0]=='-' ){ | |
| 29997 sqlite3_fprintf(stderr,"unknown option: %s\n", z); | |
| 29998 eputz("options:\n" | |
| 29999 " --escape MODE\n" | |
| 30000 " --noquote\n" | |
| 30001 " --quote\n" | |
| 30002 " --wordwrap on/off\n" | |
| 30003 " --wrap N\n" | |
| 30004 " --ww\n"); | |
| 30005 rc = 1; | |
| 30006 goto meta_command_exit; | |
| 30007 }else{ | |
| 30008 sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z); | |
| 30009 rc = 1; | |
| 30010 goto meta_command_exit; | |
| 30011 } | |
| 30012 } | |
| 30013 if( !chng ){ | |
| 30014 if( p->mode==MODE_Column | |
| 30015 || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) | |
| 30016 ){ | |
| 30017 sqlite3_fprintf(p->out, | |
| 30018 "current output mode: %s --wrap %d --wordwrap %s " | |
| 30019 "--%squote --escape %s\n", | |
| 30020 modeDescr[p->mode], p->cmOpts.iWrap, | |
| 30021 p->cmOpts.bWordWrap ? "on" : "off", | |
| 30022 p->cmOpts.bQuote ? "" : "no", | |
| 30023 shell_EscModeNames[p->eEscMode] | |
| 30024 ); | |
| 30025 }else{ | |
| 30026 sqlite3_fprintf(p->out, | |
| 30027 "current output mode: %s --escape %s\n", | |
| 30028 modeDescr[p->mode], | |
| 30029 shell_EscModeNames[p->eEscMode] | |
| 30030 ); | |
| 30031 } | |
| 30032 } | |
| 30033 if( zMode==0 ){ | |
| 30034 zMode = modeDescr[p->mode]; | |
| 30035 if( (chng&1)==0 ) cmOpts = p->cmOpts; | |
| 30036 } | |
| 30037 n2 = strlen30(zMode); | |
| 30038 if( cli_strncmp(zMode,"lines",n2)==0 ){ | |
| 30039 p->mode = MODE_Line; | |
| 30040 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); | |
| 30041 }else if( cli_strncmp(zMode,"columns",n2)==0 ){ | |
| 30042 p->mode = MODE_Column; | |
| 30043 if( (p->shellFlgs & SHFLG_HeaderSet)==0 ){ | |
| 30044 p->showHeader = 1; | |
| 30045 } | |
| 30046 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); | |
| 30047 p->cmOpts = cmOpts; | |
| 30048 }else if( cli_strncmp(zMode,"list",n2)==0 ){ | |
| 30049 p->mode = MODE_List; | |
| 30050 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Column); | |
| 30051 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); | |
| 30052 }else if( cli_strncmp(zMode,"html",n2)==0 ){ | |
| 30053 p->mode = MODE_Html; | |
| 30054 }else if( cli_strncmp(zMode,"tcl",n2)==0 ){ | |
| 30055 p->mode = MODE_Tcl; | |
| 30056 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Space); | |
| 30057 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); | |
| 30058 }else if( cli_strncmp(zMode,"csv",n2)==0 ){ | |
| 30059 p->mode = MODE_Csv; | |
| 30060 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); | |
| 30061 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); | |
| 30062 }else if( cli_strncmp(zMode,"tabs",n2)==0 ){ | |
| 30063 p->mode = MODE_List; | |
| 30064 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Tab); | |
| 30065 }else if( cli_strncmp(zMode,"insert",n2)==0 ){ | |
| 30066 p->mode = MODE_Insert; | |
| 30067 set_table_name(p, zTabname ? zTabname : "table"); | |
| 30068 if( p->eEscMode==SHELL_ESC_OFF ){ | |
| 30069 ShellSetFlag(p, SHFLG_Newlines); | |
| 30070 }else{ | |
| 30071 ShellClearFlag(p, SHFLG_Newlines); | |
| 30072 } | |
| 30073 }else if( cli_strncmp(zMode,"quote",n2)==0 ){ | |
| 30074 p->mode = MODE_Quote; | |
| 30075 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); | |
| 30076 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row); | |
| 30077 }else if( cli_strncmp(zMode,"ascii",n2)==0 ){ | |
| 30078 p->mode = MODE_Ascii; | |
| 30079 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit); | |
| 30080 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record); | |
| 30081 }else if( cli_strncmp(zMode,"markdown",n2)==0 ){ | |
| 30082 p->mode = MODE_Markdown; | |
| 30083 p->cmOpts = cmOpts; | |
| 30084 }else if( cli_strncmp(zMode,"table",n2)==0 ){ | |
| 30085 p->mode = MODE_Table; | |
| 30086 p->cmOpts = cmOpts; | |
| 30087 }else if( cli_strncmp(zMode,"box",n2)==0 ){ | |
| 30088 p->mode = MODE_Box; | |
| 30089 p->cmOpts = cmOpts; | |
| 30090 }else if( cli_strncmp(zMode,"count",n2)==0 ){ | |
| 30091 p->mode = MODE_Count; | |
| 30092 }else if( cli_strncmp(zMode,"off",n2)==0 ){ | |
| 30093 p->mode = MODE_Off; | |
| 30094 }else if( cli_strncmp(zMode,"json",n2)==0 ){ | |
| 30095 p->mode = MODE_Json; | |
| 30096 }else{ | |
| 30097 eputz("Error: mode should be one of: " | |
| 30098 "ascii box column csv html insert json line list markdown " | |
| 30099 "qbox quote table tabs tcl\n"); | |
| 30100 rc = 1; | |
| 30101 } | |
| 30102 p->cMode = p->mode; | |
| 30103 }else | |
| 30104 | |
| 30105 #ifndef SQLITE_SHELL_FIDDLE | |
| 30106 if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){ | |
| 30107 if( nArg!=2 ){ | |
| 30108 eputz("Usage: .nonce NONCE\n"); | |
| 30109 rc = 1; | |
| 30110 }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){ | |
| 30111 sqlite3_fprintf(stderr,"line %lld: incorrect nonce: \"%s\"\n", | |
| 30112 p->lineno, azArg[1]); | |
| 30113 exit(1); | |
| 30114 }else{ | |
| 30115 p->bSafeMode = 0; | |
| 30116 return 0; /* Return immediately to bypass the safe mode reset | |
| 30117 ** at the end of this procedure */ | |
| 30118 } | |
| 30119 }else | |
| 30120 #endif /* !defined(SQLITE_SHELL_FIDDLE) */ | |
| 30121 | |
| 30122 if( c=='n' && cli_strncmp(azArg[0], "nullvalue", n)==0 ){ | |
| 30123 if( nArg==2 ){ | |
| 30124 sqlite3_snprintf(sizeof(p->nullValue), p->nullValue, | |
| 30125 "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]); | |
| 30126 }else{ | |
| 30127 eputz("Usage: .nullvalue STRING\n"); | |
| 30128 rc = 1; | |
| 30129 } | |
| 30130 }else | |
| 30131 | |
| 30132 if( c=='o' && cli_strncmp(azArg[0], "open", n)==0 && n>=2 ){ | |
| 30133 const char *zFN = 0; /* Pointer to constant filename */ | |
| 30134 char *zNewFilename = 0; /* Name of the database file to open */ | |
| 30135 int iName = 1; /* Index in azArg[] of the filename */ | |
| 30136 int newFlag = 0; /* True to delete file before opening */ | |
| 30137 int openMode = SHELL_OPEN_UNSPEC; | |
| 30138 int openFlags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; | |
| 30139 | |
| 30140 /* Check for command-line arguments */ | |
| 30141 for(iName=1; iName<nArg; iName++){ | |
| 30142 const char *z = azArg[iName]; | |
| 30143 #ifndef SQLITE_SHELL_FIDDLE | |
| 30144 if( optionMatch(z,"new") ){ | |
| 30145 newFlag = 1; | |
| 30146 #ifdef SQLITE_HAVE_ZLIB | |
| 30147 }else if( optionMatch(z, "zip") ){ | |
| 30148 openMode = SHELL_OPEN_ZIPFILE; | |
| 30149 #endif | |
| 30150 }else if( optionMatch(z, "append") ){ | |
| 30151 openMode = SHELL_OPEN_APPENDVFS; | |
| 30152 }else if( optionMatch(z, "readonly") ){ | |
| 30153 openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); | |
| 30154 openFlags |= SQLITE_OPEN_READONLY; | |
| 30155 }else if( optionMatch(z, "exclusive") ){ | |
| 30156 openFlags |= SQLITE_OPEN_EXCLUSIVE; | |
| 30157 }else if( optionMatch(z, "ifexists") ){ | |
| 30158 openFlags &= ~(SQLITE_OPEN_CREATE); | |
| 30159 }else if( optionMatch(z, "nofollow") ){ | |
| 30160 openFlags |= SQLITE_OPEN_NOFOLLOW; | |
| 30161 #ifndef SQLITE_OMIT_DESERIALIZE | |
| 30162 }else if( optionMatch(z, "deserialize") ){ | |
| 30163 openMode = SHELL_OPEN_DESERIALIZE; | |
| 30164 }else if( optionMatch(z, "hexdb") ){ | |
| 30165 openMode = SHELL_OPEN_HEXDB; | |
| 30166 }else if( optionMatch(z, "normal") ){ | |
| 30167 openMode = SHELL_OPEN_NORMAL; | |
| 30168 }else if( optionMatch(z, "maxsize") && iName+1<nArg ){ | |
| 30169 p->szMax = integerValue(azArg[++iName]); | |
| 30170 #endif /* SQLITE_OMIT_DESERIALIZE */ | |
| 30171 }else | |
| 30172 #endif /* !SQLITE_SHELL_FIDDLE */ | |
| 30173 if( z[0]=='-' ){ | |
| 30174 sqlite3_fprintf(stderr,"unknown option: %s\n", z); | |
| 30175 rc = 1; | |
| 30176 goto meta_command_exit; | |
| 30177 }else if( zFN ){ | |
| 30178 sqlite3_fprintf(stderr,"extra argument: \"%s\"\n", z); | |
| 30179 rc = 1; | |
| 30180 goto meta_command_exit; | |
| 30181 }else{ | |
| 30182 zFN = z; | |
| 30183 } | |
| 30184 } | |
| 30185 | |
| 30186 /* Close the existing database */ | |
| 30187 session_close_all(p, -1); | |
| 30188 close_db(p->db); | |
| 30189 p->db = 0; | |
| 30190 p->pAuxDb->zDbFilename = 0; | |
| 30191 sqlite3_free(p->pAuxDb->zFreeOnClose); | |
| 30192 p->pAuxDb->zFreeOnClose = 0; | |
| 30193 p->openMode = openMode; | |
| 30194 p->openFlags = openFlags; | |
| 30195 p->szMax = 0; | |
| 30196 | |
| 30197 /* If a filename is specified, try to open it first */ | |
| 30198 if( zFN || p->openMode==SHELL_OPEN_HEXDB ){ | |
| 30199 if( newFlag && zFN && !p->bSafeMode ){ | |
| 30200 if( cli_strncmp(zFN,"file:",5)==0 ){ | |
| 30201 char *zDel = shellFilenameFromUri(zFN); | |
| 30202 shell_check_oom(zDel); | |
| 30203 shellDeleteFile(zDel); | |
| 30204 sqlite3_free(zDel); | |
| 30205 }else{ | |
| 30206 shellDeleteFile(zFN); | |
| 30207 } | |
| 30208 } | |
| 30209 #ifndef SQLITE_SHELL_FIDDLE | |
| 30210 if( p->bSafeMode | |
| 30211 && p->openMode!=SHELL_OPEN_HEXDB | |
| 30212 && zFN | |
| 30213 && cli_strcmp(zFN,":memory:")!=0 | |
| 30214 ){ | |
| 30215 failIfSafeMode(p, "cannot open disk-based database files in safe mode"); | |
| 30216 } | |
| 30217 #else | |
| 30218 /* WASM mode has its own sandboxed pseudo-filesystem. */ | |
| 30219 #endif | |
| 30220 if( zFN ){ | |
| 30221 zNewFilename = sqlite3_mprintf("%s", zFN); | |
| 30222 shell_check_oom(zNewFilename); | |
| 30223 }else{ | |
| 30224 zNewFilename = 0; | |
| 30225 } | |
| 30226 p->pAuxDb->zDbFilename = zNewFilename; | |
| 30227 open_db(p, OPEN_DB_KEEPALIVE); | |
| 30228 if( p->db==0 ){ | |
| 30229 sqlite3_fprintf(stderr,"Error: cannot open '%s'\n", zNewFilename); | |
| 30230 sqlite3_free(zNewFilename); | |
| 30231 }else{ | |
| 30232 p->pAuxDb->zFreeOnClose = zNewFilename; | |
| 30233 } | |
| 30234 } | |
| 30235 if( p->db==0 ){ | |
| 30236 /* As a fall-back open a TEMP database */ | |
| 30237 p->pAuxDb->zDbFilename = 0; | |
| 30238 open_db(p, 0); | |
| 30239 } | |
| 30240 }else | |
| 30241 | |
| 30242 #ifndef SQLITE_SHELL_FIDDLE | |
| 30243 if( (c=='o' | |
| 30244 && (cli_strncmp(azArg[0], "output", n)==0 | |
| 30245 || cli_strncmp(azArg[0], "once", n)==0)) | |
| 30246 || (c=='e' && n==5 && cli_strcmp(azArg[0],"excel")==0) | |
| 30247 || (c=='w' && n==3 && cli_strcmp(azArg[0],"www")==0) | |
| 30248 ){ | |
| 30249 char *zFile = 0; | |
| 30250 int i; | |
| 30251 int eMode = 0; /* 0: .outout/.once, 'x'=.excel, 'w'=.www */ | |
| 30252 int bOnce = 0; /* 0: .output, 1: .once, 2: .excel/.www */ | |
| 30253 int bPlain = 0; /* --plain option */ | |
| 30254 static const char *zBomUtf8 = "\357\273\277"; | |
| 30255 const char *zBom = 0; | |
| 30256 | |
| 30257 failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]); | |
| 30258 if( c=='e' ){ | |
| 30259 eMode = 'x'; | |
| 30260 bOnce = 2; | |
| 30261 }else if( c=='w' ){ | |
| 30262 eMode = 'w'; | |
| 30263 bOnce = 2; | |
| 30264 }else if( cli_strncmp(azArg[0],"once",n)==0 ){ | |
| 30265 bOnce = 1; | |
| 30266 } | |
| 30267 for(i=1; i<nArg; i++){ | |
| 30268 char *z = azArg[i]; | |
| 30269 if( z[0]=='-' ){ | |
| 30270 if( z[1]=='-' ) z++; | |
| 30271 if( cli_strcmp(z,"-bom")==0 ){ | |
| 30272 zBom = zBomUtf8; | |
| 30273 }else if( cli_strcmp(z,"-plain")==0 ){ | |
| 30274 bPlain = 1; | |
| 30275 }else if( c=='o' && cli_strcmp(z,"-x")==0 ){ | |
| 30276 eMode = 'x'; /* spreadsheet */ | |
| 30277 }else if( c=='o' && cli_strcmp(z,"-e")==0 ){ | |
| 30278 eMode = 'e'; /* text editor */ | |
| 30279 }else if( c=='o' && cli_strcmp(z,"-w")==0 ){ | |
| 30280 eMode = 'w'; /* Web browser */ | |
| 30281 }else{ | |
| 30282 sqlite3_fprintf(p->out, | |
| 30283 "ERROR: unknown option: \"%s\". Usage:\n", azArg[i]); | |
| 30284 showHelp(p->out, azArg[0]); | |
| 30285 rc = 1; | |
| 30286 sqlite3_free(zFile); | |
| 30287 goto meta_command_exit; | |
| 30288 } | |
| 30289 }else if( zFile==0 && eMode==0 ){ | |
| 30290 if( cli_strcmp(z, "off")==0 ){ | |
| 30291 #ifdef _WIN32 | |
| 30292 zFile = sqlite3_mprintf("nul"); | |
| 30293 #else | |
| 30294 zFile = sqlite3_mprintf("/dev/null"); | |
| 30295 #endif | |
| 30296 }else{ | |
| 30297 zFile = sqlite3_mprintf("%s", z); | |
| 30298 } | |
| 30299 if( zFile && zFile[0]=='|' ){ | |
| 30300 while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]); | |
| 30301 break; | |
| 30302 } | |
| 30303 }else{ | |
| 30304 sqlite3_fprintf(p->out, | |
| 30305 "ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]); | |
| 30306 showHelp(p->out, azArg[0]); | |
| 30307 rc = 1; | |
| 30308 sqlite3_free(zFile); | |
| 30309 goto meta_command_exit; | |
| 30310 } | |
| 30311 } | |
| 30312 if( zFile==0 ){ | |
| 30313 zFile = sqlite3_mprintf("stdout"); | |
| 30314 } | |
| 30315 shell_check_oom(zFile); | |
| 30316 if( bOnce ){ | |
| 30317 p->outCount = 2; | |
| 30318 }else{ | |
| 30319 p->outCount = 0; | |
| 30320 } | |
| 30321 output_reset(p); | |
| 30322 #ifndef SQLITE_NOHAVE_SYSTEM | |
| 30323 if( eMode=='e' || eMode=='x' || eMode=='w' ){ | |
| 30324 p->doXdgOpen = 1; | |
| 30325 outputModePush(p); | |
| 30326 if( eMode=='x' ){ | |
| 30327 /* spreadsheet mode. Output as CSV. */ | |
| 30328 newTempFile(p, "csv"); | |
| 30329 ShellClearFlag(p, SHFLG_Echo); | |
| 30330 p->mode = MODE_Csv; | |
| 30331 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma); | |
| 30332 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf); | |
| 30333 #ifdef _WIN32 | |
| 30334 zBom = zBomUtf8; /* Always include the BOM on Windows, as Excel does | |
| 30335 ** not work without it. */ | |
| 30336 #endif | |
| 30337 }else if( eMode=='w' ){ | |
| 30338 /* web-browser mode. */ | |
| 30339 newTempFile(p, "html"); | |
| 30340 if( !bPlain ) p->mode = MODE_Www; | |
| 30341 }else{ | |
| 30342 /* text editor mode */ | |
| 30343 newTempFile(p, "txt"); | |
| 30344 } | |
| 30345 sqlite3_free(zFile); | |
| 30346 zFile = sqlite3_mprintf("%s", p->zTempFile); | |
| 30347 } | |
| 30348 #endif /* SQLITE_NOHAVE_SYSTEM */ | |
| 30349 shell_check_oom(zFile); | |
| 30350 if( zFile[0]=='|' ){ | |
| 30351 #ifdef SQLITE_OMIT_POPEN | |
| 30352 eputz("Error: pipes are not supported in this OS\n"); | |
| 30353 rc = 1; | |
| 30354 output_redir(p, stdout); | |
| 30355 #else | |
| 30356 FILE *pfPipe = sqlite3_popen(zFile + 1, "w"); | |
| 30357 if( pfPipe==0 ){ | |
| 30358 assert( stderr!=NULL ); | |
| 30359 sqlite3_fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1); | |
| 30360 rc = 1; | |
| 30361 }else{ | |
| 30362 output_redir(p, pfPipe); | |
| 30363 if( zBom ) sqlite3_fputs(zBom, pfPipe); | |
| 30364 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); | |
| 30365 } | |
| 30366 #endif | |
| 30367 }else{ | |
| 30368 FILE *pfFile = output_file_open(zFile); | |
| 30369 if( pfFile==0 ){ | |
| 30370 if( cli_strcmp(zFile,"off")!=0 ){ | |
| 30371 assert( stderr!=NULL ); | |
| 30372 sqlite3_fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile); | |
| 30373 } | |
| 30374 rc = 1; | |
| 30375 } else { | |
| 30376 output_redir(p, pfFile); | |
| 30377 if( zBom ) sqlite3_fputs(zBom, pfFile); | |
| 30378 if( bPlain && eMode=='w' ){ | |
| 30379 sqlite3_fputs( | |
| 30380 "<!DOCTYPE html>\n<BODY>\n<PLAINTEXT>\n", | |
| 30381 pfFile | |
| 30382 ); | |
| 30383 } | |
| 30384 sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); | |
| 30385 } | |
| 30386 } | |
| 30387 sqlite3_free(zFile); | |
| 30388 }else | |
| 30389 #endif /* !defined(SQLITE_SHELL_FIDDLE) */ | |
| 30390 | |
| 30391 if( c=='p' && n>=3 && cli_strncmp(azArg[0], "parameter", n)==0 ){ | |
| 30392 open_db(p,0); | |
| 30393 if( nArg<=1 ) goto parameter_syntax_error; | |
| 30394 | |
| 30395 /* .parameter clear | |
| 30396 ** Clear all bind parameters by dropping the TEMP table that holds them. | |
| 30397 */ | |
| 30398 if( nArg==2 && cli_strcmp(azArg[1],"clear")==0 ){ | |
| 30399 sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;", | |
| 30400 0, 0, 0); | |
| 30401 }else | |
| 30402 | |
| 30403 /* .parameter list | |
| 30404 ** List all bind parameters. | |
| 30405 */ | |
| 30406 if( nArg==2 && cli_strcmp(azArg[1],"list")==0 ){ | |
| 30407 sqlite3_stmt *pStmt = 0; | |
| 30408 int rx; | |
| 30409 int len = 0; | |
| 30410 rx = sqlite3_prepare_v2(p->db, | |
| 30411 "SELECT max(length(key)) " | |
| 30412 "FROM temp.sqlite_parameters;", -1, &pStmt, 0); | |
| 30413 if( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 30414 len = sqlite3_column_int(pStmt, 0); | |
| 30415 if( len>40 ) len = 40; | |
| 30416 } | |
| 30417 sqlite3_finalize(pStmt); | |
| 30418 pStmt = 0; | |
| 30419 if( len ){ | |
| 30420 rx = sqlite3_prepare_v2(p->db, | |
| 30421 "SELECT key, quote(value) " | |
| 30422 "FROM temp.sqlite_parameters;", -1, &pStmt, 0); | |
| 30423 while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 30424 sqlite3_fprintf(p->out, | |
| 30425 "%-*s %s\n", len, sqlite3_column_text(pStmt,0), | |
| 30426 sqlite3_column_text(pStmt,1)); | |
| 30427 } | |
| 30428 sqlite3_finalize(pStmt); | |
| 30429 } | |
| 30430 }else | |
| 30431 | |
| 30432 /* .parameter init | |
| 30433 ** Make sure the TEMP table used to hold bind parameters exists. | |
| 30434 ** Create it if necessary. | |
| 30435 */ | |
| 30436 if( nArg==2 && cli_strcmp(azArg[1],"init")==0 ){ | |
| 30437 bind_table_init(p); | |
| 30438 }else | |
| 30439 | |
| 30440 /* .parameter set NAME VALUE | |
| 30441 ** Set or reset a bind parameter. NAME should be the full parameter | |
| 30442 ** name exactly as it appears in the query. (ex: $abc, @def). The | |
| 30443 ** VALUE can be in either SQL literal notation, or if not it will be | |
| 30444 ** understood to be a text string. | |
| 30445 */ | |
| 30446 if( nArg==4 && cli_strcmp(azArg[1],"set")==0 ){ | |
| 30447 int rx; | |
| 30448 char *zSql; | |
| 30449 sqlite3_stmt *pStmt; | |
| 30450 const char *zKey = azArg[2]; | |
| 30451 const char *zValue = azArg[3]; | |
| 30452 bind_table_init(p); | |
| 30453 zSql = sqlite3_mprintf( | |
| 30454 "REPLACE INTO temp.sqlite_parameters(key,value)" | |
| 30455 "VALUES(%Q,%s);", zKey, zValue); | |
| 30456 shell_check_oom(zSql); | |
| 30457 pStmt = 0; | |
| 30458 rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); | |
| 30459 sqlite3_free(zSql); | |
| 30460 if( rx!=SQLITE_OK ){ | |
| 30461 sqlite3_finalize(pStmt); | |
| 30462 pStmt = 0; | |
| 30463 zSql = sqlite3_mprintf( | |
| 30464 "REPLACE INTO temp.sqlite_parameters(key,value)" | |
| 30465 "VALUES(%Q,%Q);", zKey, zValue); | |
| 30466 shell_check_oom(zSql); | |
| 30467 rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); | |
| 30468 sqlite3_free(zSql); | |
| 30469 if( rx!=SQLITE_OK ){ | |
| 30470 sqlite3_fprintf(p->out, "Error: %s\n", sqlite3_errmsg(p->db)); | |
| 30471 sqlite3_finalize(pStmt); | |
| 30472 pStmt = 0; | |
| 30473 rc = 1; | |
| 30474 } | |
| 30475 } | |
| 30476 bind_prepared_stmt(p, pStmt); | |
| 30477 sqlite3_step(pStmt); | |
| 30478 sqlite3_finalize(pStmt); | |
| 30479 }else | |
| 30480 | |
| 30481 /* .parameter unset NAME | |
| 30482 ** Remove the NAME binding from the parameter binding table, if it | |
| 30483 ** exists. | |
| 30484 */ | |
| 30485 if( nArg==3 && cli_strcmp(azArg[1],"unset")==0 ){ | |
| 30486 char *zSql = sqlite3_mprintf( | |
| 30487 "DELETE FROM temp.sqlite_parameters WHERE key=%Q", azArg[2]); | |
| 30488 shell_check_oom(zSql); | |
| 30489 sqlite3_exec(p->db, zSql, 0, 0, 0); | |
| 30490 sqlite3_free(zSql); | |
| 30491 }else | |
| 30492 /* If no command name matches, show a syntax error */ | |
| 30493 parameter_syntax_error: | |
| 30494 showHelp(p->out, "parameter"); | |
| 30495 }else | |
| 30496 | |
| 30497 if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print", n)==0 ){ | |
| 30498 int i; | |
| 30499 for(i=1; i<nArg; i++){ | |
| 30500 if( i>1 ) sqlite3_fputs(" ", p->out); | |
| 30501 sqlite3_fputs(azArg[i], p->out); | |
| 30502 } | |
| 30503 sqlite3_fputs("\n", p->out); | |
| 30504 }else | |
| 30505 | |
| 30506 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK | |
| 30507 if( c=='p' && n>=3 && cli_strncmp(azArg[0], "progress", n)==0 ){ | |
| 30508 int i; | |
| 30509 int nn = 0; | |
| 30510 p->flgProgress = 0; | |
| 30511 p->mxProgress = 0; | |
| 30512 p->nProgress = 0; | |
| 30513 for(i=1; i<nArg; i++){ | |
| 30514 const char *z = azArg[i]; | |
| 30515 if( z[0]=='-' ){ | |
| 30516 z++; | |
| 30517 if( z[0]=='-' ) z++; | |
| 30518 if( cli_strcmp(z,"quiet")==0 || cli_strcmp(z,"q")==0 ){ | |
| 30519 p->flgProgress |= SHELL_PROGRESS_QUIET; | |
| 30520 continue; | |
| 30521 } | |
| 30522 if( cli_strcmp(z,"reset")==0 ){ | |
| 30523 p->flgProgress |= SHELL_PROGRESS_RESET; | |
| 30524 continue; | |
| 30525 } | |
| 30526 if( cli_strcmp(z,"once")==0 ){ | |
| 30527 p->flgProgress |= SHELL_PROGRESS_ONCE; | |
| 30528 continue; | |
| 30529 } | |
| 30530 if( cli_strcmp(z,"limit")==0 ){ | |
| 30531 if( i+1>=nArg ){ | |
| 30532 eputz("Error: missing argument on --limit\n"); | |
| 30533 rc = 1; | |
| 30534 goto meta_command_exit; | |
| 30535 }else{ | |
| 30536 p->mxProgress = (int)integerValue(azArg[++i]); | |
| 30537 } | |
| 30538 continue; | |
| 30539 } | |
| 30540 sqlite3_fprintf(stderr,"Error: unknown option: \"%s\"\n", azArg[i]); | |
| 30541 rc = 1; | |
| 30542 goto meta_command_exit; | |
| 30543 }else{ | |
| 30544 nn = (int)integerValue(z); | |
| 30545 } | |
| 30546 } | |
| 30547 open_db(p, 0); | |
| 30548 sqlite3_progress_handler(p->db, nn, progress_handler, p); | |
| 30549 }else | |
| 30550 #endif /* SQLITE_OMIT_PROGRESS_CALLBACK */ | |
| 30551 | |
| 30552 if( c=='p' && cli_strncmp(azArg[0], "prompt", n)==0 ){ | |
| 30553 if( nArg >= 2) { | |
| 30554 shell_strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1); | |
| 30555 } | |
| 30556 if( nArg >= 3) { | |
| 30557 shell_strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1); | |
| 30558 } | |
| 30559 }else | |
| 30560 | |
| 30561 #ifndef SQLITE_SHELL_FIDDLE | |
| 30562 if( c=='q' && cli_strncmp(azArg[0], "quit", n)==0 ){ | |
| 30563 rc = 2; | |
| 30564 }else | |
| 30565 #endif | |
| 30566 | |
| 30567 #ifndef SQLITE_SHELL_FIDDLE | |
| 30568 if( c=='r' && n>=3 && cli_strncmp(azArg[0], "read", n)==0 ){ | |
| 30569 FILE *inSaved = p->in; | |
| 30570 i64 savedLineno = p->lineno; | |
| 30571 failIfSafeMode(p, "cannot run .read in safe mode"); | |
| 30572 if( nArg!=2 ){ | |
| 30573 eputz("Usage: .read FILE\n"); | |
| 30574 rc = 1; | |
| 30575 goto meta_command_exit; | |
| 30576 } | |
| 30577 if( azArg[1][0]=='|' ){ | |
| 30578 #ifdef SQLITE_OMIT_POPEN | |
| 30579 eputz("Error: pipes are not supported in this OS\n"); | |
| 30580 rc = 1; | |
| 30581 #else | |
| 30582 p->in = sqlite3_popen(azArg[1]+1, "r"); | |
| 30583 if( p->in==0 ){ | |
| 30584 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); | |
| 30585 rc = 1; | |
| 30586 }else{ | |
| 30587 rc = process_input(p, "<pipe>"); | |
| 30588 pclose(p->in); | |
| 30589 } | |
| 30590 #endif | |
| 30591 }else if( (p->in = openChrSource(azArg[1]))==0 ){ | |
| 30592 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); | |
| 30593 rc = 1; | |
| 30594 }else{ | |
| 30595 rc = process_input(p, azArg[1]); | |
| 30596 fclose(p->in); | |
| 30597 } | |
| 30598 p->in = inSaved; | |
| 30599 p->lineno = savedLineno; | |
| 30600 }else | |
| 30601 #endif /* !defined(SQLITE_SHELL_FIDDLE) */ | |
| 30602 | |
| 30603 #ifndef SQLITE_SHELL_FIDDLE | |
| 30604 if( c=='r' && n>=3 && cli_strncmp(azArg[0], "restore", n)==0 ){ | |
| 30605 const char *zSrcFile; | |
| 30606 const char *zDb; | |
| 30607 sqlite3 *pSrc; | |
| 30608 sqlite3_backup *pBackup; | |
| 30609 int nTimeout = 0; | |
| 30610 | |
| 30611 failIfSafeMode(p, "cannot run .restore in safe mode"); | |
| 30612 if( nArg==2 ){ | |
| 30613 zSrcFile = azArg[1]; | |
| 30614 zDb = "main"; | |
| 30615 }else if( nArg==3 ){ | |
| 30616 zSrcFile = azArg[2]; | |
| 30617 zDb = azArg[1]; | |
| 30618 }else{ | |
| 30619 eputz("Usage: .restore ?DB? FILE\n"); | |
| 30620 rc = 1; | |
| 30621 goto meta_command_exit; | |
| 30622 } | |
| 30623 rc = sqlite3_open(zSrcFile, &pSrc); | |
| 30624 if( rc!=SQLITE_OK ){ | |
| 30625 sqlite3_fprintf(stderr,"Error: cannot open \"%s\"\n", zSrcFile); | |
| 30626 close_db(pSrc); | |
| 30627 return 1; | |
| 30628 } | |
| 30629 open_db(p, 0); | |
| 30630 pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main"); | |
| 30631 if( pBackup==0 ){ | |
| 30632 shellDatabaseError(p->db); | |
| 30633 close_db(pSrc); | |
| 30634 return 1; | |
| 30635 } | |
| 30636 while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK | |
| 30637 || rc==SQLITE_BUSY ){ | |
| 30638 if( rc==SQLITE_BUSY ){ | |
| 30639 if( nTimeout++ >= 3 ) break; | |
| 30640 sqlite3_sleep(100); | |
| 30641 } | |
| 30642 } | |
| 30643 sqlite3_backup_finish(pBackup); | |
| 30644 if( rc==SQLITE_DONE ){ | |
| 30645 rc = 0; | |
| 30646 }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){ | |
| 30647 eputz("Error: source database is busy\n"); | |
| 30648 rc = 1; | |
| 30649 }else{ | |
| 30650 shellDatabaseError(p->db); | |
| 30651 rc = 1; | |
| 30652 } | |
| 30653 close_db(pSrc); | |
| 30654 }else | |
| 30655 #endif /* !defined(SQLITE_SHELL_FIDDLE) */ | |
| 30656 | |
| 30657 if( c=='s' && | |
| 30658 (cli_strncmp(azArg[0], "scanstats", n)==0 || | |
| 30659 cli_strncmp(azArg[0], "scanstatus", n)==0) | |
| 30660 ){ | |
| 30661 if( nArg==2 ){ | |
| 30662 if( cli_strcmp(azArg[1], "vm")==0 ){ | |
| 30663 p->scanstatsOn = 3; | |
| 30664 }else | |
| 30665 if( cli_strcmp(azArg[1], "est")==0 ){ | |
| 30666 p->scanstatsOn = 2; | |
| 30667 }else{ | |
| 30668 p->scanstatsOn = (u8)booleanValue(azArg[1]); | |
| 30669 } | |
| 30670 open_db(p, 0); | |
| 30671 sqlite3_db_config( | |
| 30672 p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0 | |
| 30673 ); | |
| 30674 #if !defined(SQLITE_ENABLE_STMT_SCANSTATUS) | |
| 30675 eputz("Warning: .scanstats not available in this build.\n"); | |
| 30676 #elif !defined(SQLITE_ENABLE_BYTECODE_VTAB) | |
| 30677 if( p->scanstatsOn==3 ){ | |
| 30678 eputz("Warning: \".scanstats vm\" not available in this build.\n"); | |
| 30679 } | |
| 30680 #endif | |
| 30681 }else{ | |
| 30682 eputz("Usage: .scanstats on|off|est\n"); | |
| 30683 rc = 1; | |
| 30684 } | |
| 30685 }else | |
| 30686 | |
| 30687 if( c=='s' && cli_strncmp(azArg[0], "schema", n)==0 ){ | |
| 30688 ShellText sSelect; | |
| 30689 ShellState data; | |
| 30690 char *zErrMsg = 0; | |
| 30691 const char *zDiv = "("; | |
| 30692 const char *zName = 0; | |
| 30693 int iSchema = 0; | |
| 30694 int bDebug = 0; | |
| 30695 int bNoSystemTabs = 0; | |
| 30696 int ii; | |
| 30697 | |
| 30698 open_db(p, 0); | |
| 30699 memcpy(&data, p, sizeof(data)); | |
| 30700 data.showHeader = 0; | |
| 30701 data.cMode = data.mode = MODE_Semi; | |
| 30702 initText(&sSelect); | |
| 30703 for(ii=1; ii<nArg; ii++){ | |
| 30704 if( optionMatch(azArg[ii],"indent") ){ | |
| 30705 data.cMode = data.mode = MODE_Pretty; | |
| 30706 }else if( optionMatch(azArg[ii],"debug") ){ | |
| 30707 bDebug = 1; | |
| 30708 }else if( optionMatch(azArg[ii],"nosys") ){ | |
| 30709 bNoSystemTabs = 1; | |
| 30710 }else if( azArg[ii][0]=='-' ){ | |
| 30711 sqlite3_fprintf(stderr,"Unknown option: \"%s\"\n", azArg[ii]); | |
| 30712 rc = 1; | |
| 30713 goto meta_command_exit; | |
| 30714 }else if( zName==0 ){ | |
| 30715 zName = azArg[ii]; | |
| 30716 }else{ | |
| 30717 eputz("Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n"); | |
| 30718 rc = 1; | |
| 30719 goto meta_command_exit; | |
| 30720 } | |
| 30721 } | |
| 30722 if( zName!=0 ){ | |
| 30723 int isSchema = sqlite3_strlike(zName, "sqlite_master", '\\')==0 | |
| 30724 || sqlite3_strlike(zName, "sqlite_schema", '\\')==0 | |
| 30725 || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0 | |
| 30726 || sqlite3_strlike(zName,"sqlite_temp_schema", '\\')==0; | |
| 30727 if( isSchema ){ | |
| 30728 char *new_argv[2], *new_colv[2]; | |
| 30729 new_argv[0] = sqlite3_mprintf( | |
| 30730 "CREATE TABLE %s (\n" | |
| 30731 " type text,\n" | |
| 30732 " name text,\n" | |
| 30733 " tbl_name text,\n" | |
| 30734 " rootpage integer,\n" | |
| 30735 " sql text\n" | |
| 30736 ")", zName); | |
| 30737 shell_check_oom(new_argv[0]); | |
| 30738 new_argv[1] = 0; | |
| 30739 new_colv[0] = "sql"; | |
| 30740 new_colv[1] = 0; | |
| 30741 callback(&data, 1, new_argv, new_colv); | |
| 30742 sqlite3_free(new_argv[0]); | |
| 30743 } | |
| 30744 } | |
| 30745 if( zDiv ){ | |
| 30746 sqlite3_stmt *pStmt = 0; | |
| 30747 rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list", | |
| 30748 -1, &pStmt, 0); | |
| 30749 if( rc ){ | |
| 30750 shellDatabaseError(p->db); | |
| 30751 sqlite3_finalize(pStmt); | |
| 30752 rc = 1; | |
| 30753 goto meta_command_exit; | |
| 30754 } | |
| 30755 appendText(&sSelect, "SELECT sql FROM", 0); | |
| 30756 iSchema = 0; | |
| 30757 while( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 30758 const char *zDb = (const char*)sqlite3_column_text(pStmt, 0); | |
| 30759 char zScNum[30]; | |
| 30760 sqlite3_snprintf(sizeof(zScNum), zScNum, "%d", ++iSchema); | |
| 30761 appendText(&sSelect, zDiv, 0); | |
| 30762 zDiv = " UNION ALL "; | |
| 30763 appendText(&sSelect, "SELECT shell_add_schema(sql,", 0); | |
| 30764 if( sqlite3_stricmp(zDb, "main")!=0 ){ | |
| 30765 appendText(&sSelect, zDb, '\''); | |
| 30766 }else{ | |
| 30767 appendText(&sSelect, "NULL", 0); | |
| 30768 } | |
| 30769 appendText(&sSelect, ",name) AS sql, type, tbl_name, name, rowid,", 0); | |
| 30770 appendText(&sSelect, zScNum, 0); | |
| 30771 appendText(&sSelect, " AS snum, ", 0); | |
| 30772 appendText(&sSelect, zDb, '\''); | |
| 30773 appendText(&sSelect, " AS sname FROM ", 0); | |
| 30774 appendText(&sSelect, zDb, quoteChar(zDb)); | |
| 30775 appendText(&sSelect, ".sqlite_schema", 0); | |
| 30776 } | |
| 30777 sqlite3_finalize(pStmt); | |
| 30778 #ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS | |
| 30779 if( zName ){ | |
| 30780 appendText(&sSelect, | |
| 30781 " UNION ALL SELECT shell_module_schema(name)," | |
| 30782 " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", | |
| 30783 0); | |
| 30784 } | |
| 30785 #endif | |
| 30786 appendText(&sSelect, ") WHERE ", 0); | |
| 30787 if( zName ){ | |
| 30788 char *zQarg = sqlite3_mprintf("%Q", zName); | |
| 30789 int bGlob; | |
| 30790 shell_check_oom(zQarg); | |
| 30791 bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 || | |
| 30792 strchr(zName, '[') != 0; | |
| 30793 if( strchr(zName, '.') ){ | |
| 30794 appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0); | |
| 30795 }else{ | |
| 30796 appendText(&sSelect, "lower(tbl_name)", 0); | |
| 30797 } | |
| 30798 appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0); | |
| 30799 appendText(&sSelect, zQarg, 0); | |
| 30800 if( !bGlob ){ | |
| 30801 appendText(&sSelect, " ESCAPE '\\' ", 0); | |
| 30802 } | |
| 30803 appendText(&sSelect, " AND ", 0); | |
| 30804 sqlite3_free(zQarg); | |
| 30805 } | |
| 30806 if( bNoSystemTabs ){ | |
| 30807 appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0); | |
| 30808 } | |
| 30809 appendText(&sSelect, "sql IS NOT NULL" | |
| 30810 " ORDER BY snum, rowid", 0); | |
| 30811 if( bDebug ){ | |
| 30812 sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.zTxt); | |
| 30813 }else{ | |
| 30814 rc = sqlite3_exec(p->db, sSelect.zTxt, callback, &data, &zErrMsg); | |
| 30815 } | |
| 30816 freeText(&sSelect); | |
| 30817 } | |
| 30818 if( zErrMsg ){ | |
| 30819 shellEmitError(zErrMsg); | |
| 30820 sqlite3_free(zErrMsg); | |
| 30821 rc = 1; | |
| 30822 }else if( rc != SQLITE_OK ){ | |
| 30823 eputz("Error: querying schema information\n"); | |
| 30824 rc = 1; | |
| 30825 }else{ | |
| 30826 rc = 0; | |
| 30827 } | |
| 30828 }else | |
| 30829 | |
| 30830 if( (c=='s' && n==11 && cli_strncmp(azArg[0], "selecttrace", n)==0) | |
| 30831 || (c=='t' && n==9 && cli_strncmp(azArg[0], "treetrace", n)==0) | |
| 30832 ){ | |
| 30833 unsigned int x = nArg>=2? (unsigned int)integerValue(azArg[1]) : 0xffffffff; | |
| 30834 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x); | |
| 30835 }else | |
| 30836 | |
| 30837 #if defined(SQLITE_ENABLE_SESSION) | |
| 30838 if( c=='s' && cli_strncmp(azArg[0],"session",n)==0 && n>=3 ){ | |
| 30839 struct AuxDb *pAuxDb = p->pAuxDb; | |
| 30840 OpenSession *pSession = &pAuxDb->aSession[0]; | |
| 30841 char **azCmd = &azArg[1]; | |
| 30842 int iSes = 0; | |
| 30843 int nCmd = nArg - 1; | |
| 30844 int i; | |
| 30845 if( nArg<=1 ) goto session_syntax_error; | |
| 30846 open_db(p, 0); | |
| 30847 if( nArg>=3 ){ | |
| 30848 for(iSes=0; iSes<pAuxDb->nSession; iSes++){ | |
| 30849 if( cli_strcmp(pAuxDb->aSession[iSes].zName, azArg[1])==0 ) break; | |
| 30850 } | |
| 30851 if( iSes<pAuxDb->nSession ){ | |
| 30852 pSession = &pAuxDb->aSession[iSes]; | |
| 30853 azCmd++; | |
| 30854 nCmd--; | |
| 30855 }else{ | |
| 30856 pSession = &pAuxDb->aSession[0]; | |
| 30857 iSes = 0; | |
| 30858 } | |
| 30859 } | |
| 30860 | |
| 30861 /* .session attach TABLE | |
| 30862 ** Invoke the sqlite3session_attach() interface to attach a particular | |
| 30863 ** table so that it is never filtered. | |
| 30864 */ | |
| 30865 if( cli_strcmp(azCmd[0],"attach")==0 ){ | |
| 30866 if( nCmd!=2 ) goto session_syntax_error; | |
| 30867 if( pSession->p==0 ){ | |
| 30868 session_not_open: | |
| 30869 eputz("ERROR: No sessions are open\n"); | |
| 30870 }else{ | |
| 30871 rc = sqlite3session_attach(pSession->p, azCmd[1]); | |
| 30872 if( rc ){ | |
| 30873 sqlite3_fprintf(stderr, | |
| 30874 "ERROR: sqlite3session_attach() returns %d\n",rc); | |
| 30875 rc = 0; | |
| 30876 } | |
| 30877 } | |
| 30878 }else | |
| 30879 | |
| 30880 /* .session changeset FILE | |
| 30881 ** .session patchset FILE | |
| 30882 ** Write a changeset or patchset into a file. The file is overwritten. | |
| 30883 */ | |
| 30884 if( cli_strcmp(azCmd[0],"changeset")==0 | |
| 30885 || cli_strcmp(azCmd[0],"patchset")==0 | |
| 30886 ){ | |
| 30887 FILE *out = 0; | |
| 30888 failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]); | |
| 30889 if( nCmd!=2 ) goto session_syntax_error; | |
| 30890 if( pSession->p==0 ) goto session_not_open; | |
| 30891 out = sqlite3_fopen(azCmd[1], "wb"); | |
| 30892 if( out==0 ){ | |
| 30893 sqlite3_fprintf(stderr,"ERROR: cannot open \"%s\" for writing\n", | |
| 30894 azCmd[1]); | |
| 30895 }else{ | |
| 30896 int szChng; | |
| 30897 void *pChng; | |
| 30898 if( azCmd[0][0]=='c' ){ | |
| 30899 rc = sqlite3session_changeset(pSession->p, &szChng, &pChng); | |
| 30900 }else{ | |
| 30901 rc = sqlite3session_patchset(pSession->p, &szChng, &pChng); | |
| 30902 } | |
| 30903 if( rc ){ | |
| 30904 sqlite3_fprintf(stdout, "Error: error code %d\n", rc); | |
| 30905 rc = 0; | |
| 30906 } | |
| 30907 if( pChng | |
| 30908 && fwrite(pChng, szChng, 1, out)!=1 ){ | |
| 30909 sqlite3_fprintf(stderr, | |
| 30910 "ERROR: Failed to write entire %d-byte output\n", szChng); | |
| 30911 } | |
| 30912 sqlite3_free(pChng); | |
| 30913 fclose(out); | |
| 30914 } | |
| 30915 }else | |
| 30916 | |
| 30917 /* .session close | |
| 30918 ** Close the identified session | |
| 30919 */ | |
| 30920 if( cli_strcmp(azCmd[0], "close")==0 ){ | |
| 30921 if( nCmd!=1 ) goto session_syntax_error; | |
| 30922 if( pAuxDb->nSession ){ | |
| 30923 session_close(pSession); | |
| 30924 pAuxDb->aSession[iSes] = pAuxDb->aSession[--pAuxDb->nSession]; | |
| 30925 } | |
| 30926 }else | |
| 30927 | |
| 30928 /* .session enable ?BOOLEAN? | |
| 30929 ** Query or set the enable flag | |
| 30930 */ | |
| 30931 if( cli_strcmp(azCmd[0], "enable")==0 ){ | |
| 30932 int ii; | |
| 30933 if( nCmd>2 ) goto session_syntax_error; | |
| 30934 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); | |
| 30935 if( pAuxDb->nSession ){ | |
| 30936 ii = sqlite3session_enable(pSession->p, ii); | |
| 30937 sqlite3_fprintf(p->out, | |
| 30938 "session %s enable flag = %d\n", pSession->zName, ii); | |
| 30939 } | |
| 30940 }else | |
| 30941 | |
| 30942 /* .session filter GLOB .... | |
| 30943 ** Set a list of GLOB patterns of table names to be excluded. | |
| 30944 */ | |
| 30945 if( cli_strcmp(azCmd[0], "filter")==0 ){ | |
| 30946 int ii; | |
| 30947 i64 nByte; | |
| 30948 if( nCmd<2 ) goto session_syntax_error; | |
| 30949 if( pAuxDb->nSession ){ | |
| 30950 for(ii=0; ii<pSession->nFilter; ii++){ | |
| 30951 sqlite3_free(pSession->azFilter[ii]); | |
| 30952 } | |
| 30953 sqlite3_free(pSession->azFilter); | |
| 30954 nByte = sizeof(pSession->azFilter[0])*(nCmd-1); | |
| 30955 pSession->azFilter = sqlite3_malloc64( nByte ); | |
| 30956 shell_check_oom( pSession->azFilter ); | |
| 30957 for(ii=1; ii<nCmd; ii++){ | |
| 30958 char *x = pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]); | |
| 30959 shell_check_oom(x); | |
| 30960 } | |
| 30961 pSession->nFilter = ii-1; | |
| 30962 } | |
| 30963 }else | |
| 30964 | |
| 30965 /* .session indirect ?BOOLEAN? | |
| 30966 ** Query or set the indirect flag | |
| 30967 */ | |
| 30968 if( cli_strcmp(azCmd[0], "indirect")==0 ){ | |
| 30969 int ii; | |
| 30970 if( nCmd>2 ) goto session_syntax_error; | |
| 30971 ii = nCmd==1 ? -1 : booleanValue(azCmd[1]); | |
| 30972 if( pAuxDb->nSession ){ | |
| 30973 ii = sqlite3session_indirect(pSession->p, ii); | |
| 30974 sqlite3_fprintf(p->out, | |
| 30975 "session %s indirect flag = %d\n", pSession->zName, ii); | |
| 30976 } | |
| 30977 }else | |
| 30978 | |
| 30979 /* .session isempty | |
| 30980 ** Determine if the session is empty | |
| 30981 */ | |
| 30982 if( cli_strcmp(azCmd[0], "isempty")==0 ){ | |
| 30983 int ii; | |
| 30984 if( nCmd!=1 ) goto session_syntax_error; | |
| 30985 if( pAuxDb->nSession ){ | |
| 30986 ii = sqlite3session_isempty(pSession->p); | |
| 30987 sqlite3_fprintf(p->out, | |
| 30988 "session %s isempty flag = %d\n", pSession->zName, ii); | |
| 30989 } | |
| 30990 }else | |
| 30991 | |
| 30992 /* .session list | |
| 30993 ** List all currently open sessions | |
| 30994 */ | |
| 30995 if( cli_strcmp(azCmd[0],"list")==0 ){ | |
| 30996 for(i=0; i<pAuxDb->nSession; i++){ | |
| 30997 sqlite3_fprintf(p->out, "%d %s\n", i, pAuxDb->aSession[i].zName); | |
| 30998 } | |
| 30999 }else | |
| 31000 | |
| 31001 /* .session open DB NAME | |
| 31002 ** Open a new session called NAME on the attached database DB. | |
| 31003 ** DB is normally "main". | |
| 31004 */ | |
| 31005 if( cli_strcmp(azCmd[0],"open")==0 ){ | |
| 31006 char *zName; | |
| 31007 if( nCmd!=3 ) goto session_syntax_error; | |
| 31008 zName = azCmd[2]; | |
| 31009 if( zName[0]==0 ) goto session_syntax_error; | |
| 31010 for(i=0; i<pAuxDb->nSession; i++){ | |
| 31011 if( cli_strcmp(pAuxDb->aSession[i].zName,zName)==0 ){ | |
| 31012 sqlite3_fprintf(stderr,"Session \"%s\" already exists\n", zName); | |
| 31013 goto meta_command_exit; | |
| 31014 } | |
| 31015 } | |
| 31016 if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){ | |
| 31017 sqlite3_fprintf(stderr, | |
| 31018 "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession)); | |
| 31019 goto meta_command_exit; | |
| 31020 } | |
| 31021 pSession = &pAuxDb->aSession[pAuxDb->nSession]; | |
| 31022 rc = sqlite3session_create(p->db, azCmd[1], &pSession->p); | |
| 31023 if( rc ){ | |
| 31024 sqlite3_fprintf(stderr,"Cannot open session: error code=%d\n", rc); | |
| 31025 rc = 0; | |
| 31026 goto meta_command_exit; | |
| 31027 } | |
| 31028 pSession->nFilter = 0; | |
| 31029 sqlite3session_table_filter(pSession->p, session_filter, pSession); | |
| 31030 pAuxDb->nSession++; | |
| 31031 pSession->zName = sqlite3_mprintf("%s", zName); | |
| 31032 shell_check_oom(pSession->zName); | |
| 31033 }else | |
| 31034 /* If no command name matches, show a syntax error */ | |
| 31035 session_syntax_error: | |
| 31036 showHelp(p->out, "session"); | |
| 31037 }else | |
| 31038 #endif | |
| 31039 | |
| 31040 #ifdef SQLITE_DEBUG | |
| 31041 /* Undocumented commands for internal testing. Subject to change | |
| 31042 ** without notice. */ | |
| 31043 if( c=='s' && n>=10 && cli_strncmp(azArg[0], "selftest-", 9)==0 ){ | |
| 31044 if( cli_strncmp(azArg[0]+9, "boolean", n-9)==0 ){ | |
| 31045 int i, v; | |
| 31046 for(i=1; i<nArg; i++){ | |
| 31047 v = booleanValue(azArg[i]); | |
| 31048 sqlite3_fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v); | |
| 31049 } | |
| 31050 } | |
| 31051 if( cli_strncmp(azArg[0]+9, "integer", n-9)==0 ){ | |
| 31052 int i; sqlite3_int64 v; | |
| 31053 for(i=1; i<nArg; i++){ | |
| 31054 char zBuf[200]; | |
| 31055 v = integerValue(azArg[i]); | |
| 31056 sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v); | |
| 31057 sqlite3_fputs(zBuf, p->out); | |
| 31058 } | |
| 31059 } | |
| 31060 }else | |
| 31061 #endif | |
| 31062 | |
| 31063 if( c=='s' && n>=4 && cli_strncmp(azArg[0],"selftest",n)==0 ){ | |
| 31064 int bIsInit = 0; /* True to initialize the SELFTEST table */ | |
| 31065 int bVerbose = 0; /* Verbose output */ | |
| 31066 int bSelftestExists; /* True if SELFTEST already exists */ | |
| 31067 int i, k; /* Loop counters */ | |
| 31068 int nTest = 0; /* Number of tests runs */ | |
| 31069 int nErr = 0; /* Number of errors seen */ | |
| 31070 ShellText str; /* Answer for a query */ | |
| 31071 sqlite3_stmt *pStmt = 0; /* Query against the SELFTEST table */ | |
| 31072 | |
| 31073 open_db(p,0); | |
| 31074 for(i=1; i<nArg; i++){ | |
| 31075 const char *z = azArg[i]; | |
| 31076 if( z[0]=='-' && z[1]=='-' ) z++; | |
| 31077 if( cli_strcmp(z,"-init")==0 ){ | |
| 31078 bIsInit = 1; | |
| 31079 }else | |
| 31080 if( cli_strcmp(z,"-v")==0 ){ | |
| 31081 bVerbose++; | |
| 31082 }else | |
| 31083 { | |
| 31084 sqlite3_fprintf(stderr, | |
| 31085 "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); | |
| 31086 sqlite3_fputs("Should be one of: --init -v\n", stderr); | |
| 31087 rc = 1; | |
| 31088 goto meta_command_exit; | |
| 31089 } | |
| 31090 } | |
| 31091 if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0) | |
| 31092 != SQLITE_OK ){ | |
| 31093 bSelftestExists = 0; | |
| 31094 }else{ | |
| 31095 bSelftestExists = 1; | |
| 31096 } | |
| 31097 if( bIsInit ){ | |
| 31098 createSelftestTable(p); | |
| 31099 bSelftestExists = 1; | |
| 31100 } | |
| 31101 initText(&str); | |
| 31102 appendText(&str, "x", 0); | |
| 31103 for(k=bSelftestExists; k>=0; k--){ | |
| 31104 if( k==1 ){ | |
| 31105 rc = sqlite3_prepare_v2(p->db, | |
| 31106 "SELECT tno,op,cmd,ans FROM selftest ORDER BY tno", | |
| 31107 -1, &pStmt, 0); | |
| 31108 }else{ | |
| 31109 rc = sqlite3_prepare_v2(p->db, | |
| 31110 "VALUES(0,'memo','Missing SELFTEST table - default checks only','')," | |
| 31111 " (1,'run','PRAGMA integrity_check','ok')", | |
| 31112 -1, &pStmt, 0); | |
| 31113 } | |
| 31114 if( rc ){ | |
| 31115 eputz("Error querying the selftest table\n"); | |
| 31116 rc = 1; | |
| 31117 sqlite3_finalize(pStmt); | |
| 31118 goto meta_command_exit; | |
| 31119 } | |
| 31120 for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){ | |
| 31121 int tno = sqlite3_column_int(pStmt, 0); | |
| 31122 const char *zOp = (const char*)sqlite3_column_text(pStmt, 1); | |
| 31123 const char *zSql = (const char*)sqlite3_column_text(pStmt, 2); | |
| 31124 const char *zAns = (const char*)sqlite3_column_text(pStmt, 3); | |
| 31125 | |
| 31126 if( zOp==0 ) continue; | |
| 31127 if( zSql==0 ) continue; | |
| 31128 if( zAns==0 ) continue; | |
| 31129 k = 0; | |
| 31130 if( bVerbose>0 ){ | |
| 31131 sqlite3_fprintf(stdout, "%d: %s %s\n", tno, zOp, zSql); | |
| 31132 } | |
| 31133 if( cli_strcmp(zOp,"memo")==0 ){ | |
| 31134 sqlite3_fprintf(p->out, "%s\n", zSql); | |
| 31135 }else | |
| 31136 if( cli_strcmp(zOp,"run")==0 ){ | |
| 31137 char *zErrMsg = 0; | |
| 31138 str.n = 0; | |
| 31139 str.zTxt[0] = 0; | |
| 31140 rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg); | |
| 31141 nTest++; | |
| 31142 if( bVerbose ){ | |
| 31143 sqlite3_fprintf(p->out, "Result: %s\n", str.zTxt); | |
| 31144 } | |
| 31145 if( rc || zErrMsg ){ | |
| 31146 nErr++; | |
| 31147 rc = 1; | |
| 31148 sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg); | |
| 31149 sqlite3_free(zErrMsg); | |
| 31150 }else if( cli_strcmp(zAns,str.zTxt)!=0 ){ | |
| 31151 nErr++; | |
| 31152 rc = 1; | |
| 31153 sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns); | |
| 31154 sqlite3_fprintf(p->out, "%d: Got: [%s]\n", tno, str.zTxt); | |
| 31155 } | |
| 31156 } | |
| 31157 else{ | |
| 31158 sqlite3_fprintf(stderr, | |
| 31159 "Unknown operation \"%s\" on selftest line %d\n", zOp, tno); | |
| 31160 rc = 1; | |
| 31161 break; | |
| 31162 } | |
| 31163 } /* End loop over rows of content from SELFTEST */ | |
| 31164 sqlite3_finalize(pStmt); | |
| 31165 } /* End loop over k */ | |
| 31166 freeText(&str); | |
| 31167 sqlite3_fprintf(p->out, "%d errors out of %d tests\n", nErr, nTest); | |
| 31168 }else | |
| 31169 | |
| 31170 if( c=='s' && cli_strncmp(azArg[0], "separator", n)==0 ){ | |
| 31171 if( nArg<2 || nArg>3 ){ | |
| 31172 eputz("Usage: .separator COL ?ROW?\n"); | |
| 31173 rc = 1; | |
| 31174 } | |
| 31175 if( nArg>=2 ){ | |
| 31176 sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, | |
| 31177 "%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]); | |
| 31178 } | |
| 31179 if( nArg>=3 ){ | |
| 31180 sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, | |
| 31181 "%.*s", (int)ArraySize(p->rowSeparator)-1, azArg[2]); | |
| 31182 } | |
| 31183 }else | |
| 31184 | |
| 31185 if( c=='s' && n>=4 && cli_strncmp(azArg[0],"sha3sum",n)==0 ){ | |
| 31186 const char *zLike = 0; /* Which table to checksum. 0 means everything */ | |
| 31187 int i; /* Loop counter */ | |
| 31188 int bSchema = 0; /* Also hash the schema */ | |
| 31189 int bSeparate = 0; /* Hash each table separately */ | |
| 31190 int iSize = 224; /* Hash algorithm to use */ | |
| 31191 int bDebug = 0; /* Only show the query that would have run */ | |
| 31192 sqlite3_stmt *pStmt; /* For querying tables names */ | |
| 31193 char *zSql; /* SQL to be run */ | |
| 31194 char *zSep; /* Separator */ | |
| 31195 ShellText sSql; /* Complete SQL for the query to run the hash */ | |
| 31196 ShellText sQuery; /* Set of queries used to read all content */ | |
| 31197 open_db(p, 0); | |
| 31198 for(i=1; i<nArg; i++){ | |
| 31199 const char *z = azArg[i]; | |
| 31200 if( z[0]=='-' ){ | |
| 31201 z++; | |
| 31202 if( z[0]=='-' ) z++; | |
| 31203 if( cli_strcmp(z,"schema")==0 ){ | |
| 31204 bSchema = 1; | |
| 31205 }else | |
| 31206 if( cli_strcmp(z,"sha3-224")==0 || cli_strcmp(z,"sha3-256")==0 | |
| 31207 || cli_strcmp(z,"sha3-384")==0 || cli_strcmp(z,"sha3-512")==0 | |
| 31208 ){ | |
| 31209 iSize = atoi(&z[5]); | |
| 31210 }else | |
| 31211 if( cli_strcmp(z,"debug")==0 ){ | |
| 31212 bDebug = 1; | |
| 31213 }else | |
| 31214 { | |
| 31215 sqlite3_fprintf(stderr, | |
| 31216 "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); | |
| 31217 showHelp(p->out, azArg[0]); | |
| 31218 rc = 1; | |
| 31219 goto meta_command_exit; | |
| 31220 } | |
| 31221 }else if( zLike ){ | |
| 31222 eputz("Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n"); | |
| 31223 rc = 1; | |
| 31224 goto meta_command_exit; | |
| 31225 }else{ | |
| 31226 zLike = z; | |
| 31227 bSeparate = 1; | |
| 31228 if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1; | |
| 31229 } | |
| 31230 } | |
| 31231 if( bSchema ){ | |
| 31232 zSql = "SELECT lower(name) as tname FROM sqlite_schema" | |
| 31233 " WHERE type='table' AND coalesce(rootpage,0)>1" | |
| 31234 " UNION ALL SELECT 'sqlite_schema'" | |
| 31235 " ORDER BY 1 collate nocase"; | |
| 31236 }else{ | |
| 31237 zSql = "SELECT lower(name) as tname FROM sqlite_schema" | |
| 31238 " WHERE type='table' AND coalesce(rootpage,0)>1" | |
| 31239 " AND name NOT LIKE 'sqlite__%' ESCAPE '_'" | |
| 31240 " ORDER BY 1 collate nocase"; | |
| 31241 } | |
| 31242 sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); | |
| 31243 initText(&sQuery); | |
| 31244 initText(&sSql); | |
| 31245 appendText(&sSql, "WITH [sha3sum$query](a,b) AS(",0); | |
| 31246 zSep = "VALUES("; | |
| 31247 while( SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 31248 const char *zTab = (const char*)sqlite3_column_text(pStmt,0); | |
| 31249 if( zTab==0 ) continue; | |
| 31250 if( zLike && sqlite3_strlike(zLike, zTab, 0)!=0 ) continue; | |
| 31251 if( cli_strncmp(zTab, "sqlite_",7)!=0 ){ | |
| 31252 appendText(&sQuery,"SELECT * FROM ", 0); | |
| 31253 appendText(&sQuery,zTab,'"'); | |
| 31254 appendText(&sQuery," NOT INDEXED;", 0); | |
| 31255 }else if( cli_strcmp(zTab, "sqlite_schema")==0 ){ | |
| 31256 appendText(&sQuery,"SELECT type,name,tbl_name,sql FROM sqlite_schema" | |
| 31257 " ORDER BY name;", 0); | |
| 31258 }else if( cli_strcmp(zTab, "sqlite_sequence")==0 ){ | |
| 31259 appendText(&sQuery,"SELECT name,seq FROM sqlite_sequence" | |
| 31260 " ORDER BY name;", 0); | |
| 31261 }else if( cli_strcmp(zTab, "sqlite_stat1")==0 ){ | |
| 31262 appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1" | |
| 31263 " ORDER BY tbl,idx;", 0); | |
| 31264 }else if( cli_strcmp(zTab, "sqlite_stat4")==0 ){ | |
| 31265 appendText(&sQuery, "SELECT * FROM ", 0); | |
| 31266 appendText(&sQuery, zTab, 0); | |
| 31267 appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0); | |
| 31268 } | |
| 31269 appendText(&sSql, zSep, 0); | |
| 31270 appendText(&sSql, sQuery.zTxt, '\''); | |
| 31271 sQuery.n = 0; | |
| 31272 appendText(&sSql, ",", 0); | |
| 31273 appendText(&sSql, zTab, '\''); | |
| 31274 zSep = "),("; | |
| 31275 } | |
| 31276 sqlite3_finalize(pStmt); | |
| 31277 if( bSeparate ){ | |
| 31278 zSql = sqlite3_mprintf( | |
| 31279 "%s))" | |
| 31280 " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label" | |
| 31281 " FROM [sha3sum$query]", | |
| 31282 sSql.zTxt, iSize); | |
| 31283 }else{ | |
| 31284 zSql = sqlite3_mprintf( | |
| 31285 "%s))" | |
| 31286 " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash" | |
| 31287 " FROM [sha3sum$query]", | |
| 31288 sSql.zTxt, iSize); | |
| 31289 } | |
| 31290 shell_check_oom(zSql); | |
| 31291 freeText(&sQuery); | |
| 31292 freeText(&sSql); | |
| 31293 if( bDebug ){ | |
| 31294 sqlite3_fprintf(p->out, "%s\n", zSql); | |
| 31295 }else{ | |
| 31296 shell_exec(p, zSql, 0); | |
| 31297 } | |
| 31298 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && !defined(SQLITE_OMIT_VIRTUALTABLE) | |
| 31299 { | |
| 31300 int lrc; | |
| 31301 char *zRevText = /* Query for reversible to-blob-to-text check */ | |
| 31302 "SELECT lower(name) as tname FROM sqlite_schema\n" | |
| 31303 "WHERE type='table' AND coalesce(rootpage,0)>1\n" | |
| 31304 "AND name NOT LIKE 'sqlite__%%' ESCAPE '_'%s\n" | |
| 31305 "ORDER BY 1 collate nocase"; | |
| 31306 zRevText = sqlite3_mprintf(zRevText, zLike? " AND name LIKE $tspec" : ""); | |
| 31307 zRevText = sqlite3_mprintf( | |
| 31308 /* lower-case query is first run, producing upper-case query. */ | |
| 31309 "with tabcols as materialized(\n" | |
| 31310 "select tname, cname\n" | |
| 31311 "from (" | |
| 31312 " select printf('\"%%w\"',ss.tname) as tname," | |
| 31313 " printf('\"%%w\"',ti.name) as cname\n" | |
| 31314 " from (%z) ss\n inner join pragma_table_info(tname) ti))\n" | |
| 31315 "select 'SELECT total(bad_text_count) AS bad_text_count\n" | |
| 31316 "FROM ('||group_concat(query, ' UNION ALL ')||')' as btc_query\n" | |
| 31317 " from (select 'SELECT COUNT(*) AS bad_text_count\n" | |
| 31318 "FROM '||tname||' WHERE '\n" | |
| 31319 "||group_concat('CAST(CAST('||cname||' AS BLOB) AS TEXT)<>'||cname\n" | |
| 31320 "|| ' AND typeof('||cname||')=''text'' ',\n" | |
| 31321 "' OR ') as query, tname from tabcols group by tname)" | |
| 31322 , zRevText); | |
| 31323 shell_check_oom(zRevText); | |
| 31324 if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zRevText); | |
| 31325 lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0); | |
| 31326 if( lrc!=SQLITE_OK ){ | |
| 31327 /* assert(lrc==SQLITE_NOMEM); // might also be SQLITE_ERROR if the | |
| 31328 ** user does cruel and unnatural things like ".limit expr_depth 0". */ | |
| 31329 rc = 1; | |
| 31330 }else{ | |
| 31331 if( zLike ) sqlite3_bind_text(pStmt,1,zLike,-1,SQLITE_STATIC); | |
| 31332 lrc = SQLITE_ROW==sqlite3_step(pStmt); | |
| 31333 if( lrc ){ | |
| 31334 const char *zGenQuery = (char*)sqlite3_column_text(pStmt,0); | |
| 31335 sqlite3_stmt *pCheckStmt; | |
| 31336 lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0); | |
| 31337 if( bDebug ) sqlite3_fprintf(p->out, "%s\n", zGenQuery); | |
| 31338 if( lrc!=SQLITE_OK ){ | |
| 31339 rc = 1; | |
| 31340 }else{ | |
| 31341 if( SQLITE_ROW==sqlite3_step(pCheckStmt) ){ | |
| 31342 double countIrreversible = sqlite3_column_double(pCheckStmt, 0); | |
| 31343 if( countIrreversible>0 ){ | |
| 31344 int sz = (int)(countIrreversible + 0.5); | |
| 31345 sqlite3_fprintf(stderr, | |
| 31346 "Digest includes %d invalidly encoded text field%s.\n", | |
| 31347 sz, (sz>1)? "s": ""); | |
| 31348 } | |
| 31349 } | |
| 31350 sqlite3_finalize(pCheckStmt); | |
| 31351 } | |
| 31352 sqlite3_finalize(pStmt); | |
| 31353 } | |
| 31354 } | |
| 31355 if( rc ) eputz(".sha3sum failed.\n"); | |
| 31356 sqlite3_free(zRevText); | |
| 31357 } | |
| 31358 #endif /* !defined(*_OMIT_SCHEMA_PRAGMAS) && !defined(*_OMIT_VIRTUALTABLE) */ | |
| 31359 sqlite3_free(zSql); | |
| 31360 }else | |
| 31361 | |
| 31362 #if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) | |
| 31363 if( c=='s' | |
| 31364 && (cli_strncmp(azArg[0], "shell", n)==0 | |
| 31365 || cli_strncmp(azArg[0],"system",n)==0) | |
| 31366 ){ | |
| 31367 char *zCmd; | |
| 31368 int i, x; | |
| 31369 failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]); | |
| 31370 if( nArg<2 ){ | |
| 31371 eputz("Usage: .system COMMAND\n"); | |
| 31372 rc = 1; | |
| 31373 goto meta_command_exit; | |
| 31374 } | |
| 31375 zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]); | |
| 31376 for(i=2; i<nArg && zCmd!=0; i++){ | |
| 31377 zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"", | |
| 31378 zCmd, azArg[i]); | |
| 31379 } | |
| 31380 /*consoleRestore();*/ | |
| 31381 x = zCmd!=0 ? system(zCmd) : 1; | |
| 31382 /*consoleRenewSetup();*/ | |
| 31383 sqlite3_free(zCmd); | |
| 31384 if( x ) sqlite3_fprintf(stderr,"System command returns %d\n", x); | |
| 31385 }else | |
| 31386 #endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) */ | |
| 31387 | |
| 31388 if( c=='s' && cli_strncmp(azArg[0], "show", n)==0 ){ | |
| 31389 static const char *azBool[] = { "off", "on", "trigger", "full"}; | |
| 31390 const char *zOut; | |
| 31391 int i; | |
| 31392 if( nArg!=1 ){ | |
| 31393 eputz("Usage: .show\n"); | |
| 31394 rc = 1; | |
| 31395 goto meta_command_exit; | |
| 31396 } | |
| 31397 sqlite3_fprintf(p->out, "%12.12s: %s\n","echo", | |
| 31398 azBool[ShellHasFlag(p, SHFLG_Echo)]); | |
| 31399 sqlite3_fprintf(p->out, "%12.12s: %s\n","eqp", azBool[p->autoEQP&3]); | |
| 31400 sqlite3_fprintf(p->out, "%12.12s: %s\n","explain", | |
| 31401 p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off"); | |
| 31402 sqlite3_fprintf(p->out, "%12.12s: %s\n","headers", | |
| 31403 azBool[p->showHeader!=0]); | |
| 31404 if( p->mode==MODE_Column | |
| 31405 || (p->mode>=MODE_Markdown && p->mode<=MODE_Box) | |
| 31406 ){ | |
| 31407 sqlite3_fprintf(p->out, | |
| 31408 "%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode", | |
| 31409 modeDescr[p->mode], p->cmOpts.iWrap, | |
| 31410 p->cmOpts.bWordWrap ? "on" : "off", | |
| 31411 p->cmOpts.bQuote ? "" : "no"); | |
| 31412 }else{ | |
| 31413 sqlite3_fprintf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]); | |
| 31414 } | |
| 31415 sqlite3_fprintf(p->out, "%12.12s: ", "nullvalue"); | |
| 31416 output_c_string(p->out, p->nullValue); | |
| 31417 sqlite3_fputs("\n", p->out); | |
| 31418 sqlite3_fprintf(p->out, "%12.12s: %s\n","output", | |
| 31419 strlen30(p->outfile) ? p->outfile : "stdout"); | |
| 31420 sqlite3_fprintf(p->out, "%12.12s: ", "colseparator"); | |
| 31421 output_c_string(p->out, p->colSeparator); | |
| 31422 sqlite3_fputs("\n", p->out); | |
| 31423 sqlite3_fprintf(p->out, "%12.12s: ", "rowseparator"); | |
| 31424 output_c_string(p->out, p->rowSeparator); | |
| 31425 sqlite3_fputs("\n", p->out); | |
| 31426 switch( p->statsOn ){ | |
| 31427 case 0: zOut = "off"; break; | |
| 31428 default: zOut = "on"; break; | |
| 31429 case 2: zOut = "stmt"; break; | |
| 31430 case 3: zOut = "vmstep"; break; | |
| 31431 } | |
| 31432 sqlite3_fprintf(p->out, "%12.12s: %s\n","stats", zOut); | |
| 31433 sqlite3_fprintf(p->out, "%12.12s: ", "width"); | |
| 31434 for (i=0;i<p->nWidth;i++) { | |
| 31435 sqlite3_fprintf(p->out, "%d ", p->colWidth[i]); | |
| 31436 } | |
| 31437 sqlite3_fputs("\n", p->out); | |
| 31438 sqlite3_fprintf(p->out, "%12.12s: %s\n", "filename", | |
| 31439 p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : ""); | |
| 31440 }else | |
| 31441 | |
| 31442 if( c=='s' && cli_strncmp(azArg[0], "stats", n)==0 ){ | |
| 31443 if( nArg==2 ){ | |
| 31444 if( cli_strcmp(azArg[1],"stmt")==0 ){ | |
| 31445 p->statsOn = 2; | |
| 31446 }else if( cli_strcmp(azArg[1],"vmstep")==0 ){ | |
| 31447 p->statsOn = 3; | |
| 31448 }else{ | |
| 31449 p->statsOn = (u8)booleanValue(azArg[1]); | |
| 31450 } | |
| 31451 }else if( nArg==1 ){ | |
| 31452 display_stats(p->db, p, 0); | |
| 31453 }else{ | |
| 31454 eputz("Usage: .stats ?on|off|stmt|vmstep?\n"); | |
| 31455 rc = 1; | |
| 31456 } | |
| 31457 }else | |
| 31458 | |
| 31459 if( (c=='t' && n>1 && cli_strncmp(azArg[0], "tables", n)==0) | |
| 31460 || (c=='i' && (cli_strncmp(azArg[0], "indices", n)==0 | |
| 31461 || cli_strncmp(azArg[0], "indexes", n)==0) ) | |
| 31462 ){ | |
| 31463 sqlite3_stmt *pStmt; | |
| 31464 char **azResult; | |
| 31465 int nRow, nAlloc; | |
| 31466 int ii; | |
| 31467 ShellText s; | |
| 31468 initText(&s); | |
| 31469 open_db(p, 0); | |
| 31470 rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0); | |
| 31471 if( rc ){ | |
| 31472 sqlite3_finalize(pStmt); | |
| 31473 return shellDatabaseError(p->db); | |
| 31474 } | |
| 31475 | |
| 31476 if( nArg>2 && c=='i' ){ | |
| 31477 /* It is an historical accident that the .indexes command shows an error | |
| 31478 ** when called with the wrong number of arguments whereas the .tables | |
| 31479 ** command does not. */ | |
| 31480 eputz("Usage: .indexes ?LIKE-PATTERN?\n"); | |
| 31481 rc = 1; | |
| 31482 sqlite3_finalize(pStmt); | |
| 31483 goto meta_command_exit; | |
| 31484 } | |
| 31485 for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){ | |
| 31486 const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1); | |
| 31487 if( zDbName==0 ) continue; | |
| 31488 if( s.zTxt && s.zTxt[0] ) appendText(&s, " UNION ALL ", 0); | |
| 31489 if( sqlite3_stricmp(zDbName, "main")==0 ){ | |
| 31490 appendText(&s, "SELECT name FROM ", 0); | |
| 31491 }else{ | |
| 31492 appendText(&s, "SELECT ", 0); | |
| 31493 appendText(&s, zDbName, '\''); | |
| 31494 appendText(&s, "||'.'||name FROM ", 0); | |
| 31495 } | |
| 31496 appendText(&s, zDbName, '"'); | |
| 31497 appendText(&s, ".sqlite_schema ", 0); | |
| 31498 if( c=='t' ){ | |
| 31499 appendText(&s," WHERE type IN ('table','view')" | |
| 31500 " AND name NOT LIKE 'sqlite__%' ESCAPE '_'" | |
| 31501 " AND name LIKE ?1", 0); | |
| 31502 }else{ | |
| 31503 appendText(&s," WHERE type='index'" | |
| 31504 " AND tbl_name LIKE ?1", 0); | |
| 31505 } | |
| 31506 } | |
| 31507 rc = sqlite3_finalize(pStmt); | |
| 31508 if( rc==SQLITE_OK ){ | |
| 31509 appendText(&s, " ORDER BY 1", 0); | |
| 31510 rc = sqlite3_prepare_v2(p->db, s.zTxt, -1, &pStmt, 0); | |
| 31511 } | |
| 31512 freeText(&s); | |
| 31513 if( rc ) return shellDatabaseError(p->db); | |
| 31514 | |
| 31515 /* Run the SQL statement prepared by the above block. Store the results | |
| 31516 ** as an array of nul-terminated strings in azResult[]. */ | |
| 31517 nRow = nAlloc = 0; | |
| 31518 azResult = 0; | |
| 31519 if( nArg>1 ){ | |
| 31520 sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT); | |
| 31521 }else{ | |
| 31522 sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC); | |
| 31523 } | |
| 31524 while( sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 31525 if( nRow>=nAlloc ){ | |
| 31526 char **azNew; | |
| 31527 sqlite3_int64 n2 = 2*(sqlite3_int64)nAlloc + 10; | |
| 31528 azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2); | |
| 31529 shell_check_oom(azNew); | |
| 31530 nAlloc = (int)n2; | |
| 31531 azResult = azNew; | |
| 31532 } | |
| 31533 azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0)); | |
| 31534 shell_check_oom(azResult[nRow]); | |
| 31535 nRow++; | |
| 31536 } | |
| 31537 if( sqlite3_finalize(pStmt)!=SQLITE_OK ){ | |
| 31538 rc = shellDatabaseError(p->db); | |
| 31539 } | |
| 31540 | |
| 31541 /* Pretty-print the contents of array azResult[] to the output */ | |
| 31542 if( rc==0 && nRow>0 ){ | |
| 31543 int len, maxlen = 0; | |
| 31544 int i, j; | |
| 31545 int nPrintCol, nPrintRow; | |
| 31546 for(i=0; i<nRow; i++){ | |
| 31547 len = strlen30(azResult[i]); | |
| 31548 if( len>maxlen ) maxlen = len; | |
| 31549 } | |
| 31550 nPrintCol = 80/(maxlen+2); | |
| 31551 if( nPrintCol<1 ) nPrintCol = 1; | |
| 31552 nPrintRow = (nRow + nPrintCol - 1)/nPrintCol; | |
| 31553 for(i=0; i<nPrintRow; i++){ | |
| 31554 for(j=i; j<nRow; j+=nPrintRow){ | |
| 31555 char *zSp = j<nPrintRow ? "" : " "; | |
| 31556 sqlite3_fprintf(p->out, | |
| 31557 "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:""); | |
| 31558 } | |
| 31559 sqlite3_fputs("\n", p->out); | |
| 31560 } | |
| 31561 } | |
| 31562 | |
| 31563 for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]); | |
| 31564 sqlite3_free(azResult); | |
| 31565 }else | |
| 31566 | |
| 31567 #ifndef SQLITE_SHELL_FIDDLE | |
| 31568 /* Begin redirecting output to the file "testcase-out.txt" */ | |
| 31569 if( c=='t' && cli_strcmp(azArg[0],"testcase")==0 ){ | |
| 31570 output_reset(p); | |
| 31571 p->out = output_file_open("testcase-out.txt"); | |
| 31572 if( p->out==0 ){ | |
| 31573 eputz("Error: cannot open 'testcase-out.txt'\n"); | |
| 31574 } | |
| 31575 if( nArg>=2 ){ | |
| 31576 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]); | |
| 31577 }else{ | |
| 31578 sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?"); | |
| 31579 } | |
| 31580 }else | |
| 31581 #endif /* !defined(SQLITE_SHELL_FIDDLE) */ | |
| 31582 | |
| 31583 #ifndef SQLITE_UNTESTABLE | |
| 31584 if( c=='t' && n>=8 && cli_strncmp(azArg[0], "testctrl", n)==0 ){ | |
| 31585 static const struct { | |
| 31586 const char *zCtrlName; /* Name of a test-control option */ | |
| 31587 int ctrlCode; /* Integer code for that option */ | |
| 31588 int unSafe; /* Not valid unless --unsafe-testing */ | |
| 31589 const char *zUsage; /* Usage notes */ | |
| 31590 } aCtrl[] = { | |
| 31591 {"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" }, | |
| 31592 {"assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" }, | |
| 31593 /*{"benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/ | |
| 31594 {"bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "SIZE INT-ARRAY"}, | |
| 31595 {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, | |
| 31596 {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, | |
| 31597 {"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"args..." }, | |
| 31598 {"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" }, | |
| 31599 {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"}, | |
| 31600 {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" }, | |
| 31601 {"json_selfcheck", SQLITE_TESTCTRL_JSON_SELFCHECK ,0,"BOOLEAN" }, | |
| 31602 {"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" }, | |
| 31603 {"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" }, | |
| 31604 {"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK ..."}, | |
| 31605 #ifdef YYCOVERAGE | |
| 31606 {"parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" }, | |
| 31607 #endif | |
| 31608 {"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,1, "OFFSET " }, | |
| 31609 {"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" }, | |
| 31610 {"prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" }, | |
| 31611 {"prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" }, | |
| 31612 {"seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" }, | |
| 31613 {"sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" }, | |
| 31614 {"tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" }, | |
| 31615 }; | |
| 31616 int testctrl = -1; | |
| 31617 int iCtrl = -1; | |
| 31618 int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */ | |
| 31619 int isOk = 0; | |
| 31620 int i, n2; | |
| 31621 const char *zCmd = 0; | |
| 31622 | |
| 31623 open_db(p, 0); | |
| 31624 zCmd = nArg>=2 ? azArg[1] : "help"; | |
| 31625 | |
| 31626 /* The argument can optionally begin with "-" or "--" */ | |
| 31627 if( zCmd[0]=='-' && zCmd[1] ){ | |
| 31628 zCmd++; | |
| 31629 if( zCmd[0]=='-' && zCmd[1] ) zCmd++; | |
| 31630 } | |
| 31631 | |
| 31632 /* --help lists all test-controls */ | |
| 31633 if( cli_strcmp(zCmd,"help")==0 ){ | |
| 31634 sqlite3_fputs("Available test-controls:\n", p->out); | |
| 31635 for(i=0; i<ArraySize(aCtrl); i++){ | |
| 31636 if( aCtrl[i].unSafe && !ShellHasFlag(p,SHFLG_TestingMode) ) continue; | |
| 31637 sqlite3_fprintf(p->out, " .testctrl %s %s\n", | |
| 31638 aCtrl[i].zCtrlName, aCtrl[i].zUsage); | |
| 31639 } | |
| 31640 rc = 1; | |
| 31641 goto meta_command_exit; | |
| 31642 } | |
| 31643 | |
| 31644 /* convert testctrl text option to value. allow any unique prefix | |
| 31645 ** of the option name, or a numerical value. */ | |
| 31646 n2 = strlen30(zCmd); | |
| 31647 for(i=0; i<ArraySize(aCtrl); i++){ | |
| 31648 if( aCtrl[i].unSafe && !ShellHasFlag(p,SHFLG_TestingMode) ) continue; | |
| 31649 if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){ | |
| 31650 if( testctrl<0 ){ | |
| 31651 testctrl = aCtrl[i].ctrlCode; | |
| 31652 iCtrl = i; | |
| 31653 }else{ | |
| 31654 sqlite3_fprintf(stderr,"Error: ambiguous test-control: \"%s\"\n" | |
| 31655 "Use \".testctrl --help\" for help\n", zCmd); | |
| 31656 rc = 1; | |
| 31657 goto meta_command_exit; | |
| 31658 } | |
| 31659 } | |
| 31660 } | |
| 31661 if( testctrl<0 ){ | |
| 31662 sqlite3_fprintf(stderr,"Error: unknown test-control: %s\n" | |
| 31663 "Use \".testctrl --help\" for help\n", zCmd); | |
| 31664 }else{ | |
| 31665 switch(testctrl){ | |
| 31666 | |
| 31667 /* Special processing for .testctrl opt MASK ... | |
| 31668 ** Each MASK argument can be one of: | |
| 31669 ** | |
| 31670 ** +LABEL Enable the named optimization | |
| 31671 ** | |
| 31672 ** -LABEL Disable the named optimization | |
| 31673 ** | |
| 31674 ** INTEGER Mask of optimizations to disable | |
| 31675 */ | |
| 31676 case SQLITE_TESTCTRL_OPTIMIZATIONS: { | |
| 31677 static const struct { | |
| 31678 unsigned int mask; /* Mask for this optimization */ | |
| 31679 unsigned int bDsply; /* Display this on output */ | |
| 31680 const char *zLabel; /* Name of optimization */ | |
| 31681 } aLabel[] = { | |
| 31682 { 0x00000001, 1, "QueryFlattener" }, | |
| 31683 { 0x00000001, 0, "Flatten" }, | |
| 31684 { 0x00000002, 1, "WindowFunc" }, | |
| 31685 { 0x00000004, 1, "GroupByOrder" }, | |
| 31686 { 0x00000008, 1, "FactorOutConst" }, | |
| 31687 { 0x00000010, 1, "DistinctOpt" }, | |
| 31688 { 0x00000020, 1, "CoverIdxScan" }, | |
| 31689 { 0x00000040, 1, "OrderByIdxJoin" }, | |
| 31690 { 0x00000080, 1, "Transitive" }, | |
| 31691 { 0x00000100, 1, "OmitNoopJoin" }, | |
| 31692 { 0x00000200, 1, "CountOfView" }, | |
| 31693 { 0x00000400, 1, "CursorHints" }, | |
| 31694 { 0x00000800, 1, "Stat4" }, | |
| 31695 { 0x00001000, 1, "PushDown" }, | |
| 31696 { 0x00002000, 1, "SimplifyJoin" }, | |
| 31697 { 0x00004000, 1, "SkipScan" }, | |
| 31698 { 0x00008000, 1, "PropagateConst" }, | |
| 31699 { 0x00010000, 1, "MinMaxOpt" }, | |
| 31700 { 0x00020000, 1, "SeekScan" }, | |
| 31701 { 0x00040000, 1, "OmitOrderBy" }, | |
| 31702 { 0x00080000, 1, "BloomFilter" }, | |
| 31703 { 0x00100000, 1, "BloomPulldown" }, | |
| 31704 { 0x00200000, 1, "BalancedMerge" }, | |
| 31705 { 0x00400000, 1, "ReleaseReg" }, | |
| 31706 { 0x00800000, 1, "FlttnUnionAll" }, | |
| 31707 { 0x01000000, 1, "IndexedEXpr" }, | |
| 31708 { 0x02000000, 1, "Coroutines" }, | |
| 31709 { 0x04000000, 1, "NullUnusedCols" }, | |
| 31710 { 0x08000000, 1, "OnePass" }, | |
| 31711 { 0x10000000, 1, "OrderBySubq" }, | |
| 31712 { 0x20000000, 1, "StarQuery" }, | |
| 31713 { 0x40000000, 1, "ExistsToJoin" }, | |
| 31714 { 0xffffffff, 0, "All" }, | |
| 31715 }; | |
| 31716 unsigned int curOpt; | |
| 31717 unsigned int newOpt; | |
| 31718 unsigned int m; | |
| 31719 int ii; | |
| 31720 int nOff; | |
| 31721 sqlite3_test_control(SQLITE_TESTCTRL_GETOPT, p->db, &curOpt); | |
| 31722 newOpt = curOpt; | |
| 31723 for(ii=2; ii<nArg; ii++){ | |
| 31724 const char *z = azArg[ii]; | |
| 31725 int useLabel = 0; | |
| 31726 const char *zLabel = 0; | |
| 31727 if( (z[0]=='+'|| z[0]=='-') && !IsDigit(z[1]) ){ | |
| 31728 useLabel = z[0]; | |
| 31729 zLabel = &z[1]; | |
| 31730 }else if( !IsDigit(z[0]) && z[0]!=0 && !IsDigit(z[1]) ){ | |
| 31731 useLabel = '+'; | |
| 31732 zLabel = z; | |
| 31733 }else{ | |
| 31734 newOpt = (unsigned int)strtol(z,0,0); | |
| 31735 } | |
| 31736 if( useLabel ){ | |
| 31737 int jj; | |
| 31738 for(jj=0; jj<ArraySize(aLabel); jj++){ | |
| 31739 if( sqlite3_stricmp(zLabel, aLabel[jj].zLabel)==0 ) break; | |
| 31740 } | |
| 31741 if( jj>=ArraySize(aLabel) ){ | |
| 31742 sqlite3_fprintf(stderr, | |
| 31743 "Error: no such optimization: \"%s\"\n", zLabel); | |
| 31744 sqlite3_fputs("Should be one of:", stderr); | |
| 31745 for(jj=0; jj<ArraySize(aLabel); jj++){ | |
| 31746 sqlite3_fprintf(stderr," %s", aLabel[jj].zLabel); | |
| 31747 } | |
| 31748 sqlite3_fputs("\n", stderr); | |
| 31749 rc = 1; | |
| 31750 goto meta_command_exit; | |
| 31751 } | |
| 31752 if( useLabel=='+' ){ | |
| 31753 newOpt &= ~aLabel[jj].mask; | |
| 31754 }else{ | |
| 31755 newOpt |= aLabel[jj].mask; | |
| 31756 } | |
| 31757 } | |
| 31758 } | |
| 31759 if( curOpt!=newOpt ){ | |
| 31760 sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,p->db,newOpt); | |
| 31761 } | |
| 31762 for(ii=nOff=0, m=1; ii<32; ii++, m <<= 1){ | |
| 31763 if( m & newOpt ) nOff++; | |
| 31764 } | |
| 31765 if( nOff<12 ){ | |
| 31766 sqlite3_fputs("+All", p->out); | |
| 31767 for(ii=0; ii<ArraySize(aLabel); ii++){ | |
| 31768 if( !aLabel[ii].bDsply ) continue; | |
| 31769 if( (newOpt & aLabel[ii].mask)!=0 ){ | |
| 31770 sqlite3_fprintf(p->out, " -%s", aLabel[ii].zLabel); | |
| 31771 } | |
| 31772 } | |
| 31773 }else{ | |
| 31774 sqlite3_fputs("-All", p->out); | |
| 31775 for(ii=0; ii<ArraySize(aLabel); ii++){ | |
| 31776 if( !aLabel[ii].bDsply ) continue; | |
| 31777 if( (newOpt & aLabel[ii].mask)==0 ){ | |
| 31778 sqlite3_fprintf(p->out, " +%s", aLabel[ii].zLabel); | |
| 31779 } | |
| 31780 } | |
| 31781 } | |
| 31782 sqlite3_fputs("\n", p->out); | |
| 31783 rc2 = isOk = 3; | |
| 31784 break; | |
| 31785 } | |
| 31786 | |
| 31787 /* sqlite3_test_control(int, db, int) */ | |
| 31788 case SQLITE_TESTCTRL_FK_NO_ACTION: | |
| 31789 if( nArg==3 ){ | |
| 31790 unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0); | |
| 31791 rc2 = sqlite3_test_control(testctrl, p->db, opt); | |
| 31792 isOk = 3; | |
| 31793 } | |
| 31794 break; | |
| 31795 | |
| 31796 /* sqlite3_test_control(int) */ | |
| 31797 case SQLITE_TESTCTRL_PRNG_SAVE: | |
| 31798 case SQLITE_TESTCTRL_PRNG_RESTORE: | |
| 31799 case SQLITE_TESTCTRL_BYTEORDER: | |
| 31800 if( nArg==2 ){ | |
| 31801 rc2 = sqlite3_test_control(testctrl); | |
| 31802 isOk = testctrl==SQLITE_TESTCTRL_BYTEORDER ? 1 : 3; | |
| 31803 } | |
| 31804 break; | |
| 31805 | |
| 31806 /* sqlite3_test_control(int, uint) */ | |
| 31807 case SQLITE_TESTCTRL_PENDING_BYTE: | |
| 31808 if( nArg==3 ){ | |
| 31809 unsigned int opt = (unsigned int)integerValue(azArg[2]); | |
| 31810 rc2 = sqlite3_test_control(testctrl, opt); | |
| 31811 isOk = 3; | |
| 31812 } | |
| 31813 break; | |
| 31814 | |
| 31815 /* sqlite3_test_control(int, int, sqlite3*) */ | |
| 31816 case SQLITE_TESTCTRL_PRNG_SEED: | |
| 31817 if( nArg==3 || nArg==4 ){ | |
| 31818 int ii = (int)integerValue(azArg[2]); | |
| 31819 sqlite3 *db; | |
| 31820 if( ii==0 && cli_strcmp(azArg[2],"random")==0 ){ | |
| 31821 sqlite3_randomness(sizeof(ii),&ii); | |
| 31822 sqlite3_fprintf(stdout, "-- random seed: %d\n", ii); | |
| 31823 } | |
| 31824 if( nArg==3 ){ | |
| 31825 db = 0; | |
| 31826 }else{ | |
| 31827 db = p->db; | |
| 31828 /* Make sure the schema has been loaded */ | |
| 31829 sqlite3_table_column_metadata(db, 0, "x", 0, 0, 0, 0, 0, 0); | |
| 31830 } | |
| 31831 rc2 = sqlite3_test_control(testctrl, ii, db); | |
| 31832 isOk = 3; | |
| 31833 } | |
| 31834 break; | |
| 31835 | |
| 31836 /* sqlite3_test_control(int, int) */ | |
| 31837 case SQLITE_TESTCTRL_ASSERT: | |
| 31838 case SQLITE_TESTCTRL_ALWAYS: | |
| 31839 if( nArg==3 ){ | |
| 31840 int opt = booleanValue(azArg[2]); | |
| 31841 rc2 = sqlite3_test_control(testctrl, opt); | |
| 31842 isOk = 1; | |
| 31843 } | |
| 31844 break; | |
| 31845 | |
| 31846 /* sqlite3_test_control(int, int) */ | |
| 31847 case SQLITE_TESTCTRL_LOCALTIME_FAULT: | |
| 31848 case SQLITE_TESTCTRL_NEVER_CORRUPT: | |
| 31849 if( nArg==3 ){ | |
| 31850 int opt = booleanValue(azArg[2]); | |
| 31851 rc2 = sqlite3_test_control(testctrl, opt); | |
| 31852 isOk = 3; | |
| 31853 } | |
| 31854 break; | |
| 31855 | |
| 31856 /* sqlite3_test_control(sqlite3*) */ | |
| 31857 case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: | |
| 31858 rc2 = sqlite3_test_control(testctrl, p->db); | |
| 31859 isOk = 3; | |
| 31860 break; | |
| 31861 | |
| 31862 case SQLITE_TESTCTRL_IMPOSTER: | |
| 31863 if( nArg==5 ){ | |
| 31864 rc2 = sqlite3_test_control(testctrl, p->db, | |
| 31865 azArg[2], | |
| 31866 integerValue(azArg[3]), | |
| 31867 integerValue(azArg[4])); | |
| 31868 isOk = 3; | |
| 31869 } | |
| 31870 break; | |
| 31871 | |
| 31872 case SQLITE_TESTCTRL_SEEK_COUNT: { | |
| 31873 u64 x = 0; | |
| 31874 rc2 = sqlite3_test_control(testctrl, p->db, &x); | |
| 31875 sqlite3_fprintf(p->out, "%llu\n", x); | |
| 31876 isOk = 3; | |
| 31877 break; | |
| 31878 } | |
| 31879 | |
| 31880 #ifdef YYCOVERAGE | |
| 31881 case SQLITE_TESTCTRL_PARSER_COVERAGE: { | |
| 31882 if( nArg==2 ){ | |
| 31883 sqlite3_test_control(testctrl, p->out); | |
| 31884 isOk = 3; | |
| 31885 } | |
| 31886 break; | |
| 31887 } | |
| 31888 #endif | |
| 31889 #ifdef SQLITE_DEBUG | |
| 31890 case SQLITE_TESTCTRL_TUNE: { | |
| 31891 if( nArg==4 ){ | |
| 31892 int id = (int)integerValue(azArg[2]); | |
| 31893 int val = (int)integerValue(azArg[3]); | |
| 31894 sqlite3_test_control(testctrl, id, &val); | |
| 31895 isOk = 3; | |
| 31896 }else if( nArg==3 ){ | |
| 31897 int id = (int)integerValue(azArg[2]); | |
| 31898 sqlite3_test_control(testctrl, -id, &rc2); | |
| 31899 isOk = 1; | |
| 31900 }else if( nArg==2 ){ | |
| 31901 int id = 1; | |
| 31902 while(1){ | |
| 31903 int val = 0; | |
| 31904 rc2 = sqlite3_test_control(testctrl, -id, &val); | |
| 31905 if( rc2!=SQLITE_OK ) break; | |
| 31906 if( id>1 ) sqlite3_fputs(" ", p->out); | |
| 31907 sqlite3_fprintf(p->out, "%d: %d", id, val); | |
| 31908 id++; | |
| 31909 } | |
| 31910 if( id>1 ) sqlite3_fputs("\n", p->out); | |
| 31911 isOk = 3; | |
| 31912 } | |
| 31913 break; | |
| 31914 } | |
| 31915 #endif | |
| 31916 case SQLITE_TESTCTRL_SORTER_MMAP: | |
| 31917 if( nArg==3 ){ | |
| 31918 int opt = (unsigned int)integerValue(azArg[2]); | |
| 31919 rc2 = sqlite3_test_control(testctrl, p->db, opt); | |
| 31920 isOk = 3; | |
| 31921 } | |
| 31922 break; | |
| 31923 case SQLITE_TESTCTRL_JSON_SELFCHECK: | |
| 31924 if( nArg==2 ){ | |
| 31925 rc2 = -1; | |
| 31926 isOk = 1; | |
| 31927 }else{ | |
| 31928 rc2 = booleanValue(azArg[2]); | |
| 31929 isOk = 3; | |
| 31930 } | |
| 31931 sqlite3_test_control(testctrl, &rc2); | |
| 31932 break; | |
| 31933 case SQLITE_TESTCTRL_BITVEC_TEST: { | |
| 31934 /* Examples: | |
| 31935 ** .testctrl bitvec_test 100 6,1 -- Show BITVEC constants | |
| 31936 ** .testctrl bitvec_test 1000 1,12,7,3 -- Simple test | |
| 31937 ** ---- -------- | |
| 31938 ** size of Bitvec -----^ ^--- aOp array. 0 added at end. | |
| 31939 ** | |
| 31940 ** See comments on sqlite3BitvecBuiltinTest() for more information | |
| 31941 ** about the aOp[] array. | |
| 31942 */ | |
| 31943 int iSize; | |
| 31944 const char *zTestArg; | |
| 31945 int nOp; | |
| 31946 int ii, jj, x; | |
| 31947 int *aOp; | |
| 31948 if( nArg!=4 ){ | |
| 31949 sqlite3_fprintf(stderr, | |
| 31950 "ERROR - should be: \".testctrl bitvec_test SIZE INT-ARRAY\"\n" | |
| 31951 ); | |
| 31952 rc = 1; | |
| 31953 goto meta_command_exit; | |
| 31954 } | |
| 31955 isOk = 3; | |
| 31956 iSize = (int)integerValue(azArg[2]); | |
| 31957 zTestArg = azArg[3]; | |
| 31958 nOp = (int)strlen(zTestArg)+1; | |
| 31959 aOp = malloc( sizeof(int)*(nOp+1) ); | |
| 31960 shell_check_oom(aOp); | |
| 31961 memset(aOp, 0, sizeof(int)*(nOp+1) ); | |
| 31962 for(ii = jj = x = 0; zTestArg[ii]!=0; ii++){ | |
| 31963 if( IsDigit(zTestArg[ii]) ){ | |
| 31964 x = x*10 + zTestArg[ii] - '0'; | |
| 31965 }else{ | |
| 31966 aOp[jj++] = x; | |
| 31967 x = 0; | |
| 31968 } | |
| 31969 } | |
| 31970 aOp[jj] = x; | |
| 31971 x = sqlite3_test_control(testctrl, iSize, aOp); | |
| 31972 sqlite3_fprintf(p->out, "result: %d\n", x); | |
| 31973 free(aOp); | |
| 31974 break; | |
| 31975 } | |
| 31976 case SQLITE_TESTCTRL_FAULT_INSTALL: { | |
| 31977 int kk; | |
| 31978 int bShowHelp = nArg<=2; | |
| 31979 isOk = 3; | |
| 31980 for(kk=2; kk<nArg; kk++){ | |
| 31981 const char *z = azArg[kk]; | |
| 31982 if( z[0]=='-' && z[1]=='-' ) z++; | |
| 31983 if( cli_strcmp(z,"off")==0 ){ | |
| 31984 sqlite3_test_control(testctrl, 0); | |
| 31985 }else if( cli_strcmp(z,"on")==0 ){ | |
| 31986 faultsim_state.iCnt = faultsim_state.nSkip; | |
| 31987 if( faultsim_state.iErr==0 ) faultsim_state.iErr = 1; | |
| 31988 faultsim_state.nHit = 0; | |
| 31989 sqlite3_test_control(testctrl, faultsim_callback); | |
| 31990 }else if( cli_strcmp(z,"reset")==0 ){ | |
| 31991 faultsim_state.iCnt = faultsim_state.nSkip; | |
| 31992 faultsim_state.nHit = 0; | |
| 31993 sqlite3_test_control(testctrl, faultsim_callback); | |
| 31994 }else if( cli_strcmp(z,"status")==0 ){ | |
| 31995 sqlite3_fprintf(p->out, "faultsim.iId: %d\n", | |
| 31996 faultsim_state.iId); | |
| 31997 sqlite3_fprintf(p->out, "faultsim.iErr: %d\n", | |
| 31998 faultsim_state.iErr); | |
| 31999 sqlite3_fprintf(p->out, "faultsim.iCnt: %d\n", | |
| 32000 faultsim_state.iCnt); | |
| 32001 sqlite3_fprintf(p->out, "faultsim.nHit: %d\n", | |
| 32002 faultsim_state.nHit); | |
| 32003 sqlite3_fprintf(p->out, "faultsim.iInterval: %d\n", | |
| 32004 faultsim_state.iInterval); | |
| 32005 sqlite3_fprintf(p->out, "faultsim.eVerbose: %d\n", | |
| 32006 faultsim_state.eVerbose); | |
| 32007 sqlite3_fprintf(p->out, "faultsim.nRepeat: %d\n", | |
| 32008 faultsim_state.nRepeat); | |
| 32009 sqlite3_fprintf(p->out, "faultsim.nSkip: %d\n", | |
| 32010 faultsim_state.nSkip); | |
| 32011 }else if( cli_strcmp(z,"-v")==0 ){ | |
| 32012 if( faultsim_state.eVerbose<2 ) faultsim_state.eVerbose++; | |
| 32013 }else if( cli_strcmp(z,"-q")==0 ){ | |
| 32014 if( faultsim_state.eVerbose>0 ) faultsim_state.eVerbose--; | |
| 32015 }else if( cli_strcmp(z,"-id")==0 && kk+1<nArg ){ | |
| 32016 faultsim_state.iId = atoi(azArg[++kk]); | |
| 32017 }else if( cli_strcmp(z,"-errcode")==0 && kk+1<nArg ){ | |
| 32018 faultsim_state.iErr = atoi(azArg[++kk]); | |
| 32019 }else if( cli_strcmp(z,"-interval")==0 && kk+1<nArg ){ | |
| 32020 faultsim_state.iInterval = atoi(azArg[++kk]); | |
| 32021 }else if( cli_strcmp(z,"-repeat")==0 && kk+1<nArg ){ | |
| 32022 faultsim_state.nRepeat = atoi(azArg[++kk]); | |
| 32023 }else if( cli_strcmp(z,"-skip")==0 && kk+1<nArg ){ | |
| 32024 faultsim_state.nSkip = atoi(azArg[++kk]); | |
| 32025 }else if( cli_strcmp(z,"-?")==0 || sqlite3_strglob("*help*",z)==0){ | |
| 32026 bShowHelp = 1; | |
| 32027 }else{ | |
| 32028 sqlite3_fprintf(stderr, | |
| 32029 "Unrecognized fault_install argument: \"%s\"\n", | |
| 32030 azArg[kk]); | |
| 32031 rc = 1; | |
| 32032 bShowHelp = 1; | |
| 32033 break; | |
| 32034 } | |
| 32035 } | |
| 32036 if( bShowHelp ){ | |
| 32037 sqlite3_fputs( | |
| 32038 "Usage: .testctrl fault_install ARGS\n" | |
| 32039 "Possible arguments:\n" | |
| 32040 " off Disable faultsim\n" | |
| 32041 " on Activate faultsim\n" | |
| 32042 " reset Reset the trigger counter\n" | |
| 32043 " status Show current status\n" | |
| 32044 " -v Increase verbosity\n" | |
| 32045 " -q Decrease verbosity\n" | |
| 32046 " --errcode N When triggered, return N as error code\n" | |
| 32047 " --id ID Trigger only for the ID specified\n" | |
| 32048 " --interval N Trigger only after every N-th call\n" | |
| 32049 " --repeat N Turn off after N hits. 0 means never\n" | |
| 32050 " --skip N Skip the first N encounters\n" | |
| 32051 ,p->out | |
| 32052 ); | |
| 32053 } | |
| 32054 break; | |
| 32055 } | |
| 32056 } | |
| 32057 } | |
| 32058 if( isOk==0 && iCtrl>=0 ){ | |
| 32059 sqlite3_fprintf(p->out, | |
| 32060 "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); | |
| 32061 rc = 1; | |
| 32062 }else if( isOk==1 ){ | |
| 32063 sqlite3_fprintf(p->out, "%d\n", rc2); | |
| 32064 }else if( isOk==2 ){ | |
| 32065 sqlite3_fprintf(p->out, "0x%08x\n", rc2); | |
| 32066 } | |
| 32067 }else | |
| 32068 #endif /* !defined(SQLITE_UNTESTABLE) */ | |
| 32069 | |
| 32070 if( c=='t' && n>4 && cli_strncmp(azArg[0], "timeout", n)==0 ){ | |
| 32071 open_db(p, 0); | |
| 32072 sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0); | |
| 32073 }else | |
| 32074 | |
| 32075 if( c=='t' && n>=5 && cli_strncmp(azArg[0], "timer", n)==0 ){ | |
| 32076 if( nArg==2 ){ | |
| 32077 enableTimer = booleanValue(azArg[1]); | |
| 32078 if( enableTimer && !HAS_TIMER ){ | |
| 32079 eputz("Error: timer not available on this system.\n"); | |
| 32080 enableTimer = 0; | |
| 32081 } | |
| 32082 }else{ | |
| 32083 eputz("Usage: .timer on|off\n"); | |
| 32084 rc = 1; | |
| 32085 } | |
| 32086 }else | |
| 32087 | |
| 32088 #ifndef SQLITE_OMIT_TRACE | |
| 32089 if( c=='t' && cli_strncmp(azArg[0], "trace", n)==0 ){ | |
| 32090 int mType = 0; | |
| 32091 int jj; | |
| 32092 open_db(p, 0); | |
| 32093 for(jj=1; jj<nArg; jj++){ | |
| 32094 const char *z = azArg[jj]; | |
| 32095 if( z[0]=='-' ){ | |
| 32096 if( optionMatch(z, "expanded") ){ | |
| 32097 p->eTraceType = SHELL_TRACE_EXPANDED; | |
| 32098 } | |
| 32099 #ifdef SQLITE_ENABLE_NORMALIZE | |
| 32100 else if( optionMatch(z, "normalized") ){ | |
| 32101 p->eTraceType = SHELL_TRACE_NORMALIZED; | |
| 32102 } | |
| 32103 #endif | |
| 32104 else if( optionMatch(z, "plain") ){ | |
| 32105 p->eTraceType = SHELL_TRACE_PLAIN; | |
| 32106 } | |
| 32107 else if( optionMatch(z, "profile") ){ | |
| 32108 mType |= SQLITE_TRACE_PROFILE; | |
| 32109 } | |
| 32110 else if( optionMatch(z, "row") ){ | |
| 32111 mType |= SQLITE_TRACE_ROW; | |
| 32112 } | |
| 32113 else if( optionMatch(z, "stmt") ){ | |
| 32114 mType |= SQLITE_TRACE_STMT; | |
| 32115 } | |
| 32116 else if( optionMatch(z, "close") ){ | |
| 32117 mType |= SQLITE_TRACE_CLOSE; | |
| 32118 } | |
| 32119 else { | |
| 32120 sqlite3_fprintf(stderr,"Unknown option \"%s\" on \".trace\"\n", z); | |
| 32121 rc = 1; | |
| 32122 goto meta_command_exit; | |
| 32123 } | |
| 32124 }else{ | |
| 32125 output_file_close(p->traceOut); | |
| 32126 p->traceOut = output_file_open(z); | |
| 32127 } | |
| 32128 } | |
| 32129 if( p->traceOut==0 ){ | |
| 32130 sqlite3_trace_v2(p->db, 0, 0, 0); | |
| 32131 }else{ | |
| 32132 if( mType==0 ) mType = SQLITE_TRACE_STMT; | |
| 32133 sqlite3_trace_v2(p->db, mType, sql_trace_callback, p); | |
| 32134 } | |
| 32135 }else | |
| 32136 #endif /* !defined(SQLITE_OMIT_TRACE) */ | |
| 32137 | |
| 32138 #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE) | |
| 32139 if( c=='u' && cli_strncmp(azArg[0], "unmodule", n)==0 ){ | |
| 32140 int ii; | |
| 32141 int lenOpt; | |
| 32142 char *zOpt; | |
| 32143 if( nArg<2 ){ | |
| 32144 eputz("Usage: .unmodule [--allexcept] NAME ...\n"); | |
| 32145 rc = 1; | |
| 32146 goto meta_command_exit; | |
| 32147 } | |
| 32148 open_db(p, 0); | |
| 32149 zOpt = azArg[1]; | |
| 32150 if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++; | |
| 32151 lenOpt = (int)strlen(zOpt); | |
| 32152 if( lenOpt>=3 && cli_strncmp(zOpt, "-allexcept",lenOpt)==0 ){ | |
| 32153 assert( azArg[nArg]==0 ); | |
| 32154 sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0); | |
| 32155 }else{ | |
| 32156 for(ii=1; ii<nArg; ii++){ | |
| 32157 sqlite3_create_module(p->db, azArg[ii], 0, 0); | |
| 32158 } | |
| 32159 } | |
| 32160 }else | |
| 32161 #endif | |
| 32162 | |
| 32163 if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){ | |
| 32164 char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit"; | |
| 32165 sqlite3_fprintf(p->out, "SQLite %s %s\n" /*extra-version-info*/, | |
| 32166 sqlite3_libversion(), sqlite3_sourceid()); | |
| 32167 #if SQLITE_HAVE_ZLIB | |
| 32168 sqlite3_fprintf(p->out, "zlib version %s\n", zlibVersion()); | |
| 32169 #endif | |
| 32170 #define CTIMEOPT_VAL_(opt) #opt | |
| 32171 #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) | |
| 32172 #if defined(__clang__) && defined(__clang_major__) | |
| 32173 sqlite3_fprintf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "." | |
| 32174 CTIMEOPT_VAL(__clang_minor__) "." | |
| 32175 CTIMEOPT_VAL(__clang_patchlevel__) " (%s)\n", zPtrSz); | |
| 32176 #elif defined(_MSC_VER) | |
| 32177 sqlite3_fprintf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz); | |
| 32178 #elif defined(__GNUC__) && defined(__VERSION__) | |
| 32179 sqlite3_fprintf(p->out, "gcc-" __VERSION__ " (%s)\n", zPtrSz); | |
| 32180 #endif | |
| 32181 }else | |
| 32182 | |
| 32183 if( c=='v' && cli_strncmp(azArg[0], "vfsinfo", n)==0 ){ | |
| 32184 const char *zDbName = nArg==2 ? azArg[1] : "main"; | |
| 32185 sqlite3_vfs *pVfs = 0; | |
| 32186 if( p->db ){ | |
| 32187 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs); | |
| 32188 if( pVfs ){ | |
| 32189 sqlite3_fprintf(p->out, "vfs.zName = \"%s\"\n", pVfs->zName); | |
| 32190 sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); | |
| 32191 sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); | |
| 32192 sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); | |
| 32193 } | |
| 32194 } | |
| 32195 }else | |
| 32196 | |
| 32197 if( c=='v' && cli_strncmp(azArg[0], "vfslist", n)==0 ){ | |
| 32198 sqlite3_vfs *pVfs; | |
| 32199 sqlite3_vfs *pCurrent = 0; | |
| 32200 if( p->db ){ | |
| 32201 sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent); | |
| 32202 } | |
| 32203 for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){ | |
| 32204 sqlite3_fprintf(p->out, "vfs.zName = \"%s\"%s\n", pVfs->zName, | |
| 32205 pVfs==pCurrent ? " <--- CURRENT" : ""); | |
| 32206 sqlite3_fprintf(p->out, "vfs.iVersion = %d\n", pVfs->iVersion); | |
| 32207 sqlite3_fprintf(p->out, "vfs.szOsFile = %d\n", pVfs->szOsFile); | |
| 32208 sqlite3_fprintf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname); | |
| 32209 if( pVfs->pNext ){ | |
| 32210 sqlite3_fputs("-----------------------------------\n", p->out); | |
| 32211 } | |
| 32212 } | |
| 32213 }else | |
| 32214 | |
| 32215 if( c=='v' && cli_strncmp(azArg[0], "vfsname", n)==0 ){ | |
| 32216 const char *zDbName = nArg==2 ? azArg[1] : "main"; | |
| 32217 char *zVfsName = 0; | |
| 32218 if( p->db ){ | |
| 32219 sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName); | |
| 32220 if( zVfsName ){ | |
| 32221 sqlite3_fprintf(p->out, "%s\n", zVfsName); | |
| 32222 sqlite3_free(zVfsName); | |
| 32223 } | |
| 32224 } | |
| 32225 }else | |
| 32226 | |
| 32227 if( c=='w' && cli_strncmp(azArg[0], "wheretrace", n)==0 ){ | |
| 32228 unsigned int x = nArg>=2? (unsigned int)integerValue(azArg[1]) : 0xffffffff; | |
| 32229 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x); | |
| 32230 }else | |
| 32231 | |
| 32232 if( c=='w' && cli_strncmp(azArg[0], "width", n)==0 ){ | |
| 32233 int j; | |
| 32234 assert( nArg<=ArraySize(azArg) ); | |
| 32235 p->nWidth = nArg-1; | |
| 32236 p->colWidth = realloc(p->colWidth, (p->nWidth+1)*sizeof(int)*2); | |
| 32237 if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory(); | |
| 32238 if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth]; | |
| 32239 for(j=1; j<nArg; j++){ | |
| 32240 i64 w = integerValue(azArg[j]); | |
| 32241 if( w < -30000 ) w = -30000; | |
| 32242 if( w > +30000 ) w = +30000; | |
| 32243 p->colWidth[j-1] = (int)w; | |
| 32244 } | |
| 32245 }else | |
| 32246 | |
| 32247 { | |
| 32248 sqlite3_fprintf(stderr,"Error: unknown command or invalid arguments: " | |
| 32249 " \"%s\". Enter \".help\" for help\n", azArg[0]); | |
| 32250 rc = 1; | |
| 32251 } | |
| 32252 | |
| 32253 meta_command_exit: | |
| 32254 if( p->outCount ){ | |
| 32255 p->outCount--; | |
| 32256 if( p->outCount==0 ) output_reset(p); | |
| 32257 } | |
| 32258 p->bSafeMode = p->bSafeModePersist; | |
| 32259 return rc; | |
| 32260 } | |
| 32261 | |
| 32262 /* Line scan result and intermediate states (supporting scan resumption) | |
| 32263 */ | |
| 32264 #ifndef CHAR_BIT | |
| 32265 # define CHAR_BIT 8 | |
| 32266 #endif | |
| 32267 typedef enum { | |
| 32268 QSS_HasDark = 1<<CHAR_BIT, QSS_EndingSemi = 2<<CHAR_BIT, | |
| 32269 QSS_CharMask = (1<<CHAR_BIT)-1, QSS_ScanMask = 3<<CHAR_BIT, | |
| 32270 QSS_Start = 0 | |
| 32271 } QuickScanState; | |
| 32272 #define QSS_SETV(qss, newst) ((newst) | ((qss) & QSS_ScanMask)) | |
| 32273 #define QSS_INPLAIN(qss) (((qss)&QSS_CharMask)==QSS_Start) | |
| 32274 #define QSS_PLAINWHITE(qss) (((qss)&~QSS_EndingSemi)==QSS_Start) | |
| 32275 #define QSS_PLAINDARK(qss) (((qss)&~QSS_EndingSemi)==QSS_HasDark) | |
| 32276 #define QSS_SEMITERM(qss) (((qss)&~QSS_HasDark)==QSS_EndingSemi) | |
| 32277 | |
| 32278 /* | |
| 32279 ** Scan line for classification to guide shell's handling. | |
| 32280 ** The scan is resumable for subsequent lines when prior | |
| 32281 ** return values are passed as the 2nd argument. | |
| 32282 */ | |
| 32283 static QuickScanState quickscan(char *zLine, QuickScanState qss, | |
| 32284 SCAN_TRACKER_REFTYPE pst){ | |
| 32285 char cin; | |
| 32286 char cWait = (char)qss; /* intentional narrowing loss */ | |
| 32287 if( cWait==0 ){ | |
| 32288 PlainScan: | |
| 32289 while( (cin = *zLine++)!=0 ){ | |
| 32290 if( IsSpace(cin) ) | |
| 32291 continue; | |
| 32292 switch (cin){ | |
| 32293 case '-': | |
| 32294 if( *zLine!='-' ) | |
| 32295 break; | |
| 32296 while((cin = *++zLine)!=0 ) | |
| 32297 if( cin=='\n') | |
| 32298 goto PlainScan; | |
| 32299 return qss; | |
| 32300 case ';': | |
| 32301 qss |= QSS_EndingSemi; | |
| 32302 continue; | |
| 32303 case '/': | |
| 32304 if( *zLine=='*' ){ | |
| 32305 ++zLine; | |
| 32306 cWait = '*'; | |
| 32307 CONTINUE_PROMPT_AWAITS(pst, "/*"); | |
| 32308 qss = QSS_SETV(qss, cWait); | |
| 32309 goto TermScan; | |
| 32310 } | |
| 32311 break; | |
| 32312 case '[': | |
| 32313 cin = ']'; | |
| 32314 deliberate_fall_through; /* FALLTHRU */ | |
| 32315 case '`': case '\'': case '"': | |
| 32316 cWait = cin; | |
| 32317 qss = QSS_HasDark | cWait; | |
| 32318 CONTINUE_PROMPT_AWAITC(pst, cin); | |
| 32319 goto TermScan; | |
| 32320 case '(': | |
| 32321 CONTINUE_PAREN_INCR(pst, 1); | |
| 32322 break; | |
| 32323 case ')': | |
| 32324 CONTINUE_PAREN_INCR(pst, -1); | |
| 32325 break; | |
| 32326 default: | |
| 32327 break; | |
| 32328 } | |
| 32329 qss = (qss & ~QSS_EndingSemi) | QSS_HasDark; | |
| 32330 } | |
| 32331 }else{ | |
| 32332 TermScan: | |
| 32333 while( (cin = *zLine++)!=0 ){ | |
| 32334 if( cin==cWait ){ | |
| 32335 switch( cWait ){ | |
| 32336 case '*': | |
| 32337 if( *zLine != '/' ) | |
| 32338 continue; | |
| 32339 ++zLine; | |
| 32340 CONTINUE_PROMPT_AWAITC(pst, 0); | |
| 32341 qss = QSS_SETV(qss, 0); | |
| 32342 goto PlainScan; | |
| 32343 case '`': case '\'': case '"': | |
| 32344 if(*zLine==cWait){ | |
| 32345 /* Swallow doubled end-delimiter.*/ | |
| 32346 ++zLine; | |
| 32347 continue; | |
| 32348 } | |
| 32349 deliberate_fall_through; /* FALLTHRU */ | |
| 32350 case ']': | |
| 32351 CONTINUE_PROMPT_AWAITC(pst, 0); | |
| 32352 qss = QSS_SETV(qss, 0); | |
| 32353 goto PlainScan; | |
| 32354 default: assert(0); | |
| 32355 } | |
| 32356 } | |
| 32357 } | |
| 32358 } | |
| 32359 return qss; | |
| 32360 } | |
| 32361 | |
| 32362 /* | |
| 32363 ** Return TRUE if the line typed in is an SQL command terminator other | |
| 32364 ** than a semi-colon. The SQL Server style "go" command is understood | |
| 32365 ** as is the Oracle "/". | |
| 32366 */ | |
| 32367 static int line_is_command_terminator(char *zLine){ | |
| 32368 while( IsSpace(zLine[0]) ){ zLine++; }; | |
| 32369 if( zLine[0]=='/' ) | |
| 32370 zLine += 1; /* Oracle */ | |
| 32371 else if ( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o' ) | |
| 32372 zLine += 2; /* SQL Server */ | |
| 32373 else | |
| 32374 return 0; | |
| 32375 return quickscan(zLine, QSS_Start, 0)==QSS_Start; | |
| 32376 } | |
| 32377 | |
| 32378 /* | |
| 32379 ** The CLI needs a working sqlite3_complete() to work properly. So error | |
| 32380 ** out of the build if compiling with SQLITE_OMIT_COMPLETE. | |
| 32381 */ | |
| 32382 #ifdef SQLITE_OMIT_COMPLETE | |
| 32383 # error the CLI application is incompatible with SQLITE_OMIT_COMPLETE. | |
| 32384 #endif | |
| 32385 | |
| 32386 /* | |
| 32387 ** Return true if zSql is a complete SQL statement. Return false if it | |
| 32388 ** ends in the middle of a string literal or C-style comment. | |
| 32389 */ | |
| 32390 static int line_is_complete(char *zSql, int nSql){ | |
| 32391 int rc; | |
| 32392 if( zSql==0 ) return 1; | |
| 32393 zSql[nSql] = ';'; | |
| 32394 zSql[nSql+1] = 0; | |
| 32395 rc = sqlite3_complete(zSql); | |
| 32396 zSql[nSql] = 0; | |
| 32397 return rc; | |
| 32398 } | |
| 32399 | |
| 32400 /* | |
| 32401 ** This function is called after processing each line of SQL in the | |
| 32402 ** runOneSqlLine() function. Its purpose is to detect scenarios where | |
| 32403 ** defensive mode should be automatically turned off. Specifically, when | |
| 32404 ** | |
| 32405 ** 1. The first line of input is "PRAGMA foreign_keys=OFF;", | |
| 32406 ** 2. The second line of input is "BEGIN TRANSACTION;", | |
| 32407 ** 3. The database is empty, and | |
| 32408 ** 4. The shell is not running in --safe mode. | |
| 32409 ** | |
| 32410 ** The implementation uses the ShellState.eRestoreState to maintain state: | |
| 32411 ** | |
| 32412 ** 0: Have not seen any SQL. | |
| 32413 ** 1: Have seen "PRAGMA foreign_keys=OFF;". | |
| 32414 ** 2-6: Currently running .dump transaction. If the "2" bit is set, | |
| 32415 ** disable DEFENSIVE when done. If "4" is set, disable DQS_DDL. | |
| 32416 ** 7: Nothing left to do. This function becomes a no-op. | |
| 32417 */ | |
| 32418 static int doAutoDetectRestore(ShellState *p, const char *zSql){ | |
| 32419 int rc = SQLITE_OK; | |
| 32420 | |
| 32421 if( p->eRestoreState<7 ){ | |
| 32422 switch( p->eRestoreState ){ | |
| 32423 case 0: { | |
| 32424 const char *zExpect = "PRAGMA foreign_keys=OFF;"; | |
| 32425 assert( strlen(zExpect)==24 ); | |
| 32426 if( p->bSafeMode==0 | |
| 32427 && strlen(zSql)>=24 | |
| 32428 && memcmp(zSql, zExpect, 25)==0 | |
| 32429 ){ | |
| 32430 p->eRestoreState = 1; | |
| 32431 }else{ | |
| 32432 p->eRestoreState = 7; | |
| 32433 } | |
| 32434 break; | |
| 32435 }; | |
| 32436 | |
| 32437 case 1: { | |
| 32438 int bIsDump = 0; | |
| 32439 const char *zExpect = "BEGIN TRANSACTION;"; | |
| 32440 assert( strlen(zExpect)==18 ); | |
| 32441 if( memcmp(zSql, zExpect, 19)==0 ){ | |
| 32442 /* Now check if the database is empty. */ | |
| 32443 const char *zQuery = "SELECT 1 FROM sqlite_schema LIMIT 1"; | |
| 32444 sqlite3_stmt *pStmt = 0; | |
| 32445 | |
| 32446 bIsDump = 1; | |
| 32447 shellPrepare(p->db, &rc, zQuery, &pStmt); | |
| 32448 if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ | |
| 32449 bIsDump = 0; | |
| 32450 } | |
| 32451 shellFinalize(&rc, pStmt); | |
| 32452 } | |
| 32453 if( bIsDump && rc==SQLITE_OK ){ | |
| 32454 int bDefense = 0; | |
| 32455 int bDqsDdl = 0; | |
| 32456 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &bDefense); | |
| 32457 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DQS_DDL, -1, &bDqsDdl); | |
| 32458 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0); | |
| 32459 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DQS_DDL, 1, 0); | |
| 32460 p->eRestoreState = (bDefense ? 2 : 0) + (bDqsDdl ? 4 : 0); | |
| 32461 }else{ | |
| 32462 p->eRestoreState = 7; | |
| 32463 } | |
| 32464 break; | |
| 32465 } | |
| 32466 | |
| 32467 default: { | |
| 32468 if( sqlite3_get_autocommit(p->db) ){ | |
| 32469 if( (p->eRestoreState & 2) ){ | |
| 32470 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 1, 0); | |
| 32471 } | |
| 32472 if( (p->eRestoreState & 4) ){ | |
| 32473 sqlite3_db_config(p->db, SQLITE_DBCONFIG_DQS_DDL, 0, 0); | |
| 32474 } | |
| 32475 p->eRestoreState = 7; | |
| 32476 } | |
| 32477 break; | |
| 32478 } | |
| 32479 } | |
| 32480 } | |
| 32481 | |
| 32482 return rc; | |
| 32483 } | |
| 32484 | |
| 32485 /* | |
| 32486 ** Run a single line of SQL. Return the number of errors. | |
| 32487 */ | |
| 32488 static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){ | |
| 32489 int rc; | |
| 32490 char *zErrMsg = 0; | |
| 32491 | |
| 32492 open_db(p, 0); | |
| 32493 if( ShellHasFlag(p,SHFLG_Backslash) ) resolve_backslashes(zSql); | |
| 32494 if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0; | |
| 32495 BEGIN_TIMER; | |
| 32496 rc = shell_exec(p, zSql, &zErrMsg); | |
| 32497 END_TIMER(p->out); | |
| 32498 if( rc || zErrMsg ){ | |
| 32499 char zPrefix[100]; | |
| 32500 const char *zErrorTail; | |
| 32501 const char *zErrorType; | |
| 32502 if( zErrMsg==0 ){ | |
| 32503 zErrorType = "Error"; | |
| 32504 zErrorTail = sqlite3_errmsg(p->db); | |
| 32505 }else if( cli_strncmp(zErrMsg, "in prepare, ",12)==0 ){ | |
| 32506 zErrorType = "Parse error"; | |
| 32507 zErrorTail = &zErrMsg[12]; | |
| 32508 }else if( cli_strncmp(zErrMsg, "stepping, ", 10)==0 ){ | |
| 32509 zErrorType = "Runtime error"; | |
| 32510 zErrorTail = &zErrMsg[10]; | |
| 32511 }else{ | |
| 32512 zErrorType = "Error"; | |
| 32513 zErrorTail = zErrMsg; | |
| 32514 } | |
| 32515 if( in!=0 || !stdin_is_interactive ){ | |
| 32516 sqlite3_snprintf(sizeof(zPrefix), zPrefix, | |
| 32517 "%s near line %d:", zErrorType, startline); | |
| 32518 }else{ | |
| 32519 sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType); | |
| 32520 } | |
| 32521 sqlite3_fprintf(stderr,"%s %s\n", zPrefix, zErrorTail); | |
| 32522 sqlite3_free(zErrMsg); | |
| 32523 zErrMsg = 0; | |
| 32524 return 1; | |
| 32525 }else if( ShellHasFlag(p, SHFLG_CountChanges) ){ | |
| 32526 char zLineBuf[2000]; | |
| 32527 sqlite3_snprintf(sizeof(zLineBuf), zLineBuf, | |
| 32528 "changes: %lld total_changes: %lld", | |
| 32529 sqlite3_changes64(p->db), sqlite3_total_changes64(p->db)); | |
| 32530 sqlite3_fprintf(p->out, "%s\n", zLineBuf); | |
| 32531 } | |
| 32532 | |
| 32533 if( doAutoDetectRestore(p, zSql) ) return 1; | |
| 32534 return 0; | |
| 32535 } | |
| 32536 | |
| 32537 static void echo_group_input(ShellState *p, const char *zDo){ | |
| 32538 if( ShellHasFlag(p, SHFLG_Echo) ){ | |
| 32539 sqlite3_fprintf(p->out, "%s\n", zDo); | |
| 32540 fflush(p->out); | |
| 32541 } | |
| 32542 } | |
| 32543 | |
| 32544 #ifdef SQLITE_SHELL_FIDDLE | |
| 32545 /* | |
| 32546 ** Alternate one_input_line() impl for wasm mode. This is not in the primary | |
| 32547 ** impl because we need the global shellState and cannot access it from that | |
| 32548 ** function without moving lots of code around (creating a larger/messier diff). | |
| 32549 */ | |
| 32550 static char *one_input_line(FILE *in, char *zPrior, int isContinuation){ | |
| 32551 /* Parse the next line from shellState.wasm.zInput. */ | |
| 32552 const char *zBegin = shellState.wasm.zPos; | |
| 32553 const char *z = zBegin; | |
| 32554 char *zLine = 0; | |
| 32555 i64 nZ = 0; | |
| 32556 | |
| 32557 UNUSED_PARAMETER(in); | |
| 32558 UNUSED_PARAMETER(isContinuation); | |
| 32559 if(!z || !*z){ | |
| 32560 return 0; | |
| 32561 } | |
| 32562 while(*z && IsSpace(*z)) ++z; | |
| 32563 zBegin = z; | |
| 32564 for(; *z && '\n'!=*z; ++nZ, ++z){} | |
| 32565 if(nZ>0 && '\r'==zBegin[nZ-1]){ | |
| 32566 --nZ; | |
| 32567 } | |
| 32568 shellState.wasm.zPos = z; | |
| 32569 zLine = realloc(zPrior, nZ+1); | |
| 32570 shell_check_oom(zLine); | |
| 32571 memcpy(zLine, zBegin, nZ); | |
| 32572 zLine[nZ] = 0; | |
| 32573 return zLine; | |
| 32574 } | |
| 32575 #endif /* SQLITE_SHELL_FIDDLE */ | |
| 32576 | |
| 32577 /* | |
| 32578 ** Read input from *in and process it. If *in==0 then input | |
| 32579 ** is interactive - the user is typing it it. Otherwise, input | |
| 32580 ** is coming from a file or device. A prompt is issued and history | |
| 32581 ** is saved only if input is interactive. An interrupt signal will | |
| 32582 ** cause this routine to exit immediately, unless input is interactive. | |
| 32583 ** | |
| 32584 ** Return the number of errors. | |
| 32585 */ | |
| 32586 static int process_input(ShellState *p, const char *zSrc){ | |
| 32587 char *zLine = 0; /* A single input line */ | |
| 32588 char *zSql = 0; /* Accumulated SQL text */ | |
| 32589 i64 nLine; /* Length of current line */ | |
| 32590 i64 nSql = 0; /* Bytes of zSql[] used */ | |
| 32591 i64 nAlloc = 0; /* Allocated zSql[] space */ | |
| 32592 int rc; /* Error code */ | |
| 32593 int errCnt = 0; /* Number of errors seen */ | |
| 32594 i64 startline = 0; /* Line number for start of current input */ | |
| 32595 QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */ | |
| 32596 | |
| 32597 if( p->inputNesting==MAX_INPUT_NESTING ){ | |
| 32598 /* This will be more informative in a later version. */ | |
| 32599 sqlite3_fprintf(stderr,"%s: Input nesting limit (%d) reached at line %lld." | |
| 32600 " Check recursion.\n", zSrc, MAX_INPUT_NESTING, p->lineno); | |
| 32601 return 1; | |
| 32602 } | |
| 32603 ++p->inputNesting; | |
| 32604 p->lineno = 0; | |
| 32605 CONTINUE_PROMPT_RESET; | |
| 32606 while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){ | |
| 32607 fflush(p->out); | |
| 32608 zLine = one_input_line(p->in, zLine, nSql>0); | |
| 32609 if( zLine==0 ){ | |
| 32610 /* End of input */ | |
| 32611 if( p->in==0 && stdin_is_interactive ) sqlite3_fputs("\n", p->out); | |
| 32612 break; | |
| 32613 } | |
| 32614 if( seenInterrupt ){ | |
| 32615 if( p->in!=0 ) break; | |
| 32616 seenInterrupt = 0; | |
| 32617 } | |
| 32618 p->lineno++; | |
| 32619 if( QSS_INPLAIN(qss) | |
| 32620 && line_is_command_terminator(zLine) | |
| 32621 && line_is_complete(zSql, nSql) ){ | |
| 32622 memcpy(zLine,";",2); | |
| 32623 } | |
| 32624 qss = quickscan(zLine, qss, CONTINUE_PROMPT_PSTATE); | |
| 32625 if( QSS_PLAINWHITE(qss) && nSql==0 ){ | |
| 32626 /* Just swallow single-line whitespace */ | |
| 32627 echo_group_input(p, zLine); | |
| 32628 qss = QSS_Start; | |
| 32629 continue; | |
| 32630 } | |
| 32631 if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){ | |
| 32632 CONTINUE_PROMPT_RESET; | |
| 32633 echo_group_input(p, zLine); | |
| 32634 if( zLine[0]=='.' ){ | |
| 32635 rc = do_meta_command(zLine, p); | |
| 32636 if( rc==2 ){ /* exit requested */ | |
| 32637 break; | |
| 32638 }else if( rc ){ | |
| 32639 errCnt++; | |
| 32640 } | |
| 32641 } | |
| 32642 qss = QSS_Start; | |
| 32643 continue; | |
| 32644 } | |
| 32645 /* No single-line dispositions remain; accumulate line(s). */ | |
| 32646 nLine = strlen(zLine); | |
| 32647 if( nSql+nLine+2>=nAlloc ){ | |
| 32648 /* Grow buffer by half-again increments when big. */ | |
| 32649 nAlloc = nSql+(nSql>>1)+nLine+100; | |
| 32650 zSql = realloc(zSql, nAlloc); | |
| 32651 shell_check_oom(zSql); | |
| 32652 } | |
| 32653 if( nSql==0 ){ | |
| 32654 i64 i; | |
| 32655 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} | |
| 32656 assert( nAlloc>0 && zSql!=0 ); | |
| 32657 memcpy(zSql, zLine+i, nLine+1-i); | |
| 32658 startline = p->lineno; | |
| 32659 nSql = nLine-i; | |
| 32660 }else{ | |
| 32661 zSql[nSql++] = '\n'; | |
| 32662 memcpy(zSql+nSql, zLine, nLine+1); | |
| 32663 nSql += nLine; | |
| 32664 } | |
| 32665 if( nSql>0x7fff0000 ){ | |
| 32666 char zSize[100]; | |
| 32667 sqlite3_snprintf(sizeof(zSize),zSize,"%,lld",nSql); | |
| 32668 sqlite3_fprintf(stderr, "%s:%lld: Input SQL is too big: %s bytes\n", | |
| 32669 zSrc, startline, zSize); | |
| 32670 nSql = 0; | |
| 32671 errCnt++; | |
| 32672 break; | |
| 32673 }else if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){ | |
| 32674 echo_group_input(p, zSql); | |
| 32675 errCnt += runOneSqlLine(p, zSql, p->in, startline); | |
| 32676 CONTINUE_PROMPT_RESET; | |
| 32677 nSql = 0; | |
| 32678 if( p->outCount ){ | |
| 32679 output_reset(p); | |
| 32680 p->outCount = 0; | |
| 32681 }else{ | |
| 32682 clearTempFile(p); | |
| 32683 } | |
| 32684 p->bSafeMode = p->bSafeModePersist; | |
| 32685 qss = QSS_Start; | |
| 32686 }else if( nSql && QSS_PLAINWHITE(qss) ){ | |
| 32687 echo_group_input(p, zSql); | |
| 32688 nSql = 0; | |
| 32689 qss = QSS_Start; | |
| 32690 } | |
| 32691 } | |
| 32692 if( nSql ){ | |
| 32693 /* This may be incomplete. Let the SQL parser deal with that. */ | |
| 32694 echo_group_input(p, zSql); | |
| 32695 errCnt += runOneSqlLine(p, zSql, p->in, startline); | |
| 32696 CONTINUE_PROMPT_RESET; | |
| 32697 } | |
| 32698 free(zSql); | |
| 32699 free(zLine); | |
| 32700 --p->inputNesting; | |
| 32701 return errCnt>0; | |
| 32702 } | |
| 32703 | |
| 32704 /* | |
| 32705 ** Return a pathname which is the user's home directory. A | |
| 32706 ** 0 return indicates an error of some kind. | |
| 32707 */ | |
| 32708 static char *find_home_dir(int clearFlag){ | |
| 32709 static char *home_dir = NULL; | |
| 32710 if( clearFlag ){ | |
| 32711 free(home_dir); | |
| 32712 home_dir = 0; | |
| 32713 return 0; | |
| 32714 } | |
| 32715 if( home_dir ) return home_dir; | |
| 32716 | |
| 32717 #if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \ | |
| 32718 && !defined(__RTP__) && !defined(_WRS_KERNEL) && !defined(SQLITE_WASI) | |
| 32719 { | |
| 32720 struct passwd *pwent; | |
| 32721 uid_t uid = getuid(); | |
| 32722 if( (pwent=getpwuid(uid)) != NULL) { | |
| 32723 home_dir = pwent->pw_dir; | |
| 32724 } | |
| 32725 } | |
| 32726 #endif | |
| 32727 | |
| 32728 #if defined(_WIN32_WCE) | |
| 32729 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide getenv() | |
| 32730 */ | |
| 32731 home_dir = "/"; | |
| 32732 #else | |
| 32733 | |
| 32734 #if defined(_WIN32) || defined(WIN32) | |
| 32735 if (!home_dir) { | |
| 32736 home_dir = getenv("USERPROFILE"); | |
| 32737 } | |
| 32738 #endif | |
| 32739 | |
| 32740 if (!home_dir) { | |
| 32741 home_dir = getenv("HOME"); | |
| 32742 } | |
| 32743 | |
| 32744 #if defined(_WIN32) || defined(WIN32) | |
| 32745 if (!home_dir) { | |
| 32746 char *zDrive, *zPath; | |
| 32747 int n; | |
| 32748 zDrive = getenv("HOMEDRIVE"); | |
| 32749 zPath = getenv("HOMEPATH"); | |
| 32750 if( zDrive && zPath ){ | |
| 32751 n = strlen30(zDrive) + strlen30(zPath) + 1; | |
| 32752 home_dir = malloc( n ); | |
| 32753 if( home_dir==0 ) return 0; | |
| 32754 sqlite3_snprintf(n, home_dir, "%s%s", zDrive, zPath); | |
| 32755 return home_dir; | |
| 32756 } | |
| 32757 home_dir = "c:\\"; | |
| 32758 } | |
| 32759 #endif | |
| 32760 | |
| 32761 #endif /* !_WIN32_WCE */ | |
| 32762 | |
| 32763 if( home_dir ){ | |
| 32764 i64 n = strlen(home_dir) + 1; | |
| 32765 char *z = malloc( n ); | |
| 32766 if( z ) memcpy(z, home_dir, n); | |
| 32767 home_dir = z; | |
| 32768 } | |
| 32769 | |
| 32770 return home_dir; | |
| 32771 } | |
| 32772 | |
| 32773 /* | |
| 32774 ** On non-Windows platforms, look for: | |
| 32775 ** | |
| 32776 ** - ${zEnvVar}/${zBaseName} | |
| 32777 ** - ${HOME}/${zSubdir}/${zBaseName} | |
| 32778 ** | |
| 32779 ** $zEnvVar is intended to be the name of an XDG_... environment | |
| 32780 ** variable, e.g. XDG_CONFIG_HOME or XDG_STATE_HOME. If zEnvVar is | |
| 32781 ** NULL or getenv(zEnvVar) is NULL then fall back to the second | |
| 32782 ** option. If the selected option is not found in the filesystem, | |
| 32783 ** return 0. | |
| 32784 ** | |
| 32785 ** zSubdir may be NULL or empty, in which case ${HOME}/${zBaseName} | |
| 32786 ** becomes the fallback. | |
| 32787 ** | |
| 32788 ** Both zSubdir and zBaseName may contain subdirectory parts. zSubdir | |
| 32789 ** will conventionally be ".config" or ".local/state", which, not | |
| 32790 ** coincidentally, is the typical subdir of the corresponding XDG_... | |
| 32791 ** var with the XDG var's $HOME prefix. | |
| 32792 ** | |
| 32793 ** The returned string is obtained from sqlite3_malloc() and should be | |
| 32794 ** sqlite3_free()'d by the caller. | |
| 32795 */ | |
| 32796 static char *find_xdg_file(const char *zEnvVar, const char *zSubdir, | |
| 32797 const char *zBaseName){ | |
| 32798 #if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \ | |
| 32799 || defined(__RTP__) || defined(_WRS_KERNEL) | |
| 32800 return 0; | |
| 32801 #else | |
| 32802 char *zConfigFile = 0; | |
| 32803 const char *zXdgDir; | |
| 32804 | |
| 32805 zXdgDir = zEnvVar ? getenv(zEnvVar) : 0; | |
| 32806 if( zXdgDir ){ | |
| 32807 zConfigFile = sqlite3_mprintf("%s/%s", zXdgDir, zBaseName); | |
| 32808 }else{ | |
| 32809 const char * zHome = find_home_dir(0); | |
| 32810 if( zHome==0 ) return 0; | |
| 32811 zConfigFile = (zSubdir && *zSubdir) | |
| 32812 ? sqlite3_mprintf("%s/%s/%s", zHome, zSubdir, zBaseName) | |
| 32813 : sqlite3_mprintf("%s/%s", zHome, zBaseName); | |
| 32814 } | |
| 32815 shell_check_oom(zConfigFile); | |
| 32816 if( access(zConfigFile,0)!=0 ){ | |
| 32817 sqlite3_free(zConfigFile); | |
| 32818 zConfigFile = 0; | |
| 32819 } | |
| 32820 return zConfigFile; | |
| 32821 #endif | |
| 32822 } | |
| 32823 | |
| 32824 /* | |
| 32825 ** Read input from the file sqliterc_override. If that parameter is | |
| 32826 ** NULL, take it from find_xdg_file(), if found, or fall back to | |
| 32827 ** ~/.sqliterc. | |
| 32828 ** | |
| 32829 ** Failure to read the config is only considered a failure if | |
| 32830 ** sqliterc_override is not NULL, in which case this function may emit | |
| 32831 ** a warning or, if ::bail_on_error is true, fail fatally if the file | |
| 32832 ** named by sqliterc_override is not found. | |
| 32833 */ | |
| 32834 static void process_sqliterc( | |
| 32835 ShellState *p, /* Configuration data */ | |
| 32836 const char *sqliterc_override /* Name of config file. NULL to use default */ | |
| 32837 ){ | |
| 32838 char *home_dir = NULL; | |
| 32839 char *sqliterc = (char*)sqliterc_override; | |
| 32840 FILE *inSaved = p->in; | |
| 32841 i64 savedLineno = p->lineno; | |
| 32842 | |
| 32843 if( sqliterc == NULL ){ | |
| 32844 sqliterc = find_xdg_file("XDG_CONFIG_HOME", | |
| 32845 ".config", | |
| 32846 "sqlite3/sqliterc"); | |
| 32847 } | |
| 32848 if( sqliterc == NULL ){ | |
| 32849 home_dir = find_home_dir(0); | |
| 32850 if( home_dir==0 ){ | |
| 32851 eputz("-- warning: cannot find home directory;" | |
| 32852 " cannot read ~/.sqliterc\n"); | |
| 32853 return; | |
| 32854 } | |
| 32855 sqliterc = sqlite3_mprintf("%s/.sqliterc",home_dir); | |
| 32856 shell_check_oom(sqliterc); | |
| 32857 } | |
| 32858 p->in = sqliterc ? sqlite3_fopen(sqliterc,"rb") : 0; | |
| 32859 if( p->in ){ | |
| 32860 if( stdin_is_interactive ){ | |
| 32861 sqlite3_fprintf(stderr,"-- Loading resources from %s\n", sqliterc); | |
| 32862 } | |
| 32863 if( process_input(p, sqliterc) && bail_on_error ) exit(1); | |
| 32864 fclose(p->in); | |
| 32865 }else if( sqliterc_override!=0 ){ | |
| 32866 sqlite3_fprintf(stderr,"cannot open: \"%s\"\n", sqliterc); | |
| 32867 if( bail_on_error ) exit(1); | |
| 32868 } | |
| 32869 p->in = inSaved; | |
| 32870 p->lineno = savedLineno; | |
| 32871 if( sqliterc != sqliterc_override ){ | |
| 32872 sqlite3_free(sqliterc); | |
| 32873 } | |
| 32874 } | |
| 32875 | |
| 32876 /* | |
| 32877 ** Show available command line options | |
| 32878 */ | |
| 32879 static const char zOptions[] = | |
| 32880 " -- treat no subsequent arguments as options\n" | |
| 32881 #if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) | |
| 32882 " -A ARGS... run \".archive ARGS\" and exit\n" | |
| 32883 #endif | |
| 32884 " -append append the database to the end of the file\n" | |
| 32885 " -ascii set output mode to 'ascii'\n" | |
| 32886 " -bail stop after hitting an error\n" | |
| 32887 " -batch force batch I/O\n" | |
| 32888 " -box set output mode to 'box'\n" | |
| 32889 " -column set output mode to 'column'\n" | |
| 32890 " -cmd COMMAND run \"COMMAND\" before reading stdin\n" | |
| 32891 " -csv set output mode to 'csv'\n" | |
| 32892 #if !defined(SQLITE_OMIT_DESERIALIZE) | |
| 32893 " -deserialize open the database using sqlite3_deserialize()\n" | |
| 32894 #endif | |
| 32895 " -echo print inputs before execution\n" | |
| 32896 " -escape T ctrl-char escape; T is one of: symbol, ascii, off\n" | |
| 32897 " -init FILENAME read/process named file\n" | |
| 32898 " -[no]header turn headers on or off\n" | |
| 32899 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) | |
| 32900 " -heap SIZE Size of heap for memsys3 or memsys5\n" | |
| 32901 #endif | |
| 32902 " -help show this message\n" | |
| 32903 " -html set output mode to HTML\n" | |
| 32904 " -ifexists only open if database already exists\n" | |
| 32905 " -interactive force interactive I/O\n" | |
| 32906 " -json set output mode to 'json'\n" | |
| 32907 " -line set output mode to 'line'\n" | |
| 32908 " -list set output mode to 'list'\n" | |
| 32909 " -lookaside SIZE N use N entries of SZ bytes for lookaside memory\n" | |
| 32910 " -markdown set output mode to 'markdown'\n" | |
| 32911 #if !defined(SQLITE_OMIT_DESERIALIZE) | |
| 32912 " -maxsize N maximum size for a --deserialize database\n" | |
| 32913 #endif | |
| 32914 " -memtrace trace all memory allocations and deallocations\n" | |
| 32915 " -mmap N default mmap size set to N\n" | |
| 32916 #ifdef SQLITE_ENABLE_MULTIPLEX | |
| 32917 " -multiplex enable the multiplexor VFS\n" | |
| 32918 #endif | |
| 32919 " -newline SEP set output row separator. Default: '\\n'\n" | |
| 32920 " -nofollow refuse to open symbolic links to database files\n" | |
| 32921 " -nonce STRING set the safe-mode escape nonce\n" | |
| 32922 " -no-rowid-in-view Disable rowid-in-view using sqlite3_config()\n" | |
| 32923 " -nullvalue TEXT set text string for NULL values. Default ''\n" | |
| 32924 " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" | |
| 32925 " -pcachetrace trace all page cache operations\n" | |
| 32926 " -quote set output mode to 'quote'\n" | |
| 32927 " -readonly open the database read-only\n" | |
| 32928 " -safe enable safe-mode\n" | |
| 32929 " -separator SEP set output column separator. Default: '|'\n" | |
| 32930 #ifdef SQLITE_ENABLE_SORTER_REFERENCES | |
| 32931 " -sorterref SIZE sorter references threshold size\n" | |
| 32932 #endif | |
| 32933 " -stats print memory stats before each finalize\n" | |
| 32934 " -table set output mode to 'table'\n" | |
| 32935 " -tabs set output mode to 'tabs'\n" | |
| 32936 " -unsafe-testing allow unsafe commands and modes for testing\n" | |
| 32937 " -version show SQLite version\n" | |
| 32938 " -vfs NAME use NAME as the default VFS\n" | |
| 32939 " -vfstrace enable tracing of all VFS calls\n" | |
| 32940 #ifdef SQLITE_HAVE_ZLIB | |
| 32941 " -zip open the file as a ZIP Archive\n" | |
| 32942 #endif | |
| 32943 ; | |
| 32944 static void usage(int showDetail){ | |
| 32945 sqlite3_fprintf(stderr,"Usage: %s [OPTIONS] [FILENAME [SQL...]]\n" | |
| 32946 "FILENAME is the name of an SQLite database. A new database is created\n" | |
| 32947 "if the file does not previously exist. Defaults to :memory:.\n", Argv0); | |
| 32948 if( showDetail ){ | |
| 32949 sqlite3_fprintf(stderr,"OPTIONS include:\n%s", zOptions); | |
| 32950 }else{ | |
| 32951 eputz("Use the -help option for additional information\n"); | |
| 32952 } | |
| 32953 exit(0); | |
| 32954 } | |
| 32955 | |
| 32956 /* | |
| 32957 ** Internal check: Verify that the SQLite is uninitialized. Print a | |
| 32958 ** error message if it is initialized. | |
| 32959 */ | |
| 32960 static void verify_uninitialized(void){ | |
| 32961 if( sqlite3_config(-1)==SQLITE_MISUSE ){ | |
| 32962 sputz(stdout, "WARNING: attempt to configure SQLite after" | |
| 32963 " initialization.\n"); | |
| 32964 } | |
| 32965 } | |
| 32966 | |
| 32967 /* | |
| 32968 ** Initialize the state information in data | |
| 32969 */ | |
| 32970 static void main_init(ShellState *data) { | |
| 32971 memset(data, 0, sizeof(*data)); | |
| 32972 data->normalMode = data->cMode = data->mode = MODE_List; | |
| 32973 data->autoExplain = 1; | |
| 32974 #ifdef _WIN32 | |
| 32975 data->crlfMode = 1; | |
| 32976 #endif | |
| 32977 data->pAuxDb = &data->aAuxDb[0]; | |
| 32978 memcpy(data->colSeparator,SEP_Column, 2); | |
| 32979 memcpy(data->rowSeparator,SEP_Row, 2); | |
| 32980 data->showHeader = 0; | |
| 32981 data->shellFlgs = SHFLG_Lookaside; | |
| 32982 sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); | |
| 32983 #if !defined(SQLITE_SHELL_FIDDLE) | |
| 32984 verify_uninitialized(); | |
| 32985 #endif | |
| 32986 sqlite3_config(SQLITE_CONFIG_URI, 1); | |
| 32987 sqlite3_config(SQLITE_CONFIG_MULTITHREAD); | |
| 32988 sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); | |
| 32989 sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); | |
| 32990 } | |
| 32991 | |
| 32992 /* | |
| 32993 ** Output text to the console in a font that attracts extra attention. | |
| 32994 */ | |
| 32995 #if defined(_WIN32) || defined(WIN32) | |
| 32996 static void printBold(const char *zText){ | |
| 32997 #if !SQLITE_OS_WINRT | |
| 32998 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); | |
| 32999 CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo; | |
| 33000 GetConsoleScreenBufferInfo(out, &defaultScreenInfo); | |
| 33001 SetConsoleTextAttribute(out, | |
| 33002 FOREGROUND_RED|FOREGROUND_INTENSITY | |
| 33003 ); | |
| 33004 #endif | |
| 33005 sputz(stdout, zText); | |
| 33006 #if !SQLITE_OS_WINRT | |
| 33007 SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes); | |
| 33008 #endif | |
| 33009 } | |
| 33010 #else | |
| 33011 static void printBold(const char *zText){ | |
| 33012 sqlite3_fprintf(stdout, "\033[1m%s\033[0m", zText); | |
| 33013 } | |
| 33014 #endif | |
| 33015 | |
| 33016 /* | |
| 33017 ** Get the argument to an --option. Throw an error and die if no argument | |
| 33018 ** is available. | |
| 33019 */ | |
| 33020 static char *cmdline_option_value(int argc, char **argv, int i){ | |
| 33021 if( i==argc ){ | |
| 33022 sqlite3_fprintf(stderr, | |
| 33023 "%s: Error: missing argument to %s\n", argv[0], argv[argc-1]); | |
| 33024 exit(1); | |
| 33025 } | |
| 33026 return argv[i]; | |
| 33027 } | |
| 33028 | |
| 33029 static void sayAbnormalExit(void){ | |
| 33030 if( seenInterrupt ) eputz("Program interrupted.\n"); | |
| 33031 } | |
| 33032 | |
| 33033 /* Routine to output from vfstrace | |
| 33034 */ | |
| 33035 static int vfstraceOut(const char *z, void *pArg){ | |
| 33036 ShellState *p = (ShellState*)pArg; | |
| 33037 sqlite3_fputs(z, p->out); | |
| 33038 fflush(p->out); | |
| 33039 return 1; | |
| 33040 } | |
| 33041 | |
| 33042 #ifndef SQLITE_SHELL_IS_UTF8 | |
| 33043 # if (defined(_WIN32) || defined(WIN32)) \ | |
| 33044 && (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__))) | |
| 33045 # define SQLITE_SHELL_IS_UTF8 (0) | |
| 33046 # else | |
| 33047 # define SQLITE_SHELL_IS_UTF8 (1) | |
| 33048 # endif | |
| 33049 #endif | |
| 33050 | |
| 33051 #ifdef SQLITE_SHELL_FIDDLE | |
| 33052 # define main fiddle_main | |
| 33053 #endif | |
| 33054 | |
| 33055 #if SQLITE_SHELL_IS_UTF8 | |
| 33056 int SQLITE_CDECL main(int argc, char **argv){ | |
| 33057 #else | |
| 33058 int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ | |
| 33059 char **argv; | |
| 33060 #endif | |
| 33061 #ifdef SQLITE_DEBUG | |
| 33062 sqlite3_int64 mem_main_enter = 0; | |
| 33063 #endif | |
| 33064 char *zErrMsg = 0; | |
| 33065 #ifdef SQLITE_SHELL_FIDDLE | |
| 33066 # define data shellState | |
| 33067 #else | |
| 33068 ShellState data; | |
| 33069 #endif | |
| 33070 const char *zInitFile = 0; | |
| 33071 int i; | |
| 33072 int rc = 0; | |
| 33073 int warnInmemoryDb = 0; | |
| 33074 int readStdin = 1; | |
| 33075 int nCmd = 0; | |
| 33076 int nOptsEnd = argc; | |
| 33077 int bEnableVfstrace = 0; | |
| 33078 char **azCmd = 0; | |
| 33079 const char *zVfs = 0; /* Value of -vfs command-line option */ | |
| 33080 #if !SQLITE_SHELL_IS_UTF8 | |
| 33081 char **argvToFree = 0; | |
| 33082 int argcToFree = 0; | |
| 33083 #endif | |
| 33084 setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ | |
| 33085 | |
| 33086 #ifdef SQLITE_SHELL_FIDDLE | |
| 33087 stdin_is_interactive = 0; | |
| 33088 stdout_is_console = 1; | |
| 33089 data.wasm.zDefaultDbName = "/fiddle.sqlite3"; | |
| 33090 #else | |
| 33091 stdin_is_interactive = isatty(0); | |
| 33092 stdout_is_console = isatty(1); | |
| 33093 #endif | |
| 33094 atexit(sayAbnormalExit); | |
| 33095 #ifdef SQLITE_DEBUG | |
| 33096 mem_main_enter = sqlite3_memory_used(); | |
| 33097 #endif | |
| 33098 #if !defined(_WIN32_WCE) | |
| 33099 if( getenv("SQLITE_DEBUG_BREAK") ){ | |
| 33100 if( isatty(0) && isatty(2) ){ | |
| 33101 char zLine[100]; | |
| 33102 sqlite3_fprintf(stderr, | |
| 33103 "attach debugger to process %d and press ENTER to continue...", | |
| 33104 GETPID()); | |
| 33105 if( sqlite3_fgets(zLine, sizeof(zLine), stdin)!=0 | |
| 33106 && cli_strcmp(zLine,"stop")==0 | |
| 33107 ){ | |
| 33108 exit(1); | |
| 33109 } | |
| 33110 }else{ | |
| 33111 #if defined(_WIN32) || defined(WIN32) | |
| 33112 #if SQLITE_OS_WINRT | |
| 33113 __debugbreak(); | |
| 33114 #else | |
| 33115 DebugBreak(); | |
| 33116 #endif | |
| 33117 #elif defined(SIGTRAP) | |
| 33118 raise(SIGTRAP); | |
| 33119 #endif | |
| 33120 } | |
| 33121 } | |
| 33122 #endif | |
| 33123 /* Register a valid signal handler early, before much else is done. */ | |
| 33124 #ifdef SIGINT | |
| 33125 signal(SIGINT, interrupt_handler); | |
| 33126 #elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) | |
| 33127 if( !SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE) ){ | |
| 33128 eputz("No ^C handler.\n"); | |
| 33129 } | |
| 33130 #endif | |
| 33131 | |
| 33132 #if USE_SYSTEM_SQLITE+0!=1 | |
| 33133 if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){ | |
| 33134 sqlite3_fprintf(stderr, | |
| 33135 "SQLite header and source version mismatch\n%s\n%s\n", | |
| 33136 sqlite3_sourceid(), SQLITE_SOURCE_ID); | |
| 33137 exit(1); | |
| 33138 } | |
| 33139 #endif | |
| 33140 main_init(&data); | |
| 33141 | |
| 33142 /* On Windows, we must translate command-line arguments into UTF-8. | |
| 33143 ** The SQLite memory allocator subsystem has to be enabled in order to | |
| 33144 ** do this. But we want to run an sqlite3_shutdown() afterwards so that | |
| 33145 ** subsequent sqlite3_config() calls will work. So copy all results into | |
| 33146 ** memory that does not come from the SQLite memory allocator. | |
| 33147 */ | |
| 33148 #if !SQLITE_SHELL_IS_UTF8 | |
| 33149 sqlite3_initialize(); | |
| 33150 argvToFree = malloc(sizeof(argv[0])*argc*2); | |
| 33151 shell_check_oom(argvToFree); | |
| 33152 argcToFree = argc; | |
| 33153 argv = argvToFree + argc; | |
| 33154 for(i=0; i<argc; i++){ | |
| 33155 char *z = sqlite3_win32_unicode_to_utf8(wargv[i]); | |
| 33156 i64 n; | |
| 33157 shell_check_oom(z); | |
| 33158 n = strlen(z); | |
| 33159 argv[i] = malloc( n+1 ); | |
| 33160 shell_check_oom(argv[i]); | |
| 33161 memcpy(argv[i], z, n+1); | |
| 33162 argvToFree[i] = argv[i]; | |
| 33163 sqlite3_free(z); | |
| 33164 } | |
| 33165 sqlite3_shutdown(); | |
| 33166 #endif | |
| 33167 | |
| 33168 assert( argc>=1 && argv && argv[0] ); | |
| 33169 Argv0 = argv[0]; | |
| 33170 | |
| 33171 #ifdef SQLITE_SHELL_DBNAME_PROC | |
| 33172 { | |
| 33173 /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name | |
| 33174 ** of a C-function that will provide the name of the database file. Use | |
| 33175 ** this compile-time option to embed this shell program in larger | |
| 33176 ** applications. */ | |
| 33177 extern void SQLITE_SHELL_DBNAME_PROC(const char**); | |
| 33178 SQLITE_SHELL_DBNAME_PROC(&data.pAuxDb->zDbFilename); | |
| 33179 warnInmemoryDb = 0; | |
| 33180 } | |
| 33181 #endif | |
| 33182 | |
| 33183 /* Do an initial pass through the command-line argument to locate | |
| 33184 ** the name of the database file, the name of the initialization file, | |
| 33185 ** the size of the alternative malloc heap, options affecting commands | |
| 33186 ** or SQL run from the command line, and the first command to execute. | |
| 33187 */ | |
| 33188 #ifndef SQLITE_SHELL_FIDDLE | |
| 33189 verify_uninitialized(); | |
| 33190 #endif | |
| 33191 for(i=1; i<argc; i++){ | |
| 33192 char *z; | |
| 33193 z = argv[i]; | |
| 33194 if( z[0]!='-' || i>nOptsEnd ){ | |
| 33195 if( data.aAuxDb->zDbFilename==0 ){ | |
| 33196 data.aAuxDb->zDbFilename = z; | |
| 33197 }else{ | |
| 33198 /* Excess arguments are interpreted as SQL (or dot-commands) and | |
| 33199 ** mean that nothing is read from stdin */ | |
| 33200 readStdin = 0; | |
| 33201 nCmd++; | |
| 33202 azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd); | |
| 33203 shell_check_oom(azCmd); | |
| 33204 azCmd[nCmd-1] = z; | |
| 33205 } | |
| 33206 continue; | |
| 33207 } | |
| 33208 if( z[1]=='-' ) z++; | |
| 33209 if( cli_strcmp(z, "-")==0 ){ | |
| 33210 nOptsEnd = i; | |
| 33211 continue; | |
| 33212 }else if( cli_strcmp(z,"-separator")==0 | |
| 33213 || cli_strcmp(z,"-nullvalue")==0 | |
| 33214 || cli_strcmp(z,"-newline")==0 | |
| 33215 || cli_strcmp(z,"-cmd")==0 | |
| 33216 ){ | |
| 33217 (void)cmdline_option_value(argc, argv, ++i); | |
| 33218 }else if( cli_strcmp(z,"-init")==0 ){ | |
| 33219 zInitFile = cmdline_option_value(argc, argv, ++i); | |
| 33220 }else if( cli_strcmp(z,"-interactive")==0 ){ | |
| 33221 }else if( cli_strcmp(z,"-batch")==0 ){ | |
| 33222 /* Need to check for batch mode here to so we can avoid printing | |
| 33223 ** informational messages (like from process_sqliterc) before | |
| 33224 ** we do the actual processing of arguments later in a second pass. | |
| 33225 */ | |
| 33226 stdin_is_interactive = 0; | |
| 33227 }else if( cli_strcmp(z,"-utf8")==0 ){ | |
| 33228 }else if( cli_strcmp(z,"-no-utf8")==0 ){ | |
| 33229 }else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){ | |
| 33230 int val = 0; | |
| 33231 sqlite3_config(SQLITE_CONFIG_ROWID_IN_VIEW, &val); | |
| 33232 assert( val==0 ); | |
| 33233 }else if( cli_strcmp(z,"-heap")==0 ){ | |
| 33234 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) | |
| 33235 const char *zSize; | |
| 33236 sqlite3_int64 szHeap; | |
| 33237 | |
| 33238 zSize = cmdline_option_value(argc, argv, ++i); | |
| 33239 szHeap = integerValue(zSize); | |
| 33240 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; | |
| 33241 verify_uninitialized(); | |
| 33242 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); | |
| 33243 #else | |
| 33244 (void)cmdline_option_value(argc, argv, ++i); | |
| 33245 #endif | |
| 33246 }else if( cli_strcmp(z,"-pagecache")==0 ){ | |
| 33247 sqlite3_int64 n, sz; | |
| 33248 sz = integerValue(cmdline_option_value(argc,argv,++i)); | |
| 33249 if( sz>65536 ) sz = 65536; | |
| 33250 if( sz<0 ) sz = 0; | |
| 33251 n = integerValue(cmdline_option_value(argc,argv,++i)); | |
| 33252 if( sz>0 && n>0 && 0xffffffffffffLL/sz<n ){ | |
| 33253 n = 0xffffffffffffLL/sz; | |
| 33254 } | |
| 33255 if( sz>0 && (sz & (sz-1))==0 ){ | |
| 33256 /* If SIZE is a power of two, round it up by the PCACHE_HDRSZ */ | |
| 33257 int szHdr = 0; | |
| 33258 sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &szHdr); | |
| 33259 sz += szHdr; | |
| 33260 sqlite3_fprintf(stdout, "Page cache size increased to %d to accommodate" | |
| 33261 " the %d-byte headers\n", (int)sz, szHdr); | |
| 33262 } | |
| 33263 verify_uninitialized(); | |
| 33264 sqlite3_config(SQLITE_CONFIG_PAGECACHE, | |
| 33265 (n>0 && sz>0) ? malloc(n*sz) : 0, sz, n); | |
| 33266 data.shellFlgs |= SHFLG_Pagecache; | |
| 33267 }else if( cli_strcmp(z,"-lookaside")==0 ){ | |
| 33268 int n, sz; | |
| 33269 sz = (int)integerValue(cmdline_option_value(argc,argv,++i)); | |
| 33270 if( sz<0 ) sz = 0; | |
| 33271 n = (int)integerValue(cmdline_option_value(argc,argv,++i)); | |
| 33272 if( n<0 ) n = 0; | |
| 33273 verify_uninitialized(); | |
| 33274 sqlite3_config(SQLITE_CONFIG_LOOKASIDE, sz, n); | |
| 33275 if( (i64)sz*(i64)n==0 ) data.shellFlgs &= ~SHFLG_Lookaside; | |
| 33276 }else if( cli_strcmp(z,"-threadsafe")==0 ){ | |
| 33277 int n; | |
| 33278 n = (int)integerValue(cmdline_option_value(argc,argv,++i)); | |
| 33279 verify_uninitialized(); | |
| 33280 switch( n ){ | |
| 33281 case 0: sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); break; | |
| 33282 case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break; | |
| 33283 default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break; | |
| 33284 } | |
| 33285 }else if( cli_strcmp(z,"-vfstrace")==0 ){ | |
| 33286 bEnableVfstrace = 1; | |
| 33287 #ifdef SQLITE_ENABLE_MULTIPLEX | |
| 33288 }else if( cli_strcmp(z,"-multiplex")==0 ){ | |
| 33289 extern int sqlite3_multiplex_initialize(const char*,int); | |
| 33290 sqlite3_multiplex_initialize(0, 1); | |
| 33291 #endif | |
| 33292 }else if( cli_strcmp(z,"-mmap")==0 ){ | |
| 33293 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); | |
| 33294 verify_uninitialized(); | |
| 33295 sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); | |
| 33296 #if defined(SQLITE_ENABLE_SORTER_REFERENCES) | |
| 33297 }else if( cli_strcmp(z,"-sorterref")==0 ){ | |
| 33298 sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); | |
| 33299 verify_uninitialized(); | |
| 33300 sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz); | |
| 33301 #endif | |
| 33302 }else if( cli_strcmp(z,"-vfs")==0 ){ | |
| 33303 zVfs = cmdline_option_value(argc, argv, ++i); | |
| 33304 #ifdef SQLITE_HAVE_ZLIB | |
| 33305 }else if( cli_strcmp(z,"-zip")==0 ){ | |
| 33306 data.openMode = SHELL_OPEN_ZIPFILE; | |
| 33307 #endif | |
| 33308 }else if( cli_strcmp(z,"-append")==0 ){ | |
| 33309 data.openMode = SHELL_OPEN_APPENDVFS; | |
| 33310 #ifndef SQLITE_OMIT_DESERIALIZE | |
| 33311 }else if( cli_strcmp(z,"-deserialize")==0 ){ | |
| 33312 data.openMode = SHELL_OPEN_DESERIALIZE; | |
| 33313 }else if( cli_strcmp(z,"-maxsize")==0 && i+1<argc ){ | |
| 33314 data.szMax = integerValue(argv[++i]); | |
| 33315 #endif | |
| 33316 }else if( cli_strcmp(z,"-readonly")==0 ){ | |
| 33317 data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); | |
| 33318 data.openFlags |= SQLITE_OPEN_READONLY; | |
| 33319 }else if( cli_strcmp(z,"-nofollow")==0 ){ | |
| 33320 data.openFlags |= SQLITE_OPEN_NOFOLLOW; | |
| 33321 }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */ | |
| 33322 data.openFlags |= SQLITE_OPEN_EXCLUSIVE; | |
| 33323 }else if( cli_strcmp(z,"-ifexists")==0 ){ | |
| 33324 data.openFlags &= ~(SQLITE_OPEN_CREATE); | |
| 33325 if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE; | |
| 33326 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) | |
| 33327 }else if( cli_strncmp(z, "-A",2)==0 ){ | |
| 33328 /* All remaining command-line arguments are passed to the ".archive" | |
| 33329 ** command, so ignore them */ | |
| 33330 break; | |
| 33331 #endif | |
| 33332 }else if( cli_strcmp(z, "-memtrace")==0 ){ | |
| 33333 sqlite3MemTraceActivate(stderr); | |
| 33334 }else if( cli_strcmp(z, "-pcachetrace")==0 ){ | |
| 33335 sqlite3PcacheTraceActivate(stderr); | |
| 33336 }else if( cli_strcmp(z,"-bail")==0 ){ | |
| 33337 bail_on_error = 1; | |
| 33338 }else if( cli_strcmp(z,"-nonce")==0 ){ | |
| 33339 free(data.zNonce); | |
| 33340 data.zNonce = strdup(cmdline_option_value(argc, argv, ++i)); | |
| 33341 }else if( cli_strcmp(z,"-unsafe-testing")==0 ){ | |
| 33342 ShellSetFlag(&data,SHFLG_TestingMode); | |
| 33343 }else if( cli_strcmp(z,"-safe")==0 ){ | |
| 33344 /* no-op - catch this on the second pass */ | |
| 33345 }else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){ | |
| 33346 /* skip over the argument */ | |
| 33347 i++; | |
| 33348 } | |
| 33349 } | |
| 33350 #ifndef SQLITE_SHELL_FIDDLE | |
| 33351 if( !bEnableVfstrace ) verify_uninitialized(); | |
| 33352 #endif | |
| 33353 | |
| 33354 | |
| 33355 #ifdef SQLITE_SHELL_INIT_PROC | |
| 33356 { | |
| 33357 /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name | |
| 33358 ** of a C-function that will perform initialization actions on SQLite that | |
| 33359 ** occur just before or after sqlite3_initialize(). Use this compile-time | |
| 33360 ** option to embed this shell program in larger applications. */ | |
| 33361 extern void SQLITE_SHELL_INIT_PROC(void); | |
| 33362 SQLITE_SHELL_INIT_PROC(); | |
| 33363 } | |
| 33364 #else | |
| 33365 /* All the sqlite3_config() calls have now been made. So it is safe | |
| 33366 ** to call sqlite3_initialize() and process any command line -vfs option. */ | |
| 33367 sqlite3_initialize(); | |
| 33368 #endif | |
| 33369 | |
| 33370 if( zVfs ){ | |
| 33371 sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs); | |
| 33372 if( pVfs ){ | |
| 33373 sqlite3_vfs_register(pVfs, 1); | |
| 33374 }else{ | |
| 33375 sqlite3_fprintf(stderr,"no such VFS: \"%s\"\n", zVfs); | |
| 33376 exit(1); | |
| 33377 } | |
| 33378 } | |
| 33379 | |
| 33380 if( data.pAuxDb->zDbFilename==0 ){ | |
| 33381 #ifndef SQLITE_OMIT_MEMORYDB | |
| 33382 data.pAuxDb->zDbFilename = ":memory:"; | |
| 33383 warnInmemoryDb = argc==1; | |
| 33384 #else | |
| 33385 sqlite3_fprintf(stderr, | |
| 33386 "%s: Error: no database filename specified\n", Argv0); | |
| 33387 return 1; | |
| 33388 #endif | |
| 33389 } | |
| 33390 data.out = stdout; | |
| 33391 if( bEnableVfstrace ){ | |
| 33392 vfstrace_register("trace",0,vfstraceOut, &data, 1); | |
| 33393 } | |
| 33394 #ifndef SQLITE_SHELL_FIDDLE | |
| 33395 sqlite3_appendvfs_init(0,0,0); | |
| 33396 #endif | |
| 33397 | |
| 33398 /* Go ahead and open the database file if it already exists. If the | |
| 33399 ** file does not exist, delay opening it. This prevents empty database | |
| 33400 ** files from being created if a user mistypes the database name argument | |
| 33401 ** to the sqlite command-line tool. | |
| 33402 */ | |
| 33403 if( access(data.pAuxDb->zDbFilename, 0)==0 ){ | |
| 33404 open_db(&data, 0); | |
| 33405 } | |
| 33406 | |
| 33407 /* Process the initialization file if there is one. If no -init option | |
| 33408 ** is given on the command line, look for a file named ~/.sqliterc and | |
| 33409 ** try to process it. | |
| 33410 */ | |
| 33411 process_sqliterc(&data,zInitFile); | |
| 33412 | |
| 33413 /* Make a second pass through the command-line argument and set | |
| 33414 ** options. This second pass is delayed until after the initialization | |
| 33415 ** file is processed so that the command-line arguments will override | |
| 33416 ** settings in the initialization file. | |
| 33417 */ | |
| 33418 for(i=1; i<argc; i++){ | |
| 33419 char *z = argv[i]; | |
| 33420 if( z[0]!='-' || i>=nOptsEnd ) continue; | |
| 33421 if( z[1]=='-' ){ z++; } | |
| 33422 if( cli_strcmp(z,"-init")==0 ){ | |
| 33423 i++; | |
| 33424 }else if( cli_strcmp(z,"-html")==0 ){ | |
| 33425 data.mode = MODE_Html; | |
| 33426 }else if( cli_strcmp(z,"-list")==0 ){ | |
| 33427 data.mode = MODE_List; | |
| 33428 }else if( cli_strcmp(z,"-quote")==0 ){ | |
| 33429 data.mode = MODE_Quote; | |
| 33430 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, SEP_Comma); | |
| 33431 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, SEP_Row); | |
| 33432 }else if( cli_strcmp(z,"-line")==0 ){ | |
| 33433 data.mode = MODE_Line; | |
| 33434 }else if( cli_strcmp(z,"-column")==0 ){ | |
| 33435 data.mode = MODE_Column; | |
| 33436 }else if( cli_strcmp(z,"-json")==0 ){ | |
| 33437 data.mode = MODE_Json; | |
| 33438 }else if( cli_strcmp(z,"-markdown")==0 ){ | |
| 33439 data.mode = MODE_Markdown; | |
| 33440 }else if( cli_strcmp(z,"-table")==0 ){ | |
| 33441 data.mode = MODE_Table; | |
| 33442 }else if( cli_strcmp(z,"-box")==0 ){ | |
| 33443 data.mode = MODE_Box; | |
| 33444 }else if( cli_strcmp(z,"-csv")==0 ){ | |
| 33445 data.mode = MODE_Csv; | |
| 33446 memcpy(data.colSeparator,",",2); | |
| 33447 }else if( cli_strcmp(z,"-escape")==0 && i+1<argc ){ | |
| 33448 /* See similar code at tag-20250224-1 */ | |
| 33449 const char *zEsc = argv[++i]; | |
| 33450 int k; | |
| 33451 for(k=0; k<ArraySize(shell_EscModeNames); k++){ | |
| 33452 if( sqlite3_stricmp(zEsc,shell_EscModeNames[k])==0 ){ | |
| 33453 data.eEscMode = k; | |
| 33454 break; | |
| 33455 } | |
| 33456 } | |
| 33457 if( k>=ArraySize(shell_EscModeNames) ){ | |
| 33458 sqlite3_fprintf(stderr, "unknown control character escape mode \"%s\"" | |
| 33459 " - choices:", zEsc); | |
| 33460 for(k=0; k<ArraySize(shell_EscModeNames); k++){ | |
| 33461 sqlite3_fprintf(stderr, " %s", shell_EscModeNames[k]); | |
| 33462 } | |
| 33463 sqlite3_fprintf(stderr, "\n"); | |
| 33464 exit(1); | |
| 33465 } | |
| 33466 #ifdef SQLITE_HAVE_ZLIB | |
| 33467 }else if( cli_strcmp(z,"-zip")==0 ){ | |
| 33468 data.openMode = SHELL_OPEN_ZIPFILE; | |
| 33469 #endif | |
| 33470 }else if( cli_strcmp(z,"-append")==0 ){ | |
| 33471 data.openMode = SHELL_OPEN_APPENDVFS; | |
| 33472 #ifndef SQLITE_OMIT_DESERIALIZE | |
| 33473 }else if( cli_strcmp(z,"-deserialize")==0 ){ | |
| 33474 data.openMode = SHELL_OPEN_DESERIALIZE; | |
| 33475 }else if( cli_strcmp(z,"-maxsize")==0 && i+1<argc ){ | |
| 33476 data.szMax = integerValue(argv[++i]); | |
| 33477 #endif | |
| 33478 }else if( cli_strcmp(z,"-readonly")==0 ){ | |
| 33479 data.openFlags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); | |
| 33480 data.openFlags |= SQLITE_OPEN_READONLY; | |
| 33481 }else if( cli_strcmp(z,"-nofollow")==0 ){ | |
| 33482 data.openFlags |= SQLITE_OPEN_NOFOLLOW; | |
| 33483 }else if( cli_strcmp(z,"-exclusive")==0 ){ /* UNDOCUMENTED */ | |
| 33484 data.openFlags |= SQLITE_OPEN_EXCLUSIVE; | |
| 33485 }else if( cli_strcmp(z,"-ifexists")==0 ){ | |
| 33486 data.openFlags &= ~(SQLITE_OPEN_CREATE); | |
| 33487 if( data.openFlags==0 ) data.openFlags = SQLITE_OPEN_READWRITE; | |
| 33488 }else if( cli_strcmp(z,"-ascii")==0 ){ | |
| 33489 data.mode = MODE_Ascii; | |
| 33490 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Unit); | |
| 33491 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Record); | |
| 33492 }else if( cli_strcmp(z,"-tabs")==0 ){ | |
| 33493 data.mode = MODE_List; | |
| 33494 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,SEP_Tab); | |
| 33495 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,SEP_Row); | |
| 33496 }else if( cli_strcmp(z,"-separator")==0 ){ | |
| 33497 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, | |
| 33498 "%s",cmdline_option_value(argc,argv,++i)); | |
| 33499 }else if( cli_strcmp(z,"-newline")==0 ){ | |
| 33500 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, | |
| 33501 "%s",cmdline_option_value(argc,argv,++i)); | |
| 33502 }else if( cli_strcmp(z,"-nullvalue")==0 ){ | |
| 33503 sqlite3_snprintf(sizeof(data.nullValue), data.nullValue, | |
| 33504 "%s",cmdline_option_value(argc,argv,++i)); | |
| 33505 }else if( cli_strcmp(z,"-header")==0 ){ | |
| 33506 data.showHeader = 1; | |
| 33507 ShellSetFlag(&data, SHFLG_HeaderSet); | |
| 33508 }else if( cli_strcmp(z,"-noheader")==0 ){ | |
| 33509 data.showHeader = 0; | |
| 33510 ShellSetFlag(&data, SHFLG_HeaderSet); | |
| 33511 }else if( cli_strcmp(z,"-echo")==0 ){ | |
| 33512 ShellSetFlag(&data, SHFLG_Echo); | |
| 33513 }else if( cli_strcmp(z,"-eqp")==0 ){ | |
| 33514 data.autoEQP = AUTOEQP_on; | |
| 33515 }else if( cli_strcmp(z,"-eqpfull")==0 ){ | |
| 33516 data.autoEQP = AUTOEQP_full; | |
| 33517 }else if( cli_strcmp(z,"-stats")==0 ){ | |
| 33518 data.statsOn = 1; | |
| 33519 }else if( cli_strcmp(z,"-scanstats")==0 ){ | |
| 33520 data.scanstatsOn = 1; | |
| 33521 }else if( cli_strcmp(z,"-backslash")==0 ){ | |
| 33522 /* Undocumented command-line option: -backslash | |
| 33523 ** Causes C-style backslash escapes to be evaluated in SQL statements | |
| 33524 ** prior to sending the SQL into SQLite. Useful for injecting | |
| 33525 ** crazy bytes in the middle of SQL statements for testing and debugging. | |
| 33526 */ | |
| 33527 ShellSetFlag(&data, SHFLG_Backslash); | |
| 33528 }else if( cli_strcmp(z,"-bail")==0 ){ | |
| 33529 /* No-op. The bail_on_error flag should already be set. */ | |
| 33530 }else if( cli_strcmp(z,"-version")==0 ){ | |
| 33531 sqlite3_fprintf(stdout, "%s %s (%d-bit)\n", | |
| 33532 sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*)); | |
| 33533 return 0; | |
| 33534 }else if( cli_strcmp(z,"-interactive")==0 ){ | |
| 33535 /* Need to check for interactive override here to so that it can | |
| 33536 ** affect console setup (for Windows only) and testing thereof. | |
| 33537 */ | |
| 33538 stdin_is_interactive = 1; | |
| 33539 }else if( cli_strcmp(z,"-batch")==0 ){ | |
| 33540 /* already handled */ | |
| 33541 }else if( cli_strcmp(z,"-utf8")==0 ){ | |
| 33542 /* already handled */ | |
| 33543 }else if( cli_strcmp(z,"-no-utf8")==0 ){ | |
| 33544 /* already handled */ | |
| 33545 }else if( cli_strcmp(z,"-no-rowid-in-view")==0 ){ | |
| 33546 /* already handled */ | |
| 33547 }else if( cli_strcmp(z,"-heap")==0 ){ | |
| 33548 i++; | |
| 33549 }else if( cli_strcmp(z,"-pagecache")==0 ){ | |
| 33550 i+=2; | |
| 33551 }else if( cli_strcmp(z,"-lookaside")==0 ){ | |
| 33552 i+=2; | |
| 33553 }else if( cli_strcmp(z,"-threadsafe")==0 ){ | |
| 33554 i+=2; | |
| 33555 }else if( cli_strcmp(z,"-nonce")==0 ){ | |
| 33556 i += 2; | |
| 33557 }else if( cli_strcmp(z,"-mmap")==0 ){ | |
| 33558 i++; | |
| 33559 }else if( cli_strcmp(z,"-memtrace")==0 ){ | |
| 33560 i++; | |
| 33561 }else if( cli_strcmp(z,"-pcachetrace")==0 ){ | |
| 33562 i++; | |
| 33563 #ifdef SQLITE_ENABLE_SORTER_REFERENCES | |
| 33564 }else if( cli_strcmp(z,"-sorterref")==0 ){ | |
| 33565 i++; | |
| 33566 #endif | |
| 33567 }else if( cli_strcmp(z,"-vfs")==0 ){ | |
| 33568 i++; | |
| 33569 }else if( cli_strcmp(z,"-vfstrace")==0 ){ | |
| 33570 i++; | |
| 33571 #ifdef SQLITE_ENABLE_MULTIPLEX | |
| 33572 }else if( cli_strcmp(z,"-multiplex")==0 ){ | |
| 33573 i++; | |
| 33574 #endif | |
| 33575 }else if( cli_strcmp(z,"-help")==0 ){ | |
| 33576 usage(1); | |
| 33577 }else if( cli_strcmp(z,"-cmd")==0 ){ | |
| 33578 /* Run commands that follow -cmd first and separately from commands | |
| 33579 ** that simply appear on the command-line. This seems goofy. It would | |
| 33580 ** be better if all commands ran in the order that they appear. But | |
| 33581 ** we retain the goofy behavior for historical compatibility. */ | |
| 33582 if( i==argc-1 ) break; | |
| 33583 z = cmdline_option_value(argc,argv,++i); | |
| 33584 if( z[0]=='.' ){ | |
| 33585 rc = do_meta_command(z, &data); | |
| 33586 if( rc && bail_on_error ) return rc==2 ? 0 : rc; | |
| 33587 }else{ | |
| 33588 open_db(&data, 0); | |
| 33589 rc = shell_exec(&data, z, &zErrMsg); | |
| 33590 if( zErrMsg!=0 ){ | |
| 33591 shellEmitError(zErrMsg); | |
| 33592 sqlite3_free(zErrMsg); | |
| 33593 if( bail_on_error ) return rc!=0 ? rc : 1; | |
| 33594 }else if( rc!=0 ){ | |
| 33595 sqlite3_fprintf(stderr,"Error: unable to process SQL \"%s\"\n", z); | |
| 33596 if( bail_on_error ) return rc; | |
| 33597 } | |
| 33598 } | |
| 33599 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) | |
| 33600 }else if( cli_strncmp(z, "-A", 2)==0 ){ | |
| 33601 if( nCmd>0 ){ | |
| 33602 sqlite3_fprintf(stderr,"Error: cannot mix regular SQL or dot-commands" | |
| 33603 " with \"%s\"\n", z); | |
| 33604 rc = 1; | |
| 33605 goto shell_main_exit; | |
| 33606 } | |
| 33607 open_db(&data, OPEN_DB_ZIPFILE); | |
| 33608 if( z[2] ){ | |
| 33609 argv[i] = &z[2]; | |
| 33610 arDotCommand(&data, 1, argv+(i-1), argc-(i-1)); | |
| 33611 }else{ | |
| 33612 arDotCommand(&data, 1, argv+i, argc-i); | |
| 33613 } | |
| 33614 readStdin = 0; | |
| 33615 break; | |
| 33616 #endif | |
| 33617 }else if( cli_strcmp(z,"-safe")==0 ){ | |
| 33618 data.bSafeMode = data.bSafeModePersist = 1; | |
| 33619 }else if( cli_strcmp(z,"-unsafe-testing")==0 ){ | |
| 33620 /* Acted upon in first pass. */ | |
| 33621 }else{ | |
| 33622 sqlite3_fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z); | |
| 33623 eputz("Use -help for a list of options.\n"); | |
| 33624 return 1; | |
| 33625 } | |
| 33626 data.cMode = data.mode; | |
| 33627 } | |
| 33628 | |
| 33629 if( !readStdin ){ | |
| 33630 /* Run all arguments that do not begin with '-' as if they were separate | |
| 33631 ** command-line inputs, except for the argToSkip argument which contains | |
| 33632 ** the database filename. | |
| 33633 */ | |
| 33634 for(i=0; i<nCmd; i++){ | |
| 33635 echo_group_input(&data, azCmd[i]); | |
| 33636 if( azCmd[i][0]=='.' ){ | |
| 33637 rc = do_meta_command(azCmd[i], &data); | |
| 33638 if( rc ){ | |
| 33639 if( rc==2 ) rc = 0; | |
| 33640 goto shell_main_exit; | |
| 33641 } | |
| 33642 }else{ | |
| 33643 open_db(&data, 0); | |
| 33644 rc = shell_exec(&data, azCmd[i], &zErrMsg); | |
| 33645 if( zErrMsg || rc ){ | |
| 33646 if( zErrMsg!=0 ){ | |
| 33647 shellEmitError(zErrMsg); | |
| 33648 }else{ | |
| 33649 sqlite3_fprintf(stderr, | |
| 33650 "Error: unable to process SQL: %s\n", azCmd[i]); | |
| 33651 } | |
| 33652 sqlite3_free(zErrMsg); | |
| 33653 if( rc==0 ) rc = 1; | |
| 33654 goto shell_main_exit; | |
| 33655 } | |
| 33656 } | |
| 33657 } | |
| 33658 }else{ | |
| 33659 /* Run commands received from standard input | |
| 33660 */ | |
| 33661 if( stdin_is_interactive ){ | |
| 33662 char *zHome; | |
| 33663 char *zHistory; | |
| 33664 sqlite3_fprintf(stdout, | |
| 33665 "SQLite version %s %.19s\n" /*extra-version-info*/ | |
| 33666 "Enter \".help\" for usage hints.\n", | |
| 33667 sqlite3_libversion(), sqlite3_sourceid()); | |
| 33668 if( warnInmemoryDb ){ | |
| 33669 sputz(stdout, "Connected to a "); | |
| 33670 printBold("transient in-memory database"); | |
| 33671 sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a" | |
| 33672 " persistent database.\n"); | |
| 33673 } | |
| 33674 zHistory = getenv("SQLITE_HISTORY"); | |
| 33675 if( zHistory ){ | |
| 33676 zHistory = sqlite3_mprintf("%s", zHistory); | |
| 33677 shell_check_oom(zHistory); | |
| 33678 }else{ | |
| 33679 zHistory = find_xdg_file("XDG_STATE_HOME", | |
| 33680 ".local/state", | |
| 33681 "sqlite_history"); | |
| 33682 if( 0==zHistory && (zHome = find_home_dir(0))!=0 ){ | |
| 33683 zHistory = sqlite3_mprintf("%s/.sqlite_history", zHome); | |
| 33684 shell_check_oom(zHistory); | |
| 33685 } | |
| 33686 } | |
| 33687 if( zHistory ){ shell_read_history(zHistory); } | |
| 33688 #if (HAVE_READLINE || HAVE_EDITLINE) && !defined(SQLITE_OMIT_READLINE_COMPLETION) | |
| 33689 rl_attempted_completion_function = readline_completion; | |
| 33690 #elif HAVE_LINENOISE==1 | |
| 33691 linenoiseSetCompletionCallback(linenoise_completion); | |
| 33692 #elif HAVE_LINENOISE==2 | |
| 33693 linenoiseSetCompletionCallback(linenoise_completion, NULL); | |
| 33694 #endif | |
| 33695 data.in = 0; | |
| 33696 rc = process_input(&data, "<stdin>"); | |
| 33697 if( zHistory ){ | |
| 33698 shell_stifle_history(2000); | |
| 33699 shell_write_history(zHistory); | |
| 33700 sqlite3_free(zHistory); | |
| 33701 } | |
| 33702 }else{ | |
| 33703 data.in = stdin; | |
| 33704 rc = process_input(&data, "<stdin>"); | |
| 33705 } | |
| 33706 } | |
| 33707 #ifndef SQLITE_SHELL_FIDDLE | |
| 33708 /* In WASM mode we have to leave the db state in place so that | |
| 33709 ** client code can "push" SQL into it after this call returns. */ | |
| 33710 #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_AUTHORIZATION) | |
| 33711 if( data.expert.pExpert ){ | |
| 33712 expertFinish(&data, 1, 0); | |
| 33713 } | |
| 33714 #endif | |
| 33715 shell_main_exit: | |
| 33716 free(azCmd); | |
| 33717 set_table_name(&data, 0); | |
| 33718 if( data.db ){ | |
| 33719 session_close_all(&data, -1); | |
| 33720 close_db(data.db); | |
| 33721 } | |
| 33722 for(i=0; i<ArraySize(data.aAuxDb); i++){ | |
| 33723 sqlite3_free(data.aAuxDb[i].zFreeOnClose); | |
| 33724 if( data.aAuxDb[i].db ){ | |
| 33725 session_close_all(&data, i); | |
| 33726 close_db(data.aAuxDb[i].db); | |
| 33727 } | |
| 33728 } | |
| 33729 find_home_dir(1); | |
| 33730 output_reset(&data); | |
| 33731 data.doXdgOpen = 0; | |
| 33732 clearTempFile(&data); | |
| 33733 #if !SQLITE_SHELL_IS_UTF8 | |
| 33734 for(i=0; i<argcToFree; i++) free(argvToFree[i]); | |
| 33735 free(argvToFree); | |
| 33736 #endif | |
| 33737 free(data.colWidth); | |
| 33738 free(data.zNonce); | |
| 33739 /* Clear the global data structure so that valgrind will detect memory | |
| 33740 ** leaks */ | |
| 33741 memset(&data, 0, sizeof(data)); | |
| 33742 if( bEnableVfstrace ){ | |
| 33743 vfstrace_unregister("trace"); | |
| 33744 } | |
| 33745 #ifdef SQLITE_DEBUG | |
| 33746 if( sqlite3_memory_used()>mem_main_enter ){ | |
| 33747 sqlite3_fprintf(stderr,"Memory leaked: %u bytes\n", | |
| 33748 (unsigned int)(sqlite3_memory_used()-mem_main_enter)); | |
| 33749 } | |
| 33750 #endif | |
| 33751 #else /* SQLITE_SHELL_FIDDLE... */ | |
| 33752 shell_main_exit: | |
| 33753 #endif | |
| 33754 return rc; | |
| 33755 } | |
| 33756 | |
| 33757 | |
| 33758 #ifdef SQLITE_SHELL_FIDDLE | |
| 33759 /* Only for emcc experimentation purposes. */ | |
| 33760 int fiddle_experiment(int a,int b){ | |
| 33761 return a + b; | |
| 33762 } | |
| 33763 | |
| 33764 /* | |
| 33765 ** Returns a pointer to the current DB handle. | |
| 33766 */ | |
| 33767 sqlite3 * fiddle_db_handle(){ | |
| 33768 return globalDb; | |
| 33769 } | |
| 33770 | |
| 33771 /* | |
| 33772 ** Returns a pointer to the given DB name's VFS. If zDbName is 0 then | |
| 33773 ** "main" is assumed. Returns 0 if no db with the given name is | |
| 33774 ** open. | |
| 33775 */ | |
| 33776 sqlite3_vfs * fiddle_db_vfs(const char *zDbName){ | |
| 33777 sqlite3_vfs * pVfs = 0; | |
| 33778 if(globalDb){ | |
| 33779 sqlite3_file_control(globalDb, zDbName ? zDbName : "main", | |
| 33780 SQLITE_FCNTL_VFS_POINTER, &pVfs); | |
| 33781 } | |
| 33782 return pVfs; | |
| 33783 } | |
| 33784 | |
| 33785 /* Only for emcc experimentation purposes. */ | |
| 33786 sqlite3 * fiddle_db_arg(sqlite3 *arg){ | |
| 33787 sqlite3_fprintf(stdout, "fiddle_db_arg(%p)\n", (const void*)arg); | |
| 33788 return arg; | |
| 33789 } | |
| 33790 | |
| 33791 /* | |
| 33792 ** Intended to be called via a SharedWorker() while a separate | |
| 33793 ** SharedWorker() (which manages the wasm module) is performing work | |
| 33794 ** which should be interrupted. Unfortunately, SharedWorker is not | |
| 33795 ** portable enough to make real use of. | |
| 33796 */ | |
| 33797 void fiddle_interrupt(void){ | |
| 33798 if( globalDb ) sqlite3_interrupt(globalDb); | |
| 33799 } | |
| 33800 | |
| 33801 /* | |
| 33802 ** Returns the filename of the given db name, assuming "main" if | |
| 33803 ** zDbName is NULL. Returns NULL if globalDb is not opened. | |
| 33804 */ | |
| 33805 const char * fiddle_db_filename(const char * zDbName){ | |
| 33806 return globalDb | |
| 33807 ? sqlite3_db_filename(globalDb, zDbName ? zDbName : "main") | |
| 33808 : NULL; | |
| 33809 } | |
| 33810 | |
| 33811 /* | |
| 33812 ** Completely wipes out the contents of the currently-opened database | |
| 33813 ** but leaves its storage intact for reuse. If any transactions are | |
| 33814 ** active, they are forcibly rolled back. | |
| 33815 */ | |
| 33816 void fiddle_reset_db(void){ | |
| 33817 if( globalDb ){ | |
| 33818 int rc; | |
| 33819 while( sqlite3_txn_state(globalDb,0)>0 ){ | |
| 33820 /* | |
| 33821 ** Resolve problem reported in | |
| 33822 ** https://sqlite.org/forum/forumpost/0b41a25d65 | |
| 33823 */ | |
| 33824 sqlite3_fputs("Rolling back in-progress transaction.\n", stdout); | |
| 33825 sqlite3_exec(globalDb,"ROLLBACK", 0, 0, 0); | |
| 33826 } | |
| 33827 rc = sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); | |
| 33828 if( 0==rc ) sqlite3_exec(globalDb, "VACUUM", 0, 0, 0); | |
| 33829 sqlite3_db_config(globalDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); | |
| 33830 } | |
| 33831 } | |
| 33832 | |
| 33833 /* | |
| 33834 ** Uses the current database's VFS xRead to stream the db file's | |
| 33835 ** contents out to the given callback. The callback gets a single | |
| 33836 ** chunk of size n (its 2nd argument) on each call and must return 0 | |
| 33837 ** on success, non-0 on error. This function returns 0 on success, | |
| 33838 ** SQLITE_NOTFOUND if no db is open, or propagates any other non-0 | |
| 33839 ** code from the callback. Note that this is not thread-friendly: it | |
| 33840 ** expects that it will be the only thread reading the db file and | |
| 33841 ** takes no measures to ensure that is the case. | |
| 33842 */ | |
| 33843 int fiddle_export_db( int (*xCallback)(unsigned const char *zOut, int n) ){ | |
| 33844 sqlite3_int64 nSize = 0; | |
| 33845 sqlite3_int64 nPos = 0; | |
| 33846 sqlite3_file * pFile = 0; | |
| 33847 unsigned char buf[1024 * 8]; | |
| 33848 int nBuf = (int)sizeof(buf); | |
| 33849 int rc = shellState.db | |
| 33850 ? sqlite3_file_control(shellState.db, "main", | |
| 33851 SQLITE_FCNTL_FILE_POINTER, &pFile) | |
| 33852 : SQLITE_NOTFOUND; | |
| 33853 if( rc ) return rc; | |
| 33854 rc = pFile->pMethods->xFileSize(pFile, &nSize); | |
| 33855 if( rc ) return rc; | |
| 33856 if(nSize % nBuf){ | |
| 33857 /* DB size is not an even multiple of the buffer size. Reduce | |
| 33858 ** buffer size so that we do not unduly inflate the db size when | |
| 33859 ** exporting. */ | |
| 33860 if(0 == nSize % 4096) nBuf = 4096; | |
| 33861 else if(0 == nSize % 2048) nBuf = 2048; | |
| 33862 else if(0 == nSize % 1024) nBuf = 1024; | |
| 33863 else nBuf = 512; | |
| 33864 } | |
| 33865 for( ; 0==rc && nPos<nSize; nPos += nBuf ){ | |
| 33866 rc = pFile->pMethods->xRead(pFile, buf, nBuf, nPos); | |
| 33867 if(SQLITE_IOERR_SHORT_READ == rc){ | |
| 33868 rc = (nPos + nBuf) < nSize ? rc : 0/*assume EOF*/; | |
| 33869 } | |
| 33870 if( 0==rc ) rc = xCallback(buf, nBuf); | |
| 33871 } | |
| 33872 return rc; | |
| 33873 } | |
| 33874 | |
| 33875 /* | |
| 33876 ** Trivial exportable function for emscripten. It processes zSql as if | |
| 33877 ** it were input to the sqlite3 shell and redirects all output to the | |
| 33878 ** wasm binding. fiddle_main() must have been called before this | |
| 33879 ** is called, or results are undefined. | |
| 33880 */ | |
| 33881 void fiddle_exec(const char * zSql){ | |
| 33882 if(zSql && *zSql){ | |
| 33883 if('.'==*zSql) puts(zSql); | |
| 33884 shellState.wasm.zInput = zSql; | |
| 33885 shellState.wasm.zPos = zSql; | |
| 33886 process_input(&shellState, "<stdin>"); | |
| 33887 shellState.wasm.zInput = shellState.wasm.zPos = 0; | |
| 33888 } | |
| 33889 } | |
| 33890 #endif /* SQLITE_SHELL_FIDDLE */ |