1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-27 20:41:58 +03:00

Merge latest trunk changes into this branch.

FossilOrigin-Name: d4f3d52c5a11fc7ad7e8cad76361edbcef13a12f
This commit is contained in:
dan
2016-07-26 18:15:35 +00:00
37 changed files with 1061 additions and 228 deletions

70
configure vendored
View File

@ -903,6 +903,8 @@ with_readline_inc
enable_debug enable_debug
enable_amalgamation enable_amalgamation
enable_load_extension enable_load_extension
enable_memsys5
enable_memsys3
enable_fts3 enable_fts3
enable_fts4 enable_fts4
enable_fts5 enable_fts5
@ -1552,6 +1554,8 @@ Optional Features:
separately separately
--disable-load-extension --disable-load-extension
Disable loading of external extensions Disable loading of external extensions
--enable-memsys5 Enable MEMSYS5
--enable-memsys3 Enable MEMSYS3
--enable-fts3 Enable the FTS3 extension --enable-fts3 Enable the FTS3 extension
--enable-fts4 Enable the FTS4 extension --enable-fts4 Enable the FTS4 extension
--enable-fts5 Enable the FTS5 extension --enable-fts5 Enable the FTS5 extension
@ -3925,13 +3929,13 @@ if ${lt_cv_nm_interface+:} false; then :
else else
lt_cv_nm_interface="BSD nm" lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext echo "int some_variable = 0;" > conftest.$ac_ext
(eval echo "\"\$as_me:3928: $ac_compile\"" >&5) (eval echo "\"\$as_me:3932: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err) (eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:3931: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval echo "\"\$as_me:3935: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5 cat conftest.err >&5
(eval echo "\"\$as_me:3934: output\"" >&5) (eval echo "\"\$as_me:3938: output\"" >&5)
cat conftest.out >&5 cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin" lt_cv_nm_interface="MS dumpbin"
@ -5137,7 +5141,7 @@ ia64-*-hpux*)
;; ;;
*-*-irix6*) *-*-irix6*)
# Find out which ABI we are using. # Find out which ABI we are using.
echo '#line 5140 "configure"' > conftest.$ac_ext echo '#line 5144 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5 (eval $ac_compile) 2>&5
ac_status=$? ac_status=$?
@ -6662,11 +6666,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:6665: $lt_compile\"" >&5) (eval echo "\"\$as_me:6669: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:6669: \$? = $ac_status" >&5 echo "$as_me:6673: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@ -7001,11 +7005,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7004: $lt_compile\"" >&5) (eval echo "\"\$as_me:7008: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:7008: \$? = $ac_status" >&5 echo "$as_me:7012: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@ -7106,11 +7110,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7109: $lt_compile\"" >&5) (eval echo "\"\$as_me:7113: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:7113: \$? = $ac_status" >&5 echo "$as_me:7117: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@ -7161,11 +7165,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7164: $lt_compile\"" >&5) (eval echo "\"\$as_me:7168: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:7168: \$? = $ac_status" >&5 echo "$as_me:7172: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@ -9541,7 +9545,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 9544 "configure" #line 9548 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@ -9637,7 +9641,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF cat > conftest.$ac_ext <<_LT_EOF
#line 9640 "configure" #line 9644 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@ -11339,6 +11343,44 @@ else
OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
fi fi
##########
# Do we want to support memsys3 and/or memsys5
#
# Check whether --enable-memsys5 was given.
if test "${enable_memsys5+set}" = set; then :
enableval=$enable_memsys5; enable_memsys5=yes
else
enable_memsys5=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5
$as_echo_n "checking whether to support MEMSYS5... " >&6; }
if test "${enable_memsys5}" = "yes"; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
# Check whether --enable-memsys3 was given.
if test "${enable_memsys3+set}" = set; then :
enableval=$enable_memsys3; enable_memsys3=yes
else
enable_memsys3=no
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5
$as_echo_n "checking whether to support MEMSYS3... " >&6; }
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
######### #########
# See whether we should enable Full Text Search extensions # See whether we should enable Full Text Search extensions
# Check whether --enable-fts3 was given. # Check whether --enable-fts3 was given.

View File

@ -588,6 +588,30 @@ else
OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
fi fi
##########
# Do we want to support memsys3 and/or memsys5
#
AC_ARG_ENABLE(memsys5,
AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]),
[enable_memsys5=yes],[enable_memsys5=no])
AC_MSG_CHECKING([whether to support MEMSYS5])
if test "${enable_memsys5}" = "yes"; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS5"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
AC_ARG_ENABLE(memsys3,
AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]),
[enable_memsys3=yes],[enable_memsys3=no])
AC_MSG_CHECKING([whether to support MEMSYS3])
if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_MEMSYS3"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
######### #########
# See whether we should enable Full Text Search extensions # See whether we should enable Full Text Search extensions
AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3], AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],

View File

@ -265,7 +265,7 @@ do_test 11.0 {
execsql " execsql "
INSERT INTO t4 VALUES('a b c \x1A'); INSERT INTO t4 VALUES('a b c \x1A');
INSERT INTO t4 VALUES('a b c d\x1A'); INSERT INTO t4 VALUES('a b c d\x1A');
INSERT INTO t4 VALUES('a b c \x1Ad'); INSERT INTO t4 VALUES('a b c \x1Ag');
INSERT INTO t4 VALUES('a b c d'); INSERT INTO t4 VALUES('a b c d');
" "
} {} } {}

View File

