sqlite-amalgamation-3450000.zip
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4776 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
195
deps/sqlite/shell.c
vendored
195
deps/sqlite/shell.c
vendored
@ -296,7 +296,7 @@ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
|
||||
** CIO_WIN_WC_XLATE is defined as 0 or 1, reflecting whether console I/O
|
||||
** translation for Windows is effected for the build.
|
||||
*/
|
||||
|
||||
#define HAVE_CONSOLE_IO_H 1
|
||||
#ifndef SQLITE_INTERNAL_LINKAGE
|
||||
# define SQLITE_INTERNAL_LINKAGE extern /* external to translation unit */
|
||||
# include <stdio.h>
|
||||
@ -434,8 +434,8 @@ SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z);
|
||||
#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. */
|
||||
#endif
|
||||
SQLITE_INTERNAL_LINKAGE int
|
||||
oPutbUtf8(const char *cBuf, int nAccept);
|
||||
/* Like fPutbUtf8 except stream is always the designated error. */
|
||||
@ -575,9 +575,11 @@ zSkipValidUtf8(const char *z, int nAccept, long ccm);
|
||||
# include <stdlib.h>
|
||||
# include <limits.h>
|
||||
# include <assert.h>
|
||||
# include "console_io.h"
|
||||
/* # include "sqlite3.h" */
|
||||
#endif
|
||||
#ifndef HAVE_CONSOLE_IO_H
|
||||
# include "console_io.h"
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_CIO_NO_TRANSLATE
|
||||
# if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT
|
||||
@ -1100,12 +1102,11 @@ zSkipValidUtf8(const char *z, int nAccept, long ccm){
|
||||
#endif /*!(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))*/
|
||||
|
||||
#ifndef SQLITE_CIO_NO_TRANSLATE
|
||||
|
||||
#ifdef CONSIO_SPUTB
|
||||
# ifdef CONSIO_SPUTB
|
||||
SQLITE_INTERNAL_LINKAGE int
|
||||
fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){
|
||||
assert(pfO!=0);
|
||||
# if CIO_WIN_WC_XLATE
|
||||
# if CIO_WIN_WC_XLATE
|
||||
PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */
|
||||
PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO);
|
||||
if( pstReachesConsole(ppst) ){
|
||||
@ -1115,13 +1116,13 @@ fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){
|
||||
if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst);
|
||||
return rv;
|
||||
}else {
|
||||
# endif
|
||||
# endif
|
||||
return (int)fwrite(cBuf, 1, nAccept, pfO);
|
||||
# if CIO_WIN_WC_XLATE
|
||||
# if CIO_WIN_WC_XLATE
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
}
|
||||
#endif /* defined(CONSIO_SPUTB) */
|
||||
# endif
|
||||
|
||||
SQLITE_INTERNAL_LINKAGE int
|
||||
oPutbUtf8(const char *cBuf, int nAccept){
|
||||
@ -1232,6 +1233,7 @@ SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn){
|
||||
/************************* 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)
|
||||
/*
|
||||
@ -1256,6 +1258,7 @@ SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn){
|
||||
# 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)
|
||||
@ -1339,7 +1342,7 @@ static void endTimer(void){
|
||||
sqlite3_int64 iEnd = timeOfDay();
|
||||
struct rusage sEnd;
|
||||
getrusage(RUSAGE_SELF, &sEnd);
|
||||
oputf("Run Time: real %.3f user %f sys %f\n",
|
||||
sputf(stdout, "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));
|
||||
@ -1418,7 +1421,7 @@ static void endTimer(void){
|
||||
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",
|
||||
sputf(stdout, "Run Time: real %.3f user %f sys %f\n",
|
||||
(ftWallEnd - ftWallBegin)*0.001,
|
||||
timeDiff(&ftUserBegin, &ftUserEnd),
|
||||
timeDiff(&ftKernelBegin, &ftKernelEnd));
|
||||
@ -1715,14 +1718,14 @@ static int strlenChar(const char *z){
|
||||
*/
|
||||
static FILE * openChrSource(const char *zFile){
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
struct _stat x = {0};
|
||||
struct __stat64 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;
|
||||
if( _fstat(_fileno(rv), &x) != 0
|
||||
if( _fstat64(_fileno(rv), &x) != 0
|
||||
|| !STAT_CHR_SRC(x.st_mode)){
|
||||
fclose(rv);
|
||||
rv = 0;
|
||||
@ -14827,6 +14830,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){
|
||||
bNextPage = 1;
|
||||
}else{
|
||||
iOff += dbdataGetVarintU32(&pCsr->aPage[iOff], &nPayload);
|
||||
if( nPayload>0x7fffff00 ) nPayload &= 0x3fff;
|
||||
}
|
||||
|
||||
/* If this is a leaf intkey cell, load the rowid */
|
||||
@ -18143,6 +18147,7 @@ struct ShellState {
|
||||
u8 eTraceType; /* SHELL_TRACE_* value for type of trace */
|
||||
u8 bSafeMode; /* True to prohibit unsafe operations */
|
||||
u8 bSafeModePersist; /* The long-term value of bSafeMode */
|
||||
u8 eRestoreState; /* See comments above doAutoDetectRestore() */
|
||||
ColModeOpts cmOpts; /* Option values affecting columnar mode output */
|
||||
unsigned statsOn; /* True to display memory stats before each finalize */
|
||||
unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */
|
||||
@ -22170,7 +22175,6 @@ static void open_db(ShellState *p, int openFlags){
|
||||
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));
|
||||
@ -22187,6 +22191,7 @@ static void open_db(ShellState *p, int openFlags){
|
||||
zDbFilename);
|
||||
}
|
||||
}
|
||||
globalDb = p->db;
|
||||
sqlite3_db_config(p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, (int)0, (int*)0);
|
||||
|
||||
/* Reflect the use or absence of --unsafe-testing invocation. */
|
||||
@ -23582,7 +23587,6 @@ static int lintDotCommand(
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
#if !defined SQLITE_OMIT_VIRTUALTABLE
|
||||
static void shellPrepare(
|
||||
sqlite3 *db,
|
||||
int *pRc,
|
||||
@ -23601,12 +23605,8 @@ static void shellPrepare(
|
||||
|
||||
/*
|
||||
** Create a prepared statement using printf-style arguments for the SQL.
|
||||
**
|
||||
** 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 shellPreparePrintf(
|
||||
static void shellPreparePrintf(
|
||||
sqlite3 *db,
|
||||
int *pRc,
|
||||
sqlite3_stmt **ppStmt,
|
||||
@ -23629,13 +23629,10 @@ void shellPreparePrintf(
|
||||
}
|
||||
}
|
||||
|
||||
/* Finalize 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".
|
||||
/*
|
||||
** Finalize the prepared statement created using shellPreparePrintf().
|
||||
*/
|
||||
void shellFinalize(
|
||||
static void shellFinalize(
|
||||
int *pRc,
|
||||
sqlite3_stmt *pStmt
|
||||
){
|
||||
@ -23651,6 +23648,7 @@ void shellFinalize(
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined SQLITE_OMIT_VIRTUALTABLE
|
||||
/* Reset the prepared statement created using shellPreparePrintf().
|
||||
**
|
||||
** This routine is could be marked "static". But it is not always used,
|
||||
@ -24717,6 +24715,30 @@ FROM (\
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Check if the sqlite_schema table contains one or more virtual tables. If
|
||||
** parameter zLike is not NULL, then it is an SQL expression that the
|
||||
** sqlite_schema row must also match. If one or more such rows are found,
|
||||
** print the following warning to the output:
|
||||
**
|
||||
** WARNING: Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled
|
||||
*/
|
||||
static int outputDumpWarning(ShellState *p, const char *zLike){
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
shellPreparePrintf(p->db, &rc, &pStmt,
|
||||
"SELECT 1 FROM sqlite_schema o WHERE "
|
||||
"sql LIKE 'CREATE VIRTUAL TABLE%%' AND %s", zLike ? zLike : "true"
|
||||
);
|
||||
if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
oputz("/* WARNING: "
|
||||
"Script requires that SQLITE_DBCONFIG_DEFENSIVE be disabled */\n"
|
||||
);
|
||||
}
|
||||
shellFinalize(&rc, pStmt);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** If an input line begins with "." then invoke this routine to
|
||||
** process that line.
|
||||
@ -25179,6 +25201,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
|
||||
open_db(p, 0);
|
||||
|
||||
outputDumpWarning(p, zLike);
|
||||
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.
|
||||
@ -27607,6 +27630,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
{"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" },
|
||||
{"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
|
||||
{"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
|
||||
{"json_selfcheck", SQLITE_TESTCTRL_JSON_SELFCHECK ,0,"BOOLEAN" },
|
||||
{"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
|
||||
{"never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
|
||||
{"optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" },
|
||||
@ -27825,6 +27849,16 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
isOk = 3;
|
||||
}
|
||||
break;
|
||||
case SQLITE_TESTCTRL_JSON_SELFCHECK:
|
||||
if( nArg==2 ){
|
||||
rc2 = -1;
|
||||
isOk = 1;
|
||||
}else{
|
||||
rc2 = booleanValue(azArg[2]);
|
||||
isOk = 3;
|
||||
}
|
||||
sqlite3_test_control(testctrl, &rc2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( isOk==0 && iCtrl>=0 ){
|
||||
@ -28231,6 +28265,88 @@ static int line_is_complete(char *zSql, int nSql){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called after processing each line of SQL in the
|
||||
** runOneSqlLine() function. Its purpose is to detect scenarios where
|
||||
** defensive mode should be automatically turned off. Specifically, when
|
||||
**
|
||||
** 1. The first line of input is "PRAGMA foreign_keys=OFF;",
|
||||
** 2. The second line of input is "BEGIN TRANSACTION;",
|
||||
** 3. The database is empty, and
|
||||
** 4. The shell is not running in --safe mode.
|
||||
**
|
||||
** The implementation uses the ShellState.eRestoreState to maintain state:
|
||||
**
|
||||
** 0: Have not seen any SQL.
|
||||
** 1: Have seen "PRAGMA foreign_keys=OFF;".
|
||||
** 2-6: Currently running .dump transaction. If the "2" bit is set,
|
||||
** disable DEFENSIVE when done. If "4" is set, disable DQS_DDL.
|
||||
** 7: Nothing left to do. This function becomes a no-op.
|
||||
*/
|
||||
static int doAutoDetectRestore(ShellState *p, const char *zSql){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( p->eRestoreState<7 ){
|
||||
switch( p->eRestoreState ){
|
||||
case 0: {
|
||||
const char *zExpect = "PRAGMA foreign_keys=OFF;";
|
||||
assert( strlen(zExpect)==24 );
|
||||
if( p->bSafeMode==0 && memcmp(zSql, zExpect, 25)==0 ){
|
||||
p->eRestoreState = 1;
|
||||
}else{
|
||||
p->eRestoreState = 7;
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
||||
case 1: {
|
||||
int bIsDump = 0;
|
||||
const char *zExpect = "BEGIN TRANSACTION;";
|
||||
assert( strlen(zExpect)==18 );
|
||||
if( memcmp(zSql, zExpect, 19)==0 ){
|
||||
/* Now check if the database is empty. */
|
||||
const char *zQuery = "SELECT 1 FROM sqlite_schema LIMIT 1";
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
|
||||
bIsDump = 1;
|
||||
shellPrepare(p->db, &rc, zQuery, &pStmt);
|
||||
if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
bIsDump = 0;
|
||||
}
|
||||
shellFinalize(&rc, pStmt);
|
||||
}
|
||||
if( bIsDump && rc==SQLITE_OK ){
|
||||
int bDefense = 0;
|
||||
int bDqsDdl = 0;
|
||||
sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, -1, &bDefense);
|
||||
sqlite3_db_config(p->db, SQLITE_DBCONFIG_DQS_DDL, -1, &bDqsDdl);
|
||||
sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0);
|
||||
sqlite3_db_config(p->db, SQLITE_DBCONFIG_DQS_DDL, 1, 0);
|
||||
p->eRestoreState = (bDefense ? 2 : 0) + (bDqsDdl ? 4 : 0);
|
||||
}else{
|
||||
p->eRestoreState = 7;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
if( sqlite3_get_autocommit(p->db) ){
|
||||
if( (p->eRestoreState & 2) ){
|
||||
sqlite3_db_config(p->db, SQLITE_DBCONFIG_DEFENSIVE, 1, 0);
|
||||
}
|
||||
if( (p->eRestoreState & 4) ){
|
||||
sqlite3_db_config(p->db, SQLITE_DBCONFIG_DQS_DDL, 0, 0);
|
||||
}
|
||||
p->eRestoreState = 7;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Run a single line of SQL. Return the number of errors.
|
||||
*/
|
||||
@ -28278,6 +28394,8 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
|
||||
sqlite3_changes64(p->db), sqlite3_total_changes64(p->db));
|
||||
oputf("%s\n", zLineBuf);
|
||||
}
|
||||
|
||||
if( doAutoDetectRestore(p, zSql) ) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -28711,14 +28829,14 @@ static void printBold(const char *zText){
|
||||
FOREGROUND_RED|FOREGROUND_INTENSITY
|
||||
);
|
||||
#endif
|
||||
oputz(zText);
|
||||
sputz(stdout, zText);
|
||||
#if !SQLITE_OS_WINRT
|
||||
SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void printBold(const char *zText){
|
||||
oputf("\033[1m%s\033[0m", zText);
|
||||
sputf(stdout, "\033[1m%s\033[0m", zText);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -28912,10 +29030,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
}else if( cli_strcmp(z,"-init")==0 ){
|
||||
zInitFile = cmdline_option_value(argc, argv, ++i);
|
||||
}else if( cli_strcmp(z,"-interactive")==0 ){
|
||||
/* Need to check for interactive override here to so that it can
|
||||
** affect console setup (for Windows only) and testing thereof.
|
||||
*/
|
||||
stdin_is_interactive = 1;
|
||||
}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
|
||||
@ -29185,11 +29299,14 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
}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*));
|
||||
sputf(stdout, "%s %s (%d-bit)\n",
|
||||
sqlite3_libversion(), sqlite3_sourceid(), 8*(int)sizeof(char*));
|
||||
return 0;
|
||||
}else if( cli_strcmp(z,"-interactive")==0 ){
|
||||
/* already handled */
|
||||
/* Need to check for interactive override here to so that it can
|
||||
** affect console setup (for Windows only) and testing thereof.
|
||||
*/
|
||||
stdin_is_interactive = 1;
|
||||
}else if( cli_strcmp(z,"-batch")==0 ){
|
||||
/* already handled */
|
||||
}else if( cli_strcmp(z,"-utf8")==0 ){
|
||||
@ -29318,13 +29435,13 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
#else
|
||||
# define SHELL_CIO_CHAR_SET ""
|
||||
#endif
|
||||
oputf("SQLite version %s %.19s%s\n" /*extra-version-info*/
|
||||
sputf(stdout, "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 ");
|
||||
sputz(stdout, "Connected to a ");
|
||||
printBold("transient in-memory database");
|
||||
oputz(".\nUse \".open FILENAME\" to reopen on a"
|
||||
sputz(stdout, ".\nUse \".open FILENAME\" to reopen on a"
|
||||
" persistent database.\n");
|
||||
}
|
||||
zHistory = getenv("SQLITE_HISTORY");
|
||||
|
Reference in New Issue
Block a user