Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Update the built-in SQLite to version 3.44.1. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
2edeeee4a8ae3028070590fc9a95e2c2 |
| User & Date: | drh 2023-11-22 20:22:38.425 |
Context
|
2023-11-24
| ||
| 12:59 | Update the built-in SQLite to version 3.44.2. check-in: 3f97785608 user: drh tags: trunk | |
|
2023-11-22
| ||
| 20:22 | Update the built-in SQLite to version 3.44.1. check-in: 2edeeee4a8 user: drh tags: trunk | |
|
2023-11-20
| ||
| 19:16 | On the activity report page, make sure the graph bar with the expected changes for the current week/month is not displayed on a separate line. check-in: 698dc59ec1 user: florian tags: trunk | |
Changes
Changes to extsrc/shell.c.
| ︙ | ︙ | |||
248 249 250 251 252 253 254 | #endif #undef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #include <windows.h> /* string conversion routines only needed on Win32 */ extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); | < < > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | > > > > | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 |
#endif
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
/* string conversion routines only needed on Win32 */
extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
#endif
/* Use console I/O package as a direct INCLUDE. */
#define SQLITE_INTERNAL_LINKAGE static
#ifdef SQLITE_SHELL_FIDDLE
/* Deselect most features from the console I/O package for Fiddle. */
# define SQLITE_CIO_NO_REDIRECT
# define SQLITE_CIO_NO_CLASSIFY
# define SQLITE_CIO_NO_TRANSLATE
# define SQLITE_CIO_NO_SETMODE
#endif
/************************* Begin ../ext/consio/console_io.h ******************/
/*
** 2023 November 1
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
********************************************************************************
** This file exposes various interfaces used for console and other I/O
** by the SQLite project command-line tools. These interfaces are used
** at either source conglomeration time, compilation time, or run time.
** This source provides for either inclusion into conglomerated,
** "single-source" forms or separate compilation then linking.
**
** Platform dependencies are "hidden" here by various stratagems so
** that, provided certain conditions are met, the programs using this
** source or object code compiled from it need no explicit conditional
** compilation in their source for their console and stream I/O.
**
** The symbols and functionality exposed here are not a public API.
** This code may change in tandem with other project code as needed.
**
** When this .h file and its companion .c are directly incorporated into
** a source conglomeration (such as shell.c), the preprocessor symbol
** CIO_WIN_WC_XLATE is defined as 0 or 1, reflecting whether console I/O
** translation for Windows is effected for the build.
*/
#ifndef SQLITE_INTERNAL_LINKAGE
# define SQLITE_INTERNAL_LINKAGE extern /* external to translation unit */
# include <stdio.h>
#else
# define SHELL_NO_SYSINC /* Better yet, modify mkshellc.tcl for this. */
#endif
#ifndef SQLITE3_H
/* # include "sqlite3.h" */
#endif
#ifndef SQLITE_CIO_NO_CLASSIFY
/* Define enum for use with following function. */
typedef enum StreamsAreConsole {
SAC_NoConsole = 0,
SAC_InConsole = 1, SAC_OutConsole = 2, SAC_ErrConsole = 4,
SAC_AnyConsole = 0x7
} StreamsAreConsole;
/*
** Classify the three standard I/O streams according to whether
** they are connected to a console attached to the process.
**
** Returns the bit-wise OR of SAC_{In,Out,Err}Console values,
** or SAC_NoConsole if none of the streams reaches a console.
**
** This function should be called before any I/O is done with
** the given streams. As a side-effect, the given inputs are
** recorded so that later I/O operations on them may be done
** differently than the C library FILE* I/O would be done,
** iff the stream is used for the I/O functions that follow,
** and to support the ones that use an implicit stream.
**
** On some platforms, stream or console mode alteration (aka
** "Setup") may be made which is undone by consoleRestore().
*/
SQLITE_INTERNAL_LINKAGE StreamsAreConsole
consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr );
/* A usual call for convenience: */
#define SQLITE_STD_CONSOLE_INIT() consoleClassifySetup(stdin,stdout,stderr)
/*
** After an initial call to consoleClassifySetup(...), renew
** the same setup it effected. (A call not after is an error.)
** This will restore state altered by consoleRestore();
**
** Applications which run an inferior (child) process which
** inherits the same I/O streams may call this function after
** such a process exits to guard against console mode changes.
*/
SQLITE_INTERNAL_LINKAGE void consoleRenewSetup(void);
/*
** Undo any side-effects left by consoleClassifySetup(...).
**
** This should be called after consoleClassifySetup() and
** before the process terminates normally. It is suitable
** for use with the atexit() C library procedure. After
** this call, no console I/O should be done until one of
** console{Classify or Renew}Setup(...) is called again.
**
** Applications which run an inferior (child) process that
** inherits the same I/O streams might call this procedure
** before so that said process will have a console setup
** however users have configured it or come to expect.
*/
SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void );
#else /* defined(SQLITE_CIO_NO_CLASSIFY) */
# define consoleClassifySetup(i,o,e)
# define consoleRenewSetup()
# define consoleRestore()
#endif /* defined(SQLITE_CIO_NO_CLASSIFY) */
#ifndef SQLITE_CIO_NO_REDIRECT
/*
** Set stream to be used for the functions below which write
** to "the designated X stream", where X is Output or Error.
** Returns the previous value.
**
** Alternatively, pass the special value, invalidFileStream,
** to get the designated stream value without setting it.
**
** Before the designated streams are set, they default to
** those passed to consoleClassifySetup(...), and before
** that is called they default to stdout and stderr.
**
** It is error to close a stream so designated, then, without
** designating another, use the corresponding {o,e}Emit(...).
*/
SQLITE_INTERNAL_LINKAGE FILE *invalidFileStream;
SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf);
# ifdef CONSIO_SET_ERROR_STREAM
SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf);
# endif
#else
# define setOutputStream(pf)
# define setErrorStream(pf)
#endif /* !defined(SQLITE_CIO_NO_REDIRECT) */
#ifndef SQLITE_CIO_NO_TRANSLATE
/*
** Emit output like fprintf(). If the output is going to the
** console and translation from UTF-8 is necessary, perform
** the needed translation. Otherwise, write formatted output
** to the provided stream almost as-is, possibly with newline
** translation as specified by set{Binary,Text}Mode().
*/
SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...);
/* Like fPrintfUtf8 except stream is always the designated output. */
SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...);
/* Like fPrintfUtf8 except stream is always the designated error. */
SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...);
/*
** Emit output like fputs(). If the output is going to the
** console and translation from UTF-8 is necessary, perform
** the needed translation. Otherwise, write given text to the
** provided stream almost as-is, possibly with newline
** translation as specified by set{Binary,Text}Mode().
*/
SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO);
/* Like fPutsUtf8 except stream is always the designated output. */
SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z);
/* Like fPutsUtf8 except stream is always the designated error. */
SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z);
/*
** Emit output like fPutsUtf8(), except that the length of the
** accepted char or character sequence is limited by nAccept.
**
** Returns the number of accepted char values.
*/
#ifdef CONSIO_SPUTB
SQLITE_INTERNAL_LINKAGE int
fPutbUtf8(FILE *pfOut, const char *cBuf, int nAccept);
#endif
/* Like fPutbUtf8 except stream is always the designated output. */
SQLITE_INTERNAL_LINKAGE int
oPutbUtf8(const char *cBuf, int nAccept);
/* Like fPutbUtf8 except stream is always the designated error. */
#ifdef CONSIO_EPUTB
SQLITE_INTERNAL_LINKAGE int
ePutbUtf8(const char *cBuf, int nAccept);
#endif
/*
** Collect input like fgets(...) with special provisions for input
** from the console on platforms that require same. Defers to the
** C library fgets() when input is not from the console. Newline
** translation may be done as set by set{Binary,Text}Mode(). As a
** convenience, pfIn==NULL is treated as stdin.
*/
SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn);
/* Like fGetsUtf8 except stream is always the designated input. */
/* SQLITE_INTERNAL_LINKAGE char* iGetsUtf8(char *cBuf, int ncMax); */
#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */
#ifndef SQLITE_CIO_NO_SETMODE
/*
** Set given stream for binary mode, where newline translation is
** not done, or for text mode where, for some platforms, newlines
** are translated to the platform's conventional char sequence.
** If bFlush true, flush the stream.
**
** An additional side-effect is that if the stream is one passed
** to consoleClassifySetup() as an output, it is flushed first.
**
** Note that binary/text mode has no effect on console I/O
** translation. On all platforms, newline to the console starts
** a new line and CR,LF chars from the console become a newline.
*/
SQLITE_INTERNAL_LINKAGE void setBinaryMode(FILE *, short bFlush);
SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *, short bFlush);
#endif
#ifdef SQLITE_CIO_PROMPTED_IN
typedef struct Prompts {
int numPrompts;
const char **azPrompts;
} Prompts;
/*
** Macros for use of a line editor.
**
** The following macros define operations involving use of a
** line-editing library or simple console interaction.
** A "T" argument is a text (char *) buffer or filename.
** A "N" argument is an integer.
**
** SHELL_ADD_HISTORY(T) // Record text as line(s) of history.
** SHELL_READ_HISTORY(T) // Read history from file named by T.
** SHELL_WRITE_HISTORY(T) // Write history to file named by T.
** SHELL_STIFLE_HISTORY(N) // Limit history to N entries.
**
** A console program which does interactive console input is
** expected to call:
** SHELL_READ_HISTORY(T) before collecting such input;
** SHELL_ADD_HISTORY(T) as record-worthy input is taken;
** SHELL_STIFLE_HISTORY(N) after console input ceases; then
** SHELL_WRITE_HISTORY(T) before the program exits.
*/
/*
** Retrieve a single line of input text from an input stream.
**
** If pfIn is the input stream passed to consoleClassifySetup(),
** and azPrompt is not NULL, then a prompt is issued before the
** line is collected, as selected by the isContinuation flag.
** Array azPrompt[{0,1}] holds the {main,continuation} prompt.
**
** If zBufPrior is not NULL then it is a buffer from a prior
** call to this routine that can be reused, or will be freed.
**
** The result is stored in space obtained from malloc() and
** must either be freed by the caller or else passed back to
** this function as zBufPrior for reuse.
**
** This function may call upon services of a line-editing
** library to interactively collect line edited input.
*/
SQLITE_INTERNAL_LINKAGE char *
shellGetLine(FILE *pfIn, char *zBufPrior, int nLen,
short isContinuation, Prompts azPrompt);
#endif /* defined(SQLITE_CIO_PROMPTED_IN) */
/*
** TBD: Define an interface for application(s) to generate
** completion candidates for use by the line-editor.
**
** This may be premature; the CLI is the only application
** that does this. Yet, getting line-editing melded into
** console I/O is desirable because a line-editing library
** may have to establish console operating mode, possibly
** in a way that interferes with the above functionality.
*/
#if !(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))
/* Skip over as much z[] input char sequence as is valid UTF-8,
** limited per nAccept char's or whole characters and containing
** no char cn such that ((1<<cn) & ccm)!=0. On return, the
** sequence z:return (inclusive:exclusive) is validated UTF-8.
** Limit: nAccept>=0 => char count, nAccept<0 => character
*/
SQLITE_INTERNAL_LINKAGE const char*
zSkipValidUtf8(const char *z, int nAccept, long ccm);
#endif
/************************* End ../ext/consio/console_io.h ********************/
/************************* Begin ../ext/consio/console_io.c ******************/
/*
** 2023 November 4
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
********************************************************************************
** This file implements various interfaces used for console and stream I/O
** by the SQLite project command-line tools, as explained in console_io.h .
** Functions prefixed by "SQLITE_INTERNAL_LINKAGE" behave as described there.
*/
#ifndef SQLITE_CDECL
# define SQLITE_CDECL
#endif
#ifndef SHELL_NO_SYSINC
# include <stdarg.h>
# include <string.h>
# include <stdlib.h>
# include <limits.h>
# include <assert.h>
# include "console_io.h"
/* # include "sqlite3.h" */
#endif
#ifndef SQLITE_CIO_NO_TRANSLATE
# if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT
# ifndef SHELL_NO_SYSINC
# include <io.h>
# include <fcntl.h>
# undef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# endif
# define CIO_WIN_WC_XLATE 1 /* Use WCHAR Windows APIs for console I/O */
# else
# ifndef SHELL_NO_SYSINC
# include <unistd.h>
# endif
# define CIO_WIN_WC_XLATE 0 /* Use plain C library stream I/O at console */
# endif
#else
# define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */
#endif
#if CIO_WIN_WC_XLATE
/* Character used to represent a known-incomplete UTF-8 char group (�) */
static WCHAR cBadGroup = 0xfffd;
#endif
#if CIO_WIN_WC_XLATE
static HANDLE handleOfFile(FILE *pf){
int fileDesc = _fileno(pf);
union { intptr_t osfh; HANDLE fh; } fid = {
(fileDesc>=0)? _get_osfhandle(fileDesc) : (intptr_t)INVALID_HANDLE_VALUE
};
return fid.fh;
}
#endif
#ifndef SQLITE_CIO_NO_TRANSLATE
typedef struct PerStreamTags {
# if CIO_WIN_WC_XLATE
HANDLE hx;
DWORD consMode;
char acIncomplete[4];
# else
short reachesConsole;
# endif
FILE *pf;
} PerStreamTags;
/* Define NULL-like value for things which can validly be 0. */
# define SHELL_INVALID_FILE_PTR ((FILE *)~0)
# if CIO_WIN_WC_XLATE
# define SHELL_INVALID_CONS_MODE 0xFFFF0000
# endif
# if CIO_WIN_WC_XLATE
# define PST_INITIALIZER { INVALID_HANDLE_VALUE, SHELL_INVALID_CONS_MODE, \
{0,0,0,0}, SHELL_INVALID_FILE_PTR }
# else
# define PST_INITIALIZER { 0, SHELL_INVALID_FILE_PTR }
# endif
/* Quickly say whether a known output is going to the console. */
# if CIO_WIN_WC_XLATE
static short pstReachesConsole(PerStreamTags *ppst){
return (ppst->hx != INVALID_HANDLE_VALUE);
}
# else
# define pstReachesConsole(ppst) 0
# endif
# if CIO_WIN_WC_XLATE
static void restoreConsoleArb(PerStreamTags *ppst){
if( pstReachesConsole(ppst) ) SetConsoleMode(ppst->hx, ppst->consMode);
}
# else
# define restoreConsoleArb(ppst)
# endif
/* Say whether FILE* appears to be a console, collect associated info. */
static short streamOfConsole(FILE *pf, /* out */ PerStreamTags *ppst){
# if CIO_WIN_WC_XLATE
short rv = 0;
DWORD dwCM = SHELL_INVALID_CONS_MODE;
HANDLE fh = handleOfFile(pf);
ppst->pf = pf;
if( INVALID_HANDLE_VALUE != fh ){
rv = (GetFileType(fh) == FILE_TYPE_CHAR && GetConsoleMode(fh,&dwCM));
}
ppst->hx = (rv)? fh : INVALID_HANDLE_VALUE;
ppst->consMode = dwCM;
return rv;
# else
ppst->pf = pf;
ppst->reachesConsole = ( (short)isatty(fileno(pf)) );
return ppst->reachesConsole;
# endif
}
# if CIO_WIN_WC_XLATE
/* Define console modes for use with the Windows Console API. */
# define SHELL_CONI_MODE \
(ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | 0x80 \
| ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS | ENABLE_PROCESSED_INPUT)
# define SHELL_CONO_MODE (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT \
| ENABLE_VIRTUAL_TERMINAL_PROCESSING)
# endif
typedef struct ConsoleInfo {
PerStreamTags pstSetup[3];
PerStreamTags pstDesignated[3];
StreamsAreConsole sacSetup;
} ConsoleInfo;
static short isValidStreamInfo(PerStreamTags *ppst){
return (ppst->pf != SHELL_INVALID_FILE_PTR);
}
static ConsoleInfo consoleInfo = {
{ /* pstSetup */ PST_INITIALIZER, PST_INITIALIZER, PST_INITIALIZER },
{ /* pstDesignated[] */ PST_INITIALIZER, PST_INITIALIZER, PST_INITIALIZER },
SAC_NoConsole /* sacSetup */
};
SQLITE_INTERNAL_LINKAGE FILE* invalidFileStream = (FILE *)~0;
# if CIO_WIN_WC_XLATE
static void maybeSetupAsConsole(PerStreamTags *ppst, short odir){
if( pstReachesConsole(ppst) ){
DWORD cm = odir? SHELL_CONO_MODE : SHELL_CONI_MODE;
SetConsoleMode(ppst->hx, cm);
}
}
# else
# define maybeSetupAsConsole(ppst,odir)
# endif
SQLITE_INTERNAL_LINKAGE void consoleRenewSetup(void){
# if CIO_WIN_WC_XLATE
int ix = 0;
while( ix < 6 ){
PerStreamTags *ppst = (ix<3)?
&consoleInfo.pstSetup[ix] : &consoleInfo.pstDesignated[ix-3];
maybeSetupAsConsole(ppst, (ix % 3)>0);
++ix;
}
# endif
}
SQLITE_INTERNAL_LINKAGE StreamsAreConsole
consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ){
StreamsAreConsole rv = SAC_NoConsole;
FILE* apf[3] = { pfIn, pfOut, pfErr };
int ix;
for( ix = 2; ix >= 0; --ix ){
PerStreamTags *ppst = &consoleInfo.pstSetup[ix];
if( streamOfConsole(apf[ix], ppst) ){
rv |= (SAC_InConsole<<ix);
}
consoleInfo.pstDesignated[ix] = *ppst;
if( ix > 0 ) fflush(apf[ix]);
}
consoleInfo.sacSetup = rv;
consoleRenewSetup();
return rv;
}
SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void ){
# if CIO_WIN_WC_XLATE
static ConsoleInfo *pci = &consoleInfo;
if( pci->sacSetup ){
int ix;
for( ix=0; ix<3; ++ix ){
if( pci->sacSetup & (SAC_InConsole<<ix) ){
PerStreamTags *ppst = &pci->pstSetup[ix];
SetConsoleMode(ppst->hx, ppst->consMode);
}
}
}
# endif
}
#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */
#ifdef SQLITE_CIO_INPUT_REDIR
/* Say whether given FILE* is among those known, via either
** consoleClassifySetup() or set{Output,Error}Stream, as
** readable, and return an associated PerStreamTags pointer
** if so. Otherwise, return 0.
*/
static PerStreamTags * isKnownReadable(FILE *pf){
static PerStreamTags *apst[] = {
&consoleInfo.pstDesignated[0], &consoleInfo.pstSetup[0], 0
};
int ix = 0;
do {
if( apst[ix]->pf == pf ) break;
} while( apst[++ix] != 0 );
return apst[ix];
}
#endif
#ifndef SQLITE_CIO_NO_TRANSLATE
/* Say whether given FILE* is among those known, via either
** consoleClassifySetup() or set{Output,Error}Stream, as
** writable, and return an associated PerStreamTags pointer
** if so. Otherwise, return 0.
*/
static PerStreamTags * isKnownWritable(FILE *pf){
static PerStreamTags *apst[] = {
&consoleInfo.pstDesignated[1], &consoleInfo.pstDesignated[2],
&consoleInfo.pstSetup[1], &consoleInfo.pstSetup[2], 0
};
int ix = 0;
do {
if( apst[ix]->pf == pf ) break;
} while( apst[++ix] != 0 );
return apst[ix];
}
static FILE *designateEmitStream(FILE *pf, unsigned chix){
FILE *rv = consoleInfo.pstDesignated[chix].pf;
if( pf == invalidFileStream ) return rv;
else{
/* Setting a possibly new output stream. */
PerStreamTags *ppst = isKnownWritable(pf);
if( ppst != 0 ){
PerStreamTags pst = *ppst;
consoleInfo.pstDesignated[chix] = pst;
}else streamOfConsole(pf, &consoleInfo.pstDesignated[chix]);
}
return rv;
}
SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf){
return designateEmitStream(pf, 1);
}
# ifdef CONSIO_SET_ERROR_STREAM
SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf){
return designateEmitStream(pf, 2);
}
# endif
#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */
#ifndef SQLITE_CIO_NO_SETMODE
# if CIO_WIN_WC_XLATE
static void setModeFlushQ(FILE *pf, short bFlush, int mode){
if( bFlush ) fflush(pf);
_setmode(_fileno(pf), mode);
}
# else
# define setModeFlushQ(f, b, m) if(b) fflush(f)
# endif
SQLITE_INTERNAL_LINKAGE void setBinaryMode(FILE *pf, short bFlush){
setModeFlushQ(pf, bFlush, _O_BINARY);
}
SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *pf, short bFlush){
setModeFlushQ(pf, bFlush, _O_TEXT);
}
# undef setModeFlushQ
#else /* defined(SQLITE_CIO_NO_SETMODE) */
# define setBinaryMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0)
# define setTextMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0)
#endif /* defined(SQLITE_CIO_NO_SETMODE) */
#ifndef SQLITE_CIO_NO_TRANSLATE
# if CIO_WIN_WC_XLATE
/* Write buffer cBuf as output to stream known to reach console,
** limited to ncTake char's. Return ncTake on success, else 0. */
static int conZstrEmit(PerStreamTags *ppst, const char *z, int ncTake){
int rv = 0;
if( z!=NULL ){
int nwc = MultiByteToWideChar(CP_UTF8,0, z,ncTake, 0,0);
if( nwc > 0 ){
WCHAR *zw = sqlite3_malloc64(nwc*sizeof(WCHAR));
if( zw!=NULL ){
nwc = MultiByteToWideChar(CP_UTF8,0, z,ncTake, zw,nwc);
if( nwc > 0 ){
/* Translation from UTF-8 to UTF-16, then WCHARs out. */
if( WriteConsoleW(ppst->hx, zw,nwc, 0, NULL) ){
rv = ncTake;
}
}
sqlite3_free(zw);
}
}
}
return rv;
}
/* For {f,o,e}PrintfUtf8() when stream is known to reach console. */
static int conioVmPrintf(PerStreamTags *ppst, const char *zFormat, va_list ap){
char *z = sqlite3_vmprintf(zFormat, ap);
if( z ){
int rv = conZstrEmit(ppst, z, (int)strlen(z));
sqlite3_free(z);
return rv;
}else return 0;
}
# endif /* CIO_WIN_WC_XLATE */
# ifdef CONSIO_GET_EMIT_STREAM
static PerStreamTags * getDesignatedEmitStream(FILE *pf, unsigned chix,
PerStreamTags *ppst){
PerStreamTags *rv = isKnownWritable(pf);
short isValid = (rv!=0)? isValidStreamInfo(rv) : 0;
if( rv != 0 && isValid ) return rv;
streamOfConsole(pf, ppst);
return ppst;
}
# endif
/* Get stream info, either for designated output or error stream when
** chix equals 1 or 2, or for an arbitrary stream when chix == 0.
** In either case, ppst references a caller-owned PerStreamTags
** struct which may be filled in if none of the known writable
** streams is being held by consoleInfo. The ppf parameter is an
** output when chix!=0 and an input when chix==0.
*/
static PerStreamTags *
getEmitStreamInfo(unsigned chix, PerStreamTags *ppst,
/* in/out */ FILE **ppf){
PerStreamTags *ppstTry;
FILE *pfEmit;
if( chix > 0 ){
ppstTry = &consoleInfo.pstDesignated[chix];
if( !isValidStreamInfo(ppstTry) ){
ppstTry = &consoleInfo.pstSetup[chix];
pfEmit = ppst->pf;
}else pfEmit = ppstTry->pf;
if( !isValidStreamInfo(ppst) ){
pfEmit = (chix > 1)? stderr : stdout;
ppstTry = ppst;
streamOfConsole(pfEmit, ppstTry);
}
*ppf = pfEmit;
}else{
ppstTry = isKnownWritable(*ppf);
if( ppstTry != 0 ) return ppstTry;
streamOfConsole(*ppf, ppst);
return ppst;
}
return ppstTry;
}
SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...){
va_list ap;
int rv;
FILE *pfOut;
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
# if CIO_WIN_WC_XLATE
PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut);
# else
getEmitStreamInfo(1, &pst, &pfOut);
# endif
assert(zFormat!=0);
va_start(ap, zFormat);
# if CIO_WIN_WC_XLATE
if( pstReachesConsole(ppst) ){
rv = conioVmPrintf(ppst, zFormat, ap);
}else{
# endif
rv = vfprintf(pfOut, zFormat, ap);
# if CIO_WIN_WC_XLATE
}
# endif
va_end(ap);
return rv;
}
SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...){
va_list ap;
int rv;
FILE *pfErr;
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
# if CIO_WIN_WC_XLATE
PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr);
# else
getEmitStreamInfo(2, &pst, &pfErr);
# endif
assert(zFormat!=0);
va_start(ap, zFormat);
# if CIO_WIN_WC_XLATE
if( pstReachesConsole(ppst) ){
rv = conioVmPrintf(ppst, zFormat, ap);
}else{
# endif
rv = vfprintf(pfErr, zFormat, ap);
# if CIO_WIN_WC_XLATE
}
# endif
va_end(ap);
return rv;
}
SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...){
va_list ap;
int rv;
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
# if CIO_WIN_WC_XLATE
PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO);
# else
getEmitStreamInfo(0, &pst, &pfO);
# endif
assert(zFormat!=0);
va_start(ap, zFormat);
# if CIO_WIN_WC_XLATE
if( pstReachesConsole(ppst) ){
maybeSetupAsConsole(ppst, 1);
rv = conioVmPrintf(ppst, zFormat, ap);
if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
}else{
# endif
rv = vfprintf(pfO, zFormat, ap);
# if CIO_WIN_WC_XLATE
}
# endif
va_end(ap);
return rv;
}
SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO){
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
# if CIO_WIN_WC_XLATE
PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO);
# else
getEmitStreamInfo(0, &pst, &pfO);
# endif
assert(z!=0);
# if CIO_WIN_WC_XLATE
if( pstReachesConsole(ppst) ){
int rv;
maybeSetupAsConsole(ppst, 1);
rv = conZstrEmit(ppst, z, (int)strlen(z));
if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
return rv;
}else {
# endif
return (fputs(z, pfO)<0)? 0 : (int)strlen(z);
# if CIO_WIN_WC_XLATE
}
# endif
}
SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z){
FILE *pfErr;
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
# if CIO_WIN_WC_XLATE
PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr);
# else
getEmitStreamInfo(2, &pst, &pfErr);
# endif
assert(z!=0);
# if CIO_WIN_WC_XLATE
if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z));
else {
# endif
return (fputs(z, pfErr)<0)? 0 : (int)strlen(z);
# if CIO_WIN_WC_XLATE
}
# endif
}
SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z){
FILE *pfOut;
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
# if CIO_WIN_WC_XLATE
PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut);
# else
getEmitStreamInfo(1, &pst, &pfOut);
# endif
assert(z!=0);
# if CIO_WIN_WC_XLATE
if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z));
else {
# endif
return (fputs(z, pfOut)<0)? 0 : (int)strlen(z);
# if CIO_WIN_WC_XLATE
}
# endif
}
#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */
#if !(defined(SQLITE_CIO_NO_UTF8SCAN) && defined(SQLITE_CIO_NO_TRANSLATE))
/* Skip over as much z[] input char sequence as is valid UTF-8,
** limited per nAccept char's or whole characters and containing
** no char cn such that ((1<<cn) & ccm)!=0. On return, the
** sequence z:return (inclusive:exclusive) is validated UTF-8.
** Limit: nAccept>=0 => char count, nAccept<0 => character
*/
SQLITE_INTERNAL_LINKAGE const char*
zSkipValidUtf8(const char *z, int nAccept, long ccm){
int ng = (nAccept<0)? -nAccept : 0;
const char *pcLimit = (nAccept>=0)? z+nAccept : 0;
assert(z!=0);
while( (pcLimit)? (z<pcLimit) : (ng-- != 0) ){
char c = *z;
if( (c & 0x80) == 0 ){
if( ccm != 0L && c < 0x20 && ((1L<<c) & ccm) != 0 ) return z;
++z; /* ASCII */
}else if( (c & 0xC0) != 0xC0 ) return z; /* not a lead byte */
else{
const char *zt = z+1; /* Got lead byte, look at trail bytes.*/
do{
if( pcLimit && zt >= pcLimit ) return z;
else{
char ct = *zt++;
if( ct==0 || (zt-z)>4 || (ct & 0xC0)!=0x80 ){
/* Trailing bytes are too few, too many, or invalid. */
return z;
}
}
} while( ((c <<= 1) & 0x40) == 0x40 ); /* Eat lead byte's count. */
z = zt;
}
}
return z;
}
#endif /*!(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))*/
#ifndef SQLITE_CIO_NO_TRANSLATE
#ifdef CONSIO_SPUTB
SQLITE_INTERNAL_LINKAGE int
fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){
assert(pfO!=0);
# if CIO_WIN_WC_XLATE
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO);
if( pstReachesConsole(ppst) ){
int rv;
maybeSetupAsConsole(ppst, 1);
rv = conZstrEmit(ppst, cBuf, nAccept);
if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
return rv;
}else {
# endif
return (int)fwrite(cBuf, 1, nAccept, pfO);
# if CIO_WIN_WC_XLATE
}
# endif
}
#endif /* defined(CONSIO_SPUTB) */
SQLITE_INTERNAL_LINKAGE int
oPutbUtf8(const char *cBuf, int nAccept){
FILE *pfOut;
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
# if CIO_WIN_WC_XLATE
PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut);
# else
getEmitStreamInfo(1, &pst, &pfOut);
# endif
# if CIO_WIN_WC_XLATE
if( pstReachesConsole(ppst) ){
return conZstrEmit(ppst, cBuf, nAccept);
}else {
# endif
return (int)fwrite(cBuf, 1, nAccept, pfOut);
# if CIO_WIN_WC_XLATE
}
# endif
}
# ifdef CONSIO_EPUTB
SQLITE_INTERNAL_LINKAGE int
ePutbUtf8(const char *cBuf, int nAccept){
FILE *pfErr;
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr);
# if CIO_WIN_WC_XLATE
if( pstReachesConsole(ppst) ){
return conZstrEmit(ppst, cBuf, nAccept);
}else {
# endif
return (int)fwrite(cBuf, 1, nAccept, pfErr);
# if CIO_WIN_WC_XLATE
}
# endif
}
# endif /* defined(CONSIO_EPUTB) */
SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn){
if( pfIn==0 ) pfIn = stdin;
# if CIO_WIN_WC_XLATE
if( pfIn == consoleInfo.pstSetup[0].pf
&& (consoleInfo.sacSetup & SAC_InConsole)!=0 ){
# if CIO_WIN_WC_XLATE==1
# define SHELL_GULP 150 /* Count of WCHARS to be gulped at a time */
WCHAR wcBuf[SHELL_GULP+1];
int lend = 0, noc = 0;
if( ncMax > 0 ) cBuf[0] = 0;
while( noc < ncMax-8-1 && !lend ){
/* There is room for at least 2 more characters and a 0-terminator. */
int na = (ncMax > SHELL_GULP*4+1 + noc)? SHELL_GULP : (ncMax-1 - noc)/4;
# undef SHELL_GULP
DWORD nbr = 0;
BOOL bRC = ReadConsoleW(consoleInfo.pstSetup[0].hx, wcBuf, na, &nbr, 0);
if( bRC && nbr>0 && (wcBuf[nbr-1]&0xF800)==0xD800 ){
/* Last WHAR read is first of a UTF-16 surrogate pair. Grab its mate. */
DWORD nbrx;
bRC &= ReadConsoleW(consoleInfo.pstSetup[0].hx, wcBuf+nbr, 1, &nbrx, 0);
if( bRC ) nbr += nbrx;
}
if( !bRC || (noc==0 && nbr==0) ) return 0;
if( nbr > 0 ){
int nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,0,0,0,0);
if( nmb != 0 && noc+nmb <= ncMax ){
int iseg = noc;
nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,cBuf+noc,nmb,0,0);
noc += nmb;
/* Fixup line-ends as coded by Windows for CR (or "Enter".)
** This is done without regard for any setMode{Text,Binary}()
** call that might have been done on the interactive input.
*/
if( noc > 0 ){
if( cBuf[noc-1]=='\n' ){
lend = 1;
if( noc > 1 && cBuf[noc-2]=='\r' ) cBuf[--noc-1] = '\n';
}
}
/* Check for ^Z (anywhere in line) too, to act as EOF. */
while( iseg < noc ){
if( cBuf[iseg]=='\x1a' ){
noc = iseg; /* Chop ^Z and anything following. */
lend = 1; /* Counts as end of line too. */
break;
}
++iseg;
}
}else break; /* Drop apparent garbage in. (Could assert.) */
}else break;
}
/* If got nothing, (after ^Z chop), must be at end-of-file. */
if( noc > 0 ){
cBuf[noc] = 0;
return cBuf;
}else return 0;
# endif
}else{
# endif
return fgets(cBuf, ncMax, pfIn);
# if CIO_WIN_WC_XLATE
}
# endif
}
#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */
#undef SHELL_INVALID_FILE_PTR
/************************* End ../ext/consio/console_io.c ********************/
#ifndef SQLITE_SHELL_FIDDLE
/* From here onward, fgets() is redirected to the console_io library. */
# define fgets(b,n,f) fGetsUtf8(b,n,f)
/*
* Define macros for emitting output text in various ways:
* sputz(s, z) => emit 0-terminated string z to given stream s
* sputf(s, f, ...) => emit varargs per format f to given stream s
* oputz(z) => emit 0-terminated string z to default stream
* oputf(f, ...) => emit varargs per format f to default stream
* eputz(z) => emit 0-terminated string z to error stream
* eputf(f, ...) => emit varargs per format f to error stream
* oputb(b, n) => emit char buffer b[0..n-1] to default stream
*
* Note that the default stream is whatever has been last set via:
* setOutputStream(FILE *pf)
* This is normally the stream that CLI normal output goes to.
* For the stand-alone CLI, it is stdout with no .output redirect.
*/
# define sputz(s,z) fPutsUtf8(z,s)
# define sputf fPrintfUtf8
# define oputz(z) oPutsUtf8(z)
# define oputf oPrintfUtf8
# define eputz(z) ePutsUtf8(z)
# define eputf ePrintfUtf8
# define oputb(buf,na) oPutbUtf8(buf,na)
#else
/* For Fiddle, all console handling and emit redirection is omitted. */
# define sputz(fp,z) fputs(z,fp)
# define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__)
# define oputz(z) fputs(z,stdout)
# define oputf(fmt, ...) printf(fmt,__VA_ARGS__)
# define eputz(z) fputs(z,stderr)
# define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__)
# define oputb(buf,na) fwrite(buf,1,na,stdout)
#endif
/* True if the timer is enabled */
static int enableTimer = 0;
/* A version of strcmp() that works with NULL values */
static int cli_strcmp(const char *a, const char *b){
|
| ︙ | ︙ | |||
345 346 347 348 349 350 351 |
** Print the timing results.
*/
static void endTimer(void){
if( enableTimer ){
sqlite3_int64 iEnd = timeOfDay();
struct rusage sEnd;
getrusage(RUSAGE_SELF, &sEnd);
| | | | | | 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 |
** Print the timing results.
*/
static void endTimer(void){
if( enableTimer ){
sqlite3_int64 iEnd = timeOfDay();
struct rusage sEnd;
getrusage(RUSAGE_SELF, &sEnd);
oputf("Run Time: real %.3f user %f sys %f\n",
(iEnd - iBegin)*0.001,
timeDiff(&sBegin.ru_utime, &sEnd.ru_utime),
timeDiff(&sBegin.ru_stime, &sEnd.ru_stime));
}
}
#define BEGIN_TIMER beginTimer()
#define END_TIMER endTimer()
#define HAS_TIMER 1
|
| ︙ | ︙ | |||
424 425 426 427 428 429 430 |
** Print the timing results.
*/
static void endTimer(void){
if( enableTimer && getProcessTimesAddr){
FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
sqlite3_int64 ftWallEnd = timeOfDay();
getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
| | | | | | 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 |
** Print the timing results.
*/
static void endTimer(void){
if( enableTimer && getProcessTimesAddr){
FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd;
sqlite3_int64 ftWallEnd = timeOfDay();
getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd);
oputf("Run Time: real %.3f user %f sys %f\n",
(ftWallEnd - ftWallBegin)*0.001,
timeDiff(&ftUserBegin, &ftUserEnd),
timeDiff(&ftKernelBegin, &ftKernelEnd));
}
}
#define BEGIN_TIMER beginTimer()
#define END_TIMER endTimer()
#define HAS_TIMER hasTimer()
|
| ︙ | ︙ | |||
464 465 466 467 468 469 470 | /* ** Treat stdin as an interactive input if the following variable ** is true. Otherwise, assume stdin is connected to a file or pipe. */ static int stdin_is_interactive = 1; /* | < < < < < < < < < < < < < < < < < < < | | | | 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 | /* ** Treat stdin as an interactive input if the following variable ** is true. Otherwise, assume stdin is connected to a file or pipe. */ static int stdin_is_interactive = 1; /* ** On Windows systems we need to know if standard output is a console ** in order to show that UTF-16 translation is done in the sign-on ** banner. The following variable is true if it is the console. */ static int stdout_is_console = 1; /* ** The following is the open SQLite database. We make a pointer ** to this database a static variable so that it can be accessed ** by the SIGINT handler to interrupt database processing. |
| ︙ | ︙ | |||
607 608 609 610 611 612 613 |
shell_strncpy(dynPrompt.dynamicPrompt, "(..", 4);
}else if( dynPrompt.inParenLevel<0 ){
shell_strncpy(dynPrompt.dynamicPrompt, ")x!", 4);
}else{
shell_strncpy(dynPrompt.dynamicPrompt, "(x.", 4);
dynPrompt.dynamicPrompt[2] = (char)('0'+dynPrompt.inParenLevel);
}
| | > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 |
shell_strncpy(dynPrompt.dynamicPrompt, "(..", 4);
}else if( dynPrompt.inParenLevel<0 ){
shell_strncpy(dynPrompt.dynamicPrompt, ")x!", 4);
}else{
shell_strncpy(dynPrompt.dynamicPrompt, "(x.", 4);
dynPrompt.dynamicPrompt[2] = (char)('0'+dynPrompt.inParenLevel);
}
shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
PROMPT_LEN_MAX-4);
}
}
return dynPrompt.dynamicPrompt;
}
#endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */
/* Indicate out-of-memory and exit. */
static void shell_out_of_memory(void){
eputz("Error: out of memory\n");
exit(1);
}
/* Check a pointer to see if it is NULL. If it is NULL, exit with an
** out-of-memory error.
*/
static void shell_check_oom(const void *p){
|
| ︙ | ︙ | |||
883 884 885 886 887 888 889 |
static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
va_list ap;
char *z;
if( iotrace==0 ) return;
va_start(ap, zFormat);
z = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
| | | | | | | | 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 |
static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){
va_list ap;
char *z;
if( iotrace==0 ) return;
va_start(ap, zFormat);
z = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
sputf(iotrace, "%s", z);
sqlite3_free(z);
}
#endif
/*
** Output string zUtf to Out stream as w characters. If w is negative,
** then right-justify the text. W is the width in UTF-8 characters, not
** in bytes. This is different from the %*.*s specification in printf
** since with %*.*s the width is measured in bytes, not characters.
*/
static void utf8_width_print(int w, const char *zUtf){
int i;
int n;
int aw = w<0 ? -w : w;
if( zUtf==0 ) zUtf = "";
for(i=n=0; zUtf[i]; i++){
if( (zUtf[i]&0xc0)!=0x80 ){
n++;
if( n==aw ){
do{ i++; }while( (zUtf[i]&0xc0)==0x80 );
break;
}
}
}
if( n>=aw ){
oputf("%.*s", i, zUtf);
}else if( w<0 ){
oputf("%*s%s", aw-n, "", zUtf);
}else{
oputf("%s%*s", zUtf, aw-n, "");
}
}
/*
** Determines if a string is a number of not.
*/
|
| ︙ | ︙ | |||
973 974 975 976 977 978 979 |
/*
** Return open FILE * if zFile exists, can be opened for read
** and is an ordinary file or a character stream source.
** Otherwise return 0.
*/
static FILE * openChrSource(const char *zFile){
| | | 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 |
/*
** Return open FILE * if zFile exists, can be opened for read
** and is an ordinary file or a character stream source.
** Otherwise return 0.
*/
static FILE * openChrSource(const char *zFile){
#if defined(_WIN32) || defined(WIN32)
struct _stat x = {0};
# define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0)
/* On Windows, open first, then check the stream nature. This order
** is necessary because _stat() and sibs, when checking a named pipe,
** effectively break the pipe as its supplier sees it. */
FILE *rv = fopen(zFile, "rb");
if( rv==0 ) return 0;
|
| ︙ | ︙ | |||
1036 1037 1038 1039 1040 1041 1042 |
if( n>0 && zLine[n-1]=='\n' ){
n--;
if( n>0 && zLine[n-1]=='\r' ) n--;
zLine[n] = 0;
break;
}
}
| < < < < < < < < < < < < < < < < < | 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 |
if( n>0 && zLine[n-1]=='\n' ){
n--;
if( n>0 && zLine[n-1]=='\r' ) n--;
zLine[n] = 0;
break;
}
}
return zLine;
}
/*
** Retrieve a single line of input text.
**
** If in==0 then read from standard input and prompt before each line.
|
| ︙ | ︙ | |||
1079 1080 1081 1082 1083 1084 1085 |
char *zPrompt;
char *zResult;
if( in!=0 ){
zResult = local_getline(zPrior, in);
}else{
zPrompt = isContinuation ? CONTINUATION_PROMPT : mainPrompt;
#if SHELL_USE_LOCAL_GETLINE
| | | 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 |
char *zPrompt;
char *zResult;
if( in!=0 ){
zResult = local_getline(zPrior, in);
}else{
zPrompt = isContinuation ? CONTINUATION_PROMPT : mainPrompt;
#if SHELL_USE_LOCAL_GETLINE
sputz(stdout, zPrompt);
fflush(stdout);
do{
zResult = local_getline(zPrior, stdin);
zPrior = 0;
/* ^C trap creates a false EOF, so let "interrupt" thread catch up. */
if( zResult==0 ) sqlite3_sleep(50);
}while( zResult==0 && seenInterrupt>0 );
|
| ︙ | ︙ | |||
1326 1327 1328 1329 1330 1331 1332 |
sqlite3_value **apVal
){
double r = sqlite3_value_double(apVal[0]);
int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26;
char z[400];
if( n<1 ) n = 1;
if( n>350 ) n = 350;
| | | 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 |
sqlite3_value **apVal
){
double r = sqlite3_value_double(apVal[0]);
int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26;
char z[400];
if( n<1 ) n = 1;
if( n>350 ) n = 350;
sqlite3_snprintf(sizeof(z), z, "%#+.*e", n, r);
sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT);
}
/*
** SQL function: shell_module_schema(X)
**
|
| ︙ | ︙ | |||
17612 17613 17614 17615 17616 17617 17618 |
/*
** A callback for the sqlite3_log() interface.
*/
static void shellLog(void *pArg, int iErrCode, const char *zMsg){
ShellState *p = (ShellState*)pArg;
if( p->pLog==0 ) return;
| | | | | < | 18332 18333 18334 18335 18336 18337 18338 18339 18340 18341 18342 18343 18344 18345 18346 18347 18348 18349 18350 18351 18352 18353 18354 18355 18356 18357 18358 18359 18360 18361 18362 18363 18364 18365 18366 18367 18368 18369 18370 18371 18372 18373 18374 18375 18376 18377 18378 18379 18380 18381 18382 |
/*
** A callback for the sqlite3_log() interface.
*/
static void shellLog(void *pArg, int iErrCode, const char *zMsg){
ShellState *p = (ShellState*)pArg;
if( p->pLog==0 ) return;
sputf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
fflush(p->pLog);
}
/*
** SQL function: shell_putsnl(X)
**
** Write the text X to the screen (or whatever output is being directed)
** adding a newline at the end, and then return X.
*/
static void shellPutsFunc(
sqlite3_context *pCtx,
int nVal,
sqlite3_value **apVal
){
/* Unused: (ShellState*)sqlite3_user_data(pCtx); */
(void)nVal;
oputf("%s\n", sqlite3_value_text(apVal[0]));
sqlite3_result_value(pCtx, apVal[0]);
}
/*
** If in safe mode, print an error message described by the arguments
** and exit immediately.
*/
static void failIfSafeMode(
ShellState *p,
const char *zErrMsg,
...
){
if( p->bSafeMode ){
va_list ap;
char *zMsg;
va_start(ap, zErrMsg);
zMsg = sqlite3_vmprintf(zErrMsg, ap);
va_end(ap);
eputf("line %d: %s\n", p->lineno, zMsg);
exit(1);
}
}
/*
** SQL function: edit(VALUE)
** edit(VALUE,EDITOR)
|
| ︙ | ︙ | |||
17817 17818 17819 17820 17821 17822 17823 | memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator)); memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator)); } /* ** Output the given string as a hex-encoded blob (eg. X'1234' ) */ | | | | 18536 18537 18538 18539 18540 18541 18542 18543 18544 18545 18546 18547 18548 18549 18550 18551 18552 18553 18554 18555 18556 18557 18558 18559 18560 18561 18562 18563 18564 18565 18566 18567 |
memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
}
/*
** Output the given string as a hex-encoded blob (eg. X'1234' )
*/
static void output_hex_blob(const void *pBlob, int nBlob){
int i;
unsigned char *aBlob = (unsigned char*)pBlob;
char *zStr = sqlite3_malloc(nBlob*2 + 1);
shell_check_oom(zStr);
for(i=0; i<nBlob; i++){
static const char aHex[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
zStr[i*2] = aHex[ (aBlob[i] >> 4) ];
zStr[i*2+1] = aHex[ (aBlob[i] & 0x0F) ];
}
zStr[i*2] = '\0';
oputf("X'%s'", zStr);
sqlite3_free(zStr);
}
/*
** Find a string that is not found anywhere in z[]. Return a pointer
** to that string.
**
|
| ︙ | ︙ | |||
17864 17865 17866 17867 17868 17869 17870 | } /* ** Output the given string as a quoted string using SQL quoting conventions. ** ** See also: output_quoted_escaped_string() */ | | > > | > | | | | | > | > > > | > > | > | | | | | | | | | | | > | > > > > > > > > > > > > > > > > > > > > | | > > > > > | | > > > | < < | < < > | | > > | | < < > > > > | < > | | > | > | | > > > > > > > | | | | > > > > > > > > | | > > > > > > > > > > > | < < < < < < < < < < < < | < > | | | | | | | | | | 18583 18584 18585 18586 18587 18588 18589 18590 18591 18592 18593 18594 18595 18596 18597 18598 18599 18600 18601 18602 18603 18604 18605 18606 18607 18608 18609 18610 18611 18612 18613 18614 18615 18616 18617 18618 18619 18620 18621 18622 18623 18624 18625 18626 18627 18628 18629 18630 18631 18632 18633 18634 18635 18636 18637 18638 18639 18640 18641 18642 18643 18644 18645 18646 18647 18648 18649 18650 18651 18652 18653 18654 18655 18656 18657 18658 18659 18660 18661 18662 18663 18664 18665 18666 18667 18668 18669 18670 18671 18672 18673 18674 18675 18676 18677 18678 18679 18680 18681 18682 18683 18684 18685 18686 18687 18688 18689 18690 18691 18692 18693 18694 18695 18696 18697 18698 18699 18700 18701 18702 18703 18704 18705 18706 18707 18708 18709 18710 18711 18712 18713 18714 18715 18716 18717 18718 18719 18720 18721 18722 18723 18724 18725 18726 18727 18728 18729 18730 18731 18732 18733 18734 18735 18736 18737 18738 18739 18740 18741 18742 18743 18744 18745 18746 18747 18748 18749 18750 18751 18752 18753 18754 18755 18756 18757 18758 18759 18760 18761 18762 18763 18764 18765 18766 18767 18768 18769 18770 18771 18772 18773 18774 18775 18776 18777 18778 18779 18780 18781 18782 18783 18784 18785 18786 18787 18788 18789 18790 18791 18792 18793 18794 18795 18796 18797 18798 18799 18800 18801 18802 18803 18804 18805 18806 18807 18808 18809 18810 18811 18812 18813 18814 18815 18816 18817 18818 18819 18820 18821 18822 18823 18824 18825 18826 18827 18828 18829 18830 18831 18832 18833 18834 18835 18836 18837 18838 18839 18840 18841 18842 18843 18844 |
}
/*
** Output the given string as a quoted string using SQL quoting conventions.
**
** See also: output_quoted_escaped_string()
*/
static void output_quoted_string(const char *z){
int i;
char c;
#ifndef SQLITE_SHELL_FIDDLE
FILE *pfO = setOutputStream(invalidFileStream);
setBinaryMode(pfO, 1);
#endif
if( z==0 ) return;
for(i=0; (c = z[i])!=0 && c!='\''; i++){}
if( c==0 ){
oputf("'%s'",z);
}else{
oputz("'");
while( *z ){
for(i=0; (c = z[i])!=0 && c!='\''; i++){}
if( c=='\'' ) i++;
if( i ){
oputf("%.*s", i, z);
z += i;
}
if( c=='\'' ){
oputz("'");
continue;
}
if( c==0 ){
break;
}
z++;
}
oputz("'");
}
#ifndef SQLITE_SHELL_FIDDLE
setTextMode(pfO, 1);
#else
setTextMode(stdout, 1);
#endif
}
/*
** Output the given string as a quoted string using SQL quoting conventions.
** Additionallly , escape the "\n" and "\r" characters so that they do not
** get corrupted by end-of-line translation facilities in some operating
** systems.
**
** This is like output_quoted_string() but with the addition of the \r\n
** escape mechanism.
*/
static void output_quoted_escaped_string(const char *z){
int i;
char c;
#ifndef SQLITE_SHELL_FIDDLE
FILE *pfO = setOutputStream(invalidFileStream);
setBinaryMode(pfO, 1);
#endif
for(i=0; (c = z[i])!=0 && c!='\'' && c!='\n' && c!='\r'; i++){}
if( c==0 ){
oputf("'%s'",z);
}else{
const char *zNL = 0;
const char *zCR = 0;
int nNL = 0;
int nCR = 0;
char zBuf1[20], zBuf2[20];
for(i=0; z[i]; i++){
if( z[i]=='\n' ) nNL++;
if( z[i]=='\r' ) nCR++;
}
if( nNL ){
oputz("replace(");
zNL = unused_string(z, "\\n", "\\012", zBuf1);
}
if( nCR ){
oputz("replace(");
zCR = unused_string(z, "\\r", "\\015", zBuf2);
}
oputz("'");
while( *z ){
for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
if( c=='\'' ) i++;
if( i ){
oputf("%.*s", i, z);
z += i;
}
if( c=='\'' ){
oputz("'");
continue;
}
if( c==0 ){
break;
}
z++;
if( c=='\n' ){
oputz(zNL);
continue;
}
oputz(zCR);
}
oputz("'");
if( nCR ){
oputf(",'%s',char(13))", zCR);
}
if( nNL ){
oputf(",'%s',char(10))", zNL);
}
}
#ifndef SQLITE_SHELL_FIDDLE
setTextMode(pfO, 1);
#else
setTextMode(stdout, 1);
#endif
}
/*
** Find earliest of chars within s specified in zAny.
** With ns == ~0, is like strpbrk(s,zAny) and s must be 0-terminated.
*/
static const char *anyOfInStr(const char *s, const char *zAny, size_t ns){
const char *pcFirst = 0;
if( ns == ~(size_t)0 ) ns = strlen(s);
while(*zAny){
const char *pc = (const char*)memchr(s, *zAny&0xff, ns);
if( pc ){
pcFirst = pc;
ns = pcFirst - s;
}
++zAny;
}
return pcFirst;
}
/*
** Output the given string as a quoted according to C or TCL quoting rules.
*/
static void output_c_string(const char *z){
char c;
static const char *zq = "\"";
static long ctrlMask = ~0L;
static const char *zDQBSRO = "\"\\\x7f"; /* double-quote, backslash, rubout */
char ace[3] = "\\?";
char cbsSay;
oputz(zq);
while( *z!=0 ){
const char *pcDQBSRO = anyOfInStr(z, zDQBSRO, ~(size_t)0);
const char *pcPast = zSkipValidUtf8(z, INT_MAX, ctrlMask);
const char *pcEnd = (pcDQBSRO && pcDQBSRO < pcPast)? pcDQBSRO : pcPast;
if( pcEnd > z ) oputb(z, (int)(pcEnd-z));
if( (c = *pcEnd)==0 ) break;
++pcEnd;
switch( c ){
case '\\': case '"':
cbsSay = (char)c;
break;
case '\t': cbsSay = 't'; break;
case '\n': cbsSay = 'n'; break;
case '\r': cbsSay = 'r'; break;
case '\f': cbsSay = 'f'; break;
default: cbsSay = 0; break;
}
if( cbsSay ){
ace[1] = cbsSay;
oputz(ace);
}else if( !isprint(c&0xff) ){
oputf("\\%03o", c&0xff);
}else{
ace[1] = (char)c;
oputz(ace+1);
}
z = pcEnd;
}
oputz(zq);
}
/*
** Output the given string as a quoted according to JSON quoting rules.
*/
static void output_json_string(const char *z, i64 n){
char c;
static const char *zq = "\"";
static long ctrlMask = ~0L;
static const char *zDQBS = "\"\\";
const char *pcLimit;
char ace[3] = "\\?";
char cbsSay;
if( z==0 ) z = "";
pcLimit = z + ((n<0)? strlen(z) : (size_t)n);
oputz(zq);
while( z < pcLimit ){
const char *pcDQBS = anyOfInStr(z, zDQBS, pcLimit-z);
const char *pcPast = zSkipValidUtf8(z, (int)(pcLimit-z), ctrlMask);
const char *pcEnd = (pcDQBS && pcDQBS < pcPast)? pcDQBS : pcPast;
if( pcEnd > z ){
oputb(z, (int)(pcEnd-z));
z = pcEnd;
}
if( z >= pcLimit ) break;
c = *(z++);
switch( c ){
case '"': case '\\':
cbsSay = (char)c;
break;
case '\b': cbsSay = 'b'; break;
case '\f': cbsSay = 'f'; break;
case '\n': cbsSay = 'n'; break;
case '\r': cbsSay = 'r'; break;
case '\t': cbsSay = 't'; break;
default: cbsSay = 0; break;
}
if( cbsSay ){
ace[1] = cbsSay;
oputz(ace);
}else if( c<=0x1f ){
oputf("u%04x", c);
}else{
ace[1] = (char)c;
oputz(ace+1);
}
}
oputz(zq);
}
/*
** Output the given string with characters that are special to
** HTML escaped.
*/
static void output_html_string(const char *z){
int i;
if( z==0 ) z = "";
while( *z ){
for(i=0; z[i]
&& z[i]!='<'
&& z[i]!='&'
&& z[i]!='>'
&& z[i]!='\"'
&& z[i]!='\'';
i++){}
if( i>0 ){
oputf("%.*s",i,z);
}
if( z[i]=='<' ){
oputz("<");
}else if( z[i]=='&' ){
oputz("&");
}else if( z[i]=='>' ){
oputz(">");
}else if( z[i]=='\"' ){
oputz(""");
}else if( z[i]=='\'' ){
oputz("'");
}else{
break;
}
z += i + 1;
}
}
|
| ︙ | ︙ | |||
18093 18094 18095 18096 18097 18098 18099 |
/*
** Output a single term of CSV. Actually, p->colSeparator is used for
** the separator, which may or may not be a comma. p->nullValue is
** the null value. Strings are quoted if necessary. The separator
** is only issued if bSep is true.
*/
static void output_csv(ShellState *p, const char *z, int bSep){
| < | | | | | 18868 18869 18870 18871 18872 18873 18874 18875 18876 18877 18878 18879 18880 18881 18882 18883 18884 18885 18886 18887 18888 18889 18890 18891 18892 18893 18894 18895 18896 18897 18898 18899 18900 18901 18902 |
/*
** Output a single term of CSV. Actually, p->colSeparator is used for
** the separator, which may or may not be a comma. p->nullValue is
** the null value. Strings are quoted if necessary. The separator
** is only issued if bSep is true.
*/
static void output_csv(ShellState *p, const char *z, int bSep){
if( z==0 ){
oputf("%s",p->nullValue);
}else{
unsigned i;
for(i=0; z[i]; i++){
if( needCsvQuote[((unsigned char*)z)[i]] ){
i = 0;
break;
}
}
if( i==0 || strstr(z, p->colSeparator)!=0 ){
char *zQuoted = sqlite3_mprintf("\"%w\"", z);
shell_check_oom(zQuoted);
oputz(zQuoted);
sqlite3_free(zQuoted);
}else{
oputz(z);
}
}
if( bSep ){
oputz(p->colSeparator);
}
}
/*
** This routine runs when the user presses Ctrl-C
*/
static void interrupt_handler(int NotUsed){
|
| ︙ | ︙ | |||
18222 18223 18224 18225 18226 18227 18228 | }; int i; const char *az[4]; az[0] = zA1; az[1] = zA2; az[2] = zA3; az[3] = zA4; | | | | | | | | 18996 18997 18998 18999 19000 19001 19002 19003 19004 19005 19006 19007 19008 19009 19010 19011 19012 19013 19014 19015 19016 19017 19018 19019 19020 19021 19022 19023 19024 19025 19026 19027 19028 19029 19030 19031 19032 19033 19034 19035 |
};
int i;
const char *az[4];
az[0] = zA1;
az[1] = zA2;
az[2] = zA3;
az[3] = zA4;
oputf("authorizer: %s", azAction[op]);
for(i=0; i<4; i++){
oputz(" ");
if( az[i] ){
output_c_string(az[i]);
}else{
oputz("NULL");
}
}
oputz("\n");
if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4);
return SQLITE_OK;
}
#endif
/*
** Print a schema statement. Part of MODE_Semi and MODE_Pretty output.
**
** This routine converts some CREATE TABLE statements for shadow tables
** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements.
**
** If the schema statement in z[] contains a start-of-comment and if
** sqlite3_complete() returns false, try to terminate the comment before
** printing the result. https://sqlite.org/forum/forumpost/d7be961c5c
*/
static void printSchemaLine(const char *z, const char *zTail){
char *zToFree = 0;
if( z==0 ) return;
if( zTail==0 ) return;
if( zTail[0]==';' && (strstr(z, "/*")!=0 || strstr(z,"--")!=0) ){
const char *zOrig = z;
static const char *azTerm[] = { "", "*/", "\n" };
int i;
|
| ︙ | ︙ | |||
18269 18270 18271 18272 18273 18274 18275 |
z = zNew;
break;
}
sqlite3_free(zNew);
}
}
if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
| | | | | | 19043 19044 19045 19046 19047 19048 19049 19050 19051 19052 19053 19054 19055 19056 19057 19058 19059 19060 19061 19062 19063 19064 19065 19066 |
z = zNew;
break;
}
sqlite3_free(zNew);
}
}
if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){
oputf("CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail);
}else{
oputf("%s%s", z, zTail);
}
sqlite3_free(zToFree);
}
static void printSchemaLineN(char *z, int n, const char *zTail){
char c = z[n];
z[n] = 0;
printSchemaLine(z, zTail);
z[n] = c;
}
/*
** Return true if string z[] has nothing but whitespace and comments to the
** end of the first line.
*/
|
| ︙ | ︙ | |||
18306 18307 18308 18309 18310 18311 18312 |
*/
static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
EQPGraphRow *pNew;
i64 nText;
if( zText==0 ) return;
nText = strlen(zText);
if( p->autoEQPtest ){
| | | 19080 19081 19082 19083 19084 19085 19086 19087 19088 19089 19090 19091 19092 19093 19094 |
*/
static void eqp_append(ShellState *p, int iEqpId, int p2, const char *zText){
EQPGraphRow *pNew;
i64 nText;
if( zText==0 ) return;
nText = strlen(zText);
if( p->autoEQPtest ){
oputf("%d,%d,%s\n", iEqpId, p2, zText);
}
pNew = sqlite3_malloc64( sizeof(*pNew) + nText );
shell_check_oom(pNew);
pNew->iEqpId = iEqpId;
pNew->iParentId = p2;
memcpy(pNew->zText, zText, nText+1);
pNew->pNext = 0;
|
| ︙ | ︙ | |||
18354 18355 18356 18357 18358 18359 18360 |
static void eqp_render_level(ShellState *p, int iEqpId){
EQPGraphRow *pRow, *pNext;
i64 n = strlen(p->sGraph.zPrefix);
char *z;
for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
pNext = eqp_next_row(p, iEqpId, pRow);
z = pRow->zText;
| < | | | | | | | | | | | | | | | | 19128 19129 19130 19131 19132 19133 19134 19135 19136 19137 19138 19139 19140 19141 19142 19143 19144 19145 19146 19147 19148 19149 19150 19151 19152 19153 19154 19155 19156 19157 19158 19159 19160 19161 19162 19163 19164 19165 19166 19167 19168 19169 19170 19171 19172 19173 19174 19175 19176 19177 19178 19179 19180 19181 19182 19183 19184 19185 19186 19187 19188 19189 19190 19191 19192 19193 19194 19195 19196 19197 19198 19199 19200 19201 19202 19203 19204 19205 19206 19207 19208 19209 19210 19211 19212 19213 19214 19215 19216 19217 19218 19219 19220 19221 19222 19223 19224 19225 19226 19227 |
static void eqp_render_level(ShellState *p, int iEqpId){
EQPGraphRow *pRow, *pNext;
i64 n = strlen(p->sGraph.zPrefix);
char *z;
for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
pNext = eqp_next_row(p, iEqpId, pRow);
z = pRow->zText;
oputf("%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z);
if( n<(i64)sizeof(p->sGraph.zPrefix)-7 ){
memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4);
eqp_render_level(p, pRow->iEqpId);
p->sGraph.zPrefix[n] = 0;
}
}
}
/*
** Display and reset the EXPLAIN QUERY PLAN data
*/
static void eqp_render(ShellState *p, i64 nCycle){
EQPGraphRow *pRow = p->sGraph.pRow;
if( pRow ){
if( pRow->zText[0]=='-' ){
if( pRow->pNext==0 ){
eqp_reset(p);
return;
}
oputf("%s\n", pRow->zText+3);
p->sGraph.pRow = pRow->pNext;
sqlite3_free(pRow);
}else if( nCycle>0 ){
oputf("QUERY PLAN (cycles=%lld [100%%])\n", nCycle);
}else{
oputz("QUERY PLAN\n");
}
p->sGraph.zPrefix[0] = 0;
eqp_render_level(p, 0);
eqp_reset(p);
}
}
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/*
** Progress handler callback.
*/
static int progress_handler(void *pClientData) {
ShellState *p = (ShellState*)pClientData;
p->nProgress++;
if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
oputf("Progress limit reached (%u)\n", p->nProgress);
if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0;
return 1;
}
if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
oputf("Progress %u\n", p->nProgress);
}
return 0;
}
#endif /* SQLITE_OMIT_PROGRESS_CALLBACK */
/*
** Print N dashes
*/
static void print_dashes(int N){
const char zDash[] = "--------------------------------------------------";
const int nDash = sizeof(zDash) - 1;
while( N>nDash ){
oputz(zDash);
N -= nDash;
}
oputf("%.*s", N, zDash);
}
/*
** Print a markdown or table-style row separator using ascii-art
*/
static void print_row_separator(
ShellState *p,
int nArg,
const char *zSep
){
int i;
if( nArg>0 ){
oputz(zSep);
print_dashes(p->actualWidth[0]+2);
for(i=1; i<nArg; i++){
oputz(zSep);
print_dashes(p->actualWidth[i]+2);
}
oputz(zSep);
}
oputz("\n");
}
/*
** This is the callback routine that the shell
** invokes for each row of a query result.
*/
static int shell_callback(
|
| ︙ | ︙ | |||
18470 18471 18472 18473 18474 18475 18476 |
case MODE_Line: {
int w = 5;
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
int len = strlen30(azCol[i] ? azCol[i] : "");
if( len>w ) w = len;
}
| | | | | 19243 19244 19245 19246 19247 19248 19249 19250 19251 19252 19253 19254 19255 19256 19257 19258 19259 19260 |
case MODE_Line: {
int w = 5;
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
int len = strlen30(azCol[i] ? azCol[i] : "");
if( len>w ) w = len;
}
if( p->cnt++>0 ) oputz(p->rowSeparator);
for(i=0; i<nArg; i++){
oputf("%*s = %s%s", w, azCol[i],
azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
}
break;
}
case MODE_ScanExp:
case MODE_Explain: {
static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13};
static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 };
|
| ︙ | ︙ | |||
18500 18501 18502 18503 18504 18505 18506 |
iIndent = 3;
}
if( nArg>nWidth ) nArg = nWidth;
/* If this is the first row seen, print out the headers */
if( p->cnt++==0 ){
for(i=0; i<nArg; i++){
| | | | | | | | | | | 19273 19274 19275 19276 19277 19278 19279 19280 19281 19282 19283 19284 19285 19286 19287 19288 19289 19290 19291 19292 19293 19294 19295 19296 19297 19298 19299 19300 19301 19302 19303 19304 19305 19306 19307 19308 19309 19310 19311 19312 19313 19314 19315 19316 19317 19318 19319 19320 19321 19322 19323 19324 19325 19326 19327 19328 19329 19330 19331 19332 19333 19334 19335 |
iIndent = 3;
}
if( nArg>nWidth ) nArg = nWidth;
/* If this is the first row seen, print out the headers */
if( p->cnt++==0 ){
for(i=0; i<nArg; i++){
utf8_width_print(aWidth[i], azCol[ aMap[i] ]);
oputz(i==nArg-1 ? "\n" : " ");
}
for(i=0; i<nArg; i++){
print_dashes(aWidth[i]);
oputz(i==nArg-1 ? "\n" : " ");
}
}
/* If there is no data, exit early. */
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
const char *zSep = " ";
int w = aWidth[i];
const char *zVal = azArg[ aMap[i] ];
if( i==nArg-1 ) w = 0;
if( zVal && strlenChar(zVal)>w ){
w = strlenChar(zVal);
zSep = " ";
}
if( i==iIndent && p->aiIndent && p->pStmt ){
if( p->iIndent<p->nIndent ){
oputf("%*.s", p->aiIndent[p->iIndent], "");
}
p->iIndent++;
}
utf8_width_print(w, zVal ? zVal : p->nullValue);
oputz(i==nArg-1 ? "\n" : zSep);
}
break;
}
case MODE_Semi: { /* .schema and .fullschema output */
printSchemaLine(azArg[0], ";\n");
break;
}
case MODE_Pretty: { /* .schema and .fullschema with --indent */
char *z;
int j;
int nParen = 0;
char cEnd = 0;
char c;
int nLine = 0;
assert( nArg==1 );
if( azArg[0]==0 ) break;
if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
|| sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
){
oputf("%s;\n", azArg[0]);
break;
}
z = sqlite3_mprintf("%s", azArg[0]);
shell_check_oom(z);
j = 0;
for(i=0; IsSpace(z[i]); i++){}
for(; (c = z[i])!=0; i++){
|
| ︙ | ︙ | |||
18581 18582 18583 18584 18585 18586 18587 |
}else if( c=='-' && z[i+1]=='-' ){
cEnd = '\n';
}else if( c=='(' ){
nParen++;
}else if( c==')' ){
nParen--;
if( nLine>0 && nParen==0 && j>0 ){
| | | | < | | < | < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 19354 19355 19356 19357 19358 19359 19360 19361 19362 19363 19364 19365 19366 19367 19368 19369 19370 19371 19372 19373 19374 19375 19376 19377 19378 19379 19380 19381 19382 19383 19384 19385 19386 19387 19388 19389 19390 19391 19392 19393 19394 19395 19396 19397 19398 19399 19400 19401 19402 19403 19404 19405 19406 19407 19408 19409 19410 19411 19412 19413 19414 19415 19416 19417 19418 19419 19420 19421 19422 19423 19424 19425 19426 19427 19428 19429 19430 19431 19432 19433 19434 19435 19436 19437 19438 19439 19440 19441 19442 19443 19444 19445 19446 19447 19448 19449 19450 19451 19452 19453 19454 19455 19456 19457 19458 19459 19460 19461 19462 19463 19464 19465 19466 19467 19468 19469 19470 19471 19472 19473 19474 19475 19476 19477 19478 19479 19480 19481 19482 19483 19484 19485 19486 19487 19488 19489 19490 19491 19492 19493 19494 19495 19496 19497 19498 19499 19500 19501 19502 19503 19504 19505 19506 19507 19508 19509 19510 19511 19512 19513 19514 19515 19516 19517 19518 19519 19520 19521 19522 19523 19524 19525 19526 19527 19528 19529 19530 19531 19532 19533 19534 19535 19536 19537 19538 19539 19540 19541 19542 19543 19544 19545 19546 19547 19548 19549 19550 19551 19552 19553 19554 19555 19556 19557 19558 19559 19560 19561 19562 19563 19564 19565 19566 19567 19568 19569 19570 19571 19572 19573 19574 19575 19576 19577 19578 19579 19580 19581 19582 19583 19584 19585 19586 19587 19588 19589 19590 19591 19592 19593 19594 19595 19596 19597 19598 19599 19600 19601 19602 19603 19604 19605 19606 19607 19608 19609 19610 19611 19612 |
}else if( c=='-' && z[i+1]=='-' ){
cEnd = '\n';
}else if( c=='(' ){
nParen++;
}else if( c==')' ){
nParen--;
if( nLine>0 && nParen==0 && j>0 ){
printSchemaLineN(z, j, "\n");
j = 0;
}
}
z[j++] = c;
if( nParen==1 && cEnd==0
&& (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
){
if( c=='\n' ) j--;
printSchemaLineN(z, j, "\n ");
j = 0;
nLine++;
while( IsSpace(z[i+1]) ){ i++; }
}
}
z[j] = 0;
}
printSchemaLine(z, ";\n");
sqlite3_free(z);
break;
}
case MODE_List: {
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
oputf("%s%s",azCol[i], i==nArg-1 ? p->rowSeparator : p->colSeparator);
}
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
char *z = azArg[i];
if( z==0 ) z = p->nullValue;
oputz(z);
oputz((i<nArg-1)? p->colSeparator : p->rowSeparator);
}
break;
}
case MODE_Html: {
if( p->cnt++==0 && p->showHeader ){
oputz("<TR>");
for(i=0; i<nArg; i++){
oputz("<TH>");
output_html_string(azCol[i]);
oputz("</TH>\n");
}
oputz("</TR>\n");
}
if( azArg==0 ) break;
oputz("<TR>");
for(i=0; i<nArg; i++){
oputz("<TD>");
output_html_string(azArg[i] ? azArg[i] : p->nullValue);
oputz("</TD>\n");
}
oputz("</TR>\n");
break;
}
case MODE_Tcl: {
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
output_c_string(azCol[i] ? azCol[i] : "");
if(i<nArg-1) oputz(p->colSeparator);
}
oputz(p->rowSeparator);
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
output_c_string(azArg[i] ? azArg[i] : p->nullValue);
if(i<nArg-1) oputz(p->colSeparator);
}
oputz(p->rowSeparator);
break;
}
case MODE_Csv: {
setBinaryMode(p->out, 1);
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
}
oputz(p->rowSeparator);
}
if( nArg>0 ){
for(i=0; i<nArg; i++){
output_csv(p, azArg[i], i<nArg-1);
}
oputz(p->rowSeparator);
}
setTextMode(p->out, 1);
break;
}
case MODE_Insert: {
if( azArg==0 ) break;
oputf("INSERT INTO %s",p->zDestTable);
if( p->showHeader ){
oputz("(");
for(i=0; i<nArg; i++){
if( i>0 ) oputz(",");
if( quoteChar(azCol[i]) ){
char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
shell_check_oom(z);
oputz(z);
sqlite3_free(z);
}else{
oputf("%s", azCol[i]);
}
}
oputz(")");
}
p->cnt++;
for(i=0; i<nArg; i++){
oputz(i>0 ? "," : " VALUES(");
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
oputz("NULL");
}else if( aiType && aiType[i]==SQLITE_TEXT ){
if( ShellHasFlag(p, SHFLG_Newlines) ){
output_quoted_string(azArg[i]);
}else{
output_quoted_escaped_string(azArg[i]);
}
}else if( aiType && aiType[i]==SQLITE_INTEGER ){
oputz(azArg[i]);
}else if( aiType && aiType[i]==SQLITE_FLOAT ){
char z[50];
double r = sqlite3_column_double(p->pStmt, i);
sqlite3_uint64 ur;
memcpy(&ur,&r,sizeof(r));
if( ur==0x7ff0000000000000LL ){
oputz("9.0e+999");
}else if( ur==0xfff0000000000000LL ){
oputz("-9.0e+999");
}else{
sqlite3_int64 ir = (sqlite3_int64)r;
if( r==(double)ir ){
sqlite3_snprintf(50,z,"%lld.0", ir);
}else{
sqlite3_snprintf(50,z,"%!.20g", r);
}
oputz(z);
}
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
int nBlob = sqlite3_column_bytes(p->pStmt, i);
output_hex_blob(pBlob, nBlob);
}else if( isNumber(azArg[i], 0) ){
oputz(azArg[i]);
}else if( ShellHasFlag(p, SHFLG_Newlines) ){
output_quoted_string(azArg[i]);
}else{
output_quoted_escaped_string(azArg[i]);
}
}
oputz(");\n");
break;
}
case MODE_Json: {
if( azArg==0 ) break;
if( p->cnt==0 ){
fputs("[{", p->out);
}else{
fputs(",\n{", p->out);
}
p->cnt++;
for(i=0; i<nArg; i++){
output_json_string(azCol[i], -1);
oputz(":");
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
oputz("null");
}else if( aiType && aiType[i]==SQLITE_FLOAT ){
char z[50];
double r = sqlite3_column_double(p->pStmt, i);
sqlite3_uint64 ur;
memcpy(&ur,&r,sizeof(r));
if( ur==0x7ff0000000000000LL ){
oputz("9.0e+999");
}else if( ur==0xfff0000000000000LL ){
oputz("-9.0e+999");
}else{
sqlite3_snprintf(50,z,"%!.20g", r);
oputz(z);
}
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
int nBlob = sqlite3_column_bytes(p->pStmt, i);
output_json_string(pBlob, nBlob);
}else if( aiType && aiType[i]==SQLITE_TEXT ){
output_json_string(azArg[i], -1);
}else{
oputz(azArg[i]);
}
if( i<nArg-1 ){
oputz(",");
}
}
oputz("}");
break;
}
case MODE_Quote: {
if( azArg==0 ) break;
if( p->cnt==0 && p->showHeader ){
for(i=0; i<nArg; i++){
if( i>0 ) fputs(p->colSeparator, p->out);
output_quoted_string(azCol[i]);
}
fputs(p->rowSeparator, p->out);
}
p->cnt++;
for(i=0; i<nArg; i++){
if( i>0 ) fputs(p->colSeparator, p->out);
if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
oputz("NULL");
}else if( aiType && aiType[i]==SQLITE_TEXT ){
output_quoted_string(azArg[i]);
}else if( aiType && aiType[i]==SQLITE_INTEGER ){
oputz(azArg[i]);
}else if( aiType && aiType[i]==SQLITE_FLOAT ){
char z[50];
double r = sqlite3_column_double(p->pStmt, i);
sqlite3_snprintf(50,z,"%!.20g", r);
oputz(z);
}else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
const void *pBlob = sqlite3_column_blob(p->pStmt, i);
int nBlob = sqlite3_column_bytes(p->pStmt, i);
output_hex_blob(pBlob, nBlob);
}else if( isNumber(azArg[i], 0) ){
oputz(azArg[i]);
}else{
output_quoted_string(azArg[i]);
}
}
fputs(p->rowSeparator, p->out);
break;
}
case MODE_Ascii: {
if( p->cnt++==0 && p->showHeader ){
for(i=0; i<nArg; i++){
if( i>0 ) oputz(p->colSeparator);
oputz(azCol[i] ? azCol[i] : "");
}
oputz(p->rowSeparator);
}
if( azArg==0 ) break;
for(i=0; i<nArg; i++){
if( i>0 ) oputz(p->colSeparator);
oputz(azArg[i] ? azArg[i] : p->nullValue);
}
oputz(p->rowSeparator);
break;
}
case MODE_EQP: {
eqp_append(p, atoi(azArg[0]), atoi(azArg[1]), azArg[3]);
break;
}
}
|
| ︙ | ︙ | |||
18909 18910 18911 18912 18913 18914 18915 |
"INSERT INTO [_shell$self]\n"
" VALUES('run','PRAGMA integrity_check','ok');\n"
"INSERT INTO selftest(tno,op,cmd,ans)"
" SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
"DROP TABLE [_shell$self];"
,0,0,&zErrMsg);
if( zErrMsg ){
| | | 19677 19678 19679 19680 19681 19682 19683 19684 19685 19686 19687 19688 19689 19690 19691 |
"INSERT INTO [_shell$self]\n"
" VALUES('run','PRAGMA integrity_check','ok');\n"
"INSERT INTO selftest(tno,op,cmd,ans)"
" SELECT rowid*10,op,cmd,ans FROM [_shell$self];\n"
"DROP TABLE [_shell$self];"
,0,0,&zErrMsg);
if( zErrMsg ){
eputf("SELFTEST initialization failure: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
sqlite3_exec(p->db, "RELEASE selftest_init",0,0,0);
}
/*
|
| ︙ | ︙ | |||
19012 19013 19014 19015 19016 19017 19018 |
int rc;
int nResult;
int i;
const char *z;
rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
if( rc!=SQLITE_OK || !pSelect ){
char *zContext = shell_error_context(zSelect, p->db);
| | | | | | | | < | 19780 19781 19782 19783 19784 19785 19786 19787 19788 19789 19790 19791 19792 19793 19794 19795 19796 19797 19798 19799 19800 19801 19802 19803 19804 19805 19806 19807 19808 19809 19810 19811 19812 19813 19814 19815 19816 19817 19818 19819 |
int rc;
int nResult;
int i;
const char *z;
rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
if( rc!=SQLITE_OK || !pSelect ){
char *zContext = shell_error_context(zSelect, p->db);
oputf("/**** ERROR: (%d) %s *****/\n%s",
rc, sqlite3_errmsg(p->db), zContext);
sqlite3_free(zContext);
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
return rc;
}
rc = sqlite3_step(pSelect);
nResult = sqlite3_column_count(pSelect);
while( rc==SQLITE_ROW ){
z = (const char*)sqlite3_column_text(pSelect, 0);
oputf("%s", z);
for(i=1; i<nResult; i++){
oputf(",%s", sqlite3_column_text(pSelect, i));
}
if( z==0 ) z = "";
while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
if( z[0] ){
oputz("\n;\n");
}else{
oputz(";\n");
}
rc = sqlite3_step(pSelect);
}
rc = sqlite3_finalize(pSelect);
if( rc!=SQLITE_OK ){
oputf("/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
}
return rc;
}
/*
** Allocate space and save off string indicating current error.
|
| ︙ | ︙ | |||
19074 19075 19076 19077 19078 19079 19080 | return zErr; } #ifdef __linux__ /* ** Attempt to display I/O stats on Linux using /proc/PID/io */ | | | 19841 19842 19843 19844 19845 19846 19847 19848 19849 19850 19851 19852 19853 19854 19855 |
return zErr;
}
#ifdef __linux__
/*
** Attempt to display I/O stats on Linux using /proc/PID/io
*/
static void displayLinuxIoStats(void){
FILE *in;
char z[200];
sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
in = fopen(z, "rb");
if( in==0 ) return;
while( fgets(z, sizeof(z), in)!=0 ){
static const struct {
|
| ︙ | ︙ | |||
19097 19098 19099 19100 19101 19102 19103 |
{ "write_bytes: ", "Bytes written to storage:" },
{ "cancelled_write_bytes: ", "Cancelled write bytes:" },
};
int i;
for(i=0; i<ArraySize(aTrans); i++){
int n = strlen30(aTrans[i].zPattern);
if( cli_strncmp(aTrans[i].zPattern, z, n)==0 ){
| | < | < < | | | | | | | | | | | | | | < | < | < | < | < | < | | | | | < | < | | | | < | | | | | | 19864 19865 19866 19867 19868 19869 19870 19871 19872 19873 19874 19875 19876 19877 19878 19879 19880 19881 19882 19883 19884 19885 19886 19887 19888 19889 19890 19891 19892 19893 19894 19895 19896 19897 19898 19899 19900 19901 19902 19903 19904 19905 19906 19907 19908 19909 19910 19911 19912 19913 19914 19915 19916 19917 19918 19919 19920 19921 19922 19923 19924 19925 19926 19927 19928 19929 19930 19931 19932 19933 19934 19935 19936 19937 19938 19939 19940 19941 19942 19943 19944 19945 19946 19947 19948 19949 19950 19951 19952 19953 19954 19955 19956 19957 19958 19959 19960 19961 19962 19963 19964 19965 19966 19967 19968 19969 19970 19971 19972 19973 19974 19975 19976 19977 19978 19979 19980 19981 19982 19983 19984 19985 19986 19987 19988 19989 19990 19991 19992 19993 19994 19995 19996 19997 19998 19999 20000 20001 20002 20003 20004 20005 20006 20007 20008 20009 20010 20011 20012 20013 20014 20015 20016 20017 20018 20019 20020 20021 20022 20023 20024 20025 20026 20027 20028 20029 20030 20031 20032 20033 20034 20035 20036 20037 20038 20039 20040 20041 |
{ "write_bytes: ", "Bytes written to storage:" },
{ "cancelled_write_bytes: ", "Cancelled write bytes:" },
};
int i;
for(i=0; i<ArraySize(aTrans); i++){
int n = strlen30(aTrans[i].zPattern);
if( cli_strncmp(aTrans[i].zPattern, z, n)==0 ){
oputf("%-36s %s", aTrans[i].zDesc, &z[n]);
break;
}
}
}
fclose(in);
}
#endif
/*
** Display a single line of status using 64-bit values.
*/
static void displayStatLine(
char *zLabel, /* Label for this one line */
char *zFormat, /* Format for the result */
int iStatusCtrl, /* Which status to display */
int bReset /* True to reset the stats */
){
sqlite3_int64 iCur = -1;
sqlite3_int64 iHiwtr = -1;
int i, nPercent;
char zLine[200];
sqlite3_status64(iStatusCtrl, &iCur, &iHiwtr, bReset);
for(i=0, nPercent=0; zFormat[i]; i++){
if( zFormat[i]=='%' ) nPercent++;
}
if( nPercent>1 ){
sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iCur, iHiwtr);
}else{
sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
}
oputf("%-36s %s\n", zLabel, zLine);
}
/*
** Display memory stats.
*/
static int display_stats(
sqlite3 *db, /* Database to query */
ShellState *pArg, /* Pointer to ShellState */
int bReset /* True to reset the stats */
){
int iCur;
int iHiwtr;
if( pArg==0 || pArg->out==0 ) return 0;
if( pArg->pStmt && pArg->statsOn==2 ){
int nCol, i, x;
sqlite3_stmt *pStmt = pArg->pStmt;
char z[100];
nCol = sqlite3_column_count(pStmt);
oputf("%-36s %d\n", "Number of output columns:", nCol);
for(i=0; i<nCol; i++){
sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
oputf("%-36s %s\n", z, sqlite3_column_name(pStmt,i));
#ifndef SQLITE_OMIT_DECLTYPE
sqlite3_snprintf(30, z+x, "declared type:");
oputf("%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
#endif
#ifdef SQLITE_ENABLE_COLUMN_METADATA
sqlite3_snprintf(30, z+x, "database name:");
oputf("%-36s %s\n", z, sqlite3_column_database_name(pStmt,i));
sqlite3_snprintf(30, z+x, "table name:");
oputf("%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
sqlite3_snprintf(30, z+x, "origin name:");
oputf("%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
#endif
}
}
if( pArg->statsOn==3 ){
if( pArg->pStmt ){
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset);
oputf("VM-steps: %d\n", iCur);
}
return 0;
}
displayStatLine("Memory Used:",
"%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
displayStatLine("Number of Outstanding Allocations:",
"%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset);
if( pArg->shellFlgs & SHFLG_Pagecache ){
displayStatLine("Number of Pcache Pages Used:",
"%lld (max %lld) pages", SQLITE_STATUS_PAGECACHE_USED, bReset);
}
displayStatLine("Number of Pcache Overflow Bytes:",
"%lld (max %lld) bytes", SQLITE_STATUS_PAGECACHE_OVERFLOW, bReset);
displayStatLine("Largest Allocation:",
"%lld bytes", SQLITE_STATUS_MALLOC_SIZE, bReset);
displayStatLine("Largest Pcache Allocation:",
"%lld bytes", SQLITE_STATUS_PAGECACHE_SIZE, bReset);
#ifdef YYTRACKMAXSTACKDEPTH
displayStatLine("Deepest Parser Stack:",
"%lld (max %lld)", SQLITE_STATUS_PARSER_STACK, bReset);
#endif
if( db ){
if( pArg->shellFlgs & SHFLG_Lookaside ){
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
&iCur, &iHiwtr, bReset);
oputf("Lookaside Slots Used: %d (max %d)\n", iCur, iHiwtr);
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
&iCur, &iHiwtr, bReset);
oputf("Successful lookaside attempts: %d\n", iHiwtr);
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
&iCur, &iHiwtr, bReset);
oputf("Lookaside failures due to size: %d\n", iHiwtr);
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
&iCur, &iHiwtr, bReset);
oputf("Lookaside failures due to OOM: %d\n", iHiwtr);
}
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
oputf("Pager Heap Usage: %d bytes\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
oputf("Page cache hits: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
oputf("Page cache misses: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
oputf("Page cache writes: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
oputf("Page cache spills: %d\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
oputf("Schema Heap Usage: %d bytes\n", iCur);
iHiwtr = iCur = -1;
sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
oputf("Statement Heap/Lookaside Usage: %d bytes\n", iCur);
}
if( pArg->pStmt ){
int iHit, iMiss;
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
bReset);
oputf("Fullscan Steps: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
oputf("Sort Operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
oputf("Autoindex Inserts: %d\n", iCur);
iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT,
bReset);
iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS,
bReset);
if( iHit || iMiss ){
oputf("Bloom filter bypass taken: %d/%d\n", iHit, iHit+iMiss);
}
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
oputf("Virtual Machine Steps: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
oputf("Reprepare operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
oputf("Number of times run: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
oputf("Memory used by prepared stmt: %d\n", iCur);
}
#ifdef __linux__
displayLinuxIoStats();
#endif
/* Do not remove this machine readable comment: extra-stats-output-here */
return 0;
}
|
| ︙ | ︙ | |||
19507 19508 19509 19510 19511 19512 19513 |
ShellState *pArg /* Pointer to ShellState */
){
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(pArg);
#else
if( pArg->scanstatsOn==3 ){
| | | 20262 20263 20264 20265 20266 20267 20268 20269 20270 20271 20272 20273 20274 20275 20276 |
ShellState *pArg /* Pointer to ShellState */
){
#ifndef SQLITE_ENABLE_STMT_SCANSTATUS
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(pArg);
#else
if( pArg->scanstatsOn==3 ){
const char *zSql =
" SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec,"
" round(ncycle*100.0 / (sum(ncycle) OVER ()), 2)||'%' AS cycles"
" FROM bytecode(?)";
int rc = SQLITE_OK;
sqlite3_stmt *pStmt = 0;
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
| ︙ | ︙ | |||
19653 19654 19655 19656 19657 19658 19659 | #define BOX_234 "\342\224\254" /* U+252c -,- */ #define BOX_124 "\342\224\264" /* U+2534 -'- */ #define BOX_1234 "\342\224\274" /* U+253c -|- */ /* Draw horizontal line N characters long using unicode box ** characters */ | | | | | | | | | | | 20408 20409 20410 20411 20412 20413 20414 20415 20416 20417 20418 20419 20420 20421 20422 20423 20424 20425 20426 20427 20428 20429 20430 20431 20432 20433 20434 20435 20436 20437 20438 20439 20440 20441 20442 20443 20444 20445 20446 20447 20448 20449 20450 20451 20452 20453 20454 20455 |
#define BOX_234 "\342\224\254" /* U+252c -,- */
#define BOX_124 "\342\224\264" /* U+2534 -'- */
#define BOX_1234 "\342\224\274" /* U+253c -|- */
/* Draw horizontal line N characters long using unicode box
** characters
*/
static void print_box_line(int N){
const char zDash[] =
BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24
BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24 BOX_24;
const int nDash = sizeof(zDash) - 1;
N *= 3;
while( N>nDash ){
oputz(zDash);
N -= nDash;
}
oputf("%.*s", N, zDash);
}
/*
** Draw a horizontal separator for a MODE_Box table.
*/
static void print_box_row_separator(
ShellState *p,
int nArg,
const char *zSep1,
const char *zSep2,
const char *zSep3
){
int i;
if( nArg>0 ){
oputz(zSep1);
print_box_line(p->actualWidth[0]+2);
for(i=1; i<nArg; i++){
oputz(zSep2);
print_box_line(p->actualWidth[i]+2);
}
oputz(zSep3);
}
oputz("\n");
}
/*
** z[] is a line of text that is to be displayed the .mode box or table or
** similar tabular formats. z[] might contain control characters such
** as \n, \t, \f, or \r.
**
|
| ︙ | ︙ | |||
19949 19950 19951 19952 19953 19954 19955 |
case MODE_Column: {
colSep = " ";
rowSep = "\n";
if( p->showHeader ){
for(i=0; i<nColumn; i++){
w = p->actualWidth[i];
if( p->colWidth[i]<0 ) w = -w;
| | | | | | | | | | | | | | | | | | 20704 20705 20706 20707 20708 20709 20710 20711 20712 20713 20714 20715 20716 20717 20718 20719 20720 20721 20722 20723 20724 20725 20726 20727 20728 20729 20730 20731 20732 20733 20734 20735 20736 20737 20738 20739 20740 20741 20742 20743 20744 20745 20746 20747 20748 20749 20750 20751 20752 20753 20754 20755 20756 20757 20758 20759 20760 20761 20762 20763 20764 20765 20766 20767 20768 20769 20770 20771 20772 20773 20774 20775 20776 20777 20778 20779 20780 20781 20782 20783 20784 20785 20786 20787 20788 20789 20790 20791 20792 20793 20794 20795 20796 20797 20798 20799 20800 20801 20802 20803 20804 |
case MODE_Column: {
colSep = " ";
rowSep = "\n";
if( p->showHeader ){
for(i=0; i<nColumn; i++){
w = p->actualWidth[i];
if( p->colWidth[i]<0 ) w = -w;
utf8_width_print(w, azData[i]);
fputs(i==nColumn-1?"\n":" ", p->out);
}
for(i=0; i<nColumn; i++){
print_dashes(p->actualWidth[i]);
fputs(i==nColumn-1?"\n":" ", p->out);
}
}
break;
}
case MODE_Table: {
colSep = " | ";
rowSep = " |\n";
print_row_separator(p, nColumn, "+");
fputs("| ", p->out);
for(i=0; i<nColumn; i++){
w = p->actualWidth[i];
n = strlenChar(azData[i]);
oputf("%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
oputz(i==nColumn-1?" |\n":" | ");
}
print_row_separator(p, nColumn, "+");
break;
}
case MODE_Markdown: {
colSep = " | ";
rowSep = " |\n";
fputs("| ", p->out);
for(i=0; i<nColumn; i++){
w = p->actualWidth[i];
n = strlenChar(azData[i]);
oputf("%*s%s%*s", (w-n)/2, "", azData[i], (w-n+1)/2, "");
oputz(i==nColumn-1?" |\n":" | ");
}
print_row_separator(p, nColumn, "|");
break;
}
case MODE_Box: {
colSep = " " BOX_13 " ";
rowSep = " " BOX_13 "\n";
print_box_row_separator(p, nColumn, BOX_23, BOX_234, BOX_34);
oputz(BOX_13 " ");
for(i=0; i<nColumn; i++){
w = p->actualWidth[i];
n = strlenChar(azData[i]);
oputf("%*s%s%*s%s",
(w-n)/2, "", azData[i], (w-n+1)/2, "",
i==nColumn-1?" "BOX_13"\n":" "BOX_13" ");
}
print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
break;
}
}
for(i=nColumn, j=0; i<nTotal; i++, j++){
if( j==0 && p->cMode!=MODE_Column ){
oputz(p->cMode==MODE_Box?BOX_13" ":"| ");
}
z = azData[i];
if( z==0 ) z = p->nullValue;
w = p->actualWidth[j];
if( p->colWidth[j]<0 ) w = -w;
utf8_width_print(w, z);
if( j==nColumn-1 ){
oputz(rowSep);
if( bMultiLineRowExists && abRowDiv[i/nColumn-1] && i+1<nTotal ){
if( p->cMode==MODE_Table ){
print_row_separator(p, nColumn, "+");
}else if( p->cMode==MODE_Box ){
print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
}else if( p->cMode==MODE_Column ){
oputz("\n");
}
}
j = -1;
if( seenInterrupt ) goto columnar_end;
}else{
oputz(colSep);
}
}
if( p->cMode==MODE_Table ){
print_row_separator(p, nColumn, "+");
}else if( p->cMode==MODE_Box ){
print_box_row_separator(p, nColumn, BOX_12, BOX_124, BOX_14);
}
columnar_end:
if( seenInterrupt ){
oputz("Interrupt\n");
}
nData = (nRow+1)*nColumn;
for(i=0; i<nData; i++){
z = azData[i];
if( z!=zEmpty && z!=zShowNull ) free(azData[i]);
}
sqlite3_free(azData);
|
| ︙ | ︙ | |||
20174 20175 20176 20177 20178 20179 20180 |
char **pzErr
){
int rc = SQLITE_OK;
sqlite3expert *p = pState->expert.pExpert;
assert( p );
assert( bCancel || pzErr==0 || *pzErr==0 );
if( bCancel==0 ){
| < | | | | | | | 20929 20930 20931 20932 20933 20934 20935 20936 20937 20938 20939 20940 20941 20942 20943 20944 20945 20946 20947 20948 20949 20950 20951 20952 20953 20954 20955 20956 20957 20958 20959 20960 20961 20962 20963 20964 20965 |
char **pzErr
){
int rc = SQLITE_OK;
sqlite3expert *p = pState->expert.pExpert;
assert( p );
assert( bCancel || pzErr==0 || *pzErr==0 );
if( bCancel==0 ){
int bVerbose = pState->expert.bVerbose;
rc = sqlite3_expert_analyze(p, pzErr);
if( rc==SQLITE_OK ){
int nQuery = sqlite3_expert_count(p);
int i;
if( bVerbose ){
const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
oputz("-- Candidates -----------------------------\n");
oputf("%s\n", zCand);
}
for(i=0; i<nQuery; i++){
const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES);
const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
if( zIdx==0 ) zIdx = "(no new indexes)\n";
if( bVerbose ){
oputf("-- Query %d --------------------------------\n",i+1);
oputf("%s\n\n", zSql);
}
oputf("%s\n", zIdx);
oputf("%s\n", zEQP);
}
}
}
sqlite3_expert_destroy(p);
pState->expert.pExpert = 0;
return rc;
}
|
| ︙ | ︙ | |||
20232 20233 20234 20235 20236 20237 20238 |
if( z[0]=='-' && z[1]=='-' ) z++;
n = strlen30(z);
if( n>=2 && 0==cli_strncmp(z, "-verbose", n) ){
pState->expert.bVerbose = 1;
}
else if( n>=2 && 0==cli_strncmp(z, "-sample", n) ){
if( i==(nArg-1) ){
| | | | < | | 20986 20987 20988 20989 20990 20991 20992 20993 20994 20995 20996 20997 20998 20999 21000 21001 21002 21003 21004 21005 21006 21007 21008 21009 21010 21011 21012 21013 21014 21015 21016 21017 21018 21019 |
if( z[0]=='-' && z[1]=='-' ) z++;
n = strlen30(z);
if( n>=2 && 0==cli_strncmp(z, "-verbose", n) ){
pState->expert.bVerbose = 1;
}
else if( n>=2 && 0==cli_strncmp(z, "-sample", n) ){
if( i==(nArg-1) ){
eputf("option requires an argument: %s\n", z);
rc = SQLITE_ERROR;
}else{
iSample = (int)integerValue(azArg[++i]);
if( iSample<0 || iSample>100 ){
eputf("value out of range: %s\n", azArg[i]);
rc = SQLITE_ERROR;
}
}
}
else{
eputf("unknown option: %s\n", z);
rc = SQLITE_ERROR;
}
}
if( rc==SQLITE_OK ){
pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
if( pState->expert.pExpert==0 ){
eputf("sqlite3_expert_new: %s\n", zErr ? zErr : "out of memory");
rc = SQLITE_ERROR;
}else{
sqlite3_expert_config(
pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
);
}
}
|
| ︙ | ︙ | |||
20579 20580 20581 20582 20583 20584 20585 |
zSql = azArg[2];
if( zTable==0 ) return 0;
if( zType==0 ) return 0;
dataOnly = (p->shellFlgs & SHFLG_DumpDataOnly)!=0;
noSys = (p->shellFlgs & SHFLG_DumpNoSys)!=0;
if( cli_strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
| | | | | | | 21332 21333 21334 21335 21336 21337 21338 21339 21340 21341 21342 21343 21344 21345 21346 21347 21348 21349 21350 21351 21352 21353 21354 21355 21356 21357 21358 21359 21360 21361 21362 21363 21364 21365 21366 21367 21368 |
zSql = azArg[2];
if( zTable==0 ) return 0;
if( zType==0 ) return 0;
dataOnly = (p->shellFlgs & SHFLG_DumpDataOnly)!=0;
noSys = (p->shellFlgs & SHFLG_DumpNoSys)!=0;
if( cli_strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
if( !dataOnly ) oputz("DELETE FROM sqlite_sequence;\n");
}else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
if( !dataOnly ) oputz("ANALYZE sqlite_schema;\n");
}else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){
return 0;
}else if( dataOnly ){
/* no-op */
}else if( cli_strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
char *zIns;
if( !p->writableSchema ){
oputz("PRAGMA writable_schema=ON;\n");
p->writableSchema = 1;
}
zIns = sqlite3_mprintf(
"INSERT INTO sqlite_schema(type,name,tbl_name,rootpage,sql)"
"VALUES('table','%q','%q',0,'%q');",
zTable, zTable, zSql);
shell_check_oom(zIns);
oputf("%s\n", zIns);
sqlite3_free(zIns);
return 0;
}else{
printSchemaLine(zSql, ";\n");
}
if( cli_strcmp(zType, "table")==0 ){
ShellText sSelect;
ShellText sTable;
char **azCol;
int i;
|
| ︙ | ︙ | |||
20659 20660 20661 20662 20663 20664 20665 |
savedDestTable = p->zDestTable;
savedMode = p->mode;
p->zDestTable = sTable.z;
p->mode = p->cMode = MODE_Insert;
rc = shell_exec(p, sSelect.z, 0);
if( (rc&0xff)==SQLITE_CORRUPT ){
| | | 21412 21413 21414 21415 21416 21417 21418 21419 21420 21421 21422 21423 21424 21425 21426 |
savedDestTable = p->zDestTable;
savedMode = p->mode;
p->zDestTable = sTable.z;
p->mode = p->cMode = MODE_Insert;
rc = shell_exec(p, sSelect.z, 0);
if( (rc&0xff)==SQLITE_CORRUPT ){
oputz("/****** CORRUPTION ERROR *******/\n");
toggleSelectOrder(p->db);
shell_exec(p, sSelect.z, 0);
toggleSelectOrder(p->db);
}
p->zDestTable = savedDestTable;
p->mode = savedMode;
freeText(&sTable);
|
| ︙ | ︙ | |||
20690 20691 20692 20693 20694 20695 20696 |
){
int rc;
char *zErr = 0;
rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
if( rc==SQLITE_CORRUPT ){
char *zQ2;
int len = strlen30(zQuery);
| | | | | 21443 21444 21445 21446 21447 21448 21449 21450 21451 21452 21453 21454 21455 21456 21457 21458 21459 21460 21461 21462 21463 21464 21465 21466 21467 21468 |
){
int rc;
char *zErr = 0;
rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
if( rc==SQLITE_CORRUPT ){
char *zQ2;
int len = strlen30(zQuery);
oputz("/****** CORRUPTION ERROR *******/\n");
if( zErr ){
oputf("/****** %s ******/\n", zErr);
sqlite3_free(zErr);
zErr = 0;
}
zQ2 = malloc( len+100 );
if( zQ2==0 ) return rc;
sqlite3_snprintf(len+100, zQ2, "%s ORDER BY rowid DESC", zQuery);
rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
if( rc ){
oputf("/****** ERROR: %s ******/\n", zErr);
}else{
rc = SQLITE_CORRUPT;
}
sqlite3_free(zErr);
free(zQ2);
}
return rc;
|
| ︙ | ︙ | |||
21057 21058 21059 21060 21061 21062 21063 |
break;
default:
hh &= ~HH_Summary;
break;
}
if( ((hw^hh)&HH_Undoc)==0 ){
if( (hh&HH_Summary)!=0 ){
| | | | | | | | 21810 21811 21812 21813 21814 21815 21816 21817 21818 21819 21820 21821 21822 21823 21824 21825 21826 21827 21828 21829 21830 21831 21832 21833 21834 21835 21836 21837 21838 21839 21840 21841 21842 21843 21844 21845 21846 21847 21848 21849 21850 21851 21852 21853 21854 21855 21856 21857 21858 21859 21860 21861 21862 21863 21864 21865 21866 21867 21868 |
break;
default:
hh &= ~HH_Summary;
break;
}
if( ((hw^hh)&HH_Undoc)==0 ){
if( (hh&HH_Summary)!=0 ){
sputf(out, ".%s\n", azHelp[i]+1);
++n;
}else if( (hw&HW_SummaryOnly)==0 ){
sputf(out, "%s\n", azHelp[i]);
}
}
}
}else{
/* Seek documented commands for which zPattern is an exact prefix */
zPat = sqlite3_mprintf(".%s*", zPattern);
shell_check_oom(zPat);
for(i=0; i<ArraySize(azHelp); i++){
if( sqlite3_strglob(zPat, azHelp[i])==0 ){
sputf(out, "%s\n", azHelp[i]);
j = i+1;
n++;
}
}
sqlite3_free(zPat);
if( n ){
if( n==1 ){
/* when zPattern is a prefix of exactly one command, then include
** the details of that command, which should begin at offset j */
while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){
sputf(out, "%s\n", azHelp[j]);
j++;
}
}
return n;
}
/* Look for documented commands that contain zPattern anywhere.
** Show complete text of all documented commands that match. */
zPat = sqlite3_mprintf("%%%s%%", zPattern);
shell_check_oom(zPat);
for(i=0; i<ArraySize(azHelp); i++){
if( azHelp[i][0]==',' ){
while( i<ArraySize(azHelp)-1 && azHelp[i+1][0]==' ' ) ++i;
continue;
}
if( azHelp[i][0]=='.' ) j = i;
if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
sputf(out, "%s\n", azHelp[j]);
while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]==' ' ){
j++;
sputf(out, "%s\n", azHelp[j]);
}
i = j;
n++;
}
}
sqlite3_free(zPat);
}
|
| ︙ | ︙ | |||
21139 21140 21141 21142 21143 21144 21145 |
long nIn;
size_t nRead;
char *pBuf;
int rc;
if( in==0 ) return 0;
rc = fseek(in, 0, SEEK_END);
if( rc!=0 ){
| | | | | 21892 21893 21894 21895 21896 21897 21898 21899 21900 21901 21902 21903 21904 21905 21906 21907 21908 21909 21910 21911 21912 21913 21914 21915 21916 21917 21918 21919 21920 21921 21922 |
long nIn;
size_t nRead;
char *pBuf;
int rc;
if( in==0 ) return 0;
rc = fseek(in, 0, SEEK_END);
if( rc!=0 ){
eputf("Error: '%s' not seekable\n", zName);
fclose(in);
return 0;
}
nIn = ftell(in);
rewind(in);
pBuf = sqlite3_malloc64( nIn+1 );
if( pBuf==0 ){
eputz("Error: out of memory\n");
fclose(in);
return 0;
}
nRead = fread(pBuf, nIn, 1, in);
fclose(in);
if( nRead!=1 ){
sqlite3_free(pBuf);
eputf("Error: cannot read '%s'\n", zName);
return 0;
}
pBuf[nIn] = 0;
if( pnByte ) *pnByte = nIn;
return pBuf;
}
|
| ︙ | ︙ | |||
21276 21277 21278 21279 21280 21281 21282 |
FILE *in;
const char *zDbFilename = p->pAuxDb->zDbFilename;
unsigned int x[16];
char zLine[1000];
if( zDbFilename ){
in = fopen(zDbFilename, "r");
if( in==0 ){
| | | | 22029 22030 22031 22032 22033 22034 22035 22036 22037 22038 22039 22040 22041 22042 22043 22044 22045 22046 22047 22048 22049 22050 22051 22052 22053 22054 22055 22056 22057 22058 22059 22060 22061 22062 22063 22064 |
FILE *in;
const char *zDbFilename = p->pAuxDb->zDbFilename;
unsigned int x[16];
char zLine[1000];
if( zDbFilename ){
in = fopen(zDbFilename, "r");
if( in==0 ){
eputf("cannot open \"%s\" for reading\n", zDbFilename);
return 0;
}
nLine = 0;
}else{
in = p->in;
nLine = p->lineno;
if( in==0 ) in = stdin;
}
*pnData = 0;
nLine++;
if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
if( rc!=2 ) goto readHexDb_error;
if( n<0 ) goto readHexDb_error;
if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error;
n = (n+pgsz-1)&~(pgsz-1); /* Round n up to the next multiple of pgsz */
a = sqlite3_malloc( n ? n : 1 );
shell_check_oom(a);
memset(a, 0, n);
if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
eputz("invalid pagesize\n");
goto readHexDb_error;
}
for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){
rc = sscanf(zLine, "| page %d offset %d", &j, &k);
if( rc==2 ){
iOffset = k;
continue;
|
| ︙ | ︙ | |||
21339 21340 21341 21342 21343 21344 21345 |
while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
nLine++;
if(cli_strncmp(zLine, "| end ", 6)==0 ) break;
}
p->lineno = nLine;
}
sqlite3_free(a);
| | | 22092 22093 22094 22095 22096 22097 22098 22099 22100 22101 22102 22103 22104 22105 22106 |
while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
nLine++;
if(cli_strncmp(zLine, "| end ", 6)==0 ) break;
}
p->lineno = nLine;
}
sqlite3_free(a);
eputf("Error on line %d of --hexdb input\n", nLine);
return 0;
}
#endif /* SQLITE_OMIT_DESERIALIZE */
/*
** Scalar function "usleep(X)" invokes sqlite3_sleep(X) and returns X.
*/
|
| ︙ | ︙ | |||
21415 21416 21417 21418 21419 21420 21421 |
sqlite3_open_v2(zDbFilename, &p->db,
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
break;
}
}
globalDb = p->db;
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
| | | < | < < | | | 22168 22169 22170 22171 22172 22173 22174 22175 22176 22177 22178 22179 22180 22181 22182 22183 22184 22185 22186 22187 22188 22189 22190 22191 22192 22193 22194 |
sqlite3_open_v2(zDbFilename, &p->db,
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|p->openFlags, 0);
break;
}
}
globalDb = p->db;
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
eputf("Error: unable to open database \"%s\": %s\n",
zDbFilename, sqlite3_errmsg(p->db));
if( (openFlags & OPEN_DB_KEEPALIVE)==0 ){
exit(1);
}
sqlite3_close(p->db);
sqlite3_open(":memory:", &p->db);
if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
eputz("Also: unable to open substitute in-memory database.\n");
exit(1);
}else{
eputf("Notice: using substitute in-memory database instead of \"%s\"\n",
zDbFilename);
}
}
sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, (int)0, (int*)0);
/* Reflect the use or absence of --unsafe-testing invocation. */
{
int testmode_on = ShellHasFlag(p,SHFLG_TestingMode);
|
| ︙ | ︙ | |||
21537 21538 21539 21540 21541 21542 21543 |
if( aData==0 ){
return;
}
rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
SQLITE_DESERIALIZE_RESIZEABLE |
SQLITE_DESERIALIZE_FREEONCLOSE);
if( rc ){
| | | 22287 22288 22289 22290 22291 22292 22293 22294 22295 22296 22297 22298 22299 22300 22301 |
if( aData==0 ){
return;
}
rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
SQLITE_DESERIALIZE_RESIZEABLE |
SQLITE_DESERIALIZE_FREEONCLOSE);
if( rc ){
eputf("Error: sqlite3_deserialize() returns %d\n", rc);
}
if( p->szMax>0 ){
sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax);
}
}
#endif
}
|
| ︙ | ︙ | |||
21561 21562 21563 21564 21565 21566 21567 |
/*
** Attempt to close the database connection. Report errors.
*/
void close_db(sqlite3 *db){
int rc = sqlite3_close(db);
if( rc ){
| | < | 22311 22312 22313 22314 22315 22316 22317 22318 22319 22320 22321 22322 22323 22324 22325 |
/*
** Attempt to close the database connection. Report errors.
*/
void close_db(sqlite3 *db){
int rc = sqlite3_close(db);
if( rc ){
eputf("Error: sqlite3_close() returns %d: %s\n", rc, sqlite3_errmsg(db));
}
}
#if HAVE_READLINE || HAVE_EDITLINE
/*
** Readline completion callbacks
*/
|
| ︙ | ︙ | |||
21723 21724 21725 21726 21727 21728 21729 |
if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
return 1;
}
if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
return 0;
}
| | < | 22472 22473 22474 22475 22476 22477 22478 22479 22480 22481 22482 22483 22484 22485 22486 |
if( i>0 && zArg[i]==0 ) return (int)(integerValue(zArg) & 0xffffffff);
if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
return 1;
}
if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
return 0;
}
eputf("ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n", zArg);
return 0;
}
/*
** Set or clear a shell flag according to a boolean value.
*/
static void setOrClearFlag(ShellState *p, unsigned mFlag, const char *zArg){
|
| ︙ | ︙ | |||
21762 21763 21764 21765 21766 21767 21768 |
}else if( cli_strcmp(zFile, "stderr")==0 ){
f = stderr;
}else if( cli_strcmp(zFile, "off")==0 ){
f = 0;
}else{
f = fopen(zFile, bTextMode ? "w" : "wb");
if( f==0 ){
| | | 22510 22511 22512 22513 22514 22515 22516 22517 22518 22519 22520 22521 22522 22523 22524 |
}else if( cli_strcmp(zFile, "stderr")==0 ){
f = stderr;
}else if( cli_strcmp(zFile, "off")==0 ){
f = 0;
}else{
f = fopen(zFile, bTextMode ? "w" : "wb");
if( f==0 ){
eputf("Error: cannot open \"%s\"\n", zFile);
}
}
return f;
}
#ifndef SQLITE_OMIT_TRACE
/*
|
| ︙ | ︙ | |||
21784 21785 21786 21787 21788 21789 21790 |
){
ShellState *p = (ShellState*)pArg;
sqlite3_stmt *pStmt;
const char *zSql;
i64 nSql;
if( p->traceOut==0 ) return 0;
if( mType==SQLITE_TRACE_CLOSE ){
| | | 22532 22533 22534 22535 22536 22537 22538 22539 22540 22541 22542 22543 22544 22545 22546 |
){
ShellState *p = (ShellState*)pArg;
sqlite3_stmt *pStmt;
const char *zSql;
i64 nSql;
if( p->traceOut==0 ) return 0;
if( mType==SQLITE_TRACE_CLOSE ){
sputz(p->traceOut, "-- closing database connection\n");
return 0;
}
if( mType!=SQLITE_TRACE_ROW && pX!=0 && ((const char*)pX)[0]=='-' ){
zSql = (const char*)pX;
}else{
pStmt = (sqlite3_stmt*)pP;
switch( p->eTraceType ){
|
| ︙ | ︙ | |||
21815 21816 21817 21818 21819 21820 21821 |
if( zSql==0 ) return 0;
nSql = strlen(zSql);
if( nSql>1000000000 ) nSql = 1000000000;
while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; }
switch( mType ){
case SQLITE_TRACE_ROW:
case SQLITE_TRACE_STMT: {
| | | | 22563 22564 22565 22566 22567 22568 22569 22570 22571 22572 22573 22574 22575 22576 22577 22578 22579 22580 22581 22582 |
if( zSql==0 ) return 0;
nSql = strlen(zSql);
if( nSql>1000000000 ) nSql = 1000000000;
while( nSql>0 && zSql[nSql-1]==';' ){ nSql--; }
switch( mType ){
case SQLITE_TRACE_ROW:
case SQLITE_TRACE_STMT: {
sputf(p->traceOut, "%.*s;\n", (int)nSql, zSql);
break;
}
case SQLITE_TRACE_PROFILE: {
sqlite3_int64 nNanosec = pX ? *(sqlite3_int64*)pX : 0;
sputf(p->traceOut, "%.*s; -- %lld ns\n", (int)nSql, zSql, nNanosec);
break;
}
}
return 0;
}
#endif
|
| ︙ | ︙ | |||
21927 21928 21929 21930 21931 21932 21933 |
|| (c==EOF && pc==cQuote)
){
do{ p->n--; }while( p->z[p->n]!=cQuote );
p->cTerm = c;
break;
}
if( pc==cQuote && c!='\r' ){
| < | | | | 22675 22676 22677 22678 22679 22680 22681 22682 22683 22684 22685 22686 22687 22688 22689 22690 22691 22692 22693 |
|| (c==EOF && pc==cQuote)
){
do{ p->n--; }while( p->z[p->n]!=cQuote );
p->cTerm = c;
break;
}
if( pc==cQuote && c!='\r' ){
eputf("%s:%d: unescaped %c character\n", p->zFile, p->nLine, cQuote);
}
if( c==EOF ){
eputf("%s:%d: unterminated %c-quoted field\n",
p->zFile, startLine, cQuote);
p->cTerm = c;
break;
}
import_append_char(p, c);
ppc = pc;
pc = c;
}
|
| ︙ | ︙ | |||
22030 22031 22032 22033 22034 22035 22036 |
int cnt = 0;
const int spinRate = 10000;
zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
shell_check_oom(zQuery);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
| | | < | | < | 22777 22778 22779 22780 22781 22782 22783 22784 22785 22786 22787 22788 22789 22790 22791 22792 22793 22794 22795 22796 22797 22798 22799 22800 22801 22802 22803 22804 22805 22806 22807 22808 22809 |
int cnt = 0;
const int spinRate = 10000;
zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
shell_check_oom(zQuery);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
eputf("Error %d: %s on [%s]\n",
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery);
goto end_data_xfer;
}
n = sqlite3_column_count(pQuery);
zInsert = sqlite3_malloc64(200 + nTable + n*3);
shell_check_oom(zInsert);
sqlite3_snprintf(200+nTable,zInsert,
"INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
i = strlen30(zInsert);
for(j=1; j<n; j++){
memcpy(zInsert+i, ",?", 2);
i += 2;
}
memcpy(zInsert+i, ");", 3);
rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
if( rc ){
eputf("Error %d: %s on [%s]\n",
sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), zInsert);
goto end_data_xfer;
}
for(k=0; k<2; k++){
while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
for(i=0; i<n; i++){
switch( sqlite3_column_type(pQuery, i) ){
case SQLITE_NULL: {
|
| ︙ | ︙ | |||
22085 22086 22087 22088 22089 22090 22091 |
SQLITE_STATIC);
break;
}
}
} /* End for */
rc = sqlite3_step(pInsert);
if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
| | | | | 22830 22831 22832 22833 22834 22835 22836 22837 22838 22839 22840 22841 22842 22843 22844 22845 22846 22847 22848 22849 22850 22851 22852 22853 22854 22855 22856 22857 22858 22859 22860 22861 22862 |
SQLITE_STATIC);
break;
}
}
} /* End for */
rc = sqlite3_step(pInsert);
if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
eputf("Error %d: %s\n",
sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb));
}
sqlite3_reset(pInsert);
cnt++;
if( (cnt%spinRate)==0 ){
printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
fflush(stdout);
}
} /* End while */
if( rc==SQLITE_DONE ) break;
sqlite3_finalize(pQuery);
sqlite3_free(zQuery);
zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
zTable);
shell_check_oom(zQuery);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
eputf("Warning: cannot step \"%s\" backwards", zTable);
break;
}
} /* End for(k=0...) */
end_data_xfer:
sqlite3_finalize(pQuery);
sqlite3_finalize(pInsert);
|
| ︙ | ︙ | |||
22140 22141 22142 22143 22144 22145 22146 |
char *zErrMsg = 0;
zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
" WHERE %s ORDER BY rowid ASC", zWhere);
shell_check_oom(zQuery);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
| | | < | | | | | < | | | | | < > > > > > > > > > > > > | 22885 22886 22887 22888 22889 22890 22891 22892 22893 22894 22895 22896 22897 22898 22899 22900 22901 22902 22903 22904 22905 22906 22907 22908 22909 22910 22911 22912 22913 22914 22915 22916 22917 22918 22919 22920 22921 22922 22923 22924 22925 22926 22927 22928 22929 22930 22931 22932 22933 22934 22935 22936 22937 22938 22939 22940 22941 22942 22943 22944 22945 22946 22947 22948 22949 22950 22951 22952 22953 22954 22955 22956 22957 22958 22959 22960 22961 22962 22963 22964 22965 22966 22967 22968 22969 22970 22971 22972 22973 22974 22975 22976 22977 22978 22979 22980 22981 22982 22983 22984 22985 22986 22987 22988 22989 22990 22991 22992 |
char *zErrMsg = 0;
zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
" WHERE %s ORDER BY rowid ASC", zWhere);
shell_check_oom(zQuery);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
eputf("Error: (%d) %s on [%s]\n", sqlite3_extended_errcode(p->db),
sqlite3_errmsg(p->db), zQuery);
goto end_schema_xfer;
}
while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
zName = sqlite3_column_text(pQuery, 0);
zSql = sqlite3_column_text(pQuery, 1);
if( zName==0 || zSql==0 ) continue;
if( sqlite3_stricmp((char*)zName, "sqlite_sequence")!=0 ){
sputf(stdout, "%s... ", zName); fflush(stdout);
sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
if( zErrMsg ){
eputf("Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
sqlite3_free(zErrMsg);
zErrMsg = 0;
}
}
if( xForEach ){
xForEach(p, newDb, (const char*)zName);
}
sputz(stdout, "done\n");
}
if( rc!=SQLITE_DONE ){
sqlite3_finalize(pQuery);
sqlite3_free(zQuery);
zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_schema"
" WHERE %s ORDER BY rowid DESC", zWhere);
shell_check_oom(zQuery);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
eputf("Error: (%d) %s on [%s]\n",
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db), zQuery);
goto end_schema_xfer;
}
while( sqlite3_step(pQuery)==SQLITE_ROW ){
zName = sqlite3_column_text(pQuery, 0);
zSql = sqlite3_column_text(pQuery, 1);
if( zName==0 || zSql==0 ) continue;
if( sqlite3_stricmp((char*)zName, "sqlite_sequence")==0 ) continue;
sputf(stdout, "%s... ", zName); fflush(stdout);
sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
if( zErrMsg ){
eputf("Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
sqlite3_free(zErrMsg);
zErrMsg = 0;
}
if( xForEach ){
xForEach(p, newDb, (const char*)zName);
}
sputz(stdout, "done\n");
}
}
end_schema_xfer:
sqlite3_finalize(pQuery);
sqlite3_free(zQuery);
}
/*
** Open a new database file named "zNewDb". Try to recover as much information
** as possible out of the main database (which might be corrupt) and write it
** into zNewDb.
*/
static void tryToClone(ShellState *p, const char *zNewDb){
int rc;
sqlite3 *newDb = 0;
if( access(zNewDb,0)==0 ){
eputf("File \"%s\" already exists.\n", zNewDb);
return;
}
rc = sqlite3_open(zNewDb, &newDb);
if( rc ){
eputf("Cannot create output database: %s\n", sqlite3_errmsg(newDb));
}else{
sqlite3_exec(p->db, "PRAGMA writable_schema=ON;", 0, 0, 0);
sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
tryToCloneSchema(p, newDb, "type!='table'", 0);
sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
}
close_db(newDb);
}
#ifndef SQLITE_SHELL_FIDDLE
/*
** Change the output stream (file or pipe or console) to something else.
*/
static void output_redir(ShellState *p, FILE *pfNew){
if( p->out != stdout ) eputz("Output already redirected.\n");
else{
p->out = pfNew;
setOutputStream(pfNew);
}
}
/*
** Change the output file back to stdout.
**
** If the p->doXdgOpen flag is set, that means the output was being
** redirected to a temporary file named by p->zTempFile. In that case,
** launch start/open/xdg-open on that temporary file.
|
| ︙ | ︙ | |||
22253 22254 22255 22256 22257 22258 22259 |
"open";
#else
"xdg-open";
#endif
char *zCmd;
zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
if( system(zCmd) ){
| | > > > > > | 23007 23008 23009 23010 23011 23012 23013 23014 23015 23016 23017 23018 23019 23020 23021 23022 23023 23024 23025 23026 23027 23028 23029 23030 23031 23032 23033 23034 23035 23036 23037 23038 23039 23040 23041 |
"open";
#else
"xdg-open";
#endif
char *zCmd;
zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
if( system(zCmd) ){
eputf("Failed: [%s]\n", zCmd);
}else{
/* Give the start/open/xdg-open command some time to get
** going before we continue, and potential delete the
** p->zTempFile data file out from under it */
sqlite3_sleep(2000);
}
sqlite3_free(zCmd);
outputModePop(p);
p->doXdgOpen = 0;
}
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
}
p->outfile[0] = 0;
p->out = stdout;
setOutputStream(stdout);
}
#else
# define output_redir(SS,pfO)
# define output_reset(SS)
#endif
/*
** Run an SQL command and return the single integer result.
*/
static int db_int(sqlite3 *db, const char *zSql){
sqlite3_stmt *pStmt;
int res = 0;
|
| ︙ | ︙ | |||
22339 22340 22341 22342 22343 22344 22345 |
unsigned char aHdr[100];
open_db(p, 0);
if( p->db==0 ) return 1;
rc = sqlite3_prepare_v2(p->db,
"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
-1, &pStmt, 0);
if( rc ){
| | | | | | | | | | | | | | | | 23098 23099 23100 23101 23102 23103 23104 23105 23106 23107 23108 23109 23110 23111 23112 23113 23114 23115 23116 23117 23118 23119 23120 23121 23122 23123 23124 23125 23126 23127 23128 23129 23130 23131 23132 23133 23134 23135 23136 23137 23138 23139 23140 23141 23142 23143 23144 23145 23146 23147 23148 23149 23150 23151 23152 23153 23154 23155 23156 23157 23158 23159 23160 23161 23162 23163 23164 23165 23166 23167 23168 23169 23170 23171 23172 23173 |
unsigned char aHdr[100];
open_db(p, 0);
if( p->db==0 ) return 1;
rc = sqlite3_prepare_v2(p->db,
"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
-1, &pStmt, 0);
if( rc ){
eputf("error: %s\n", sqlite3_errmsg(p->db));
sqlite3_finalize(pStmt);
return 1;
}
sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
if( sqlite3_step(pStmt)==SQLITE_ROW
&& sqlite3_column_bytes(pStmt,0)>100
){
const u8 *pb = sqlite3_column_blob(pStmt,0);
shell_check_oom(pb);
memcpy(aHdr, pb, 100);
sqlite3_finalize(pStmt);
}else{
eputz("unable to read database header\n");
sqlite3_finalize(pStmt);
return 1;
}
i = get2byteInt(aHdr+16);
if( i==1 ) i = 65536;
oputf("%-20s %d\n", "database page size:", i);
oputf("%-20s %d\n", "write format:", aHdr[18]);
oputf("%-20s %d\n", "read format:", aHdr[19]);
oputf("%-20s %d\n", "reserved bytes:", aHdr[20]);
for(i=0; i<ArraySize(aField); i++){
int ofst = aField[i].ofst;
unsigned int val = get4byteInt(aHdr + ofst);
oputf("%-20s %u", aField[i].zName, val);
switch( ofst ){
case 56: {
if( val==1 ) oputz(" (utf8)");
if( val==2 ) oputz(" (utf16le)");
if( val==3 ) oputz(" (utf16be)");
}
}
oputz("\n");
}
if( zDb==0 ){
zSchemaTab = sqlite3_mprintf("main.sqlite_schema");
}else if( cli_strcmp(zDb,"temp")==0 ){
zSchemaTab = sqlite3_mprintf("%s", "sqlite_temp_schema");
}else{
zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_schema", zDb);
}
for(i=0; i<ArraySize(aQuery); i++){
char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
int val = db_int(p->db, zSql);
sqlite3_free(zSql);
oputf("%-20s %d\n", aQuery[i].zName, val);
}
sqlite3_free(zSchemaTab);
sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_DATA_VERSION, &iDataVersion);
oputf("%-20s %u\n", "data version", iDataVersion);
return 0;
}
#endif /* SQLITE_SHELL_HAVE_RECOVER */
/*
** Print the current sqlite3_errmsg() value to stderr and return 1.
*/
static int shellDatabaseError(sqlite3 *db){
const char *zErr = sqlite3_errmsg(db);
eputf("Error: %s\n", zErr);
return 1;
}
/*
** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
** if they match and FALSE (0) if they do not match.
**
|
| ︙ | ︙ | |||
22635 22636 22637 22638 22639 22640 22641 |
*/
static int lintFkeyIndexes(
ShellState *pState, /* Current shell tool state */
char **azArg, /* Array of arguments passed to dot command */
int nArg /* Number of entries in azArg[] */
){
sqlite3 *db = pState->db; /* Database handle to query "main" db of */
| < | 23394 23395 23396 23397 23398 23399 23400 23401 23402 23403 23404 23405 23406 23407 |
*/
static int lintFkeyIndexes(
ShellState *pState, /* Current shell tool state */
char **azArg, /* Array of arguments passed to dot command */
int nArg /* Number of entries in azArg[] */
){
sqlite3 *db = pState->db; /* Database handle to query "main" db of */
int bVerbose = 0; /* If -verbose is present */
int bGroupByParent = 0; /* If -groupbyparent is present */
int i; /* To iterate through azArg[] */
const char *zIndent = ""; /* How much to indent CREATE INDEX by */
int rc; /* Return code */
sqlite3_stmt *pSql = 0; /* Compiled version of SQL statement below */
|
| ︙ | ︙ | |||
22717 22718 22719 22720 22721 22722 22723 |
bVerbose = 1;
}
else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
bGroupByParent = 1;
zIndent = " ";
}
else{
| | < < | 23475 23476 23477 23478 23479 23480 23481 23482 23483 23484 23485 23486 23487 23488 23489 |
bVerbose = 1;
}
else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
bGroupByParent = 1;
zIndent = " ";
}
else{
eputf("Usage: %s %s ?-verbose? ?-groupbyparent?\n", azArg[0], azArg[1]);
return SQLITE_ERROR;
}
}
/* Register the fkey_collate_clause() SQL function */
rc = sqlite3_create_function(db, "fkey_collate_clause", 4, SQLITE_UTF8,
0, shellFkeyCollateClause, 0, 0
|
| ︙ | ︙ | |||
22763 22764 22765 22766 22767 22768 22769 |
res = zPlan!=0 && ( 0==sqlite3_strglob(zGlob, zPlan)
|| 0==sqlite3_strglob(zGlobIPK, zPlan));
}
rc = sqlite3_finalize(pExplain);
if( rc!=SQLITE_OK ) break;
if( res<0 ){
| | | | | | | | | | | | < | < | 23519 23520 23521 23522 23523 23524 23525 23526 23527 23528 23529 23530 23531 23532 23533 23534 23535 23536 23537 23538 23539 23540 23541 23542 23543 23544 23545 23546 23547 23548 23549 23550 23551 23552 23553 23554 23555 23556 23557 23558 23559 23560 23561 23562 23563 23564 23565 23566 23567 23568 23569 23570 23571 23572 23573 23574 23575 23576 23577 23578 23579 23580 23581 23582 23583 23584 23585 23586 23587 23588 23589 23590 23591 23592 23593 23594 23595 23596 23597 23598 23599 23600 23601 23602 23603 |
res = zPlan!=0 && ( 0==sqlite3_strglob(zGlob, zPlan)
|| 0==sqlite3_strglob(zGlobIPK, zPlan));
}
rc = sqlite3_finalize(pExplain);
if( rc!=SQLITE_OK ) break;
if( res<0 ){
eputz("Error: internal error");
break;
}else{
if( bGroupByParent
&& (bVerbose || res==0)
&& (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
){
oputf("-- Parent table %s\n", zParent);
sqlite3_free(zPrev);
zPrev = sqlite3_mprintf("%s", zParent);
}
if( res==0 ){
oputf("%s%s --> %s\n", zIndent, zCI, zTarget);
}else if( bVerbose ){
oputf("%s/* no extra indexes required for %s -> %s */\n",
zIndent, zFrom, zTarget
);
}
}
}
sqlite3_free(zPrev);
if( rc!=SQLITE_OK ){
eputf("%s\n", sqlite3_errmsg(db));
}
rc2 = sqlite3_finalize(pSql);
if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
rc = rc2;
eputf("%s\n", sqlite3_errmsg(db));
}
}else{
eputf("%s\n", sqlite3_errmsg(db));
}
return rc;
}
/*
** Implementation of ".lint" dot command.
*/
static int lintDotCommand(
ShellState *pState, /* Current shell tool state */
char **azArg, /* Array of arguments passed to dot command */
int nArg /* Number of entries in azArg[] */
){
int n;
n = (nArg>=2 ? strlen30(azArg[1]) : 0);
if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
return lintFkeyIndexes(pState, azArg, nArg);
usage:
eputf("Usage %s sub-command ?switches...?\n", azArg[0]);
eputz("Where sub-commands are:\n");
eputz(" fkey-indexes\n");
return SQLITE_ERROR;
}
#if !defined SQLITE_OMIT_VIRTUALTABLE
static void shellPrepare(
sqlite3 *db,
int *pRc,
const char *zSql,
sqlite3_stmt **ppStmt
){
*ppStmt = 0;
if( *pRc==SQLITE_OK ){
int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
if( rc!=SQLITE_OK ){
eputf("sql error: %s (%d)\n", sqlite3_errmsg(db), sqlite3_errcode(db));
*pRc = rc;
}
}
}
/*
** Create a prepared statement using printf-style arguments for the SQL.
|
| ︙ | ︙ | |||
22886 22887 22888 22889 22890 22891 22892 |
sqlite3_stmt *pStmt
){
if( pStmt ){
sqlite3 *db = sqlite3_db_handle(pStmt);
int rc = sqlite3_finalize(pStmt);
if( *pRc==SQLITE_OK ){
if( rc!=SQLITE_OK ){
| | | | 23640 23641 23642 23643 23644 23645 23646 23647 23648 23649 23650 23651 23652 23653 23654 23655 23656 23657 23658 23659 23660 23661 23662 23663 23664 23665 23666 23667 23668 23669 23670 23671 23672 23673 23674 23675 |
sqlite3_stmt *pStmt
){
if( pStmt ){
sqlite3 *db = sqlite3_db_handle(pStmt);
int rc = sqlite3_finalize(pStmt);
if( *pRc==SQLITE_OK ){
if( rc!=SQLITE_OK ){
eputf("SQL error: %s\n", sqlite3_errmsg(db));
}
*pRc = rc;
}
}
}
/* Reset the prepared statement created using shellPreparePrintf().
**
** This routine is could be marked "static". But it is not always used,
** depending on compile-time options. By omitting the "static", we avoid
** nuisance compiler warnings about "defined but not used".
*/
void shellReset(
int *pRc,
sqlite3_stmt *pStmt
){
int rc = sqlite3_reset(pStmt);
if( *pRc==SQLITE_OK ){
if( rc!=SQLITE_OK ){
sqlite3 *db = sqlite3_db_handle(pStmt);
eputf("SQL error: %s\n", sqlite3_errmsg(db));
}
*pRc = rc;
}
}
#endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
|
| ︙ | ︙ | |||
22957 22958 22959 22960 22961 22962 22963 |
*/
static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
va_list ap;
char *z;
va_start(ap, zFmt);
z = sqlite3_vmprintf(zFmt, ap);
va_end(ap);
| | | | | 23711 23712 23713 23714 23715 23716 23717 23718 23719 23720 23721 23722 23723 23724 23725 23726 23727 23728 23729 |
*/
static int arErrorMsg(ArCommand *pAr, const char *zFmt, ...){
va_list ap;
char *z;
va_start(ap, zFmt);
z = sqlite3_vmprintf(zFmt, ap);
va_end(ap);
eputf("Error: %s\n", z);
if( pAr->fromCmdLine ){
eputz("Use \"-A\" for more help\n");
}else{
eputz("Use \".archive --help\" for more help\n");
}
sqlite3_free(z);
return SQLITE_ERROR;
}
/*
** Values for ArCommand.eCmd.
|
| ︙ | ︙ | |||
23061 23062 23063 23064 23065 23066 23067 |
{ "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
{ "glob", 'g', AR_SWITCH_GLOB, 0 },
};
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
struct ArSwitch *pEnd = &aSwitch[nSwitch];
if( nArg<=1 ){
| | | 23815 23816 23817 23818 23819 23820 23821 23822 23823 23824 23825 23826 23827 23828 23829 |
{ "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
{ "glob", 'g', AR_SWITCH_GLOB, 0 },
};
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
struct ArSwitch *pEnd = &aSwitch[nSwitch];
if( nArg<=1 ){
eputz("Wrong number of arguments. Usage:\n");
return arUsage(stderr);
}else{
char *z = azArg[1];
if( z[0]!='-' ){
/* Traditional style [tar] invocation */
int i;
int iArg = 2;
|
| ︙ | ︙ | |||
23167 23168 23169 23170 23171 23172 23173 |
}
if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR;
}
}
}
}
if( pAr->eCmd==0 ){
| | | 23921 23922 23923 23924 23925 23926 23927 23928 23929 23930 23931 23932 23933 23934 23935 |
}
if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR;
}
}
}
}
if( pAr->eCmd==0 ){
eputz("Required argument missing. Usage:\n");
return arUsage(stderr);
}
return SQLITE_OK;
}
/*
** This function assumes that all arguments within the ArCommand.azArg[]
|
| ︙ | ︙ | |||
23210 23211 23212 23213 23214 23215 23216 |
z[n] = '\0';
sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC);
if( SQLITE_ROW==sqlite3_step(pTest) ){
bOk = 1;
}
shellReset(&rc, pTest);
if( rc==SQLITE_OK && bOk==0 ){
| | | 23964 23965 23966 23967 23968 23969 23970 23971 23972 23973 23974 23975 23976 23977 23978 |
z[n] = '\0';
sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC);
if( SQLITE_ROW==sqlite3_step(pTest) ){
bOk = 1;
}
shellReset(&rc, pTest);
if( rc==SQLITE_OK && bOk==0 ){
eputf("not found in archive: %s\n", z);
rc = SQLITE_ERROR;
}
}
shellFinalize(&rc, pTest);
}
return rc;
}
|
| ︙ | ︙ | |||
23277 23278 23279 23280 23281 23282 23283 |
rc = arCheckEntries(pAr);
arWhereClause(&rc, pAr, &zWhere);
shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
pAr->zSrcTable, zWhere);
if( pAr->bDryRun ){
| | | | < | < < | < | | | 24031 24032 24033 24034 24035 24036 24037 24038 24039 24040 24041 24042 24043 24044 24045 24046 24047 24048 24049 24050 24051 24052 24053 24054 24055 24056 24057 24058 24059 24060 24061 24062 24063 24064 24065 24066 24067 24068 24069 24070 24071 24072 24073 24074 24075 24076 24077 24078 24079 24080 24081 24082 24083 24084 24085 24086 24087 24088 24089 24090 24091 24092 24093 |
rc = arCheckEntries(pAr);
arWhereClause(&rc, pAr, &zWhere);
shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
pAr->zSrcTable, zWhere);
if( pAr->bDryRun ){
oputf("%s\n", sqlite3_sql(pSql));
}else{
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
if( pAr->bVerbose ){
oputf("%s % 10d %s %s\n",
sqlite3_column_text(pSql, 0), sqlite3_column_int(pSql, 1),
sqlite3_column_text(pSql, 2),sqlite3_column_text(pSql, 3));
}else{
oputf("%s\n", sqlite3_column_text(pSql, 0));
}
}
}
shellFinalize(&rc, pSql);
sqlite3_free(zWhere);
return rc;
}
/*
** Implementation of .ar "Remove" command.
*/
static int arRemoveCommand(ArCommand *pAr){
int rc = 0;
char *zSql = 0;
char *zWhere = 0;
if( pAr->nArg ){
/* Verify that args actually exist within the archive before proceeding.
** And formulate a WHERE clause to match them. */
rc = arCheckEntries(pAr);
arWhereClause(&rc, pAr, &zWhere);
}
if( rc==SQLITE_OK ){
zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;",
pAr->zSrcTable, zWhere);
if( pAr->bDryRun ){
oputf("%s\n", zSql);
}else{
char *zErr = 0;
rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
if( rc!=SQLITE_OK ){
sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0);
}else{
rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0);
}
}
if( zErr ){
sputf(stdout, "ERROR: %s\n", zErr); /* stdout? */
sqlite3_free(zErr);
}
}
}
sqlite3_free(zWhere);
sqlite3_free(zSql);
return rc;
|
| ︙ | ︙ | |||
23393 23394 23395 23396 23397 23398 23399 |
** only for the directories. This is because the timestamps for
** extracted directories must be reset after they are populated (as
** populating them changes the timestamp). */
for(i=0; i<2; i++){
j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
sqlite3_bind_int(pSql, j, i);
if( pAr->bDryRun ){
| | | | | | 24143 24144 24145 24146 24147 24148 24149 24150 24151 24152 24153 24154 24155 24156 24157 24158 24159 24160 24161 24162 24163 24164 24165 24166 24167 24168 24169 24170 24171 24172 24173 24174 24175 24176 24177 24178 24179 24180 24181 24182 24183 24184 24185 24186 24187 |
** only for the directories. This is because the timestamps for
** extracted directories must be reset after they are populated (as
** populating them changes the timestamp). */
for(i=0; i<2; i++){
j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
sqlite3_bind_int(pSql, j, i);
if( pAr->bDryRun ){
oputf("%s\n", sqlite3_sql(pSql));
}else{
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
if( i==0 && pAr->bVerbose ){
oputf("%s\n", sqlite3_column_text(pSql, 0));
}
}
}
shellReset(&rc, pSql);
}
shellFinalize(&rc, pSql);
}
sqlite3_free(zDir);
sqlite3_free(zWhere);
return rc;
}
/*
** Run the SQL statement in zSql. Or if doing a --dryrun, merely print it out.
*/
static int arExecSql(ArCommand *pAr, const char *zSql){
int rc;
if( pAr->bDryRun ){
oputf("%s\n", zSql);
rc = SQLITE_OK;
}else{
char *zErr = 0;
rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
if( zErr ){
sputf(stdout, "ERROR: %s\n", zErr);
sqlite3_free(zErr);
}
}
return rc;
}
|
| ︙ | ︙ | |||
23598 23599 23600 23601 23602 23603 23604 |
|| cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){
flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
}else{
flags = SQLITE_OPEN_READONLY;
}
cmd.db = 0;
if( cmd.bDryRun ){
| | | < | < | | 24348 24349 24350 24351 24352 24353 24354 24355 24356 24357 24358 24359 24360 24361 24362 24363 24364 24365 24366 24367 24368 24369 24370 24371 24372 24373 24374 24375 24376 24377 24378 24379 24380 24381 |
|| cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){
flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
}else{
flags = SQLITE_OPEN_READONLY;
}
cmd.db = 0;
if( cmd.bDryRun ){
oputf("-- open database '%s'%s\n", cmd.zFile,
eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
}
rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags,
eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
if( rc!=SQLITE_OK ){
eputf("cannot open file: %s (%s)\n", cmd.zFile, sqlite3_errmsg(cmd.db));
goto end_ar_command;
}
sqlite3_fileio_init(cmd.db, 0, 0);
sqlite3_sqlar_init(cmd.db, 0, 0);
sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p,
shellPutsFunc, 0, 0);
}
if( cmd.zSrcTable==0 && cmd.bZip==0 && cmd.eCmd!=AR_CMD_HELP ){
if( cmd.eCmd!=AR_CMD_CREATE
&& sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
){
eputz("database does not contain an 'sqlar' table\n");
rc = SQLITE_ERROR;
goto end_ar_command;
}
cmd.zSrcTable = sqlite3_mprintf("sqlar");
}
switch( cmd.eCmd ){
|
| ︙ | ︙ | |||
23677 23678 23679 23680 23681 23682 23683 |
/*
** This function is used as a callback by the recover extension. Simply
** print the supplied SQL statement to stdout.
*/
static int recoverSqlCb(void *pCtx, const char *zSql){
ShellState *pState = (ShellState*)pCtx;
| | | 24425 24426 24427 24428 24429 24430 24431 24432 24433 24434 24435 24436 24437 24438 24439 |
/*
** This function is used as a callback by the recover extension. Simply
** print the supplied SQL statement to stdout.
*/
static int recoverSqlCb(void *pCtx, const char *zSql){
ShellState *pState = (ShellState*)pCtx;
sputf(pState->out, "%s;\n", zSql);
return SQLITE_OK;
}
/*
** This function is called to recover data from the database. A script
** to construct a new database containing all recovered data is output
** on stream pState->out.
|
| ︙ | ︙ | |||
23720 23721 23722 23723 23724 23725 23726 |
i++;
zLAF = azArg[i];
}else
if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
bRowids = 0;
}
else{
| | | | 24468 24469 24470 24471 24472 24473 24474 24475 24476 24477 24478 24479 24480 24481 24482 24483 24484 24485 24486 24487 24488 24489 24490 24491 24492 24493 24494 24495 24496 24497 24498 24499 24500 24501 |
i++;
zLAF = azArg[i];
}else
if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
bRowids = 0;
}
else{
eputf("unexpected option: %s\n", azArg[i]);
showHelp(pState->out, azArg[0]);
return 1;
}
}
p = sqlite3_recover_init_sql(
pState->db, "main", recoverSqlCb, (void*)pState
);
sqlite3_recover_config(p, 789, (void*)zRecoveryDb); /* Debug use only */
sqlite3_recover_config(p, SQLITE_RECOVER_LOST_AND_FOUND, (void*)zLAF);
sqlite3_recover_config(p, SQLITE_RECOVER_ROWIDS, (void*)&bRowids);
sqlite3_recover_config(p, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist);
sqlite3_recover_run(p);
if( sqlite3_recover_errcode(p)!=SQLITE_OK ){
const char *zErr = sqlite3_recover_errmsg(p);
int errCode = sqlite3_recover_errcode(p);
eputf("sql error: %s (%d)\n", zErr, errCode);
}
rc = sqlite3_recover_finish(p);
return rc;
}
#endif /* SQLITE_SHELL_HAVE_RECOVER */
|
| ︙ | ︙ | |||
23764 23765 23766 23767 23768 23769 23770 | * done if renaming was necessary, or set to 0 if none was done. The out * string (if any) must be sqlite3_free()'ed by the caller. */ #ifdef SHELL_DEBUG #define rc_err_oom_die(rc) \ if( rc==SQLITE_NOMEM ) shell_check_oom(0); \ else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \ | | | 24512 24513 24514 24515 24516 24517 24518 24519 24520 24521 24522 24523 24524 24525 24526 |
* done if renaming was necessary, or set to 0 if none was done. The out
* string (if any) must be sqlite3_free()'ed by the caller.
*/
#ifdef SHELL_DEBUG
#define rc_err_oom_die(rc) \
if( rc==SQLITE_NOMEM ) shell_check_oom(0); \
else if(!(rc==SQLITE_OK||rc==SQLITE_DONE)) \
eputf("E:%d\n",rc), assert(0)
#else
static void rc_err_oom_die(int rc){
if( rc==SQLITE_NOMEM ) shell_check_oom(0);
assert(rc==SQLITE_OK||rc==SQLITE_DONE);
}
#endif
|
| ︙ | ︙ | |||
23904 23905 23906 23907 23908 23909 23910 23911 23912 23913 23914 23915 23916 23917 |
if( *pDb==0 ){
if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0;
#ifdef SHELL_COLFIX_DB
if(*zCOL_DB!=':')
sqlite3_exec(*pDb,"drop table if exists ColNames;"
"drop view if exists RepeatedNames;",0,0,0);
#endif
rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0);
rc_err_oom_die(rc);
}
assert(*pDb!=0);
rc = sqlite3_prepare_v2(*pDb, zTabFill, -1, &pStmt, 0);
rc_err_oom_die(rc);
rc = sqlite3_bind_text(pStmt, 1, zColNew, -1, 0);
| > | 24652 24653 24654 24655 24656 24657 24658 24659 24660 24661 24662 24663 24664 24665 24666 |
if( *pDb==0 ){
if( SQLITE_OK!=sqlite3_open(zCOL_DB, pDb) ) return 0;
#ifdef SHELL_COLFIX_DB
if(*zCOL_DB!=':')
sqlite3_exec(*pDb,"drop table if exists ColNames;"
"drop view if exists RepeatedNames;",0,0,0);
#endif
#undef SHELL_COLFIX_DB
rc = sqlite3_exec(*pDb, zTabMake, 0, 0, 0);
rc_err_oom_die(rc);
}
assert(*pDb!=0);
rc = sqlite3_prepare_v2(*pDb, zTabFill, -1, &pStmt, 0);
rc_err_oom_die(rc);
rc = sqlite3_bind_text(pStmt, 1, zColNew, -1, 0);
|
| ︙ | ︙ | |||
24017 24018 24019 24020 24021 24022 24023 |
n = strlen30(azArg[0]);
c = azArg[0][0];
clearTempFile(p);
#ifndef SQLITE_OMIT_AUTHORIZATION
if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){
if( nArg!=2 ){
| | | 24766 24767 24768 24769 24770 24771 24772 24773 24774 24775 24776 24777 24778 24779 24780 |
n = strlen30(azArg[0]);
c = azArg[0][0];
clearTempFile(p);
#ifndef SQLITE_OMIT_AUTHORIZATION
if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){
if( nArg!=2 ){
eputz("Usage: .auth ON|OFF\n");
rc = 1;
goto meta_command_exit;
}
open_db(p, 0);
if( booleanValue(azArg[1]) ){
sqlite3_set_authorizer(p->db, shellAuth, p);
}else if( p->bSafeModePersist ){
|
| ︙ | ︙ | |||
24064 24065 24066 24067 24068 24069 24070 |
if( cli_strcmp(z, "-append")==0 ){
zVfs = "apndvfs";
}else
if( cli_strcmp(z, "-async")==0 ){
bAsync = 1;
}else
{
| | | | | | | | | < | | 24813 24814 24815 24816 24817 24818 24819 24820 24821 24822 24823 24824 24825 24826 24827 24828 24829 24830 24831 24832 24833 24834 24835 24836 24837 24838 24839 24840 24841 24842 24843 24844 24845 24846 24847 24848 24849 24850 24851 24852 24853 24854 24855 24856 24857 24858 24859 24860 24861 24862 24863 24864 24865 24866 24867 24868 24869 24870 24871 24872 24873 24874 24875 24876 24877 24878 24879 24880 24881 24882 24883 24884 24885 24886 24887 24888 24889 24890 24891 24892 24893 24894 |
if( cli_strcmp(z, "-append")==0 ){
zVfs = "apndvfs";
}else
if( cli_strcmp(z, "-async")==0 ){
bAsync = 1;
}else
{
eputf("unknown option: %s\n", azArg[j]);
return 1;
}
}else if( zDestFile==0 ){
zDestFile = azArg[j];
}else if( zDb==0 ){
zDb = zDestFile;
zDestFile = azArg[j];
}else{
eputz("Usage: .backup ?DB? ?OPTIONS? FILENAME\n");
return 1;
}
}
if( zDestFile==0 ){
eputz("missing FILENAME argument on .backup\n");
return 1;
}
if( zDb==0 ) zDb = "main";
rc = sqlite3_open_v2(zDestFile, &pDest,
SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, zVfs);
if( rc!=SQLITE_OK ){
eputf("Error: cannot open \"%s\"\n", zDestFile);
close_db(pDest);
return 1;
}
if( bAsync ){
sqlite3_exec(pDest, "PRAGMA synchronous=OFF; PRAGMA journal_mode=OFF;",
0, 0, 0);
}
open_db(p, 0);
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
if( pBackup==0 ){
eputf("Error: %s\n", sqlite3_errmsg(pDest));
close_db(pDest);
return 1;
}
while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
sqlite3_backup_finish(pBackup);
if( rc==SQLITE_DONE ){
rc = 0;
}else{
eputf("Error: %s\n", sqlite3_errmsg(pDest));
rc = 1;
}
close_db(pDest);
}else
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
if( c=='b' && n>=3 && cli_strncmp(azArg[0], "bail", n)==0 ){
if( nArg==2 ){
bail_on_error = booleanValue(azArg[1]);
}else{
eputz("Usage: .bail on|off\n");
rc = 1;
}
}else
/* Undocumented. Legacy only. See "crnl" below */
if( c=='b' && n>=3 && cli_strncmp(azArg[0], "binary", n)==0 ){
if( nArg==2 ){
if( booleanValue(azArg[1]) ){
setBinaryMode(p->out, 1);
}else{
setTextMode(p->out, 1);
}
}else{
eputz("The \".binary\" command is deprecated. Use \".crnl\" instead.\n"
"Usage: .binary on|off\n");
rc = 1;
}
}else
/* The undocumented ".breakpoint" command causes a call to the no-op
** routine named test_breakpoint().
*/
|
| ︙ | ︙ | |||
24156 24157 24158 24159 24160 24161 24162 |
wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
rc = !SetCurrentDirectoryW(z);
sqlite3_free(z);
#else
rc = chdir(azArg[1]);
#endif
if( rc ){
| | | | | < | | | | | | | | | | | | < < | | | 24904 24905 24906 24907 24908 24909 24910 24911 24912 24913 24914 24915 24916 24917 24918 24919 24920 24921 24922 24923 24924 24925 24926 24927 24928 24929 24930 24931 24932 24933 24934 24935 24936 24937 24938 24939 24940 24941 24942 24943 24944 24945 24946 24947 24948 24949 24950 24951 24952 24953 24954 24955 24956 24957 24958 24959 24960 24961 24962 24963 24964 24965 24966 24967 24968 24969 24970 24971 24972 24973 24974 24975 24976 24977 24978 24979 24980 24981 24982 24983 24984 24985 24986 24987 24988 24989 24990 24991 24992 24993 24994 24995 24996 24997 24998 24999 25000 25001 25002 25003 25004 25005 25006 25007 25008 25009 25010 25011 25012 25013 25014 25015 25016 25017 25018 25019 25020 25021 25022 25023 25024 25025 25026 25027 25028 25029 25030 25031 25032 25033 25034 25035 25036 25037 25038 25039 25040 25041 25042 25043 25044 25045 25046 25047 25048 25049 25050 25051 25052 25053 25054 25055 25056 25057 25058 25059 25060 25061 25062 25063 25064 25065 |
wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
rc = !SetCurrentDirectoryW(z);
sqlite3_free(z);
#else
rc = chdir(azArg[1]);
#endif
if( rc ){
eputf("Cannot change to directory \"%s\"\n", azArg[1]);
rc = 1;
}
}else{
eputz("Usage: .cd DIRECTORY\n");
rc = 1;
}
}else
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
if( c=='c' && n>=3 && cli_strncmp(azArg[0], "changes", n)==0 ){
if( nArg==2 ){
setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
}else{
eputz("Usage: .changes on|off\n");
rc = 1;
}
}else
#ifndef SQLITE_SHELL_FIDDLE
/* Cancel output redirection, if it is currently set (by .testcase)
** Then read the content of the testcase-out.txt file and compare against
** azArg[1]. If there are differences, report an error and exit.
*/
if( c=='c' && n>=3 && cli_strncmp(azArg[0], "check", n)==0 ){
char *zRes = 0;
output_reset(p);
if( nArg!=2 ){
eputz("Usage: .check GLOB-PATTERN\n");
rc = 2;
}else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
rc = 2;
}else if( testcase_glob(azArg[1],zRes)==0 ){
eputf("testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
p->zTestcase, azArg[1], zRes);
rc = 1;
}else{
oputf("testcase-%s ok\n", p->zTestcase);
p->nCheck++;
}
sqlite3_free(zRes);
}else
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
#ifndef SQLITE_SHELL_FIDDLE
if( c=='c' && cli_strncmp(azArg[0], "clone", n)==0 ){
failIfSafeMode(p, "cannot run .clone in safe mode");
if( nArg==2 ){
tryToClone(p, azArg[1]);
}else{
eputz("Usage: .clone FILENAME\n");
rc = 1;
}
}else
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
if( c=='c' && cli_strncmp(azArg[0], "connection", n)==0 ){
if( nArg==1 ){
/* List available connections */
int i;
for(i=0; i<ArraySize(p->aAuxDb); i++){
const char *zFile = p->aAuxDb[i].zDbFilename;
if( p->aAuxDb[i].db==0 && p->pAuxDb!=&p->aAuxDb[i] ){
zFile = "(not open)";
}else if( zFile==0 ){
zFile = "(memory)";
}else if( zFile[0]==0 ){
zFile = "(temporary-file)";
}
if( p->pAuxDb == &p->aAuxDb[i] ){
sputf(stdout, "ACTIVE %d: %s\n", i, zFile);
}else if( p->aAuxDb[i].db!=0 ){
sputf(stdout, " %d: %s\n", i, zFile);
}
}
}else if( nArg==2 && IsDigit(azArg[1][0]) && azArg[1][1]==0 ){
int i = azArg[1][0] - '0';
if( p->pAuxDb != &p->aAuxDb[i] && i>=0 && i<ArraySize(p->aAuxDb) ){
p->pAuxDb->db = p->db;
p->pAuxDb = &p->aAuxDb[i];
globalDb = p->db = p->pAuxDb->db;
p->pAuxDb->db = 0;
}
}else if( nArg==3 && cli_strcmp(azArg[1], "close")==0
&& IsDigit(azArg[2][0]) && azArg[2][1]==0 ){
int i = azArg[2][0] - '0';
if( i<0 || i>=ArraySize(p->aAuxDb) ){
/* No-op */
}else if( p->pAuxDb == &p->aAuxDb[i] ){
eputz("cannot close the active database connection\n");
rc = 1;
}else if( p->aAuxDb[i].db ){
session_close_all(p, i);
close_db(p->aAuxDb[i].db);
p->aAuxDb[i].db = 0;
}
}else{
eputz("Usage: .connection [close] [CONNECTION-NUMBER]\n");
rc = 1;
}
}else
if( c=='c' && n==4 && cli_strncmp(azArg[0], "crnl", n)==0 ){
if( nArg==2 ){
if( booleanValue(azArg[1]) ){
setTextMode(p->out, 1);
}else{
setBinaryMode(p->out, 1);
}
}else{
#if !defined(_WIN32) && !defined(WIN32)
eputz("The \".crnl\" is a no-op on non-Windows machines.\n");
#endif
eputz("Usage: .crnl on|off\n");
rc = 1;
}
}else
if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){
char **azName = 0;
int nName = 0;
sqlite3_stmt *pStmt;
int i;
open_db(p, 0);
rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
if( rc ){
eputf("Error: %s\n", sqlite3_errmsg(p->db));
rc = 1;
}else{
while( sqlite3_step(pStmt)==SQLITE_ROW ){
const char *zSchema = (const char *)sqlite3_column_text(pStmt,1);
const char *zFile = (const char*)sqlite3_column_text(pStmt,2);
if( zSchema==0 || zFile==0 ) continue;
azName = sqlite3_realloc(azName, (nName+1)*2*sizeof(char*));
shell_check_oom(azName);
azName[nName*2] = strdup(zSchema);
azName[nName*2+1] = strdup(zFile);
nName++;
}
}
sqlite3_finalize(pStmt);
for(i=0; i<nName; i++){
int eTxn = sqlite3_txn_state(p->db, azName[i*2]);
int bRdonly = sqlite3_db_readonly(p->db, azName[i*2]);
const char *z = azName[i*2+1];
oputf("%s: %s %s%s\n",
azName[i*2], z && z[0] ? z : "\"\"", bRdonly ? "r/o" : "r/w",
eTxn==SQLITE_TXN_NONE ? "" :
eTxn==SQLITE_TXN_READ ? " read-txn" : " write-txn");
free(azName[i*2]);
free(azName[i*2+1]);
}
sqlite3_free(azName);
}else
|
| ︙ | ︙ | |||
24346 24347 24348 24349 24350 24351 24352 |
open_db(p, 0);
for(ii=0; ii<ArraySize(aDbConfig); ii++){
if( nArg>1 && cli_strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
if( nArg>=3 ){
sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
}
sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
| | | | | 25091 25092 25093 25094 25095 25096 25097 25098 25099 25100 25101 25102 25103 25104 25105 25106 25107 25108 25109 25110 |
open_db(p, 0);
for(ii=0; ii<ArraySize(aDbConfig); ii++){
if( nArg>1 && cli_strcmp(azArg[1], aDbConfig[ii].zName)!=0 ) continue;
if( nArg>=3 ){
sqlite3_db_config(p->db, aDbConfig[ii].op, booleanValue(azArg[2]), 0);
}
sqlite3_db_config(p->db, aDbConfig[ii].op, -1, &v);
oputf("%19s %s\n", aDbConfig[ii].zName, v ? "on" : "off");
if( nArg>1 ) break;
}
if( nArg>1 && ii==ArraySize(aDbConfig) ){
eputf("Error: unknown dbconfig \"%s\"\n", azArg[1]);
eputz("Enter \".dbconfig\" with no arguments for a list\n");
}
}else
#if SQLITE_SHELL_HAVE_RECOVER
if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbinfo", n)==0 ){
rc = shell_dbinfo_command(p, nArg, azArg);
}else
|
| ︙ | ︙ | |||
24381 24382 24383 24384 24385 24386 24387 |
|SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
for(i=1; i<nArg; i++){
if( azArg[i][0]=='-' ){
const char *z = azArg[i]+1;
if( z[0]=='-' ) z++;
if( cli_strcmp(z,"preserve-rowids")==0 ){
#ifdef SQLITE_OMIT_VIRTUALTABLE
| | | | | 25126 25127 25128 25129 25130 25131 25132 25133 25134 25135 25136 25137 25138 25139 25140 25141 25142 25143 25144 25145 25146 25147 25148 25149 25150 25151 25152 25153 25154 25155 25156 25157 25158 25159 |
|SHFLG_DumpDataOnly|SHFLG_DumpNoSys);
for(i=1; i<nArg; i++){
if( azArg[i][0]=='-' ){
const char *z = azArg[i]+1;
if( z[0]=='-' ) z++;
if( cli_strcmp(z,"preserve-rowids")==0 ){
#ifdef SQLITE_OMIT_VIRTUALTABLE
eputz("The --preserve-rowids option is not compatible"
" with SQLITE_OMIT_VIRTUALTABLE\n");
rc = 1;
sqlite3_free(zLike);
goto meta_command_exit;
#else
ShellSetFlag(p, SHFLG_PreserveRowid);
#endif
}else
if( cli_strcmp(z,"newlines")==0 ){
ShellSetFlag(p, SHFLG_Newlines);
}else
if( cli_strcmp(z,"data-only")==0 ){
ShellSetFlag(p, SHFLG_DumpDataOnly);
}else
if( cli_strcmp(z,"nosys")==0 ){
ShellSetFlag(p, SHFLG_DumpNoSys);
}else
{
eputf("Unknown option \"%s\" on \".dump\"\n", azArg[i]);
rc = 1;
sqlite3_free(zLike);
goto meta_command_exit;
}
}else{
/* azArg[i] contains a LIKE pattern. This ".dump" request should
** only dump data for tables for which either the table name matches
|
| ︙ | ︙ | |||
24434 24435 24436 24437 24438 24439 24440 |
open_db(p, 0);
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
/* When playing back a "dump", the content might appear in an order
** which causes immediate foreign key constraints to be violated.
** So disable foreign-key constraint enforcement to prevent problems. */
| | | | 25179 25180 25181 25182 25183 25184 25185 25186 25187 25188 25189 25190 25191 25192 25193 25194 |
open_db(p, 0);
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
/* When playing back a "dump", the content might appear in an order
** which causes immediate foreign key constraints to be violated.
** So disable foreign-key constraint enforcement to prevent problems. */
oputz("PRAGMA foreign_keys=OFF;\n");
oputz("BEGIN TRANSACTION;\n");
}
p->writableSchema = 0;
p->showHeader = 0;
/* Set writable_schema=ON since doing so forces SQLite to initialize
** as much of the schema as it can even if the sqlite_schema table is
** corrupt. */
sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
|
| ︙ | ︙ | |||
24466 24467 24468 24469 24470 24471 24472 |
zLike
);
run_table_dump_query(p, zSql);
sqlite3_free(zSql);
}
sqlite3_free(zLike);
if( p->writableSchema ){
| | | | | 25211 25212 25213 25214 25215 25216 25217 25218 25219 25220 25221 25222 25223 25224 25225 25226 25227 25228 25229 25230 25231 25232 25233 25234 25235 25236 25237 25238 25239 25240 25241 |
zLike
);
run_table_dump_query(p, zSql);
sqlite3_free(zSql);
}
sqlite3_free(zLike);
if( p->writableSchema ){
oputz("PRAGMA writable_schema=OFF;\n");
p->writableSchema = 0;
}
sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
oputz(p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
}
p->showHeader = savedShowHeader;
p->shellFlgs = savedShellFlags;
}else
if( c=='e' && cli_strncmp(azArg[0], "echo", n)==0 ){
if( nArg==2 ){
setOrClearFlag(p, SHFLG_Echo, azArg[1]);
}else{
eputz("Usage: .echo on|off\n");
rc = 1;
}
}else
if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){
if( nArg==2 ){
p->autoEQPtest = 0;
|
| ︙ | ︙ | |||
24513 24514 24515 24516 24517 24518 24519 |
sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1", 0, 0, 0);
sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;", 0, 0, 0);
#endif
}else{
p->autoEQP = (u8)booleanValue(azArg[1]);
}
}else{
| | | 25258 25259 25260 25261 25262 25263 25264 25265 25266 25267 25268 25269 25270 25271 25272 |
sqlite3_exec(p->db, "SELECT name FROM sqlite_schema LIMIT 1", 0, 0, 0);
sqlite3_exec(p->db, "PRAGMA vdbe_trace=ON;", 0, 0, 0);
#endif
}else{
p->autoEQP = (u8)booleanValue(azArg[1]);
}
}else{
eputz("Usage: .eqp off|on|trace|trigger|full\n");
rc = 1;
}
}else
#ifndef SQLITE_SHELL_FIDDLE
if( c=='e' && cli_strncmp(azArg[0], "exit", n)==0 ){
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
|
| ︙ | ︙ | |||
24552 24553 24554 24555 24556 24557 24558 |
p->autoExplain = 1;
}
}else
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){
if( p->bSafeMode ){
| < | | | 25297 25298 25299 25300 25301 25302 25303 25304 25305 25306 25307 25308 25309 25310 25311 25312 |
p->autoExplain = 1;
}
}else
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){
if( p->bSafeMode ){
eputf("Cannot run experimental commands such as \"%s\" in safe mode\n",
azArg[0]);
rc = 1;
}else{
open_db(p, 0);
expertDotCommand(p, azArg, nArg);
}
}else
#endif
|
| ︙ | ︙ | |||
24610 24611 24612 24613 24614 24615 24616 |
if( zCmd[0]=='-' && zCmd[1] ){
zCmd++;
if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
}
/* --help lists all file-controls */
if( cli_strcmp(zCmd,"help")==0 ){
| | < | | | | | | 25354 25355 25356 25357 25358 25359 25360 25361 25362 25363 25364 25365 25366 25367 25368 25369 25370 25371 25372 25373 25374 25375 25376 25377 25378 25379 25380 25381 25382 25383 25384 25385 25386 25387 25388 25389 25390 25391 25392 25393 25394 |
if( zCmd[0]=='-' && zCmd[1] ){
zCmd++;
if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
}
/* --help lists all file-controls */
if( cli_strcmp(zCmd,"help")==0 ){
oputz("Available file-controls:\n");
for(i=0; i<ArraySize(aCtrl); i++){
oputf(" .filectrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage);
}
rc = 1;
goto meta_command_exit;
}
/* convert filectrl text option to value. allow any unique prefix
** of the option name, or a numerical value. */
n2 = strlen30(zCmd);
for(i=0; i<ArraySize(aCtrl); i++){
if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
if( filectrl<0 ){
filectrl = aCtrl[i].ctrlCode;
iCtrl = i;
}else{
eputf("Error: ambiguous file-control: \"%s\"\n"
"Use \".filectrl --help\" for help\n", zCmd);
rc = 1;
goto meta_command_exit;
}
}
}
if( filectrl<0 ){
eputf("Error: unknown file-control: %s\n"
"Use \".filectrl --help\" for help\n", zCmd);
}else{
switch(filectrl){
case SQLITE_FCNTL_SIZE_LIMIT: {
if( nArg!=2 && nArg!=3 ) break;
iRes = nArg==3 ? integerValue(azArg[2]) : -1;
sqlite3_file_control(p->db, zSchema, SQLITE_FCNTL_SIZE_LIMIT, &iRes);
isOk = 1;
|
| ︙ | ︙ | |||
24680 24681 24682 24683 24684 24685 24686 |
break;
}
case SQLITE_FCNTL_TEMPFILENAME: {
char *z = 0;
if( nArg!=2 ) break;
sqlite3_file_control(p->db, zSchema, filectrl, &z);
if( z ){
| | | | | | | 25423 25424 25425 25426 25427 25428 25429 25430 25431 25432 25433 25434 25435 25436 25437 25438 25439 25440 25441 25442 25443 25444 25445 25446 25447 25448 25449 25450 25451 25452 25453 25454 25455 25456 25457 25458 25459 25460 25461 25462 25463 25464 25465 25466 25467 25468 25469 25470 25471 25472 25473 25474 25475 25476 25477 25478 |
break;
}
case SQLITE_FCNTL_TEMPFILENAME: {
char *z = 0;
if( nArg!=2 ) break;
sqlite3_file_control(p->db, zSchema, filectrl, &z);
if( z ){
oputf("%s\n", z);
sqlite3_free(z);
}
isOk = 2;
break;
}
case SQLITE_FCNTL_RESERVE_BYTES: {
int x;
if( nArg>=3 ){
x = atoi(azArg[2]);
sqlite3_file_control(p->db, zSchema, filectrl, &x);
}
x = -1;
sqlite3_file_control(p->db, zSchema, filectrl, &x);
oputf("%d\n", x);
isOk = 2;
break;
}
}
}
if( isOk==0 && iCtrl>=0 ){
oputf("Usage: .filectrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
rc = 1;
}else if( isOk==1 ){
char zBuf[100];
sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes);
oputf("%s\n", zBuf);
}
}else
if( c=='f' && cli_strncmp(azArg[0], "fullschema", n)==0 ){
ShellState data;
int doStats = 0;
memcpy(&data, p, sizeof(data));
data.showHeader = 0;
data.cMode = data.mode = MODE_Semi;
if( nArg==2 && optionMatch(azArg[1], "indent") ){
data.cMode = data.mode = MODE_Pretty;
nArg = 1;
}
if( nArg!=1 ){
eputz("Usage: .fullschema ?--indent?\n");
rc = 1;
goto meta_command_exit;
}
open_db(p, 0);
rc = sqlite3_exec(p->db,
"SELECT sql FROM"
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
|
| ︙ | ︙ | |||
24747 24748 24749 24750 24751 24752 24753 |
-1, &pStmt, 0);
if( rc==SQLITE_OK ){
doStats = sqlite3_step(pStmt)==SQLITE_ROW;
sqlite3_finalize(pStmt);
}
}
if( doStats==0 ){
| | | | | | | 25490 25491 25492 25493 25494 25495 25496 25497 25498 25499 25500 25501 25502 25503 25504 25505 25506 25507 25508 25509 25510 25511 25512 25513 25514 25515 25516 25517 25518 25519 25520 25521 25522 25523 25524 25525 25526 25527 25528 25529 25530 |
-1, &pStmt, 0);
if( rc==SQLITE_OK ){
doStats = sqlite3_step(pStmt)==SQLITE_ROW;
sqlite3_finalize(pStmt);
}
}
if( doStats==0 ){
oputz("/* No STAT tables available */\n");
}else{
oputz("ANALYZE sqlite_schema;\n");
data.cMode = data.mode = MODE_Insert;
data.zDestTable = "sqlite_stat1";
shell_exec(&data, "SELECT * FROM sqlite_stat1", 0);
data.zDestTable = "sqlite_stat4";
shell_exec(&data, "SELECT * FROM sqlite_stat4", 0);
oputz("ANALYZE sqlite_schema;\n");
}
}else
if( c=='h' && cli_strncmp(azArg[0], "headers", n)==0 ){
if( nArg==2 ){
p->showHeader = booleanValue(azArg[1]);
p->shellFlgs |= SHFLG_HeaderSet;
}else{
eputz("Usage: .headers on|off\n");
rc = 1;
}
}else
if( c=='h' && cli_strncmp(azArg[0], "help", n)==0 ){
if( nArg>=2 ){
n = showHelp(p->out, azArg[1]);
if( n==0 ){
oputf("Nothing matches '%s'\n", azArg[1]);
}
}else{
showHelp(p->out, 0);
}
}else
#ifndef SQLITE_SHELL_FIDDLE
|
| ︙ | ︙ | |||
24817 24818 24819 24820 24821 24822 24823 |
if( z[0]=='-' && z[1]=='-' ) z++;
if( z[0]!='-' ){
if( zFile==0 ){
zFile = z;
}else if( zTable==0 ){
zTable = z;
}else{
| | | | | < | < | < | | | | | | | | | | | 25560 25561 25562 25563 25564 25565 25566 25567 25568 25569 25570 25571 25572 25573 25574 25575 25576 25577 25578 25579 25580 25581 25582 25583 25584 25585 25586 25587 25588 25589 25590 25591 25592 25593 25594 25595 25596 25597 25598 25599 25600 25601 25602 25603 25604 25605 25606 25607 25608 25609 25610 25611 25612 25613 25614 25615 25616 25617 25618 25619 25620 25621 25622 25623 25624 25625 25626 25627 25628 25629 25630 25631 25632 25633 25634 25635 25636 25637 25638 25639 25640 25641 25642 25643 25644 25645 25646 25647 25648 25649 25650 25651 25652 25653 25654 25655 25656 25657 25658 25659 25660 25661 25662 25663 25664 25665 25666 25667 25668 25669 25670 25671 25672 |
if( z[0]=='-' && z[1]=='-' ) z++;
if( z[0]!='-' ){
if( zFile==0 ){
zFile = z;
}else if( zTable==0 ){
zTable = z;
}else{
oputf("ERROR: extra argument: \"%s\". Usage:\n", z);
showHelp(p->out, "import");
goto meta_command_exit;
}
}else if( cli_strcmp(z,"-v")==0 ){
eVerbose++;
}else if( cli_strcmp(z,"-schema")==0 && i<nArg-1 ){
zSchema = azArg[++i];
}else if( cli_strcmp(z,"-skip")==0 && i<nArg-1 ){
nSkip = integerValue(azArg[++i]);
}else if( cli_strcmp(z,"-ascii")==0 ){
sCtx.cColSep = SEP_Unit[0];
sCtx.cRowSep = SEP_Record[0];
xRead = ascii_read_one_field;
useOutputMode = 0;
}else if( cli_strcmp(z,"-csv")==0 ){
sCtx.cColSep = ',';
sCtx.cRowSep = '\n';
xRead = csv_read_one_field;
useOutputMode = 0;
}else{
oputf("ERROR: unknown option: \"%s\". Usage:\n", z);
showHelp(p->out, "import");
goto meta_command_exit;
}
}
if( zTable==0 ){
oputf("ERROR: missing %s argument. Usage:\n",
zFile==0 ? "FILE" : "TABLE");
showHelp(p->out, "import");
goto meta_command_exit;
}
seenInterrupt = 0;
open_db(p, 0);
if( useOutputMode ){
/* If neither the --csv or --ascii options are specified, then set
** the column and row separator characters from the output mode. */
nSep = strlen30(p->colSeparator);
if( nSep==0 ){
eputz("Error: non-null column separator required for import\n");
goto meta_command_exit;
}
if( nSep>1 ){
eputz("Error: multi-character column separators not allowed"
" for import\n");
goto meta_command_exit;
}
nSep = strlen30(p->rowSeparator);
if( nSep==0 ){
eputz("Error: non-null row separator required for import\n");
goto meta_command_exit;
}
if( nSep==2 && p->mode==MODE_Csv
&& cli_strcmp(p->rowSeparator,SEP_CrLf)==0
){
/* When importing CSV (only), if the row separator is set to the
** default output row separator, change it to the default input
** row separator. This avoids having to maintain different input
** and output row separators. */
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
nSep = strlen30(p->rowSeparator);
}
if( nSep>1 ){
eputz("Error: multi-character row separators not allowed"
" for import\n");
goto meta_command_exit;
}
sCtx.cColSep = (u8)p->colSeparator[0];
sCtx.cRowSep = (u8)p->rowSeparator[0];
}
sCtx.zFile = zFile;
sCtx.nLine = 1;
if( sCtx.zFile[0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
eputz("Error: pipes are not supported in this OS\n");
goto meta_command_exit;
#else
sCtx.in = popen(sCtx.zFile+1, "r");
sCtx.zFile = "<pipe>";
sCtx.xCloser = pclose;
#endif
}else{
sCtx.in = fopen(sCtx.zFile, "rb");
sCtx.xCloser = fclose;
}
if( sCtx.in==0 ){
eputf("Error: cannot open \"%s\"\n", zFile);
goto meta_command_exit;
}
if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
char zSep[2];
zSep[1] = 0;
zSep[0] = sCtx.cColSep;
oputz("Column separator ");
output_c_string(zSep);
oputz(", row separator ");
zSep[0] = sCtx.cRowSep;
output_c_string(zSep);
oputz("\n");
}
sCtx.z = sqlite3_malloc64(120);
if( sCtx.z==0 ){
import_cleanup(&sCtx);
shell_out_of_memory();
}
/* Below, resources must be freed before exit. */
|
| ︙ | ︙ | |||
24953 24954 24955 24956 24957 24958 24959 |
zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName);
while( xRead(&sCtx) ){
zAutoColumn(sCtx.z, &dbCols, 0);
if( sCtx.cTerm!=sCtx.cColSep ) break;
}
zColDefs = zAutoColumn(0, &dbCols, &zRenames);
if( zRenames!=0 ){
| | | | | | | | | 25693 25694 25695 25696 25697 25698 25699 25700 25701 25702 25703 25704 25705 25706 25707 25708 25709 25710 25711 25712 25713 25714 25715 25716 25717 25718 25719 25720 25721 25722 25723 25724 25725 25726 25727 25728 25729 25730 25731 25732 25733 25734 25735 25736 25737 25738 |
zCreate = sqlite3_mprintf("CREATE TABLE %s", zFullTabName);
while( xRead(&sCtx) ){
zAutoColumn(sCtx.z, &dbCols, 0);
if( sCtx.cTerm!=sCtx.cColSep ) break;
}
zColDefs = zAutoColumn(0, &dbCols, &zRenames);
if( zRenames!=0 ){
sputf((stdin_is_interactive && p->in==stdin)? p->out : stderr,
"Columns renamed during .import %s due to duplicates:\n"
"%s\n", sCtx.zFile, zRenames);
sqlite3_free(zRenames);
}
assert(dbCols==0);
if( zColDefs==0 ){
eputf("%s: empty file\n", sCtx.zFile);
import_fail:
sqlite3_free(zCreate);
sqlite3_free(zSql);
sqlite3_free(zFullTabName);
import_cleanup(&sCtx);
rc = 1;
goto meta_command_exit;
}
zCreate = sqlite3_mprintf("%z%z\n", zCreate, zColDefs);
if( eVerbose>=1 ){
oputf("%s\n", zCreate);
}
rc = sqlite3_exec(p->db, zCreate, 0, 0, 0);
if( rc ){
eputf("%s failed:\n%s\n", zCreate, sqlite3_errmsg(p->db));
goto import_fail;
}
sqlite3_free(zCreate);
zCreate = 0;
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
}
if( rc ){
if (pStmt) sqlite3_finalize(pStmt);
eputf("Error: %s\n", sqlite3_errmsg(p->db));
goto import_fail;
}
sqlite3_free(zSql);
nCol = sqlite3_column_count(pStmt);
sqlite3_finalize(pStmt);
pStmt = 0;
if( nCol==0 ) return 0; /* no columns, no error */
|
| ︙ | ︙ | |||
25006 25007 25008 25009 25010 25011 25012 |
for(i=1; i<nCol; i++){
zSql[j++] = ',';
zSql[j++] = '?';
}
zSql[j++] = ')';
zSql[j] = 0;
if( eVerbose>=2 ){
| | | | 25746 25747 25748 25749 25750 25751 25752 25753 25754 25755 25756 25757 25758 25759 25760 25761 25762 25763 25764 |
for(i=1; i<nCol; i++){
zSql[j++] = ',';
zSql[j++] = '?';
}
zSql[j++] = ')';
zSql[j] = 0;
if( eVerbose>=2 ){
oputf("Insert using: %s\n", zSql);
}
rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
if( rc ){
eputf("Error: %s\n", sqlite3_errmsg(p->db));
if (pStmt) sqlite3_finalize(pStmt);
goto import_fail;
}
sqlite3_free(zSql);
sqlite3_free(zFullTabName);
needCommit = sqlite3_get_autocommit(p->db);
if( needCommit ) sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
|
| ︙ | ︙ | |||
25043 25044 25045 25046 25047 25048 25049 |
** (If there are too few fields, it's not valid CSV anyway.)
*/
if( z==0 && (xRead==csv_read_one_field) && i==nCol-1 && i>0 ){
z = "";
}
sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
| | | | | < | | | < | | | | | | | 25783 25784 25785 25786 25787 25788 25789 25790 25791 25792 25793 25794 25795 25796 25797 25798 25799 25800 25801 25802 25803 25804 25805 25806 25807 25808 25809 25810 25811 25812 25813 25814 25815 25816 25817 25818 25819 25820 25821 25822 25823 25824 25825 25826 25827 25828 25829 25830 25831 25832 25833 25834 25835 25836 25837 25838 25839 25840 25841 25842 25843 25844 25845 25846 25847 25848 25849 25850 25851 25852 |
** (If there are too few fields, it's not valid CSV anyway.)
*/
if( z==0 && (xRead==csv_read_one_field) && i==nCol-1 && i>0 ){
z = "";
}
sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
eputf("%s:%d: expected %d columns but found %d"
" - filling the rest with NULL\n",
sCtx.zFile, startLine, nCol, i+1);
i += 2;
while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
}
}
if( sCtx.cTerm==sCtx.cColSep ){
do{
xRead(&sCtx);
i++;
}while( sCtx.cTerm==sCtx.cColSep );
eputf("%s:%d: expected %d columns but found %d - extras ignored\n",
sCtx.zFile, startLine, nCol, i);
}
if( i>=nCol ){
sqlite3_step(pStmt);
rc = sqlite3_reset(pStmt);
if( rc!=SQLITE_OK ){
eputf("%s:%d: INSERT failed: %s\n",
sCtx.zFile, startLine, sqlite3_errmsg(p->db));
sCtx.nErr++;
}else{
sCtx.nRow++;
}
}
}while( sCtx.cTerm!=EOF );
import_cleanup(&sCtx);
sqlite3_finalize(pStmt);
if( needCommit ) sqlite3_exec(p->db, "COMMIT", 0, 0, 0);
if( eVerbose>0 ){
oputf("Added %d rows with %d errors using %d lines of input\n",
sCtx.nRow, sCtx.nErr, sCtx.nLine-1);
}
}else
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
#ifndef SQLITE_UNTESTABLE
if( c=='i' && cli_strncmp(azArg[0], "imposter", n)==0 ){
char *zSql;
char *zCollist = 0;
sqlite3_stmt *pStmt;
int tnum = 0;
int isWO = 0; /* True if making an imposter of a WITHOUT ROWID table */
int lenPK = 0; /* Length of the PRIMARY KEY string for isWO tables */
int i;
if( !ShellHasFlag(p,SHFLG_TestingMode) ){
eputf(".%s unavailable without --unsafe-testing\n",
"imposter");
rc = 1;
goto meta_command_exit;
}
if( !(nArg==3 || (nArg==2 && sqlite3_stricmp(azArg[1],"off")==0)) ){
eputz("Usage: .imposter INDEX IMPOSTER\n"
" .imposter off\n");
/* Also allowed, but not documented:
**
** .imposter TABLE IMPOSTER
**
** where TABLE is a WITHOUT ROWID table. In that case, the
** imposter is another WITHOUT ROWID table with the columns in
** storage order. */
|
| ︙ | ︙ | |||
25159 25160 25161 25162 25163 25164 25165 |
zCollist = sqlite3_mprintf("\"%w\"", zCol);
}else{
zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
}
}
sqlite3_finalize(pStmt);
if( i==0 || tnum==0 ){
| | | | < | | < | | | 25897 25898 25899 25900 25901 25902 25903 25904 25905 25906 25907 25908 25909 25910 25911 25912 25913 25914 25915 25916 25917 25918 25919 25920 25921 25922 25923 25924 25925 25926 25927 25928 25929 25930 25931 25932 25933 25934 25935 25936 25937 25938 25939 25940 25941 25942 25943 25944 25945 25946 25947 25948 25949 25950 25951 25952 25953 |
zCollist = sqlite3_mprintf("\"%w\"", zCol);
}else{
zCollist = sqlite3_mprintf("%z,\"%w\"", zCollist, zCol);
}
}
sqlite3_finalize(pStmt);
if( i==0 || tnum==0 ){
eputf("no such index: \"%s\"\n", azArg[1]);
rc = 1;
sqlite3_free(zCollist);
goto meta_command_exit;
}
if( lenPK==0 ) lenPK = 100000;
zSql = sqlite3_mprintf(
"CREATE TABLE \"%w\"(%s,PRIMARY KEY(%.*s))WITHOUT ROWID",
azArg[2], zCollist, lenPK, zCollist);
sqlite3_free(zCollist);
rc = sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 1, tnum);
if( rc==SQLITE_OK ){
rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 0);
if( rc ){
eputf("Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
}else{
sputf(stdout, "%s;\n", zSql);
sputf(stdout, "WARNING: writing to an imposter table will corrupt"
" the \"%s\" %s!\n", azArg[1], isWO ? "table" : "index");
}
}else{
eputf("SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
rc = 1;
}
sqlite3_free(zSql);
}else
#endif /* !defined(SQLITE_OMIT_TEST_CONTROL) */
#ifdef SQLITE_ENABLE_IOTRACE
if( c=='i' && cli_strncmp(azArg[0], "iotrace", n)==0 ){
SQLITE_API extern void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...);
if( iotrace && iotrace!=stdout ) fclose(iotrace);
iotrace = 0;
if( nArg<2 ){
sqlite3IoTrace = 0;
}else if( cli_strcmp(azArg[1], "-")==0 ){
sqlite3IoTrace = iotracePrintf;
iotrace = stdout;
}else{
iotrace = fopen(azArg[1], "w");
if( iotrace==0 ){
eputf("Error: cannot open \"%s\"\n", azArg[1]);
sqlite3IoTrace = 0;
rc = 1;
}else{
sqlite3IoTrace = iotracePrintf;
}
}
}else
|
| ︙ | ︙ | |||
25235 25236 25237 25238 25239 25240 25241 |
{ "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
{ "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
};
int i, n2;
open_db(p, 0);
if( nArg==1 ){
for(i=0; i<ArraySize(aLimit); i++){
| | | | | | | | | | | | | | | | 25971 25972 25973 25974 25975 25976 25977 25978 25979 25980 25981 25982 25983 25984 25985 25986 25987 25988 25989 25990 25991 25992 25993 25994 25995 25996 25997 25998 25999 26000 26001 26002 26003 26004 26005 26006 26007 26008 26009 26010 26011 26012 26013 26014 26015 26016 26017 26018 26019 26020 26021 26022 26023 26024 26025 26026 26027 26028 26029 26030 26031 26032 26033 26034 26035 26036 26037 26038 26039 26040 26041 26042 26043 26044 26045 26046 26047 26048 26049 26050 26051 26052 26053 26054 26055 26056 26057 26058 26059 26060 26061 |
{ "trigger_depth", SQLITE_LIMIT_TRIGGER_DEPTH },
{ "worker_threads", SQLITE_LIMIT_WORKER_THREADS },
};
int i, n2;
open_db(p, 0);
if( nArg==1 ){
for(i=0; i<ArraySize(aLimit); i++){
sputf(stdout, "%20s %d\n", aLimit[i].zLimitName,
sqlite3_limit(p->db, aLimit[i].limitCode, -1));
}
}else if( nArg>3 ){
eputz("Usage: .limit NAME ?NEW-VALUE?\n");
rc = 1;
goto meta_command_exit;
}else{
int iLimit = -1;
n2 = strlen30(azArg[1]);
for(i=0; i<ArraySize(aLimit); i++){
if( sqlite3_strnicmp(aLimit[i].zLimitName, azArg[1], n2)==0 ){
if( iLimit<0 ){
iLimit = i;
}else{
eputf("ambiguous limit: \"%s\"\n", azArg[1]);
rc = 1;
goto meta_command_exit;
}
}
}
if( iLimit<0 ){
eputf("unknown limit: \"%s\"\n"
"enter \".limits\" with no arguments for a list.\n",
azArg[1]);
rc = 1;
goto meta_command_exit;
}
if( nArg==3 ){
sqlite3_limit(p->db, aLimit[iLimit].limitCode,
(int)integerValue(azArg[2]));
}
sputf(stdout, "%20s %d\n", aLimit[iLimit].zLimitName,
sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
}
}else
if( c=='l' && n>2 && cli_strncmp(azArg[0], "lint", n)==0 ){
open_db(p, 0);
lintDotCommand(p, azArg, nArg);
}else
#if !defined(SQLITE_OMIT_LOAD_EXTENSION) && !defined(SQLITE_SHELL_FIDDLE)
if( c=='l' && cli_strncmp(azArg[0], "load", n)==0 ){
const char *zFile, *zProc;
char *zErrMsg = 0;
failIfSafeMode(p, "cannot run .load in safe mode");
if( nArg<2 || azArg[1][0]==0 ){
/* Must have a non-empty FILE. (Will not load self.) */
eputz("Usage: .load FILE ?ENTRYPOINT?\n");
rc = 1;
goto meta_command_exit;
}
zFile = azArg[1];
zProc = nArg>=3 ? azArg[2] : 0;
open_db(p, 0);
rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
if( rc!=SQLITE_OK ){
eputf("Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
rc = 1;
}
}else
#endif
if( c=='l' && cli_strncmp(azArg[0], "log", n)==0 ){
if( nArg!=2 ){
eputz("Usage: .log FILENAME\n");
rc = 1;
}else{
const char *zFile = azArg[1];
if( p->bSafeMode
&& cli_strcmp(zFile,"on")!=0
&& cli_strcmp(zFile,"off")!=0
){
sputz(stdout, "cannot set .log to anything other"
" than \"on\" or \"off\"\n");
zFile = "off";
}
output_file_close(p->pLog);
if( cli_strcmp(zFile,"on")==0 ) zFile = "stdout";
p->pLog = output_file_open(zFile, 0);
}
}else
|
| ︙ | ︙ | |||
25350 25351 25352 25353 25354 25355 25356 |
ColModeOpts cmo = ColModeOpts_default_qbox;
zMode = "box";
cmOpts = cmo;
}
}else if( zTabname==0 ){
zTabname = z;
}else if( z[0]=='-' ){
| | | | | | | | | < < | | | | | | 26086 26087 26088 26089 26090 26091 26092 26093 26094 26095 26096 26097 26098 26099 26100 26101 26102 26103 26104 26105 26106 26107 26108 26109 26110 26111 26112 26113 26114 26115 26116 26117 26118 26119 26120 26121 26122 26123 26124 |
ColModeOpts cmo = ColModeOpts_default_qbox;
zMode = "box";
cmOpts = cmo;
}
}else if( zTabname==0 ){
zTabname = z;
}else if( z[0]=='-' ){
eputf("unknown option: %s\n", z);
eputz("options:\n"
" --noquote\n"
" --quote\n"
" --wordwrap on/off\n"
" --wrap N\n"
" --ww\n");
rc = 1;
goto meta_command_exit;
}else{
eputf("extra argument: \"%s\"\n", z);
rc = 1;
goto meta_command_exit;
}
}
if( zMode==0 ){
if( p->mode==MODE_Column
|| (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
){
oputf("current output mode: %s --wrap %d --wordwrap %s --%squote\n",
modeDescr[p->mode], p->cmOpts.iWrap,
p->cmOpts.bWordWrap ? "on" : "off",
p->cmOpts.bQuote ? "" : "no");
}else{
oputf("current output mode: %s\n", modeDescr[p->mode]);
}
zMode = modeDescr[p->mode];
}
n2 = strlen30(zMode);
if( cli_strncmp(zMode,"lines",n2)==0 ){
p->mode = MODE_Line;
sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
|
| ︙ | ︙ | |||
25435 25436 25437 25438 25439 25440 25441 |
}else if( cli_strncmp(zMode,"count",n2)==0 ){
p->mode = MODE_Count;
}else if( cli_strncmp(zMode,"off",n2)==0 ){
p->mode = MODE_Off;
}else if( cli_strncmp(zMode,"json",n2)==0 ){
p->mode = MODE_Json;
}else{
| | | | | | | | | 26169 26170 26171 26172 26173 26174 26175 26176 26177 26178 26179 26180 26181 26182 26183 26184 26185 26186 26187 26188 26189 26190 26191 26192 26193 26194 26195 26196 26197 26198 26199 26200 26201 26202 26203 26204 26205 26206 26207 26208 26209 26210 26211 26212 26213 |
}else if( cli_strncmp(zMode,"count",n2)==0 ){
p->mode = MODE_Count;
}else if( cli_strncmp(zMode,"off",n2)==0 ){
p->mode = MODE_Off;
}else if( cli_strncmp(zMode,"json",n2)==0 ){
p->mode = MODE_Json;
}else{
eputz("Error: mode should be one of: "
"ascii box column csv html insert json line list markdown "
"qbox quote table tabs tcl\n");
rc = 1;
}
p->cMode = p->mode;
}else
#ifndef SQLITE_SHELL_FIDDLE
if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){
if( nArg!=2 ){
eputz("Usage: .nonce NONCE\n");
rc = 1;
}else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
eputf("line %d: incorrect nonce: \"%s\"\n",
p->lineno, azArg[1]);
exit(1);
}else{
p->bSafeMode = 0;
return 0; /* Return immediately to bypass the safe mode reset
** at the end of this procedure */
}
}else
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
if( c=='n' && cli_strncmp(azArg[0], "nullvalue", n)==0 ){
if( nArg==2 ){
sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
"%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
}else{
eputz("Usage: .nullvalue STRING\n");
rc = 1;
}
}else
if( c=='o' && cli_strncmp(azArg[0], "open", n)==0 && n>=2 ){
const char *zFN = 0; /* Pointer to constant filename */
char *zNewFilename = 0; /* Name of the database file to open */
|
| ︙ | ︙ | |||
25504 25505 25506 25507 25508 25509 25510 |
openMode = SHELL_OPEN_HEXDB;
}else if( optionMatch(z, "maxsize") && iName+1<nArg ){
p->szMax = integerValue(azArg[++iName]);
#endif /* SQLITE_OMIT_DESERIALIZE */
}else
#endif /* !SQLITE_SHELL_FIDDLE */
if( z[0]=='-' ){
| | | | 26238 26239 26240 26241 26242 26243 26244 26245 26246 26247 26248 26249 26250 26251 26252 26253 26254 26255 26256 |
openMode = SHELL_OPEN_HEXDB;
}else if( optionMatch(z, "maxsize") && iName+1<nArg ){
p->szMax = integerValue(azArg[++iName]);
#endif /* SQLITE_OMIT_DESERIALIZE */
}else
#endif /* !SQLITE_SHELL_FIDDLE */
if( z[0]=='-' ){
eputf("unknown option: %s\n", z);
rc = 1;
goto meta_command_exit;
}else if( zFN ){
eputf("extra argument: \"%s\"\n", z);
rc = 1;
goto meta_command_exit;
}else{
zFN = z;
}
}
|
| ︙ | ︙ | |||
25550 25551 25552 25553 25554 25555 25556 |
shell_check_oom(zNewFilename);
}else{
zNewFilename = 0;
}
p->pAuxDb->zDbFilename = zNewFilename;
open_db(p, OPEN_DB_KEEPALIVE);
if( p->db==0 ){
| | | 26284 26285 26286 26287 26288 26289 26290 26291 26292 26293 26294 26295 26296 26297 26298 |
shell_check_oom(zNewFilename);
}else{
zNewFilename = 0;
}
p->pAuxDb->zDbFilename = zNewFilename;
open_db(p, OPEN_DB_KEEPALIVE);
if( p->db==0 ){
eputf("Error: cannot open '%s'\n", zNewFilename);
sqlite3_free(zNewFilename);
}else{
p->pAuxDb->zFreeOnClose = zNewFilename;
}
}
if( p->db==0 ){
/* As a fall-back open a TEMP database */
|
| ︙ | ︙ | |||
25574 25575 25576 25577 25578 25579 25580 |
|| (c=='e' && n==5 && cli_strcmp(azArg[0],"excel")==0)
){
char *zFile = 0;
int bTxtMode = 0;
int i;
int eMode = 0;
int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
| > | < < < < | | < | < | 26308 26309 26310 26311 26312 26313 26314 26315 26316 26317 26318 26319 26320 26321 26322 26323 26324 26325 26326 26327 26328 26329 26330 26331 26332 26333 26334 26335 26336 26337 26338 26339 26340 26341 26342 26343 26344 26345 26346 26347 26348 26349 26350 26351 26352 26353 26354 26355 |
|| (c=='e' && n==5 && cli_strcmp(azArg[0],"excel")==0)
){
char *zFile = 0;
int bTxtMode = 0;
int i;
int eMode = 0;
int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */
static const char *zBomUtf8 = "\xef\xbb\xbf";
const char *zBom = 0;
failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
if( c=='e' ){
eMode = 'x';
bOnce = 2;
}else if( cli_strncmp(azArg[0],"once",n)==0 ){
bOnce = 1;
}
for(i=1; i<nArg; i++){
char *z = azArg[i];
if( z[0]=='-' ){
if( z[1]=='-' ) z++;
if( cli_strcmp(z,"-bom")==0 ){
zBom = zBomUtf8;
}else if( c!='e' && cli_strcmp(z,"-x")==0 ){
eMode = 'x'; /* spreadsheet */
}else if( c!='e' && cli_strcmp(z,"-e")==0 ){
eMode = 'e'; /* text editor */
}else{
oputf("ERROR: unknown option: \"%s\". Usage:\n", azArg[i]);
showHelp(p->out, azArg[0]);
rc = 1;
goto meta_command_exit;
}
}else if( zFile==0 && eMode!='e' && eMode!='x' ){
zFile = sqlite3_mprintf("%s", z);
if( zFile && zFile[0]=='|' ){
while( i+1<nArg ) zFile = sqlite3_mprintf("%z %s", zFile, azArg[++i]);
break;
}
}else{
oputf("ERROR: extra parameter: \"%s\". Usage:\n", azArg[i]);
showHelp(p->out, azArg[0]);
rc = 1;
sqlite3_free(zFile);
goto meta_command_exit;
}
}
if( zFile==0 ){
|
| ︙ | ︙ | |||
25651 25652 25653 25654 25655 25656 25657 |
sqlite3_free(zFile);
zFile = sqlite3_mprintf("%s", p->zTempFile);
}
#endif /* SQLITE_NOHAVE_SYSTEM */
shell_check_oom(zFile);
if( zFile[0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
| | | | | | < > | | | | < > | | 26380 26381 26382 26383 26384 26385 26386 26387 26388 26389 26390 26391 26392 26393 26394 26395 26396 26397 26398 26399 26400 26401 26402 26403 26404 26405 26406 26407 26408 26409 26410 26411 26412 26413 26414 26415 26416 26417 |
sqlite3_free(zFile);
zFile = sqlite3_mprintf("%s", p->zTempFile);
}
#endif /* SQLITE_NOHAVE_SYSTEM */
shell_check_oom(zFile);
if( zFile[0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
eputz("Error: pipes are not supported in this OS\n");
rc = 1;
output_redir(p, stdout);
#else
FILE *pfPipe = popen(zFile + 1, "w");
if( pfPipe==0 ){
eputf("Error: cannot open pipe \"%s\"\n", zFile + 1);
rc = 1;
}else{
output_redir(p, pfPipe);
if( zBom ) oputz(zBom);
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
}
#endif
}else{
FILE *pfFile = output_file_open(zFile, bTxtMode);
if( pfFile==0 ){
if( cli_strcmp(zFile,"off")!=0 ){
eputf("Error: cannot write to \"%s\"\n", zFile);
}
rc = 1;
} else {
output_redir(p, pfFile);
if( zBom ) oputz(zBom);
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
}
}
sqlite3_free(zFile);
}else
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
|
| ︙ | ︙ | |||
25715 25716 25717 25718 25719 25720 25721 |
sqlite3_finalize(pStmt);
pStmt = 0;
if( len ){
rx = sqlite3_prepare_v2(p->db,
"SELECT key, quote(value) "
"FROM temp.sqlite_parameters;", -1, &pStmt, 0);
while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
| | | | 26444 26445 26446 26447 26448 26449 26450 26451 26452 26453 26454 26455 26456 26457 26458 26459 |
sqlite3_finalize(pStmt);
pStmt = 0;
if( len ){
rx = sqlite3_prepare_v2(p->db,
"SELECT key, quote(value) "
"FROM temp.sqlite_parameters;", -1, &pStmt, 0);
while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
oputf("%-*s %s\n", len, sqlite3_column_text(pStmt,0),
sqlite3_column_text(pStmt,1));
}
sqlite3_finalize(pStmt);
}
}else
/* .parameter init
** Make sure the TEMP table used to hold bind parameters exists.
|
| ︙ | ︙ | |||
25760 25761 25762 25763 25764 25765 25766 |
zSql = sqlite3_mprintf(
"REPLACE INTO temp.sqlite_parameters(key,value)"
"VALUES(%Q,%Q);", zKey, zValue);
shell_check_oom(zSql);
rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rx!=SQLITE_OK ){
| | | 26489 26490 26491 26492 26493 26494 26495 26496 26497 26498 26499 26500 26501 26502 26503 |
zSql = sqlite3_mprintf(
"REPLACE INTO temp.sqlite_parameters(key,value)"
"VALUES(%Q,%Q);", zKey, zValue);
shell_check_oom(zSql);
rx = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rx!=SQLITE_OK ){
oputf("Error: %s\n", sqlite3_errmsg(p->db));
sqlite3_finalize(pStmt);
pStmt = 0;
rc = 1;
}
}
sqlite3_step(pStmt);
sqlite3_finalize(pStmt);
|
| ︙ | ︙ | |||
25789 25790 25791 25792 25793 25794 25795 |
parameter_syntax_error:
showHelp(p->out, "parameter");
}else
if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print", n)==0 ){
int i;
for(i=1; i<nArg; i++){
| | | | | 26518 26519 26520 26521 26522 26523 26524 26525 26526 26527 26528 26529 26530 26531 26532 26533 26534 26535 |
parameter_syntax_error:
showHelp(p->out, "parameter");
}else
if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print", n)==0 ){
int i;
for(i=1; i<nArg; i++){
if( i>1 ) oputz(" ");
oputz(azArg[i]);
}
oputz("\n");
}else
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
if( c=='p' && n>=3 && cli_strncmp(azArg[0], "progress", n)==0 ){
int i;
int nn = 0;
p->flgProgress = 0;
|
| ︙ | ︙ | |||
25821 25822 25823 25824 25825 25826 25827 |
}
if( cli_strcmp(z,"once")==0 ){
p->flgProgress |= SHELL_PROGRESS_ONCE;
continue;
}
if( cli_strcmp(z,"limit")==0 ){
if( i+1>=nArg ){
| | | | 26550 26551 26552 26553 26554 26555 26556 26557 26558 26559 26560 26561 26562 26563 26564 26565 26566 26567 26568 26569 26570 26571 26572 |
}
if( cli_strcmp(z,"once")==0 ){
p->flgProgress |= SHELL_PROGRESS_ONCE;
continue;
}
if( cli_strcmp(z,"limit")==0 ){
if( i+1>=nArg ){
eputz("Error: missing argument on --limit\n");
rc = 1;
goto meta_command_exit;
}else{
p->mxProgress = (int)integerValue(azArg[++i]);
}
continue;
}
eputf("Error: unknown option: \"%s\"\n", azArg[i]);
rc = 1;
goto meta_command_exit;
}else{
nn = (int)integerValue(z);
}
}
open_db(p, 0);
|
| ︙ | ︙ | |||
25862 25863 25864 25865 25866 25867 25868 |
#ifndef SQLITE_SHELL_FIDDLE
if( c=='r' && n>=3 && cli_strncmp(azArg[0], "read", n)==0 ){
FILE *inSaved = p->in;
int savedLineno = p->lineno;
failIfSafeMode(p, "cannot run .read in safe mode");
if( nArg!=2 ){
| | | | | | 26591 26592 26593 26594 26595 26596 26597 26598 26599 26600 26601 26602 26603 26604 26605 26606 26607 26608 26609 26610 26611 26612 26613 26614 26615 26616 26617 26618 26619 26620 26621 26622 26623 26624 26625 |
#ifndef SQLITE_SHELL_FIDDLE
if( c=='r' && n>=3 && cli_strncmp(azArg[0], "read", n)==0 ){
FILE *inSaved = p->in;
int savedLineno = p->lineno;
failIfSafeMode(p, "cannot run .read in safe mode");
if( nArg!=2 ){
eputz("Usage: .read FILE\n");
rc = 1;
goto meta_command_exit;
}
if( azArg[1][0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
eputz("Error: pipes are not supported in this OS\n");
rc = 1;
p->out = stdout;
#else
p->in = popen(azArg[1]+1, "r");
if( p->in==0 ){
eputf("Error: cannot open \"%s\"\n", azArg[1]);
rc = 1;
}else{
rc = process_input(p);
pclose(p->in);
}
#endif
}else if( (p->in = openChrSource(azArg[1]))==0 ){
eputf("Error: cannot open \"%s\"\n", azArg[1]);
rc = 1;
}else{
rc = process_input(p);
fclose(p->in);
}
p->in = inSaved;
p->lineno = savedLineno;
|
| ︙ | ︙ | |||
25909 25910 25911 25912 25913 25914 25915 |
if( nArg==2 ){
zSrcFile = azArg[1];
zDb = "main";
}else if( nArg==3 ){
zSrcFile = azArg[2];
zDb = azArg[1];
}else{
| | | | | | | | > > > > | | 26638 26639 26640 26641 26642 26643 26644 26645 26646 26647 26648 26649 26650 26651 26652 26653 26654 26655 26656 26657 26658 26659 26660 26661 26662 26663 26664 26665 26666 26667 26668 26669 26670 26671 26672 26673 26674 26675 26676 26677 26678 26679 26680 26681 26682 26683 26684 26685 26686 26687 26688 26689 26690 26691 26692 26693 26694 26695 26696 26697 26698 26699 26700 26701 26702 26703 26704 26705 26706 26707 26708 26709 26710 26711 26712 |
if( nArg==2 ){
zSrcFile = azArg[1];
zDb = "main";
}else if( nArg==3 ){
zSrcFile = azArg[2];
zDb = azArg[1];
}else{
eputz("Usage: .restore ?DB? FILE\n");
rc = 1;
goto meta_command_exit;
}
rc = sqlite3_open(zSrcFile, &pSrc);
if( rc!=SQLITE_OK ){
eputf("Error: cannot open \"%s\"\n", zSrcFile);
close_db(pSrc);
return 1;
}
open_db(p, 0);
pBackup = sqlite3_backup_init(p->db, zDb, pSrc, "main");
if( pBackup==0 ){
eputf("Error: %s\n", sqlite3_errmsg(p->db));
close_db(pSrc);
return 1;
}
while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
|| rc==SQLITE_BUSY ){
if( rc==SQLITE_BUSY ){
if( nTimeout++ >= 3 ) break;
sqlite3_sleep(100);
}
}
sqlite3_backup_finish(pBackup);
if( rc==SQLITE_DONE ){
rc = 0;
}else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
eputz("Error: source database is busy\n");
rc = 1;
}else{
eputf("Error: %s\n", sqlite3_errmsg(p->db));
rc = 1;
}
close_db(pSrc);
}else
#endif /* !defined(SQLITE_SHELL_FIDDLE) */
if( c=='s' && cli_strncmp(azArg[0], "scanstats", n)==0 ){
if( nArg==2 ){
if( cli_strcmp(azArg[1], "vm")==0 ){
p->scanstatsOn = 3;
}else
if( cli_strcmp(azArg[1], "est")==0 ){
p->scanstatsOn = 2;
}else{
p->scanstatsOn = (u8)booleanValue(azArg[1]);
}
open_db(p, 0);
sqlite3_db_config(
p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0
);
#if !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
eputz("Warning: .scanstats not available in this build.\n");
#elif !defined(SQLITE_ENABLE_BYTECODE_VTAB)
if( p->scanstatsOn==3 ){
eputz("Warning: \".scanstats vm\" not available in this build.\n");
}
#endif
}else{
eputz("Usage: .scanstats on|off|est\n");
rc = 1;
}
}else
if( c=='s' && cli_strncmp(azArg[0], "schema", n)==0 ){
ShellText sSelect;
ShellState data;
|
| ︙ | ︙ | |||
25994 25995 25996 25997 25998 25999 26000 |
if( optionMatch(azArg[ii],"indent") ){
data.cMode = data.mode = MODE_Pretty;
}else if( optionMatch(azArg[ii],"debug") ){
bDebug = 1;
}else if( optionMatch(azArg[ii],"nosys") ){
bNoSystemTabs = 1;
}else if( azArg[ii][0]=='-' ){
| | < | | 26727 26728 26729 26730 26731 26732 26733 26734 26735 26736 26737 26738 26739 26740 26741 26742 26743 26744 26745 26746 26747 |
if( optionMatch(azArg[ii],"indent") ){
data.cMode = data.mode = MODE_Pretty;
}else if( optionMatch(azArg[ii],"debug") ){
bDebug = 1;
}else if( optionMatch(azArg[ii],"nosys") ){
bNoSystemTabs = 1;
}else if( azArg[ii][0]=='-' ){
eputf("Unknown option: \"%s\"\n", azArg[ii]);
rc = 1;
goto meta_command_exit;
}else if( zName==0 ){
zName = azArg[ii];
}else{
eputz("Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
rc = 1;
goto meta_command_exit;
}
}
if( zName!=0 ){
int isSchema = sqlite3_strlike(zName, "sqlite_master", '\\')==0
|| sqlite3_strlike(zName, "sqlite_schema", '\\')==0
|
| ︙ | ︙ | |||
26034 26035 26036 26037 26038 26039 26040 |
}
}
if( zDiv ){
sqlite3_stmt *pStmt = 0;
rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
-1, &pStmt, 0);
if( rc ){
| | | 26766 26767 26768 26769 26770 26771 26772 26773 26774 26775 26776 26777 26778 26779 26780 |
}
}
if( zDiv ){
sqlite3_stmt *pStmt = 0;
rc = sqlite3_prepare_v2(p->db, "SELECT name FROM pragma_database_list",
-1, &pStmt, 0);
if( rc ){
eputf("Error: %s\n", sqlite3_errmsg(p->db));
sqlite3_finalize(pStmt);
rc = 1;
goto meta_command_exit;
}
appendText(&sSelect, "SELECT sql FROM", 0);
iSchema = 0;
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
| ︙ | ︙ | |||
26096 26097 26098 26099 26100 26101 26102 |
}
if( bNoSystemTabs ){
appendText(&sSelect, "name NOT LIKE 'sqlite_%%' AND ", 0);
}
appendText(&sSelect, "sql IS NOT NULL"
" ORDER BY snum, rowid", 0);
if( bDebug ){
| | | | | 26828 26829 26830 26831 26832 26833 26834 26835 26836 26837 26838 26839 26840 26841 26842 26843 26844 26845 26846 26847 26848 26849 26850 26851 26852 26853 |
}
if( bNoSystemTabs ){
appendText(&sSelect, "name NOT LIKE 'sqlite_%%' AND ", 0);
}
appendText(&sSelect, "sql IS NOT NULL"
" ORDER BY snum, rowid", 0);
if( bDebug ){
oputf("SQL: %s;\n", sSelect.z);
}else{
rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
}
freeText(&sSelect);
}
if( zErrMsg ){
eputf("Error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
rc = 1;
}else if( rc != SQLITE_OK ){
eputz("Error: querying schema information\n");
rc = 1;
}else{
rc = 0;
}
}else
if( (c=='s' && n==11 && cli_strncmp(azArg[0], "selecttrace", n)==0)
|
| ︙ | ︙ | |||
26153 26154 26155 26156 26157 26158 26159 |
** Invoke the sqlite3session_attach() interface to attach a particular
** table so that it is never filtered.
*/
if( cli_strcmp(azCmd[0],"attach")==0 ){
if( nCmd!=2 ) goto session_syntax_error;
if( pSession->p==0 ){
session_not_open:
| | | | | | | < | 26885 26886 26887 26888 26889 26890 26891 26892 26893 26894 26895 26896 26897 26898 26899 26900 26901 26902 26903 26904 26905 26906 26907 26908 26909 26910 26911 26912 26913 26914 26915 26916 26917 26918 26919 26920 26921 26922 26923 26924 26925 26926 26927 26928 26929 26930 26931 26932 26933 26934 26935 26936 26937 26938 |
** Invoke the sqlite3session_attach() interface to attach a particular
** table so that it is never filtered.
*/
if( cli_strcmp(azCmd[0],"attach")==0 ){
if( nCmd!=2 ) goto session_syntax_error;
if( pSession->p==0 ){
session_not_open:
eputz("ERROR: No sessions are open\n");
}else{
rc = sqlite3session_attach(pSession->p, azCmd[1]);
if( rc ){
eputf("ERROR: sqlite3session_attach() returns %d\n",rc);
rc = 0;
}
}
}else
/* .session changeset FILE
** .session patchset FILE
** Write a changeset or patchset into a file. The file is overwritten.
*/
if( cli_strcmp(azCmd[0],"changeset")==0
|| cli_strcmp(azCmd[0],"patchset")==0
){
FILE *out = 0;
failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]);
if( nCmd!=2 ) goto session_syntax_error;
if( pSession->p==0 ) goto session_not_open;
out = fopen(azCmd[1], "wb");
if( out==0 ){
eputf("ERROR: cannot open \"%s\" for writing\n",
azCmd[1]);
}else{
int szChng;
void *pChng;
if( azCmd[0][0]=='c' ){
rc = sqlite3session_changeset(pSession->p, &szChng, &pChng);
}else{
rc = sqlite3session_patchset(pSession->p, &szChng, &pChng);
}
if( rc ){
sputf(stdout, "Error: error code %d\n", rc);
rc = 0;
}
if( pChng
&& fwrite(pChng, szChng, 1, out)!=1 ){
eputf("ERROR: Failed to write entire %d-byte output\n", szChng);
}
sqlite3_free(pChng);
fclose(out);
}
}else
/* .session close
|
| ︙ | ︙ | |||
26220 26221 26222 26223 26224 26225 26226 |
*/
if( cli_strcmp(azCmd[0], "enable")==0 ){
int ii;
if( nCmd>2 ) goto session_syntax_error;
ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
if( pAuxDb->nSession ){
ii = sqlite3session_enable(pSession->p, ii);
| | < | < < < | < | < | | < | | | 26951 26952 26953 26954 26955 26956 26957 26958 26959 26960 26961 26962 26963 26964 26965 26966 26967 26968 26969 26970 26971 26972 26973 26974 26975 26976 26977 26978 26979 26980 26981 26982 26983 26984 26985 26986 26987 26988 26989 26990 26991 26992 26993 26994 26995 26996 26997 26998 26999 27000 27001 27002 27003 27004 27005 27006 27007 27008 27009 27010 27011 27012 27013 27014 27015 27016 27017 27018 27019 27020 27021 27022 27023 27024 27025 27026 27027 27028 27029 27030 27031 27032 27033 27034 27035 27036 27037 27038 27039 27040 27041 27042 27043 27044 27045 27046 27047 |
*/
if( cli_strcmp(azCmd[0], "enable")==0 ){
int ii;
if( nCmd>2 ) goto session_syntax_error;
ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
if( pAuxDb->nSession ){
ii = sqlite3session_enable(pSession->p, ii);
oputf("session %s enable flag = %d\n", pSession->zName, ii);
}
}else
/* .session filter GLOB ....
** Set a list of GLOB patterns of table names to be excluded.
*/
if( cli_strcmp(azCmd[0], "filter")==0 ){
int ii, nByte;
if( nCmd<2 ) goto session_syntax_error;
if( pAuxDb->nSession ){
for(ii=0; ii<pSession->nFilter; ii++){
sqlite3_free(pSession->azFilter[ii]);
}
sqlite3_free(pSession->azFilter);
nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
pSession->azFilter = sqlite3_malloc( nByte );
shell_check_oom( pSession->azFilter );
for(ii=1; ii<nCmd; ii++){
char *x = pSession->azFilter[ii-1] = sqlite3_mprintf("%s", azCmd[ii]);
shell_check_oom(x);
}
pSession->nFilter = ii-1;
}
}else
/* .session indirect ?BOOLEAN?
** Query or set the indirect flag
*/
if( cli_strcmp(azCmd[0], "indirect")==0 ){
int ii;
if( nCmd>2 ) goto session_syntax_error;
ii = nCmd==1 ? -1 : booleanValue(azCmd[1]);
if( pAuxDb->nSession ){
ii = sqlite3session_indirect(pSession->p, ii);
oputf("session %s indirect flag = %d\n", pSession->zName, ii);
}
}else
/* .session isempty
** Determine if the session is empty
*/
if( cli_strcmp(azCmd[0], "isempty")==0 ){
int ii;
if( nCmd!=1 ) goto session_syntax_error;
if( pAuxDb->nSession ){
ii = sqlite3session_isempty(pSession->p);
oputf("session %s isempty flag = %d\n", pSession->zName, ii);
}
}else
/* .session list
** List all currently open sessions
*/
if( cli_strcmp(azCmd[0],"list")==0 ){
for(i=0; i<pAuxDb->nSession; i++){
oputf("%d %s\n", i, pAuxDb->aSession[i].zName);
}
}else
/* .session open DB NAME
** Open a new session called NAME on the attached database DB.
** DB is normally "main".
*/
if( cli_strcmp(azCmd[0],"open")==0 ){
char *zName;
if( nCmd!=3 ) goto session_syntax_error;
zName = azCmd[2];
if( zName[0]==0 ) goto session_syntax_error;
for(i=0; i<pAuxDb->nSession; i++){
if( cli_strcmp(pAuxDb->aSession[i].zName,zName)==0 ){
eputf("Session \"%s\" already exists\n", zName);
goto meta_command_exit;
}
}
if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){
eputf("Maximum of %d sessions\n", ArraySize(pAuxDb->aSession));
goto meta_command_exit;
}
pSession = &pAuxDb->aSession[pAuxDb->nSession];
rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
if( rc ){
eputf("Cannot open session: error code=%d\n", rc);
rc = 0;
goto meta_command_exit;
}
pSession->nFilter = 0;
sqlite3session_table_filter(pSession->p, session_filter, pSession);
pAuxDb->nSession++;
pSession->zName = sqlite3_mprintf("%s", zName);
|
| ︙ | ︙ | |||
26333 26334 26335 26336 26337 26338 26339 |
/* Undocumented commands for internal testing. Subject to change
** without notice. */
if( c=='s' && n>=10 && cli_strncmp(azArg[0], "selftest-", 9)==0 ){
if( cli_strncmp(azArg[0]+9, "boolean", n-9)==0 ){
int i, v;
for(i=1; i<nArg; i++){
v = booleanValue(azArg[i]);
| | | | 27057 27058 27059 27060 27061 27062 27063 27064 27065 27066 27067 27068 27069 27070 27071 27072 27073 27074 27075 27076 27077 27078 27079 27080 |
/* Undocumented commands for internal testing. Subject to change
** without notice. */
if( c=='s' && n>=10 && cli_strncmp(azArg[0], "selftest-", 9)==0 ){
if( cli_strncmp(azArg[0]+9, "boolean", n-9)==0 ){
int i, v;
for(i=1; i<nArg; i++){
v = booleanValue(azArg[i]);
oputf("%s: %d 0x%x\n", azArg[i], v, v);
}
}
if( cli_strncmp(azArg[0]+9, "integer", n-9)==0 ){
int i; sqlite3_int64 v;
for(i=1; i<nArg; i++){
char zBuf[200];
v = integerValue(azArg[i]);
sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
oputz(zBuf);
}
}
}else
#endif
if( c=='s' && n>=4 && cli_strncmp(azArg[0],"selftest",n)==0 ){
int bIsInit = 0; /* True to initialize the SELFTEST table */
|
| ︙ | ︙ | |||
26369 26370 26371 26372 26373 26374 26375 |
if( cli_strcmp(z,"-init")==0 ){
bIsInit = 1;
}else
if( cli_strcmp(z,"-v")==0 ){
bVerbose++;
}else
{
| | < | | 27093 27094 27095 27096 27097 27098 27099 27100 27101 27102 27103 27104 27105 27106 27107 27108 |
if( cli_strcmp(z,"-init")==0 ){
bIsInit = 1;
}else
if( cli_strcmp(z,"-v")==0 ){
bVerbose++;
}else
{
eputf("Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]);
eputz("Should be one of: --init -v\n");
rc = 1;
goto meta_command_exit;
}
}
if( sqlite3_table_column_metadata(p->db,"main","selftest",0,0,0,0,0,0)
!= SQLITE_OK ){
bSelftestExists = 0;
|
| ︙ | ︙ | |||
26400 26401 26402 26403 26404 26405 26406 |
}else{
rc = sqlite3_prepare_v2(p->db,
"VALUES(0,'memo','Missing SELFTEST table - default checks only',''),"
" (1,'run','PRAGMA integrity_check','ok')",
-1, &pStmt, 0);
}
if( rc ){
| | | | | | | | > | < < | | | | 27123 27124 27125 27126 27127 27128 27129 27130 27131 27132 27133 27134 27135 27136 27137 27138 27139 27140 27141 27142 27143 27144 27145 27146 27147 27148 27149 27150 27151 27152 27153 27154 27155 27156 27157 27158 27159 27160 27161 27162 27163 27164 27165 27166 27167 27168 27169 27170 27171 27172 27173 27174 27175 27176 27177 27178 27179 27180 27181 27182 27183 27184 27185 27186 27187 27188 27189 27190 27191 27192 27193 |
}else{
rc = sqlite3_prepare_v2(p->db,
"VALUES(0,'memo','Missing SELFTEST table - default checks only',''),"
" (1,'run','PRAGMA integrity_check','ok')",
-1, &pStmt, 0);
}
if( rc ){
eputz("Error querying the selftest table\n");
rc = 1;
sqlite3_finalize(pStmt);
goto meta_command_exit;
}
for(i=1; sqlite3_step(pStmt)==SQLITE_ROW; i++){
int tno = sqlite3_column_int(pStmt, 0);
const char *zOp = (const char*)sqlite3_column_text(pStmt, 1);
const char *zSql = (const char*)sqlite3_column_text(pStmt, 2);
const char *zAns = (const char*)sqlite3_column_text(pStmt, 3);
if( zOp==0 ) continue;
if( zSql==0 ) continue;
if( zAns==0 ) continue;
k = 0;
if( bVerbose>0 ){
sputf(stdout, "%d: %s %s\n", tno, zOp, zSql);
}
if( cli_strcmp(zOp,"memo")==0 ){
oputf("%s\n", zSql);
}else
if( cli_strcmp(zOp,"run")==0 ){
char *zErrMsg = 0;
str.n = 0;
str.z[0] = 0;
rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
nTest++;
if( bVerbose ){
oputf("Result: %s\n", str.z);
}
if( rc || zErrMsg ){
nErr++;
rc = 1;
oputf("%d: error-code-%d: %s\n", tno, rc, zErrMsg);
sqlite3_free(zErrMsg);
}else if( cli_strcmp(zAns,str.z)!=0 ){
nErr++;
rc = 1;
oputf("%d: Expected: [%s]\n", tno, zAns);
oputf("%d: Got: [%s]\n", tno, str.z);
}
}
else{
eputf("Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
rc = 1;
break;
}
} /* End loop over rows of content from SELFTEST */
sqlite3_finalize(pStmt);
} /* End loop over k */
freeText(&str);
oputf("%d errors out of %d tests\n", nErr, nTest);
}else
if( c=='s' && cli_strncmp(azArg[0], "separator", n)==0 ){
if( nArg<2 || nArg>3 ){
eputz("Usage: .separator COL ?ROW?\n");
rc = 1;
}
if( nArg>=2 ){
sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator,
"%.*s", (int)ArraySize(p->colSeparator)-1, azArg[1]);
}
if( nArg>=3 ){
|
| ︙ | ︙ | |||
26500 26501 26502 26503 26504 26505 26506 |
){
iSize = atoi(&z[5]);
}else
if( cli_strcmp(z,"debug")==0 ){
bDebug = 1;
}else
{
| | < | | 27222 27223 27224 27225 27226 27227 27228 27229 27230 27231 27232 27233 27234 27235 27236 27237 27238 27239 27240 27241 27242 |
){
iSize = atoi(&z[5]);
}else
if( cli_strcmp(z,"debug")==0 ){
bDebug = 1;
}else
{
eputf("Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]);
showHelp(p->out, azArg[0]);
rc = 1;
goto meta_command_exit;
}
}else if( zLike ){
eputz("Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
rc = 1;
goto meta_command_exit;
}else{
zLike = z;
bSeparate = 1;
if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1;
}
|
| ︙ | ︙ | |||
26579 26580 26581 26582 26583 26584 26585 |
" FROM [sha3sum$query]",
sSql.z, iSize);
}
shell_check_oom(zSql);
freeText(&sQuery);
freeText(&sSql);
if( bDebug ){
| | | 27300 27301 27302 27303 27304 27305 27306 27307 27308 27309 27310 27311 27312 27313 27314 |
" FROM [sha3sum$query]",
sSql.z, iSize);
}
shell_check_oom(zSql);
freeText(&sQuery);
freeText(&sSql);
if( bDebug ){
oputf("%s\n", zSql);
}else{
shell_exec(p, zSql, 0);
}
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && !defined(SQLITE_OMIT_VIRTUALTABLE)
{
int lrc;
char *zRevText = /* Query for reversible to-blob-to-text check */
|
| ︙ | ︙ | |||
26609 26610 26611 26612 26613 26614 26615 |
" from (select 'SELECT COUNT(*) AS bad_text_count\n"
"FROM '||tname||' WHERE '\n"
"||group_concat('CAST(CAST('||cname||' AS BLOB) AS TEXT)<>'||cname\n"
"|| ' AND typeof('||cname||')=''text'' ',\n"
"' OR ') as query, tname from tabcols group by tname)"
, zRevText);
shell_check_oom(zRevText);
| | | < | | | | > > | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | 27330 27331 27332 27333 27334 27335 27336 27337 27338 27339 27340 27341 27342 27343 27344 27345 27346 27347 27348 27349 27350 27351 27352 27353 27354 27355 27356 27357 27358 27359 27360 27361 27362 27363 27364 27365 27366 27367 27368 27369 27370 27371 27372 27373 27374 27375 27376 27377 27378 27379 27380 27381 27382 27383 27384 27385 27386 27387 27388 27389 27390 27391 27392 27393 27394 27395 27396 27397 27398 27399 27400 27401 27402 27403 27404 27405 27406 27407 27408 27409 27410 27411 27412 27413 27414 27415 27416 27417 27418 27419 27420 27421 27422 27423 27424 27425 27426 27427 27428 27429 27430 27431 27432 27433 27434 27435 27436 27437 27438 27439 27440 27441 27442 27443 27444 27445 27446 27447 27448 27449 27450 27451 27452 27453 27454 27455 27456 27457 27458 27459 27460 27461 27462 27463 27464 27465 27466 27467 27468 27469 27470 27471 |
" from (select 'SELECT COUNT(*) AS bad_text_count\n"
"FROM '||tname||' WHERE '\n"
"||group_concat('CAST(CAST('||cname||' AS BLOB) AS TEXT)<>'||cname\n"
"|| ' AND typeof('||cname||')=''text'' ',\n"
"' OR ') as query, tname from tabcols group by tname)"
, zRevText);
shell_check_oom(zRevText);
if( bDebug ) oputf("%s\n", zRevText);
lrc = sqlite3_prepare_v2(p->db, zRevText, -1, &pStmt, 0);
if( lrc!=SQLITE_OK ){
/* assert(lrc==SQLITE_NOMEM); // might also be SQLITE_ERROR if the
** user does cruel and unnatural things like ".limit expr_depth 0". */
rc = 1;
}else{
if( zLike ) sqlite3_bind_text(pStmt,1,zLike,-1,SQLITE_STATIC);
lrc = SQLITE_ROW==sqlite3_step(pStmt);
if( lrc ){
const char *zGenQuery = (char*)sqlite3_column_text(pStmt,0);
sqlite3_stmt *pCheckStmt;
lrc = sqlite3_prepare_v2(p->db, zGenQuery, -1, &pCheckStmt, 0);
if( bDebug ) oputf("%s\n", zGenQuery);
if( lrc!=SQLITE_OK ){
rc = 1;
}else{
if( SQLITE_ROW==sqlite3_step(pCheckStmt) ){
double countIrreversible = sqlite3_column_double(pCheckStmt, 0);
if( countIrreversible>0 ){
int sz = (int)(countIrreversible + 0.5);
eputf("Digest includes %d invalidly encoded text field%s.\n",
sz, (sz>1)? "s": "");
}
}
sqlite3_finalize(pCheckStmt);
}
sqlite3_finalize(pStmt);
}
}
if( rc ) eputz(".sha3sum failed.\n");
sqlite3_free(zRevText);
}
#endif /* !defined(*_OMIT_SCHEMA_PRAGMAS) && !defined(*_OMIT_VIRTUALTABLE) */
sqlite3_free(zSql);
}else
#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE)
if( c=='s'
&& (cli_strncmp(azArg[0], "shell", n)==0
|| cli_strncmp(azArg[0],"system",n)==0)
){
char *zCmd;
int i, x;
failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
if( nArg<2 ){
eputz("Usage: .system COMMAND\n");
rc = 1;
goto meta_command_exit;
}
zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
for(i=2; i<nArg && zCmd!=0; i++){
zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
zCmd, azArg[i]);
}
consoleRestore();
x = zCmd!=0 ? system(zCmd) : 1;
consoleRenewSetup();
sqlite3_free(zCmd);
if( x ) eputf("System command returns %d\n", x);
}else
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) */
if( c=='s' && cli_strncmp(azArg[0], "show", n)==0 ){
static const char *azBool[] = { "off", "on", "trigger", "full"};
const char *zOut;
int i;
if( nArg!=1 ){
eputz("Usage: .show\n");
rc = 1;
goto meta_command_exit;
}
oputf("%12.12s: %s\n","echo",
azBool[ShellHasFlag(p, SHFLG_Echo)]);
oputf("%12.12s: %s\n","eqp", azBool[p->autoEQP&3]);
oputf("%12.12s: %s\n","explain",
p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
oputf("%12.12s: %s\n","headers", azBool[p->showHeader!=0]);
if( p->mode==MODE_Column
|| (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
){
oputf("%12.12s: %s --wrap %d --wordwrap %s --%squote\n", "mode",
modeDescr[p->mode], p->cmOpts.iWrap,
p->cmOpts.bWordWrap ? "on" : "off",
p->cmOpts.bQuote ? "" : "no");
}else{
oputf("%12.12s: %s\n","mode", modeDescr[p->mode]);
}
oputf("%12.12s: ", "nullvalue");
output_c_string(p->nullValue);
oputz("\n");
oputf("%12.12s: %s\n","output",
strlen30(p->outfile) ? p->outfile : "stdout");
oputf("%12.12s: ", "colseparator");
output_c_string(p->colSeparator);
oputz("\n");
oputf("%12.12s: ", "rowseparator");
output_c_string(p->rowSeparator);
oputz("\n");
switch( p->statsOn ){
case 0: zOut = "off"; break;
default: zOut = "on"; break;
case 2: zOut = "stmt"; break;
case 3: zOut = "vmstep"; break;
}
oputf("%12.12s: %s\n","stats", zOut);
oputf("%12.12s: ", "width");
for (i=0;i<p->nWidth;i++) {
oputf("%d ", p->colWidth[i]);
}
oputz("\n");
oputf("%12.12s: %s\n", "filename",
p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : "");
}else
if( c=='s' && cli_strncmp(azArg[0], "stats", n)==0 ){
if( nArg==2 ){
if( cli_strcmp(azArg[1],"stmt")==0 ){
p->statsOn = 2;
}else if( cli_strcmp(azArg[1],"vmstep")==0 ){
p->statsOn = 3;
}else{
p->statsOn = (u8)booleanValue(azArg[1]);
}
}else if( nArg==1 ){
display_stats(p->db, p, 0);
}else{
eputz("Usage: .stats ?on|off|stmt|vmstep?\n");
rc = 1;
}
}else
if( (c=='t' && n>1 && cli_strncmp(azArg[0], "tables", n)==0)
|| (c=='i' && (cli_strncmp(azArg[0], "indices", n)==0
|| cli_strncmp(azArg[0], "indexes", n)==0) )
|
| ︙ | ︙ | |||
26762 26763 26764 26765 26766 26767 26768 |
return shellDatabaseError(p->db);
}
if( nArg>2 && c=='i' ){
/* It is an historical accident that the .indexes command shows an error
** when called with the wrong number of arguments whereas the .tables
** command does not. */
| | | 27483 27484 27485 27486 27487 27488 27489 27490 27491 27492 27493 27494 27495 27496 27497 |
return shellDatabaseError(p->db);
}
if( nArg>2 && c=='i' ){
/* It is an historical accident that the .indexes command shows an error
** when called with the wrong number of arguments whereas the .tables
** command does not. */
eputz("Usage: .indexes ?LIKE-PATTERN?\n");
rc = 1;
sqlite3_finalize(pStmt);
goto meta_command_exit;
}
for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
if( zDbName==0 ) continue;
|
| ︙ | ︙ | |||
26838 26839 26840 26841 26842 26843 26844 |
}
nPrintCol = 80/(maxlen+2);
if( nPrintCol<1 ) nPrintCol = 1;
nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
for(i=0; i<nPrintRow; i++){
for(j=i; j<nRow; j+=nPrintRow){
char *zSp = j<nPrintRow ? "" : " ";
| < | | | | 27559 27560 27561 27562 27563 27564 27565 27566 27567 27568 27569 27570 27571 27572 27573 27574 27575 27576 27577 27578 27579 27580 27581 27582 27583 27584 27585 27586 27587 27588 27589 |
}
nPrintCol = 80/(maxlen+2);
if( nPrintCol<1 ) nPrintCol = 1;
nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
for(i=0; i<nPrintRow; i++){
for(j=i; j<nRow; j+=nPrintRow){
char *zSp = j<nPrintRow ? "" : " ";
oputf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
}
oputz("\n");
}
}
for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
sqlite3_free(azResult);
}else
#ifndef SQLITE_SHELL_FIDDLE
/* Begin redirecting output to the file "testcase-out.txt" */
if( c=='t' && cli_strcmp(azArg[0],"testcase")==0 ){
output_reset(p);
p->out = output_file_open("testcase-out.txt", 0);
if( p->out==0 ){
eputz("Error: cannot open 'testcase-out.txt'\n");
}
if( nArg>=2 ){
sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
}else{
sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
}
}else
|
| ︙ | ︙ | |||
26896 26897 26898 26899 26900 26901 26902 |
{"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " },
{"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" },
{"prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" },
{"prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" },
{"seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" },
{"sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" },
{"tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" },
| | | | | | | | | | 27616 27617 27618 27619 27620 27621 27622 27623 27624 27625 27626 27627 27628 27629 27630 27631 27632 27633 27634 27635 27636 27637 27638 27639 27640 27641 27642 27643 27644 27645 27646 27647 27648 27649 27650 27651 27652 27653 27654 27655 27656 27657 27658 27659 27660 27661 27662 27663 27664 27665 27666 27667 27668 27669 27670 27671 27672 27673 27674 27675 27676 27677 27678 27679 |
{"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " },
{"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" },
{"prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" },
{"prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" },
{"seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" },
{"sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" },
{"tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" },
{"uselongdouble", SQLITE_TESTCTRL_USELONGDOUBLE,0,"?BOOLEAN|\"default\"?"},
};
int testctrl = -1;
int iCtrl = -1;
int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */
int isOk = 0;
int i, n2;
const char *zCmd = 0;
open_db(p, 0);
zCmd = nArg>=2 ? azArg[1] : "help";
/* The argument can optionally begin with "-" or "--" */
if( zCmd[0]=='-' && zCmd[1] ){
zCmd++;
if( zCmd[0]=='-' && zCmd[1] ) zCmd++;
}
/* --help lists all test-controls */
if( cli_strcmp(zCmd,"help")==0 ){
oputz("Available test-controls:\n");
for(i=0; i<ArraySize(aCtrl); i++){
if( aCtrl[i].unSafe && !ShellHasFlag(p,SHFLG_TestingMode) ) continue;
oputf(" .testctrl %s %s\n",
aCtrl[i].zCtrlName, aCtrl[i].zUsage);
}
rc = 1;
goto meta_command_exit;
}
/* convert testctrl text option to value. allow any unique prefix
** of the option name, or a numerical value. */
n2 = strlen30(zCmd);
for(i=0; i<ArraySize(aCtrl); i++){
if( aCtrl[i].unSafe && !ShellHasFlag(p,SHFLG_TestingMode) ) continue;
if( cli_strncmp(zCmd, aCtrl[i].zCtrlName, n2)==0 ){
if( testctrl<0 ){
testctrl = aCtrl[i].ctrlCode;
iCtrl = i;
}else{
eputf("Error: ambiguous test-control: \"%s\"\n"
"Use \".testctrl --help\" for help\n", zCmd);
rc = 1;
goto meta_command_exit;
}
}
}
if( testctrl<0 ){
eputf("Error: unknown test-control: %s\n"
"Use \".testctrl --help\" for help\n", zCmd);
}else{
switch(testctrl){
/* sqlite3_test_control(int, db, int) */
case SQLITE_TESTCTRL_OPTIMIZATIONS:
case SQLITE_TESTCTRL_FK_NO_ACTION:
if( nArg==3 ){
|
| ︙ | ︙ | |||
26985 26986 26987 26988 26989 26990 26991 |
/* sqlite3_test_control(int, int, sqlite3*) */
case SQLITE_TESTCTRL_PRNG_SEED:
if( nArg==3 || nArg==4 ){
int ii = (int)integerValue(azArg[2]);
sqlite3 *db;
if( ii==0 && cli_strcmp(azArg[2],"random")==0 ){
sqlite3_randomness(sizeof(ii),&ii);
| | | 27705 27706 27707 27708 27709 27710 27711 27712 27713 27714 27715 27716 27717 27718 27719 |
/* sqlite3_test_control(int, int, sqlite3*) */
case SQLITE_TESTCTRL_PRNG_SEED:
if( nArg==3 || nArg==4 ){
int ii = (int)integerValue(azArg[2]);
sqlite3 *db;
if( ii==0 && cli_strcmp(azArg[2],"random")==0 ){
sqlite3_randomness(sizeof(ii),&ii);
sputf(stdout, "-- random seed: %d\n", ii);
}
if( nArg==3 ){
db = 0;
}else{
db = p->db;
/* Make sure the schema has been loaded */
sqlite3_table_column_metadata(db, 0, "x", 0, 0, 0, 0, 0, 0);
|
| ︙ | ︙ | |||
27053 27054 27055 27056 27057 27058 27059 |
isOk = 3;
}
break;
case SQLITE_TESTCTRL_SEEK_COUNT: {
u64 x = 0;
rc2 = sqlite3_test_control(testctrl, p->db, &x);
| | | 27773 27774 27775 27776 27777 27778 27779 27780 27781 27782 27783 27784 27785 27786 27787 |
isOk = 3;
}
break;
case SQLITE_TESTCTRL_SEEK_COUNT: {
u64 x = 0;
rc2 = sqlite3_test_control(testctrl, p->db, &x);
oputf("%llu\n", x);
isOk = 3;
break;
}
#ifdef YYCOVERAGE
case SQLITE_TESTCTRL_PARSER_COVERAGE: {
if( nArg==2 ){
|
| ︙ | ︙ | |||
27084 27085 27086 27087 27088 27089 27090 |
isOk = 1;
}else if( nArg==2 ){
int id = 1;
while(1){
int val = 0;
rc2 = sqlite3_test_control(testctrl, -id, &val);
if( rc2!=SQLITE_OK ) break;
| | | | | | | | | | 27804 27805 27806 27807 27808 27809 27810 27811 27812 27813 27814 27815 27816 27817 27818 27819 27820 27821 27822 27823 27824 27825 27826 27827 27828 27829 27830 27831 27832 27833 27834 27835 27836 27837 27838 27839 27840 27841 27842 27843 27844 27845 27846 27847 27848 27849 27850 27851 27852 27853 27854 27855 27856 27857 27858 27859 27860 27861 |
isOk = 1;
}else if( nArg==2 ){
int id = 1;
while(1){
int val = 0;
rc2 = sqlite3_test_control(testctrl, -id, &val);
if( rc2!=SQLITE_OK ) break;
if( id>1 ) oputz(" ");
oputf("%d: %d", id, val);
id++;
}
if( id>1 ) oputz("\n");
isOk = 3;
}
break;
}
#endif
case SQLITE_TESTCTRL_SORTER_MMAP:
if( nArg==3 ){
int opt = (unsigned int)integerValue(azArg[2]);
rc2 = sqlite3_test_control(testctrl, p->db, opt);
isOk = 3;
}
break;
}
}
if( isOk==0 && iCtrl>=0 ){
oputf("Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
rc = 1;
}else if( isOk==1 ){
oputf("%d\n", rc2);
}else if( isOk==2 ){
oputf("0x%08x\n", rc2);
}
}else
#endif /* !defined(SQLITE_UNTESTABLE) */
if( c=='t' && n>4 && cli_strncmp(azArg[0], "timeout", n)==0 ){
open_db(p, 0);
sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
}else
if( c=='t' && n>=5 && cli_strncmp(azArg[0], "timer", n)==0 ){
if( nArg==2 ){
enableTimer = booleanValue(azArg[1]);
if( enableTimer && !HAS_TIMER ){
eputz("Error: timer not available on this system.\n");
enableTimer = 0;
}
}else{
eputz("Usage: .timer on|off\n");
rc = 1;
}
}else
#ifndef SQLITE_OMIT_TRACE
if( c=='t' && cli_strncmp(azArg[0], "trace", n)==0 ){
int mType = 0;
|
| ︙ | ︙ | |||
27164 27165 27166 27167 27168 27169 27170 |
else if( optionMatch(z, "stmt") ){
mType |= SQLITE_TRACE_STMT;
}
else if( optionMatch(z, "close") ){
mType |= SQLITE_TRACE_CLOSE;
}
else {
| | | 27884 27885 27886 27887 27888 27889 27890 27891 27892 27893 27894 27895 27896 27897 27898 |
else if( optionMatch(z, "stmt") ){
mType |= SQLITE_TRACE_STMT;
}
else if( optionMatch(z, "close") ){
mType |= SQLITE_TRACE_CLOSE;
}
else {
eputf("Unknown option \"%s\" on \".trace\"\n", z);
rc = 1;
goto meta_command_exit;
}
}else{
output_file_close(p->traceOut);
p->traceOut = output_file_open(z, 0);
}
|
| ︙ | ︙ | |||
27188 27189 27190 27191 27192 27193 27194 |
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
if( c=='u' && cli_strncmp(azArg[0], "unmodule", n)==0 ){
int ii;
int lenOpt;
char *zOpt;
if( nArg<2 ){
| | | 27908 27909 27910 27911 27912 27913 27914 27915 27916 27917 27918 27919 27920 27921 27922 |
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
if( c=='u' && cli_strncmp(azArg[0], "unmodule", n)==0 ){
int ii;
int lenOpt;
char *zOpt;
if( nArg<2 ){
eputz("Usage: .unmodule [--allexcept] NAME ...\n");
rc = 1;
goto meta_command_exit;
}
open_db(p, 0);
zOpt = azArg[1];
if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++;
lenOpt = (int)strlen(zOpt);
|
| ︙ | ︙ | |||
27210 27211 27212 27213 27214 27215 27216 |
}
}else
#endif
#if SQLITE_USER_AUTHENTICATION
if( c=='u' && cli_strncmp(azArg[0], "user", n)==0 ){
if( nArg<2 ){
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 27930 27931 27932 27933 27934 27935 27936 27937 27938 27939 27940 27941 27942 27943 27944 27945 27946 27947 27948 27949 27950 27951 27952 27953 27954 27955 27956 27957 27958 27959 27960 27961 27962 27963 27964 27965 27966 27967 27968 27969 27970 27971 27972 27973 27974 27975 27976 27977 27978 27979 27980 27981 27982 27983 27984 27985 27986 27987 27988 27989 27990 27991 27992 27993 27994 27995 27996 27997 27998 27999 28000 28001 28002 28003 28004 28005 28006 28007 28008 28009 28010 28011 28012 28013 28014 28015 28016 28017 28018 28019 28020 28021 28022 28023 28024 28025 28026 28027 28028 28029 28030 28031 28032 28033 28034 28035 28036 28037 28038 28039 28040 28041 28042 28043 28044 28045 28046 28047 28048 28049 28050 28051 28052 28053 28054 28055 28056 28057 28058 28059 28060 28061 28062 |
}
}else
#endif
#if SQLITE_USER_AUTHENTICATION
if( c=='u' && cli_strncmp(azArg[0], "user", n)==0 ){
if( nArg<2 ){
eputz("Usage: .user SUBCOMMAND ...\n");
rc = 1;
goto meta_command_exit;
}
open_db(p, 0);
if( cli_strcmp(azArg[1],"login")==0 ){
if( nArg!=4 ){
eputz("Usage: .user login USER PASSWORD\n");
rc = 1;
goto meta_command_exit;
}
rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
strlen30(azArg[3]));
if( rc ){
eputf("Authentication failed for user %s\n", azArg[2]);
rc = 1;
}
}else if( cli_strcmp(azArg[1],"add")==0 ){
if( nArg!=5 ){
eputz("Usage: .user add USER PASSWORD ISADMIN\n");
rc = 1;
goto meta_command_exit;
}
rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
booleanValue(azArg[4]));
if( rc ){
eputf("User-Add failed: %d\n", rc);
rc = 1;
}
}else if( cli_strcmp(azArg[1],"edit")==0 ){
if( nArg!=5 ){
eputz("Usage: .user edit USER PASSWORD ISADMIN\n");
rc = 1;
goto meta_command_exit;
}
rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
booleanValue(azArg[4]));
if( rc ){
eputf("User-Edit failed: %d\n", rc);
rc = 1;
}
}else if( cli_strcmp(azArg[1],"delete")==0 ){
if( nArg!=3 ){
eputz("Usage: .user delete USER\n");
rc = 1;
goto meta_command_exit;
}
rc = sqlite3_user_delete(p->db, azArg[2]);
if( rc ){
eputf("User-Delete failed: %d\n", rc);
rc = 1;
}
}else{
eputz("Usage: .user login|add|edit|delete ...\n");
rc = 1;
goto meta_command_exit;
}
}else
#endif /* SQLITE_USER_AUTHENTICATION */
if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){
char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit";
oputf("SQLite %s %s\n" /*extra-version-info*/,
sqlite3_libversion(), sqlite3_sourceid());
#if SQLITE_HAVE_ZLIB
oputf("zlib version %s\n", zlibVersion());
#endif
#define CTIMEOPT_VAL_(opt) #opt
#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
#if defined(__clang__) && defined(__clang_major__)
oputf("clang-" CTIMEOPT_VAL(__clang_major__) "."
CTIMEOPT_VAL(__clang_minor__) "."
CTIMEOPT_VAL(__clang_patchlevel__) " (%s)\n", zPtrSz);
#elif defined(_MSC_VER)
oputf("msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz);
#elif defined(__GNUC__) && defined(__VERSION__)
oputf("gcc-" __VERSION__ " (%s)\n", zPtrSz);
#endif
}else
if( c=='v' && cli_strncmp(azArg[0], "vfsinfo", n)==0 ){
const char *zDbName = nArg==2 ? azArg[1] : "main";
sqlite3_vfs *pVfs = 0;
if( p->db ){
sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
if( pVfs ){
oputf("vfs.zName = \"%s\"\n", pVfs->zName);
oputf("vfs.iVersion = %d\n", pVfs->iVersion);
oputf("vfs.szOsFile = %d\n", pVfs->szOsFile);
oputf("vfs.mxPathname = %d\n", pVfs->mxPathname);
}
}
}else
if( c=='v' && cli_strncmp(azArg[0], "vfslist", n)==0 ){
sqlite3_vfs *pVfs;
sqlite3_vfs *pCurrent = 0;
if( p->db ){
sqlite3_file_control(p->db, "main", SQLITE_FCNTL_VFS_POINTER, &pCurrent);
}
for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
oputf("vfs.zName = \"%s\"%s\n", pVfs->zName,
pVfs==pCurrent ? " <--- CURRENT" : "");
oputf("vfs.iVersion = %d\n", pVfs->iVersion);
oputf("vfs.szOsFile = %d\n", pVfs->szOsFile);
oputf("vfs.mxPathname = %d\n", pVfs->mxPathname);
if( pVfs->pNext ){
oputz("-----------------------------------\n");
}
}
}else
if( c=='v' && cli_strncmp(azArg[0], "vfsname", n)==0 ){
const char *zDbName = nArg==2 ? azArg[1] : "main";
char *zVfsName = 0;
if( p->db ){
sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
if( zVfsName ){
oputf("%s\n", zVfsName);
sqlite3_free(zVfsName);
}
}
}else
if( c=='w' && cli_strncmp(azArg[0], "wheretrace", n)==0 ){
unsigned int x = nArg>=2? (unsigned int)integerValue(azArg[1]) : 0xffffffff;
|
| ︙ | ︙ | |||
27352 27353 27354 27355 27356 27357 27358 |
if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
for(j=1; j<nArg; j++){
p->colWidth[j-1] = (int)integerValue(azArg[j]);
}
}else
{
| | | | 28072 28073 28074 28075 28076 28077 28078 28079 28080 28081 28082 28083 28084 28085 28086 28087 |
if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
for(j=1; j<nArg; j++){
p->colWidth[j-1] = (int)integerValue(azArg[j]);
}
}else
{
eputf("Error: unknown command or invalid arguments: "
" \"%s\". Enter \".help\" for help\n", azArg[0]);
rc = 1;
}
meta_command_exit:
if( p->outCount ){
p->outCount--;
if( p->outCount==0 ) output_reset(p);
|
| ︙ | ︙ | |||
27543 27544 27545 27546 27547 27548 27549 |
}
if( in!=0 || !stdin_is_interactive ){
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
"%s near line %d:", zErrorType, startline);
}else{
sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType);
}
| | | | | 28263 28264 28265 28266 28267 28268 28269 28270 28271 28272 28273 28274 28275 28276 28277 28278 28279 28280 28281 28282 28283 28284 28285 28286 28287 28288 28289 28290 28291 28292 |
}
if( in!=0 || !stdin_is_interactive ){
sqlite3_snprintf(sizeof(zPrefix), zPrefix,
"%s near line %d:", zErrorType, startline);
}else{
sqlite3_snprintf(sizeof(zPrefix), zPrefix, "%s:", zErrorType);
}
eputf("%s %s\n", zPrefix, zErrorTail);
sqlite3_free(zErrMsg);
zErrMsg = 0;
return 1;
}else if( ShellHasFlag(p, SHFLG_CountChanges) ){
char zLineBuf[2000];
sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
"changes: %lld total_changes: %lld",
sqlite3_changes64(p->db), sqlite3_total_changes64(p->db));
oputf("%s\n", zLineBuf);
}
return 0;
}
static void echo_group_input(ShellState *p, const char *zDo){
if( ShellHasFlag(p, SHFLG_Echo) ) oputf("%s\n", zDo);
}
#ifdef SQLITE_SHELL_FIDDLE
/*
** Alternate one_input_line() impl for wasm mode. This is not in the primary
** impl because we need the global shellState and cannot access it from that
** function without moving lots of code around (creating a larger/messier diff).
|
| ︙ | ︙ | |||
27616 27617 27618 27619 27620 27621 27622 |
int rc; /* Error code */
int errCnt = 0; /* Number of errors seen */
i64 startline = 0; /* Line number for start of current input */
QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
if( p->inputNesting==MAX_INPUT_NESTING ){
/* This will be more informative in a later version. */
| | | | | 28336 28337 28338 28339 28340 28341 28342 28343 28344 28345 28346 28347 28348 28349 28350 28351 28352 28353 28354 28355 28356 28357 28358 28359 28360 28361 28362 |
int rc; /* Error code */
int errCnt = 0; /* Number of errors seen */
i64 startline = 0; /* Line number for start of current input */
QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */
if( p->inputNesting==MAX_INPUT_NESTING ){
/* This will be more informative in a later version. */
eputf("Input nesting limit (%d) reached at line %d."
" Check recursion.\n", MAX_INPUT_NESTING, p->lineno);
return 1;
}
++p->inputNesting;
p->lineno = 0;
CONTINUE_PROMPT_RESET;
while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
fflush(p->out);
zLine = one_input_line(p->in, zLine, nSql>0);
if( zLine==0 ){
/* End of input */
if( p->in==0 && stdin_is_interactive ) oputz("\n");
break;
}
if( seenInterrupt ){
if( p->in!=0 ) break;
seenInterrupt = 0;
}
p->lineno++;
|
| ︙ | ︙ | |||
27838 27839 27840 27841 27842 27843 27844 |
if( sqliterc == NULL ){
sqliterc = find_xdg_config();
}
if( sqliterc == NULL ){
home_dir = find_home_dir(0);
if( home_dir==0 ){
| | | | | | 28558 28559 28560 28561 28562 28563 28564 28565 28566 28567 28568 28569 28570 28571 28572 28573 28574 28575 28576 28577 28578 28579 28580 28581 28582 28583 28584 28585 28586 28587 28588 |
if( sqliterc == NULL ){
sqliterc = find_xdg_config();
}
if( sqliterc == NULL ){
home_dir = find_home_dir(0);
if( home_dir==0 ){
eputz("-- warning: cannot find home directory;"
" cannot read ~/.sqliterc\n");
return;
}
zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
shell_check_oom(zBuf);
sqliterc = zBuf;
}
p->in = fopen(sqliterc,"rb");
if( p->in ){
if( stdin_is_interactive ){
eputf("-- Loading resources from %s\n", sqliterc);
}
if( process_input(p) && bail_on_error ) exit(1);
fclose(p->in);
}else if( sqliterc_override!=0 ){
eputf("cannot open: \"%s\"\n", sqliterc);
if( bail_on_error ) exit(1);
}
p->in = inSaved;
p->lineno = savedLineno;
sqlite3_free(zBuf);
}
|
| ︙ | ︙ | |||
27904 27905 27906 27907 27908 27909 27910 | #endif " -memtrace trace all memory allocations and deallocations\n" " -mmap N default mmap size set to N\n" #ifdef SQLITE_ENABLE_MULTIPLEX " -multiplex enable the multiplexor VFS\n" #endif " -newline SEP set output row separator. Default: '\\n'\n" | < < < < < < < | | | | | | | | 28624 28625 28626 28627 28628 28629 28630 28631 28632 28633 28634 28635 28636 28637 28638 28639 28640 28641 28642 28643 28644 28645 28646 28647 28648 28649 28650 28651 28652 28653 28654 28655 28656 28657 28658 28659 28660 28661 28662 28663 28664 28665 28666 28667 28668 28669 28670 28671 28672 28673 28674 28675 28676 28677 28678 28679 28680 28681 28682 |
#endif
" -memtrace trace all memory allocations and deallocations\n"
" -mmap N default mmap size set to N\n"
#ifdef SQLITE_ENABLE_MULTIPLEX
" -multiplex enable the multiplexor VFS\n"
#endif
" -newline SEP set output row separator. Default: '\\n'\n"
" -nofollow refuse to open symbolic links to database files\n"
" -nonce STRING set the safe-mode escape nonce\n"
" -nullvalue TEXT set text string for NULL values. Default ''\n"
" -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n"
" -pcachetrace trace all page cache operations\n"
" -quote set output mode to 'quote'\n"
" -readonly open the database read-only\n"
" -safe enable safe-mode\n"
" -separator SEP set output column separator. Default: '|'\n"
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
" -sorterref SIZE sorter references threshold size\n"
#endif
" -stats print memory stats before each finalize\n"
" -table set output mode to 'table'\n"
" -tabs set output mode to 'tabs'\n"
" -unsafe-testing allow unsafe commands and modes for testing\n"
" -version show SQLite version\n"
" -vfs NAME use NAME as the default VFS\n"
#ifdef SQLITE_ENABLE_VFSTRACE
" -vfstrace enable tracing of all VFS calls\n"
#endif
#ifdef SQLITE_HAVE_ZLIB
" -zip open the file as a ZIP Archive\n"
#endif
;
static void usage(int showDetail){
eputf("Usage: %s [OPTIONS] [FILENAME [SQL]]\n"
"FILENAME is the name of an SQLite database. A new database is created\n"
"if the file does not previously exist. Defaults to :memory:.\n", Argv0);
if( showDetail ){
eputf("OPTIONS include:\n%s", zOptions);
}else{
eputz("Use the -help option for additional information\n");
}
exit(1);
}
/*
** Internal check: Verify that the SQLite is uninitialized. Print a
** error message if it is initialized.
*/
static void verify_uninitialized(void){
if( sqlite3_config(-1)==SQLITE_MISUSE ){
sputz(stdout, "WARNING: attempt to configure SQLite after"
" initialization.\n");
}
}
/*
** Initialize the state information in data
*/
static void main_init(ShellState *data) {
|
| ︙ | ︙ | |||
27984 27985 27986 27987 27988 27989 27990 | sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); } /* ** Output text to the console in a font that attracts extra attention. */ | | | | | < | | 28697 28698 28699 28700 28701 28702 28703 28704 28705 28706 28707 28708 28709 28710 28711 28712 28713 28714 28715 28716 28717 28718 28719 28720 28721 28722 28723 28724 28725 28726 28727 28728 28729 28730 28731 28732 28733 28734 28735 28736 28737 28738 28739 28740 28741 28742 28743 28744 28745 |
sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> ");
sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> ");
}
/*
** Output text to the console in a font that attracts extra attention.
*/
#if defined(_WIN32) || defined(WIN32)
static void printBold(const char *zText){
#if !SQLITE_OS_WINRT
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
SetConsoleTextAttribute(out,
FOREGROUND_RED|FOREGROUND_INTENSITY
);
#endif
oputz(zText);
#if !SQLITE_OS_WINRT
SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
#endif
}
#else
static void printBold(const char *zText){
oputf("\033[1m%s\033[0m", zText);
}
#endif
/*
** Get the argument to an --option. Throw an error and die if no argument
** is available.
*/
static char *cmdline_option_value(int argc, char **argv, int i){
if( i==argc ){
eputf("%s: Error: missing argument to %s\n", argv[0], argv[argc-1]);
exit(1);
}
return argv[i];
}
static void sayAbnormalExit(void){
if( seenInterrupt ) eputz("Program interrupted.\n");
}
#ifndef SQLITE_SHELL_IS_UTF8
# if (defined(_WIN32) || defined(WIN32)) \
&& (defined(_MSC_VER) || (defined(UNICODE) && defined(__GNUC__)))
# define SQLITE_SHELL_IS_UTF8 (0)
# else
|
| ︙ | ︙ | |||
28049 28050 28051 28052 28053 28054 28055 28056 28057 28058 28059 28060 28061 28062 | sqlite3_int64 mem_main_enter = 0; #endif char *zErrMsg = 0; #ifdef SQLITE_SHELL_FIDDLE # define data shellState #else ShellState data; #endif const char *zInitFile = 0; int i; int rc = 0; int warnInmemoryDb = 0; int readStdin = 1; int nCmd = 0; | > | 28761 28762 28763 28764 28765 28766 28767 28768 28769 28770 28771 28772 28773 28774 28775 | sqlite3_int64 mem_main_enter = 0; #endif char *zErrMsg = 0; #ifdef SQLITE_SHELL_FIDDLE # define data shellState #else ShellState data; StreamsAreConsole consStreams = SAC_NoConsole; #endif const char *zInitFile = 0; int i; int rc = 0; int warnInmemoryDb = 0; int readStdin = 1; int nCmd = 0; |
| ︙ | ︙ | |||
28070 28071 28072 28073 28074 28075 28076 | setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */ #ifdef SQLITE_SHELL_FIDDLE stdin_is_interactive = 0; stdout_is_console = 1; data.wasm.zDefaultDbName = "/fiddle.sqlite3"; #else | > | | < < < | < | | | | | | 28783 28784 28785 28786 28787 28788 28789 28790 28791 28792 28793 28794 28795 28796 28797 28798 28799 28800 28801 28802 28803 28804 28805 28806 28807 28808 28809 28810 28811 28812 28813 28814 28815 28816 28817 28818 28819 28820 28821 28822 28823 28824 28825 28826 28827 28828 28829 28830 28831 28832 28833 28834 28835 28836 28837 |
setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
#ifdef SQLITE_SHELL_FIDDLE
stdin_is_interactive = 0;
stdout_is_console = 1;
data.wasm.zDefaultDbName = "/fiddle.sqlite3";
#else
consStreams = consoleClassifySetup(stdin, stdout, stderr);
stdin_is_interactive = (consStreams & SAC_InConsole)!=0;
stdout_is_console = (consStreams & SAC_OutConsole)!=0;
atexit(consoleRestore);
#endif
atexit(sayAbnormalExit);
#ifdef SQLITE_DEBUG
mem_main_enter = sqlite3_memory_used();
#endif
#if !defined(_WIN32_WCE)
if( getenv("SQLITE_DEBUG_BREAK") ){
if( isatty(0) && isatty(2) ){
eputf("attach debugger to process %d and press any key to continue.\n",
GETPID());
fgetc(stdin);
}else{
#if defined(_WIN32) || defined(WIN32)
#if SQLITE_OS_WINRT
__debugbreak();
#else
DebugBreak();
#endif
#elif defined(SIGTRAP)
raise(SIGTRAP);
#endif
}
}
#endif
/* Register a valid signal handler early, before much else is done. */
#ifdef SIGINT
signal(SIGINT, interrupt_handler);
#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE)
if( !SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE) ){
eputz("No ^C handler.\n");
}
#endif
#if USE_SYSTEM_SQLITE+0!=1
if( cli_strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
eputf("SQLite header and source version mismatch\n%s\n%s\n",
sqlite3_sourceid(), SQLITE_SOURCE_ID);
exit(1);
}
#endif
main_init(&data);
/* On Windows, we must translate command-line arguments into UTF-8.
** The SQLite memory allocator subsystem has to be enabled in order to
|
| ︙ | ︙ | |||
28209 28210 28211 28212 28213 28214 28215 |
}else if( cli_strcmp(z,"-batch")==0 ){
/* Need to check for batch mode here to so we can avoid printing
** informational messages (like from process_sqliterc) before
** we do the actual processing of arguments later in a second pass.
*/
stdin_is_interactive = 0;
}else if( cli_strcmp(z,"-utf8")==0 ){
| < < < < < < < | 28919 28920 28921 28922 28923 28924 28925 28926 28927 28928 28929 28930 28931 28932 28933 |
}else if( cli_strcmp(z,"-batch")==0 ){
/* Need to check for batch mode here to so we can avoid printing
** informational messages (like from process_sqliterc) before
** we do the actual processing of arguments later in a second pass.
*/
stdin_is_interactive = 0;
}else if( cli_strcmp(z,"-utf8")==0 ){
}else if( cli_strcmp(z,"-no-utf8")==0 ){
}else if( cli_strcmp(z,"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
const char *zSize;
sqlite3_int64 szHeap;
zSize = cmdline_option_value(argc, argv, ++i);
szHeap = integerValue(zSize);
|
| ︙ | ︙ | |||
28351 28352 28353 28354 28355 28356 28357 |
#endif
if( zVfs ){
sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
if( pVfs ){
sqlite3_vfs_register(pVfs, 1);
}else{
| | < < < < < < < < < | | 29054 29055 29056 29057 29058 29059 29060 29061 29062 29063 29064 29065 29066 29067 29068 29069 29070 29071 29072 29073 29074 29075 29076 29077 29078 |
#endif
if( zVfs ){
sqlite3_vfs *pVfs = sqlite3_vfs_find(zVfs);
if( pVfs ){
sqlite3_vfs_register(pVfs, 1);
}else{
eputf("no such VFS: \"%s\"\n", zVfs);
exit(1);
}
}
if( data.pAuxDb->zDbFilename==0 ){
#ifndef SQLITE_OMIT_MEMORYDB
data.pAuxDb->zDbFilename = ":memory:";
warnInmemoryDb = argc==1;
#else
eputf("%s: Error: no database filename specified\n", Argv0);
return 1;
#endif
}
data.out = stdout;
#ifndef SQLITE_SHELL_FIDDLE
sqlite3_appendvfs_init(0,0,0);
#endif
|
| ︙ | ︙ | |||
28487 28488 28489 28490 28491 28492 28493 |
** prior to sending the SQL into SQLite. Useful for injecting
** crazy bytes in the middle of SQL statements for testing and debugging.
*/
ShellSetFlag(&data, SHFLG_Backslash);
}else if( cli_strcmp(z,"-bail")==0 ){
/* No-op. The bail_on_error flag should already be set. */
}else if( cli_strcmp(z,"-version")==0 ){
| | | | 29181 29182 29183 29184 29185 29186 29187 29188 29189 29190 29191 29192 29193 29194 29195 29196 |
** prior to sending the SQL into SQLite. Useful for injecting
** crazy bytes in the middle of SQL statements for testing and debugging.
*/
ShellSetFlag(&data, SHFLG_Backslash);
}else if( cli_strcmp(z,"-bail")==0 ){
/* No-op. The bail_on_error flag should already be set. */
}else if( cli_strcmp(z,"-version")==0 ){
oputf("%s %s (%d-bit)\n", sqlite3_libversion(), sqlite3_sourceid(),
8*(int)sizeof(char*));
return 0;
}else if( cli_strcmp(z,"-interactive")==0 ){
/* already handled */
}else if( cli_strcmp(z,"-batch")==0 ){
/* already handled */
}else if( cli_strcmp(z,"-utf8")==0 ){
/* already handled */
|
| ︙ | ︙ | |||
28544 28545 28546 28547 28548 28549 28550 |
if( z[0]=='.' ){
rc = do_meta_command(z, &data);
if( rc && bail_on_error ) return rc==2 ? 0 : rc;
}else{
open_db(&data, 0);
rc = shell_exec(&data, z, &zErrMsg);
if( zErrMsg!=0 ){
| | | | | | | | 29238 29239 29240 29241 29242 29243 29244 29245 29246 29247 29248 29249 29250 29251 29252 29253 29254 29255 29256 29257 29258 29259 29260 29261 29262 29263 29264 29265 29266 29267 29268 29269 29270 29271 29272 29273 29274 29275 29276 29277 29278 29279 29280 29281 29282 |
if( z[0]=='.' ){
rc = do_meta_command(z, &data);
if( rc && bail_on_error ) return rc==2 ? 0 : rc;
}else{
open_db(&data, 0);
rc = shell_exec(&data, z, &zErrMsg);
if( zErrMsg!=0 ){
eputf("Error: %s\n", zErrMsg);
if( bail_on_error ) return rc!=0 ? rc : 1;
}else if( rc!=0 ){
eputf("Error: unable to process SQL \"%s\"\n", z);
if( bail_on_error ) return rc;
}
}
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
}else if( cli_strncmp(z, "-A", 2)==0 ){
if( nCmd>0 ){
eputf("Error: cannot mix regular SQL or dot-commands"
" with \"%s\"\n", z);
return 1;
}
open_db(&data, OPEN_DB_ZIPFILE);
if( z[2] ){
argv[i] = &z[2];
arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
}else{
arDotCommand(&data, 1, argv+i, argc-i);
}
readStdin = 0;
break;
#endif
}else if( cli_strcmp(z,"-safe")==0 ){
data.bSafeMode = data.bSafeModePersist = 1;
}else if( cli_strcmp(z,"-unsafe-testing")==0 ){
/* Acted upon in first pass. */
}else{
eputf("%s: Error: unknown option: %s\n", Argv0, z);
eputz("Use -help for a list of options.\n");
return 1;
}
data.cMode = data.mode;
}
if( !readStdin ){
/* Run all arguments that do not begin with '-' as if they were separate
|
| ︙ | ︙ | |||
28598 28599 28600 28601 28602 28603 28604 |
}
}else{
open_db(&data, 0);
echo_group_input(&data, azCmd[i]);
rc = shell_exec(&data, azCmd[i], &zErrMsg);
if( zErrMsg || rc ){
if( zErrMsg!=0 ){
| | | < | | > | < < < < < | | | < | | | | 29292 29293 29294 29295 29296 29297 29298 29299 29300 29301 29302 29303 29304 29305 29306 29307 29308 29309 29310 29311 29312 29313 29314 29315 29316 29317 29318 29319 29320 29321 29322 29323 29324 29325 29326 29327 29328 29329 29330 29331 29332 29333 29334 29335 |
}
}else{
open_db(&data, 0);
echo_group_input(&data, azCmd[i]);
rc = shell_exec(&data, azCmd[i], &zErrMsg);
if( zErrMsg || rc ){
if( zErrMsg!=0 ){
eputf("Error: %s\n", zErrMsg);
}else{
eputf("Error: unable to process SQL: %s\n", azCmd[i]);
}
sqlite3_free(zErrMsg);
free(azCmd);
return rc!=0 ? rc : 1;
}
}
}
}else{
/* Run commands received from standard input
*/
if( stdin_is_interactive ){
char *zHome;
char *zHistory;
int nHistory;
#if CIO_WIN_WC_XLATE
# define SHELL_CIO_CHAR_SET (stdout_is_console? " (UTF-16 console I/O)" : "")
#else
# define SHELL_CIO_CHAR_SET ""
#endif
oputf("SQLite version %s %.19s%s\n" /*extra-version-info*/
"Enter \".help\" for usage hints.\n",
sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);
if( warnInmemoryDb ){
oputz("Connected to a ");
printBold("transient in-memory database");
oputz(".\nUse \".open FILENAME\" to reopen on a"
" persistent database.\n");
}
zHistory = getenv("SQLITE_HISTORY");
if( zHistory ){
zHistory = strdup(zHistory);
}else if( (zHome = find_home_dir(0))!=0 ){
nHistory = strlen30(zHome) + 20;
if( (zHistory = malloc(nHistory))!=0 ){
|
| ︙ | ︙ | |||
28693 28694 28695 28696 28697 28698 28699 |
free(data.colWidth);
free(data.zNonce);
/* Clear the global data structure so that valgrind will detect memory
** leaks */
memset(&data, 0, sizeof(data));
#ifdef SQLITE_DEBUG
if( sqlite3_memory_used()>mem_main_enter ){
| | | | 29381 29382 29383 29384 29385 29386 29387 29388 29389 29390 29391 29392 29393 29394 29395 29396 |
free(data.colWidth);
free(data.zNonce);
/* Clear the global data structure so that valgrind will detect memory
** leaks */
memset(&data, 0, sizeof(data));
#ifdef SQLITE_DEBUG
if( sqlite3_memory_used()>mem_main_enter ){
eputf("Memory leaked: %u bytes\n",
(unsigned int)(sqlite3_memory_used()-mem_main_enter));
}
#endif
#endif /* !SQLITE_SHELL_FIDDLE */
return rc;
}
|
| ︙ | ︙ |
Changes to extsrc/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.44.1. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines ** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy embedded within ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed ** if you want a wrapper to interface SQLite with your choice of programming ** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in ** d295f48e8f367b066b881780c98bdf980a1d. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE # define SQLITE_PRIVATE static #endif /************** Begin file sqliteInt.h ***************************************/ |
| ︙ | ︙ | |||
455 456 457 458 459 460 461 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.44.1" #define SQLITE_VERSION_NUMBER 3044001 #define SQLITE_SOURCE_ID "2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
5882 5883 5884 5885 5886 5887 5888 | ** are innocuous. Developers are advised to avoid using the ** SQLITE_INNOCUOUS flag for application-defined functions unless the ** function has been carefully audited and found to be free of potentially ** security-adverse side-effects and information-leaks. ** </dd> ** ** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd> | | | | | | > | > > > > > > > > > > > > > > | 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 | ** are innocuous. Developers are advised to avoid using the ** SQLITE_INNOCUOUS flag for application-defined functions unless the ** function has been carefully audited and found to be free of potentially ** security-adverse side-effects and information-leaks. ** </dd> ** ** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd> ** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. ** This flag instructs SQLite to omit some corner-case optimizations that ** might disrupt the operation of the [sqlite3_value_subtype()] function, ** causing it to return zero rather than the correct subtype(). ** SQL functions that invokes [sqlite3_value_subtype()] should have this ** property. If the SQLITE_SUBTYPE property is omitted, then the return ** value from [sqlite3_value_subtype()] might sometimes be zero even though ** a non-zero subtype was specified by the function argument expression. ** ** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd> ** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_result_subtype()] to cause a sub-type to be associated with its ** result. ** Every function that invokes [sqlite3_result_subtype()] should have this ** property. If it does not, then the call to [sqlite3_result_subtype()] ** might become a no-op if the function is used as term in an ** [expression index]. On the other hand, SQL functions that never invoke ** [sqlite3_result_subtype()] should avoid setting this property, as the ** purpose of this property is to disable certain optimizations that are ** incompatible with subtypes. ** </dd> ** </dl> */ #define SQLITE_DETERMINISTIC 0x000000800 #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 #define SQLITE_RESULT_SUBTYPE 0x001000000 /* ** CAPI3REF: Deprecated Functions ** DEPRECATED ** ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue |
| ︙ | ︙ | |||
6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 | ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for ** an [application-defined SQL function] argument V. The subtype ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); /* ** CAPI3REF: Copy And Free SQL Values ** METHOD: sqlite3_value ** | > > > > > > | 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 | ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for ** an [application-defined SQL function] argument V. The subtype ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. ** ** Every [application-defined SQL function] that invoke this interface ** should include the [SQLITE_SUBTYPE] property in the text ** encoding argument when the function is [sqlite3_create_function|registered]. ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() ** might return zero instead of the upstream subtype in some corner cases. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); /* ** CAPI3REF: Copy And Free SQL Values ** METHOD: sqlite3_value ** |
| ︙ | ︙ | |||
6222 6223 6224 6225 6226 6227 6228 | ** SQLite is free to discard the auxiliary data at any time, including: <ul> ** <li> ^(when the corresponding function parameter changes)^, or ** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement)^, or ** <li> ^(when sqlite3_set_auxdata() is invoked again on the same ** parameter)^, or ** <li> ^(during the original sqlite3_set_auxdata() call when a memory | | > > > | | > > > > > | 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 | ** SQLite is free to discard the auxiliary data at any time, including: <ul> ** <li> ^(when the corresponding function parameter changes)^, or ** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement)^, or ** <li> ^(when sqlite3_set_auxdata() is invoked again on the same ** parameter)^, or ** <li> ^(during the original sqlite3_set_auxdata() call when a memory ** allocation error occurs.)^ ** <li> ^(during the original sqlite3_set_auxdata() call if the function ** is evaluated during query planning instead of during query execution, ** as sometimes happens with [SQLITE_ENABLE_STAT4].)^ </ul> ** ** Note the last two bullets in particular. The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after ** sqlite3_set_auxdata() has been called. Furthermore, a call to ** sqlite3_get_auxdata() that occurs immediately after a corresponding call ** to sqlite3_set_auxdata() might still return NULL if an out-of-memory ** condition occurred during the sqlite3_set_auxdata() call or if the ** function is being evaluated during query planning rather than during ** query execution. ** ** ^(In practice, auxiliary data is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** ** The value of the N parameter to these interfaces should be non-negative. ** Future enhancements may make use of negative N values to define new |
| ︙ | ︙ | |||
6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 | ** The sqlite3_result_subtype(C,T) function causes the subtype of ** the result from the [application-defined SQL function] with ** [sqlite3_context] C to be the value T. Only the lower 8 bits ** of the subtype T are preserved in current versions of SQLite; ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase ** in future releases of SQLite. */ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); /* ** CAPI3REF: Define New Collating Sequences ** METHOD: sqlite3 ** | > > > > > > > > > > > > > > | 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 | ** The sqlite3_result_subtype(C,T) function causes the subtype of ** the result from the [application-defined SQL function] with ** [sqlite3_context] C to be the value T. Only the lower 8 bits ** of the subtype T are preserved in current versions of SQLite; ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase ** in future releases of SQLite. ** ** Every [application-defined SQL function] that invokes this interface ** should include the [SQLITE_RESULT_SUBTYPE] property in its ** text encoding argument when the SQL function is ** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE] ** property is omitted from the function that invokes sqlite3_result_subtype(), ** then in some cases the sqlite3_result_subtype() might fail to set ** the result subtype. ** ** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any ** SQL function that invokes the sqlite3_result_subtype() interface ** and that does not have the SQLITE_RESULT_SUBTYPE property will raise ** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1 ** by default. */ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); /* ** CAPI3REF: Define New Collating Sequences ** METHOD: sqlite3 ** |
| ︙ | ︙ | |||
17807 17808 17809 17810 17811 17812 17813 |
/* 0x0200 -- available for reuse */
#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
** single query - might change over time */
#define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */
| | | > | 17850 17851 17852 17853 17854 17855 17856 17857 17858 17859 17860 17861 17862 17863 17864 17865 17866 17867 17868 17869 17870 17871 17872 |
/* 0x0200 -- available for reuse */
#define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */
#define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
#define SQLITE_FUNC_MINMAX 0x1000 /* True for min() and max() aggregates */
#define SQLITE_FUNC_SLOCHNG 0x2000 /* "Slow Change". Value constant during a
** single query - might change over time */
#define SQLITE_FUNC_TEST 0x4000 /* Built-in testing functions */
#define SQLITE_FUNC_RUNONLY 0x8000 /* Cannot be used by valueFromFunction */
#define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
/* SQLITE_SUBTYPE 0x00100000 // Consumer of subtypes */
#define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */
#define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */
#define SQLITE_FUNC_BUILTIN 0x00800000 /* This is a built-in function */
/* SQLITE_RESULT_SUBTYPE 0x01000000 // Generator of subtypes */
#define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */
/* Identifier numbers for each in-line function */
#define INLINEFUNC_coalesce 0
#define INLINEFUNC_implies_nonnull_row 1
#define INLINEFUNC_expr_implies_expr 2
#define INLINEFUNC_expr_compare 3
|
| ︙ | ︙ | |||
17906 17907 17908 17909 17910 17911 17912 |
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define MFUNCTION(zName, nArg, xPtr, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
| | | | > | 17950 17951 17952 17953 17954 17955 17956 17957 17958 17959 17960 17961 17962 17963 17964 17965 17966 17967 |
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define MFUNCTION(zName, nArg, xPtr, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, iArg, xFunc) \
{nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\
SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\
((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
#define INLINE_FUNC(zName, nArg, iArg, mFlags) \
{nArg, SQLITE_FUNC_BUILTIN|\
SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
#define TEST_FUNC(zName, nArg, iArg, mFlags) \
{nArg, SQLITE_FUNC_BUILTIN|\
|
| ︙ | ︙ | |||
29449 29450 29451 29452 29453 29454 29455 |
** compiled without mutexes (SQLITE_THREADSAFE=0).
*/
SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
#if defined(SQLITE_MEMORY_BARRIER)
SQLITE_MEMORY_BARRIER;
#elif defined(__GNUC__)
__sync_synchronize();
| | | 29494 29495 29496 29497 29498 29499 29500 29501 29502 29503 29504 29505 29506 29507 29508 |
** compiled without mutexes (SQLITE_THREADSAFE=0).
*/
SQLITE_PRIVATE void sqlite3MemoryBarrier(void){
#if defined(SQLITE_MEMORY_BARRIER)
SQLITE_MEMORY_BARRIER;
#elif defined(__GNUC__)
__sync_synchronize();
#elif MSVC_VERSION>=1400
_ReadWriteBarrier();
#elif defined(MemoryBarrier)
MemoryBarrier();
#endif
}
/*
|
| ︙ | ︙ | |||
61443 61444 61445 61446 61447 61448 61449 61450 61451 61452 |
/*
** Return the sqlite3_file for the main database given the name
** of the corresponding WAL or Journal name as passed into
** xOpen.
*/
SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){
Pager *pPager;
while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
zName--;
}
| > > > | | 61488 61489 61490 61491 61492 61493 61494 61495 61496 61497 61498 61499 61500 61501 61502 61503 61504 61505 61506 61507 61508 |
/*
** Return the sqlite3_file for the main database given the name
** of the corresponding WAL or Journal name as passed into
** xOpen.
*/
SQLITE_API sqlite3_file *sqlite3_database_file_object(const char *zName){
Pager *pPager;
const char *p;
while( zName[-1]!=0 || zName[-2]!=0 || zName[-3]!=0 || zName[-4]!=0 ){
zName--;
}
p = zName - 4 - sizeof(Pager*);
assert( EIGHT_BYTE_ALIGNMENT(p) );
pPager = *(Pager**)p;
return pPager->fd;
}
/*
** This function is called after transitioning from PAGER_UNLOCK to
** PAGER_SHARED state. It tests if there is a hot journal present in
|
| ︙ | ︙ | |||
83407 83408 83409 83410 83411 83412 83413 | assert( !ExprHasProperty(p, EP_IntValue) ); pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION if( pFunc==0 ) return SQLITE_OK; #endif assert( pFunc ); if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 | | | 83455 83456 83457 83458 83459 83460 83461 83462 83463 83464 83465 83466 83467 83468 83469 |
assert( !ExprHasProperty(p, EP_IntValue) );
pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
if( pFunc==0 ) return SQLITE_OK;
#endif
assert( pFunc );
if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
|| (pFunc->funcFlags & (SQLITE_FUNC_NEEDCOLL|SQLITE_FUNC_RUNONLY))!=0
){
return SQLITE_OK;
}
if( pList ){
apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
if( apVal==0 ){
|
| ︙ | ︙ | |||
89948 89949 89950 89951 89952 89953 89954 89955 89956 89957 89958 89959 89960 89961 |
sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor);
}
SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
Mem *pOut;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pOut->db->mutex) );
pOut->eSubtype = eSubtype & 0xff;
pOut->flags |= MEM_Subtype;
}
SQLITE_API void sqlite3_result_text(
sqlite3_context *pCtx,
| > > > > > > > > > > > > | 89996 89997 89998 89999 90000 90001 90002 90003 90004 90005 90006 90007 90008 90009 90010 90011 90012 90013 90014 90015 90016 90017 90018 90019 90020 90021 |
sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor);
}
SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
Mem *pOut;
#ifdef SQLITE_ENABLE_API_ARMOR
if( pCtx==0 ) return;
#endif
#if defined(SQLITE_STRICT_SUBTYPE) && SQLITE_STRICT_SUBTYPE+0!=0
if( pCtx->pFunc!=0
&& (pCtx->pFunc->funcFlags & SQLITE_RESULT_SUBTYPE)==0
){
char zErr[200];
sqlite3_snprintf(sizeof(zErr), zErr,
"misuse of sqlite3_result_subtype() by %s()",
pCtx->pFunc->zName);
sqlite3_result_error(pCtx, zErr, -1);
return;
}
#endif /* SQLITE_STRICT_SUBTYPE */
pOut = pCtx->pOut;
assert( sqlite3_mutex_held(pOut->db->mutex) );
pOut->eSubtype = eSubtype & 0xff;
pOut->flags |= MEM_Subtype;
}
SQLITE_API void sqlite3_result_text(
sqlite3_context *pCtx,
|
| ︙ | ︙ | |||
100317 100318 100319 100320 100321 100322 100323 | pOut = &aMem[pOp->p2]; sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ assert( pOp->p4type==P4_TABLE ); pTab = pOp->p4.pTab; assert( pTab!=0 ); assert( IsVirtual(pTab) ); | | | 100377 100378 100379 100380 100381 100382 100383 100384 100385 100386 100387 100388 100389 100390 100391 | pOut = &aMem[pOp->p2]; sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ assert( pOp->p4type==P4_TABLE ); pTab = pOp->p4.pTab; assert( pTab!=0 ); assert( IsVirtual(pTab) ); if( pTab->u.vtab.p==0 ) break; pVtab = pTab->u.vtab.p->pVtab; assert( pVtab!=0 ); pModule = pVtab->pModule; assert( pModule!=0 ); assert( pModule->iVersion>=4 ); assert( pModule->xIntegrity!=0 ); pTab->nTabRef++; |
| ︙ | ︙ | |||
113913 113914 113915 113916 113917 113918 113919 |
/*
** Like sqlite3ExprCompare() except COLLATE operators at the top-level
** are ignored.
*/
SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){
return sqlite3ExprCompare(0,
| | | | 113973 113974 113975 113976 113977 113978 113979 113980 113981 113982 113983 113984 113985 113986 113987 113988 |
/*
** Like sqlite3ExprCompare() except COLLATE operators at the top-level
** are ignored.
*/
SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){
return sqlite3ExprCompare(0,
sqlite3ExprSkipCollate(pA),
sqlite3ExprSkipCollate(pB),
iTab);
}
/*
** Return non-zero if Expr p can only be true if pNN is not NULL.
**
** Or if seenNot is true, return non-zero if Expr p can only be
|
| ︙ | ︙ | |||
147601 147602 147603 147604 147605 147606 147607 |
*/
static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
Parse *pParse;
int i;
SrcList *pTabList;
SrcItem *pFrom;
| < > > | 147661 147662 147663 147664 147665 147666 147667 147668 147669 147670 147671 147672 147673 147674 147675 147676 147677 147678 147679 |
*/
static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
Parse *pParse;
int i;
SrcList *pTabList;
SrcItem *pFrom;
if( p->selFlags & SF_HasTypeInfo ) return;
p->selFlags |= SF_HasTypeInfo;
pParse = pWalker->pParse;
testcase( (p->selFlags & SF_Resolved)==0 );
assert( (p->selFlags & SF_Resolved) || IN_RENAME_OBJECT );
pTabList = p->pSrc;
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab = pFrom->pTab;
assert( pTab!=0 );
if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
/* A sub-query in the FROM clause of a SELECT */
Select *pSel = pFrom->pSelect;
|
| ︙ | ︙ | |||
148626 148627 148628 148629 148630 148631 148632 148633 148634 148635 148636 148637 148638 148639 148640 148641 148642 148643 148644 148645 148646 148647 148648 148649 |
TREETRACE(0x1000,pParse,p,
("FULL-JOIN simplifies to RIGHT-JOIN on term %d\n",i));
pItem->fg.jointype &= ~JT_LEFT;
}else{
TREETRACE(0x1000,pParse,p,
("LEFT-JOIN simplifies to JOIN on term %d\n",i));
pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
}
}
if( pItem->fg.jointype & JT_LTORJ ){
for(j=i+1; j<pTabList->nSrc; j++){
SrcItem *pI2 = &pTabList->a[j];
if( pI2->fg.jointype & JT_RIGHT ){
if( pI2->fg.jointype & JT_LEFT ){
TREETRACE(0x1000,pParse,p,
("FULL-JOIN simplifies to LEFT-JOIN on term %d\n",j));
pI2->fg.jointype &= ~JT_RIGHT;
}else{
TREETRACE(0x1000,pParse,p,
("RIGHT-JOIN simplifies to JOIN on term %d\n",j));
pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER);
}
}
}
| > > | < < < | 148687 148688 148689 148690 148691 148692 148693 148694 148695 148696 148697 148698 148699 148700 148701 148702 148703 148704 148705 148706 148707 148708 148709 148710 148711 148712 148713 148714 148715 148716 148717 148718 148719 148720 148721 148722 148723 148724 |
TREETRACE(0x1000,pParse,p,
("FULL-JOIN simplifies to RIGHT-JOIN on term %d\n",i));
pItem->fg.jointype &= ~JT_LEFT;
}else{
TREETRACE(0x1000,pParse,p,
("LEFT-JOIN simplifies to JOIN on term %d\n",i));
pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
unsetJoinExpr(p->pWhere, pItem->iCursor, 0);
}
}
if( pItem->fg.jointype & JT_LTORJ ){
for(j=i+1; j<pTabList->nSrc; j++){
SrcItem *pI2 = &pTabList->a[j];
if( pI2->fg.jointype & JT_RIGHT ){
if( pI2->fg.jointype & JT_LEFT ){
TREETRACE(0x1000,pParse,p,
("FULL-JOIN simplifies to LEFT-JOIN on term %d\n",j));
pI2->fg.jointype &= ~JT_RIGHT;
}else{
TREETRACE(0x1000,pParse,p,
("RIGHT-JOIN simplifies to JOIN on term %d\n",j));
pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER);
unsetJoinExpr(p->pWhere, pI2->iCursor, 1);
}
}
}
for(j=pTabList->nSrc-1; j>=0; j--){
pTabList->a[j].fg.jointype &= ~JT_LTORJ;
if( pTabList->a[j].fg.jointype & JT_RIGHT ) break;
}
}
}
/* No further action if this term of the FROM clause is not a subquery */
if( pSub==0 ) continue;
/* Catch mismatch in the declared columns of a view and the number of
** columns in the SELECT on the RHS */
|
| ︙ | ︙ | |||
166054 166055 166056 166057 166058 166059 166060 166061 166062 166063 166064 166065 166066 166067 |
}else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){
pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]);
bMaybeNullRow = 0;
}else{
continue;
}
if( sqlite3ExprIsConstant(pExpr) ) continue;
p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr));
if( p==0 ) break;
p->pIENext = pParse->pIdxEpr;
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace & 0x200 ){
sqlite3DebugPrintf("New pParse->pIdxEpr term {%d,%d}\n", iIdxCur, i);
if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr);
| > > > > > > > > > > > > > > | 166114 166115 166116 166117 166118 166119 166120 166121 166122 166123 166124 166125 166126 166127 166128 166129 166130 166131 166132 166133 166134 166135 166136 166137 166138 166139 166140 166141 |
}else if( j>=0 && (pTab->aCol[j].colFlags & COLFLAG_VIRTUAL)!=0 ){
pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]);
bMaybeNullRow = 0;
}else{
continue;
}
if( sqlite3ExprIsConstant(pExpr) ) continue;
if( pExpr->op==TK_FUNCTION ){
/* Functions that might set a subtype should not be replaced by the
** value taken from an expression index since the index omits the
** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */
int n;
FuncDef *pDef;
sqlite3 *db = pParse->db;
assert( ExprUseXList(pExpr) );
n = pExpr->x.pList ? pExpr->x.pList->nExpr : 0;
pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0);
if( pDef==0 || (pDef->funcFlags & SQLITE_RESULT_SUBTYPE)!=0 ){
continue;
}
}
p = sqlite3DbMallocRaw(pParse->db, sizeof(IndexedExpr));
if( p==0 ) break;
p->pIENext = pParse->pIdxEpr;
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace & 0x200 ){
sqlite3DebugPrintf("New pParse->pIdxEpr term {%d,%d}\n", iIdxCur, i);
if( sqlite3WhereTrace & 0x5000 ) sqlite3ShowExpr(pExpr);
|
| ︙ | ︙ | |||
168236 168237 168238 168239 168240 168241 168242 |
** window function - one for the accumulator, another for interim
** results. */
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
ExprList *pArgs;
assert( ExprUseXList(pWin->pOwner) );
assert( pWin->pWFunc!=0 );
pArgs = pWin->pOwner->x.pList;
| | | 168310 168311 168312 168313 168314 168315 168316 168317 168318 168319 168320 168321 168322 168323 168324 |
** window function - one for the accumulator, another for interim
** results. */
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
ExprList *pArgs;
assert( ExprUseXList(pWin->pOwner) );
assert( pWin->pWFunc!=0 );
pArgs = pWin->pOwner->x.pList;
if( pWin->pWFunc->funcFlags & SQLITE_SUBTYPE ){
selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
pWin->bExprArgs = 1;
}else{
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
pSublist = exprListAppendList(pParse, pSublist, pArgs, 0);
}
|
| ︙ | ︙ | |||
179410 179411 179412 179413 179414 179415 179416 |
){
return SQLITE_MISUSE_BKPT;
}
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
| | | 179484 179485 179486 179487 179488 179489 179490 179491 179492 179493 179494 179495 179496 179497 179498 |
){
return SQLITE_MISUSE_BKPT;
}
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY );
extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|
SQLITE_SUBTYPE|SQLITE_INNOCUOUS|SQLITE_RESULT_SUBTYPE);
enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
/* The SQLITE_INNOCUOUS flag is the same bit as SQLITE_FUNC_UNSAFE. But
** the meaning is inverted. So flip the bit. */
assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS );
extraFlags ^= SQLITE_FUNC_UNSAFE; /* tag-20230109-1 */
|
| ︙ | ︙ | |||
202991 202992 202993 202994 202995 202996 202997 |
*/
static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){
u32 i;
jsonAppendChar(p, '"');
zIn++;
N -= 2;
while( N>0 ){
| | > > > > > > | 203065 203066 203067 203068 203069 203070 203071 203072 203073 203074 203075 203076 203077 203078 203079 203080 203081 203082 203083 203084 203085 203086 203087 203088 203089 203090 |
*/
static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){
u32 i;
jsonAppendChar(p, '"');
zIn++;
N -= 2;
while( N>0 ){
for(i=0; i<N && zIn[i]!='\\' && zIn[i]!='"'; i++){}
if( i>0 ){
jsonAppendRawNZ(p, zIn, i);
zIn += i;
N -= i;
if( N==0 ) break;
}
if( zIn[0]=='"' ){
jsonAppendRawNZ(p, "\\\"", 2);
zIn++;
N--;
continue;
}
assert( zIn[0]=='\\' );
switch( (u8)zIn[1] ){
case '\'':
jsonAppendChar(p, '\'');
break;
case 'v':
|
| ︙ | ︙ | |||
203392 203393 203394 203395 203396 203397 203398 | /* ** Return a JsonNode and all its descendants as a JSON string. */ static void jsonReturnJson( JsonParse *pParse, /* The complete JSON */ JsonNode *pNode, /* Node to return */ sqlite3_context *pCtx, /* Return value for this function */ | | > | | 203472 203473 203474 203475 203476 203477 203478 203479 203480 203481 203482 203483 203484 203485 203486 203487 203488 203489 203490 203491 203492 203493 203494 203495 203496 203497 203498 203499 203500 203501 203502 |
/*
** Return a JsonNode and all its descendants as a JSON string.
*/
static void jsonReturnJson(
JsonParse *pParse, /* The complete JSON */
JsonNode *pNode, /* Node to return */
sqlite3_context *pCtx, /* Return value for this function */
int bGenerateAlt, /* Also store the rendered text in zAlt */
int omitSubtype /* Do not call sqlite3_result_subtype() */
){
JsonString s;
if( pParse->oom ){
sqlite3_result_error_nomem(pCtx);
return;
}
if( pParse->nErr==0 ){
jsonInit(&s, pCtx);
jsonRenderNode(pParse, pNode, &s);
if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){
pParse->zAlt = sqlite3RCStrRef(s.zBuf);
pParse->nAlt = s.nUsed;
}
jsonResult(&s);
if( !omitSubtype ) sqlite3_result_subtype(pCtx, JSON_SUBTYPE);
}
}
/*
** Translate a single byte of Hex into an integer.
** This routine only works if h really is a valid hexadecimal
** character: 0..9a..fA..F
|
| ︙ | ︙ | |||
203448 203449 203450 203451 203452 203453 203454 | /* ** Make the JsonNode the return value of the function. */ static void jsonReturn( JsonParse *pParse, /* Complete JSON parse tree */ JsonNode *pNode, /* Node to return */ | | > | 203529 203530 203531 203532 203533 203534 203535 203536 203537 203538 203539 203540 203541 203542 203543 203544 |
/*
** Make the JsonNode the return value of the function.
*/
static void jsonReturn(
JsonParse *pParse, /* Complete JSON parse tree */
JsonNode *pNode, /* Node to return */
sqlite3_context *pCtx, /* Return value for this function */
int omitSubtype /* Do not call sqlite3_result_subtype() */
){
switch( pNode->eType ){
default: {
assert( pNode->eType==JSON_NULL );
sqlite3_result_null(pCtx);
break;
}
|
| ︙ | ︙ | |||
203594 203595 203596 203597 203598 203599 203600 |
zOut[j] = 0;
sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
}
break;
}
case JSON_ARRAY:
case JSON_OBJECT: {
| | | 203676 203677 203678 203679 203680 203681 203682 203683 203684 203685 203686 203687 203688 203689 203690 |
zOut[j] = 0;
sqlite3_result_text(pCtx, zOut, j, sqlite3_free);
}
break;
}
case JSON_ARRAY:
case JSON_OBJECT: {
jsonReturnJson(pParse, pNode, pCtx, 0, omitSubtype);
break;
}
}
}
/* Forward reference */
static int jsonParseAddNode(JsonParse*,u32,u32,const char*);
|
| ︙ | ︙ | |||
204946 204947 204948 204949 204950 204951 204952 |
printf("hasNonstd = %u\n", p->hasNonstd);
printf("useMod = %u\n", p->useMod);
printf("hasMod = %u\n", p->hasMod);
printf("nJPRef = %u\n", p->nJPRef);
printf("iSubst = %u\n", p->iSubst);
printf("iHold = %u\n", p->iHold);
jsonDebugPrintNodeEntries(p->aNode, p->nNode);
| | | 205028 205029 205030 205031 205032 205033 205034 205035 205036 205037 205038 205039 205040 205041 205042 |
printf("hasNonstd = %u\n", p->hasNonstd);
printf("useMod = %u\n", p->useMod);
printf("hasMod = %u\n", p->hasMod);
printf("nJPRef = %u\n", p->nJPRef);
printf("iSubst = %u\n", p->iSubst);
printf("iHold = %u\n", p->iHold);
jsonDebugPrintNodeEntries(p->aNode, p->nNode);
jsonReturnJson(p, p->aNode, ctx, 1, 0);
}
/*
** The json_test1(JSON) function return true (1) if the input is JSON
** text generated by another json function. It returns (0) if the input
** is not known to be JSON.
*/
|
| ︙ | ︙ | |||
205132 205133 205134 205135 205136 205137 205138 |
pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx);
jsonReset(&jx);
}else{
pNode = jsonLookup(p, zPath, 0, ctx);
}
if( pNode ){
if( flags & JSON_JSON ){
| | | < | | 205214 205215 205216 205217 205218 205219 205220 205221 205222 205223 205224 205225 205226 205227 205228 205229 205230 205231 205232 205233 205234 205235 |
pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx);
jsonReset(&jx);
}else{
pNode = jsonLookup(p, zPath, 0, ctx);
}
if( pNode ){
if( flags & JSON_JSON ){
jsonReturnJson(p, pNode, ctx, 0, 0);
}else{
jsonReturn(p, pNode, ctx, 1);
}
}
}else{
pNode = jsonLookup(p, zPath, 0, ctx);
if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx, 0);
}
}else{
/* Two or more PATH arguments results in a JSON array with each
** element of the array being the value selected by one of the PATHs */
int i;
jsonInit(&jx, ctx);
jsonAppendChar(&jx, '[');
|
| ︙ | ︙ | |||
205266 205267 205268 205269 205270 205271 205272 |
pX->useMod = 1;
pY->useMod = 1;
pResult = jsonMergePatch(pX, 0, pY->aNode);
assert( pResult!=0 || pX->oom );
if( pResult && pX->oom==0 ){
jsonDebugPrintParse(pX);
jsonDebugPrintNode(pResult);
| | | 205347 205348 205349 205350 205351 205352 205353 205354 205355 205356 205357 205358 205359 205360 205361 |
pX->useMod = 1;
pY->useMod = 1;
pResult = jsonMergePatch(pX, 0, pY->aNode);
assert( pResult!=0 || pX->oom );
if( pResult && pX->oom==0 ){
jsonDebugPrintParse(pX);
jsonDebugPrintNode(pResult);
jsonReturnJson(pX, pResult, ctx, 0, 0);
}else{
sqlite3_result_error_nomem(ctx);
}
}
/*
|
| ︙ | ︙ | |||
205345 205346 205347 205348 205349 205350 205351 |
if( pNode ){
pNode->jnFlags |= JNODE_REMOVE;
pParse->hasMod = 1;
pParse->useMod = 1;
}
}
if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){
| | | 205426 205427 205428 205429 205430 205431 205432 205433 205434 205435 205436 205437 205438 205439 205440 |
if( pNode ){
pNode->jnFlags |= JNODE_REMOVE;
pParse->hasMod = 1;
pParse->useMod = 1;
}
}
if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){
jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0);
}
remove_done:
jsonDebugPrintParse(p);
}
/*
** Substitute the value at iNode with the pValue parameter.
|
| ︙ | ︙ | |||
205474 205475 205476 205477 205478 205479 205480 |
pParse->useMod = 1;
pNode = jsonLookup(pParse, zPath, 0, ctx);
if( pParse->nErr ) goto replace_err;
if( pNode ){
jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
}
}
| | | 205555 205556 205557 205558 205559 205560 205561 205562 205563 205564 205565 205566 205567 205568 205569 |
pParse->useMod = 1;
pNode = jsonLookup(pParse, zPath, 0, ctx);
if( pParse->nErr ) goto replace_err;
if( pNode ){
jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
}
}
jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0);
replace_err:
jsonDebugPrintParse(pParse);
jsonParseFree(pParse);
}
/*
|
| ︙ | ︙ | |||
205528 205529 205530 205531 205532 205533 205534 |
}else if( pParse->nErr ){
goto jsonSetDone;
}else if( pNode && (bApnd || bIsSet) ){
jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
}
}
jsonDebugPrintParse(pParse);
| | | 205609 205610 205611 205612 205613 205614 205615 205616 205617 205618 205619 205620 205621 205622 205623 |
}else if( pParse->nErr ){
goto jsonSetDone;
}else if( pNode && (bApnd || bIsSet) ){
jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]);
}
}
jsonDebugPrintParse(pParse);
jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0);
jsonSetDone:
jsonParseFree(pParse);
}
/*
** json_type(JSON)
** json_type(JSON, PATH)
|
| ︙ | ︙ | |||
206043 206044 206045 206046 206047 206048 206049 |
){
JsonEachCursor *p = (JsonEachCursor*)cur;
JsonNode *pThis = &p->sParse.aNode[p->i];
switch( i ){
case JEACH_KEY: {
if( p->i==0 ) break;
if( p->eType==JSON_OBJECT ){
| | | | | 206124 206125 206126 206127 206128 206129 206130 206131 206132 206133 206134 206135 206136 206137 206138 206139 206140 206141 206142 206143 206144 206145 206146 206147 206148 206149 206150 206151 206152 206153 206154 206155 206156 206157 206158 206159 206160 206161 206162 206163 206164 206165 |
){
JsonEachCursor *p = (JsonEachCursor*)cur;
JsonNode *pThis = &p->sParse.aNode[p->i];
switch( i ){
case JEACH_KEY: {
if( p->i==0 ) break;
if( p->eType==JSON_OBJECT ){
jsonReturn(&p->sParse, pThis, ctx, 0);
}else if( p->eType==JSON_ARRAY ){
u32 iKey;
if( p->bRecursive ){
if( p->iRowid==0 ) break;
assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 );
iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
}else{
iKey = p->iRowid;
}
sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
}
break;
}
case JEACH_VALUE: {
if( pThis->jnFlags & JNODE_LABEL ) pThis++;
jsonReturn(&p->sParse, pThis, ctx, 0);
break;
}
case JEACH_TYPE: {
if( pThis->jnFlags & JNODE_LABEL ) pThis++;
sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC);
break;
}
case JEACH_ATOM: {
if( pThis->jnFlags & JNODE_LABEL ) pThis++;
if( pThis->eType>=JSON_ARRAY ) break;
jsonReturn(&p->sParse, pThis, ctx, 0);
break;
}
case JEACH_ID: {
sqlite3_result_int64(ctx,
(sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0));
break;
}
|
| ︙ | ︙ | |||
206363 206364 206365 206366 206367 206368 206369 |
/*
** Register JSON functions.
*/
SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){
#ifndef SQLITE_OMIT_JSON
static FuncDef aJsonFunc[] = {
| > > > > > > > | | | | | | | | | | | | | | | | | | | | | > | > | | 206444 206445 206446 206447 206448 206449 206450 206451 206452 206453 206454 206455 206456 206457 206458 206459 206460 206461 206462 206463 206464 206465 206466 206467 206468 206469 206470 206471 206472 206473 206474 206475 206476 206477 206478 206479 206480 206481 206482 206483 206484 206485 206486 206487 206488 206489 206490 206491 206492 206493 206494 |
/*
** Register JSON functions.
*/
SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){
#ifndef SQLITE_OMIT_JSON
static FuncDef aJsonFunc[] = {
/* calls sqlite3_result_subtype() */
/* | */
/* Uses cache ______ | __ calls sqlite3_value_subtype() */
/* | | | */
/* Num args _________ | | | ___ Flags */
/* | | | | | */
/* | | | | | */
JFUNCTION(json, 1, 1, 1, 0, 0, jsonRemoveFunc),
JFUNCTION(json_array, -1, 0, 1, 1, 0, jsonArrayFunc),
JFUNCTION(json_array_length, 1, 1, 0, 0, 0, jsonArrayLengthFunc),
JFUNCTION(json_array_length, 2, 1, 0, 0, 0, jsonArrayLengthFunc),
JFUNCTION(json_error_position,1, 1, 0, 0, 0, jsonErrorFunc),
JFUNCTION(json_extract, -1, 1, 1, 0, 0, jsonExtractFunc),
JFUNCTION(->, 2, 1, 1, 0, JSON_JSON, jsonExtractFunc),
JFUNCTION(->>, 2, 1, 0, 0, JSON_SQL, jsonExtractFunc),
JFUNCTION(json_insert, -1, 1, 1, 1, 0, jsonSetFunc),
JFUNCTION(json_object, -1, 0, 1, 1, 0, jsonObjectFunc),
JFUNCTION(json_patch, 2, 1, 1, 0, 0, jsonPatchFunc),
JFUNCTION(json_quote, 1, 0, 1, 1, 0, jsonQuoteFunc),
JFUNCTION(json_remove, -1, 1, 1, 0, 0, jsonRemoveFunc),
JFUNCTION(json_replace, -1, 1, 1, 1, 0, jsonReplaceFunc),
JFUNCTION(json_set, -1, 1, 1, 1, JSON_ISSET, jsonSetFunc),
JFUNCTION(json_type, 1, 1, 0, 0, 0, jsonTypeFunc),
JFUNCTION(json_type, 2, 1, 0, 0, 0, jsonTypeFunc),
JFUNCTION(json_valid, 1, 1, 0, 0, 0, jsonValidFunc),
#ifdef SQLITE_DEBUG
JFUNCTION(json_parse, 1, 1, 1, 0, 0, jsonParseFunc),
JFUNCTION(json_test1, 1, 1, 0, 1, 0, jsonTest1Func),
#endif
WAGGREGATE(json_group_array, 1, 0, 0,
jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse,
SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
SQLITE_DETERMINISTIC),
WAGGREGATE(json_group_object, 2, 0, 0,
jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse,
SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|
SQLITE_DETERMINISTIC)
};
sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
#endif
}
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
/*
|
| ︙ | ︙ | |||
236127 236128 236129 236130 236131 236132 236133 |
}
}
return pRet;
}
/*
| | | < < | 236217 236218 236219 236220 236221 236222 236223 236224 236225 236226 236227 236228 236229 236230 236231 236232 |
}
}
return pRet;
}
/*
** Link all tokens from hash table iHash into a list in sorted order. The
** tokens are not removed from the hash table.
*/
static int fts5HashEntrySort(
Fts5Hash *pHash,
const char *pTerm, int nTerm, /* Query prefix, if any */
Fts5HashEntry **ppSorted
){
const int nMergeSlot = 32;
|
| ︙ | ︙ | |||
238996 238997 238998 238999 239000 239001 239002 239003 239004 239005 239006 239007 239008 239009 |
n = (z ? (int)strlen((const char*)z) : 0);
if( pList ){
pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
if( pLeaf ){
pLeaf->p = (u8*)pList;
}
}
}else{
p->rc = sqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data),
(const char*)pTerm, nTerm, (void**)&pLeaf, &nList
);
if( pLeaf ){
pLeaf->p = (u8*)&pLeaf[1];
}
| > > > > > > > > | 239084 239085 239086 239087 239088 239089 239090 239091 239092 239093 239094 239095 239096 239097 239098 239099 239100 239101 239102 239103 239104 239105 |
n = (z ? (int)strlen((const char*)z) : 0);
if( pList ){
pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data));
if( pLeaf ){
pLeaf->p = (u8*)pList;
}
}
/* The call to sqlite3Fts5HashScanInit() causes the hash table to
** fill the size field of all existing position lists. This means they
** can no longer be appended to. Since the only scenario in which they
** can be appended to is if the previous operation on this table was
** a DELETE, by clearing the Fts5Index.bDelete flag we can avoid this
** possibility altogether. */
p->bDelete = 0;
}else{
p->rc = sqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data),
(const char*)pTerm, nTerm, (void**)&pLeaf, &nList
);
if( pLeaf ){
pLeaf->p = (u8*)&pLeaf[1];
}
|
| ︙ | ︙ | |||
240673 240674 240675 240676 240677 240678 240679 |
const u8 *aData,
int nData
){
Fts5PageWriter *pPage = &pWriter->writer;
const u8 *a = aData;
int n = nData;
| | | 240769 240770 240771 240772 240773 240774 240775 240776 240777 240778 240779 240780 240781 240782 240783 |
const u8 *aData,
int nData
){
Fts5PageWriter *pPage = &pWriter->writer;
const u8 *a = aData;
int n = nData;
assert( p->pConfig->pgsz>0 || p->rc!=SQLITE_OK );
while( p->rc==SQLITE_OK
&& (pPage->buf.n + pPage->pgidx.n + n)>=p->pConfig->pgsz
){
int nReq = p->pConfig->pgsz - pPage->buf.n - pPage->pgidx.n;
int nCopy = 0;
while( nCopy<nReq ){
i64 dummy;
|
| ︙ | ︙ | |||
241933 241934 241935 241936 241937 241938 241939 |
static int sqlite3Fts5IndexOptimize(Fts5Index *p){
Fts5Structure *pStruct;
Fts5Structure *pNew = 0;
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
| | > | 242029 242030 242031 242032 242033 242034 242035 242036 242037 242038 242039 242040 242041 242042 242043 242044 242045 |
static int sqlite3Fts5IndexOptimize(Fts5Index *p){
Fts5Structure *pStruct;
Fts5Structure *pNew = 0;
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
assert( p->rc!=SQLITE_OK || p->nContentlessDelete==0 );
pStruct = fts5StructureRead(p);
assert( p->rc!=SQLITE_OK || pStruct!=0 );
fts5StructureInvalidate(p);
if( pStruct ){
pNew = fts5IndexOptimizeStruct(p, pStruct);
}
fts5StructureRelease(pStruct);
|
| ︙ | ︙ | |||
247511 247512 247513 247514 247515 247516 247517 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
| | | 247608 247609 247610 247611 247612 247613 247614 247615 247616 247617 247618 247619 247620 247621 247622 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4", -1, SQLITE_TRANSIENT);
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){
|
| ︙ | ︙ |
Changes to extsrc/sqlite3.h.
| ︙ | ︙ | |||
142 143 144 145 146 147 148 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.44.1" #define SQLITE_VERSION_NUMBER 3044001 #define SQLITE_SOURCE_ID "2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
5569 5570 5571 5572 5573 5574 5575 | ** are innocuous. Developers are advised to avoid using the ** SQLITE_INNOCUOUS flag for application-defined functions unless the ** function has been carefully audited and found to be free of potentially ** security-adverse side-effects and information-leaks. ** </dd> ** ** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd> | | | | | | > | > > > > > > > > > > > > > > | 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 | ** are innocuous. Developers are advised to avoid using the ** SQLITE_INNOCUOUS flag for application-defined functions unless the ** function has been carefully audited and found to be free of potentially ** security-adverse side-effects and information-leaks. ** </dd> ** ** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd> ** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. ** This flag instructs SQLite to omit some corner-case optimizations that ** might disrupt the operation of the [sqlite3_value_subtype()] function, ** causing it to return zero rather than the correct subtype(). ** SQL functions that invokes [sqlite3_value_subtype()] should have this ** property. If the SQLITE_SUBTYPE property is omitted, then the return ** value from [sqlite3_value_subtype()] might sometimes be zero even though ** a non-zero subtype was specified by the function argument expression. ** ** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd> ** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_result_subtype()] to cause a sub-type to be associated with its ** result. ** Every function that invokes [sqlite3_result_subtype()] should have this ** property. If it does not, then the call to [sqlite3_result_subtype()] ** might become a no-op if the function is used as term in an ** [expression index]. On the other hand, SQL functions that never invoke ** [sqlite3_result_subtype()] should avoid setting this property, as the ** purpose of this property is to disable certain optimizations that are ** incompatible with subtypes. ** </dd> ** </dl> */ #define SQLITE_DETERMINISTIC 0x000000800 #define SQLITE_DIRECTONLY 0x000080000 #define SQLITE_SUBTYPE 0x000100000 #define SQLITE_INNOCUOUS 0x000200000 #define SQLITE_RESULT_SUBTYPE 0x001000000 /* ** CAPI3REF: Deprecated Functions ** DEPRECATED ** ** These functions are [deprecated]. In order to maintain ** backwards compatibility with older code, these functions continue |
| ︙ | ︙ | |||
5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 | ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for ** an [application-defined SQL function] argument V. The subtype ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); /* ** CAPI3REF: Copy And Free SQL Values ** METHOD: sqlite3_value ** | > > > > > > | 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 | ** METHOD: sqlite3_value ** ** The sqlite3_value_subtype(V) function returns the subtype for ** an [application-defined SQL function] argument V. The subtype ** information can be used to pass a limited amount of context from ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. ** ** Every [application-defined SQL function] that invoke this interface ** should include the [SQLITE_SUBTYPE] property in the text ** encoding argument when the function is [sqlite3_create_function|registered]. ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() ** might return zero instead of the upstream subtype in some corner cases. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); /* ** CAPI3REF: Copy And Free SQL Values ** METHOD: sqlite3_value ** |
| ︙ | ︙ | |||
5909 5910 5911 5912 5913 5914 5915 | ** SQLite is free to discard the auxiliary data at any time, including: <ul> ** <li> ^(when the corresponding function parameter changes)^, or ** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement)^, or ** <li> ^(when sqlite3_set_auxdata() is invoked again on the same ** parameter)^, or ** <li> ^(during the original sqlite3_set_auxdata() call when a memory | | > > > | | > > > > > | 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 | ** SQLite is free to discard the auxiliary data at any time, including: <ul> ** <li> ^(when the corresponding function parameter changes)^, or ** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement)^, or ** <li> ^(when sqlite3_set_auxdata() is invoked again on the same ** parameter)^, or ** <li> ^(during the original sqlite3_set_auxdata() call when a memory ** allocation error occurs.)^ ** <li> ^(during the original sqlite3_set_auxdata() call if the function ** is evaluated during query planning instead of during query execution, ** as sometimes happens with [SQLITE_ENABLE_STAT4].)^ </ul> ** ** Note the last two bullets in particular. The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after ** sqlite3_set_auxdata() has been called. Furthermore, a call to ** sqlite3_get_auxdata() that occurs immediately after a corresponding call ** to sqlite3_set_auxdata() might still return NULL if an out-of-memory ** condition occurred during the sqlite3_set_auxdata() call or if the ** function is being evaluated during query planning rather than during ** query execution. ** ** ^(In practice, auxiliary data is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** ** The value of the N parameter to these interfaces should be non-negative. ** Future enhancements may make use of negative N values to define new |
| ︙ | ︙ | |||
6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 | ** The sqlite3_result_subtype(C,T) function causes the subtype of ** the result from the [application-defined SQL function] with ** [sqlite3_context] C to be the value T. Only the lower 8 bits ** of the subtype T are preserved in current versions of SQLite; ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase ** in future releases of SQLite. */ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); /* ** CAPI3REF: Define New Collating Sequences ** METHOD: sqlite3 ** | > > > > > > > > > > > > > > | 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 | ** The sqlite3_result_subtype(C,T) function causes the subtype of ** the result from the [application-defined SQL function] with ** [sqlite3_context] C to be the value T. Only the lower 8 bits ** of the subtype T are preserved in current versions of SQLite; ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase ** in future releases of SQLite. ** ** Every [application-defined SQL function] that invokes this interface ** should include the [SQLITE_RESULT_SUBTYPE] property in its ** text encoding argument when the SQL function is ** [sqlite3_create_function|registered]. If the [SQLITE_RESULT_SUBTYPE] ** property is omitted from the function that invokes sqlite3_result_subtype(), ** then in some cases the sqlite3_result_subtype() might fail to set ** the result subtype. ** ** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any ** SQL function that invokes the sqlite3_result_subtype() interface ** and that does not have the SQLITE_RESULT_SUBTYPE property will raise ** an error. Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1 ** by default. */ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); /* ** CAPI3REF: Define New Collating Sequences ** METHOD: sqlite3 ** |
| ︙ | ︙ |