@ -237,7 +237,7 @@ static int carrayFilter(
if( idxNum<3 ){ if( idxNum<3 ){
pCur->eType = CARRAY_INT32; pCur->eType = CARRAY_INT32;
}else{ }else{
int i; unsigned char i;
const char *zType = (const char*)sqlite3_value_text(argv[2]); const char *zType = (const char*)sqlite3_value_text(argv[2]);
for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){ for(i=0; i<sizeof(azType)/sizeof(azType[0]); i++){
if( sqlite3_stricmp(zType, azType[i])==0 ) break; if( sqlite3_stricmp(zType, azType[i])==0 ) break;

View File

@ -232,7 +232,7 @@ static char *csv_read_one_field(CsvReader *p){
|| (c==EOF && pc=='"') || (c==EOF && pc=='"')
){ ){
do{ p->n--; }while( p->z[p->n]!='"' ); do{ p->n--; }while( p->z[p->n]!='"' );
p->cTerm = c; p->cTerm = (char)c;
break; break;
} }
if( pc=='"' && c!='\r' ){ if( pc=='"' && c!='\r' ){
@ -242,7 +242,7 @@ static char *csv_read_one_field(CsvReader *p){
if( c==EOF ){ if( c==EOF ){
csv_errmsg(p, "line %d: unterminated %c-quoted field\n", csv_errmsg(p, "line %d: unterminated %c-quoted field\n",
startLine, '"'); startLine, '"');
p->cTerm = c; p->cTerm = (char)c;
break; break;
} }
} }
@ -259,7 +259,7 @@ static char *csv_read_one_field(CsvReader *p){
p->nLine++; p->nLine++;
if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--; if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
} }
p->cTerm = c; p->cTerm = (char)c;
} }
if( p->z ) p->z[p->n] = 0; if( p->z ) p->z[p->n] = 0;
return p->z; return p->z;
@ -338,9 +338,9 @@ static void csv_trim_whitespace(char *z){
/* Dequote the string */ /* Dequote the string */
static void csv_dequote(char *z){ static void csv_dequote(char *z){
int i, j; int j;
char cQuote = z[0]; char cQuote = z[0];
size_t n; size_t i, n;
if( cQuote!='\'' && cQuote!='"' ) return; if( cQuote!='\'' && cQuote!='"' ) return;
n = strlen(z); n = strlen(z);
@ -725,7 +725,8 @@ static int csvtabFilter(
pCur->iRowid = 0; pCur->iRowid = 0;
if( pCur->rdr.in==0 ){ if( pCur->rdr.in==0 ){
assert( pCur->rdr.zIn==pTab->zData ); assert( pCur->rdr.zIn==pTab->zData );
assert( pTab->iStart<=pCur->rdr.nIn ); assert( pTab->iStart>=0 );
assert( (size_t)pTab->iStart<=pCur->rdr.nIn );
pCur->rdr.iIn = pTab->iStart; pCur->rdr.iIn = pTab->iStart;
}else{ }else{
fseek(pCur->rdr.in, pTab->iStart, SEEK_SET); fseek(pCur->rdr.in, pTab->iStart, SEEK_SET);

View File

@ -1211,6 +1211,25 @@ static void jsonTest1Func(
** Scalar SQL function implementations ** Scalar SQL function implementations
****************************************************************************/ ****************************************************************************/
/*
** Implementation of the json_QUOTE(VALUE) function. Return a JSON value
** corresponding to the SQL value input. Mostly this means putting
** double-quotes around strings and returning the unquoted string "null"
** when given a NULL input.
*/
static void jsonQuoteFunc(
sqlite3_context *ctx,
int argc,
sqlite3_value **argv
){
JsonString jx;
jsonInit(&jx, ctx);
jsonAppendValue(&jx, argv[0]);
jsonResult(&jx);
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
}
/* /*
** Implementation of the json_array(VALUE,...) function. Return a JSON ** Implementation of the json_array(VALUE,...) function. Return a JSON
** array that contains all values given in arguments. Or if any argument ** array that contains all values given in arguments. Or if any argument
@ -2124,6 +2143,7 @@ int sqlite3Json1Init(sqlite3 *db){
{ "json_extract", -1, 0, jsonExtractFunc }, { "json_extract", -1, 0, jsonExtractFunc },
{ "json_insert", -1, 0, jsonSetFunc }, { "json_insert", -1, 0, jsonSetFunc },
{ "json_object", -1, 0, jsonObjectFunc }, { "json_object", -1, 0, jsonObjectFunc },
{ "json_quote", 1, 0, jsonQuoteFunc },
{ "json_remove", -1, 0, jsonRemoveFunc }, { "json_remove", -1, 0, jsonRemoveFunc },
{ "json_replace", -1, 0, jsonReplaceFunc }, { "json_replace", -1, 0, jsonReplaceFunc },
{ "json_set", -1, 1, jsonSetFunc }, { "json_set", -1, 1, jsonSetFunc },

View File

@ -74,6 +74,7 @@ struct ScrubState {
u32 szPage; /* Page size */ u32 szPage; /* Page size */
u32 szUsable; /* Usable bytes on each page */ u32 szUsable; /* Usable bytes on each page */
u32 nPage; /* Number of pages */ u32 nPage; /* Number of pages */
u32 iLastPage; /* Page number of last page written so far*/
u8 *page1; /* Content of page 1 */ u8 *page1; /* Content of page 1 */
}; };
@ -130,6 +131,7 @@ static void scrubBackupWrite(ScrubState *p, int pgno, const u8 *pData){
scrubBackupErr(p, "write failed for page %d", pgno); scrubBackupErr(p, "write failed for page %d", pgno);
p->rcErr = SQLITE_IOERR; p->rcErr = SQLITE_IOERR;
} }
if( pgno>p->iLastPage ) p->iLastPage = pgno;
} }
/* Prepare a statement against the "db" database. */ /* Prepare a statement against the "db" database. */
@ -541,6 +543,20 @@ int sqlite3_scrub_backup(
} }
sqlite3_finalize(pStmt); sqlite3_finalize(pStmt);
/* If the last page of the input db file is a free-list leaf, then the
** backup file on disk is still smaller than the size indicated within
** the database header. In this case, write a page of zeroes to the
** last page of the backup database so that SQLite does not mistakenly
** think the db is corrupt. */
if( s.iLastPage<s.nPage ){
u8 *aZero = scrubBackupAllocPage(&s);
if( aZero ){
memset(aZero, 0, s.szPage);
scrubBackupWrite(&s, s.nPage, aZero);
sqlite3_free(aZero);
}
}
scrub_abort: scrub_abort:
/* Close the destination database without closing the transaction. If we /* Close the destination database without closing the transaction. If we
** commit, page zero will be overwritten. */ ** commit, page zero will be overwritten. */

View File

@ -1,5 +1,5 @@
C Fix\swhere.c\shandling\sof\s"IN\s(SELECT\s...)"\sexpressions\swhen\sthe\sSELECT\sreturns\smore\sthan\sone\sresult\scolumn.\sAlso\serror\shandling\sfor\sother\srow\svalue\sconstructor\scases. C Merge\slatest\strunk\schanges\sinto\sthis\sbranch.
D 2016-07-26T18:06:08.100 D 2016-07-26T18:15:35.133
F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db F Makefile.in 6c20d44f72d4564f11652b26291a214c8367e5db
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a F Makefile.msc d66d0395c38571aab3804f8db0fa20707ae4609a
@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 25cf7eb52a88846e4c1978016a9db22763c54f41 x F configure 35ce04a15ca046262bf9baaa2ced9337708cc653 x
F configure.ac 480e1a17d5316b1751c8edcb15b8e6b8ab0a6cc3 F configure.ac b5d3df43161374f8dffd2e5f4b88fbb51685b975
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2 F doc/lemon.html e2118945e5f07ed146b45c9cd2b2dd6eabb8ebf2
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
@ -180,7 +180,7 @@ F ext/fts5/test/fts5rank.test 2bdc0c5f22ccc1f9dbe9f4d0b82a491dce6f8a32
F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b
F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17
F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6
F ext/fts5/test/fts5simple.test cd23d4072ea095d652c9b6db12284cc642e49c98 F ext/fts5/test/fts5simple.test 5da9b15ed534eb0be9f279d8a2bb2e24d30e4e38
F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46
F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e
F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48
@ -204,20 +204,20 @@ F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43
F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7 F ext/icu/icu.c 43df9d8ef2fae7a325100ebd713ab089dc829dd7
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234 F ext/misc/amatch.c 211108e201105e4bb0c076527b8cfd34330fc234
F ext/misc/carray.c 214c9e9d909ceaae3b2f5f917cc2204deca85cc6 F ext/misc/carray.c 40c27641010a4dc67e3690bdb7c9d36ca58b3c2d
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704 F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83 F ext/misc/compress.c 122faa92d25033d6c3f07c39231de074ab3d2e83
F ext/misc/csv.c f51b0566ea15e24cce871037e30a4db99ea6cf77 F ext/misc/csv.c 816a3715356e4210dae2d242057745e937050896
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
F ext/misc/json1.c b9c88d5c3b6ecd8c731ffdd7f5b3d902857f8c96 F ext/misc/json1.c d51a764ba43a49e191bc3536238bfab3def258ca
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63
F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4
F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a
F ext/misc/scrub.c ea0903701e3ac02b4466ce9cffd0325c7ddbfcf0 F ext/misc/scrub.c 1c5bfb8b0cd18b602fcb55755e84abf0023ac2fb
F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35 F ext/misc/series.c e11e534ada797d5b816d7e7a93c022306563ca35
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be F ext/misc/spellfix.c bf1b922c2750698e9a3d4c50cce6974adb7e93be
@ -327,7 +327,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240
F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556 F src/backup.c 6df65fdd569c901a418887a1a76f82ec35044556
F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63 F src/bitvec.c 3ee4c8b2c94ed3a7377256e18199e6ff5cf33f63
F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73
F src/btree.c dc4e5f3e95fd57b610422e36e0913662ecd6814c F src/btree.c 6a42efa461cf3a0c33e8755e9d236371ac80d1b3
F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da F src/btree.h 075c45707c0f8f8af118f739f36df8098a08b7da
F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5
F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6 F src/build.c d1fdfd7ab8f5447e494ef15825973bf0719527c6
@ -347,8 +347,8 @@ F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b F src/insert.c 8f4e9fcbd8e95e85f15647ba8b413b18d556ec2b
F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e F src/legacy.c 75d3023be8f0d2b99d60f905090341a03358c58e
F src/loadext.c 4237fd37ca589f1d90b3ea925dd9df20da8e0c84 F src/loadext.c 5dd8b5a67d32a98bb75657c2a9e48b2cedbf13a4
F src/main.c 405d13e3a4f7c5add9fb27702ae70ed0a6e32cca F src/main.c 16c1b2114eae8804caf3a8de8cb47bf2c6d83ad3
F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec F src/malloc.c 1443d1ad95d67c21d77af7ae3f44678252f0efec
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b
@ -372,7 +372,7 @@ F src/os_win.c 520f23475f1de530c435d30b67b7b15fe90874b0
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60 F src/pager.c c368634b888b1c8740aea83b36bfd266f2443e60
F src/pager.h 031a87445e5e0afc85312d1c380e123ad6c7aeaf F src/pager.h 031a87445e5e0afc85312d1c380e123ad6c7aeaf
F src/parse.y fa040d742fe4922b219143fe2e04f74061daabcb F src/parse.y a7402dff6fe8238795f15ca194e1f1b734d169f4
F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df F src/pcache.c 5583c8ade4b05075a60ba953ef471d1c1a9c05df
F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490 F src/pcache.h 2cedcd8407eb23017d92790b112186886e179490
F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d F src/pcache1.c 7f51d2b541aab57596adf62db2c4bb025d34f04d
@ -384,16 +384,16 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c 5c4d301a855d0245ddcc27365ddcbddd2f244665 F src/resolve.c 5c4d301a855d0245ddcc27365ddcbddd2f244665
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
F src/select.c 0115f5d222f5cf9b5511ec4072088417354d738a F src/select.c 0115f5d222f5cf9b5511ec4072088417354d738a
F src/shell.c a8a9e392a6a2777fabf5feb536931cb190f235e5 F src/shell.c 9351fc6de11e1d908648c0a92d85627138e3dee5
F src/sqlite.h.in b9ba728c1083b7a8ab5f6a628b25cd2a00325fbf F src/sqlite.h.in c6e68a4a47610631822a4f8f83a44c9f75339331
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 2a170163d121095c6ab1ef05ed0413722f391d01 F src/sqlite3ext.h 46f300b6e300e0fa916d7d58c44b53415b8471a9
F src/sqliteInt.h c4877fb0519c13558d18d08775bc8e79476cb56c F src/sqliteInt.h a78e53083262e9a10fd1f09a8777755253c00b44
F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247 F src/sqliteLimit.h c0373387c287c8d0932510b5547ecde31b5da247
F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab F src/status.c 5b18f9526900f61189ab0b83f1ef41d9f871a2ab
F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9 F src/table.c 5226df15ab9179b9ed558d89575ea0ce37b03fc9
F src/tclsqlite.c 25fbbbb97f76dbfd113153fb63f52d7ecfac5dd0 F src/tclsqlite.c 5c213bf5fee084390f632df2328cf0821d483799
F src/test1.c 640f862c490c8eee09a9d02d0d128c6a8a75336d F src/test1.c 186e3b53c402b7a73bcb4ade2b77709675c39fe3
F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b
F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59 F src/test3.c c75c8af0eadb335236c9e61b51044c58a8f7dd59
F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e
@ -448,16 +448,16 @@ F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280
F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd F src/update.c 4f05ea8cddfa367d045e03589756c02199e8f9bd
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d F src/util.c 810ec3f22e2d1b62e66c30fe3621ebdedd23584d
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52 F src/vacuum.c 9dd2f5d276bc6094d8f1d85ecd41b30c1a002a43
F src/vdbe.c 680c118a20b4b496644001e7ff4819c3e3ff8d85 F src/vdbe.c 44d75e3585d93bf56c72de5e2ec4c5a16cd40370
F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10 F src/vdbe.h 67bc551f7faf04c33493892e4b378aada823ed10
F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d F src/vdbeInt.h c59381049af5c7751a83456c39b80d1a6fde1f9d
F src/vdbeapi.c 02bcbc2ca5d2004b029088b05b468b394881e103 F src/vdbeapi.c c3f6715a99995c11748ecad91d25e93fd9fc390b
F src/vdbeaux.c c90275b0e55a2b32c03dc09314194fe46f2429d8 F src/vdbeaux.c a32d79aeaa88dc2b97c261172d952d395254a055
F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b F src/vdbeblob.c 83d2d266383157b02e2b809350bb197e89d7895b
F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1 F src/vdbemem.c 1ecaa5ee0caff07255f25d04e8dc88befb6f88d1
F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c F src/vdbesort.c 91fda3909326860382b0ca8aa251e609c6a9d62c
F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e F src/vtab.c 948d2d4984219eee37a7bf427d6667e21e6eb92e
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a F src/wal.c 02eeecc265f6ffd0597378f5d8ae9070b62a406a
@ -465,7 +465,7 @@ F src/wal.h 6dd221ed384afdc204bc61e25c23ef7fd5a511f2
F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354
F src/where.c e7054b2c1fe31fef5136e5735d7958f5c2c7707d F src/where.c e7054b2c1fe31fef5136e5735d7958f5c2c7707d
F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613 F src/whereInt.h 14dd243e13b81cbb0a66063d38b70f93a7d6e613
F src/wherecode.c 03fbaa63909d7e4b8af986595b811ae591032240 F src/wherecode.c 3aff7683566af3428f865904aafa7efb1fbd8701
F src/whereexpr.c b896f8ff6a53cbd3daaee84ec33e39098762bb46 F src/whereexpr.c b896f8ff6a53cbd3daaee84ec33e39098762bb46
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd
@ -616,12 +616,12 @@ F test/crashM.test d95f59046fa749b0d0822edf18a717788c8f318d
F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
F test/csv01.test 0929a9ce47021519512be92861f29e32d2538e5f F test/csv01.test e0ba3caaa57e4c667a0b45977689fb8082f14348
F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c F test/ctime.test 0b995accd44a52914bd4744d5c1b6e1a56c7897c
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255 F test/cursorhint2.test 2b45341d32d1aae9991a00ef31ebca339b274255
F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65 F test/date.test 984ac1e3e5e031386866f034006148d3972b4a65
F test/dbstatus.test 85833ba5bc95262749d080dcd40af87072ea8d5b F test/dbstatus.test 73149851b3aff14fc6db478e58f9083a66422cf5
F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab F test/dbstatus2.test e93ab03bfae6d62d4d935f20de928c19ca0ed0ab
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f
@ -877,7 +877,7 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307
F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa
F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/json101.test ef42283f0b60d8bacbc2243448e7c84988578e52 F test/json101.test 865776ed8580703e1684fe4b8ee2e473333bb121
F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a
F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
@ -929,7 +929,7 @@ F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test 6d268d0ae90f8d61a2356a1838665654d83de518 F test/memsubsys1.test 6d268d0ae90f8d61a2356a1838665654d83de518
F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08 F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08
F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd F test/minmax.test 6751e87b409fe11b02e70a306d846fa544e25a41
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f F test/minmax4.test 936941484ebdceb8adec7c86b6cd9b6e5e897c1f
@ -1009,7 +1009,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8
F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144 F test/regexp2.test aa7ffcc21350007a78361b82bcf3b74d12227144
F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 F test/reindex.test 44edd3966b474468b823d481eafef0c305022254
F test/releasetest.tcl 7d80014d0245b3f9d02d393d420bf03ca155aec0 F test/releasetest.tcl 3a66c7b8fbe55bcd97c907217c3d812d1d3c6b93
F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb
F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea
F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5
@ -1067,7 +1067,7 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506 F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test c90b0415cea6eeefb86b4ab1651b06247922ca52 F test/shell1.test 77896b65f1cde4ee79e38b2c0ed8578a8f4000e5
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd F test/shell3.test da513d522ef6f01cee8475dcf8332bff8982b3dd
F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9 F test/shell4.test 69995ee1cc278eb149aa8746ce1f935f4eaf98b9
@ -1123,7 +1123,7 @@ F test/tabfunc01.test 50a9fb379f9747fd0d40ea6d8fa3a101361bb537
F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f
F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
F test/tclsqlite.test cf0d0a3fd03d64892cec2d48aae9fb2f148680a5 F test/tclsqlite.test 1d73b9203b1ca8798d7d7310742b8d3febc0d56e
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6 F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
F test/tempdb2.test 4fc92055f2a3f7626c0f2eabbb637dc021b311d5 F test/tempdb2.test 4fc92055f2a3f7626c0f2eabbb637dc021b311d5
F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
@ -1131,7 +1131,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e F test/temptable2.test cd396beb41117a5302fff61767c35fa4270a0d5e
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
F test/tester.tcl e1379282de5810a047c75d84eb6c914e00743b7e F test/tester.tcl 542e38e307a6c1c362122d186f580ec3e58a288c
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
@ -1288,6 +1288,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4 F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836 F test/trace.test 6f676313e3ebd2a50585036d2f212a3319dd5836
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983 F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
F test/trace3.test 01e4111d582c7b20ab1c63156169157d256bc3d5
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
@ -1326,7 +1327,7 @@ F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d
F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b F test/vacuum2.test aa048abee196c16c9ba308465494009057b79f9b
F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d F test/vacuum3.test 77ecdd54592b45a0bcb133339f99f1ae0ae94d0d
F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9 F test/vacuum4.test d3f8ecff345f166911568f397d2432c16d2867d9
F test/vacuummem.test 09c8b72a12405649ed84564367dad729bff88760 F test/vacuummem.test e53a3fdca4612a99c515e1afe7934728a2383764
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661
F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab F test/view.test 765802c7a66d37fabd5ac8e2f2dbe572b43eb9ab
@ -1368,7 +1369,7 @@ F test/walcksum.test bb234a1bb42248b3515d992b719708015c384278
F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a
F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36
F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af
F test/walcrash4.test 3374d6a0813bfe9d841a973958e0552b545a6423 F test/walcrash4.test e7b6e7639a950a0cca8e210e248c8dad4d63bf20
F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
@ -1477,7 +1478,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
F tool/sqldiff.c 4478f0d30230de6adde90bdb0bfe60f68c5ab782 F tool/sqldiff.c 4478f0d30230de6adde90bdb0bfe60f68c5ab782
F tool/srcck1.c 4c39bdfa9a92edd20233ee720df84dbeb2417602 F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148 F tool/symbols.sh c5a617b8c61a0926747a56c65f5671ef8ac0e148
@ -1509,7 +1510,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P e2fd6f49b1b145bec09c581cc982b89429643ae9 P 061b8006034f06a0311b4304c8b14d2c8b0153df 483994a54dee3c7a3801e0e9d3c96fa9dbd8d2fd
R a369e1eed01f702cd78474a2d1d557f1 R 675e1e72a3d3f117d790dda9dd43e7d1
U dan U dan
Z 9143269c80fa998d2598183a7a999846 Z b0c1b915de5ec6a4159f97e64d5655ae

View File

@ -1 +1 @@
061b8006034f06a0311b4304c8b14d2c8b0153df d4f3d52c5a11fc7ad7e8cad76361edbcef13a12f

View File

@ -7340,7 +7340,7 @@ static int balance_nonroot(
assert( r<nMaxCells ); assert( r<nMaxCells );
(void)cachedCellSize(&b, r); (void)cachedCellSize(&b, r);
if( szRight!=0 if( szRight!=0
&& (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+2)) ){ && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+(i==k-1?0:2)))){
break; break;
} }
szRight += b.szCell[d] + 2; szRight += b.szCell[d] + 2;

