1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-01 06:27:03 +03:00

Merge all recent trunk changes, especially the fix for

ticket [369d57fb8e5ccdff06f1], but also the skip-scan improvement and
performance improvements in the b-tree code.

FossilOrigin-Name: 0b9e2c3269695713b538561d999c68097db70f0c
This commit is contained in:
drh
2014-08-21 16:09:36 +00:00
22 changed files with 374 additions and 155 deletions

View File

@ -1 +1 @@
3.8.6 3.8.7

View File

@ -73,6 +73,7 @@ exec_prefix = @exec_prefix@
bindir = @bindir@ bindir = @bindir@
libdir = @libdir@ libdir = @libdir@
datarootdir = @datarootdir@
datadir = @datadir@ datadir = @datadir@
mandir = @mandir@ mandir = @mandir@
includedir = @includedir@ includedir = @includedir@

View File

@ -166,8 +166,10 @@ AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs])
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Redefine fdatasync as fsync on systems that lack fdatasync # Redefine fdatasync as fsync on systems that lack fdatasync
#-------------------------------------------------------------------- #--------------------------------------------------------------------
#
AC_CHECK_FUNC(fdatasync, , AC_DEFINE(fdatasync, fsync)) #AC_CHECK_FUNC(fdatasync, , AC_DEFINE(fdatasync, fsync))
# Check for library functions that SQLite can optionally use.
AC_CHECK_FUNCS([fdatasync usleep fullfsync localtime_r gmtime_r])
AC_FUNC_STRERROR_R AC_FUNC_STRERROR_R

View File

@ -1641,6 +1641,7 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
SHLIB_CFLAGS="-fPIC" SHLIB_CFLAGS="-fPIC"
SHLIB_LD="${CC} -shared" SHLIB_LD="${CC} -shared"
TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$[@]" TCL_SHLIB_LD_EXTRAS="-Wl,-soname=\$[@]"
TK_SHLIB_LD_EXTRAS="-Wl,-soname,\$[@]"
SHLIB_SUFFIX=".so" SHLIB_SUFFIX=".so"
LDFLAGS="" LDFLAGS=""
AS_IF([test $doRpath = yes], [ AS_IF([test $doRpath = yes], [
@ -1651,11 +1652,15 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
LIBS=`echo $LIBS | sed s/-pthread//` LIBS=`echo $LIBS | sed s/-pthread//`
CFLAGS="$CFLAGS $PTHREAD_CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LDFLAGS="$LDFLAGS $PTHREAD_LIBS"]) LDFLAGS="$LDFLAGS $PTHREAD_LIBS"])
# Version numbers are dot-stripped by system policy. case $system in
TCL_TRIM_DOTS=`echo ${PACKAGE_VERSION} | tr -d .` FreeBSD-3.*)
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' # Version numbers are dot-stripped by system policy.
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.so.1' TCL_TRIM_DOTS=`echo ${VERSION} | tr -d .`
TCL_LIB_VERSIONS_OK=nodots UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so'
TCL_LIB_VERSIONS_OK=nodots
;;
esac
;; ;;
Darwin-*) Darwin-*)
CFLAGS_OPTIMIZE="-Os" CFLAGS_OPTIMIZE="-Os"
@ -1826,8 +1831,8 @@ AC_DEFUN([TEA_CONFIG_CFLAGS], [
SHLIB_CFLAGS="-fPIC -melf" SHLIB_CFLAGS="-fPIC -melf"
LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
], [ ], [
SHLIB_CFLAGS="-Kpic -belf" SHLIB_CFLAGS="-Kpic -belf"
LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
]) ])
SHLIB_LD="ld -G" SHLIB_LD="ld -G"
SHLIB_LD_LIBS="" SHLIB_LD_LIBS=""
@ -4158,8 +4163,6 @@ AC_DEFUN([TEA_PATH_CELIB], [
fi fi
fi fi
]) ])
# Local Variables: # Local Variables:
# mode: autoconf # mode: autoconf
# End: # End:

