MFV r354257:

Update sqlite3-3.29.0 (3290000) --> sqlite3-3.30.1 (3300100)

MFC after:	1 month
This commit is contained in:
Cy Schubert 2019-11-03 01:25:46 +00:00
commit f1b328b32f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=354269
10 changed files with 5642 additions and 4098 deletions

View File

@ -73,7 +73,7 @@ API_ARMOR = 0
!IFNDEF NO_WARN !IFNDEF NO_WARN
!IF $(USE_FULLWARN)!=0 !IF $(USE_FULLWARN)!=0
NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206 NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706 NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4244 -wd4305 -wd4306 -wd4702 -wd4706
!ENDIF !ENDIF
!ENDIF !ENDIF

View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.29.0. # Generated by GNU Autoconf 2.69 for sqlite 3.30.1.
# #
# Report bugs to <http://www.sqlite.org>. # Report bugs to <http://www.sqlite.org>.
# #
@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='sqlite' PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite' PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.29.0' PACKAGE_VERSION='3.30.1'
PACKAGE_STRING='sqlite 3.29.0' PACKAGE_STRING='sqlite 3.30.1'
PACKAGE_BUGREPORT='http://www.sqlite.org' PACKAGE_BUGREPORT='http://www.sqlite.org'
PACKAGE_URL='' PACKAGE_URL=''
@ -1341,7 +1341,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures sqlite 3.29.0 to adapt to many kinds of systems. \`configure' configures sqlite 3.30.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1412,7 +1412,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.29.0:";; short | recursive ) echo "Configuration of sqlite 3.30.1:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1537,7 +1537,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
sqlite configure 3.29.0 sqlite configure 3.30.1
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -1952,7 +1952,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.29.0, which was It was created by sqlite $as_me 3.30.1, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -2818,7 +2818,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='sqlite' PACKAGE='sqlite'
VERSION='3.29.0' VERSION='3.30.1'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -14438,7 +14438,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by sqlite $as_me 3.29.0, which was This file was extended by sqlite $as_me 3.30.1, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -14495,7 +14495,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
sqlite config.status 3.29.0 sqlite config.status 3.30.1
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -10,7 +10,7 @@
# #
AC_PREREQ(2.61) AC_PREREQ(2.61)
AC_INIT(sqlite, 3.29.0, http://www.sqlite.org) AC_INIT(sqlite, 3.30.1, http://www.sqlite.org)
AC_CONFIG_SRCDIR([sqlite3.c]) AC_CONFIG_SRCDIR([sqlite3.c])
AC_CONFIG_AUX_DIR([.]) AC_CONFIG_AUX_DIR([.])

View File

@ -9801,12 +9801,12 @@ static void editFunc(
} }
sz = sqlite3_value_bytes(argv[0]); sz = sqlite3_value_bytes(argv[0]);
if( bBin ){ if( bBin ){
x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f); x = fwrite(sqlite3_value_blob(argv[0]), 1, (size_t)sz, f);
}else{ }else{
const char *z = (const char*)sqlite3_value_text(argv[0]); const char *z = (const char*)sqlite3_value_text(argv[0]);
/* Remember whether or not the value originally contained \r\n */ /* Remember whether or not the value originally contained \r\n */
if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1; if( z && strstr(z,"\r\n")!=0 ) hasCRNL = 1;
x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f); x = fwrite(sqlite3_value_text(argv[0]), 1, (size_t)sz, f);
} }
fclose(f); fclose(f);
f = 0; f = 0;
@ -9834,12 +9834,12 @@ static void editFunc(
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
sz = ftell(f); sz = ftell(f);
rewind(f); rewind(f);
p = sqlite3_malloc64( sz+(bBin==0) ); p = sqlite3_malloc64( sz+1 );
if( p==0 ){ if( p==0 ){
sqlite3_result_error_nomem(context); sqlite3_result_error_nomem(context);
goto edit_func_end; goto edit_func_end;
} }
x = fread(p, 1, sz, f); x = fread(p, 1, (size_t)sz, f);
fclose(f); fclose(f);
f = 0; f = 0;
if( x!=sz ){ if( x!=sz ){
@ -10311,7 +10311,8 @@ static void eqp_render_level(ShellState *p, int iEqpId){
for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){ for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){
pNext = eqp_next_row(p, iEqpId, pRow); pNext = eqp_next_row(p, iEqpId, pRow);
z = pRow->zText; z = pRow->zText;
utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z); utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix,
pNext ? "|--" : "`--", z);
if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){ if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){
memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4); memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4);
eqp_render_level(p, pRow->iEqpId); eqp_render_level(p, pRow->iEqpId);
@ -10502,7 +10503,7 @@ static int shell_callback(
while( j>0 && IsSpace(z[j-1]) ){ j--; } while( j>0 && IsSpace(z[j-1]) ){ j--; }
z[j] = 0; z[j] = 0;
if( strlen30(z)>=79 ){ if( strlen30(z)>=79 ){
for(i=j=0; (c = z[i])!=0; i++){ /* Copy changes from z[i] back to z[j] */ for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */
if( c==cEnd ){ if( c==cEnd ){
cEnd = 0; cEnd = 0;
}else if( c=='"' || c=='\'' || c=='`' ){ }else if( c=='"' || c=='\'' || c=='`' ){
@ -11081,7 +11082,7 @@ static int display_stats(
raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur); raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
raw_printf(pArg->out, "Reprepare operations: %d\n", iCur); raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
raw_printf(pArg->out, "Number of times run: %d\n", iCur); raw_printf(pArg->out, "Number of times run: %d\n", iCur);
@ -12004,20 +12005,20 @@ static const char *(azHelp[]) = {
".archive ... Manage SQL archives", ".archive ... Manage SQL archives",
" Each command must have exactly one of the following options:", " Each command must have exactly one of the following options:",
" -c, --create Create a new archive", " -c, --create Create a new archive",
" -u, --update Add files or update files with changed mtime", " -u, --update Add or update files with changed mtime",
" -i, --insert Like -u but always add even if mtime unchanged", " -i, --insert Like -u but always add even if unchanged",
" -t, --list List contents of archive", " -t, --list List contents of archive",
" -x, --extract Extract files from archive", " -x, --extract Extract files from archive",
" Optional arguments:", " Optional arguments:",
" -v, --verbose Print each filename as it is processed", " -v, --verbose Print each filename as it is processed",
" -f FILE, --file FILE Operate on archive FILE (default is current db)", " -f FILE, --file FILE Use archive FILE (default is current db)",
" -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS", " -a FILE, --append FILE Open FILE using the apndvfs VFS",
" -C DIR, --directory DIR Change to directory DIR to read/extract files", " -C DIR, --directory DIR Read/extract files from directory DIR",
" -n, --dryrun Show the SQL that would have occurred", " -n, --dryrun Show the SQL that would have occurred",
" Examples:", " Examples:",
" .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar", " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
" .ar -tf archive.sar # List members of archive.sar", " .ar -tf ARCHIVE # List members of ARCHIVE",
" .ar -xvf archive.sar # Verbosely extract files from archive.sar", " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
" See also:", " See also:",
" http://sqlite.org/cli.html#sqlar_archive_support", " http://sqlite.org/cli.html#sqlar_archive_support",
#endif #endif
@ -12026,7 +12027,7 @@ static const char *(azHelp[]) = {
#endif #endif
".backup ?DB? FILE Backup DB (default \"main\") to FILE", ".backup ?DB? FILE Backup DB (default \"main\") to FILE",
" --append Use the appendvfs", " --append Use the appendvfs",
" --async Write to FILE without a journal and without fsync()", " --async Write to FILE without journal and fsync()",
".bail on|off Stop after hitting an error. Default OFF", ".bail on|off Stop after hitting an error. Default OFF",
".binary on|off Turn binary output on or off. Default OFF", ".binary on|off Turn binary output on or off. Default OFF",
".cd DIRECTORY Change the working directory to DIRECTORY", ".cd DIRECTORY Change the working directory to DIRECTORY",
@ -12046,15 +12047,15 @@ static const char *(azHelp[]) = {
" Other Modes:", " Other Modes:",
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
" test Show raw EXPLAIN QUERY PLAN output", " test Show raw EXPLAIN QUERY PLAN output",
" trace Like \"full\" but also enable \"PRAGMA vdbe_trace\"", " trace Like \"full\" but enable \"PRAGMA vdbe_trace\"",
#endif #endif
" trigger Like \"full\" but also show trigger bytecode", " trigger Like \"full\" but also show trigger bytecode",
".excel Display the output of next command in a spreadsheet", ".excel Display the output of next command in spreadsheet",
".exit ?CODE? Exit this program with return-code CODE", ".exit ?CODE? Exit this program with return-code CODE",
".expert EXPERIMENTAL. Suggest indexes for specified queries", ".expert EXPERIMENTAL. Suggest indexes for queries",
/* Because explain mode comes on automatically now, the ".explain" mode /* Because explain mode comes on automatically now, the ".explain" mode
** is removed from the help screen. It is still supported for legacy, however */ ** is removed from the help screen. It is still supported for legacy, however */
/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic",*/ /*".explain ?on|off|auto? Turn EXPLAIN output mode on or off",*/
".filectrl CMD ... Run various sqlite3_file_control() operations", ".filectrl CMD ... Run various sqlite3_file_control() operations",
" Run \".filectrl\" with no arguments for details", " Run \".filectrl\" with no arguments for details",
".fullschema ?--indent? Show schema and the content of sqlite_stat tables", ".fullschema ?--indent? Show schema and the content of sqlite_stat tables",
@ -12101,7 +12102,7 @@ static const char *(azHelp[]) = {
" --append Use appendvfs to append database to the end of FILE", " --append Use appendvfs to append database to the end of FILE",
#ifdef SQLITE_ENABLE_DESERIALIZE #ifdef SQLITE_ENABLE_DESERIALIZE
" --deserialize Load into memory useing sqlite3_deserialize()", " --deserialize Load into memory useing sqlite3_deserialize()",
" --hexdb Load the output of \"dbtotxt\" as an in-memory database", " --hexdb Load the output of \"dbtotxt\" as an in-memory db",
" --maxsize N Maximum size for --hexdb or --deserialized database", " --maxsize N Maximum size for --hexdb or --deserialized database",
#endif #endif
" --new Initialize FILE to an empty database", " --new Initialize FILE to an empty database",
@ -12114,7 +12115,7 @@ static const char *(azHelp[]) = {
" init Initialize the TEMP table that holds bindings", " init Initialize the TEMP table that holds bindings",
" list List the current parameter bindings", " list List the current parameter bindings",
" set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE", " set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE",
" PARAMETER should start with '$', ':', '@', or '?'", " PARAMETER should start with one of: $ : @ ?",
" unset PARAMETER Remove PARAMETER from the binding table", " unset PARAMETER Remove PARAMETER from the binding table",
".print STRING... Print literal STRING", ".print STRING... Print literal STRING",
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
@ -12129,6 +12130,11 @@ static const char *(azHelp[]) = {
".read FILE Read input from FILE", ".read FILE Read input from FILE",
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
".recover Recover as much data as possible from corrupt db.", ".recover Recover as much data as possible from corrupt db.",
" --freelist-corrupt Assume the freelist is corrupt",
" --recovery-db NAME Store recovery metadata in database file NAME",
" --lost-and-found TABLE Alternative name for the lost-and-found table",
" --no-rowids Do not attempt to recover rowid values",
" that are not also INTEGER PRIMARY KEYs",
#endif #endif
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE", ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
".save FILE Write in-memory database into FILE", ".save FILE Write in-memory database into FILE",
@ -12160,7 +12166,7 @@ static const char *(azHelp[]) = {
" Options:", " Options:",
" --schema Also hash the sqlite_master table", " --schema Also hash the sqlite_master table",
" --sha3-224 Use the sha3-224 algorithm", " --sha3-224 Use the sha3-224 algorithm",
" --sha3-256 Use the sha3-256 algorithm. This is the default.", " --sha3-256 Use the sha3-256 algorithm (default)",
" --sha3-384 Use the sha3-384 algorithm", " --sha3-384 Use the sha3-384 algorithm",
" --sha3-512 Use the sha3-512 algorithm", " --sha3-512 Use the sha3-512 algorithm",
" Any other argument is a LIKE pattern for tables to hash", " Any other argument is a LIKE pattern for tables to hash",
@ -12194,6 +12200,10 @@ static const char *(azHelp[]) = {
" --row Trace each row (SQLITE_TRACE_ROW)", " --row Trace each row (SQLITE_TRACE_ROW)",
" --close Trace connection close (SQLITE_TRACE_CLOSE)", " --close Trace connection close (SQLITE_TRACE_CLOSE)",
#endif /* SQLITE_OMIT_TRACE */ #endif /* SQLITE_OMIT_TRACE */
#ifdef SQLITE_DEBUG
".unmodule NAME ... Unregister virtual table modules",
" --allexcept Unregister everything except those named",
#endif
".vfsinfo ?AUX? Information about the top-level VFS", ".vfsinfo ?AUX? Information about the top-level VFS",
".vfslist List all available VFSes", ".vfslist List all available VFSes",
".vfsname ?AUX? Print the name of the VFS stack", ".vfsname ?AUX? Print the name of the VFS stack",
@ -12436,6 +12446,8 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){
rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
if( rc!=2 ) goto readHexDb_error; if( rc!=2 ) goto readHexDb_error;
if( n<0 ) 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 ); a = sqlite3_malloc( n ? n : 1 );
if( a==0 ){ if( a==0 ){
utf8_printf(stderr, "Out of memory!\n"); utf8_printf(stderr, "Out of memory!\n");
@ -12520,6 +12532,23 @@ static void shellInt32(
} }
} }
/*
** Scalar function "shell_idquote(X)" returns string X quoted as an identifier,
** using "..." with internal double-quote characters doubled.
*/
static void shellIdQuote(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *zName = (const char*)sqlite3_value_text(argv[0]);
UNUSED_PARAMETER(argc);
if( zName ){
char *z = sqlite3_mprintf("\"%w\"", zName);
sqlite3_result_text(context, z, -1, sqlite3_free);
}
}
/* /*
** Scalar function "shell_escape_crnl" used by the .recover command. ** Scalar function "shell_escape_crnl" used by the .recover command.
** The argument passed to this function is the output of built-in ** The argument passed to this function is the output of built-in
@ -12696,6 +12725,8 @@ static void open_db(ShellState *p, int openFlags){
shellEscapeCrnl, 0, 0); shellEscapeCrnl, 0, 0);
sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0, sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0,
shellInt32, 0, 0); shellInt32, 0, 0);
sqlite3_create_function(p->db, "shell_idquote", 1, SQLITE_UTF8, 0,
shellIdQuote, 0, 0);
#ifndef SQLITE_NOHAVE_SYSTEM #ifndef SQLITE_NOHAVE_SYSTEM
sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0, sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
editFunc, 0, 0); editFunc, 0, 0);
@ -14043,7 +14074,7 @@ void shellReset(
#endif /* !defined SQLITE_OMIT_VIRTUALTABLE */ #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
/********************************************************************************* /******************************************************************************
** The ".archive" or ".ar" command. ** The ".archive" or ".ar" command.
*/ */
/* /*
@ -14241,7 +14272,8 @@ static int arParseCommand(
i = n; i = n;
}else{ }else{
if( iArg>=(nArg-1) ){ if( iArg>=(nArg-1) ){
return arErrorMsg(pAr, "option requires an argument: %c",z[i]); return arErrorMsg(pAr, "option requires an argument: %c",
z[i]);
} }
zArg = azArg[++iArg]; zArg = azArg[++iArg];
} }
@ -14629,10 +14661,10 @@ static int arCreateOrUpdateCommand(
** Implementation of ".ar" dot command. ** Implementation of ".ar" dot command.
*/ */
static int arDotCommand( static int arDotCommand(
ShellState *pState, /* Current shell tool state */ ShellState *pState, /* Current shell tool state */
int fromCmdLine, /* True if -A command-line option, not .ar cmd */ int fromCmdLine, /* True if -A command-line option, not .ar cmd */
char **azArg, /* Array of arguments passed to dot command */ char **azArg, /* Array of arguments passed to dot command */
int nArg /* Number of entries in azArg[] */ int nArg /* Number of entries in azArg[] */
){ ){
ArCommand cmd; ArCommand cmd;
int rc; int rc;
@ -14732,7 +14764,7 @@ static int arDotCommand(
return rc; return rc;
} }
/* End of the ".archive" or ".ar" command logic /* End of the ".archive" or ".ar" command logic
**********************************************************************************/ *******************************************************************************/
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
@ -14873,6 +14905,10 @@ static RecoverTable *recoverNewTable(
sqlite3_stmt *pStmt = 0; sqlite3_stmt *pStmt = 0;
rc = sqlite3_open("", &dbtmp); rc = sqlite3_open("", &dbtmp);
if( rc==SQLITE_OK ){
sqlite3_create_function(dbtmp, "shell_idquote", 1, SQLITE_UTF8, 0,
shellIdQuote, 0, 0);
}
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0); rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0);
} }
@ -14929,18 +14965,18 @@ static RecoverTable *recoverNewTable(
} }
} }
pTab->zQuoted = shellMPrintf(&rc, "%Q", zName); pTab->zQuoted = shellMPrintf(&rc, "\"%w\"", zName);
pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1)); pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1));
pTab->nCol = nSqlCol; pTab->nCol = nSqlCol;
if( bIntkey ){ if( bIntkey ){
pTab->azlCol[0] = shellMPrintf(&rc, "%Q", zPk); pTab->azlCol[0] = shellMPrintf(&rc, "\"%w\"", zPk);
}else{ }else{
pTab->azlCol[0] = shellMPrintf(&rc, ""); pTab->azlCol[0] = shellMPrintf(&rc, "");
} }
i = 1; i = 1;
shellPreparePrintf(dbtmp, &rc, &pStmt, shellPreparePrintf(dbtmp, &rc, &pStmt,
"SELECT %Q || group_concat(name, ', ') " "SELECT %Q || group_concat(shell_idquote(name), ', ') "
" FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) " " FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) "
"FROM pragma_table_info(%Q)", "FROM pragma_table_info(%Q)",
bIntkey ? ", " : "", pTab->iPk, bIntkey ? ", " : "", pTab->iPk,
@ -15054,7 +15090,7 @@ static RecoverTable *recoverOrphanTable(
pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable)); pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable));
if( pTab ){ if( pTab ){
pTab->zQuoted = shellMPrintf(pRc, "%Q", zTab); pTab->zQuoted = shellMPrintf(pRc, "\"%w\"", zTab);
pTab->nCol = nCol; pTab->nCol = nCol;
pTab->iPk = -2; pTab->iPk = -2;
if( nCol>0 ){ if( nCol>0 ){
@ -15103,6 +15139,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
RecoverTable *pOrphan = 0; RecoverTable *pOrphan = 0;
int bFreelist = 1; /* 0 if --freelist-corrupt is specified */ int bFreelist = 1; /* 0 if --freelist-corrupt is specified */
int bRowids = 1; /* 0 if --no-rowids */
for(i=1; i<nArg; i++){ for(i=1; i<nArg; i++){
char *z = azArg[i]; char *z = azArg[i];
int n; int n;
@ -15118,13 +15155,13 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){ if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){
i++; i++;
zLostAndFound = azArg[i]; zLostAndFound = azArg[i];
}else
if( n<=10 && memcmp("-no-rowids", z, n)==0 ){
bRowids = 0;
} }
else{ else{
raw_printf(stderr, "unexpected option: %s\n", azArg[i]); utf8_printf(stderr, "unexpected option: %s\n", azArg[i]);
raw_printf(stderr, "options are:\n"); showHelp(pState->out, azArg[0]);
raw_printf(stderr, " --freelist-corrupt\n");
raw_printf(stderr, " --recovery-db DATABASE\n");
raw_printf(stderr, " --lost-and-found TABLE-NAME\n");
return 1; return 1;
} }
} }
@ -15132,6 +15169,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
shellExecPrintf(pState->db, &rc, shellExecPrintf(pState->db, &rc,
/* Attach an in-memory database named 'recovery'. Create an indexed /* Attach an in-memory database named 'recovery'. Create an indexed
** cache of the sqlite_dbptr virtual table. */ ** cache of the sqlite_dbptr virtual table. */
"PRAGMA writable_schema = on;"
"ATTACH %Q AS recovery;" "ATTACH %Q AS recovery;"
"DROP TABLE IF EXISTS recovery.dbptr;" "DROP TABLE IF EXISTS recovery.dbptr;"
"DROP TABLE IF EXISTS recovery.freelist;" "DROP TABLE IF EXISTS recovery.freelist;"
@ -15162,6 +15200,21 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
); );
} }
/* If this is an auto-vacuum database, add all pointer-map pages to
** the freelist table. Do this regardless of whether or not
** --freelist-corrupt was specified. */
shellExec(pState->db, &rc,
"WITH ptrmap(pgno) AS ("
" SELECT 2 WHERE shell_int32("
" (SELECT data FROM sqlite_dbpage WHERE pgno=1), 13"
" )"
" UNION ALL "
" SELECT pgno+1+(SELECT page_size FROM pragma_page_size)/5 AS pp "
" FROM ptrmap WHERE pp<=(SELECT page_count FROM pragma_page_count)"
")"
"REPLACE INTO recovery.freelist SELECT pgno FROM ptrmap"
);
shellExec(pState->db, &rc, shellExec(pState->db, &rc,
"CREATE TABLE recovery.dbptr(" "CREATE TABLE recovery.dbptr("
" pgno, child, PRIMARY KEY(child, pgno)" " pgno, child, PRIMARY KEY(child, pgno)"
@ -15210,7 +15263,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
" )" " )"
" SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)" " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)"
") " ") "
"FROM pages WHERE maxlen > 0 AND i NOT IN freelist;" "FROM pages WHERE maxlen IS NOT NULL AND i NOT IN freelist;"
"UPDATE recovery.map AS o SET intkey = (" "UPDATE recovery.map AS o SET intkey = ("
" SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno" " SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno"
");" ");"
@ -15235,6 +15288,11 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
** CREATE TABLE statements that extracted from the existing schema. */ ** CREATE TABLE statements that extracted from the existing schema. */
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
sqlite3_stmt *pStmt = 0; sqlite3_stmt *pStmt = 0;
/* ".recover" might output content in an order which causes immediate
** foreign key constraints to be violated. So disable foreign-key
** constraint enforcement to prevent problems when running the output
** script. */
raw_printf(pState->out, "PRAGMA foreign_keys=OFF;\n");
raw_printf(pState->out, "BEGIN;\n"); raw_printf(pState->out, "BEGIN;\n");
raw_printf(pState->out, "PRAGMA writable_schema = on;\n"); raw_printf(pState->out, "PRAGMA writable_schema = on;\n");
shellPrepare(pState->db, &rc, shellPrepare(pState->db, &rc,
@ -15265,8 +15323,12 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
shellPrepare(pState->db, &rc, shellPrepare(pState->db, &rc,
"SELECT pgno FROM recovery.map WHERE root=?", &pPages "SELECT pgno FROM recovery.map WHERE root=?", &pPages
); );
shellPrepare(pState->db, &rc, shellPrepare(pState->db, &rc,
"SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')" "SELECT max(field), group_concat(shell_escape_crnl(quote"
"(case when (? AND field<0) then NULL else value end)"
"), ', ')"
", min(field) "
"FROM sqlite_dbdata WHERE pgno = ? AND field != ?" "FROM sqlite_dbdata WHERE pgno = ? AND field != ?"
"GROUP BY cell", &pCells "GROUP BY cell", &pCells
); );
@ -15285,6 +15347,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
int bNoop = 0; int bNoop = 0;
RecoverTable *pTab; RecoverTable *pTab;
assert( bIntkey==0 || bIntkey==1 );
pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop); pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop);
if( bNoop || rc ) continue; if( bNoop || rc ) continue;
if( pTab==0 ){ if( pTab==0 ){
@ -15295,29 +15358,44 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
if( pTab==0 ) break; if( pTab==0 ) break;
} }
if( 0==sqlite3_stricmp(pTab->zQuoted, "'sqlite_sequence'") ){ if( 0==sqlite3_stricmp(pTab->zQuoted, "\"sqlite_sequence\"") ){
raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n"); raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n");
} }
sqlite3_bind_int(pPages, 1, iRoot); sqlite3_bind_int(pPages, 1, iRoot);
sqlite3_bind_int(pCells, 2, pTab->iPk); if( bRowids==0 && pTab->iPk<0 ){
sqlite3_bind_int(pCells, 1, 1);
}else{
sqlite3_bind_int(pCells, 1, 0);
}
sqlite3_bind_int(pCells, 3, pTab->iPk);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){
int iPgno = sqlite3_column_int(pPages, 0); int iPgno = sqlite3_column_int(pPages, 0);
sqlite3_bind_int(pCells, 1, iPgno); sqlite3_bind_int(pCells, 2, iPgno);
while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){
int nField = sqlite3_column_int(pCells, 0); int nField = sqlite3_column_int(pCells, 0);
int iMin = sqlite3_column_int(pCells, 2);
const char *zVal = (const char*)sqlite3_column_text(pCells, 1); const char *zVal = (const char*)sqlite3_column_text(pCells, 1);
RecoverTable *pTab2 = pTab;
if( pTab!=pOrphan && (iMin<0)!=bIntkey ){
if( pOrphan==0 ){
pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan);
}
pTab2 = pOrphan;
if( pTab2==0 ) break;
}
nField = nField+1; nField = nField+1;
if( pTab==pOrphan ){ if( pTab2==pOrphan ){
raw_printf(pState->out, raw_printf(pState->out,
"INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n", "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n",
pTab->zQuoted, iRoot, iPgno, nField, pTab2->zQuoted, iRoot, iPgno, nField,
bIntkey ? "" : "NULL, ", zVal, pTab->azlCol[nField] iMin<0 ? "" : "NULL, ", zVal, pTab2->azlCol[nField]
); );
}else{ }else{
raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n", raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n",
pTab->zQuoted, pTab->azlCol[nField], zVal pTab2->zQuoted, pTab2->azlCol[nField], zVal
); );
} }
} }
@ -15376,7 +15454,7 @@ static int do_meta_command(char *zLine, ShellState *p){
int nArg = 0; int nArg = 0;
int n, c; int n, c;
int rc = 0; int rc = 0;
char *azArg[50]; char *azArg[52];
#ifndef SQLITE_OMIT_VIRTUALTABLE #ifndef SQLITE_OMIT_VIRTUALTABLE
if( p->expert.pExpert ){ if( p->expert.pExpert ){
@ -15386,7 +15464,7 @@ static int do_meta_command(char *zLine, ShellState *p){
/* Parse the input line into tokens. /* Parse the input line into tokens.
*/ */
while( zLine[h] && nArg<ArraySize(azArg) ){ while( zLine[h] && nArg<ArraySize(azArg)-1 ){
while( IsSpace(zLine[h]) ){ h++; } while( IsSpace(zLine[h]) ){ h++; }
if( zLine[h]==0 ) break; if( zLine[h]==0 ) break;
if( zLine[h]=='\'' || zLine[h]=='"' ){ if( zLine[h]=='\'' || zLine[h]=='"' ){
@ -15407,6 +15485,7 @@ static int do_meta_command(char *zLine, ShellState *p){
resolve_backslashes(azArg[nArg-1]); resolve_backslashes(azArg[nArg-1]);
} }
} }
azArg[nArg] = 0;
/* Process the input line. /* Process the input line.
*/ */
@ -15622,6 +15701,7 @@ static int do_meta_command(char *zLine, ShellState *p){
} aDbConfig[] = { } aDbConfig[] = {
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
{ "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
{ "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
{ "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
{ "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
@ -15995,8 +16075,6 @@ static int do_meta_command(char *zLine, ShellState *p){
data.cMode = data.mode = MODE_Insert; data.cMode = data.mode = MODE_Insert;
data.zDestTable = "sqlite_stat1"; data.zDestTable = "sqlite_stat1";
shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg); shell_exec(&data, "SELECT * FROM sqlite_stat1", &zErrMsg);
data.zDestTable = "sqlite_stat3";
shell_exec(&data, "SELECT * FROM sqlite_stat3", &zErrMsg);
data.zDestTable = "sqlite_stat4"; data.zDestTable = "sqlite_stat4";
shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg); shell_exec(&data, "SELECT * FROM sqlite_stat4", &zErrMsg);
raw_printf(p->out, "ANALYZE sqlite_master;\n"); raw_printf(p->out, "ANALYZE sqlite_master;\n");
@ -16615,12 +16693,8 @@ static int do_meta_command(char *zLine, ShellState *p){
** Clear all bind parameters by dropping the TEMP table that holds them. ** Clear all bind parameters by dropping the TEMP table that holds them.
*/ */
if( nArg==2 && strcmp(azArg[1],"clear")==0 ){ if( nArg==2 && strcmp(azArg[1],"clear")==0 ){
int wrSchema = 0;
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, -1, &wrSchema);
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, 1, 0);
sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;", sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp.sqlite_parameters;",
0, 0, 0); 0, 0, 0);
sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_SCHEMA, wrSchema, 0);
}else }else
/* .parameter list /* .parameter list
@ -16933,7 +17007,7 @@ static int do_meta_command(char *zLine, ShellState *p){
zDiv = " UNION ALL "; zDiv = " UNION ALL ";
appendText(&sSelect, "SELECT shell_add_schema(sql,", 0); appendText(&sSelect, "SELECT shell_add_schema(sql,", 0);
if( sqlite3_stricmp(zDb, "main")!=0 ){ if( sqlite3_stricmp(zDb, "main")!=0 ){
appendText(&sSelect, zDb, '"'); appendText(&sSelect, zDb, '\'');
}else{ }else{
appendText(&sSelect, "NULL", 0); appendText(&sSelect, "NULL", 0);
} }
@ -16942,15 +17016,16 @@ static int do_meta_command(char *zLine, ShellState *p){
appendText(&sSelect, " AS snum, ", 0); appendText(&sSelect, " AS snum, ", 0);
appendText(&sSelect, zDb, '\''); appendText(&sSelect, zDb, '\'');
appendText(&sSelect, " AS sname FROM ", 0); appendText(&sSelect, " AS sname FROM ", 0);
appendText(&sSelect, zDb, '"'); appendText(&sSelect, zDb, quoteChar(zDb));
appendText(&sSelect, ".sqlite_master", 0); appendText(&sSelect, ".sqlite_master", 0);
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
#ifdef SQLITE_INTROSPECTION_PRAGMAS #ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS
if( zName ){ if( zName ){
appendText(&sSelect, appendText(&sSelect,
" UNION ALL SELECT shell_module_schema(name)," " UNION ALL SELECT shell_module_schema(name),"
" 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0); " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list",
0);
} }
#endif #endif
appendText(&sSelect, ") WHERE ", 0); appendText(&sSelect, ") WHERE ", 0);
@ -17049,7 +17124,8 @@ static int do_meta_command(char *zLine, ShellState *p){
if( pSession->p==0 ) goto session_not_open; if( pSession->p==0 ) goto session_not_open;
out = fopen(azCmd[1], "wb"); out = fopen(azCmd[1], "wb");
if( out==0 ){ if( out==0 ){
utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n",
azCmd[1]);
}else{ }else{
int szChng; int szChng;
void *pChng; void *pChng;
@ -17370,8 +17446,7 @@ static int do_meta_command(char *zLine, ShellState *p){
{ {
utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n", utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
azArg[i], azArg[0]); azArg[i], azArg[0]);
raw_printf(stderr, "Should be one of: --schema" showHelp(p->out, azArg[0]);
" --sha3-224 --sha3-256 --sha3-384 --sha3-512\n");
rc = 1; rc = 1;
goto meta_command_exit; goto meta_command_exit;
} }
@ -17417,8 +17492,7 @@ static int do_meta_command(char *zLine, ShellState *p){
}else if( strcmp(zTab, "sqlite_stat1")==0 ){ }else if( strcmp(zTab, "sqlite_stat1")==0 ){
appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1" appendText(&sQuery,"SELECT tbl,idx,stat FROM sqlite_stat1"
" ORDER BY tbl,idx;", 0); " ORDER BY tbl,idx;", 0);
}else if( strcmp(zTab, "sqlite_stat3")==0 }else if( strcmp(zTab, "sqlite_stat4")==0 ){
|| strcmp(zTab, "sqlite_stat4")==0 ){
appendText(&sQuery, "SELECT * FROM ", 0); appendText(&sQuery, "SELECT * FROM ", 0);
appendText(&sQuery, zTab, 0); appendText(&sQuery, zTab, 0);
appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0); appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
@ -17650,25 +17724,26 @@ static int do_meta_command(char *zLine, ShellState *p){
int ctrlCode; /* Integer code for that option */ int ctrlCode; /* Integer code for that option */
const char *zUsage; /* Usage notes */ const char *zUsage; /* Usage notes */
} aCtrl[] = { } aCtrl[] = {
{ "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" }, { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" },
{ "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" }, { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" },
/*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/ /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
/*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/ /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
{ "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" }, { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
/*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */ { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" },
{ "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"}, /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/
{ "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" }, { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
{ "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" }, { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" },
{ "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" }, { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
{ "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" }, { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
{ "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
#ifdef YYCOVERAGE #ifdef YYCOVERAGE
{ "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" }, { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
#endif #endif
{ "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " }, { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
{ "prng_reset", SQLITE_TESTCTRL_PRNG_RESET, "" }, { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
{ "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" }, { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
{ "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" }, { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
{ "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE" }, { "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE"},
}; };
int testctrl = -1; int testctrl = -1;
int iCtrl = -1; int iCtrl = -1;
@ -17749,6 +17824,27 @@ static int do_meta_command(char *zLine, ShellState *p){
} }
break; break;
/* 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 && strcmp(azArg[2],"random")==0 ){
sqlite3_randomness(sizeof(ii),&ii);
printf("-- 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);
}
rc2 = sqlite3_test_control(testctrl, ii, db);
isOk = 3;
}
break;
/* sqlite3_test_control(int, int) */ /* sqlite3_test_control(int, int) */
case SQLITE_TESTCTRL_ASSERT: case SQLITE_TESTCTRL_ASSERT:
case SQLITE_TESTCTRL_ALWAYS: case SQLITE_TESTCTRL_ALWAYS:
@ -17790,7 +17886,7 @@ static int do_meta_command(char *zLine, ShellState *p){
} }
} }
if( isOk==0 && iCtrl>=0 ){ if( isOk==0 && iCtrl>=0 ){
utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd, aCtrl[iCtrl].zUsage); utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
rc = 1; rc = 1;
}else if( isOk==1 ){ }else if( isOk==1 ){
raw_printf(p->out, "%d\n", rc2); raw_printf(p->out, "%d\n", rc2);
@ -17868,6 +17964,31 @@ static int do_meta_command(char *zLine, ShellState *p){
}else }else
#endif /* !defined(SQLITE_OMIT_TRACE) */ #endif /* !defined(SQLITE_OMIT_TRACE) */
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_VIRTUALTABLE)
if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){
int ii;
int lenOpt;
char *zOpt;
if( nArg<2 ){
raw_printf(stderr, "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);
if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){
assert( azArg[nArg]==0 );
sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0);
}else{
for(ii=1; ii<nArg; ii++){
sqlite3_create_module(p->db, azArg[ii], 0, 0);
}
}
}else
#endif
#if SQLITE_USER_AUTHENTICATION #if SQLITE_USER_AUTHENTICATION
if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ if( c=='u' && strncmp(azArg[0], "user", n)==0 ){
if( nArg<2 ){ if( nArg<2 ){
@ -17882,7 +18003,8 @@ static int do_meta_command(char *zLine, ShellState *p){
rc = 1; rc = 1;
goto meta_command_exit; goto meta_command_exit;
} }
rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3])); rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
strlen30(azArg[3]));
if( rc ){ if( rc ){
utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]); utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
rc = 1; rc = 1;

File diff suppressed because it is too large Load Diff

View File

@ -123,9 +123,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.29.0" #define SQLITE_VERSION "3.30.1"
#define SQLITE_VERSION_NUMBER 3029000 #define SQLITE_VERSION_NUMBER 3030001
#define SQLITE_SOURCE_ID "2019-07-10 17:32:03 fc82b73eaac8b36950e527f12c4b5dc1e147e6f4ad2217ae43ad82882a88bfa6" #define SQLITE_SOURCE_ID "2019-10-10 20:19:45 18db032d058f1436ce3dea84081f4ee5a0f2259ad97301d43c426bc7f3df1b0b"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@ -2093,6 +2093,17 @@ struct sqlite3_mem_methods {
** following this call. The second parameter may be a NULL pointer, in ** following this call. The second parameter may be a NULL pointer, in
** which case the trigger setting is not reported back. </dd> ** which case the trigger setting is not reported back. </dd>
** **
** [[SQLITE_DBCONFIG_ENABLE_VIEW]]
** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt>
** <dd> ^This option is used to enable or disable [CREATE VIEW | views].
** There should be two additional arguments.
** The first argument is an integer which is 0 to disable views,
** positive to enable views or negative to leave the setting unchanged.
** The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether views are disabled or enabled
** following this call. The second parameter may be a NULL pointer, in
** which case the view setting is not reported back. </dd>
**
** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]]
** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
** <dd> ^This option is used to enable or disable the ** <dd> ^This option is used to enable or disable the
@ -2265,7 +2276,8 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */
#define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */
#define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */
#define SQLITE_DBCONFIG_MAX 1014 /* Largest DBCONFIG */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */
#define SQLITE_DBCONFIG_MAX 1015 /* Largest DBCONFIG */
/* /*
** CAPI3REF: Enable Or Disable Extended Result Codes ** CAPI3REF: Enable Or Disable Extended Result Codes
@ -3814,7 +3826,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
** ^The specific value of WHERE-clause [parameter] might influence the ** ^The specific value of WHERE-clause [parameter] might influence the
** choice of query plan if the parameter is the left-hand side of a [LIKE] ** choice of query plan if the parameter is the left-hand side of a [LIKE]
** or [GLOB] operator or if the parameter is compared to an indexed column ** or [GLOB] operator or if the parameter is compared to an indexed column
** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. ** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled.
** </li> ** </li>
** </ol> ** </ol>
** **
@ -4849,6 +4861,12 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** perform additional optimizations on deterministic functions, so use ** perform additional optimizations on deterministic functions, so use
** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. ** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
** **
** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY]
** flag, which if present prevents the function from being invoked from
** within VIEWs or TRIGGERs. For security reasons, the [SQLITE_DIRECTONLY]
** flag is recommended for any application-defined SQL function that has
** side-effects.
**
** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^ ** function can gain access to this pointer using [sqlite3_user_data()].)^
** **
@ -4965,8 +4983,30 @@ SQLITE_API int sqlite3_create_window_function(
** [SQLITE_UTF8 | preferred text encoding] as the fourth argument ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
** to [sqlite3_create_function()], [sqlite3_create_function16()], or ** to [sqlite3_create_function()], [sqlite3_create_function16()], or
** [sqlite3_create_function_v2()]. ** [sqlite3_create_function_v2()].
**
** The SQLITE_DETERMINISTIC flag means that the new function will always
** maps the same inputs into the same output. The abs() function is
** deterministic, for example, but randomblob() is not.
**
** The SQLITE_DIRECTONLY flag means that the function may only be invoked
** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. This is
** a security feature which is recommended for all
** [application-defined SQL functions] that have side-effects. This flag
** prevents an attacker from adding triggers and views to a schema then
** tricking a high-privilege application into causing unintended side-effects
** while performing ordinary queries.
**
** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call
** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.
** Specifying this flag makes no difference for scalar or aggregate user
** functions. However, if it is not specified for a user-defined window
** function, then any sub-types belonging to arguments passed to the window
** function may be discarded before the window function is called (i.e.
** sqlite3_value_subtype() will always return 0).
*/ */
#define SQLITE_DETERMINISTIC 0x800 #define SQLITE_DETERMINISTIC 0x000000800
#define SQLITE_DIRECTONLY 0x000080000
#define SQLITE_SUBTYPE 0x000100000
/* /*
** CAPI3REF: Deprecated Functions ** CAPI3REF: Deprecated Functions
@ -6612,6 +6652,12 @@ struct sqlite3_index_info {
** ^The sqlite3_create_module() ** ^The sqlite3_create_module()
** interface is equivalent to sqlite3_create_module_v2() with a NULL ** interface is equivalent to sqlite3_create_module_v2() with a NULL
** destructor. ** destructor.
**
** ^If the third parameter (the pointer to the sqlite3_module object) is
** NULL then no new module is create and any existing modules with the
** same name are dropped.
**
** See also: [sqlite3_drop_modules()]
*/ */
SQLITE_API int sqlite3_create_module( SQLITE_API int sqlite3_create_module(
sqlite3 *db, /* SQLite connection to register module with */ sqlite3 *db, /* SQLite connection to register module with */
@ -6627,6 +6673,23 @@ SQLITE_API int sqlite3_create_module_v2(
void(*xDestroy)(void*) /* Module destructor function */ void(*xDestroy)(void*) /* Module destructor function */
); );
/*
** CAPI3REF: Remove Unnecessary Virtual Table Implementations
** METHOD: sqlite3
**
** ^The sqlite3_drop_modules(D,L) interface removes all virtual
** table modules from database connection D except those named on list L.
** The L parameter must be either NULL or a pointer to an array of pointers
** to strings where the array is terminated by a single NULL pointer.
** ^If the L parameter is NULL, then all virtual table modules are removed.
**
** See also: [sqlite3_create_module()]
*/
SQLITE_API int sqlite3_drop_modules(
sqlite3 *db, /* Remove modules from this connection */
const char **azKeep /* Except, do not remove the ones named here */
);
/* /*
** CAPI3REF: Virtual Table Instance Object ** CAPI3REF: Virtual Table Instance Object
** KEYWORDS: sqlite3_vtab ** KEYWORDS: sqlite3_vtab
@ -7335,7 +7398,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_FIRST 5 #define SQLITE_TESTCTRL_FIRST 5
#define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_SAVE 5
#define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESTORE 6
#define SQLITE_TESTCTRL_PRNG_RESET 7 #define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */
#define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_BITVEC_TEST 8
#define SQLITE_TESTCTRL_FAULT_INSTALL 9 #define SQLITE_TESTCTRL_FAULT_INSTALL 9
#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10
@ -7358,7 +7421,9 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_IMPOSTER 25 #define SQLITE_TESTCTRL_IMPOSTER 25
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26 #define SQLITE_TESTCTRL_PARSER_COVERAGE 26
#define SQLITE_TESTCTRL_RESULT_INTREAL 27 #define SQLITE_TESTCTRL_RESULT_INTREAL 27
#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */ #define SQLITE_TESTCTRL_PRNG_SEED 28
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
#define SQLITE_TESTCTRL_LAST 29 /* Largest TESTCTRL */
/* /*
** CAPI3REF: SQL Keyword Checking ** CAPI3REF: SQL Keyword Checking

View File

@ -322,6 +322,8 @@ struct sqlite3_api_routines {
/* Version 3.28.0 and later */ /* Version 3.28.0 and later */
int (*stmt_isexplain)(sqlite3_stmt*); int (*stmt_isexplain)(sqlite3_stmt*);
int (*value_frombind)(sqlite3_value*); int (*value_frombind)(sqlite3_value*);
/* Version 3.30.0 and later */
int (*drop_modules)(sqlite3*,const char**);
}; };
/* /*
@ -614,6 +616,8 @@ typedef int (*sqlite3_loadext_entry)(
/* Version 3.28.0 and later */ /* Version 3.28.0 and later */
#define sqlite3_stmt_isexplain sqlite3_api->isexplain #define sqlite3_stmt_isexplain sqlite3_api->isexplain
#define sqlite3_value_frombind sqlite3_api->frombind #define sqlite3_value_frombind sqlite3_api->frombind
/* Version 3.30.0 and later */
#define sqlite3_drop_modules sqlite3_api->drop_modules
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)

View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.29.0. # Generated by GNU Autoconf 2.69 for sqlite 3.30.1.
# #
# #
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@ -577,8 +577,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='sqlite' PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite' PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.29.0' PACKAGE_VERSION='3.30.1'
PACKAGE_STRING='sqlite 3.29.0' PACKAGE_STRING='sqlite 3.30.1'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
PACKAGE_URL='' PACKAGE_URL=''
@ -1303,7 +1303,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures sqlite 3.29.0 to adapt to many kinds of systems. \`configure' configures sqlite 3.30.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1365,7 +1365,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.29.0:";; short | recursive ) echo "Configuration of sqlite 3.30.1:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1467,7 +1467,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
sqlite configure 3.29.0 sqlite configure 3.30.1
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -1878,7 +1878,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.29.0, which was It was created by sqlite $as_me 3.30.1, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -9373,7 +9373,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by sqlite $as_me 3.29.0, which was This file was extended by sqlite $as_me 3.30.1, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -9426,7 +9426,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
sqlite config.status 3.29.0 sqlite config.status 3.30.1
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -19,7 +19,7 @@ dnl to configure the system for the local environment.
# so you can encode the package version directly into the source files. # so you can encode the package version directly into the source files.
#----------------------------------------------------------------------- #-----------------------------------------------------------------------
AC_INIT([sqlite], [3.29.0]) AC_INIT([sqlite], [3.30.1])
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars. # Call TEA_INIT as the first TEA_ macro to set up initial vars.

View File

@ -1922,33 +1922,33 @@ static int SQLITE_TCLAPI DbObjCmd(
"authorizer", "backup", "bind_fallback", "authorizer", "backup", "bind_fallback",
"busy", "cache", "changes", "busy", "cache", "changes",
"close", "collate", "collation_needed", "close", "collate", "collation_needed",
"commit_hook", "complete", "copy", "commit_hook", "complete", "config",
"deserialize", "enable_load_extension", "errorcode", "copy", "deserialize", "enable_load_extension",
"eval", "exists", "function", "errorcode", "eval", "exists",
"incrblob", "interrupt", "last_insert_rowid", "function", "incrblob", "interrupt",
"nullvalue", "onecolumn", "preupdate", "last_insert_rowid", "nullvalue", "onecolumn",
"profile", "progress", "rekey", "preupdate", "profile", "progress",
"restore", "rollback_hook", "serialize", "rekey", "restore", "rollback_hook",
"status", "timeout", "total_changes", "serialize", "status", "timeout",
"trace", "trace_v2", "transaction", "total_changes", "trace", "trace_v2",
"unlock_notify", "update_hook", "version", "transaction", "unlock_notify", "update_hook",
"wal_hook", 0 "version", "wal_hook", 0
}; };
enum DB_enum { enum DB_enum {
DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK, DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK,
DB_BUSY, DB_CACHE, DB_CHANGES, DB_BUSY, DB_CACHE, DB_CHANGES,
DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED,
DB_COMMIT_HOOK, DB_COMPLETE, DB_COPY, DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG,
DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE, DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,
DB_EVAL, DB_EXISTS, DB_FUNCTION, DB_ERRORCODE, DB_EVAL, DB_EXISTS,
DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT,
DB_NULLVALUE, DB_ONECOLUMN, DB_PREUPDATE, DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN,
DB_PROFILE, DB_PROGRESS, DB_REKEY, DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
DB_RESTORE, DB_ROLLBACK_HOOK, DB_SERIALIZE, DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, DB_SERIALIZE, DB_STATUS, DB_TIMEOUT,
DB_TRACE, DB_TRACE_V2, DB_TRANSACTION, DB_TOTAL_CHANGES, DB_TRACE, DB_TRACE_V2,
DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK,
DB_WAL_HOOK DB_VERSION, DB_WAL_HOOK
}; };
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
@ -2336,6 +2336,74 @@ static int SQLITE_TCLAPI DbObjCmd(
break; break;
} }
/* $db config ?OPTION? ?BOOLEAN?
**
** Configure the database connection using the sqlite3_db_config()
** interface.
*/
case DB_CONFIG: {
static const struct DbConfigChoices {
const char *zName;
int op;
} aDbConfig[] = {
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
{ "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
{ "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
{ "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
{ "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE },
{ "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
{ "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP },
{ "reset_database", SQLITE_DBCONFIG_RESET_DATABASE },
{ "defensive", SQLITE_DBCONFIG_DEFENSIVE },
{ "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA },
{ "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE },
{ "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
{ "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
};
Tcl_Obj *pResult;
int ii;
if( objc>4 ){
Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?");
return TCL_ERROR;
}
if( objc==2 ){
/* With no arguments, list all configuration options and with the
** current value */
pResult = Tcl_NewListObj(0,0);
for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
int v = 0;
sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v);
Tcl_ListObjAppendElement(interp, pResult,
Tcl_NewStringObj(aDbConfig[ii].zName,-1));
Tcl_ListObjAppendElement(interp, pResult,
Tcl_NewIntObj(v));
}
}else{
const char *zOpt = Tcl_GetString(objv[2]);
int onoff = -1;
int v = 0;
if( zOpt[0]=='-' ) zOpt++;
for(ii=0; ii<sizeof(aDbConfig)/sizeof(aDbConfig[0]); ii++){
if( strcmp(aDbConfig[ii].zName, zOpt)==0 ) break;
}
if( ii>=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){
Tcl_AppendResult(interp, "unknown config option: \"", zOpt,
"\"", (void*)0);
return TCL_ERROR;
}
if( objc==4 ){
if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){
return TCL_ERROR;
}
}
sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v);
pResult = Tcl_NewIntObj(v);
}
Tcl_SetObjResult(interp, pResult);
break;
}
/* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
** **
** Copy data into table from filename, optionally using SEPARATOR ** Copy data into table from filename, optionally using SEPARATOR
@ -2746,10 +2814,16 @@ static int SQLITE_TCLAPI DbObjCmd(
} }
/* /*
** $db function NAME [-argcount N] [-deterministic] SCRIPT ** $db function NAME [OPTIONS] SCRIPT
** **
** Create a new SQL function called NAME. Whenever that function is ** Create a new SQL function called NAME. Whenever that function is
** called, invoke SCRIPT to evaluate the function. ** called, invoke SCRIPT to evaluate the function.
**
** Options:
** --argcount N Function has exactly N arguments
** --deterministic The function is pure
** --directonly Prohibit use inside triggers and views
** --returntype TYPE Specify the return type of the function
*/ */
case DB_FUNCTION: { case DB_FUNCTION: {
int flags = SQLITE_UTF8; int flags = SQLITE_UTF8;
@ -2782,6 +2856,9 @@ static int SQLITE_TCLAPI DbObjCmd(
if( n>1 && strncmp(z, "-deterministic",n)==0 ){ if( n>1 && strncmp(z, "-deterministic",n)==0 ){
flags |= SQLITE_DETERMINISTIC; flags |= SQLITE_DETERMINISTIC;
}else }else
if( n>1 && strncmp(z, "-directonly",n)==0 ){
flags |= SQLITE_DIRECTONLY;
}else
if( n>1 && strncmp(z, "-returntype", n)==0 ){ if( n>1 && strncmp(z, "-returntype", n)==0 ){
const char *azType[] = {"integer", "real", "text", "blob", "any", 0}; const char *azType[] = {"integer", "real", "text", "blob", "any", 0};
assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 ); assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 );
@ -2797,7 +2874,8 @@ static int SQLITE_TCLAPI DbObjCmd(
eType++; eType++;
}else{ }else{
Tcl_AppendResult(interp, "bad option \"", z, Tcl_AppendResult(interp, "bad option \"", z,
"\": must be -argcount, -deterministic or -returntype", (char*)0 "\": must be -argcount, -deterministic, -directonly,"
" or -returntype", (char*)0
); );
return TCL_ERROR; return TCL_ERROR;
} }