View File

@ -91,7 +91,7 @@
# define sqlite3_enable_shared_cache 0 # define sqlite3_enable_shared_cache 0
#endif #endif
#ifdef SQLITE_OMIT_TRACE #if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED)
# define sqlite3_profile 0 # define sqlite3_profile 0
# define sqlite3_trace 0 # define sqlite3_trace 0
#endif #endif

View File

@ -1033,6 +1033,9 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
return SQLITE_MISUSE_BKPT; return SQLITE_MISUSE_BKPT;
} }
sqlite3_mutex_enter(db->mutex); sqlite3_mutex_enter(db->mutex);
if( db->mTrace & SQLITE_TRACE_CLOSE ){
db->xTrace(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0);
}
/* Force xDisconnect calls on all virtual tables */ /* Force xDisconnect calls on all virtual tables */
disconnectAllVtab(db); disconnectAllVtab(db);
@ -1801,7 +1804,8 @@ int sqlite3_overload_function(
** trace is a pointer to a function that is invoked at the start of each ** trace is a pointer to a function that is invoked at the start of each
** SQL statement. ** SQL statement.
*/ */
void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){ #ifndef SQLITE_OMIT_DEPRECATED
void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){
void *pOld; void *pOld;
#ifdef SQLITE_ENABLE_API_ARMOR #ifdef SQLITE_ENABLE_API_ARMOR
@ -1812,11 +1816,36 @@ void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
#endif #endif
sqlite3_mutex_enter(db->mutex); sqlite3_mutex_enter(db->mutex);
pOld = db->pTraceArg; pOld = db->pTraceArg;
db->xTrace = xTrace; db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0;
db->xTrace = (int(*)(u32,void*,void*,void*))xTrace;
db->pTraceArg = pArg; db->pTraceArg = pArg;
sqlite3_mutex_leave(db->mutex); sqlite3_mutex_leave(db->mutex);
return pOld; return pOld;
} }
#endif /* SQLITE_OMIT_DEPRECATED */
/* Register a trace callback using the version-2 interface.
*/
int sqlite3_trace_v2(
sqlite3 *db, /* Trace this connection */
unsigned mTrace, /* Mask of events to be traced */
int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */
void *pArg /* Context */
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
#endif
sqlite3_mutex_enter(db->mutex);
db->mTrace = mTrace;
db->xTrace = xTrace;
db->pTraceArg = pArg;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_DEPRECATED
/* /*
** Register a profile function. The pArg from the previously registered ** Register a profile function. The pArg from the previously registered
** profile function is returned. ** profile function is returned.
@ -1845,6 +1874,7 @@ void *sqlite3_profile(
sqlite3_mutex_leave(db->mutex); sqlite3_mutex_leave(db->mutex);
return pOld; return pOld;
} }
#endif /* SQLITE_OMIT_DEPRECATED */
#endif /* SQLITE_OMIT_TRACE */ #endif /* SQLITE_OMIT_TRACE */
/* /*

View File

@ -1203,13 +1203,14 @@ nexprlist(A) ::= nexprlist(A) COMMA expr(Y).
nexprlist(A) ::= expr(Y). nexprlist(A) ::= expr(Y).
{A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/} {A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/}
%ifndef SQLITE_OMIT_SUBQUERY
/* A paren_exprlist is an optional expression list contained inside /* A paren_exprlist is an optional expression list contained inside
** of parenthesis */ ** of parenthesis */
%type paren_exprlist {ExprList*} %type paren_exprlist {ExprList*}
%destructor paren_exprlist {sqlite3ExprListDelete(pParse->db, $$);} %destructor paren_exprlist {sqlite3ExprListDelete(pParse->db, $$);}
paren_exprlist(A) ::= . {A = 0;} paren_exprlist(A) ::= . {A = 0;}
paren_exprlist(A) ::= LP exprlist(X) RP. {A = X;} paren_exprlist(A) ::= LP exprlist(X) RP. {A = X;}
%endif SQLITE_OMIT_SUBQUERY
///////////////////////////// The CREATE INDEX command /////////////////////// ///////////////////////////// The CREATE INDEX command ///////////////////////

View File

@ -2543,13 +2543,20 @@ static FILE *output_file_open(const char *zFile){
/* /*
** A routine for handling output from sqlite3_trace(). ** A routine for handling output from sqlite3_trace().
*/ */
static void sql_trace_callback(void *pArg, const char *z){ static int sql_trace_callback(
unsigned mType,
void *pArg,
void *pP,
void *pX
){
FILE *f = (FILE*)pArg; FILE *f = (FILE*)pArg;
if( f ){ if( f ){
const char *z = (const char*)pX;
int i = (int)strlen(z); int i = (int)strlen(z);
while( i>0 && z[i-1]==';' ){ i--; } while( i>0 && z[i-1]==';' ){ i--; }
utf8_printf(f, "%.*s;\n", i, z); utf8_printf(f, "%.*s;\n", i, z);
} }
return 0;
} }
/* /*
@ -4655,9 +4662,9 @@ static int do_meta_command(char *zLine, ShellState *p){
p->traceOut = output_file_open(azArg[1]); p->traceOut = output_file_open(azArg[1]);
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
if( p->traceOut==0 ){ if( p->traceOut==0 ){
sqlite3_trace(p->db, 0, 0); sqlite3_trace_v2(p->db, 0, 0, 0);
}else{ }else{
sqlite3_trace(p->db, sql_trace_callback, p->traceOut); sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
} }
#endif #endif
}else }else
@ -5317,6 +5324,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
szHeap = integerValue(zSize); szHeap = integerValue(zSize);
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
#else
(void)cmdline_option_value(argc, argv, ++i);
#endif #endif
}else if( strcmp(z,"-scratch")==0 ){ }else if( strcmp(z,"-scratch")==0 ){
int n, sz; int n, sz;

View File

@ -2755,6 +2755,9 @@ int sqlite3_set_authorizer(
** CAPI3REF: Tracing And Profiling Functions ** CAPI3REF: Tracing And Profiling Functions
** METHOD: sqlite3 ** METHOD: sqlite3
** **
** These routines are deprecated. Use the [sqlite3_trace_v2()] interface
** instead of the routines described here.
**
** These routines register callback functions that can be used for ** These routines register callback functions that can be used for
** tracing and profiling the execution of SQL statements. ** tracing and profiling the execution of SQL statements.
** **
@ -2780,10 +2783,104 @@ int sqlite3_set_authorizer(
** sqlite3_profile() function is considered experimental and is ** sqlite3_profile() function is considered experimental and is
** subject to change in future versions of SQLite. ** subject to change in future versions of SQLite.
*/ */
void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*,
SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, void(*xTrace)(void*,const char*), void*);
SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*,
void(*xProfile)(void*,const char*,sqlite3_uint64), void*); void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
/*
** CAPI3REF: SQL Trace Event Codes
** KEYWORDS: SQLITE_TRACE
**
** These constants identify classes of events that can be monitored
** using the [sqlite3_trace_v2()] tracing logic. The third argument
** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
** the following constants. ^The first argument to the trace callback
** is one of the following constants.
**
** New tracing constants may be added in future releases.
**
** ^A trace callback has four arguments: xCallback(T,C,P,X).
** ^The T argument is one of the integer type codes above.
** ^The C argument is a copy of the context pointer passed in as the
** fourth argument to [sqlite3_trace_v2()].
** The P and X arguments are pointers whose meanings depend on T.
**
** <dl>
** [[SQLITE_TRACE_STMT]] <dt>SQLITE_TRACE_STMT</dt>
** <dd>^An SQLITE_TRACE_STMT callback is invoked when a prepared statement
** first begins running and possibly at other times during the
** execution of the prepared statement, such as at the start of each
** trigger subprogram. ^The P argument is a pointer to the
** [prepared statement]. ^The X argument is a pointer to a string which
** is the unexpanded SQL text of the prepared statement or an SQL comment
** that indicates the invocation of a trigger. ^The callback can compute
** the same text that would have been returned by the legacy [sqlite3_trace()]
** interface by using the X argument when X begins with "--" and invoking
** [sqlite3_expanded_sql(P)] otherwise.
**
** [[SQLITE_TRACE_PROFILE]] <dt>SQLITE_TRACE_PROFILE</dt>
** <dd>^An SQLITE_TRACE_PROFILE callback provides approximately the same
** information as is provided by the [sqlite3_profile()] callback.
** ^The P argument is a pointer to the [prepared statement] and the
** X argument points to a 64-bit integer which is the estimated of
** the number of nanosecond that the prepared statement took to run.
** ^The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.
**
** [[SQLITE_TRACE_ROW]] <dt>SQLITE_TRACE_ROW</dt>
** <dd>^An SQLITE_TRACE_ROW callback is invoked whenever a prepared
** statement generates a single row of result.
** ^The P argument is a pointer to the [prepared statement] and the
** X argument is unused.
**
** [[SQLITE_TRACE_CLOSE]] <dt>SQLITE_TRACE_CLOSE</dt>
** <dd>^An SQLITE_TRACE_CLOSE callback is invoked when a database
** connection closes.
** ^The P argument is a pointer to the [database connection] object
** and the X argument is unused.
** </dl>
*/
#define SQLITE_TRACE_STMT 0x01
#define SQLITE_TRACE_PROFILE 0x02
#define SQLITE_TRACE_ROW 0x04
#define SQLITE_TRACE_CLOSE 0x08
/*
** CAPI3REF: SQL Trace Hook
** METHOD: sqlite3
**
** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback
** function X against [database connection] D, using property mask M
** and context pointer P. ^If the X callback is
** NULL or if the M mask is zero, then tracing is disabled. The
** M argument should be the bitwise OR-ed combination of
** zero or more [SQLITE_TRACE] constants.
**
** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides
** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().
**
** ^The X callback is invoked whenever any of the events identified by
** mask M occur. ^The integer return value from the callback is currently
** ignored, though this may change in future releases. Callback
** implementations should return zero to ensure future compatibility.
**
** ^A trace callback is invoked with four arguments: callback(T,C,P,X).
** ^The T argument is one of the [SQLITE_TRACE]
** constants to indicate why the callback was invoked.
** ^The C argument is a copy of the context pointer.
** The P and X arguments are pointers whose meanings depend on T.
**
** The sqlite3_trace_v2() interface is intended to replace the legacy
** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which
** are deprecated.
*/
int sqlite3_trace_v2(
sqlite3*,
unsigned uMask,
int(*xCallback)(unsigned,void*,void*,void*),
void *pCtx
);
/* /*
** CAPI3REF: Query Progress Callbacks ** CAPI3REF: Query Progress Callbacks
** METHOD: sqlite3 ** METHOD: sqlite3
@ -3402,11 +3499,35 @@ int sqlite3_prepare16_v2(
** CAPI3REF: Retrieving Statement SQL ** CAPI3REF: Retrieving Statement SQL
** METHOD: sqlite3_stmt ** METHOD: sqlite3_stmt
** **
** ^This interface can be used to retrieve a saved copy of the original ** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8
** SQL text used to create a [prepared statement] if that statement was ** SQL text used to create [prepared statement] P if P was
** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()]. ** created by either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8
** string containing the SQL text of prepared statement P with
** [bound parameters] expanded.
**
** ^(For example, if a prepared statement is created using the SQL
** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345
** and parameter :xyz is unbound, then sqlite3_sql() will return
** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql()
** will return "SELECT 2345,NULL".)^
**
** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory
** is available to hold the result, or if the result would exceed the
** the maximum string length determined by the [SQLITE_LIMIT_LENGTH].
**
** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of
** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time
** option causes sqlite3_expanded_sql() to always return NULL.
**
** ^The string returned by sqlite3_sql(P) is managed by SQLite and is
** automatically freed when the prepared statement is finalized.
** ^The string returned by sqlite3_expanded_sql(P), on the other hand,
** is obtained from [sqlite3_malloc()] and must be free by the application
** by passing it to [sqlite3_free()].
*/ */
const char *sqlite3_sql(sqlite3_stmt *pStmt); const char *sqlite3_sql(sqlite3_stmt *pStmt);
char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
/* /*
** CAPI3REF: Determine If An SQL Statement Writes The Database ** CAPI3REF: Determine If An SQL Statement Writes The Database

View File

@ -281,6 +281,9 @@ struct sqlite3_api_routines {
int (*db_cacheflush)(sqlite3*); int (*db_cacheflush)(sqlite3*);
/* Version 3.12.0 and later */ /* Version 3.12.0 and later */
int (*system_errno)(sqlite3*); int (*system_errno)(sqlite3*);
/* Version 3.14.0 and later */
int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*);
char *(*expanded_sql)(sqlite3_stmt*);
}; };
/* /*
@ -526,6 +529,9 @@ struct sqlite3_api_routines {
#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush
/* Version 3.12.0 and later */ /* Version 3.12.0 and later */
#define sqlite3_system_errno sqlite3_api->system_errno #define sqlite3_system_errno sqlite3_api->system_errno
/* Version 3.14.0 and later */
#define sqlite3_trace_v2 sqlite3_api->trace_v2
#define sqlite3_expanded_sql sqlite3_api->expanded_sql
#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