18
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.8.6. # Generated by GNU Autoconf 2.62 for sqlite 3.8.7.
# #
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='sqlite' PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite' PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.8.6' PACKAGE_VERSION='3.8.7'
PACKAGE_STRING='sqlite 3.8.6' PACKAGE_STRING='sqlite 3.8.7'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
# Factoring default headers for most tests. # Factoring default headers for most tests.
@ -1483,7 +1483,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures sqlite 3.8.6 to adapt to many kinds of systems. \`configure' configures sqlite 3.8.7 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1548,7 +1548,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.8.6:";; short | recursive ) echo "Configuration of sqlite 3.8.7:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1664,7 +1664,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
sqlite configure 3.8.6 sqlite configure 3.8.7
generated by GNU Autoconf 2.62 generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@ -1678,7 +1678,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.8.6, which was It was created by sqlite $as_me 3.8.7, which was
generated by GNU Autoconf 2.62. Invocation command line was generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@ $ $0 $@
@ -14021,7 +14021,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by sqlite $as_me 3.8.6, which was This file was extended by sqlite $as_me 3.8.7, which was
generated by GNU Autoconf 2.62. Invocation command line was generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -14074,7 +14074,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\ ac_cs_version="\\
sqlite config.status 3.8.6 sqlite config.status 3.8.7
configured by $0, generated by GNU Autoconf 2.62, configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

81
ext/rtree/rtreeF.test Normal file
View File

@ -0,0 +1,81 @@
# 2014-08-21
#
# 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 contains tests for the r-tree module.
#
# This file contains test cases for the ticket
# [369d57fb8e5ccdff06f197a37147a88f9de95cda] (2014-08-21)
#
# The following SQL causes an assertion fault while running
# sqlite3_prepare() on the DELETE statement:
#
# CREATE TABLE t1(x);
# CREATE TABLE t2(y);
# CREATE VIRTUAL TABLE t3 USING rtree(a,b,c);
# CREATE TRIGGER t2del AFTER DELETE ON t2 WHEN (SELECT 1 from t1) BEGIN
# DELETE FROM t3 WHERE a=old.y;
# END;
# DELETE FROM t2 WHERE y=1;
#
if {![info exists testdir]} {
set testdir [file join [file dirname [info script]] .. .. test]
}
source $testdir/tester.tcl
ifcapable !rtree { finish_test ; return }
do_execsql_test rtreeF-1.1 {
CREATE TABLE t1(x);
CREATE TABLE t2(y);
CREATE VIRTUAL TABLE t3 USING rtree(a,b,c);
CREATE TRIGGER t2dwl AFTER DELETE ON t2 WHEN (SELECT 1 from t1) BEGIN
DELETE FROM t3 WHERE a=old.y;
END;
INSERT INTO t1(x) VALUES(999);
INSERT INTO t2(y) VALUES(1),(2),(3),(4),(5);
INSERT INTO t3(a,b,c) VALUES(1,2,3),(2,3,4),(3,4,5),(4,5,6),(5,6,7);
SELECT a FROM t3 ORDER BY a;
SELECT '|';
SELECT y FROM t2 ORDER BY y;
} {1 2 3 4 5 | 1 2 3 4 5}
do_execsql_test rtreeF-1.2 {
DELETE FROM t2 WHERE y=3;
SELECT a FROM t3 ORDER BY a;
SELECT '|';
SELECT y FROM t2 ORDER BY y;
} {1 2 4 5 | 1 2 4 5}
do_execsql_test rtreeF-1.3 {
DELETE FROM t1;
DELETE FROM t2 WHERE y=5;
SELECT a FROM t3 ORDER BY a;
SELECT '|';
SELECT y FROM t2 ORDER BY y;
} {1 2 4 5 | 1 2 4}
do_execsql_test rtreeF-1.4 {
INSERT INTO t1 DEFAULT VALUES;
DELETE FROM t2 WHERE y=5;
SELECT a FROM t3 ORDER BY a;
SELECT '|';
SELECT y FROM t2 ORDER BY y;
} {1 2 4 5 | 1 2 4}
do_execsql_test rtreeF-1.5 {
DELETE FROM t2 WHERE y=2;
SELECT a FROM t3 ORDER BY a;
SELECT '|';
SELECT y FROM t2 ORDER BY y;
} {1 4 5 | 1 4}
finish_test

View File

@ -1,12 +1,12 @@
C Disable\sthe\shook-7.5.2\stests\swhen\susing\ssessions,\ssince\sthat\sare\snot\scorrect\nin\sthat\scase. C Merge\sall\srecent\strunk\schanges,\sespecially\sthe\sfix\sfor\nticket\s[369d57fb8e5ccdff06f1],\sbut\salso\sthe\sskip-scan\simprovement\sand\nperformance\simprovements\sin\sthe\sb-tree\scode.
D 2014-08-19T00:33:22.234 D 2014-08-21T16:09:36.975
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in d5ad373b7a23525414b8843b3084cf90c560d92f F Makefile.in d5ad373b7a23525414b8843b3084cf90c560d92f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc f1bbf555916b6e60887d86cea62f27e6a26cdb24 F Makefile.msc f1bbf555916b6e60887d86cea62f27e6a26cdb24
F Makefile.vxworks 034289efa9d591b04b1a73598623119c306cbba0 F Makefile.vxworks 034289efa9d591b04b1a73598623119c306cbba0
F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8 F README.md 64f270c43c38c46de749e419c22f0ae2f4499fe8
F VERSION 1c877615a9db323e3cd301e3d57d853f9d5c4a07 F VERSION 53a0b870e7f16d3b06623c31d233a304c163a6af
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811 F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@ -23,22 +23,22 @@ F autoconf/depcomp 0b26f101e3bc9fd1ff0be1da9fb4a82371142f92 x
F autoconf/install-sh 06ee6336e63bb845c8439d777c32eb2eccc4fbf1 x F autoconf/install-sh 06ee6336e63bb845c8439d777c32eb2eccc4fbf1 x
F autoconf/ltmain.sh 7a658a24028f02331c1d2446562758083c5eadd1 F autoconf/ltmain.sh 7a658a24028f02331c1d2446562758083c5eadd1
F autoconf/missing d7c9981a81af13370d4ed152b24c0a82b7028585 x F autoconf/missing d7c9981a81af13370d4ed152b24c0a82b7028585 x
F autoconf/tea/Makefile.in 5c3b0bdfb66c20d55ebff59d1718864461570ca9 F autoconf/tea/Makefile.in d55bcc63832caf0309c2ff80358756116618cfca
F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873
F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43
F autoconf/tea/configure.in e0466b881b53f31f5a4a69e7a91ad130902fb359 F autoconf/tea/configure.in 93d43c79e936fb16556e22498177d7e8571efa04
F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb
F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523
F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d
F autoconf/tea/tclconfig/install-sh bdd5e293591621ae60d9824d86a4b1c5f22c3d00 F autoconf/tea/tclconfig/install-sh bdd5e293591621ae60d9824d86a4b1c5f22c3d00
F autoconf/tea/tclconfig/tcl.m4 f035b86539a5ab30689e997a11ae9e7fd2e65570 F autoconf/tea/tclconfig/tcl.m4 66ddf0a5d5e4b1d29bff472c0985fd7fa89d0fb5
F autoconf/tea/win/makefile.vc f89d0184d0eee5f7e356ea407964dcd139939928 F autoconf/tea/win/makefile.vc f89d0184d0eee5f7e356ea407964dcd139939928
F autoconf/tea/win/nmakehlp.c 2070e086f39866b353a482d3a14dedaf26196506 F autoconf/tea/win/nmakehlp.c 2070e086f39866b353a482d3a14dedaf26196506
F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure 513f1e2464c3673bcdb5471b13d98e7eeb6f5ca2 x F configure ad59a5f48b3c59a92b5506040a22fbe3f733a9d8 x
F configure.ac 4cf9f60785143fa141b10962ccc885d973792e9a F configure.ac 4cf9f60785143fa141b10962ccc885d973792e9a
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1
@ -138,6 +138,7 @@ F ext/rtree/rtreeB.test c85f9ce78766c4e68b8b89fbf2979ee9cfa82b4e
F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06 F ext/rtree/rtreeC.test df158dcc81f1a43ce7eef361af03c48ec91f1e06
F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca F ext/rtree/rtreeD.test 636630357638f5983701550b37f0f5867130d2ca
F ext/rtree/rtreeE.test 388c1c8602c3ce55c15f03b509e9cf545fb7c41f F ext/rtree/rtreeE.test 388c1c8602c3ce55c15f03b509e9cf545fb7c41f
F ext/rtree/rtreeF.test 66deb9fd1611c7ca2e374adba63debdc2dbb12b4
F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195
F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd F ext/rtree/sqlite3rtree.h 83349d519fe5f518b3ea025d18dd1fe51b1684bd
@ -183,7 +184,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c fa057e30794bfd867963b44a3a42710a45c335a1 F src/btree.c 4195fed5741b4dbcc9831b623aec487258f3e62d
F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a
F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
F src/build.c 5abf794fe8a605f2005b422e98a3cedad9b9ef5b F src/build.c 5abf794fe8a605f2005b422e98a3cedad9b9ef5b
@ -191,7 +192,7 @@ F src/callback.c fcff28cf0df2403dd2f313bb8d1b8f31f6f3cd64
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c 50b74c1dde25d1ebcb4fa5c870762e6470ee46f1 F src/delete.c cb7a757eb829ebb046c66f6399435c6636fe1314
F src/expr.c f749009cf4a8534efb5e0d5cd7c9fb1fb0f2836c F src/expr.c f749009cf4a8534efb5e0d5cd7c9fb1fb0f2836c
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 8545f3b36da47473e10800ea4fb0810fd4062514 F src/fkey.c 8545f3b36da47473e10800ea4fb0810fd4062514
@ -200,7 +201,7 @@ F src/global.c 1e4bd956dc2f608f87d2a929abc4a20db65f30e4
F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c b1f57e168d39fed8a0d3d891bf38091b104dd707 F src/insert.c 3d41db1398a5863c4a1c064d2082d0dc43274628
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c febc2a9e7ad6c1a6191c7b5b9170b325d263f343 F src/legacy.c febc2a9e7ad6c1a6191c7b5b9170b325d263f343
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
@ -239,7 +240,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 0ea356d32a5e884add23d1b9b4e8736681dd5697 F src/resolve.c 0ea356d32a5e884add23d1b9b4e8736681dd5697
F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
F src/select.c ea48e891406ccdf748f3eb02893e056d134a0fea F src/select.c ea48e891406ccdf748f3eb02893e056d134a0fea
F src/shell.c 220564b70a2115e2157688f8faa6bb751ffe019a F src/shell.c 34be9dc9e7b96081488acebecae6cd92632397a6
F src/sqlite.h.in 021a1f5c50e83060675d994a6014fd409e611d9e F src/sqlite.h.in 021a1f5c50e83060675d994a6014fd409e611d9e
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
@ -247,7 +248,7 @@ F src/sqliteInt.h d60dbbadfd64374a5a2f362fc6f45899540c2c8e
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 7ada527ce7916adcabad7997c10f09680aac7c9b F src/tclsqlite.c 30d8f4ba516061832cfe10d7c71d84e17bff1918
F src/test1.c 14409a611e9c27c6c522c610bbff5561f05c1558 F src/test1.c 14409a611e9c27c6c522c610bbff5561f05c1558
F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712 F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
@ -268,8 +269,8 @@ F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f
F src/test_func.c d3013ce36f19ac72a99c73864930fd1fa41832f8 F src/test_func.c d3013ce36f19ac72a99c73864930fd1fa41832f8
F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd
F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32
F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61 F src/test_intarray.c db4614c2262a06abc4409dc048d59c580c38320f
F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d F src/test_intarray.h 9dc57417fb65bc7835cc18548852cc08cc062202
F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64
F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4 F src/test_loadext.c a5251f956ab6af21e138dc1f9c0399394a510cb4
F src/test_malloc.c 1ff5b1243d96124c9a180f3b89424820a1f337f3 F src/test_malloc.c 1ff5b1243d96124c9a180f3b89424820a1f337f3
@ -302,7 +303,7 @@ F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c ff9bec31cc128e98d852ebee6e5d4e160846e0c5 F src/vdbe.c ff9bec31cc128e98d852ebee6e5d4e160846e0c5
F src/vdbe.h ca3b6df299adce6e2f499c57e42ae54f142ae823 F src/vdbe.h ca3b6df299adce6e2f499c57e42ae54f142ae823
F src/vdbeInt.h 5eee1752eff410de9373196e2b327f7deefb3920 F src/vdbeInt.h 5eee1752eff410de9373196e2b327f7deefb3920
F src/vdbeapi.c 52335de5ff97bba93d6779d8df87feab5d53d7df F src/vdbeapi.c 11d97cd50ca78f6c6ce796d0c78913ef27f5383d
F src/vdbeaux.c 22aabbdea2394cea26e35b2190fa9111e4bc18c2 F src/vdbeaux.c 22aabbdea2394cea26e35b2190fa9111e4bc18c2
F src/vdbeblob.c d7c232d1c6afc7ee1176c38b7d81b2e17af15ceb F src/vdbeblob.c d7c232d1c6afc7ee1176c38b7d81b2e17af15ceb
F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394 F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394
@ -312,7 +313,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
F src/where.c ab20f9c24a422ee8900831b343c3d1e5e7aca87b F src/where.c 4c499d185827a492643cf017ae5e3aa0523f9f18
F src/whereInt.h 923820bee9726033a501a08d2fc69b9c1ee4feb3 F src/whereInt.h 923820bee9726033a501a08d2fc69b9c1ee4feb3
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@ -718,7 +719,7 @@ F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e
F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
F test/memdb.test fcb5297b321b562084fc79d64d5a12a1cd2b639b F test/memdb.test fcb5297b321b562084fc79d64d5a12a1cd2b639b
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test f97cfd0b30e85c2f1ed16d642e7ac58006be84b2 F test/memsubsys1.test bf270964ab83bc2da5927960f78304a866fb9a9d
F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9 F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
@ -849,6 +850,7 @@ F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
F test/skipscan1.test 28c7faa41a0d7265040ecb0a0abd90c0904270b2 F test/skipscan1.test 28c7faa41a0d7265040ecb0a0abd90c0904270b2
F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a
F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5
F test/skipscan5.test d8b9692b702745a0e41c23f9da6beac81df01196 F test/skipscan5.test d8b9692b702745a0e41c23f9da6beac81df01196
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24 F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
@ -1034,7 +1036,7 @@ F test/tkt3997.test a335fa41ca3985660a139df7b734a26ef53284bd
F test/tkt4018.test 7c2c9ba4df489c676a0a7a0e809a1fb9b2185bd1 F test/tkt4018.test 7c2c9ba4df489c676a0a7a0e809a1fb9b2185bd1
F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7 F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4 F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
F test/trace.test 4b36a41a3e9c7842151af6da5998f5080cdad9e5 F test/trace.test 73a5508100f7fccfbc3f8018d5f6963ed478eea0
F test/trace2.test 93b47ca6996c66b47f57224cfb146f34e07df382 F test/trace2.test 93b47ca6996c66b47f57224cfb146f34e07df382
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
@ -1165,7 +1167,7 @@ F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/lemon.c 3ff0fec22f92dfb54e62eeb48772eddffdbeb0d6 F tool/lemon.c 3ff0fec22f92dfb54e62eeb48772eddffdbeb0d6
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6
F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383 F tool/mkautoconfamal.sh 5dc5010e2e748a9e1bba67baca5956a2c2deda7b
F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670 F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkpragmatab.tcl 78a77b2c554d534c6f2dc903130186ed15715460 F tool/mkpragmatab.tcl 78a77b2c554d534c6f2dc903130186ed15715460
@ -1181,7 +1183,7 @@ F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b
F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5
F tool/showdb.c b9ee6b6c81a094bf33badbf7e9da34cdbc0cce25 F tool/showdb.c bd073a78bce714a0e42d92ea474b3eb8cb53be5d
F tool/showjournal.c 053eb1cc774710c6890b7dd6293300cc297b16a5 F tool/showjournal.c 053eb1cc774710c6890b7dd6293300cc297b16a5
F tool/showstat4.c c39279d6bd37cb999b634f0064f6f86ad7af008f F tool/showstat4.c c39279d6bd37cb999b634f0064f6f86ad7af008f
F tool/showwal.c 3209120269cdf9380f091459e47b776b4f81dfd3 F tool/showwal.c 3209120269cdf9380f091459e47b776b4f81dfd3
@ -1203,7 +1205,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P b69f7dd1f35846c3bb9f4f160d50c4f03796f887 P 6d5b9332e8d8bb572ac98b0f4e47e59ad12aac26 7029b3404d3f5f698a496934f3a3f2972051b257
R 8c550f2382b76c35956caff857ef2faa R a953db417f3d0f990497f5e1512b276c
U drh U drh
Z 2eb508c95168b21e7a389265ba7bb22f Z d706f9a9d70b2e75b205ef1091dd3b5f

View File

@ -1 +1 @@
6d5b9332e8d8bb572ac98b0f4e47e59ad12aac26 0b9e2c3269695713b538561d999c68097db70f0c

View File

@ -1197,7 +1197,6 @@ static int defragmentPage(MemPage *pPage){
static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */
u8 * const data = pPage->aData; /* Local cache of pPage->aData */ u8 * const data = pPage->aData; /* Local cache of pPage->aData */
int nFrag; /* Number of fragmented bytes on pPage */
int top; /* First byte of cell content area */ int top; /* First byte of cell content area */
int gap; /* First byte of gap between cell pointers and cell content */ int gap; /* First byte of gap between cell pointers and cell content */
int rc; /* Integer return code */ int rc; /* Integer return code */
@ -1212,25 +1211,26 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
usableSize = pPage->pBt->usableSize; usableSize = pPage->pBt->usableSize;
assert( nByte < usableSize-8 ); assert( nByte < usableSize-8 );
nFrag = data[hdr+7];
assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
gap = pPage->cellOffset + 2*pPage->nCell; gap = pPage->cellOffset + 2*pPage->nCell;
top = get2byteNotZero(&data[hdr+5]); assert( gap<=65536 );
if( gap>top ) return SQLITE_CORRUPT_BKPT; top = get2byte(&data[hdr+5]);
if( gap>top ){
if( top==0 ){
top = 65536;
}else{
return SQLITE_CORRUPT_BKPT;
}
}
/* If there is enough space between gap and top for one more cell pointer
** array entry offset, and if the freelist is not empty, then search the
** freelist looking for a free slot big enough to satisfy the request.
*/
testcase( gap+2==top ); testcase( gap+2==top );
testcase( gap+1==top ); testcase( gap+1==top );
testcase( gap==top ); testcase( gap==top );
if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){
if( nFrag>=60 ){
/* Always defragment highly fragmented pages */
rc = defragmentPage(pPage);
if( rc ) return rc;
top = get2byteNotZero(&data[hdr+5]);
}else if( gap+2<=top ){
/* Search the freelist looking for a free slot big enough to satisfy
** the request. The allocation is made from the first free slot in
** the list that is large enough to accommodate it.
*/
int pc, addr; int pc, addr;
for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){ for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
int size; /* Size of the free slot */ int size; /* Size of the free slot */
@ -1243,10 +1243,11 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
testcase( x==4 ); testcase( x==4 );
testcase( x==3 ); testcase( x==3 );
if( x<4 ){ if( x<4 ){
if( data[hdr+7]>=60 ) goto defragment_page;
/* Remove the slot from the free-list. Update the number of /* Remove the slot from the free-list. Update the number of
** fragmented bytes within the page. */ ** fragmented bytes within the page. */
memcpy(&data[addr], &data[pc], 2); memcpy(&data[addr], &data[pc], 2);
data[hdr+7] = (u8)(nFrag + x); data[hdr+7] += (u8)x;
}else if( size+pc > usableSize ){ }else if( size+pc > usableSize ){
return SQLITE_CORRUPT_BKPT; return SQLITE_CORRUPT_BKPT;
}else{ }else{
@ -1260,11 +1261,13 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
} }
} }
/* Check to make sure there is enough space in the gap to satisfy /* The request could not be fulfilled using a freelist slot. Check
** the allocation. If not, defragment. ** to see if defragmentation is necessary.
*/ */
testcase( gap+2+nByte==top ); testcase( gap+2+nByte==top );
if( gap+2+nByte>top ){ if( gap+2+nByte>top ){
defragment_page:
testcase( pPage->nCell==0 );
rc = defragmentPage(pPage); rc = defragmentPage(pPage);
if( rc ) return rc; if( rc ) return rc;
top = get2byteNotZero(&data[hdr+5]); top = get2byteNotZero(&data[hdr+5]);
@ -1287,90 +1290,100 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
/* /*
** Return a section of the pPage->aData to the freelist. ** Return a section of the pPage->aData to the freelist.
** The first byte of the new free block is pPage->aDisk[start] ** The first byte of the new free block is pPage->aData[iStart]
** and the size of the block is "size" bytes. ** and the size of the block is iSize bytes.
** **
** Most of the effort here is involved in coalesing adjacent ** Adjacent freeblocks are coalesced.
** free blocks into a single big free block. **
** Note that even though the freeblock list was checked by btreeInitPage(),
** that routine will not detect overlap between cells or freeblocks. Nor
** does it detect cells or freeblocks that encrouch into the reserved bytes
** at the end of the page. So do additional corruption checks inside this
** routine and return SQLITE_CORRUPT if any problems are found.
*/ */
static int freeSpace(MemPage *pPage, int start, int size){ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
int addr, pbegin, hdr; u16 iPtr; /* Address of pointer to next freeblock */
int iLast; /* Largest possible freeblock offset */ u16 iFreeBlk; /* Address of the next freeblock */
unsigned char *data = pPage->aData; u8 hdr; /* Page header size. 0 or 100 */
u8 nFrag = 0; /* Reduction in fragmentation */
u16 iOrigSize = iSize; /* Original value of iSize */
u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
unsigned char *data = pPage->aData; /* Page content */
assert( pPage->pBt!=0 ); assert( pPage->pBt!=0 );
assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( sqlite3PagerIswriteable(pPage->pDbPage) );
assert( start>=pPage->hdrOffset+6+pPage->childPtrSize ); assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
assert( (start + size) <= (int)pPage->pBt->usableSize ); assert( iEnd <= pPage->pBt->usableSize );
assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) );
assert( size>=0 ); /* Minimum cell size is 4 */ assert( iSize>=4 ); /* Minimum cell size is 4 */
assert( iStart<=iLast );
/* Overwrite deleted information with zeros when the secure_delete
** option is enabled */
if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){ if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){
/* Overwrite deleted information with zeros when the secure_delete memset(&data[iStart], 0, iSize);
** option is enabled */
memset(&data[start], 0, size);
} }
/* Add the space back into the linked list of freeblocks. Note that /* The list of freeblocks must be in ascending order. Find the
** even though the freeblock list was checked by btreeInitPage(), ** spot on the list where iStart should be inserted.
** btreeInitPage() did not detect overlapping cells or
** freeblocks that overlapped cells. Nor does it detect when the
** cell content area exceeds the value in the page header. If these
** situations arise, then subsequent insert operations might corrupt
** the freelist. So we do need to check for corruption while scanning
** the freelist.
*/ */
hdr = pPage->hdrOffset; hdr = pPage->hdrOffset;
addr = hdr + 1; iPtr = hdr + 1;
iLast = pPage->pBt->usableSize - 4; if( data[iPtr+1]==0 && data[iPtr]==0 ){
assert( start<=iLast ); iFreeBlk = 0; /* Shortcut for the case when the freelist is empty */
while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){ }else{
if( pbegin<addr+4 ){ while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlk<iStart ){
return SQLITE_CORRUPT_BKPT; if( iFreeBlk<iPtr+4 ) return SQLITE_CORRUPT_BKPT;
iPtr = iFreeBlk;
} }
addr = pbegin; if( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT;
} assert( iFreeBlk>iPtr || iFreeBlk==0 );
if( pbegin>iLast ){
return SQLITE_CORRUPT_BKPT; /* At this point:
} ** iFreeBlk: First freeblock after iStart, or zero if none
assert( pbegin>addr || pbegin==0 ); ** iPtr: The address of a pointer iFreeBlk
put2byte(&data[addr], start); **
put2byte(&data[start], pbegin); ** Check to see if iFreeBlk should be coalesced onto the end of iStart.
put2byte(&data[start+2], size); */
pPage->nFree = pPage->nFree + (u16)size; if( iFreeBlk && iEnd+3>=iFreeBlk ){
nFrag = iFreeBlk - iEnd;
/* Coalesce adjacent free blocks */ if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT;
addr = hdr + 1; iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
while( (pbegin = get2byte(&data[addr]))>0 ){ iSize = iEnd - iStart;
int pnext, psize, x; iFreeBlk = get2byte(&data[iFreeBlk]);
assert( pbegin>addr ); }
assert( pbegin <= (int)pPage->pBt->usableSize-4 );
pnext = get2byte(&data[pbegin]); /* If iPtr is another freeblock (that is, if iPtr is not the freelist pointer
psize = get2byte(&data[pbegin+2]); ** in the page header) then check to see if iStart should be coalesced
if( pbegin + psize + 3 >= pnext && pnext>0 ){ ** onto the end of iPtr.
int frag = pnext - (pbegin+psize); */
if( (frag<0) || (frag>(int)data[hdr+7]) ){ if( iPtr>hdr+1 ){
return SQLITE_CORRUPT_BKPT; int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
if( iPtrEnd+3>=iStart ){
if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
nFrag += iStart - iPtrEnd;
iSize = iEnd - iPtr;
iStart = iPtr;
} }
data[hdr+7] -= (u8)frag;
x = get2byte(&data[pnext]);
put2byte(&data[pbegin], x);
x = pnext + get2byte(&data[pnext+2]) - pbegin;
put2byte(&data[pbegin+2], x);
}else{
addr = pbegin;
} }
if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT;
data[hdr+7] -= nFrag;
} }
if( iStart==get2byte(&data[hdr+5]) ){
/* If the cell content area begins with a freeblock, remove it. */ /* The new freeblock is at the beginning of the cell content area,
if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){ ** so just extend the cell content area rather than create another
int top; ** freelist entry */
pbegin = get2byte(&data[hdr+1]); if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT;
memcpy(&data[hdr+1], &data[pbegin], 2); put2byte(&data[hdr+1], iFreeBlk);
top = get2byte(&data[hdr+5]) + get2byte(&data[pbegin+2]); put2byte(&data[hdr+5], iEnd);
put2byte(&data[hdr+5], top); }else{
/* Insert the new freeblock into the freelist */
put2byte(&data[iPtr], iStart);
put2byte(&data[iStart], iFreeBlk);
put2byte(&data[iStart+2], iSize);
} }
assert( sqlite3PagerIswriteable(pPage->pDbPage) ); pPage->nFree += iOrigSize;
return SQLITE_OK; return SQLITE_OK;
} }

View File

@ -473,10 +473,11 @@ void sqlite3DeleteFrom(
** triggers. ** triggers.
*/ */
if( !isView ){ if( !isView ){
testcase( IsVirtual(pTab) );
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen, sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
&iDataCur, &iIdxCur); &iDataCur, &iIdxCur);
assert( pPk || iDataCur==iTabCur ); assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
assert( pPk || iIdxCur==iDataCur+1 ); assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
} }
/* Set up a loop over the rowids/primary-keys that were found in the /* Set up a loop over the rowids/primary-keys that were found in the
@ -484,7 +485,8 @@ void sqlite3DeleteFrom(
*/ */
if( okOnePass ){ if( okOnePass ){
/* Just one row. Hence the top-of-loop is a no-op */ /* Just one row. Hence the top-of-loop is a no-op */
assert( nKey==nPk ); /* OP_Found will use an unpacked key */ assert( nKey==nPk ); /* OP_Found will use an unpacked key */
assert( !IsVirtual(pTab) );
if( aToOpen[iDataCur-iTabCur] ){ if( aToOpen[iDataCur-iTabCur] ){
assert( pPk!=0 ); assert( pPk!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);

View File

@ -1624,6 +1624,9 @@ void sqlite3CompleteInsertion(
** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range ** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range
** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the ** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the
** pTab->pIndex list. ** pTab->pIndex list.
**
** If pTab is a virtual table, then this routine is a no-op and the
** *piDataCur and *piIdxCur values are left uninitialized.
*/ */
int sqlite3OpenTableAndIndices( int sqlite3OpenTableAndIndices(
Parse *pParse, /* Parsing context */ Parse *pParse, /* Parsing context */
@ -1642,9 +1645,9 @@ int sqlite3OpenTableAndIndices(
assert( op==OP_OpenRead || op==OP_OpenWrite ); assert( op==OP_OpenRead || op==OP_OpenWrite );
if( IsVirtual(pTab) ){ if( IsVirtual(pTab) ){
assert( aToOpen==0 ); /* This routine is a no-op for virtual tables. Leave the output
*piDataCur = 0; ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
*piIdxCur = 1; ** can detect if they are used by mistake in the caller. */
return 0; return 0;
} }
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);

View File

@ -1988,7 +1988,11 @@ static FILE *output_file_open(const char *zFile){
*/ */
static void sql_trace_callback(void *pArg, const char *z){ static void sql_trace_callback(void *pArg, const char *z){
FILE *f = (FILE*)pArg; FILE *f = (FILE*)pArg;
if( f ) fprintf(f, "%s\n", z); if( f ){
int i = (int)strlen(z);
while( i>0 && z[i-1]==';' ){ i--; }
fprintf(f, "%.*s;\n", i, z);
}
} }
/* /*
@ -2600,7 +2604,7 @@ static int do_meta_command(char *zLine, ShellState *p){
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_master UNION ALL" " FROM sqlite_master UNION ALL"
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
"WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
"ORDER BY rowid", "ORDER BY rowid",
callback, &data, &zErrMsg callback, &data, &zErrMsg
); );
@ -3155,7 +3159,7 @@ static int do_meta_command(char *zLine, ShellState *p){
" (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x" " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_master UNION ALL" " FROM sqlite_master UNION ALL"
" SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) " " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
"WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
"ORDER BY rowid", "ORDER BY rowid",
callback, &data, &zErrMsg callback, &data, &zErrMsg
); );

View File

@ -2466,7 +2466,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
if( rc==TCL_OK ){ if( rc==TCL_OK ){
rc = createIncrblobChannel( rc = createIncrblobChannel(
interp, pDb, zDb, zTable, zColumn, iRow, isReadonly interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly
); );
} }
#endif #endif

View File

@ -216,7 +216,7 @@ static sqlite3_module intarrayModule = {
** explicitly by the application, the virtual table will be dropped implicitly ** explicitly by the application, the virtual table will be dropped implicitly
** by the system when the database connection is closed. ** by the system when the database connection is closed.
*/ */
int sqlite3_intarray_create( SQLITE_API int sqlite3_intarray_create(
sqlite3 *db, sqlite3 *db,
const char *zName, const char *zName,
sqlite3_intarray **ppReturn sqlite3_intarray **ppReturn
@ -250,7 +250,7 @@ int sqlite3_intarray_create(
** any query against the corresponding virtual table. If the integer ** any query against the corresponding virtual table. If the integer
** array does change or is deallocated undefined behavior will result. ** array does change or is deallocated undefined behavior will result.
*/ */
int sqlite3_intarray_bind( SQLITE_API int sqlite3_intarray_bind(
sqlite3_intarray *pIntArray, /* The intarray object to bind to */ sqlite3_intarray *pIntArray, /* The intarray object to bind to */
int nElements, /* Number of elements in the intarray */ int nElements, /* Number of elements in the intarray */
sqlite3_int64 *aElements, /* Content of the intarray */ sqlite3_int64 *aElements, /* Content of the intarray */

View File

@ -102,7 +102,7 @@ typedef struct sqlite3_intarray sqlite3_intarray;
** explicitly by the application, the virtual table will be dropped implicitly ** explicitly by the application, the virtual table will be dropped implicitly
** by the system when the database connection is closed. ** by the system when the database connection is closed.
*/ */
int sqlite3_intarray_create( SQLITE_API int sqlite3_intarray_create(
sqlite3 *db, sqlite3 *db,
const char *zName, const char *zName,
sqlite3_intarray **ppReturn sqlite3_intarray **ppReturn
@ -115,7 +115,7 @@ int sqlite3_intarray_create(
** any query against the corresponding virtual table. If the integer ** any query against the corresponding virtual table. If the integer
** array does change or is deallocated undefined behavior will result. ** array does change or is deallocated undefined behavior will result.
*/ */
int sqlite3_intarray_bind( SQLITE_API int sqlite3_intarray_bind(
sqlite3_intarray *pIntArray, /* The intarray object to bind to */ sqlite3_intarray *pIntArray, /* The intarray object to bind to */
int nElements, /* Number of elements in the intarray */ int nElements, /* Number of elements in the intarray */
sqlite3_int64 *aElements, /* Content of the intarray */ sqlite3_int64 *aElements, /* Content of the intarray */

View File

@ -513,10 +513,12 @@ int sqlite3_step(sqlite3_stmt *pStmt){
sqlite3_mutex_enter(db->mutex); sqlite3_mutex_enter(db->mutex);
v->doingRerun = 0; v->doingRerun = 0;
while( (rc = sqlite3Step(v))==SQLITE_SCHEMA while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
&& cnt++ < SQLITE_MAX_SCHEMA_RETRY && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
&& (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){ int savedPc = v->pc;
rc2 = rc = sqlite3Reprepare(v);
if( rc!=SQLITE_OK) break;
sqlite3_reset(pStmt); sqlite3_reset(pStmt);
v->doingRerun = 1; if( savedPc>=0 ) v->doingRerun = 1;
assert( v->expired==0 ); assert( v->expired==0 );
} }
if( rc2!=SQLITE_OK ){ if( rc2!=SQLITE_OK ){

View File

@ -3781,8 +3781,8 @@ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
sqlite3DebugPrintf(" %12s", sqlite3DebugPrintf(" %12s",
pItem->zAlias ? pItem->zAlias : pTab->zName); pItem->zAlias ? pItem->zAlias : pTab->zName);
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
const char *zName; const char *zName;
if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){ if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
int i = sqlite3Strlen30(zName) - 1; int i = sqlite3Strlen30(zName) - 1;
while( zName[i]!='_' ) i--; while( zName[i]!='_' ) i--;
@ -3803,7 +3803,11 @@ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
sqlite3DebugPrintf(" %-19s", z); sqlite3DebugPrintf(" %-19s", z);
sqlite3_free(z); sqlite3_free(z);
} }
sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm); if( p->wsFlags & WHERE_SKIPSCAN ){
sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->u.btree.nSkip);
}else{
sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
}
sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
#ifdef SQLITE_ENABLE_TREE_EXPLAIN #ifdef SQLITE_ENABLE_TREE_EXPLAIN
/* If the 0x100 bit of wheretracing is set, then show all of the constraint /* If the 0x100 bit of wheretracing is set, then show all of the constraint
@ -4316,8 +4320,7 @@ static int whereLoopAddBtreeIndex(
** On the other hand, the extra seeks could end up being significantly ** On the other hand, the extra seeks could end up being significantly
** more expensive. */ ** more expensive. */
assert( 42==sqlite3LogEst(18) ); assert( 42==sqlite3LogEst(18) );
if( pTerm==0 if( saved_nEq==saved_nSkip
&& saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol && saved_nEq+1<pProbe->nKeyCol
&& pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */ && pProbe->aiRowLogEst[saved_nEq+1]>=42 /* TUNING: Minimum for skip-scan */
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
@ -4328,9 +4331,17 @@ static int whereLoopAddBtreeIndex(
pNew->aLTerm[pNew->nLTerm++] = 0; pNew->aLTerm[pNew->nLTerm++] = 0;
pNew->wsFlags |= WHERE_SKIPSCAN; pNew->wsFlags |= WHERE_SKIPSCAN;
nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1]; nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
if( pTerm ){
/* TUNING: When estimating skip-scan for a term that is also indexable,
** increase the cost of the skip-scan by 2x, to make it a little less
** desirable than the regular index lookup. */
nIter += 10; assert( 10==sqlite3LogEst(2) );
}
pNew->nOut -= nIter; pNew->nOut -= nIter;
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
pNew->nOut = saved_nOut; pNew->nOut = saved_nOut;
pNew->u.btree.nEq = saved_nEq;
pNew->u.btree.nSkip = saved_nSkip;
} }
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */ u16 eOp = pTerm->eOperator; /* Shorthand for pTerm->eOperator */

View File

@ -124,7 +124,13 @@ do_test memsubsys1-3.1.3 {
} 0 } 0
do_test memsubsys1-3.1.4 { do_test memsubsys1-3.1.4 {
set overflow [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2] set overflow [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
} $max_pagecache # Note: The measured PAGECACHE_OVERFLOW is amount malloc() returns, not what
# was requested. System malloc() implementations might (arbitrarily) return
# slightly different oversize buffers, which can result in slightly different
# PAGECACHE_OVERFLOW sizes between consecutive runs. So we cannot do an
# exact comparison. Simply verify that the amount is within 5%.
expr {$overflow>=$max_pagecache*0.95 && $overflow<=$max_pagecache*1.05}
} 1
do_test memsubsys1-3.1.5 { do_test memsubsys1-3.1.5 {
set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2] set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
} 0 } 0

73
test/skipscan3.test Normal file
View File

@ -0,0 +1,73 @@
# 2014-08-20
#
# 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 tests of the "skip-scan" query strategy.
# In particular, this file looks at skipping intermediate terms
# in an index. For example, if (a,b,c) are indexed, and we have
# "WHERE a=?1 AND c=?2" - verify that skip-scan can still be used.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_execsql_test skipscan3-1.1 {
CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,b,c));
WITH RECURSIVE
c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
INSERT INTO t1(a,b,c,d)
SELECT 1, 1, x, printf('x%04d',x) FROM c;
ANALYZE;
} {}
# This version has long used skip-scan because of the "+a"
#
do_execsql_test skipscan3-1.2eqp {
EXPLAIN QUERY PLAN SELECT d FROM t1 WHERE +a=1 AND c=32;
} {/*ANY(a) AND ANY(b)*/}
do_execsql_test skipscan3-1.2 {
SELECT d FROM t1 WHERE +a=1 AND c=32;
} {x0032}
# This version (with "a" instead of "+a") should use skip-scan but
# did not prior to changes implemented on 2014-08-20
#
do_execsql_test skipscan3-1.3eqp {
EXPLAIN QUERY PLAN SELECT d FROM t1 WHERE a=1 AND c=32;
} {/*ANY(a) AND ANY(b)*/}
do_execsql_test skipscan3-1.3 {
SELECT d FROM t1 WHERE a=1 AND c=32;
} {x0032}
# Repeat the test on a WITHOUT ROWID table
#
do_execsql_test skipscan3-2.1 {
CREATE TABLE t2(a,b,c,d,PRIMARY KEY(a,b,c)) WITHOUT ROWID;
WITH RECURSIVE
c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<1000)
INSERT INTO t2(a,b,c,d)
SELECT 1, 1, x, printf('x%04d',x) FROM c;
ANALYZE;
} {}
do_execsql_test skipscan3-2.2eqp {
EXPLAIN QUERY PLAN SELECT d FROM t2 WHERE +a=1 AND c=32;
} {/*ANY(a) AND ANY(b)*/}
do_execsql_test skipscan3-2.2 {
SELECT d FROM t2 WHERE +a=1 AND c=32;
} {x0032}
do_execsql_test skipscan3-2.3eqp {
EXPLAIN QUERY PLAN SELECT d FROM t2 WHERE a=1 AND c=32;
} {/*ANY(a) AND ANY(b)*/}
do_execsql_test skipscan3-2.3 {
SELECT d FROM t2 WHERE a=1 AND c=32;
} {x0032}
finish_test

View File

@ -48,6 +48,22 @@ do_test trace-1.5 {
db trace {} db trace {}
db trace db trace
} {} } {}
do_test trace-1.6 {
db eval {
CREATE TABLE t1b(x TEXT PRIMARY KEY, y);
INSERT INTO t1b VALUES('abc','def'),('ghi','jkl'),('mno','pqr');
}
set ::stmtlist {}
set xyzzy a*
db trace trace_proc
db eval {
SELECT y FROM t1b WHERE x GLOB $xyzzy
}
} {def}
do_test trace-1.7 {
set ::stmtlist
} {{SELECT y FROM t1b WHERE x GLOB 'a*'}}
db trace {}
# If we prepare a statement and execute it multiple times, the trace # If we prepare a statement and execute it multiple times, the trace
# happens on each execution. # happens on each execution.

View File

@ -62,7 +62,7 @@ mkdir -p tea/generic
echo "#ifdef USE_SYSTEM_SQLITE" > tea/generic/tclsqlite3.c echo "#ifdef USE_SYSTEM_SQLITE" > tea/generic/tclsqlite3.c
echo "# include <sqlite3.h>" >> tea/generic/tclsqlite3.c echo "# include <sqlite3.h>" >> tea/generic/tclsqlite3.c
echo "#else" >> tea/generic/tclsqlite3.c echo "#else" >> tea/generic/tclsqlite3.c
echo "#include \"../../sqlite3.c\"" >> tea/generic/tclsqlite3.c echo "#include \"sqlite3.c\"" >> tea/generic/tclsqlite3.c
echo "#endif" >> tea/generic/tclsqlite3.c echo "#endif" >> tea/generic/tclsqlite3.c
cat $TOP/src/tclsqlite.c >> tea/generic/tclsqlite3.c cat $TOP/src/tclsqlite.c >> tea/generic/tclsqlite3.c

View File

@ -957,7 +957,7 @@ static void usage(const char *argv0){
" NNNbdCCC Decode cell CCC on btree page NNN\n" " NNNbdCCC Decode cell CCC on btree page NNN\n"
" NNNt Decode freelist trunk page NNN\n" " NNNt Decode freelist trunk page NNN\n"
" NNNtd Show leaf freelist pages on the decode\n" " NNNtd Show leaf freelist pages on the decode\n"
" NNNtr Recurisvely decode freelist starting at NNN\n" " NNNtr Recursively decode freelist starting at NNN\n"
); );
} }