@ -1241,6 +1241,15 @@ void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
const char*); const char*);
#endif #endif
#ifndef SQLITE_OMIT_DEPRECATED
/* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing
** in the style of sqlite3_trace()
*/
#define SQLITE_TRACE_LEGACY 0x80
#else
#define SQLITE_TRACE_LEGACY 0
#endif /* SQLITE_OMIT_DEPRECATED */
/* /*
** Each database connection is an instance of the following structure. ** Each database connection is an instance of the following structure.
@ -1270,6 +1279,7 @@ struct sqlite3 {
u8 suppressErr; /* Do not issue error messages if true */ u8 suppressErr; /* Do not issue error messages if true */
u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */
u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */
u8 mTrace; /* zero or more SQLITE_TRACE flags */
int nextPagesize; /* Pagesize after VACUUM if >0 */ int nextPagesize; /* Pagesize after VACUUM if >0 */
u32 magic; /* Magic number for detect library misuse */ u32 magic; /* Magic number for detect library misuse */
int nChange; /* Value returned by sqlite3_changes() */ int nChange; /* Value returned by sqlite3_changes() */
@ -1290,7 +1300,7 @@ struct sqlite3 {
int nVDestroy; /* Number of active OP_VDestroy operations */ int nVDestroy; /* Number of active OP_VDestroy operations */
int nExtension; /* Number of loaded extensions */ int nExtension; /* Number of loaded extensions */
void **aExtension; /* Array of shared library handles */ void **aExtension; /* Array of shared library handles */
void (*xTrace)(void*,const char*); /* Trace function */ int (*xTrace)(u32,void*,void*,void*); /* Trace function */
void *pTraceArg; /* Argument to the trace function */ void *pTraceArg; /* Argument to the trace function */
void (*xProfile)(void*,const char*,u64); /* Profiling function */ void (*xProfile)(void*,const char*,u64); /* Profiling function */
void *pProfileArg; /* Argument to profile function */ void *pProfileArg; /* Argument to profile function */
@ -3432,11 +3442,15 @@ int sqlite3HeapNearlyFull(void);
# define sqlite3StackFree(D,P) sqlite3DbFree(D,P) # define sqlite3StackFree(D,P) sqlite3DbFree(D,P)
#endif #endif
#ifdef SQLITE_ENABLE_MEMSYS3 /* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they
const sqlite3_mem_methods *sqlite3MemGetMemsys3(void); ** are, disable MEMSYS3
#endif */
#ifdef SQLITE_ENABLE_MEMSYS5 #ifdef SQLITE_ENABLE_MEMSYS5
const sqlite3_mem_methods *sqlite3MemGetMemsys5(void); const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
#undef SQLITE_ENABLE_MEMSYS3
#endif
#ifdef SQLITE_ENABLE_MEMSYS3
const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
#endif #endif

View File

@ -133,6 +133,7 @@ struct SqliteDb {
char *zBusy; /* The busy callback routine */ char *zBusy; /* The busy callback routine */
char *zCommit; /* The commit hook callback routine */ char *zCommit; /* The commit hook callback routine */
char *zTrace; /* The trace callback routine */ char *zTrace; /* The trace callback routine */
char *zTraceV2; /* The trace_v2 callback routine */
char *zProfile; /* The profile callback routine */ char *zProfile; /* The profile callback routine */
char *zProgress; /* The progress callback routine */ char *zProgress; /* The progress callback routine */
char *zAuth; /* The authorization callback routine */ char *zAuth; /* The authorization callback routine */
@ -192,7 +193,7 @@ static void closeIncrblobChannels(SqliteDb *pDb){
for(p=pDb->pIncrblob; p; p=pNext){ for(p=pDb->pIncrblob; p; p=pNext){
pNext = p->pNext; pNext = p->pNext;
/* Note: Calling unregister here call Tcl_Close on the incrblob channel, /* Note: Calling unregister here call Tcl_Close on the incrblob channel,
** which deletes the IncrblobChannel structure at *p. So do not ** which deletes the IncrblobChannel structure at *p. So do not
** call Tcl_Free() here. ** call Tcl_Free() here.
*/ */
@ -233,8 +234,8 @@ static int incrblobClose(ClientData instanceData, Tcl_Interp *interp){
** Read data from an incremental blob channel. ** Read data from an incremental blob channel.
*/ */
static int incrblobInput( static int incrblobInput(
ClientData instanceData, ClientData instanceData,
char *buf, char *buf,
int bufSize, int bufSize,
int *errorCodePtr int *errorCodePtr
){ ){
@ -265,8 +266,8 @@ static int incrblobInput(
** Write data to an incremental blob channel. ** Write data to an incremental blob channel.
*/ */
static int incrblobOutput( static int incrblobOutput(
ClientData instanceData, ClientData instanceData,
CONST char *buf, CONST char *buf,
int toWrite, int toWrite,
int *errorCodePtr int *errorCodePtr
){ ){
@ -298,7 +299,7 @@ static int incrblobOutput(
** Seek an incremental blob channel. ** Seek an incremental blob channel.
*/ */
static int incrblobSeek( static int incrblobSeek(
ClientData instanceData, ClientData instanceData,
long offset, long offset,
int seekMode, int seekMode,
int *errorCodePtr int *errorCodePtr
@ -323,8 +324,8 @@ static int incrblobSeek(
} }
static void incrblobWatch(ClientData instanceData, int mode){ static void incrblobWatch(ClientData instanceData, int mode){
/* NO-OP */ /* NO-OP */
} }
static int incrblobHandle(ClientData instanceData, int dir, ClientData *hPtr){ static int incrblobHandle(ClientData instanceData, int dir, ClientData *hPtr){
return TCL_ERROR; return TCL_ERROR;
@ -352,11 +353,11 @@ static Tcl_ChannelType IncrblobChannelType = {
** Create a new incrblob channel. ** Create a new incrblob channel.
*/ */
static int createIncrblobChannel( static int createIncrblobChannel(
Tcl_Interp *interp, Tcl_Interp *interp,
SqliteDb *pDb, SqliteDb *pDb,
const char *zDb, const char *zDb,
const char *zTable, const char *zTable,
const char *zColumn, const char *zColumn,
sqlite_int64 iRow, sqlite_int64 iRow,
int isReadonly int isReadonly
){ ){
@ -438,7 +439,7 @@ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 ); pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 );
pNew->zName = (char*)&pNew[1]; pNew->zName = (char*)&pNew[1];
memcpy(pNew->zName, zName, nName+1); memcpy(pNew->zName, zName, nName+1);
for(p=pDb->pFunc; p; p=p->pNext){ for(p=pDb->pFunc; p; p=p->pNext){
if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){ if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){
Tcl_Free((char*)pNew); Tcl_Free((char*)pNew);
return p; return p;
@ -508,6 +509,9 @@ static void DbDeleteCmd(void *db){
if( pDb->zTrace ){ if( pDb->zTrace ){
Tcl_Free(pDb->zTrace); Tcl_Free(pDb->zTrace);
} }
if( pDb->zTraceV2 ){
Tcl_Free(pDb->zTraceV2);
}
if( pDb->zProfile ){ if( pDb->zProfile ){
Tcl_Free(pDb->zProfile); Tcl_Free(pDb->zProfile);
} }
@ -587,6 +591,82 @@ static void DbTraceHandler(void *cd, const char *zSql){
} }
#endif #endif
#ifndef SQLITE_OMIT_TRACE
/*
** This routine is called by the SQLite trace_v2 handler whenever a new
** supported event is generated. Unsupported event types are ignored.
** The TCL script in pDb->zTraceV2 is executed, with the arguments for
** the event appended to it (as list elements).
*/
static int DbTraceV2Handler(
unsigned type, /* One of the SQLITE_TRACE_* event types. */
void *cd, /* The original context data pointer. */
void *pd, /* Primary event data, depends on event type. */
void *xd /* Extra event data, depends on event type. */
){
SqliteDb *pDb = (SqliteDb*)cd;
Tcl_Obj *pCmd;
switch( type ){
case SQLITE_TRACE_STMT: {
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
char *zSql = (char *)xd;
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewStringObj(zSql, -1));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
Tcl_DecrRefCount(pCmd);
Tcl_ResetResult(pDb->interp);
break;
}
case SQLITE_TRACE_PROFILE: {
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
sqlite3_int64 ns = (sqlite3_int64)xd;
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)ns));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
Tcl_DecrRefCount(pCmd);
Tcl_ResetResult(pDb->interp);
break;
}
case SQLITE_TRACE_ROW: {
sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
Tcl_DecrRefCount(pCmd);
Tcl_ResetResult(pDb->interp);
break;
}
case SQLITE_TRACE_CLOSE: {
sqlite3 *db = (sqlite3 *)pd;
pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
Tcl_IncrRefCount(pCmd);
Tcl_ListObjAppendElement(pDb->interp, pCmd,
Tcl_NewWideIntObj((Tcl_WideInt)db));
Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
Tcl_DecrRefCount(pCmd);
Tcl_ResetResult(pDb->interp);
break;
}
}
return SQLITE_OK;
}
#endif
#ifndef SQLITE_OMIT_TRACE #ifndef SQLITE_OMIT_TRACE
/* /*
** This routine is called by the SQLite profile handler after a statement ** This routine is called by the SQLite profile handler after a statement
@ -637,9 +717,9 @@ static void DbRollbackHandler(void *clientData){
** This procedure handles wal_hook callbacks. ** This procedure handles wal_hook callbacks.
*/ */
static int DbWalHandler( static int DbWalHandler(
void *clientData, void *clientData,
sqlite3 *db, sqlite3 *db,
const char *zDb, const char *zDb,
int nEntry int nEntry
){ ){
int ret = SQLITE_OK; int ret = SQLITE_OK;
@ -653,7 +733,7 @@ static int DbWalHandler(
Tcl_IncrRefCount(p); Tcl_IncrRefCount(p);
Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1)); Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1));
Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry)); Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry));
if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0) if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0)
|| TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret) || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret)
){ ){
Tcl_BackgroundError(interp); Tcl_BackgroundError(interp);
@ -695,11 +775,11 @@ static void DbUnlockNotify(void **apArg, int nArg){
** Pre-update hook callback. ** Pre-update hook callback.
*/ */
static void DbPreUpdateHandler( static void DbPreUpdateHandler(
void *p, void *p,
sqlite3 *db, sqlite3 *db,
int op, int op,
const char *zDb, const char *zDb,
const char *zTbl, const char *zTbl,
sqlite_int64 iKey1, sqlite_int64 iKey1,
sqlite_int64 iKey2 sqlite_int64 iKey2
){ ){
@ -727,10 +807,10 @@ static void DbPreUpdateHandler(
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
static void DbUpdateHandler( static void DbUpdateHandler(
void *p, void *p,
int op, int op,
const char *zDb, const char *zDb,
const char *zTbl, const char *zTbl,
sqlite_int64 rowid sqlite_int64 rowid
){ ){
SqliteDb *pDb = (SqliteDb *)p; SqliteDb *pDb = (SqliteDb *)p;
@ -815,7 +895,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
** script object, lappend the arguments, then evaluate the copy. ** script object, lappend the arguments, then evaluate the copy.
** **
** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated. ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated.
** The new Tcl_Obj contains pointers to the original list elements. ** The new Tcl_Obj contains pointers to the original list elements.
** That way, when Tcl_EvalObjv() is run and shimmers the first element ** That way, when Tcl_EvalObjv() is run and shimmers the first element
** of the list to tclCmdNameType, that alternate representation will ** of the list to tclCmdNameType, that alternate representation will
** be preserved and reused on the next invocation. ** be preserved and reused on the next invocation.
@ -823,15 +903,15 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
Tcl_Obj **aArg; Tcl_Obj **aArg;
int nArg; int nArg;
if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
return; return;
} }
pCmd = Tcl_NewListObj(nArg, aArg); pCmd = Tcl_NewListObj(nArg, aArg);
Tcl_IncrRefCount(pCmd); Tcl_IncrRefCount(pCmd);
for(i=0; i<argc; i++){ for(i=0; i<argc; i++){
sqlite3_value *pIn = argv[i]; sqlite3_value *pIn = argv[i];
Tcl_Obj *pVal; Tcl_Obj *pVal;
/* Set pVal to contain the i'th column of this row. */ /* Set pVal to contain the i'th column of this row. */
switch( sqlite3_value_type(pIn) ){ switch( sqlite3_value_type(pIn) ){
case SQLITE_BLOB: { case SQLITE_BLOB: {
@ -866,7 +946,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal); rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
if( rc ){ if( rc ){
Tcl_DecrRefCount(pCmd); Tcl_DecrRefCount(pCmd);
sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
return; return;
} }
} }
@ -881,7 +961,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
} }
if( rc && rc!=TCL_RETURN ){ if( rc && rc!=TCL_RETURN ){
sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
}else{ }else{
Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
int n; int n;
@ -983,7 +1063,7 @@ static int auth_callback(
Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
#ifdef SQLITE_USER_AUTHENTICATION #ifdef SQLITE_USER_AUTHENTICATION
Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : ""); Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : "");
#endif #endif
rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
Tcl_DStringFree(&str); Tcl_DStringFree(&str);
zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY"; zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
@ -1075,12 +1155,12 @@ static int DbTransPostCmd(
pDb->disableAuth++; pDb->disableAuth++;
if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){ if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
/* This is a tricky scenario to handle. The most likely cause of an /* This is a tricky scenario to handle. The most likely cause of an
** error is that the exec() above was an attempt to commit the ** error is that the exec() above was an attempt to commit the
** top-level transaction that returned SQLITE_BUSY. Or, less likely, ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
** that an IO-error has occurred. In either case, throw a Tcl exception ** that an IO-error has occurred. In either case, throw a Tcl exception
** and try to rollback the transaction. ** and try to rollback the transaction.
** **
** But it could also be that the user executed one or more BEGIN, ** But it could also be that the user executed one or more BEGIN,
** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
** this method's logic. Not clear how this would be best handled. ** this method's logic. Not clear how this would be best handled.
*/ */
@ -1099,7 +1179,7 @@ static int DbTransPostCmd(
** Unless SQLITE_TEST is defined, this function is a simple wrapper around ** Unless SQLITE_TEST is defined, this function is a simple wrapper around
** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either ** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending ** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
** on whether or not the [db_use_legacy_prepare] command has been used to ** on whether or not the [db_use_legacy_prepare] command has been used to
** configure the connection. ** configure the connection.
*/ */
static int dbPrepare( static int dbPrepare(
@ -1155,7 +1235,7 @@ static int dbPrepareAndBind(
for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
int n = pPreStmt->nSql; int n = pPreStmt->nSql;
if( nSql>=n if( nSql>=n
&& memcmp(pPreStmt->zSql, zSql, n)==0 && memcmp(pPreStmt->zSql, zSql, n)==0
&& (zSql[n]==0 || zSql[n-1]==';') && (zSql[n]==0 || zSql[n-1]==';')
){ ){
@ -1181,7 +1261,7 @@ static int dbPrepareAndBind(
break; break;
} }
} }
/* If no prepared statement was found. Compile the SQL text. Also allocate /* If no prepared statement was found. Compile the SQL text. Also allocate
** a new SqlPreparedStmt structure. */ ** a new SqlPreparedStmt structure. */
if( pPreStmt==0 ){ if( pPreStmt==0 ){
@ -1227,7 +1307,7 @@ static int dbPrepareAndBind(
assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql ); assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) ); assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );
/* Bind values to parameters that begin with $ or : */ /* Bind values to parameters that begin with $ or : */
for(i=1; i<=nVar; i++){ for(i=1; i<=nVar; i++){
const char *zVar = sqlite3_bind_parameter_name(pStmt, i); const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){ if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
@ -1315,8 +1395,8 @@ static void dbReleaseStmt(
assert( pDb->nStmt>0 ); assert( pDb->nStmt>0 );
} }
pDb->nStmt++; pDb->nStmt++;
/* If we have too many statement in cache, remove the surplus from /* If we have too many statement in cache, remove the surplus from
** the end of the cache list. */ ** the end of the cache list. */
while( pDb->nStmt>pDb->maxStmt ){ while( pDb->nStmt>pDb->maxStmt ){
SqlPreparedStmt *pLast = pDb->stmtLast; SqlPreparedStmt *pLast = pDb->stmtLast;
@ -1370,8 +1450,8 @@ static void dbReleaseColumnNames(DbEvalContext *p){
** If pArray is not NULL, then it contains the name of a Tcl array ** If pArray is not NULL, then it contains the name of a Tcl array
** variable. The "*" member of this array is set to a list containing ** variable. The "*" member of this array is set to a list containing
** the names of the columns returned by the statement as part of each ** the names of the columns returned by the statement as part of each
** call to dbEvalStep(), in order from left to right. e.g. if the names ** call to dbEvalStep(), in order from left to right. e.g. if the names
** of the returned columns are a, b and c, it does the equivalent of the ** of the returned columns are a, b and c, it does the equivalent of the
** tcl command: ** tcl command:
** **
** set ${pArray}(*) {a b c} ** set ${pArray}(*) {a b c}
@ -1492,7 +1572,7 @@ static int dbEvalStep(DbEvalContext *p){
#if SQLITE_TEST #if SQLITE_TEST
if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){ if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
/* If the runtime error was an SQLITE_SCHEMA, and the database /* If the runtime error was an SQLITE_SCHEMA, and the database
** handle is configured to use the legacy sqlite3_prepare() ** handle is configured to use the legacy sqlite3_prepare()
** interface, retry prepare()/step() on the same SQL statement. ** interface, retry prepare()/step() on the same SQL statement.
** This only happens once. If there is a second SQLITE_SCHEMA ** This only happens once. If there is a second SQLITE_SCHEMA
** error, the error will be returned to the caller. */ ** error, the error will be returned to the caller. */
@ -1580,11 +1660,11 @@ static int DbUseNre(void){
return( (major==8 && minor>=6) || major>8 ); return( (major==8 && minor>=6) || major>8 );
} }
#else #else
/* /*
** Compiling using headers earlier than 8.6. In this case NR cannot be ** Compiling using headers earlier than 8.6. In this case NR cannot be
** used, so DbUseNre() to always return zero. Add #defines for the other ** used, so DbUseNre() to always return zero. Add #defines for the other
** Tcl_NRxxx() functions to prevent them from causing compilation errors, ** Tcl_NRxxx() functions to prevent them from causing compilation errors,
** even though the only invocations of them are within conditional blocks ** even though the only invocations of them are within conditional blocks
** of the form: ** of the form:
** **
** if( DbUseNre() ) { ... } ** if( DbUseNre() ) { ... }
@ -1630,11 +1710,11 @@ static int DbEvalNextCmd(
} }
} }
/* The required interpreter variables are now populated with the data /* The required interpreter variables are now populated with the data
** from the current row. If using NRE, schedule callbacks to evaluate ** from the current row. If using NRE, schedule callbacks to evaluate
** script pScript, then to invoke this function again to fetch the next ** script pScript, then to invoke this function again to fetch the next
** row (or clean up if there is no next row or the script throws an ** row (or clean up if there is no next row or the script throws an
** exception). After scheduling the callbacks, return control to the ** exception). After scheduling the callbacks, return control to the
** caller. ** caller.
** **
** If not using NRE, evaluate pScript directly and continue with the ** If not using NRE, evaluate pScript directly and continue with the
@ -1659,7 +1739,7 @@ static int DbEvalNextCmd(
} }
/* /*
** This function is used by the implementations of the following database ** This function is used by the implementations of the following database
** handle sub-commands: ** handle sub-commands:
** **
** $db update_hook ?SCRIPT? ** $db update_hook ?SCRIPT?
@ -1726,9 +1806,10 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
"preupdate", "profile", "progress", "preupdate", "profile", "progress",
"rekey", "restore", "rollback_hook", "rekey", "restore", "rollback_hook",
"status", "timeout", "total_changes", "status", "timeout", "total_changes",
"trace", "transaction", "unlock_notify", "trace", "trace_v2", "transaction",
"update_hook", "version", "wal_hook", "unlock_notify", "update_hook", "version",
0 "wal_hook",
0
}; };
enum DB_enum { enum DB_enum {
DB_AUTHORIZER, DB_BACKUP, DB_BUSY, DB_AUTHORIZER, DB_BACKUP, DB_BUSY,
@ -1741,8 +1822,9 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
DB_PREUPDATE, DB_PROFILE, DB_PROGRESS, DB_PREUPDATE, DB_PROFILE, DB_PROGRESS,
DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK,
DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES,
DB_TRACE, DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_TRACE, DB_TRACE_V2, DB_TRANSACTION,
DB_UPDATE_HOOK, DB_VERSION, DB_WAL_HOOK, DB_UNLOCK_NOTIFY, DB_UPDATE_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 */
@ -1928,7 +2010,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
return TCL_ERROR; return TCL_ERROR;
}else{ }else{
if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){ if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
Tcl_AppendResult( interp, "cannot convert \"", Tcl_AppendResult( interp, "cannot convert \"",
Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0); Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0);
return TCL_ERROR; return TCL_ERROR;
}else{ }else{
@ -1942,7 +2024,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
} }
} }
}else{ }else{
Tcl_AppendResult( interp, "bad option \"", Tcl_AppendResult( interp, "bad option \"",
Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size",
(char*)0); (char*)0);
return TCL_ERROR; return TCL_ERROR;
@ -1953,7 +2035,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
/* $db changes /* $db changes
** **
** Return the number of rows that were modified, inserted, or deleted by ** Return the number of rows that were modified, inserted, or deleted by
** the most recent INSERT, UPDATE or DELETE statement, not including ** the most recent INSERT, UPDATE or DELETE statement, not including
** any changes made by trigger programs. ** any changes made by trigger programs.
*/ */
case DB_CHANGES: { case DB_CHANGES: {
@ -2000,7 +2082,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
pCollate->zScript = (char*)&pCollate[1]; pCollate->zScript = (char*)&pCollate[1];
pDb->pCollate = pCollate; pDb->pCollate = pCollate;
memcpy(pCollate->zScript, zScript, nScript+1); memcpy(pCollate->zScript, zScript, nScript+1);
if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
pCollate, tclSqlCollate) ){ pCollate, tclSqlCollate) ){
Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
return TCL_ERROR; return TCL_ERROR;
@ -2126,7 +2208,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
const char *zSep; const char *zSep;
const char *zNull; const char *zNull;
if( objc<5 || objc>7 ){ if( objc<5 || objc>7 ){
Tcl_WrongNumArgs(interp, 2, objv, Tcl_WrongNumArgs(interp, 2, objv,
"CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
return TCL_ERROR; return TCL_ERROR;
} }
@ -2155,7 +2237,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
strcmp(zConflict, "fail" ) != 0 && strcmp(zConflict, "fail" ) != 0 &&
strcmp(zConflict, "ignore" ) != 0 && strcmp(zConflict, "ignore" ) != 0 &&
strcmp(zConflict, "replace" ) != 0 ) { strcmp(zConflict, "replace" ) != 0 ) {
Tcl_AppendResult(interp, "Error: \"", zConflict, Tcl_AppendResult(interp, "Error: \"", zConflict,
"\", conflict-algorithm must be one of: rollback, " "\", conflict-algorithm must be one of: rollback, "
"abort, fail, ignore, or replace", (char*)0); "abort, fail, ignore, or replace", (char*)0);
return TCL_ERROR; return TCL_ERROR;
@ -2244,7 +2326,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
for(i=0; i<nCol; i++){ for(i=0; i<nCol; i++){
/* check for null data, if so, bind as null */ /* check for null data, if so, bind as null */
if( (nNull>0 && strcmp(azCol[i], zNull)==0) if( (nNull>0 && strcmp(azCol[i], zNull)==0)
|| strlen30(azCol[i])==0 || strlen30(azCol[i])==0
){ ){
sqlite3_bind_null(pStmt, i+1); sqlite3_bind_null(pStmt, i+1);
}else{ }else{
@ -2323,7 +2405,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
** The onecolumn method is the equivalent of: ** The onecolumn method is the equivalent of:
** lindex [$db eval $sql] 0 ** lindex [$db eval $sql] 0
*/ */
case DB_EXISTS: case DB_EXISTS:
case DB_ONECOLUMN: { case DB_ONECOLUMN: {
Tcl_Obj *pResult = 0; Tcl_Obj *pResult = 0;
DbEvalContext sEval; DbEvalContext sEval;
@ -2351,7 +2433,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
} }
break; break;
} }
/* /*
** $db eval $sql ?array? ?{ ...code... }? ** $db eval $sql ?array? ?{ ...code... }?
** **
@ -2397,7 +2479,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
} }
pScript = objv[objc-1]; pScript = objv[objc-1];
Tcl_IncrRefCount(pScript); Tcl_IncrRefCount(pScript);
p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext)); p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
dbEvalInit(p, pDb, objv[2], pArray); dbEvalInit(p, pDb, objv[2], pArray);
@ -2444,7 +2526,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
if( n>2 && strncmp(z, "-deterministic",n)==0 ){ if( n>2 && strncmp(z, "-deterministic",n)==0 ){
flags |= SQLITE_DETERMINISTIC; flags |= SQLITE_DETERMINISTIC;
}else{ }else{
Tcl_AppendResult(interp, "bad option \"", z, Tcl_AppendResult(interp, "bad option \"", z,
"\": must be -argcount or -deterministic", 0 "\": must be -argcount or -deterministic", 0
); );
return TCL_ERROR; return TCL_ERROR;
@ -2553,7 +2635,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
} }
/* /*
** $db last_insert_rowid ** $db last_insert_rowid
** **
** Return an integer which is the ROWID for the most recent insert. ** Return an integer which is the ROWID for the most recent insert.
*/ */
@ -2575,7 +2657,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
*/ */
/* $db progress ?N CALLBACK? /* $db progress ?N CALLBACK?
** **
** Invoke the given callback every N virtual machine opcodes while executing ** Invoke the given callback every N virtual machine opcodes while executing
** queries. ** queries.
*/ */
@ -2682,7 +2764,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
/* $db restore ?DATABASE? FILENAME /* $db restore ?DATABASE? FILENAME
** **
** Open a database file named FILENAME. Transfer the content ** Open a database file named FILENAME. Transfer the content
** of FILENAME into the local database DATABASE (default: "main"). ** of FILENAME into the local database DATABASE (default: "main").
*/ */
case DB_RESTORE: { case DB_RESTORE: {
@ -2743,7 +2825,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
/* /*
** $db status (step|sort|autoindex) ** $db status (step|sort|autoindex)
** **
** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
** SQLITE_STMTSTATUS_SORT for the most recent eval. ** SQLITE_STMTSTATUS_SORT for the most recent eval.
*/ */
case DB_STATUS: { case DB_STATUS: {
@ -2761,15 +2843,15 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}else if( strcmp(zOp, "autoindex")==0 ){ }else if( strcmp(zOp, "autoindex")==0 ){
v = pDb->nIndex; v = pDb->nIndex;
}else{ }else{
Tcl_AppendResult(interp, Tcl_AppendResult(interp,
"bad argument: should be autoindex, step, or sort", "bad argument: should be autoindex, step, or sort",
(char*)0); (char*)0);
return TCL_ERROR; return TCL_ERROR;
} }
Tcl_SetObjResult(interp, Tcl_NewIntObj(v)); Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
break; break;
} }
/* /*
** $db timeout MILLESECONDS ** $db timeout MILLESECONDS
** **
@ -2785,11 +2867,11 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
sqlite3_busy_timeout(pDb->db, ms); sqlite3_busy_timeout(pDb->db, ms);
break; break;
} }
/* /*
** $db total_changes ** $db total_changes
** **
** Return the number of rows that were modified, inserted, or deleted ** Return the number of rows that were modified, inserted, or deleted
** since the database handle was created. ** since the database handle was created.
*/ */
case DB_TOTAL_CHANGES: { case DB_TOTAL_CHANGES: {
@ -2830,7 +2912,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
}else{ }else{
pDb->zTrace = 0; pDb->zTrace = 0;
} }
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) \
&& !defined(SQLITE_OMIT_DEPRECATED)
if( pDb->zTrace ){ if( pDb->zTrace ){
pDb->interp = interp; pDb->interp = interp;
sqlite3_trace(pDb->db, DbTraceHandler, pDb); sqlite3_trace(pDb->db, DbTraceHandler, pDb);
@ -2842,6 +2925,88 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
break; break;
} }
/* $db trace_v2 ?CALLBACK? ?MASK?
**
** Make arrangements to invoke the CALLBACK routine for each trace event
** matching the mask that is generated. The parameters are appended to
** CALLBACK before it is executed.
*/
case DB_TRACE_V2: {
if( objc>4 ){
Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?");
return TCL_ERROR;
}else if( objc==2 ){
if( pDb->zTraceV2 ){
Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0);
}
}else{
char *zTraceV2;
int len;
Tcl_WideInt wMask = 0;
if( objc==4 ){
static const char *TTYPE_strs[] = {
"statement", "profile", "row", "close", 0
};
enum TTYPE_enum {
TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE
};
int i;
if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){
return TCL_ERROR;
}
for(i=0; i<len; i++){
Tcl_Obj *pObj;
int ttype;
if( TCL_OK!=Tcl_ListObjIndex(interp, objv[3], i, &pObj) ){
return TCL_ERROR;
}
if( Tcl_GetIndexFromObj(interp, pObj, TTYPE_strs, "trace type",
0, &ttype)!=TCL_OK ){
Tcl_WideInt wType;
Tcl_Obj *pError = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
Tcl_IncrRefCount(pError);
if( TCL_OK==Tcl_GetWideIntFromObj(interp, pObj, &wType) ){
Tcl_DecrRefCount(pError);
wMask |= wType;
}else{
Tcl_SetObjResult(interp, pError);
Tcl_DecrRefCount(pError);
return TCL_ERROR;
}
}else{
switch( (enum TTYPE_enum)ttype ){
case TTYPE_STMT: wMask |= SQLITE_TRACE_STMT; break;
case TTYPE_PROFILE: wMask |= SQLITE_TRACE_PROFILE; break;
case TTYPE_ROW: wMask |= SQLITE_TRACE_ROW; break;
case TTYPE_CLOSE: wMask |= SQLITE_TRACE_CLOSE; break;
}
}
}
}else{
wMask = SQLITE_TRACE_STMT; /* use the "legacy" default */
}
if( pDb->zTraceV2 ){
Tcl_Free(pDb->zTraceV2);
}
zTraceV2 = Tcl_GetStringFromObj(objv[2], &len);
if( zTraceV2 && len>0 ){
pDb->zTraceV2 = Tcl_Alloc( len + 1 );
memcpy(pDb->zTraceV2, zTraceV2, len+1);
}else{
pDb->zTraceV2 = 0;
}
#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
if( pDb->zTraceV2 ){
pDb->interp = interp;
sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb);
}else{
sqlite3_trace_v2(pDb->db, 0, 0, 0);
}
#endif
}
break;
}
/* $db transaction [-deferred|-immediate|-exclusive] SCRIPT /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT
** **
** Start a new transaction (if we are not already in the midst of a ** Start a new transaction (if we are not already in the midst of a
@ -2894,7 +3059,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
/* If using NRE, schedule a callback to invoke the script pScript, then /* If using NRE, schedule a callback to invoke the script pScript, then
** a second callback to commit (or rollback) the transaction or savepoint ** a second callback to commit (or rollback) the transaction or savepoint
** opened above. If not using NRE, evaluate the script directly, then ** opened above. If not using NRE, evaluate the script directly, then
** call function DbTransPostCmd() to commit (or rollback) the transaction ** call function DbTransPostCmd() to commit (or rollback) the transaction
** or savepoint. */ ** or savepoint. */
if( DbUseNre() ){ if( DbUseNre() ){
Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0); Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
@ -2925,14 +3090,14 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
Tcl_DecrRefCount(pDb->pUnlockNotify); Tcl_DecrRefCount(pDb->pUnlockNotify);
pDb->pUnlockNotify = 0; pDb->pUnlockNotify = 0;
} }
if( objc==3 ){ if( objc==3 ){
xNotify = DbUnlockNotify; xNotify = DbUnlockNotify;
pNotifyArg = (void *)pDb; pNotifyArg = (void *)pDb;
pDb->pUnlockNotify = objv[2]; pDb->pUnlockNotify = objv[2];
Tcl_IncrRefCount(pDb->pUnlockNotify); Tcl_IncrRefCount(pDb->pUnlockNotify);
} }
if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){ if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0); Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
rc = TCL_ERROR; rc = TCL_ERROR;
@ -3031,13 +3196,13 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
** $db update_hook ?script? ** $db update_hook ?script?
** $db rollback_hook ?script? ** $db rollback_hook ?script?
*/ */
case DB_WAL_HOOK: case DB_WAL_HOOK:
case DB_UPDATE_HOOK: case DB_UPDATE_HOOK:
case DB_ROLLBACK_HOOK: { case DB_ROLLBACK_HOOK: {
/* set ppHook to point at pUpdateHook or pRollbackHook, depending on /* set ppHook to point at pUpdateHook or pRollbackHook, depending on
** whether [$db update_hook] or [$db rollback_hook] was invoked. ** whether [$db update_hook] or [$db rollback_hook] was invoked.
*/ */
Tcl_Obj **ppHook = 0; Tcl_Obj **ppHook = 0;
if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook; if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook;
if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook; if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook;
if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook; if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook;
@ -3198,7 +3363,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
} }
} }
if( objc<3 || (objc&1)!=1 ){ if( objc<3 || (objc&1)!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, Tcl_WrongNumArgs(interp, 1, objv,
"HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
" ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?" " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL) #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
@ -3490,7 +3655,7 @@ static void MD5Init(MD5Context *ctx){
* Update context to reflect the concatenation of another buffer full * Update context to reflect the concatenation of another buffer full
* of bytes. * of bytes.
*/ */
static static
void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){ void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
uint32 t; uint32 t;
@ -3536,7 +3701,7 @@ void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
} }
/* /*
* Final wrapup - pad to 64-byte boundary with the bit pattern * Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first) * 1 0* (64-bit count of bits processed, MSB-first)
*/ */
static void MD5Final(unsigned char digest[16], MD5Context *ctx){ static void MD5Final(unsigned char digest[16], MD5Context *ctx){
@ -3612,7 +3777,7 @@ static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
/* /*
** A TCL command for md5. The argument is the text to be hashed. The ** A TCL command for md5. The argument is the text to be hashed. The
** Result is the hash in base64. ** Result is the hash in base64.
*/ */
static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){ static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
MD5Context ctx; MD5Context ctx;
@ -3621,7 +3786,7 @@ static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
void (*converter)(unsigned char*, char*); void (*converter)(unsigned char*, char*);
if( argc!=2 ){ if( argc!=2 ){
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
" TEXT\"", (char*)0); " TEXT\"", (char*)0);
return TCL_ERROR; return TCL_ERROR;
} }
@ -3646,13 +3811,13 @@ static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){
char zBuf[10240]; char zBuf[10240];
if( argc!=2 ){ if( argc!=2 ){
Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
" FILENAME\"", (char*)0); " FILENAME\"", (char*)0);
return TCL_ERROR; return TCL_ERROR;
} }
in = fopen(argv[1],"rb"); in = fopen(argv[1],"rb");
if( in==0 ){ if( in==0 ){
Tcl_AppendResult(interp,"unable to open file \"", argv[1], Tcl_AppendResult(interp,"unable to open file \"", argv[1],
"\" for reading", (char*)0); "\" for reading", (char*)0);
return TCL_ERROR; return TCL_ERROR;
} }
@ -3719,7 +3884,7 @@ static void md5finalize(sqlite3_context *context){
sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
} }
int Md5_Register(sqlite3 *db){ int Md5_Register(sqlite3 *db){
int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,
md5step, md5finalize); md5step, md5finalize);
sqlite3_overload_function(db, "md5sum", -1); /* To exercise this API */ sqlite3_overload_function(db, "md5sum", -1); /* To exercise this API */
return rc; return rc;
@ -3870,7 +4035,7 @@ static int db_last_stmt_ptr(
** Configure the interpreter passed as the first argument to have access ** Configure the interpreter passed as the first argument to have access
** to the commands and linked variables that make up: ** to the commands and linked variables that make up:
** **
** * the [sqlite3] extension itself, ** * the [sqlite3] extension itself,
** **
** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and ** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
** **

View File

@ -3633,7 +3633,7 @@ static int test_bind_blob(
Tcl_Obj *CONST objv[] Tcl_Obj *CONST objv[]
){ ){
sqlite3_stmt *pStmt; sqlite3_stmt *pStmt;
int idx; int len, idx;
int bytes; int bytes;
char *value; char *value;
int rc; int rc;
@ -3652,9 +3652,18 @@ static int test_bind_blob(
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
value = Tcl_GetString(objv[3]);
value = (char*)Tcl_GetByteArrayFromObj(objv[3], &len);
if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
if( bytes>len ){
char zBuf[200];
sqlite3_snprintf(sizeof(zBuf), zBuf,
"cannot use %d blob bytes, have %d", bytes, len);
Tcl_AppendResult(interp, zBuf, -1);
return TCL_ERROR;
}
rc = sqlite3_bind_blob(pStmt, idx, value, bytes, xDestructor); rc = sqlite3_bind_blob(pStmt, idx, value, bytes, xDestructor);
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
if( rc!=SQLITE_OK ){ if( rc!=SQLITE_OK ){
@ -4386,6 +4395,26 @@ static int test_sql(
Tcl_SetResult(interp, (char *)sqlite3_sql(pStmt), TCL_VOLATILE); Tcl_SetResult(interp, (char *)sqlite3_sql(pStmt), TCL_VOLATILE);
return TCL_OK; return TCL_OK;
} }
static int test_ex_sql(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
sqlite3_stmt *pStmt;
char *z;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "STMT");
return TCL_ERROR;
}
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
z = sqlite3_expanded_sql(pStmt);
Tcl_SetResult(interp, z, TCL_VOLATILE);
sqlite3_free(z);
return TCL_OK;
}
/* /*
** Usage: sqlite3_column_count STMT ** Usage: sqlite3_column_count STMT
@ -7276,6 +7305,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "sqlite3_changes", test_changes ,0 }, { "sqlite3_changes", test_changes ,0 },
{ "sqlite3_step", test_step ,0 }, { "sqlite3_step", test_step ,0 },
{ "sqlite3_sql", test_sql ,0 }, { "sqlite3_sql", test_sql ,0 },
{ "sqlite3_expanded_sql", test_ex_sql ,0 },
{ "sqlite3_next_stmt", test_next_stmt ,0 }, { "sqlite3_next_stmt", test_next_stmt ,0 },
{ "sqlite3_stmt_readonly", test_stmt_readonly ,0 }, { "sqlite3_stmt_readonly", test_stmt_readonly ,0 },
{ "sqlite3_stmt_busy", test_stmt_busy ,0 }, { "sqlite3_stmt_busy", test_stmt_busy ,0 },

View File

@ -121,7 +121,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
int saved_flags; /* Saved value of the db->flags */ int saved_flags; /* Saved value of the db->flags */
int saved_nChange; /* Saved value of db->nChange */ int saved_nChange; /* Saved value of db->nChange */
int saved_nTotalChange; /* Saved value of db->nTotalChange */ int saved_nTotalChange; /* Saved value of db->nTotalChange */
void (*saved_xTrace)(void*,const char*); /* Saved db->xTrace */ u8 saved_mTrace; /* Saved trace settings */
Db *pDb = 0; /* Database to detach at end of vacuum */ Db *pDb = 0; /* Database to detach at end of vacuum */
int isMemDb; /* True if vacuuming a :memory: database */ int isMemDb; /* True if vacuuming a :memory: database */
int nRes; /* Bytes of reserved space at the end of each page */ int nRes; /* Bytes of reserved space at the end of each page */
@ -142,10 +142,10 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
saved_flags = db->flags; saved_flags = db->flags;
saved_nChange = db->nChange; saved_nChange = db->nChange;
saved_nTotalChange = db->nTotalChange; saved_nTotalChange = db->nTotalChange;
saved_xTrace = db->xTrace; saved_mTrace = db->mTrace;
db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks | SQLITE_PreferBuiltin;
db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder); db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder);
db->xTrace = 0; db->mTrace = 0;
pMain = db->aDb[0].pBt; pMain = db->aDb[0].pBt;
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
@ -197,6 +197,8 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
} }
#endif #endif
sqlite3BtreeSetCacheSize(pTemp, db->aDb[0].pSchema->cache_size);
sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0));
rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF"); rc = execSql(db, pzErrMsg, "PRAGMA vacuum_db.synchronous=OFF");
if( rc!=SQLITE_OK ) goto end_of_vacuum; if( rc!=SQLITE_OK ) goto end_of_vacuum;
@ -345,7 +347,7 @@ end_of_vacuum:
db->flags = saved_flags; db->flags = saved_flags;
db->nChange = saved_nChange; db->nChange = saved_nChange;
db->nTotalChange = saved_nTotalChange; db->nTotalChange = saved_nTotalChange;
db->xTrace = saved_xTrace; db->mTrace = saved_mTrace;
sqlite3BtreeSetPageSize(pMain, -1, -1, 1); sqlite3BtreeSetPageSize(pMain, -1, -1, 1);
/* Currently there is an SQL level transaction open on the vacuum /* Currently there is an SQL level transaction open on the vacuum

View File

@ -1383,6 +1383,10 @@ case OP_ResultRow: {
} }
if( db->mallocFailed ) goto no_mem; if( db->mallocFailed ) goto no_mem;
if( db->mTrace & SQLITE_TRACE_ROW ){
db->xTrace(SQLITE_TRACE_ROW, db->pTraceArg, p, 0);
}
/* Return SQLITE_ROW /* Return SQLITE_ROW
*/ */
p->pc = (int)(pOp - aOp) + 1; p->pc = (int)(pOp - aOp) + 1;
@ -6816,16 +6820,34 @@ case OP_MaxPgcnt: { /* out2 */
*/ */
case OP_Init: { /* jump */ case OP_Init: { /* jump */
char *zTrace; char *zTrace;
char *z;
/* If the P4 argument is not NULL, then it must be an SQL comment string.
** The "--" string is broken up to prevent false-positives with srcck1.c.
**
** This assert() provides evidence for:
** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that
** would have been returned by the legacy sqlite3_trace() interface by
** using the X argument when X begins with "--" and invoking
** sqlite3_expanded_sql(P) otherwise.
*/
assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 );
#ifndef SQLITE_OMIT_TRACE #ifndef SQLITE_OMIT_TRACE
if( db->xTrace if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0
&& !p->doingRerun && !p->doingRerun
&& (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){ ){
z = sqlite3VdbeExpandSql(p, zTrace); #ifndef SQLITE_OMIT_DEPRECATED
db->xTrace(db->pTraceArg, z); if( db->mTrace & SQLITE_TRACE_LEGACY ){
sqlite3DbFree(db, z); void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace;
char *z = sqlite3VdbeExpandSql(p, zTrace);
x(db->pTraceArg, z);
sqlite3_free(z);
}else
#endif
{
(void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace);
}
} }
#ifdef SQLITE_USE_FCNTL_TRACE #ifdef SQLITE_USE_FCNTL_TRACE
zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);

View File

@ -60,12 +60,19 @@ static int vdbeSafetyNotNull(Vdbe *p){
*/ */
static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){
sqlite3_int64 iNow; sqlite3_int64 iNow;
sqlite3_int64 iElapse;
assert( p->startTime>0 ); assert( p->startTime>0 );
assert( db->xProfile!=0 ); assert( db->xProfile!=0 || (db->mTrace & SQLITE_TRACE_PROFILE)!=0 );
assert( db->init.busy==0 ); assert( db->init.busy==0 );
assert( p->zSql!=0 ); assert( p->zSql!=0 );
sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); sqlite3OsCurrentTimeInt64(db->pVfs, &iNow);
db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000); iElapse = (iNow - p->startTime)*1000000;
if( db->xProfile ){
db->xProfile(db->pProfileArg, p->zSql, iElapse);
}
if( db->mTrace & SQLITE_TRACE_PROFILE ){
db->xTrace(SQLITE_TRACE_PROFILE, db->pTraceArg, p, (void*)&iElapse);
}
p->startTime = 0; p->startTime = 0;
} }
/* /*
@ -569,7 +576,8 @@ static int sqlite3Step(Vdbe *p){
); );
#ifndef SQLITE_OMIT_TRACE #ifndef SQLITE_OMIT_TRACE
if( db->xProfile && !db->init.busy && p->zSql ){ if( (db->xProfile || (db->mTrace & SQLITE_TRACE_PROFILE)!=0)
&& !db->init.busy && p->zSql ){
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
}else{ }else{
assert( p->startTime==0 ); assert( p->startTime==0 );
@ -1604,6 +1612,39 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
return (int)v; return (int)v;
} }
/*
** Return the SQL associated with a prepared statement
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe *)pStmt;
return p ? p->zSql : 0;
}
/*
** Return the SQL associated with a prepared statement with
** bound parameters expanded. Space to hold the returned string is
** obtained from sqlite3_malloc(). The caller is responsible for
** freeing the returned string by passing it to sqlite3_free().
**
** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of
** expanded bound parameters.
*/
char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){
#ifdef SQLITE_OMIT_TRACE
return 0;
#else
char *z = 0;
const char *zSql = sqlite3_sql(pStmt);
if( zSql ){
Vdbe *p = (Vdbe *)pStmt;
sqlite3_mutex_enter(p->db->mutex);
z = sqlite3VdbeExpandSql(p, zSql);
sqlite3_mutex_leave(p->db->mutex);
}
return z;
#endif
}
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
/* /*
** Allocate and populate an UnpackedRecord structure based on the serialized ** Allocate and populate an UnpackedRecord structure based on the serialized

View File

@ -64,14 +64,6 @@ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
p->isPrepareV2 = (u8)isPrepareV2; p->isPrepareV2 = (u8)isPrepareV2;
} }
/*
** Return the SQL associated with a prepared statement
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt){
Vdbe *p = (Vdbe *)pStmt;
return p ? p->zSql : 0;
}
/* /*
** Swap all content between two VDBE structures. ** Swap all content between two VDBE structures.
*/ */

View File

@ -81,10 +81,13 @@ char *sqlite3VdbeExpandSql(
int i; /* Loop counter */ int i; /* Loop counter */
Mem *pVar; /* Value of a host parameter */ Mem *pVar; /* Value of a host parameter */
StrAccum out; /* Accumulate the output here */ StrAccum out; /* Accumulate the output here */
#ifndef SQLITE_OMIT_UTF16
Mem utf8; /* Used to convert UTF16 parameters into UTF8 for display */
#endif
char zBase[100]; /* Initial working space */ char zBase[100]; /* Initial working space */
db = p->db; db = p->db;
sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase), sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]); db->aLimit[SQLITE_LIMIT_LENGTH]);
if( db->nVdbeExec>1 ){ if( db->nVdbeExec>1 ){
while( *zRawSql ){ while( *zRawSql ){
@ -135,12 +138,14 @@ char *sqlite3VdbeExpandSql(
int nOut; /* Number of bytes of the string text to include in output */ int nOut; /* Number of bytes of the string text to include in output */
#ifndef SQLITE_OMIT_UTF16 #ifndef SQLITE_OMIT_UTF16
u8 enc = ENC(db); u8 enc = ENC(db);
Mem utf8;
if( enc!=SQLITE_UTF8 ){ if( enc!=SQLITE_UTF8 ){
memset(&utf8, 0, sizeof(utf8)); memset(&utf8, 0, sizeof(utf8));
utf8.db = db; utf8.db = db;
sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC);
sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8); if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){
out.accError = STRACCUM_NOMEM;
out.nAlloc = 0;
}
pVar = &utf8; pVar = &utf8;
} }
#endif #endif
@ -182,6 +187,7 @@ char *sqlite3VdbeExpandSql(
} }
} }
} }
if( out.accError ) sqlite3StrAccumReset(&out);
return sqlite3StrAccumFinish(&out); return sqlite3StrAccumFinish(&out);
} }

View File

@ -1416,6 +1416,7 @@ Bitmask sqlite3WhereCodeOneLoopStart(
}else{ }else{
startEq = 1; startEq = 1;
} }
bSeekPastNull = 0;
}else if( bSeekPastNull ){ }else if( bSeekPastNull ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
nConstraint++; nConstraint++;

View File

@ -13,7 +13,7 @@
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
set testprefix closure01 set testprefix csv01
ifcapable !vtab||!cte { finish_test ; return } ifcapable !vtab||!cte { finish_test ; return }

View File

@ -379,35 +379,40 @@ foreach ::lookaside_buffer_size {0 64 120} {
# The following tests focus on DBSTATUS_CACHE_USED_SHARED # The following tests focus on DBSTATUS_CACHE_USED_SHARED
# #
ifcapable shared_cache { ifcapable shared_cache {
proc do_cacheused_test {tn db res} { if {[permutation]=="memsys3"
set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0] || [permutation]=="memsys5"
set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0] || $::tcl_platform(os)=="Linux"} {
set cu [lindex $cu 1] proc do_cacheused_test {tn db res} {
set pcu [lindex $pcu 1] set cu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED 0]
uplevel [list do_test $tn [list list $cu $pcu] "#/$res/"] set pcu [sqlite3_db_status $db SQLITE_DBSTATUS_CACHE_USED_SHARED 0]
set cu [lindex $cu 1]
set pcu [lindex $pcu 1]
uplevel [list do_test $tn [list list $cu $pcu] "#/$res/"]
}
reset_db
sqlite3 db file:test.db?cache=shared
do_execsql_test 4.0 {
PRAGMA auto_vacuum=NONE;
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
}
do_cacheused_test 4.0.1 db { 4568 4568 }
do_execsql_test 4.1 {
CREATE TEMP TABLE tt(a, b, c);
INSERT INTO tt VALUES(1, 2, 3);
}
do_cacheused_test 4.1.1 db { 9000 9000 }
sqlite3 db2 file:test.db?cache=shared
do_cacheused_test 4.2.1 db2 { 4568 2284 }
do_cacheused_test 4.2.2 db { 9000 6716 }
db close
do_cacheused_test 4.2.3 db2 { 4568 4568 }
sqlite3 db file:test.db?cache=shared
do_cacheused_test 4.2.4 db2 { 4568 2284 }
db2 close
} }
reset_db
sqlite3 db file:test.db?cache=shared
do_execsql_test 4.0 {
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES(1, 2, 3);
}
do_cacheused_test 4.0.1 db { 4568 4568 }
do_execsql_test 4.1 {
CREATE TEMP TABLE tt(a, b, c);
INSERT INTO tt VALUES(1, 2, 3);
}
do_cacheused_test 4.1.1 db { 9000 9000 }
sqlite3 db2 file:test.db?cache=shared
do_cacheused_test 4.2.1 db2 { 4568 2284 }
do_cacheused_test 4.2.2 db { 9000 6716 }
db close
do_cacheused_test 4.2.3 db2 { 4568 4568 }
sqlite3 db file:test.db?cache=shared
do_cacheused_test 4.2.4 db2 { 4568 2284 }
db2 close
} }
finish_test finish_test

View File

@ -356,5 +356,34 @@ do_execsql_test json-8.2 {
SELECT a=json_extract(b,'$[0]') FROM t8; SELECT a=json_extract(b,'$[0]') FROM t8;
} {1} } {1}
# The json_quote() function transforms an SQL value into a JSON value.
# String values are quoted and interior quotes are escaped. NULL values
# are rendered as the unquoted string "null".
#
do_execsql_test json-9.1 {
SELECT json_quote('abc"xyz');
} {{"abc\"xyz"}}
do_execsql_test json-9.2 {
SELECT json_quote(3.14159);
} {3.14159}
do_execsql_test json-9.3 {
SELECT json_quote(12345);
} {12345}
do_execsql_test json-9.4 {
SELECT json_quote(null);
} {"null"}
do_catchsql_test json-9.5 {
SELECT json_quote(x'30313233');
} {1 {JSON cannot hold BLOB values}}
do_catchsql_test json-9.6 {
SELECT json_quote(123,456)
} {1 {wrong number of arguments to function json_quote()}}
do_catchsql_test json-9.7 {
SELECT json_quote()
} {1 {wrong number of arguments to function json_quote()}}
finish_test finish_test

View File

@ -628,5 +628,19 @@ do_test_13_noopt 13.7 {
SELECT min(c), count(c) FROM t1 WHERE a='a'; SELECT min(c), count(c) FROM t1 WHERE a='a';
} {1 5} } {1 5}
# 2016-07-26. https://www.sqlite.org/src/info/a0bac8b3c3d1bb75
# Incorrect result on a min() query after a CREATE INDEX.
#
do_execsql_test 14.1 {
CREATE TABLE t14(a INTEGER, b INTEGER);
INSERT INTO t14(a,b) VALUES(100,2),(200,2),(300,2),(400,1),(500,2);
SELECT min(a) FROM t14 WHERE b='2' AND a>'50';
} {100}
do_execsql_test 14.2 {
CREATE INDEX t14ba ON t14(b,a);
SELECT min(a) FROM t14 WHERE b='2' AND a>'50';
} {100}
finish_test finish_test

View File

@ -120,7 +120,6 @@ array set ::Configs [strip_comments {
-DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3=1
-DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_RTREE=1
-DSQLITE_ENABLE_MEMSYS5=1 -DSQLITE_ENABLE_MEMSYS5=1
-DSQLITE_ENABLE_MEMSYS3=1
-DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_ENABLE_COLUMN_METADATA=1
-DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_STAT4
-DSQLITE_ENABLE_HIDDEN_COLUMNS -DSQLITE_ENABLE_HIDDEN_COLUMNS

View File

@ -870,6 +870,7 @@ do_test shell1-5.0 {
if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} { if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} {
continue continue
} }
if {$i>=0xE0 && $tcl_platform(os)=="OpenBSD"} continue
set hex [format %02X $i] set hex [format %02X $i]
set char [subst \\x$hex]; set oldChar $char set char [subst \\x$hex]; set oldChar $char
set escapes [list] set escapes [list]

View File

@ -34,7 +34,7 @@ do_test tcl-1.1 {
do_test tcl-1.2 { do_test tcl-1.2 {
set v [catch {db bogus} msg] set v [catch {db bogus} msg]
lappend v $msg lappend v $msg
} {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, transaction, unlock_notify, update_hook, version, or wal_hook}} } {1 {bad option "bogus": must be authorizer, backup, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}}
do_test tcl-1.2.1 { do_test tcl-1.2.1 {
set v [catch {db cache bogus} msg] set v [catch {db cache bogus} msg]
lappend v $msg lappend v $msg

View File

@ -373,6 +373,7 @@ proc do_not_use_codec {} {
set ::do_not_use_codec 1 set ::do_not_use_codec 1
reset_db reset_db
} }
unset -nocomplain do_not_use_codec
# Return true if the "reserved_bytes" integer on database files is non-zero. # Return true if the "reserved_bytes" integer on database files is non-zero.
# #

233
test/trace3.test Normal file
View File

@ -0,0 +1,233 @@
# 2016 July 14
#
# 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 regression tests for SQLite library. The focus of
# this test file is the "sqlite3_trace_v2()" and "sqlite3_expanded_sql()"
# APIs.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !trace { finish_test ; return }
set ::testprefix trace3
proc trace_v2_error { args } {
lappend ::stmtlist(error) [string trim $args]
error "trace error"; # this will be ignored.
}
proc trace_v2_record { args } {
lappend ::stmtlist(record) [string trim $args]
}
proc trace_v2_nop { args } {}; # do nothing.
do_test trace3-1.0 {
execsql {
CREATE TABLE t1(a,b);
INSERT INTO t1 VALUES(1,NULL);
INSERT INTO t1 VALUES(2,-1);
INSERT INTO t1 VALUES(3,0);
INSERT INTO t1 VALUES(4,1);
INSERT INTO t1 VALUES(5,-2147483648);
INSERT INTO t1 VALUES(6,2147483647);
INSERT INTO t1 VALUES(7,-9223372036854775808);
INSERT INTO t1 VALUES(8,9223372036854775807);
INSERT INTO t1 VALUES(9,-1.0);
INSERT INTO t1 VALUES(10,0.0);
INSERT INTO t1 VALUES(11,1.0);
INSERT INTO t1 VALUES(12,'');
INSERT INTO t1 VALUES(13,'1');
INSERT INTO t1 VALUES(14,'one');
INSERT INTO t1 VALUES(15,x'abcd0123');
INSERT INTO t1 VALUES(16,x'4567cdef');
}
} {}
do_test trace3-1.1 {
set rc [catch {db trace_v2 1 2 3} msg]
lappend rc $msg
} {1 {wrong # args: should be "db trace_v2 ?CALLBACK? ?MASK?"}}
do_test trace3-1.2 {
set rc [catch {db trace_v2 1 bad} msg]
lappend rc $msg
} {1 {bad trace type "bad": must be statement, profile, row, or close}}
do_test trace3-2.1 {
db trace_v2 trace_v2_nop
db trace_v2
} {trace_v2_nop}
do_test trace3-3.1 {
unset -nocomplain ::stmtlist
db trace_v2 trace_v2_nop
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
array get ::stmtlist
} {}
do_test trace3-3.2 {
set ::stmtlist(error) {}
db trace_v2 trace_v2_error
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
set ::stmtlist(error)
} {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/}
do_test trace3-3.3 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
set ::stmtlist(record)
} {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/}
do_test trace3-3.4 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record statement
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
set ::stmtlist(record)
} {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/}
do_test trace3-3.5 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record 1
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
set ::stmtlist(record)
} {/^\{-?\d+ \{SELECT a, b FROM t1 ORDER BY a;\}\}$/}
do_test trace3-4.1 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record profile
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
set ::stmtlist(record)
} {/^\{-?\d+ -?\d+\}$/}
do_test trace3-4.2 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record 2
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
set ::stmtlist(record)
} {/^\{-?\d+ -?\d+\}$/}
do_test trace3-5.1 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record row
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
set ::stmtlist(record)
} "/^[string trim [string repeat {\d+ } 16]]\$/"
do_test trace3-5.2 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record 4
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
set ::stmtlist(record)
} "/^[string trim [string repeat {\d+ } 16]]\$/"
do_test trace3-6.1 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record {profile row}
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
set ::stmtlist(record)
} "/^[string trim [string repeat {-?\d+ } 16]] \\\{-?\\d+ -?\\d+\\\}\$/"
do_test trace3-6.2 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record {statement profile row}
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
set ::stmtlist(record)
} "/^\\\{-?\\d+ \\\{SELECT a, b FROM t1 ORDER BY a;\\\}\\\} [string trim \
[string repeat {-?\d+ } 16]] \\\{-?\\d+ -?\\d+\\\}\$/"
do_test trace3-7.1 {
set DB [sqlite3_connection_pointer db]
set STMT [sqlite3_prepare_v2 $DB \
"SELECT a, b FROM t1 WHERE b = ? ORDER BY a;" -1 TAIL]
} {/^[0-9A-Fa-f]+$/}
do_test trace3-8.1 {
list [sqlite3_bind_null $STMT 1] [sqlite3_expanded_sql $STMT]
} {{} {SELECT a, b FROM t1 WHERE b = NULL ORDER BY a;}}
do_test trace3-8.2 {
list [sqlite3_bind_int $STMT 1 123] [sqlite3_expanded_sql $STMT]
} {{} {SELECT a, b FROM t1 WHERE b = 123 ORDER BY a;}}
do_test trace3-8.3 {
list [sqlite3_bind_int64 $STMT 1 123] [sqlite3_expanded_sql $STMT]
} {{} {SELECT a, b FROM t1 WHERE b = 123 ORDER BY a;}}
do_test trace3-8.4 {
list [sqlite3_bind_text $STMT 1 "some string" 11] \
[sqlite3_expanded_sql $STMT]
} {{} {SELECT a, b FROM t1 WHERE b = 'some string' ORDER BY a;}}
do_test trace3-8.5 {
list [sqlite3_bind_text $STMT 1 "some 'bad' string" 17] \
[sqlite3_expanded_sql $STMT]
} {{} {SELECT a, b FROM t1 WHERE b = 'some ''bad'' string' ORDER BY a;}}
do_test trace3-8.6 {
list [sqlite3_bind_double $STMT 1 123] [sqlite3_expanded_sql $STMT]
} {{} {SELECT a, b FROM t1 WHERE b = 123.0 ORDER BY a;}}
do_test trace3-8.7 {
list [sqlite3_bind_text16 $STMT 1 \
[encoding convertto unicode hi\000yall\000] 16] \
[sqlite3_expanded_sql $STMT]
} {{} {SELECT a, b FROM t1 WHERE b = 'hi' ORDER BY a;}}
do_test trace3-8.8 {
list [sqlite3_bind_blob $STMT 1 "\x12\x34\x56" 3] \
[sqlite3_expanded_sql $STMT]
} {{} {SELECT a, b FROM t1 WHERE b = x'123456' ORDER BY a;}}
do_test trace3-8.9 {
list [sqlite3_bind_blob $STMT 1 "\xAB\xCD\xEF" 3] \
[sqlite3_expanded_sql $STMT]
} {{} {SELECT a, b FROM t1 WHERE b = x'abcdef' ORDER BY a;}}
do_test trace3-9.1 {
sqlite3_finalize $STMT
} {SQLITE_OK}
do_test trace3-10.1 {
db trace_v2 ""
db trace_v2
} {}
do_test trace3-10.2 {
unset -nocomplain ::stmtlist
db trace_v2 "" {statement profile row}
execsql {
SELECT a, b FROM t1 ORDER BY a;
}
array get ::stmtlist
} {}
do_test trace3-11.1 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record close
db close
set ::stmtlist(record)
} {/^-?\d+$/}
reset_db
do_test trace3-11.2 {
set ::stmtlist(record) {}
db trace_v2 trace_v2_record 8
db close
set ::stmtlist(record)
} {/^-?\d+$/}
finish_test

View File

@ -17,6 +17,12 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
set testprefix vacuummem set testprefix vacuummem
if {[permutation]=="memsubsys1"} {
finish_test
return
}
proc memory_used {} { proc memory_used {} {
set stat [sqlite3_status SQLITE_STATUS_MEMORY_USED 1] set stat [sqlite3_status SQLITE_STATUS_MEMORY_USED 1]
lindex $stat 1 lindex $stat 1
@ -35,20 +41,20 @@ do_execsql_test 1.0 {
CREATE INDEX t1b ON t1(b); CREATE INDEX t1b ON t1(b);
CREATE INDEX t1c ON t1(c); CREATE INDEX t1c ON t1(c);
} }
set ans "#/[memory_used]/"
do_test 1.1 { memory_used } {#/2300000/} do_test 1.1 { memory_used } $ans
do_execsql_test 1.2 VACUUM do_execsql_test 1.2 VACUUM
do_test 1.3 { memory_used } {#/2300000/} do_test 1.3 { memory_used } $ans
do_execsql_test 1.4 { do_execsql_test 1.4 {
SELECT count(*) FROM t1 WHERE +a IS NOT NULL SELECT count(*) FROM t1 WHERE +a IS NOT NULL
} {100000} } {100000}
do_test 1.5 { memory_used } {#/2300000/} do_test 1.5 { memory_used } $ans
finish_test finish_test

View File

@ -17,6 +17,7 @@ source $testdir/lock_common.tcl
source $testdir/wal_common.tcl source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return } ifcapable !wal {finish_test ; return }
set testprefix walcrash4 set testprefix walcrash4
do_not_use_codec
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# At one point, if "PRAGMA synchronous=full" is set and the platform # At one point, if "PRAGMA synchronous=full" is set and the platform

View File

@ -58,7 +58,7 @@ static char *readFile(const char *zFilename){
return z; return z;
} }
/* Change the C code in the argument to see if it might have /* Check the C code in the argument to see if it might have
** side effects. The only accurate way to know this is to do a full ** side effects. The only accurate way to know this is to do a full
** parse of the C code, which this routine does not do. This routine ** parse of the C code, which this routine does not do. This routine
** uses a simple heuristic of looking for: ** uses a simple heuristic of looking for: